cba36394c902b3366305f7acffe47127124af3c0
91 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
8d43717d25 |
fix(deps): update dependency @scalar/nestjs-api-reference to v1.1.19 (#225)
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.16` -> `1.1.19`](https://renovatebot.com/diffs/npm/@scalar%2fnestjs-api-reference/1.1.16/1.1.19) | --- ### Release Notes <details> <summary>scalar/scalar (@​scalar/nestjs-api-reference)</summary> ### [`v1.1.19`](https://github.com/scalar/scalar/blob/HEAD/integrations/nestjs/CHANGELOG.md#1119) ### [`v1.1.18`](https://github.com/scalar/scalar/blob/HEAD/integrations/nestjs/CHANGELOG.md#1118) ### [`v1.1.17`](https://github.com/scalar/scalar/blob/HEAD/integrations/nestjs/CHANGELOG.md#1117) </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: #225 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> |
||
|
|
7d89591f9a |
fix(deps): update dependency @grpc/grpc-js to v1.14.4 (#218)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@grpc/grpc-js](https://grpc.io/) ([source](https://github.com/grpc/grpc-node)) | dependencies | patch | [`1.14.3` -> `1.14.4`](https://renovatebot.com/diffs/npm/@grpc%2fgrpc-js/1.14.3/1.14.4) | --- ### Release Notes <details> <summary>grpc/grpc-node (@​grpc/grpc-js)</summary> ### [`v1.14.4`](https://github.com/grpc/grpc-node/releases/tag/%40grpc/grpc-js%401.14.4): @​grpc/grpc-js 1.14.4 [Compare Source](https://github.com/grpc/grpc-node/compare/@grpc/grpc-js@1.14.3...@grpc/grpc-js@1.14.4) - Fix a bug that could cause servers to crash when handling malformed requests ([advisory GHSA-5375-pq7m-f5r2](https://github.com/grpc/grpc-node/security/advisories/GHSA-5375-pq7m-f5r2)) - Fix a bug that could cause clients and servers to crash when handling malformed compressed messages ([advisory GHSA-99f4-grh7-6pcq](https://github.com/grpc/grpc-node/security/advisories/GHSA-99f4-grh7-6pcq)) </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: #218 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> |
||
|
|
abd1f91809 |
fix(deps): update angular (#215)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@angular-devkit/core](https://github.com/angular/angular-cli) | devDependencies | patch | [`21.2.11` -> `21.2.12`](https://renovatebot.com/diffs/npm/@angular-devkit%2fcore/21.2.11/21.2.12) | | [@angular-devkit/schematics](https://github.com/angular/angular-cli) | devDependencies | patch | [`21.2.11` -> `21.2.12`](https://renovatebot.com/diffs/npm/@angular-devkit%2fschematics/21.2.11/21.2.12) | | [@angular/build](https://github.com/angular/angular-cli) | devDependencies | patch | [`21.2.11` -> `21.2.12`](https://renovatebot.com/diffs/npm/@angular%2fbuild/21.2.11/21.2.12) | | [@angular/cdk](https://github.com/angular/components) | dependencies | patch | [`21.2.11` -> `21.2.12`](https://renovatebot.com/diffs/npm/@angular%2fcdk/21.2.11/21.2.12) | | [@angular/cli](https://github.com/angular/angular-cli) | devDependencies | patch | [`21.2.11` -> `21.2.12`](https://renovatebot.com/diffs/npm/@angular%2fcli/21.2.11/21.2.12) | | [@angular/common](https://github.com/angular/angular) ([source](https://github.com/angular/angular/tree/HEAD/packages/common)) | dependencies | patch | [`21.2.13` -> `21.2.14`](https://renovatebot.com/diffs/npm/@angular%2fcommon/21.2.13/21.2.14) | | [@angular/compiler](https://github.com/angular/angular) ([source](https://github.com/angular/angular/tree/HEAD/packages/compiler)) | dependencies | patch | [`21.2.13` -> `21.2.14`](https://renovatebot.com/diffs/npm/@angular%2fcompiler/21.2.13/21.2.14) | | [@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.13` -> `21.2.14`](https://renovatebot.com/diffs/npm/@angular%2fcompiler-cli/21.2.13/21.2.14) | | [@angular/core](https://github.com/angular/angular) ([source](https://github.com/angular/angular/tree/HEAD/packages/core)) | dependencies | patch | [`21.2.13` -> `21.2.14`](https://renovatebot.com/diffs/npm/@angular%2fcore/21.2.13/21.2.14) | | [@angular/forms](https://github.com/angular/angular) ([source](https://github.com/angular/angular/tree/HEAD/packages/forms)) | dependencies | patch | [`21.2.13` -> `21.2.14`](https://renovatebot.com/diffs/npm/@angular%2fforms/21.2.13/21.2.14) | | [@angular/language-service](https://github.com/angular/angular) ([source](https://github.com/angular/angular/tree/HEAD/packages/language-service)) | devDependencies | patch | [`21.2.13` -> `21.2.14`](https://renovatebot.com/diffs/npm/@angular%2flanguage-service/21.2.13/21.2.14) | | [@angular/localize](https://github.com/angular/angular) | dependencies | patch | [`21.2.13` -> `21.2.14`](https://renovatebot.com/diffs/npm/@angular%2flocalize/21.2.13/21.2.14) | | [@angular/platform-browser](https://github.com/angular/angular) ([source](https://github.com/angular/angular/tree/HEAD/packages/platform-browser)) | dependencies | patch | [`21.2.13` -> `21.2.14`](https://renovatebot.com/diffs/npm/@angular%2fplatform-browser/21.2.13/21.2.14) | | [@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.13` -> `21.2.14`](https://renovatebot.com/diffs/npm/@angular%2frouter/21.2.13/21.2.14) | | [@schematics/angular](https://github.com/angular/angular-cli) | devDependencies | patch | [`21.2.11` -> `21.2.12`](https://renovatebot.com/diffs/npm/@schematics%2fangular/21.2.11/21.2.12) | --- ### Release Notes <details> <summary>angular/angular-cli (@​angular-devkit/core)</summary> ### [`v21.2.12`](https://github.com/angular/angular-cli/blob/HEAD/CHANGELOG.md#21212-2026-05-20) [Compare Source](https://github.com/angular/angular-cli/compare/v21.2.11...v21.2.12) ##### [@​angular/build](https://github.com/angular/build) | Commit | Type | Description | | --------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------- | | [cbad57579](https://github.com/angular/angular-cli/commit/cbad57579adb5de7887985afbb2bf1f40adf3cb2) | fix | ignore virtual esbuild paths with (disabled): | <!-- CHANGELOG SPLIT MARKER --> </details> <details> <summary>angular/components (@​angular/cdk)</summary> ### [`v21.2.12`](https://github.com/angular/components/blob/HEAD/CHANGELOG.md#21212-plastic-moose-2026-05-20) [Compare Source](https://github.com/angular/components/compare/v21.2.11...v21.2.12) ##### material | Commit | Type | Description | | -- | -- | -- | | [da87be7646](https://github.com/angular/components/commit/da87be76464d76ec11ae922abd5f4c72c5b4ea3e) | fix | **datepicker:** ensure dates don't overflow on a small screen ([#​33281](https://github.com/angular/components/pull/33281)) | <!-- CHANGELOG SPLIT MARKER --> </details> <details> <summary>angular/angular (@​angular/common)</summary> ### [`v21.2.14`](https://github.com/angular/angular/blob/HEAD/CHANGELOG.md#21214-2026-05-20) [Compare Source](https://github.com/angular/angular/compare/v21.2.13...v21.2.14) ##### compiler | Commit | Type | Description | | -- | -- | -- | | [68282dff9f](https://github.com/angular/angular/commit/68282dff9f9ef46540cca4bd38fc1ab739c8a783) | fix | strip namespaced SVG script elements during template compilation | ##### core | Commit | Type | Description | | -- | -- | -- | | [c0f52272ed](https://github.com/angular/angular/commit/c0f52272ed337d4776bd4178cbbdc7f32037500f) | fix | do not insert todo when migrating void [@​Output](https://github.com/Output) | | [938a7f3edd](https://github.com/angular/angular/commit/938a7f3eddda97a39edb9edcc8b4dd970858b3a2) | fix | makes resource URL sanitizer lookup case-insensitive | | [0fb2724194](https://github.com/angular/angular/commit/0fb272419407a64a0a47096b03a911f4e7e83d79) | fix | reject script element as a dynamic component host | | [49113ac0ef](https://github.com/angular/angular/commit/49113ac0eff852d987b5acb28a9bbda0242842cd) | fix | visit ICU expressions in signal migration schematics | ##### router | Commit | Type | Description | | -- | -- | -- | | [099bf577ee](https://github.com/angular/angular/commit/099bf577ee8f0bab60593a8fd2a1de7d298e3cd6) | fix | skip scroll-to-top on initial navigation when hydrating | <!-- CHANGELOG SPLIT MARKER --> </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. 👻 **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: #215 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> |
||
|
|
e8796e94f4 |
chore(deps): update dependency ts-jest to v29.4.11 (#214)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [ts-jest](https://kulshekhar.github.io/ts-jest) ([source](https://github.com/kulshekhar/ts-jest)) | devDependencies | patch | [`29.4.10` -> `29.4.11`](https://renovatebot.com/diffs/npm/ts-jest/29.4.10/29.4.11) | --- ### Release Notes <details> <summary>kulshekhar/ts-jest (ts-jest)</summary> ### [`v29.4.11`](https://github.com/kulshekhar/ts-jest/blob/HEAD/CHANGELOG.md#29411-2026-05-21) [Compare Source](https://github.com/kulshekhar/ts-jest/compare/v29.4.10...v29.4.11) ##### Bug Fixes - preserve Bundler on the CJS path under TypeScript >= 6 ([3941818](https://github.com/kulshekhar/ts-jest/commit/39418187515f11b6584d35a4e3ddf50231f74936)), closes [#​4198](https://github.com/kulshekhar/ts-jest/issues/4198) </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/214 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> |
||
|
|
77af6951c9 |
fix(deps): bump uuid to >=11.1.1 via pnpm.overrides (GHSA-w5hq-g745-h8pq) (#210)
## Summary `pnpm ci:audit` was failing on `main` with one moderate-severity finding: ``` uuid: Missing buffer bounds check in v3/v5/v6 when buf is provided GHSA-w5hq-g745-h8pq Vulnerable: uuid < 11.1.1 Path: . > @lhci/cli@0.15.1 > uuid@8.3.2 ``` `@lhci/cli@0.15.1` is the latest release and still ships `uuid@8.3.2`; no upstream fix yet. Renovate cannot solve this on its own. ## What lands | File | Change | | --- | --- | | `package.json` | `pnpm.overrides`: add `"uuid@<11.1.1": ">=11.1.1"` alongside the existing axios / ajv / brace-expansion / esbuild / follow-redirects / ip-address / protobufjs / tmp / ws / yaml entries. | | `pnpm-lock.yaml` | Refreshed. Both `@lhci/cli` and `sockjs` (transitive via the rspack / webpack dev-servers) now resolve to `uuid@14.0.0` — the same major already in the tree via `mermaid`. Net `uuid` versions: 2 → 1. | ## Notes for the reviewer - **Why an override and not an `auditConfig.ignoreGhsas`.** The repo already uses `pnpm.overrides` for 10 prior advisories on transitive deps with no patched release in their consumer — same pattern applied here. An exemption-document path was drafted then dropped: forcing the fix is cleaner than waving away the warning, and the upgrade actually works. - **Why our usage was not at risk (context, not justification to skip).** The advisory affects `uuid.v3` / `uuid.v5` / `uuid.v6` when called with the optional `buf` argument. Both consumers in the tree only use `uuid.v4()` (random): - `@lhci/cli/src/collect/node-runner.js:65` — `\`flags-${uuid.v4()}.json\`` - `sockjs/lib/transport.js:9` — `uuidv4 = require('uuid').v4` But the audit gate is set to `moderate` per [ADR-0015](docs/decisions/0015-cicd-gitea-actions.md); every flagged advisory blocks merge regardless of reachability. Forcing the fix is the documented response. - **Why `uuid@14` works for the CJS consumers.** `uuid@14` is ESM-only (`type: module` + conditional `exports`). `@lhci/cli` does `const uuid = require('uuid')` which is a CJS-requires-ESM pattern. Node `>= 22.12` supports it natively via the stable `require(esm)` capability; the workspace pins Node 24 in [`.nvmrc`](.nvmrc), so the consumer is fine. Verified locally: ``` $ node -e "require('@lhci/cli/src/collect/node-runner.js')" # no error ``` - **Side benefit.** `uuid@8.3.2` was also pulled in transitively via `sockjs`. After the override, the dep tree consolidates onto a single `uuid@14.0.0` — removes the `Found 2 versions of uuid` dedup notice and aligns with the version `mermaid` already uses. - **Closure condition.** When `@lhci/cli` ships a release with `uuid >= 11.1.1` (or with `uuid@14` directly), Renovate will surface the bump; this override row becomes redundant and can be deleted. Same removal cadence as the other `pnpm.overrides` entries. ## Test plan - [x] `pnpm ci:audit` — clean: `No known vulnerabilities found`. - [x] `pnpm ci:check` — 13 projects green (no behavioural change against the previous run). - [x] Loaded `@lhci/cli`'s node-runner module under the override to confirm `require('uuid')` resolves without error on Node 24. - [ ] Post-merge CI on `main` runs `pnpm ci:audit` cleanly. --------- Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr> Reviewed-on: #210 |
||
|
|
a34709613f |
fix(ci): refresh lockfile for the new shared-auth lib (#207)
## Summary The auth-catalogue skeleton PR (#206) added `libs/shared/auth/` with three dev dependencies (`tslib`, `vitest`, `@nx/vite`) in the new lib's `package.json` but did not refresh `pnpm-lock.yaml`. As a result the post-merge `pnpm install --frozen-lockfile` step in CI on `main` fails with: ``` ERR_PNPM_OUTDATED_LOCKFILE Cannot install with "frozen-lockfile" because pnpm-lock.yaml is not up to date with <ROOT>/libs/shared/auth/package.json specifiers in the lockfile don't match specifiers in package.json: * 3 dependencies were added: tslib@^2.3.0, vitest@^4.0.8, @nx/vite@^22.7.1 ``` Running `pnpm install` locally adds the missing `importers["libs/shared/auth"]` block. No other dependency moves — every other version is pinned to what `main` already resolved. ## What lands | File | Change | | --- | --- | | `pnpm-lock.yaml` | +12 lines: new `importers["libs/shared/auth"]` entry with the three deps resolved to `tslib@2.8.1`, `vitest@4.1.6`, `@nx/vite@22.7.2` — same versions as the other `libs/shared/*` libs already use. | ## Notes for the reviewer - **Why this didn't surface during #206's CI run.** PR-level CI runs against the branch's `pnpm-lock.yaml` *after* `pnpm install` had refreshed it locally during the work. The lockfile delta should have been part of #206 but was missed at commit time. Post-merge CI on `main` is the first run that exercises a clean `--frozen-lockfile` against the merged tree, which is when the gap shows. - **Why not amend #206.** It's already on `main`. A separate small fix-up PR is cleaner than re-opening the merged history. - **Preventing recurrence.** Standard Nx flow: every PR that creates a new lib or moves a dep should run `pnpm install` and stage the lockfile alongside the source. A future drift-gate (mentioned in ADR-0025 §"Confirmation" for catalogue drift) could be extended to also assert lockfile-vs-package-json alignment, but that's out of scope for this fix. ## Test plan - [x] `pnpm install --frozen-lockfile` succeeds locally on this branch. - [ ] Post-merge CI on `main` runs through the install step cleanly. --------- Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr> Reviewed-on: #207 |
||
|
|
273d96551f |
chore(deps): update dependency @swc/core to v1.15.40 (#204)
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.33` -> `1.15.40`](https://renovatebot.com/diffs/npm/@swc%2fcore/1.15.33/1.15.40) | --- ### Release Notes <details> <summary>swc-project/swc (@​swc/core)</summary> ### [`v1.15.40`](https://github.com/swc-project/swc/blob/HEAD/CHANGELOG.md#11540---2026-05-23) [Compare Source](https://github.com/swc-project/swc/compare/v1.15.33...v1.15.40) ##### Bug Fixes - **(es/minifier)** Preserve args for destructured callbacks ([#​11830](https://github.com/swc-project/swc/issues/11830)) ([21873b0](https://github.com/swc-project/swc/commit/21873b06df3fd62d952a21cf879e14d11d4b39d7)) - **(es/minifier)** Avoid generating mangled property names that collide with existing properties ([#​11839](https://github.com/swc-project/swc/issues/11839)) ([9b4fab5](https://github.com/swc-project/swc/commit/9b4fab58c90256a6da688de87ea405225a5a6fdb)) - **(es/minifier)** Respect ecma for iife temp vars ([#​11873](https://github.com/swc-project/swc/issues/11873)) ([e481934](https://github.com/swc-project/swc/commit/e481934a63c0ee891e4a770c4f0cd5ec3fd8624e)) - **(es/minifier)** Preserve default parameter object props ([#​11884](https://github.com/swc-project/swc/issues/11884)) ([71ff84f](https://github.com/swc-project/swc/commit/71ff84f19762306ab9b86accb29eb6ed83c46f84)) - **(es/parser)** Reject object-rest assignment to array/object literal ([#​11875](https://github.com/swc-project/swc/issues/11875)) ([7b57d1f](https://github.com/swc-project/swc/commit/7b57d1f8717d8bf6be0b617b04bc6e219a2b3775)) - **(es/parser)** Reject object rest assignment to literals ([#​11881](https://github.com/swc-project/swc/issues/11881)) ([4ec2eaf](https://github.com/swc-project/swc/commit/4ec2eaf4d89ddd95293b8f09169a88b0434c5a13)) - **(es/react)** Exclude self-recursive hooks from refresh dependency array ([#​11838](https://github.com/swc-project/swc/issues/11838)) ([9101c71](https://github.com/swc-project/swc/commit/9101c719fa8f3f5cb410d716d4f50544650cd81e)) - **(ts/fast-dts)** Strip definite assertions in dts ([#​11858](https://github.com/swc-project/swc/issues/11858)) ([2ab1b8a](https://github.com/swc-project/swc/commit/2ab1b8a50f2af3d8b4c42d6c4dd4f2051940cae0)) - **(ts/fast-strip)** Reject unsafe assertion erasure in binary expressions ([#​11828](https://github.com/swc-project/swc/issues/11828)) ([aa5b539](https://github.com/swc-project/swc/commit/aa5b539b277dbf4c68c87380d16f4b8713145df3)) - **(typescript)** Strip parameter binding defaults in dts ([#​11857](https://github.com/swc-project/swc/issues/11857)) ([800bc17](https://github.com/swc-project/swc/commit/800bc170334a74191eb5ae21e3bfc96bf6f7fe56)) ##### Documentation - Update agent guidance ([#​11842](https://github.com/swc-project/swc/issues/11842)) ([bf2d015](https://github.com/swc-project/swc/commit/bf2d0154cf8b66fdab16085585fda0086d297a64)) - Add security policy ([#​11876](https://github.com/swc-project/swc/issues/11876)) ([6c43c2d](https://github.com/swc-project/swc/commit/6c43c2de9cb9d5516b0ac87101345940964e943e)) - Clarify security scope for npm packages ([#​11877](https://github.com/swc-project/swc/issues/11877)) ([4662db8](https://github.com/swc-project/swc/commit/4662db8fe3e503f298a285697ea63ecc1ca3b958)) - Clarify untrusted input security model ([#​11882](https://github.com/swc-project/swc/issues/11882)) ([5463777](https://github.com/swc-project/swc/commit/546377770e164aead174404fb678319c9c56a9dc)) ##### Features - **(es/minifier)** Fine grained effect analysis of class ([#​11814](https://github.com/swc-project/swc/issues/11814)) ([c9058ad](https://github.com/swc-project/swc/commit/c9058adb5bb7d6bbe354e6136685271f722354a0)) - **(swc\_cli)** Implement all features for `swc_cli` ([#​11797](https://github.com/swc-project/swc/issues/11797)) ([9300ede](https://github.com/swc-project/swc/commit/9300ede1d495463042da1db11754c76057a50954)) ##### Miscellaneous Tasks - **(es/minifier)** Fix typo in debug log ([#​11866](https://github.com/swc-project/swc/issues/11866)) ([3de0254](https://github.com/swc-project/swc/commit/3de0254db7fae5a2883af78b8b7d57af4cb94531)) - **(html)** Add webcontainer fallback for `@swc/html` ([#​11860](https://github.com/swc-project/swc/issues/11860)) ([7692eed](https://github.com/swc-project/swc/commit/7692eed981916bb01a3c4c231b3af012d4993d9e)) ##### Performance - **(ecma)** Reduce transformer compat overhead ([#​11856](https://github.com/swc-project/swc/issues/11856)) ([d03cb71](https://github.com/swc-project/swc/commit/d03cb71fb8b39f01f0ad704473109294e52e07fd)) - **(es/codegen)** Speed up JsWriter position and srcmap tracking ([#​11867](https://github.com/swc-project/swc/issues/11867)) ([dbceade](https://github.com/swc-project/swc/commit/dbceade22809ac9a9cb7548456ab335df26fb046)) - **(es/codegen)** Remove JsWriter last\_srcmap cache ([#​11869](https://github.com/swc-project/swc/issues/11869)) ([3bc1c2b](https://github.com/swc-project/swc/commit/3bc1c2b9b2594b05478dc4240977b981d6f8521b)) - **(es/minifier)** Reduce minifier profiling hotspots ([#​11853](https://github.com/swc-project/swc/issues/11853)) ([28c1091](https://github.com/swc-project/swc/commit/28c1091adb2c6f6d0e46daa5595908d1ba6fccb7)) - Optimize es parser comment finalization ([#​11852](https://github.com/swc-project/swc/issues/11852)) ([2959ddf](https://github.com/swc-project/swc/commit/2959ddf87af0ac95eb5176180782819bd1073d66)) ##### Testing - **(es/minifier)** Move issue\_11835 fixture out of terser folder ([#​11840](https://github.com/swc-project/swc/issues/11840)) ([3dd3431](https://github.com/swc-project/swc/commit/3dd34310d429baff6e8d1a6393266c648684d3c6)) ##### Ci - Update corepack in publish docker jobs ([#​11885](https://github.com/swc-project/swc/issues/11885)) ([9a7d954](https://github.com/swc-project/swc/commit/9a7d954c4939b12da4c60023eba50d6df8086fd7)) - Pass publish docker env explicitly ([#​11888](https://github.com/swc-project/swc/issues/11888)) ([c5f7547](https://github.com/swc-project/swc/commit/c5f7547cf68a4803aec3e88901e0d6b57ebbeb55)) - Lock issues closed by merged prs ([#​11887](https://github.com/swc-project/swc/issues/11887)) ([6bd74e5](https://github.com/swc-project/swc/commit/6bd74e5683ed43640db64f78dc74001a056c1bfa)) - Provide aarch64 musl linker in publish job ([#​11889](https://github.com/swc-project/swc/issues/11889)) ([20234fd](https://github.com/swc-project/swc/commit/20234fd265f8f86f0c81c31c36e467d405a04d01)) - Fix publish musl linker and windows tests ([#​11890](https://github.com/swc-project/swc/issues/11890)) ([a798a23](https://github.com/swc-project/swc/commit/a798a23e5f5018e5c01f874457aa20370c0d7058)) - Make minifier test path explicit ([#​11891](https://github.com/swc-project/swc/issues/11891)) ([e7cba97](https://github.com/swc-project/swc/commit/e7cba972ff25565208c4448accab19c259e6947c)) ##### Security - Save CI caches only on main ([#​11848](https://github.com/swc-project/swc/issues/11848)) ([7582529](https://github.com/swc-project/swc/commit/75825293150b548216bf5c08531e1850bd064fcb)) - Update rkyv and Rust dependencies ([#​11851](https://github.com/swc-project/swc/issues/11851)) ([20d92eb](https://github.com/swc-project/swc/commit/20d92eb3c8dee378f046a6bff839913600a1fbdb)) - Harden PR workflow permissions ([#​11849](https://github.com/swc-project/swc/issues/11849)) ([e199564](https://github.com/swc-project/swc/commit/e199564ebaae88ec121a777cf0ec4eec9644aed5)) </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/204 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> |
||
|
|
82d4245ab7 |
chore(deps): update analog monorepo to v2.5.2 (#203)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@analogjs/vite-plugin-angular](https://github.com/analogjs/analog) | devDependencies | patch | [`2.5.1` -> `2.5.2`](https://renovatebot.com/diffs/npm/@analogjs%2fvite-plugin-angular/2.5.1/2.5.2) | | [@analogjs/vitest-angular](https://analogjs.org) ([source](https://github.com/analogjs/analog)) | devDependencies | patch | [`2.5.1` -> `2.5.2`](https://renovatebot.com/diffs/npm/@analogjs%2fvitest-angular/2.5.1/2.5.2) | --- ### Release Notes <details> <summary>analogjs/analog (@​analogjs/vite-plugin-angular)</summary> ### [`v2.5.2`](https://github.com/analogjs/analog/blob/HEAD/CHANGELOG.md#252-2026-05-22) [Compare Source](https://github.com/analogjs/analog/compare/v2.5.1...v2.5.2) ##### Bug Fixes - **storybook-angular:** support Storybook 10.4+ object-shaped core preset ([#​2337](https://github.com/analogjs/analog/issues/2337)) ([1956794](https://github.com/analogjs/analog/commit/1956794ce6bb0b15d5aacf53a81b22469bb568a7)) - **vite-plugin-angular:** compose fastCompile JIT strip map and cover esbuild fallback ([#​2341](https://github.com/analogjs/analog/issues/2341)) ([532aa3e](https://github.com/analogjs/analog/commit/532aa3e0ff239175ead36d57278a243022492f0c)) - **vite-plugin-angular:** reject [@​Service](https://github.com/Service) on Angular below 22 ([bc63520](https://github.com/analogjs/analog/commit/bc63520720dd983d6ae8e2dcd6a936efe6168625)) - **vite-plugin-angular:** skip source .d.ts files for composite TS projects ([#​2335](https://github.com/analogjs/analog/issues/2335)) ([96ec5b3](https://github.com/analogjs/analog/commit/96ec5b38c030aa36009be2c6f0d9c5be342aa351)) - **vite-plugin-angular:** strip TS in fastCompile JIT path for StackBlitz ([#​2340](https://github.com/analogjs/analog/issues/2340)) ([44e6334](https://github.com/analogjs/analog/commit/44e6334cd9add9187fab6f5007e0b43361a9d84c)) - **vite-plugin-angular:** support the [@​Service](https://github.com/Service) decorator in the fast compiler ([b284696](https://github.com/analogjs/analog/commit/b284696088faa4e65f572eb83708329b6eed3f79)) </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/203 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> |
||
|
|
2b93710eaa |
chore(deps): update dependency vite to v8.0.14 (#202)
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.13` -> `8.0.14`](https://renovatebot.com/diffs/npm/vite/8.0.13/8.0.14) | --- ### Release Notes <details> <summary>vitejs/vite (vite)</summary> ### [`v8.0.14`](https://github.com/vitejs/vite/blob/HEAD/packages/vite/CHANGELOG.md#small-8014-2026-05-21-small) [Compare Source](https://github.com/vitejs/vite/compare/v8.0.13...v8.0.14) ##### Features - update rolldown to 1.0.2 ([#​22484](https://github.com/vitejs/vite/issues/22484)) ([96efc88](https://github.com/vitejs/vite/commit/96efc88570b6a6ddf1a910f106920cbac07b3cf0)) ##### Bug Fixes - **deps:** update all non-major dependencies ([#​22471](https://github.com/vitejs/vite/issues/22471)) ([98b8163](https://github.com/vitejs/vite/commit/98b81632139d51820f82036e58d6fbbf122b77b3)) - **dev:** handle errors when sending messages to vite server ([#​22450](https://github.com/vitejs/vite/issues/22450)) ([e8e9a34](https://github.com/vitejs/vite/commit/e8e9a34dcf2540139de558a10187630884d10217)) - **html:** handle trailing slash paths in transformIndexHtml ([#​22480](https://github.com/vitejs/vite/issues/22480)) ([5d94d1b](https://github.com/vitejs/vite/commit/5d94d1bffdb2a15de9341194d89baec86ce1f693)) - **optimizer:** pass oxc jsx options to transformSync in dependency scan ([#​22342](https://github.com/vitejs/vite/issues/22342)) ([b3132da](https://github.com/vitejs/vite/commit/b3132dacea9c6e0cf526cd9f0f09d850f577c262)) ##### Miscellaneous Chores - **deps:** update rolldown-related dependencies ([#​22470](https://github.com/vitejs/vite/issues/22470)) ([7cb728e](https://github.com/vitejs/vite/commit/7cb728eb629cc677661f1bc52a044ffc0b87fc7f)) - remove irrelevant commits from changelog ([2c69495](https://github.com/vitejs/vite/commit/2c69495f250edf01132d4a20128de19dbe836086)) ##### Code Refactoring - **glob:** do not rewrite import path for absolute base ([#​22310](https://github.com/vitejs/vite/issues/22310)) ([0ae2844](https://github.com/vitejs/vite/commit/0ae2844ab6d6d1ccf78a2975b8132769fc35b302)) ##### Tests - **css:** sass does not use main field ([#​22449](https://github.com/vitejs/vite/issues/22449)) ([ebf39a0](https://github.com/vitejs/vite/commit/ebf39a04329ddc6ba765e006a5d463680a952270)) </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/202 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> |
||
|
|
e389567a3c |
fix(ci): move grpc-tools to optionalDependencies (revert NODE_OPTIONS attempt) (#200)
## Summary The `NODE_OPTIONS=--use-system-ca` workaround merged in #199 did not clear the CI install failure — the runner still rejects the TLS chain to `node-precompiled-binaries.grpc.io`. Either the runner's OS CA bundle is missing the same intermediate Node's bundled set is missing, or `--use-system-ca` does not propagate down to the `node-fetch@2` that `node-pre-gyp` uses. Without runner shell access the exact reason is not worth chasing. Switch angle: **the protoc binary `grpc-tools` downloads is never used in CI**. The generated TypeScript stubs in `apps/portal-bff/src/grpc/gen/` are committed per [ADR-0024](docs/decisions/0024-ai-service-relay-grpc-sse-bridge.md) §"Sub-decision 3 — vendored protos", so CI only needs to type-check them; protoc only runs when a developer regenerates from `apps/portal-bff/src/grpc/proto/apf-ai/*.proto`. This PR moves `grpc-tools` from `devDependencies` to `optionalDependencies`. Per pnpm semantics, when an optional dep's install (including postinstall) fails, pnpm logs a warning and the overall install completes. CI's `pnpm install --frozen-lockfile` therefore succeeds even when the binary cannot be fetched; developer machines (where TLS validates) install grpc-tools normally and `pnpm grpc:codegen` works unchanged. ## What lands - `package.json` — `grpc-tools: "^1.13.0"` moves out of `devDependencies` and into a new `optionalDependencies` block. The entry in `pnpm.onlyBuiltDependencies` stays — it controls whether pnpm *attempts* the postinstall, not whether failure is fatal. Local installs (where TLS works) still run the postinstall and download the binary. - `pnpm-lock.yaml` — refreshed; the lockfile reflects the new optional-dep classification. No version changes to anything else. - `.gitea/workflows/ci.yml` — revert the workflow-level `env: NODE_OPTIONS: --use-system-ca` block added in #199. Did not help; left in place it would be a misleading "this is supposed to fix CI TLS" signpost. - `.gitea/workflows/docs-site.yml` — same revert. ## Notes for the reviewer - **Why `optionalDependencies` is the right primitive.** pnpm 10 documents the contract: a package listed in `optionalDependencies` is *attempted*; if the install fails for any reason (platform mismatch, postinstall script error, network failure), the failure is logged and the overall command continues. That maps exactly to what this PR needs: try in CI, fail gracefully, succeed locally. - **Why not remove `grpc-tools` from `pnpm.onlyBuiltDependencies` instead.** Removing it from the allowlist tells pnpm not to even *try* the postinstall, which would also fix CI. But it would also break the developer workflow — locally, the protoc binary would never download, and `pnpm grpc:codegen` would fail. The dev would have to manually trigger the build (`pnpm approve-builds` then `pnpm rebuild grpc-tools`), or worse, devs would commit accidental `package.json` mutations from `approve-builds`. The `optionalDependencies` route keeps the local DX identical. - **Why revert the workflow `env:` blocks.** They do not help here, and leaving them in place implies that `--use-system-ca` is the canonical fix for this class of failure — which it is *not*, at least not for this runner / this CDN. If a future native dep hits a similar wall and `--use-system-ca` *does* fix it for that case, the env var lands in a focused PR with a real validation. Carrying it now as a "maybe useful later" workaround is noise. - **Codegen workflow on developer machines.** Unchanged. `pnpm install` runs the postinstall (TLS validates locally), the protoc binary lands in `node_modules/`, `pnpm grpc:codegen` regenerates stubs. The only visible difference is a one-line `WARN GET_RESOLVED_FROM_REGISTRY ...` if a contributor ever encounters the same TLS failure locally (e.g., on a corporate-proxied machine) — pnpm will mark grpc-tools as failed-optional and the rest of the install proceeds; the dev can then debug their own network without blocking the whole repo. - **Idempotence with CI's `--frozen-lockfile`.** The lockfile change is small (re-classifies grpc-tools from `dev` to `optional`) and lands in this PR. After merge, CI runs against the new lockfile; no further coordination needed. ## Test plan - [x] `pnpm install` locally — clean, grpc-tools postinstall runs successfully (TLS validates), protoc binary present. - [x] `pnpm grpc:codegen` — regenerates the TypeScript stubs identically (no diff in `apps/portal-bff/src/grpc/gen/`). - [x] `pnpm nx run-many -t lint test build -p portal-shell,portal-admin,portal-bff,shared-ui,shared-charts` — all five projects green. - [ ] **CI green on this PR's first run.** The validation that matters: `pnpm install --frozen-lockfile` completes despite grpc-tools' postinstall failure; `ci:check` runs to completion. - [ ] Spot-check of post-merge CI runs over the next few days to confirm the warning is recurring (expected) and the install never fails (the contract). ## What's next - If the CI behaviour is what this PR predicts (warning instead of failure), no further action required. - If `optionalDependencies` does not work as documented (highly unlikely, but possible if the pnpm version has a regression), the fallback is to drop `grpc-tools` from `pnpm.onlyBuiltDependencies` and add a small dev-onboarding note. One-line change away. - Long-term cleanup: if a future PR migrates the codegen step to a Docker-based tool (`buf`, system protoc) the optional-dep entry can be removed entirely. Out of scope here. --------- Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr> Reviewed-on: #200 |
||
|
|
0d5ce1e153 |
fix(deps): update dependency @azure/msal-node to v5.2.2 (#198)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@azure/msal-node](https://github.com/AzureAD/microsoft-authentication-library-for-js) | dependencies | patch | [`5.2.1` -> `5.2.2`](https://renovatebot.com/diffs/npm/@azure%2fmsal-node/5.2.1/5.2.2) | --- ### 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: #198 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> |
||
|
|
9b7d16601d |
feat(portal-bff): ai-client skeleton — vendored protos + grpc client + Principal mapper (#195)
## Summary Step 2 of the AI-relay chantier (after [ADR-0024](docs/decisions/0024-ai-service-relay-grpc-sse-bridge.md) merged in #194). Lands the BFF-side **skeleton** that talks to `apf-ai-service` over gRPC: vendored protos, generated TypeScript stubs, typed wrapper clients, Principal mapper, and metadata builder — all tested against an in-process fake gRPC server. **No HTTP route is exposed in this PR**; the SSE bridge (`POST /api/ai/chat`, `GET /api/ai/rag/search`, `GET /api/ai/models`) ships in the next PR. The skeleton is self-contained: `AiClientModule` is built but is NOT imported in `AppModule` yet. The BFF runtime is byte-for-byte unchanged. Everything below exists for the next PR to wire into a controller. ## What lands ### Proto vendoring + codegen - `apps/portal-bff/src/grpc/proto/apf-ai/` — mirror of `apf-ai-service/contract/proto/` (common, chat, rag, ingestion, models). Both the `.proto` files and the regenerated `ts-proto` output under `grpc/gen/` are committed for hermetic builds and reviewable diffs (per ADR-0024 §"Sub-decision 3"). - `pnpm run grpc:codegen` — regenerates the stubs via `grpc-tools`' bundled `protoc` and the `ts-proto` plugin (`outputServices=grpc-js, esModuleInterop, forceLong=long, useOptionals=messages, exportCommonSymbols=false`). - `pnpm run grpc:sync` — copies the vendored `.proto` files from the sibling `apf-ai-service` working tree (`../apf-ai-service/contract/proto/`); developer convenience, never invoked from CI. Errors with an actionable message when the sibling tree is not where it expects. - Generated tree (`grpc/gen/**`) excluded from Prettier (`.prettierignore`) and ESLint (`eslint.config.mjs` ignores). Hand-rules apply to wrappers under `ai-client/`, not to codegen output. ### Dependencies - `@grpc/grpc-js@^1.13.0` — runtime gRPC client. - `@bufbuild/protobuf@^2.10.2` — wire codec used by `ts-proto`'s emitted code. - `long@^5.2.3` — int64 representation for proto Long fields (`forceLong=long`). - `ts-proto@^2.7.0` — devDep, TypeScript codegen plugin. - `grpc-tools@^1.13.0` — devDep, ships `protoc` + the gRPC plugin; added to `pnpm.onlyBuiltDependencies` so the postinstall binary download runs. ### Env validator `apps/portal-bff/src/config/check-ai-service-config.ts` follows the same posture as the other validators (per ADR-0018 §"BFF env-var loading"): small, per-key, runs at module init, throws with an actionable message on misconfiguration. Three vars: | Var | Mandatory | Purpose | |---|---|---| | `AI_SERVICE_GRPC_ENDPOINT` | yes | `host:port` reachable from the BFF — `apf-ai-service:8080` in dev Compose, service DNS + 443 in prod | | `AI_SERVICE_CLIENT_ID` | yes | Deployment slug propagated as the `x-client-id` metadata. Convention: `apf-portal-<env>` | | `AI_SERVICE_GRPC_TLS` | no (default `true`) | `false` for h2c in dev, `true` for h2 + TLS in prod | 7 spec cases lock the validation contract end-to-end. ### `AiClientModule` `apps/portal-bff/src/grpc/ai-client/` houses: - **`tokens.ts`** — DI tokens (`AI_CONFIG`, `AI_CREDENTIALS`, one per generated stub). - **`principal.mapper.ts`** — `PrincipalMapper.fromInputs({oid, tid, roles, extraAttributes})` returns the proto `Principal`. `subject` is hashed via `HashUserIdService` (the **same** salt + algorithm the audit writer uses) so `Principal.subject` matches `audit.events.actor_id_hash` byte-for-byte. `roles` passes through verbatim — inclusive expansion lands with a future role-hierarchy ADR; the wire contract on the AI side is unchanged. - **`grpc-metadata.builder.ts`** — stamps every outbound call with `x-client-id` (from config) and `x-correlation-id` (active OTel span's trace-id when present, else explicit override, else fresh UUID). - **`chat.client.ts`** — server-stream wrapper around `ChatServiceClient`. Returns the raw `ClientReadableStream<ChatEvent>` (Node `Readable` is async-iterable so the SSE bridge consumes with `for await`). Optional `AbortSignal` propagates browser disconnect to `call.cancel()`. - **`rag.client.ts`**, **`models.client.ts`**, **`ingestion.client.ts`** — unary promisified wrappers. `IngestionClient` is unused in v1 (the admin "manage AI corpus" surface lands later) but wired now so the future controller is one new file, not a new module. - **`ai-client.module.ts`** — NestJS module wiring the providers. `HashUserIdService` is declared locally rather than imported via `AuditModule` (the global module) to keep the module unit-testable in isolation; runtime equivalence is guaranteed by the service being a pure function of `LOG_USER_ID_SALT`. ### Tests 5 new spec files, 18 new test cases. All run against in-process fake gRPC servers; no network, no live `apf-ai-service`: - `check-ai-service-config.spec.ts` — 7 cases (happy path + 6 rejection branches). - `principal.mapper.spec.ts` — 7 cases including the cross-service hash-stability invariant and the `tenantId` reserved-key contract. - `grpc-metadata.builder.spec.ts` — 5 cases covering all three correlation-id resolution paths and metadata immutability. - `chat.client.spec.ts` — 4 cases: happy-path stream, metadata propagation, mid-stream cancel via AbortSignal, pre-aborted signal. - `rag.client.spec.ts` — 2 cases: unary happy path, `ServiceError` propagation. - `ai-client.module.spec.ts` — 4 cases: module bootstrap, all four wrappers resolved, env-driven `AI_CONFIG`, shared credentials across stubs. **Total BFF spec suite: 443 → 461 (after merge accounting), all passing.** ## Notes for the reviewer - **Why both `.proto` and generated `.ts` are committed.** Hermetic builds. Reviewers see both sides of a contract change in one diff. CI never runs codegen — drift between proto and stub would otherwise hide behind a successful build. The drift gate that compares the vendored copy against an upstream tag of `apf-ai-service` is the post-v1 follow-up listed in ADR-0024's "What's next". - **`HashUserIdService` declared locally in `AiClientModule`.** Two instances of the service exist when both `AuditModule` (global) and `AiClientModule` are wired into `AppModule`. The cost is one extra constructor call at bootstrap; the value is full test isolation of `AiClientModule` and a self-contained Principal-mapping boundary. The cross-service hash join invariant from ADR-0013 still holds because the service is a pure function of the `LOG_USER_ID_SALT` env var. - **`AiClientModule` is NOT imported by `AppModule`.** Deliberately. The skeleton compiles, type-checks, and unit-tests cleanly with no runtime side effects. The next PR (SSE bridge controller) adds the `imports: [AiClientModule]` line + the controller, in one focused change. - **`ts-proto` flat-oneof emission.** `ChatEvent` is generated with optional siblings (`token?`, `citation?`, `done?`, …) rather than a discriminated union (`$case: 'token'`). The flatter shape composes more naturally with the SSE writer the next PR will introduce (`event:` field name maps directly to the populated sibling). - **Cancellation test deliberately relaxed.** The "AbortSignal already aborted before call dial" test asserts the client-side outcome (no payload, error or clean end) but not server-side observation. gRPC-js may or may not propagate a cancel frame depending on whether the call had time to dial — both outcomes are correct per the contract; only the absence of payload matters. - **Lifecycle (`onApplicationShutdown`) deferred.** The module does not close the gRPC channel on shutdown today. Process termination closes the sockets via OS-level descriptor reclaim — sufficient for dev/preprod. The next PR wires the module into `AppModule` and adds an explicit Nest lifecycle hook in the same change (paired with `app.enableShutdownHooks()` in `main.ts`). ## Test plan - [x] `pnpm run grpc:codegen` — clean regeneration. Generated tree byte-identical to what's committed. - [x] `pnpm nx test portal-bff` — **443 specs pass** (was 425). - [x] `pnpm nx lint portal-bff` — clean. The eslint ignore for `grpc/gen/**` covers ts-proto's relaxed style; hand-written `ai-client/` files pass the project's full rule set. - [x] `pnpm nx build portal-bff` — clean, webpack-compiled. No bundle-size delta on the runtime artefact yet (the module is unimported). - [x] `pnpm install` — lockfile reconciled; `grpc-tools` postinstall fetches `protoc` from the precompiled-binaries mirror without errors on Linux x64. - [ ] **Manual smoke (next PR)** — once the SSE bridge ships, point `AI_SERVICE_GRPC_ENDPOINT` at the local `apf-ai-service` Compose service and run an end-to-end chat against the canned stub responses on the AI side. Not in scope for this PR. ## What's next 1. **PR — SSE bridge controller.** Wires `AiClientModule` into `AppModule`, adds `POST /api/ai/chat` (SSE), `GET /api/ai/rag/search`, `GET /api/ai/models`. Adds the `OnApplicationShutdown` hook + `enableShutdownHooks()`. Adds `apf-ai-service` to `infra/local/dev.compose.yml`. Promotes ADR-0024 from `proposed` to `accepted` and updates `CLAUDE.md`'s ADR roll-up. 2. **PR (frontend chantier)** — chatbot widget on `portal-shell` consuming the SSE endpoint. 3. **PR (post-v1)** — proto-drift CI gate diffing the vendored `proto/apf-ai/` against the upstream tag. 4. **Coordinated amendment** — when the first production deployment is in scope, both repos record the same prod-hardening choice (signed envelope or mTLS) on the same date. --------- Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr> Reviewed-on: #195 |
||
|
|
40d4f7d290 |
chore(deps): update dependency cytoscape to v3.33.4 (#193)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [cytoscape](http://js.cytoscape.org) ([source](https://github.com/cytoscape/cytoscape.js)) | devDependencies | patch | [`3.33.3` -> `3.33.4`](https://renovatebot.com/diffs/npm/cytoscape/3.33.3/3.33.4) | --- ### Release Notes <details> <summary>cytoscape/cytoscape.js (cytoscape)</summary> ### [`v3.33.4`](https://github.com/cytoscape/cytoscape.js/releases/tag/v3.33.4) [Compare Source](https://github.com/cytoscape/cytoscape.js/compare/v3.33.3...v3.33.4) Release version v3.33.4 </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: #193 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> |
||
|
|
8bdfe0a273 |
chore(deps): update dependency ts-jest to v29.4.10 (#192)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [ts-jest](https://kulshekhar.github.io/ts-jest) ([source](https://github.com/kulshekhar/ts-jest)) | devDependencies | patch | [`29.4.9` -> `29.4.10`](https://renovatebot.com/diffs/npm/ts-jest/29.4.9/29.4.10) | --- ### Release Notes <details> <summary>kulshekhar/ts-jest (ts-jest)</summary> ### [`v29.4.10`](https://github.com/kulshekhar/ts-jest/blob/HEAD/CHANGELOG.md#29410-2026-05-18) [Compare Source](https://github.com/kulshekhar/ts-jest/compare/v29.4.9...v29.4.10) ##### Bug Fixes - pass `resolutionMode` to `ts.resolveModuleName` for hybrid module support ([b557a85](https://github.com/kulshekhar/ts-jest/commit/b557a85f85c3fd34523ec3a15293afbdc9dea83c)) - rebuild `Program` when consecutive compiles need different module kinds ([a82a2b3](https://github.com/kulshekhar/ts-jest/commit/a82a2b32c4987a5249fd5284283117dd2fa3be47)), closes [#​4774](https://github.com/kulshekhar/ts-jest/issues/4774) - respect tsconfig `moduleResolution` instead of forcing `Node10` ([1bffffc](https://github.com/kulshekhar/ts-jest/commit/1bffffc667557c173ae0c1f93dd436920775dac4)) - **transformer:** transpile `mjs` files from `node_modules` for CJS mode ([96d025d](https://github.com/kulshekhar/ts-jest/commit/96d025dd912ea2bceb18b67d2d509ada7a756d9d)) - **transformer:** use a consistent comparator in hoist-jest sortStatements ([8a8fd2f](https://github.com/kulshekhar/ts-jest/commit/8a8fd2fb8446655bba18367db9306a1089490e62)) </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/192 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> |
||
|
|
90504dd32b |
chore(deps): update dependency postcss to v8.5.15 (#191)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [postcss](https://postcss.org/) ([source](https://github.com/postcss/postcss)) | devDependencies | patch | [`8.5.14` -> `8.5.15`](https://renovatebot.com/diffs/npm/postcss/8.5.14/8.5.15) | --- ### Release Notes <details> <summary>postcss/postcss (postcss)</summary> ### [`v8.5.15`](https://github.com/postcss/postcss/blob/HEAD/CHANGELOG.md#8515) [Compare Source](https://github.com/postcss/postcss/compare/8.5.14...8.5.15) - Fixed declaration parsing performance (by [@​homanp](https://github.com/homanp)). </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: #191 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> |
||
|
|
8136695fa8 |
chore(deps): bump brace-expansion + ws overrides to clear audit (#190)
## Summary Clears the two moderate GHSA advisories that started failing `ci:audit`: - **`brace-expansion`** `>=5.0.0 <5.0.6` — DoS via large numeric range that bypasses the documented `max` protection ([GHSA-jxxr-4gwj-5jf2](https://github.com/advisories/GHSA-jxxr-4gwj-5jf2)). The existing override floor was at `5.0.5`; bumped one patch to `5.0.6`. - **`ws`** `>=8.0.0 <8.20.1` — uninitialized memory disclosure ([GHSA-58qx-3vcg-4xpx](https://github.com/advisories/GHSA-58qx-3vcg-4xpx)). No prior override; added one scoped to the 8.x advisory window only. Both are reached transitively through Nx; nothing in this repo's own dependency surface is vulnerable directly. ## What lands `package.json` (`pnpm.overrides` block): ```diff - "brace-expansion@<5.0.5": ">=5.0.5", + "brace-expansion@<5.0.6": ">=5.0.6", + "ws@>=8.0.0 <8.20.1": ">=8.20.1", ``` `pnpm-lock.yaml` reconciled with `pnpm install`. ## Notes for the reviewer - **Why the `ws` override is range-scoped, not a blanket `ws@<8.20.1`.** Lighthouse pulls `ws@7.5.10` via its own tree; the 7.x line sits entirely outside the advisory window (`>=8.0.0 <8.20.1`). A blanket `<8.20.1` override would force-bump that transitive across a major version boundary and risk Lighthouse breakage with no security gain. The range form `>=8.0.0 <8.20.1 → >=8.20.1` patches exactly the vulnerable consumers (`@module-federation/dts-plugin`, etc.) and leaves Lighthouse's pin untouched. - **Why an override and not waiting for Nx to bump.** Nx 22.7.2 is already on `main` (commits `bd94bb4` / `6b20c34`) but its sub-chain still resolves `ws@8.18.0` and `brace-expansion@5.0.5`. Upstream pickup will land eventually via Renovate; in the meantime the audit gate blocks CI on every PR. Overrides are the standard pnpm escape hatch for this exact situation. The pattern is already used in this file (`axios`, `ajv`, `esbuild`, `follow-redirects`, `ip-address`, `protobufjs`, `tmp`, `yaml`). - **Pruning policy.** Once Nx ships a release whose `pnpm-lock.yaml` resolves both packages at or above the patched versions on its own, both override entries can be removed. The convention in this file's existing entries is to leave overrides in place even when redundant (cheap insurance against silent regressions); pruning is a separate sweep, not part of this fix. - **No application code touched.** Both packages live deep in the Nx/Module Federation build tooling — `brace-expansion` inside `minimatch`'s glob expansion, `ws` inside Module Federation's HMR dev socket. Neither surfaces in the BFF or SPA runtime bundles. Build + test + lint were re-run across `portal-shell`, `portal-admin`, `portal-bff`, `shared-charts`, `shared-ui` as a sanity check; all green. ## Test plan - [x] `pnpm install` — lockfile reconciled, no extraneous package churn. - [x] `pnpm audit --audit-level=moderate` — "No known vulnerabilities found" (replaces the two-row failure that started this PR). - [x] `pnpm nx run-many -t build test lint -p portal-shell,portal-admin,portal-bff,shared-charts,shared-ui` — all green. Module Federation's HMR socket (the surface that *uses* `ws`) is exercised implicitly by every Angular build via `@nx/angular`'s webpack pipeline. - [ ] **Manual smoke** — `pnpm nx serve portal-shell` + `pnpm nx serve portal-admin`: dev servers come up, HMR reloads on a trivial edit, no warnings or stack traces about `ws` or `brace-expansion` resolution. ## What's next - Renovate will eventually pick up an Nx release whose own sub-chain ships `ws@>=8.20.1` and `brace-expansion@>=5.0.6` natively. At that point, the two override entries here are dead weight and can be pruned as a follow-up sweep alongside any other stale overrides. --------- Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr> Reviewed-on: #190 |
||
|
|
3e120da668 |
chore(deps): update typescript tooling to v8.59.4 (#188)
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.3` -> `8.59.4`](https://renovatebot.com/diffs/npm/@typescript-eslint%2futils/8.59.3/8.59.4) | | [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.3` -> `8.59.4`](https://renovatebot.com/diffs/npm/typescript-eslint/8.59.3/8.59.4) | --- ### Release Notes <details> <summary>typescript-eslint/typescript-eslint (@​typescript-eslint/utils)</summary> ### [`v8.59.4`](https://github.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/utils/CHANGELOG.md#8594-2026-05-18) [Compare Source](https://github.com/typescript-eslint/typescript-eslint/compare/v8.59.3...v8.59.4) 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.4) 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.4`](https://github.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/typescript-eslint/CHANGELOG.md#8594-2026-05-18) [Compare Source](https://github.com/typescript-eslint/typescript-eslint/compare/v8.59.3...v8.59.4) ##### 🩹 Fixes - **typescript-eslint:** export Compatible\* types from typescript-eslint to resolve pnpm TS error ([#​12340](https://github.com/typescript-eslint/typescript-eslint/pull/12340)) ##### ❤️ Thank You - Kirk Waiblinger [@​kirkwaiblinger](https://github.com/kirkwaiblinger) See [GitHub Releases](https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.4) 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: #188 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> |
||
|
|
5ef1e3d9bb |
chore(deps): lock file maintenance (#187)
This PR contains the following updates: | Update | Change | |---|---| | lockFileMaintenance | All locks refreshed | 🔧 This Pull Request updates lock files to use the latest dependency versions. --- ### Configuration 📅 **Schedule**: Branch creation - "before 4am on monday" (UTC), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, 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: #187 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> |
||
|
|
0e206d4f89 |
chore(deps): lock file maintenance (#186)
This PR contains the following updates: | Update | Change | |---|---| | lockFileMaintenance | All locks refreshed | 🔧 This Pull Request updates lock files to use the latest dependency versions. --- ### Configuration 📅 **Schedule**: Branch creation - "before 4am on monday" (UTC), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, 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: #186 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> |
||
|
|
93cf30679e |
fix(deps): update opentelemetry-js-contrib monorepo (#184)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@opentelemetry/instrumentation-document-load](https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/packages/instrumentation-document-load#readme) ([source](https://github.com/open-telemetry/opentelemetry-js-contrib/tree/HEAD/packages/instrumentation-document-load)) | dependencies | minor | [`^0.62.0` -> `^0.63.0`](https://renovatebot.com/diffs/npm/@opentelemetry%2finstrumentation-document-load/0.62.0/0.63.0) | | [@opentelemetry/instrumentation-express](https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/packages/instrumentation-express#readme) ([source](https://github.com/open-telemetry/opentelemetry-js-contrib/tree/HEAD/packages/instrumentation-express)) | dependencies | minor | [`^0.65.0` -> `^0.66.0`](https://renovatebot.com/diffs/npm/@opentelemetry%2finstrumentation-express/0.65.0/0.66.0) | | [@opentelemetry/instrumentation-ioredis](https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/packages/instrumentation-ioredis#readme) ([source](https://github.com/open-telemetry/opentelemetry-js-contrib/tree/HEAD/packages/instrumentation-ioredis)) | dependencies | minor | [`^0.65.0` -> `^0.66.0`](https://renovatebot.com/diffs/npm/@opentelemetry%2finstrumentation-ioredis/0.65.0/0.66.0) | | [@opentelemetry/instrumentation-nestjs-core](https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/packages/instrumentation-nestjs-core#readme) ([source](https://github.com/open-telemetry/opentelemetry-js-contrib/tree/HEAD/packages/instrumentation-nestjs-core)) | dependencies | minor | [`^0.63.0` -> `^0.64.0`](https://renovatebot.com/diffs/npm/@opentelemetry%2finstrumentation-nestjs-core/0.63.0/0.64.0) | | [@opentelemetry/instrumentation-pg](https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/packages/instrumentation-pg#readme) ([source](https://github.com/open-telemetry/opentelemetry-js-contrib/tree/HEAD/packages/instrumentation-pg)) | dependencies | minor | [`^0.69.0` -> `^0.70.0`](https://renovatebot.com/diffs/npm/@opentelemetry%2finstrumentation-pg/0.69.0/0.70.0) | | [@opentelemetry/instrumentation-pino](https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/packages/instrumentation-pino#readme) ([source](https://github.com/open-telemetry/opentelemetry-js-contrib/tree/HEAD/packages/instrumentation-pino)) | dependencies | minor | [`^0.63.0` -> `^0.64.0`](https://renovatebot.com/diffs/npm/@opentelemetry%2finstrumentation-pino/0.63.0/0.64.0) | | [@opentelemetry/instrumentation-user-interaction](https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/packages/instrumentation-user-interaction#readme) ([source](https://github.com/open-telemetry/opentelemetry-js-contrib/tree/HEAD/packages/instrumentation-user-interaction)) | dependencies | minor | [`^0.61.0` -> `^0.62.0`](https://renovatebot.com/diffs/npm/@opentelemetry%2finstrumentation-user-interaction/0.61.0/0.62.0) | --- ### Release Notes <details> <summary>open-telemetry/opentelemetry-js-contrib (@​opentelemetry/instrumentation-document-load)</summary> ### [`v0.63.0`](https://github.com/open-telemetry/opentelemetry-js-contrib/blob/HEAD/packages/instrumentation-document-load/CHANGELOG.md#0630-2026-05-13) [Compare Source](https://github.com/open-telemetry/opentelemetry-js-contrib/compare/b68fb6dcc0649631ebecab7bde81879486f74f0b...15ef7506553f631ea4181391e0c5725a56f0d082) ##### Features - **deps:** update deps matching '@​opentelemetry/\*' ([#​3523](https://github.com/open-telemetry/opentelemetry-js-contrib/issues/3523)) ([e26a90a](https://github.com/open-telemetry/opentelemetry-js-contrib/commit/e26a90af6e2fb4666b22388b770add7a60140c9b)) </details> <details> <summary>open-telemetry/opentelemetry-js-contrib (@​opentelemetry/instrumentation-express)</summary> ### [`v0.66.0`](https://github.com/open-telemetry/opentelemetry-js-contrib/blob/HEAD/packages/instrumentation-express/CHANGELOG.md#0660-2026-05-13) [Compare Source](https://github.com/open-telemetry/opentelemetry-js-contrib/compare/b68fb6dcc0649631ebecab7bde81879486f74f0b...15ef7506553f631ea4181391e0c5725a56f0d082) ##### Features - **deps:** update deps matching '@​opentelemetry/\*' ([#​3523](https://github.com/open-telemetry/opentelemetry-js-contrib/issues/3523)) ([e26a90a](https://github.com/open-telemetry/opentelemetry-js-contrib/commit/e26a90af6e2fb4666b22388b770add7a60140c9b)) ##### Dependencies - The following workspace dependencies were updated - devDependencies - [@​opentelemetry/contrib-test-utils](https://github.com/opentelemetry/contrib-test-utils) bumped from ^0.64.0 to ^0.65.0 </details> <details> <summary>open-telemetry/opentelemetry-js-contrib (@​opentelemetry/instrumentation-ioredis)</summary> ### [`v0.66.0`](https://github.com/open-telemetry/opentelemetry-js-contrib/blob/HEAD/packages/instrumentation-ioredis/CHANGELOG.md#0660-2026-05-13) [Compare Source](https://github.com/open-telemetry/opentelemetry-js-contrib/compare/b68fb6dcc0649631ebecab7bde81879486f74f0b...15ef7506553f631ea4181391e0c5725a56f0d082) ##### Features - **deps:** update deps matching '@​opentelemetry/\*' ([#​3523](https://github.com/open-telemetry/opentelemetry-js-contrib/issues/3523)) ([e26a90a](https://github.com/open-telemetry/opentelemetry-js-contrib/commit/e26a90af6e2fb4666b22388b770add7a60140c9b)) ##### Dependencies - The following workspace dependencies were updated - devDependencies - [@​opentelemetry/contrib-test-utils](https://github.com/opentelemetry/contrib-test-utils) bumped from ^0.64.0 to ^0.65.0 </details> <details> <summary>open-telemetry/opentelemetry-js-contrib (@​opentelemetry/instrumentation-nestjs-core)</summary> ### [`v0.64.0`](https://github.com/open-telemetry/opentelemetry-js-contrib/blob/HEAD/packages/instrumentation-nestjs-core/CHANGELOG.md#0640-2026-05-13) [Compare Source](https://github.com/open-telemetry/opentelemetry-js-contrib/compare/b68fb6dcc0649631ebecab7bde81879486f74f0b...15ef7506553f631ea4181391e0c5725a56f0d082) ##### Features - **deps:** update deps matching '@​opentelemetry/\*' ([#​3523](https://github.com/open-telemetry/opentelemetry-js-contrib/issues/3523)) ([e26a90a](https://github.com/open-telemetry/opentelemetry-js-contrib/commit/e26a90af6e2fb4666b22388b770add7a60140c9b)) </details> <details> <summary>open-telemetry/opentelemetry-js-contrib (@​opentelemetry/instrumentation-pg)</summary> ### [`v0.70.0`](https://github.com/open-telemetry/opentelemetry-js-contrib/blob/HEAD/packages/instrumentation-pg/CHANGELOG.md#0700-2026-05-13) [Compare Source](https://github.com/open-telemetry/opentelemetry-js-contrib/compare/b68fb6dcc0649631ebecab7bde81879486f74f0b...15ef7506553f631ea4181391e0c5725a56f0d082) ##### Features - **deps:** update deps matching '@​opentelemetry/\*' ([#​3523](https://github.com/open-telemetry/opentelemetry-js-contrib/issues/3523)) ([e26a90a](https://github.com/open-telemetry/opentelemetry-js-contrib/commit/e26a90af6e2fb4666b22388b770add7a60140c9b)) ##### Dependencies - The following workspace dependencies were updated - devDependencies - [@​opentelemetry/contrib-test-utils](https://github.com/opentelemetry/contrib-test-utils) bumped from ^0.64.0 to ^0.65.0 </details> <details> <summary>open-telemetry/opentelemetry-js-contrib (@​opentelemetry/instrumentation-pino)</summary> ### [`v0.64.0`](https://github.com/open-telemetry/opentelemetry-js-contrib/blob/HEAD/packages/instrumentation-pino/CHANGELOG.md#0640-2026-05-13) [Compare Source](https://github.com/open-telemetry/opentelemetry-js-contrib/compare/b68fb6dcc0649631ebecab7bde81879486f74f0b...15ef7506553f631ea4181391e0c5725a56f0d082) ##### Features - **deps:** update deps matching '@​opentelemetry/\*' ([#​3523](https://github.com/open-telemetry/opentelemetry-js-contrib/issues/3523)) ([e26a90a](https://github.com/open-telemetry/opentelemetry-js-contrib/commit/e26a90af6e2fb4666b22388b770add7a60140c9b)) ##### Dependencies - The following workspace dependencies were updated - devDependencies - [@​opentelemetry/contrib-test-utils](https://github.com/opentelemetry/contrib-test-utils) bumped from ^0.64.0 to ^0.65.0 </details> <details> <summary>open-telemetry/opentelemetry-js-contrib (@​opentelemetry/instrumentation-user-interaction)</summary> ### [`v0.62.0`](https://github.com/open-telemetry/opentelemetry-js-contrib/blob/HEAD/packages/instrumentation-user-interaction/CHANGELOG.md#0620-2026-05-13) [Compare Source](https://github.com/open-telemetry/opentelemetry-js-contrib/compare/b68fb6dcc0649631ebecab7bde81879486f74f0b...15ef7506553f631ea4181391e0c5725a56f0d082) ##### Features - **deps:** update deps matching '@​opentelemetry/\*' ([#​3523](https://github.com/open-telemetry/opentelemetry-js-contrib/issues/3523)) ([e26a90a](https://github.com/open-telemetry/opentelemetry-js-contrib/commit/e26a90af6e2fb4666b22388b770add7a60140c9b)) </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/184 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> |
||
|
|
ee59fd900c |
fix(deps): update opentelemetry-js monorepo (#183)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@opentelemetry/exporter-trace-otlp-http](https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/exporter-trace-otlp-http) ([source](https://github.com/open-telemetry/opentelemetry-js)) | dependencies | minor | [`^0.217.0` -> `^0.218.0`](https://renovatebot.com/diffs/npm/@opentelemetry%2fexporter-trace-otlp-http/0.217.0/0.218.0) | | [@opentelemetry/exporter-trace-otlp-proto](https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/exporter-trace-otlp-proto) ([source](https://github.com/open-telemetry/opentelemetry-js)) | dependencies | minor | [`^0.217.0` -> `^0.218.0`](https://renovatebot.com/diffs/npm/@opentelemetry%2fexporter-trace-otlp-proto/0.217.0/0.218.0) | | [@opentelemetry/instrumentation](https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-instrumentation) ([source](https://github.com/open-telemetry/opentelemetry-js)) | dependencies | minor | [`^0.217.0` -> `^0.218.0`](https://renovatebot.com/diffs/npm/@opentelemetry%2finstrumentation/0.217.0/0.218.0) | | [@opentelemetry/instrumentation-fetch](https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-instrumentation-fetch) ([source](https://github.com/open-telemetry/opentelemetry-js)) | dependencies | minor | [`^0.217.0` -> `^0.218.0`](https://renovatebot.com/diffs/npm/@opentelemetry%2finstrumentation-fetch/0.217.0/0.218.0) | | [@opentelemetry/instrumentation-http](https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-instrumentation-http) ([source](https://github.com/open-telemetry/opentelemetry-js)) | dependencies | minor | [`^0.217.0` -> `^0.218.0`](https://renovatebot.com/diffs/npm/@opentelemetry%2finstrumentation-http/0.217.0/0.218.0) | | [@opentelemetry/sdk-node](https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-sdk-node) ([source](https://github.com/open-telemetry/opentelemetry-js)) | dependencies | minor | [`^0.217.0` -> `^0.218.0`](https://renovatebot.com/diffs/npm/@opentelemetry%2fsdk-node/0.217.0/0.218.0) | | [@opentelemetry/semantic-conventions](https://github.com/open-telemetry/opentelemetry-js/tree/main/semantic-conventions) ([source](https://github.com/open-telemetry/opentelemetry-js)) | dependencies | minor | [`1.40.0` -> `1.41.1`](https://renovatebot.com/diffs/npm/@opentelemetry%2fsemantic-conventions/1.40.0/1.41.1) | --- ### Release Notes <details> <summary>open-telemetry/opentelemetry-js (@​opentelemetry/exporter-trace-otlp-http)</summary> ### [`v0.218.0`](https://github.com/open-telemetry/opentelemetry-js/compare/74cde1b674508ccc0ed2601ac43a80ff2d35114c...06ad0eaaecbd49f5ead871325f852cc2a3454079) [Compare Source](https://github.com/open-telemetry/opentelemetry-js/compare/74cde1b674508ccc0ed2601ac43a80ff2d35114c...06ad0eaaecbd49f5ead871325f852cc2a3454079) </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: #183 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> |
||
|
|
868cbb6747 |
chore(deps): update dependency @playwright/test to v1.60.0 (#182)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@playwright/test](https://playwright.dev) ([source](https://github.com/microsoft/playwright)) | devDependencies | minor | [`1.59.1` -> `1.60.0`](https://renovatebot.com/diffs/npm/@playwright%2ftest/1.59.1/1.60.0) | --- ### Release Notes <details> <summary>microsoft/playwright (@​playwright/test)</summary> ### [`v1.60.0`](https://github.com/microsoft/playwright/releases/tag/v1.60.0) [Compare Source](https://github.com/microsoft/playwright/compare/v1.59.1...v1.60.0) #### 🌐 HAR recording on Tracing [tracing.startHar()](https://playwright.dev/docs/api/class-tracing#tracing-start-har) / [tracing.stopHar()](https://playwright.dev/docs/api/class-tracing#tracing-stop-har) expose HAR recording as a first-class tracing API, with the same `content`, `mode` and `urlFilter` options as `recordHar`. The returned [Disposable](https://playwright.dev/docs/api/class-disposable) makes it easy to scope a recording with `await using`: ```js await using har = await context.tracing.startHar('trace.har'); const page = await context.newPage(); await page.goto('https://playwright.dev'); // HAR is finalized when `har` goes out of scope. ``` #### 🪝 Drop API New [locator.drop()](https://playwright.dev/docs/api/class-locator#locator-drop) simulates an external drag-and-drop of files or clipboard-like data onto an element. Playwright dispatches `dragenter`, `dragover`, and `drop` with a synthetic \[DataTransfer] in the page context — works cross-browser and is great for testing upload zones: ```js await page.locator('#dropzone').drop({ files: { name: 'note.txt', mimeType: 'text/plain', buffer: Buffer.from('hello') }, }); await page.locator('#dropzone').drop({ data: { 'text/plain': 'hello world', 'text/uri-list': 'https://example.com', }, }); ``` #### 🎯 Aria snapshots - [expect(page).toMatchAriaSnapshot()](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-match-aria-snapshot) now works on a [Page](https://playwright.dev/docs/api/class-page), in addition to a [Locator](https://playwright.dev/docs/api/class-locator) — equivalent to asserting against `page.locator('body')`. - New `boxes` option on [locator.ariaSnapshot()](https://playwright.dev/docs/api/class-locator#locator-aria-snapshot) / [page.ariaSnapshot()](https://playwright.dev/docs/api/class-page#page-aria-snapshot) appends each element's bounding box as `[box=x,y,width,height]`, useful for AI consumption. #### 🛑 test.abort() New [test.abort()](https://playwright.dev/docs/api/class-test#test-abort) aborts the currently running test from a fixture, hook, or route handler with an optional message. Use it when you have detected an unrecoverable misuse and want to fail the test right away: ```js test('does not publish to the shared page', async ({ page }) => { await page.route('**/publish', route => { test.abort('Tests must not publish to the shared page. Use the `clone` option.'); return route.abort(); }); // ... }); ``` #### New APIs ##### Browser, Context and Page - Event [browser.on('context')](https://playwright.dev/docs/api/class-browser#browser-event-context) — fired when a new context is created on the browser. - [BrowserContext](https://playwright.dev/docs/api/class-browsercontext) now mirrors lifecycle events from its pages: [browserContext.on('download')](https://playwright.dev/docs/api/class-browsercontext#browser-context-event-download), [browserContext.on('frameattached')](https://playwright.dev/docs/api/class-browsercontext#browser-context-event-frame-attached), [browserContext.on('framedetached')](https://playwright.dev/docs/api/class-browsercontext#browser-context-event-frame-detached), [browserContext.on('framenavigated')](https://playwright.dev/docs/api/class-browsercontext#browser-context-event-frame-navigated), [browserContext.on('pageclose')](https://playwright.dev/docs/api/class-browsercontext#browser-context-event-page-close), [browserContext.on('pageload')](https://playwright.dev/docs/api/class-browsercontext#browser-context-event-page-load). ##### Locators and Assertions - New option `description` in [page.getByRole()](https://playwright.dev/docs/api/class-page#page-get-by-role) / [locator.getByRole()](https://playwright.dev/docs/api/class-locator#locator-get-by-role) / [frame.getByRole()](https://playwright.dev/docs/api/class-frame#frame-get-by-role) / [frameLocator.getByRole()](https://playwright.dev/docs/api/class-framelocator#frame-locator-get-by-role) for matching the [accessible description](https://www.w3.org/TR/wai-aria-1.2/#dfn-accessible-description). - New option `pseudo` in [expect(locator).toHaveCSS()](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-have-css) reads computed styles from `::before` or `::after`. - New option `style` in [locator.highlight()](https://playwright.dev/docs/api/class-locator#locator-highlight) applies extra inline CSS to the highlight overlay, plus new [page.hideHighlight()](https://playwright.dev/docs/api/class-page#page-hide-highlight) to clear all highlights. ##### Network - [webSocketRoute.protocols()](https://playwright.dev/docs/api/class-websocketroute#web-socket-route-protocols) returns the WebSocket subprotocols requested by the page. - New option `noDefaults` in [browserType.connectOverCDP()](https://playwright.dev/docs/api/class-browsertype#browser-type-connect-over-cdp) disables Playwright's default overrides on the default context (download behavior, focus emulation, media emulation), so attaching to a user's daily-driver browser doesn't disturb its state. ##### Errors and Reporting - New [webError.location()](https://playwright.dev/docs/api/class-weberror#web-error-location) mirrors [consoleMessage.location()](https://playwright.dev/docs/api/class-consolemessage#console-message-location). - [consoleMessage.location()](https://playwright.dev/docs/api/class-consolemessage#console-message-location) now exposes `line` / `column` properties (`lineNumber` / `columnNumber` are deprecated). - New [testInfoError.errorContext](https://playwright.dev/docs/api/class-testinfoerror#test-info-error-error-context) surfaces additional diagnostic context, such as the aria snapshot of the receiver at the time of an `expect(...)` matcher failure. - [reporter.onError()](https://playwright.dev/docs/api/class-reporter#reporter-on-error) now receives a `workerInfo` argument with details about the worker for fixture teardown errors. ##### Test runner - New `{testFileBaseName}` token in [testProject.snapshotPathTemplate](https://playwright.dev/docs/api/class-testproject#test-project-snapshot-path-template) — file name without extension. - Test runner now errors when a config tries to override a non-option fixture, and rejects `workers: 0` or negative values. #### 🛠️ Other improvements - HTML reporter: - `npx playwright show-report` accepts `.zip` files directly — no need to unzip first. - Steps that contain attachments inside nested children show an indicator on the parent step. - The `repeatEachIndex` is shown in the test header when non-zero. - Trace Viewer adds a pretty-print toggle for JSON / form request and response bodies in the network details panel. #### Breaking Changes ⚠️ - Removed long-deprecated APIs: - `Locator.ariaRef()` — use the standard [locator.ariaSnapshot()](https://playwright.dev/docs/api/class-locator#locator-aria-snapshot) pipeline. - `handle` option on `BrowserContext.exposeBinding` and `Page.exposeBinding`. - `logger` option on `BrowserType.connect` and `BrowserType.connectOverCDP` — use [tracing](https://playwright.dev/docs/trace-viewer) instead. - Context options `videosPath` / `videoSize` — use `recordVideo` instead. #### Browser Versions - Chromium 148.0.7778.96 - Mozilla Firefox 150.0.2 - WebKit 26.4 This version was also tested against the following stable channels: - Google Chrome 147 - Microsoft Edge 147 </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: #182 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> |
||
|
|
e376ea1295 |
chore(deps): update dependency @oxc-project/runtime to ^0.131.0 (#181)
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.129.0` -> `^0.131.0`](https://renovatebot.com/diffs/npm/@oxc-project%2fruntime/0.129.0/0.131.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: #181 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> |
||
|
|
8a02ca86a2 |
fix(deps): update vitest to v4.1.6 (#180)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@vitest/coverage-v8](https://vitest.dev/guide/coverage) ([source](https://github.com/vitest-dev/vitest/tree/HEAD/packages/coverage-v8)) | devDependencies | patch | [`4.1.5` -> `4.1.6`](https://renovatebot.com/diffs/npm/@vitest%2fcoverage-v8/4.1.5/4.1.6) | | [@vitest/ui](https://vitest.dev/guide/ui) ([source](https://github.com/vitest-dev/vitest/tree/HEAD/packages/ui)) | devDependencies | patch | [`4.1.5` -> `4.1.6`](https://renovatebot.com/diffs/npm/@vitest%2fui/4.1.5/4.1.6) | | [vitest](https://vitest.dev) ([source](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest)) | devDependencies | patch | [`4.1.5` -> `4.1.6`](https://renovatebot.com/diffs/npm/vitest/4.1.5/4.1.6) | | [vitest](https://vitest.dev) ([source](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest)) | dependencies | patch | [`4.1.5` -> `4.1.6`](https://renovatebot.com/diffs/npm/vitest/4.1.5/4.1.6) | --- ### Release Notes <details> <summary>vitest-dev/vitest (@​vitest/coverage-v8)</summary> ### [`v4.1.6`](https://github.com/vitest-dev/vitest/releases/tag/v4.1.6) [Compare Source](https://github.com/vitest-dev/vitest/compare/v4.1.5...v4.1.6) ##### 🐞 Bug Fixes - **browser**: Provide project reference in `ToMatchScreenshotResolvePath` - by [@​macarie](https://github.com/macarie) and [@​sheremet-va](https://github.com/sheremet-va) in https://github.com/vitest-dev/vitest/issues/10138 [<samp>(31882)</samp>](https://github.com/vitest-dev/vitest/commit/31882607c) - Global `sequence.concurrent: true` with top-level `test(..., { concurrent: false })` + depreacte `sequential` test API and options - by [@​hi-ogawa](https://github.com/hi-ogawa), **Codex** and [@​sheremet-va](https://github.com/sheremet-va) in https://github.com/vitest-dev/vitest/issues/10196 [<samp>(2847d)</samp>](https://github.com/vitest-dev/vitest/commit/2847dfa2a) - **browser**: Simplify orchestrator otel carrier - by [@​hi-ogawa](https://github.com/hi-ogawa) in https://github.com/vitest-dev/vitest/issues/10285 [<samp>(18af9)</samp>](https://github.com/vitest-dev/vitest/commit/18af98cee) ##### 🏎 Performance - Stringify diff objects only once - by [@​sheremet-va](https://github.com/sheremet-va) in https://github.com/vitest-dev/vitest/issues/10276 [<samp>(9f7b1)</samp>](https://github.com/vitest-dev/vitest/commit/9f7b1528c) ##### [View changes on GitHub](https://github.com/vitest-dev/vitest/compare/v4.1.5...v4.1.6) </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/180 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> |
||
|
|
bd94bb4ffe |
fix(deps): update nx to v22.7.2 (#179)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@nx/devkit](https://nx.dev) ([source](https://github.com/nrwl/nx/tree/HEAD/packages/devkit)) | devDependencies | patch | [`22.7.1` -> `22.7.2`](https://renovatebot.com/diffs/npm/@nx%2fdevkit/22.7.1/22.7.2) | | [@nx/eslint-plugin](https://nx.dev) ([source](https://github.com/nrwl/nx/tree/HEAD/packages/eslint-plugin)) | devDependencies | patch | [`22.7.1` -> `22.7.2`](https://renovatebot.com/diffs/npm/@nx%2feslint-plugin/22.7.1/22.7.2) | | [@nx/jest](https://nx.dev) ([source](https://github.com/nrwl/nx/tree/HEAD/packages/jest)) | devDependencies | patch | [`22.7.1` -> `22.7.2`](https://renovatebot.com/diffs/npm/@nx%2fjest/22.7.1/22.7.2) | | [@nx/js](https://nx.dev) ([source](https://github.com/nrwl/nx/tree/HEAD/packages/js)) | devDependencies | patch | [`22.7.1` -> `22.7.2`](https://renovatebot.com/diffs/npm/@nx%2fjs/22.7.1/22.7.2) | | [@nx/node](https://nx.dev) ([source](https://github.com/nrwl/nx/tree/HEAD/packages/node)) | devDependencies | patch | [`22.7.1` -> `22.7.2`](https://renovatebot.com/diffs/npm/@nx%2fnode/22.7.1/22.7.2) | | [@nx/playwright](https://nx.dev) ([source](https://github.com/nrwl/nx/tree/HEAD/packages/playwright)) | devDependencies | patch | [`22.7.1` -> `22.7.2`](https://renovatebot.com/diffs/npm/@nx%2fplaywright/22.7.1/22.7.2) | | [@nx/vite](https://nx.dev) ([source](https://github.com/nrwl/nx/tree/HEAD/packages/vite)) | dependencies | patch | [`22.7.1` -> `22.7.2`](https://renovatebot.com/diffs/npm/@nx%2fvite/22.7.1/22.7.2) | | [@nx/vitest](https://nx.dev) ([source](https://github.com/nrwl/nx/tree/HEAD/packages/vitest)) | devDependencies | patch | [`22.7.1` -> `22.7.2`](https://renovatebot.com/diffs/npm/@nx%2fvitest/22.7.1/22.7.2) | | [@nx/web](https://nx.dev) ([source](https://github.com/nrwl/nx/tree/HEAD/packages/web)) | devDependencies | patch | [`22.7.1` -> `22.7.2`](https://renovatebot.com/diffs/npm/@nx%2fweb/22.7.1/22.7.2) | | [@nx/webpack](https://nx.dev) ([source](https://github.com/nrwl/nx/tree/HEAD/packages/webpack)) | devDependencies | patch | [`22.7.1` -> `22.7.2`](https://renovatebot.com/diffs/npm/@nx%2fwebpack/22.7.1/22.7.2) | | [nx](https://nx.dev) ([source](https://github.com/nrwl/nx/tree/HEAD/packages/nx)) | devDependencies | patch | [`22.7.1` -> `22.7.2`](https://renovatebot.com/diffs/npm/nx/22.7.1/22.7.2) | --- ### Release Notes <details> <summary>nrwl/nx (@​nx/devkit)</summary> ### [`v22.7.2`](https://github.com/nrwl/nx/releases/tag/22.7.2) [Compare Source](https://github.com/nrwl/nx/compare/22.7.1...22.7.2) ##### 22.7.2 (2026-05-14) ##### 🚀 Features - **gradle:** stream batch task results to nx as they finish ([#​35487](https://github.com/nrwl/nx/pull/35487)) - **nx-dev:** track docs analytics for code copy, LLM prompt, YouTube ([#​35526](https://github.com/nrwl/nx/pull/35526)) - **testing:** add migration for Jest 30 snapshot guide link ([#​35629](https://github.com/nrwl/nx/pull/35629)) ##### 🩹 Fixes - **angular:** disable vitest watch by default ([#​35493](https://github.com/nrwl/nx/pull/35493)) - **angular-rspack:** keep root-scoped assets out of per-locale i18n emit ([#​35621](https://github.com/nrwl/nx/pull/35621)) - **bundling:** include tsconfig solution input for rollup ([#​35476](https://github.com/nrwl/nx/pull/35476)) - **bundling:** include tsconfig solution input for webpack ([#​35477](https://github.com/nrwl/nx/pull/35477), [#​35476](https://github.com/nrwl/nx/issues/35476)) - **core:** bump axios to 1.16.0 for all packages ([#​35568](https://github.com/nrwl/nx/pull/35568)) - **core:** add provenance check in nx console status path ([#​35485](https://github.com/nrwl/nx/pull/35485)) - **core:** remove access control header from graph app ([#​35494](https://github.com/nrwl/nx/pull/35494)) - **core:** ensure verbose logs go to stderr and daemon logs are properly decorated ([#​34358](https://github.com/nrwl/nx/pull/34358)) - **core:** show flaky-task count in run summary ([#​35491](https://github.com/nrwl/nx/pull/35491)) - **core:** unique telemetry user\_id; expose workspace\_id dimension ([#​35553](https://github.com/nrwl/nx/pull/35553)) - **core:** update minimatch to 10.2.5 ([#​35569](https://github.com/nrwl/nx/pull/35569), [#​34660](https://github.com/nrwl/nx/issues/34660)) - **core:** restore use-legacy-versioning shim for [@​nx/js](https://github.com/nx/js)[@​21](https://github.com/21) ensurePackage path ([#​35574](https://github.com/nrwl/nx/pull/35574)) - **core:** isolate NX\_PARALLEL env var in parallel-related specs ([#​35579](https://github.com/nrwl/nx/pull/35579)) - **core:** skip handleimport miss path when nx key packages are absent ([#​35596](https://github.com/nrwl/nx/pull/35596)) - **core:** use gethostuuid(3) instead of ioreg on macOS ([#​35599](https://github.com/nrwl/nx/pull/35599)) - **core:** isolate cache env vars in splitArgs spec ([#​35584](https://github.com/nrwl/nx/pull/35584)) - **core:** enable node's native v8 compile cache support ([#​35415](https://github.com/nrwl/nx/pull/35415), [#​20454](https://github.com/nrwl/nx/issues/20454)) - **core:** support skipped batch tasks end-to-end and fix TUI double logs ([#​35617](https://github.com/nrwl/nx/pull/35617)) - **core:** keep TUI task selection on the in-progress section ([#​35640](https://github.com/nrwl/nx/pull/35640)) - **core:** allow `nx mcp` to run outside of an Nx workspace ([#​35655](https://github.com/nrwl/nx/pull/35655)) - **core:** cast perf entries to PerformanceMeasure for detail access ([43c0c821ba](https://github.com/nrwl/nx/commit/43c0c821ba)) - **devkit:** exclude dist from jest module path scan ([#​35615](https://github.com/nrwl/nx/pull/35615)) - **devkit:** expand @​nx/devkit/internal re-exports for cherry-picked v23 deep-import migration ([#​35541](https://github.com/nrwl/nx/issues/35541)) - **dotnet:** correct output paths for Web SDK and centralized dist setups ([#​35398](https://github.com/nrwl/nx/pull/35398)) - **gradle:** exclude batch-runner from jest haste-map crawl ([#​35501](https://github.com/nrwl/nx/pull/35501)) - **gradle:** exclude project-graph from jest module path scan ([#​35609](https://github.com/nrwl/nx/pull/35609)) - **gradle:** support Windows file paths ([#​35184](https://github.com/nrwl/nx/pull/35184), [#​34987](https://github.com/nrwl/nx/issues/34987)) - **js:** strip glob from inferred outputs before resolving as path ([#​35463](https://github.com/nrwl/nx/pull/35463), [#​35452](https://github.com/nrwl/nx/issues/35452)) - **js:** reference vitest.config in eslint dep-checks for vitest libs ([#​35460](https://github.com/nrwl/nx/pull/35460), [#​33670](https://github.com/nrwl/nx/issues/33670), [#​35450](https://github.com/nrwl/nx/issues/35450)) - **js:** include transitive workspace deps in pruned pnpm lockfile ([#​35532](https://github.com/nrwl/nx/pull/35532), [#​35347](https://github.com/nrwl/nx/issues/35347), [#​34655](https://github.com/nrwl/nx/issues/34655)) - **linter:** prevent ENOENT crash in getRelativeImportPath for unresolvable paths ([#​35007](https://github.com/nrwl/nx/pull/35007), [#​13872](https://github.com/nrwl/nx/issues/13872), [#​34066](https://github.com/nrwl/nx/issues/34066), [#​30491](https://github.com/nrwl/nx/issues/30491), [#​16716](https://github.com/nrwl/nx/issues/16716), [#​35006](https://github.com/nrwl/nx/issues/35006), [#​21889](https://github.com/nrwl/nx/issues/21889), [#​32190](https://github.com/nrwl/nx/issues/32190)) - **maven:** skip attached artifacts that fail to materialize in batch record ([#​35473](https://github.com/nrwl/nx/pull/35473)) - **maven:** serialize Maven 4 build state recording ([#​35555](https://github.com/nrwl/nx/pull/35555)) - **maven:** widen runCLI timeout for --no-batch maven.test.ts cases ([#​35589](https://github.com/nrwl/nx/pull/35589)) - **nx-dev:** document nested CLI subcommands beyond two levels ([#​35519](https://github.com/nrwl/nx/pull/35519)) - **nx-dev:** short-circuit bot probes in framer rewrite edge function ([#​35527](https://github.com/nrwl/nx/pull/35527)) - **react:** withSvgr migration preserves other properties ([#​35484](https://github.com/nrwl/nx/pull/35484)) - **repo:** clear NX\_INVOCATION\_ROOT\_PID in run-native-target to avoid recursion false-positive ([443dee0b22](https://github.com/nrwl/nx/commit/443dee0b22)) - **repo:** revert deep-import rewrites that targeted v23-only @​nx/devkit/internal entry ([ac8187963d](https://github.com/nrwl/nx/commit/ac8187963d)) - **repo:** unblock 22.7.x cargo tests and nx-build e2e ([#​34285](https://github.com/nrwl/nx/issues/34285)) - **repo:** expand "..." spread token in graph typecheck inputs ([#​34285](https://github.com/nrwl/nx/issues/34285), [#​35458](https://github.com/nrwl/nx/issues/35458)) - **testing:** pin jest to ~30.3.0 to avoid jest-runtime 30.4 RN incompat ([#​35618](https://github.com/nrwl/nx/pull/35618)) - **testing:** handle absolute cypress screenshotsFolder/videosFolder paths ([#​35624](https://github.com/nrwl/nx/pull/35624)) - **testing:** exclude dist and out-tsc from default jest module path scan ([#​35619](https://github.com/nrwl/nx/pull/35619)) - **testing:** update remaining snapshot guide links missed by migration ([cd350c1140](https://github.com/nrwl/nx/commit/cd350c1140)) ##### ❤️ Thank You - Adam Keenan [@​adamk33n3r](https://github.com/adamk33n3r) - AgentEnder [@​AgentEnder](https://github.com/AgentEnder) - beeman - Claude - Craigory Coppola [@​AgentEnder](https://github.com/AgentEnder) - FrozenPandaz [@​FrozenPandaz](https://github.com/FrozenPandaz) - Jack Hsu [@​jaysoo](https://github.com/jaysoo) - Jason Jean [@​FrozenPandaz](https://github.com/FrozenPandaz) - Leosvel Pérez Espinosa [@​leosvelperez](https://github.com/leosvelperez) - Max Kless - MaxKless [@​MaxKless](https://github.com/MaxKless) - Optischa [@​Optischa](https://github.com/Optischa) - Sharon Lougheed </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled because a matching PR was automerged previously. ♻ **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/179 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> |
||
|
|
6b20c3413b |
fix(deps): update nx to v22.7.2 (#178)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@nx/angular](https://nx.dev) ([source](https://github.com/nrwl/nx/tree/HEAD/packages/angular)) | devDependencies | patch | [`22.7.1` -> `22.7.2`](https://renovatebot.com/diffs/npm/@nx%2fangular/22.7.1/22.7.2) | | [@nx/devkit](https://nx.dev) ([source](https://github.com/nrwl/nx/tree/HEAD/packages/devkit)) | devDependencies | patch | [`22.7.1` -> `22.7.2`](https://renovatebot.com/diffs/npm/@nx%2fdevkit/22.7.1/22.7.2) | | [@nx/eslint](https://nx.dev) ([source](https://github.com/nrwl/nx/tree/HEAD/packages/eslint)) | devDependencies | patch | [`22.7.1` -> `22.7.2`](https://renovatebot.com/diffs/npm/@nx%2feslint/22.7.1/22.7.2) | | [@nx/eslint-plugin](https://nx.dev) ([source](https://github.com/nrwl/nx/tree/HEAD/packages/eslint-plugin)) | devDependencies | patch | [`22.7.1` -> `22.7.2`](https://renovatebot.com/diffs/npm/@nx%2feslint-plugin/22.7.1/22.7.2) | | [@nx/jest](https://nx.dev) ([source](https://github.com/nrwl/nx/tree/HEAD/packages/jest)) | devDependencies | patch | [`22.7.1` -> `22.7.2`](https://renovatebot.com/diffs/npm/@nx%2fjest/22.7.1/22.7.2) | | [@nx/js](https://nx.dev) ([source](https://github.com/nrwl/nx/tree/HEAD/packages/js)) | devDependencies | patch | [`22.7.1` -> `22.7.2`](https://renovatebot.com/diffs/npm/@nx%2fjs/22.7.1/22.7.2) | | [@nx/nest](https://nx.dev) ([source](https://github.com/nrwl/nx/tree/HEAD/packages/nest)) | devDependencies | patch | [`22.7.1` -> `22.7.2`](https://renovatebot.com/diffs/npm/@nx%2fnest/22.7.1/22.7.2) | | [@nx/node](https://nx.dev) ([source](https://github.com/nrwl/nx/tree/HEAD/packages/node)) | devDependencies | patch | [`22.7.1` -> `22.7.2`](https://renovatebot.com/diffs/npm/@nx%2fnode/22.7.1/22.7.2) | | [@nx/playwright](https://nx.dev) ([source](https://github.com/nrwl/nx/tree/HEAD/packages/playwright)) | devDependencies | patch | [`22.7.1` -> `22.7.2`](https://renovatebot.com/diffs/npm/@nx%2fplaywright/22.7.1/22.7.2) | | [@nx/vite](https://nx.dev) ([source](https://github.com/nrwl/nx/tree/HEAD/packages/vite)) | devDependencies | patch | [`22.7.1` -> `22.7.2`](https://renovatebot.com/diffs/npm/@nx%2fvite/22.7.1/22.7.2) | | [@nx/vite](https://nx.dev) ([source](https://github.com/nrwl/nx/tree/HEAD/packages/vite)) | dependencies | patch | [`22.7.1` -> `22.7.2`](https://renovatebot.com/diffs/npm/@nx%2fvite/22.7.1/22.7.2) | | [@nx/vitest](https://nx.dev) ([source](https://github.com/nrwl/nx/tree/HEAD/packages/vitest)) | devDependencies | patch | [`22.7.1` -> `22.7.2`](https://renovatebot.com/diffs/npm/@nx%2fvitest/22.7.1/22.7.2) | | [@nx/web](https://nx.dev) ([source](https://github.com/nrwl/nx/tree/HEAD/packages/web)) | devDependencies | patch | [`22.7.1` -> `22.7.2`](https://renovatebot.com/diffs/npm/@nx%2fweb/22.7.1/22.7.2) | | [@nx/webpack](https://nx.dev) ([source](https://github.com/nrwl/nx/tree/HEAD/packages/webpack)) | devDependencies | patch | [`22.7.1` -> `22.7.2`](https://renovatebot.com/diffs/npm/@nx%2fwebpack/22.7.1/22.7.2) | | [nx](https://nx.dev) ([source](https://github.com/nrwl/nx/tree/HEAD/packages/nx)) | devDependencies | patch | [`22.7.1` -> `22.7.2`](https://renovatebot.com/diffs/npm/nx/22.7.1/22.7.2) | --- ### Release Notes <details> <summary>nrwl/nx (@​nx/angular)</summary> ### [`v22.7.2`](https://github.com/nrwl/nx/releases/tag/22.7.2) [Compare Source](https://github.com/nrwl/nx/compare/22.7.1...22.7.2) ##### 22.7.2 (2026-05-14) ##### 🚀 Features - **gradle:** stream batch task results to nx as they finish ([#​35487](https://github.com/nrwl/nx/pull/35487)) - **nx-dev:** track docs analytics for code copy, LLM prompt, YouTube ([#​35526](https://github.com/nrwl/nx/pull/35526)) - **testing:** add migration for Jest 30 snapshot guide link ([#​35629](https://github.com/nrwl/nx/pull/35629)) ##### 🩹 Fixes - **angular:** disable vitest watch by default ([#​35493](https://github.com/nrwl/nx/pull/35493)) - **angular-rspack:** keep root-scoped assets out of per-locale i18n emit ([#​35621](https://github.com/nrwl/nx/pull/35621)) - **bundling:** include tsconfig solution input for rollup ([#​35476](https://github.com/nrwl/nx/pull/35476)) - **bundling:** include tsconfig solution input for webpack ([#​35477](https://github.com/nrwl/nx/pull/35477), [#​35476](https://github.com/nrwl/nx/issues/35476)) - **core:** bump axios to 1.16.0 for all packages ([#​35568](https://github.com/nrwl/nx/pull/35568)) - **core:** add provenance check in nx console status path ([#​35485](https://github.com/nrwl/nx/pull/35485)) - **core:** remove access control header from graph app ([#​35494](https://github.com/nrwl/nx/pull/35494)) - **core:** ensure verbose logs go to stderr and daemon logs are properly decorated ([#​34358](https://github.com/nrwl/nx/pull/34358)) - **core:** show flaky-task count in run summary ([#​35491](https://github.com/nrwl/nx/pull/35491)) - **core:** unique telemetry user\_id; expose workspace\_id dimension ([#​35553](https://github.com/nrwl/nx/pull/35553)) - **core:** update minimatch to 10.2.5 ([#​35569](https://github.com/nrwl/nx/pull/35569), [#​34660](https://github.com/nrwl/nx/issues/34660)) - **core:** restore use-legacy-versioning shim for [@​nx/js](https://github.com/nx/js)[@​21](https://github.com/21) ensurePackage path ([#​35574](https://github.com/nrwl/nx/pull/35574)) - **core:** isolate NX\_PARALLEL env var in parallel-related specs ([#​35579](https://github.com/nrwl/nx/pull/35579)) - **core:** skip handleimport miss path when nx key packages are absent ([#​35596](https://github.com/nrwl/nx/pull/35596)) - **core:** use gethostuuid(3) instead of ioreg on macOS ([#​35599](https://github.com/nrwl/nx/pull/35599)) - **core:** isolate cache env vars in splitArgs spec ([#​35584](https://github.com/nrwl/nx/pull/35584)) - **core:** enable node's native v8 compile cache support ([#​35415](https://github.com/nrwl/nx/pull/35415), [#​20454](https://github.com/nrwl/nx/issues/20454)) - **core:** support skipped batch tasks end-to-end and fix TUI double logs ([#​35617](https://github.com/nrwl/nx/pull/35617)) - **core:** keep TUI task selection on the in-progress section ([#​35640](https://github.com/nrwl/nx/pull/35640)) - **core:** allow `nx mcp` to run outside of an Nx workspace ([#​35655](https://github.com/nrwl/nx/pull/35655)) - **core:** cast perf entries to PerformanceMeasure for detail access ([43c0c821ba](https://github.com/nrwl/nx/commit/43c0c821ba)) - **devkit:** exclude dist from jest module path scan ([#​35615](https://github.com/nrwl/nx/pull/35615)) - **devkit:** expand @​nx/devkit/internal re-exports for cherry-picked v23 deep-import migration ([#​35541](https://github.com/nrwl/nx/issues/35541)) - **dotnet:** correct output paths for Web SDK and centralized dist setups ([#​35398](https://github.com/nrwl/nx/pull/35398)) - **gradle:** exclude batch-runner from jest haste-map crawl ([#​35501](https://github.com/nrwl/nx/pull/35501)) - **gradle:** exclude project-graph from jest module path scan ([#​35609](https://github.com/nrwl/nx/pull/35609)) - **gradle:** support Windows file paths ([#​35184](https://github.com/nrwl/nx/pull/35184), [#​34987](https://github.com/nrwl/nx/issues/34987)) - **js:** strip glob from inferred outputs before resolving as path ([#​35463](https://github.com/nrwl/nx/pull/35463), [#​35452](https://github.com/nrwl/nx/issues/35452)) - **js:** reference vitest.config in eslint dep-checks for vitest libs ([#​35460](https://github.com/nrwl/nx/pull/35460), [#​33670](https://github.com/nrwl/nx/issues/33670), [#​35450](https://github.com/nrwl/nx/issues/35450)) - **js:** include transitive workspace deps in pruned pnpm lockfile ([#​35532](https://github.com/nrwl/nx/pull/35532), [#​35347](https://github.com/nrwl/nx/issues/35347), [#​34655](https://github.com/nrwl/nx/issues/34655)) - **linter:** prevent ENOENT crash in getRelativeImportPath for unresolvable paths ([#​35007](https://github.com/nrwl/nx/pull/35007), [#​13872](https://github.com/nrwl/nx/issues/13872), [#​34066](https://github.com/nrwl/nx/issues/34066), [#​30491](https://github.com/nrwl/nx/issues/30491), [#​16716](https://github.com/nrwl/nx/issues/16716), [#​35006](https://github.com/nrwl/nx/issues/35006), [#​21889](https://github.com/nrwl/nx/issues/21889), [#​32190](https://github.com/nrwl/nx/issues/32190)) - **maven:** skip attached artifacts that fail to materialize in batch record ([#​35473](https://github.com/nrwl/nx/pull/35473)) - **maven:** serialize Maven 4 build state recording ([#​35555](https://github.com/nrwl/nx/pull/35555)) - **maven:** widen runCLI timeout for --no-batch maven.test.ts cases ([#​35589](https://github.com/nrwl/nx/pull/35589)) - **nx-dev:** document nested CLI subcommands beyond two levels ([#​35519](https://github.com/nrwl/nx/pull/35519)) - **nx-dev:** short-circuit bot probes in framer rewrite edge function ([#​35527](https://github.com/nrwl/nx/pull/35527)) - **react:** withSvgr migration preserves other properties ([#​35484](https://github.com/nrwl/nx/pull/35484)) - **repo:** clear NX\_INVOCATION\_ROOT\_PID in run-native-target to avoid recursion false-positive ([443dee0b22](https://github.com/nrwl/nx/commit/443dee0b22)) - **repo:** revert deep-import rewrites that targeted v23-only @​nx/devkit/internal entry ([ac8187963d](https://github.com/nrwl/nx/commit/ac8187963d)) - **repo:** unblock 22.7.x cargo tests and nx-build e2e ([#​34285](https://github.com/nrwl/nx/issues/34285)) - **repo:** expand "..." spread token in graph typecheck inputs ([#​34285](https://github.com/nrwl/nx/issues/34285), [#​35458](https://github.com/nrwl/nx/issues/35458)) - **testing:** pin jest to ~30.3.0 to avoid jest-runtime 30.4 RN incompat ([#​35618](https://github.com/nrwl/nx/pull/35618)) - **testing:** handle absolute cypress screenshotsFolder/videosFolder paths ([#​35624](https://github.com/nrwl/nx/pull/35624)) - **testing:** exclude dist and out-tsc from default jest module path scan ([#​35619](https://github.com/nrwl/nx/pull/35619)) - **testing:** update remaining snapshot guide links missed by migration ([cd350c1140](https://github.com/nrwl/nx/commit/cd350c1140)) ##### ❤️ Thank You - Adam Keenan [@​adamk33n3r](https://github.com/adamk33n3r) - AgentEnder [@​AgentEnder](https://github.com/AgentEnder) - beeman - Claude - Craigory Coppola [@​AgentEnder](https://github.com/AgentEnder) - FrozenPandaz [@​FrozenPandaz](https://github.com/FrozenPandaz) - Jack Hsu [@​jaysoo](https://github.com/jaysoo) - Jason Jean [@​FrozenPandaz](https://github.com/FrozenPandaz) - Leosvel Pérez Espinosa [@​leosvelperez](https://github.com/leosvelperez) - Max Kless - MaxKless [@​MaxKless](https://github.com/MaxKless) - Optischa [@​Optischa](https://github.com/Optischa) - Sharon Lougheed </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/178 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> |
||
|
|
eb8b65c7bc |
feat(shared-charts): foundations + bar / donut / stacked-bar components (#171)
## Summary Implementation of [ADR-0023](docs/decisions/0023-charts-d3-observable-plot.md) — the foundations of the workspace's chart library. PR 2 of the chantier: | PR | Périmètre | | --- | --- | | PR 1 ✅ | ADR-0023 — decision + a11y contract + bundle plan. | | **PR 2 (this one)** | `libs/shared/charts/` foundations + `<lib-bar-chart>`, `<lib-donut-chart>`, `<lib-stacked-bar-chart>`. | | PR 3 | Integration on the `/audit` page — daily-volume bar + outcome-breakdown donut + event-type-over-time stacked bar. | ## What lands ### Workspace deps ``` d3 — top-level toolkit, types via @types/d3 d3-shape — used directly by <lib-donut-chart> d3-scale-chromatic — colour-blind-safe palette source @observablehq/plot — declarative layer over D3, used by bar + stacked-bar ``` All four (+ matching `@types/*`) land in the workspace root `devDependencies`. Tree-shaken at build time per ADR-0023's bundle plan. ### New lib `libs/shared/charts/` ``` libs/shared/charts/src/lib/ ├── _internal/ ← single source of truth for the a11y contract │ ├── a11y.ts ← chartId, findChartSvg, injectSvgTitleDesc, prefersReducedMotion, resolveTheme │ ├── chart-envelope.scss ← shared figure / caption / fallback / dark-mode rules │ ├── chart-types.ts ← `ChartBaseInputs<T>` extended by each component │ └── palette.ts ← Viridis / Cividis (sequential) + ColorBrewer Set2 (categorical) ├── bar-chart/ ← Plot.barY ├── donut-chart/ ← raw d3-shape (pie + arc); Plot has no donut mark └── stacked-bar-chart/ ← Plot.barY with `fill: <seriesKey>` (auto-stacked, legend on) ``` ### A11y contract baked in for v1 Per ADR-0023's six commitments, every chart component produces (and unit-tests for): 1. `<figure role="img" aria-labelledby aria-describedby>` wrapping the SVG. 2. SVG `<title>` + `<desc>` as the **first two children** — injected post-render via `injectSvgTitleDesc` because Plot doesn't emit them itself. `findChartSvg` handles both Plot output shapes (bare SVG, or `<figure>` wrapping a legend + SVG for `legend: true` configs). 3. A `<details>` disclosure with a `<table>` rendering every data point — the keyboard-navigable / screen-reader-friendly fallback for non-visual users. 4. Palette from `_internal/palette.ts` only — Viridis / Cividis for sequential, ColorBrewer Set2 for categorical. Both colour-blind-safe. 5. AA-contrast axis text via `:where(.dark)` flips in `_internal/chart-envelope.scss`. 6. `prefers-reduced-motion` → `data-no-transitions` marker on the SVG, CSS strips animations + transitions. A custom ESLint rule in [`libs/shared/charts/eslint.config.mjs`](libs/shared/charts/eslint.config.mjs) bans direct imports of `d3-scale-chromatic` outside `_internal/palette.ts` so a future contributor can't bypass the colour-blind-safe contract. ### Component contract Every `<lib-*-chart>` exposes the same Signal-based shape per ADR-0023: ```ts [data]: readonly T[]; [caption]: string; [description]: string; [ariaLabel]: string; [colorScheme]?: 'sequential' | 'categorical'; // + chart-specific keys (xKey, yKey, categoryKey, valueKey, seriesKey, …) ``` Re-renders triggered by Angular's `effect()` on input changes; the previous SVG is `replaceChildren`-d out so there's no DOM accumulation across data updates. ## Notes for the reviewer - **Why three SCSS files importing one shared envelope?** Extracted at the third consumer per CLAUDE.md's "three similar lines is better than a premature abstraction" rule — bar + donut + stacked-bar share ~70 LOC of figure / caption / fallback / dark-mode chrome. `_internal/chart-envelope.scss` is the consolidation; each chart's `.scss` is now 4-20 LOC of chart-specific tweaks. - **Why is `<lib-donut-chart>` raw D3 rather than Plot?** Plot's design philosophy explicitly excludes pie/donut marks ("a bar chart is almost always more legible"). The audit-log outcome breakdown reads naturally as a donut (the centre carries the total). Raw `d3-shape` is the lower-level fallback ADR-0023 reserves precisely for this kind of case; the component's API is identical to the Plot-backed siblings. - **Why does the donut also stamp per-slice `<title>`?** Belt-and-suspenders. The top-level SVG `<title>` reads the caption; per-slice `<title>` reads "category: value" on hover (the SVG-native tooltip convention) for keyboard / screen-reader users who land on a specific slice. - **Why no `pnpm.overrides` adjustment for `d3-*` transitives?** None of the new deps brought a vulnerability in this install. The `pnpm audit --audit-level=moderate` gate from #161 stays green. - **What's deliberately deferred to PR 3?** The `/audit`-page integration — data aggregation from the current page (`AdminAuditPage` rows already loaded), the actual `<lib-*-chart>` placements above the existing table, the i18n strings for the captions / descriptions / aria-labels. No mock SAMPLE data shipped in this PR — every test uses local fixtures so the lib stays decoupled from any specific consumer. ## Test plan - [x] `pnpm nx test shared-charts` — **13 specs pass** across the three components. - [x] `pnpm nx lint shared-charts` — clean, including the custom `no-restricted-imports` guard on `d3-scale-chromatic`. - [x] `pnpm nx build shared-charts` — clean (TS strict + ng-packagr). - [x] `pnpm nx run-many -t lint test build --projects=shared-charts,portal-shell,portal-admin` — 12/12 tasks green. - [x] `pnpm nx build portal-shell --configuration=production` — i18n-strict prod build clean. The lib ships no i18n marks (axis labels are caller-supplied per ADR-0023's i18n posture), so no xlf entry change here. - [ ] **Visual smoke (deferred to PR 3 when the components are placed on `/audit`)** — `<figure>` + caption visible, SVG `<title>` exposed by VoiceOver / NVDA, `<details>` fallback expands to a table, dark-mode toggle flips axis text + Cividis palette, `prefers-reduced-motion` strips Plot's fade-in. ## What's next PR 3 wires the three components onto the `/audit` page: aggregates `AdminAuditPage.items` client-side into the three required shapes (daily totals, outcome counts, daily-by-event-type pivots), places them above the existing filter form, ships the i18n strings for the captions and descriptions in `messages.fr.xlf`. Bundle impact on the lazy `audit` chunk gets verified there (the ~65 KB gzip plan from the ADR). --------- Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr> Reviewed-on: #171 |
||
|
|
6c42d4c232 |
fix(deps): update nestjs to v11.1.21 (#169)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@nestjs/common](https://nestjs.com) ([source](https://github.com/nestjs/nest/tree/HEAD/packages/common)) | dependencies | patch | [`11.1.19` -> `11.1.21`](https://renovatebot.com/diffs/npm/@nestjs%2fcommon/11.1.19/11.1.21) | | [@nestjs/core](https://nestjs.com) ([source](https://github.com/nestjs/nest/tree/HEAD/packages/core)) | dependencies | patch | [`11.1.19` -> `11.1.21`](https://renovatebot.com/diffs/npm/@nestjs%2fcore/11.1.19/11.1.21) | | [@nestjs/platform-express](https://nestjs.com) ([source](https://github.com/nestjs/nest/tree/HEAD/packages/platform-express)) | dependencies | patch | [`11.1.19` -> `11.1.21`](https://renovatebot.com/diffs/npm/@nestjs%2fplatform-express/11.1.19/11.1.21) | | [@nestjs/testing](https://nestjs.com) ([source](https://github.com/nestjs/nest/tree/HEAD/packages/testing)) | devDependencies | patch | [`11.1.19` -> `11.1.21`](https://renovatebot.com/diffs/npm/@nestjs%2ftesting/11.1.19/11.1.21) | --- ### Release Notes <details> <summary>nestjs/nest (@​nestjs/common)</summary> ### [`v11.1.21`](https://github.com/nestjs/nest/releases/tag/v11.1.21) [Compare Source](https://github.com/nestjs/nest/compare/v11.1.20...v11.1.21) ##### v11.1.21 (2026-05-14) ##### Bug fixes - `core` - [#​16948](https://github.com/nestjs/nest/pull/16948) fix(core): settle skipped provider initialization ([@​yudin-s](https://github.com/yudin-s)) ##### Committers: 1 - Serge Yudin ([@​yudin-s](https://github.com/yudin-s)) ### [`v11.1.20`](https://github.com/nestjs/nest/releases/tag/v11.1.20) [Compare Source](https://github.com/nestjs/nest/compare/v11.1.19...v11.1.20) ##### v11.1.20 (2026-05-13) ##### Bug fixes - `core`, `testing` - [#​16939](https://github.com/nestjs/nest/pull/16939) fix(core): fix deeply nested transient providers resolution ([@​kamilmysliwiec](https://github.com/kamilmysliwiec)) - `core` - [#​16861](https://github.com/nestjs/nest/pull/16861) fix(core): fix [@​Sse](https://github.com/Sse) losing events on complete ([@​MatthiasBrehmer](https://github.com/MatthiasBrehmer)) - [#​16753](https://github.com/nestjs/nest/pull/16753) fix(core): defer sse writehead until after lifecycle completes ([@​jkalberer](https://github.com/jkalberer)) - [#​16782](https://github.com/nestjs/nest/pull/16782) fix(core): use strict null check for SSE message id ([@​burhanharoon](https://github.com/burhanharoon)) - `microservices` - [#​16850](https://github.com/nestjs/nest/pull/16850) fix(microservices): ServerRMQ crashes at boot when [@​MessagePattern](https://github.com/MessagePattern)(undefined) is combined with wildcards: true ([@​lavieennoir](https://github.com/lavieennoir)) - `common` - [#​16845](https://github.com/nestjs/nest/pull/16845) fix(common): accept zero timestamp in parse date pipe ([@​Mysh3ll](https://github.com/Mysh3ll)) - `platform-socket.io` - [#​16742](https://github.com/nestjs/nest/pull/16742) fix(socket.io): Deduplicate disconnect listener in bindMessageHandlers ([@​fru1tworld](https://github.com/fru1tworld)) ##### Enhancements - `microservices` - [#​16676](https://github.com/nestjs/nest/pull/16676) feat(microservices): add return buffers option for binary data ([@​Forceres](https://github.com/Forceres)) - [#​16826](https://github.com/nestjs/nest/pull/16826) feat(microservices): handle rmq blocked/unblocked connection events ([@​thisalihassan](https://github.com/thisalihassan)) - `common` - [#​16902](https://github.com/nestjs/nest/pull/16902) fix(common): filetype validator buffer message ([@​QusaiAlbonni](https://github.com/QusaiAlbonni)) - `platform-express` - [#​16844](https://github.com/nestjs/nest/pull/16844) feat(platform-express): add defParamCharset to MulterOptions ([@​starnayuta](https://github.com/starnayuta)) ##### Dependencies - `platform-ws` - [#​16941](https://github.com/nestjs/nest/pull/16941) chore(deps): bump ws from 8.20.0 to 8.20.1 ([@​dependabot\[bot\]](https://github.com/apps/dependabot)) ##### Committers: 13 - Ali Hassan ([@​thisalihassan](https://github.com/thisalihassan)) - Burhan Haroon⚡ ([@​burhanharoon](https://github.com/burhanharoon)) - Dmytro Khyzhniak ([@​lavieennoir](https://github.com/lavieennoir)) - Harsh Rathod ([@​harshrathod50](https://github.com/harshrathod50)) - IlyaCredo ([@​Forceres](https://github.com/Forceres)) - Kamil Mysliwiec ([@​kamilmysliwiec](https://github.com/kamilmysliwiec)) - Mysh3ll ([@​Mysh3ll](https://github.com/Mysh3ll)) - [@​MatthiasBrehmer](https://github.com/MatthiasBrehmer) - [@​QusaiAlbonni](https://github.com/QusaiAlbonni) - [@​jkalberer](https://github.com/jkalberer) - [@​pazaderey](https://github.com/pazaderey) - fru1tworld ([@​fru1tworld](https://github.com/fru1tworld)) - starnayuta ([@​starnayuta](https://github.com/starnayuta)) </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: #169 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> |
||
|
|
1edf154b67 |
fix(deps): update dependency express-rate-limit to v8.5.2 (#168)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [express-rate-limit](https://github.com/express-rate-limit/express-rate-limit) | dependencies | patch | [`8.5.1` -> `8.5.2`](https://renovatebot.com/diffs/npm/express-rate-limit/8.5.1/8.5.2) | --- ### Release Notes <details> <summary>express-rate-limit/express-rate-limit (express-rate-limit)</summary> ### [`v8.5.2`](https://github.com/express-rate-limit/express-rate-limit/releases/tag/v8.5.2) [Compare Source](https://github.com/express-rate-limit/express-rate-limit/compare/v8.5.1...v8.5.2) You can view the changelog [here](https://express-rate-limit.mintlify.app/reference/changelog). </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: #168 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> |
||
|
|
b61e550d59 |
chore(deps): update dependency lint-staged to v17.0.5 (#167)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [lint-staged](https://github.com/lint-staged/lint-staged) | devDependencies | patch | [`17.0.4` -> `17.0.5`](https://renovatebot.com/diffs/npm/lint-staged/17.0.4/17.0.5) | --- ### Release Notes <details> <summary>lint-staged/lint-staged (lint-staged)</summary> ### [`v17.0.5`](https://github.com/lint-staged/lint-staged/blob/HEAD/CHANGELOG.md#1705) [Compare Source](https://github.com/lint-staged/lint-staged/compare/v17.0.4...v17.0.5) ##### Patch Changes - [#​1792](https://github.com/lint-staged/lint-staged/pull/1792) [`1f67271`](https://github.com/lint-staged/lint-staged/commit/1f672718b6fa67e0f00aafe107cb9f084f4d9102) - Correctly set the `--max-arg-length` default value based on the running platform. This controls how very long lists of staged files are split into multiple chunks. </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: #167 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> |
||
|
|
bba1703622 |
fix(deps): scope the vite < 7 override to vitepress so @angular/build keeps vite 8 (#163)
## Summary Hotfix on the override added in [#161](#161). The unconditional `"vite": ">=6.4.2 <7"` was too broad — it downgraded **every** vite consumer in the workspace to vite 6.4.2, including `@angular/build@21.2.11`. Angular's dev-server plugin (`angular-memory-plugin.js > loadViteClientCode`) monkey-patches Vite's client error-overlay code; the patch targets vite 8.x's internal layout, fails against vite 6, and the home page blank-screens with: ``` [vite] Internal server error: Failed to update Vite client error overlay text. at loadViteClientCode (angular-memory-plugin.js:140:31) ``` …on the very first request to `pnpm nx serve portal-shell`. ## Fix One-line change in [`package.json`](package.json) → `pnpm.overrides`: ```diff - "vite": ">=6.4.2 <7", + "vitepress>vite": ">=6.4.2 <7", ``` pnpm's `parent>child` selector syntax scopes the override to vitepress's transitive resolution only. Other vite consumers (Angular, Nx, Vitest, the analog plugin) follow their own peer constraints and resolve to vite 8.0.13 again. ## Resolution after the fix | Consumer | vite version | Why | | --- | --- | --- | | `vitepress 1.6.4` | **6.4.2** | Override target — keeps VitePress 1.x off rolldown-vite | | `@angular/build 21.2.11` | **8.0.13** | Restored; its dev-server plugin needs vite 8's client layout | | `@nx/vite`, `@analogjs/vite-plugin-angular`, Vitest | **8.0.13** | Restored | | `@vitejs/plugin-basic-ssl` (analog transitive) | 7.3.2 | Its own peer range; HTTPS-cert helper only, not the dev-server host. Doesn't affect us. | ## Why this regression didn't surface in #161's CI The `docs-site.yml` workflow and `pnpm exec nx run-many -t lint test build` exercise the **production build** paths. Vite 6 ↔ Angular-build 21.2's monkey-patch incompatibility is a **dev-server-only** failure (the prod Rollup pipeline doesn't go through `loadViteClientCode`). CI couldn't have caught it; manual `nx serve portal-shell` is the only repro path. Lesson logged. ## Test plan - [x] `pnpm install` — clean. Lockfile diff confirms: vite 6.4.2 only under vitepress, vite 8.0.13 restored everywhere else. - [x] `pnpm audit --audit-level=moderate` — no known vulnerabilities. - [x] `pnpm docs:build` — ~9.5 s, Mermaid still renders in ADR-0009's HTML (regression fence passes). - [x] `pnpm exec nx run-many -t lint test build --projects=portal-shell,portal-admin,portal-bff,shared-ui,shared-state,feature-auth` — green. - [x] **`pnpm nx serve portal-shell`** — boots cleanly, `curl http://localhost:4200/` returns HTTP 200 with the SPA shell, no `loadViteClientCode` error in the dev log. (This is the path that broke.) - [ ] **Manual smoke (the user's repro)** — `pnpm nx serve portal-shell`, open the home page in a browser, confirm: - No "Failed to update Vite client error overlay text" in the browser DevTools console. - Page renders; navigating to `/accessibility`, `/profile` works. - Theme switcher in the footer toggles light / dark / system; locale switcher likewise. ## Notes for the reviewer - **Lesson on override scoping**: the version-selector form (`"package@<vuln-range>": "patched"`) is the safest default — it only kicks in for the vulnerable range. The unconditional form (`"package": "<range>"`) is a sledgehammer and should be reserved for cases where the version-selector form genuinely can't express the intent (as was the case in #161 where the resolved version was already past the vulnerable range, so the selector was a no-op). When the unconditional form is needed, **always scope to a parent** (`"parent>package": …`) to avoid the workspace-wide blast radius. - **No documentation change in this PR**: development.md's "Transitive vulnerabilities — `pnpm.overrides`" subsection (from #160) is still accurate. A follow-up edit could add a "scope to a parent when possible" sentence; not blocking. --------- Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr> Reviewed-on: #163 |
||
|
|
2dbf2d8ce4 |
fix(docs): cap vite below 7 (rolldown-vite) and pin mermaid transitives (#161)
## Summary `pnpm docs:dev` failed after #159's transitive-vuln fix landed. Two distinct symptoms in the same log : 1. **VitePress refused to boot** — `VitePress v1 is not compatible with rolldown-vite. Use VitePress v2 instead.` The override added in #159 (`vite@<6.4.2 → >=6.4.2`) had no upper bound; pnpm resolved vitepress's `vite ^5.0.0` constraint up to **vite 7.3.2**, which uses the new rolldown bundler. VitePress 1.x explicitly rejects rolldown-vite. 2. **Resolution-warning flood** — Even on a fallback port, the console showed `Failed to resolve dependency: dayjs / debug / @braintree/sanitize-url / cytoscape / cytoscape-cose-bilkent` from `optimizeDeps.include`. The vitepress-plugin-mermaid wrapper injects those into the optimizer's include list, but under pnpm's strict isolation they aren't reachable from the workspace root (transitives of mermaid, never hoisted). ## What lands ### 1. Vite override is now an **unconditional** `>=6.4.2 <7` range [`package.json`](package.json): ```diff - "vite@<6.4.2": ">=6.4.2", + "vite": ">=6.4.2 <7", ``` The selector form (`vite@<6.4.2`) was a no-op once vite had resolved into 7.x — the override only activates when the resolved version is _in_ the vulnerable range. Vite 7 is ≥ 6.4.2, so the override stayed dormant and rolldown-vite slipped through. The unconditional form forces a downgrade across every consumer (vitepress, `@nx/vite`, `@analogjs/vite-plugin-angular`, Vitest, etc.). All six top-level projects still lint, test, and build under vite 6.4.2. **Trade-off acknowledged**: we're now pinning the whole workspace to vite 6.x to keep VitePress 1.x happy. The day VitePress 2 ships a 1.0 (currently in beta), we revisit and let vite advance again. Tracked as a soft follow-up. ### 2. `optimizeDeps.include` simplified to `['mermaid']` [`docs/.vitepress/config.mts`](docs/.vitepress/config.mts): ```diff - include: ['mermaid', 'dayjs', 'debug', '@braintree/sanitize-url'], + include: ['mermaid'], ``` Vite 6's dep optimizer walks Mermaid's transitives automatically once Mermaid itself is in `include`. The explicit child list from #157 was carried forward in the rolldown attempt and tripped on vite's stricter resolver — collapsing it now both removes the noise and matches what the plugin's docs recommend for vite 6. ### 3. Mermaid transitives pinned as top-level devDeps [`package.json`](package.json): ```diff + "@braintree/sanitize-url": "^7.1.2", + "cytoscape": "^3.33.3", + "cytoscape-cose-bilkent": "^4.1.0", + "dayjs": "^1.11.20", + "debug": "^4.4.3", ``` These are already in `node_modules` (pulled in by mermaid). Declaring them at the workspace root makes them reachable from `optimizeDeps.include` under pnpm's strict isolation, which silences the five "Failed to resolve dependency" warnings the plugin's wrapper produced. Cost: five extra devDep lines in `package.json` whose only purpose is to make the optimizer happy. Acceptable — they don't influence the resolved tree, just the resolver's reachability rules. ## Notes for the reviewer - **Why not bump VitePress 1 → 2?** VitePress 2 is still beta. Per [CLAUDE.md](CLAUDE.md) §"Project rules": pre-1.0 dependencies and one-maintainer projects are rejected unless an ADR justifies the exception. ADR-0022 already records VitePress 1.6.4 as the chosen baseline; switching to a beta on the very first follow-up PR would burn the rationale. - **Why an unconditional vite range, not a tighter selector?** The selector form (`vite@vulnerable-range → patched-range`) is the standard pattern when the parent dep's own range *includes* a patched version — pnpm picks it naturally and the override never fires. Here vite's 5.x branch was never patched (5.4.21 stayed vulnerable; vite team moved on to 6.x), so we need to force the downgrade from 7.x to 6.x regardless of the previous resolution. An unconditional override is the cleanest expression of that intent. - **Why not extract the mermaid-transitive pins into the ADR-0022 trail?** They're plumbing for the plugin wrapper, not an architectural decision worth recording. If the plugin ships a fix that removes the include list, these can be removed without consequence. Pinning them is reversible. ## Test plan - [x] `pnpm install` clean; lockfile changes reflect vite 6.4.2 across all consumers. - [x] `pnpm audit --audit-level=moderate` — **No known vulnerabilities found**. - [x] `pnpm docs:dev` — server boots cleanly on `:5173`, no warnings, home + ADR-0009 page return 200. - [x] `pnpm docs:build` — clean build in ~9 s (back to Rollup-based timings; the rolldown 3.87 s we saw briefly was the incompatible path). - [x] `pnpm exec nx run-many -t lint test --projects=portal-shell,portal-admin,portal-bff,shared-ui,shared-state,feature-auth` — 12/12 tasks green under the vite 6 downgrade. - [x] `pnpm exec nx build portal-shell` — clean Angular production build; no Vite 6 incompatibility surfaced. - [ ] **Manual smoke (visual)** — `pnpm docs:dev`, open `http://localhost:5173`, navigate to `/decisions/0009-…` and `/architecture`, confirm Mermaid diagrams render inline (this is the actual UX the user opened the issue on). Dark mode toggle still flips diagrams. ## Follow-ups (optional) - When VitePress 2 reaches 1.0 (`vue/vitepress > releases`), revisit this override and let vite resume its mainline cadence. - If the next Renovate cycle proposes a `cytoscape` / `dayjs` / `debug` major bump that VitePress 1.x can't keep up with, the pins above act as the safety net — Renovate will open a PR rather than silently break the dev server. --------- Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr> Reviewed-on: #161 |
||
|
|
a8f027f546 |
fix(deps): update dependency axios to v1.16.1 (#158)
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [axios](https://axios-http.com) ([source](https://github.com/axios/axios)) | dependencies | patch | [`1.16.0` -> `1.16.1`](https://renovatebot.com/diffs/npm/axios/1.16.0/1.16.1) | --- ### Release Notes <details> <summary>axios/axios (axios)</summary> ### [`v1.16.1`](https://github.com/axios/axios/releases/tag/v1.16.1) [Compare Source](https://github.com/axios/axios/compare/v1.16.0...v1.16.1) #### v1.16.1 — May 13, 2026 This release ships a defence-in-depth fix for prototype pollution in `formDataToJSON`, hardens proxy and CI workflows, restores Webpack 4 compatibility for the fetch adapter, and includes several small bug fixes and maintenance improvements. #### 🔒 Security Fixes - **Prototype Pollution Defence-in-Depth:** Hardened `formDataToJSON` against already-polluted `Object.prototype` by walking own properties only, so attacker-controlled keys inherited from a poisoned prototype cannot propagate through deserialization. (**[#​7413](https://github.com/axios/axios/issues/7413)**) - **Proxy Cleartext Leak:** Fixed an issue where HTTPS request data could be transmitted in cleartext to an HTTP proxy under certain configurations. (**[#​10858](https://github.com/axios/axios/issues/10858)**) - **CI Cache Removal:** Removed all GitHub Actions caches as a defence-in-depth measure against cache poisoning vectors in the build pipeline. (**[#​10882](https://github.com/axios/axios/issues/10882)**) #### 🐛 Bug Fixes - **Data URI Parsing:** Updated the `fromDataURI` regex to match RFC 2397 more strictly, fixing edge cases in `data:` URL handling. (**[#​10829](https://github.com/axios/axios/issues/10829)**) - **Unicode Headers:** Preserved Unicode header values when running through request interceptors, so non-ASCII header content is no longer corrupted before dispatch. (**[#​10850](https://github.com/axios/axios/issues/10850)**) - **XHR Upload Progress:** Guarded against malformed `ProgressEvent` payloads emitted by some environments during XHR upload, preventing crashes when `loaded` / `total` are missing or invalid. (**[#​10868](https://github.com/axios/axios/issues/10868)**) - **Webpack 4 Fetch Adapter:** Fixed an "unexpected token" error caused by syntax in the fetch adapter that Webpack 4 could not parse, restoring compatibility for legacy bundler users. (**[#​10864](https://github.com/axios/axios/issues/10864)**) - **Type Definitions:** Made `parseReviver` `context.source` optional in the type definitions to align with the ES2023 specification. (**[#​10837](https://github.com/axios/axios/issues/10837)**) - **URL Object Support Reverted:** Reverted the change that allowed passing a `URL` object as `config.url` (originally **[#​10866](https://github.com/axios/axios/issues/10866)**) due to regressions; this support will be reintroduced in a later release once the underlying issues are addressed. (**[#​10874](https://github.com/axios/axios/issues/10874)**) #### 🔧 Maintenance & Chores - **Cycle Detection Refactor:** Replaced the array-based cycle tracker in `toJSONObject` with a `WeakSet`, improving performance and memory behaviour on large nested structures. (**[#​10832](https://github.com/axios/axios/issues/10832)**) - **composeSignals Cleanup:** Refactored `composeSignals` to use a clearer early-return structure, simplifying the cancellation/abort composition path. (**[#​10844](https://github.com/axios/axios/issues/10844)**) - **AI Readiness & Repo Docs:** Added `AGENTS.md` and related contributor-guide updates for both human and AI agents, plus post-release documentation improvements. (**[#​10835](https://github.com/axios/axios/issues/10835)**, **[#​10841](https://github.com/axios/axios/issues/10841)**) - **Docs Improvements:** Clarified the GET request example, fixed the interceptor `eject` example to reference the correct instance, and corrected the Buzzoid sponsor description in the README. (**[#​10836](https://github.com/axios/axios/issues/10836)**, **[#​10853](https://github.com/axios/axios/issues/10853)**, **[#​10856](https://github.com/axios/axios/issues/10856)**) - **Sponsorship Tooling:** Fixed empty sponsor arrays in the sponsor processing script, added the ability to inject additional sponsors, updated the sponsorship link, and added a Twicsy advertisement entry. (**[#​10843](https://github.com/axios/axios/issues/10843)**, **[#​10859](https://github.com/axios/axios/issues/10859)**, **[#​10869](https://github.com/axios/axios/issues/10869)**) - **Dependencies:** Bumped `@commitlint/cli` from 20.5.0 to 20.5.2. (**[#​10846](https://github.com/axios/axios/issues/10846)**) #### 🌟 New Contributors We are thrilled to welcome our new contributors. Thank you for helping improve axios: - **[@​hpinmetaverse](https://github.com/hpinmetaverse)** (**[#​10836](https://github.com/axios/axios/issues/10836)**) - **[@​tommyhgunz14](https://github.com/tommyhgunz14)** (**[#​7413](https://github.com/axios/axios/issues/7413)**) - **[@​abhu85](https://github.com/abhu85)** (**[#​10829](https://github.com/axios/axios/issues/10829)**) - **[@​divyanshuraj1095](https://github.com/divyanshuraj1095)** (**[#​10853](https://github.com/axios/axios/issues/10853)**) - **[@​sagodi97](https://github.com/sagodi97)** (**[#​10856](https://github.com/axios/axios/issues/10856)**) - **[@​rkdfx](https://github.com/rkdfx)** (**[#​10868](https://github.com/axios/axios/issues/10868)**) - **[@​Liuwei1125](https://github.com/Liuwei1125)** (**[#​10866](https://github.com/axios/axios/issues/10866)**) [Full Changelog](https://github.com/axios/axios/compare/v1.16.0...v1.16.1) </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/158 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> |
||
|
|
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 |