diff --git a/.bazelversion b/.bazelversion index f9c71a52e2fd..acd405b1d62e 100644 --- a/.bazelversion +++ b/.bazelversion @@ -1 +1 @@ -8.5.1 +8.6.0 diff --git a/.gemini/config.yaml b/.gemini/config.yaml new file mode 100644 index 000000000000..9f4eb5f02da3 --- /dev/null +++ b/.gemini/config.yaml @@ -0,0 +1,11 @@ +have_fun: false +code_review: + disable: false + comment_severity_threshold: MEDIUM + max_review_comments: -1 + pull_request_opened: + help: false + summary: false + code_review: true + include_drafts: false +ignore_patterns: [] diff --git a/.github/workflows/assistant-to-the-branch-manager.yml b/.github/workflows/assistant-to-the-branch-manager.yml index 6e0a4cb8c7d7..efde5bc5d875 100644 --- a/.github/workflows/assistant-to-the-branch-manager.yml +++ b/.github/workflows/assistant-to-the-branch-manager.yml @@ -17,6 +17,6 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - - uses: angular/dev-infra/github-actions/branch-manager@469708f109a90884ca403d150d33079a3a5a8769 + - uses: angular/dev-infra/github-actions/branch-manager@616a50d0b747031b7ea052733adf3771fa6cace9 with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5f62362d4410..4a89f2d7f9ad 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,9 +21,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@616a50d0b747031b7ea052733adf3771fa6cace9 - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/bazel/setup@616a50d0b747031b7ea052733adf3771fa6cace9 - name: Install node modules run: pnpm install --frozen-lockfile - name: Generate JSON schema types @@ -44,11 +44,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@616a50d0b747031b7ea052733adf3771fa6cace9 - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/bazel/setup@616a50d0b747031b7ea052733adf3771fa6cace9 - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/bazel/configure-remote@616a50d0b747031b7ea052733adf3771fa6cace9 with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -61,11 +61,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@616a50d0b747031b7ea052733adf3771fa6cace9 - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/bazel/setup@616a50d0b747031b7ea052733adf3771fa6cace9 - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/bazel/configure-remote@616a50d0b747031b7ea052733adf3771fa6cace9 with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -84,13 +84,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@616a50d0b747031b7ea052733adf3771fa6cace9 - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/bazel/setup@616a50d0b747031b7ea052733adf3771fa6cace9 - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/bazel/configure-remote@616a50d0b747031b7ea052733adf3771fa6cace9 with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -100,11 +100,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@616a50d0b747031b7ea052733adf3771fa6cace9 - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/bazel/setup@616a50d0b747031b7ea052733adf3771fa6cace9 - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/bazel/configure-remote@616a50d0b747031b7ea052733adf3771fa6cace9 with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -137,7 +137,7 @@ jobs: runs-on: windows-2025 steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@616a50d0b747031b7ea052733adf3771fa6cace9 - name: Install node modules run: pnpm install --frozen-lockfile - name: Download built Windows E2E tests @@ -164,13 +164,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@616a50d0b747031b7ea052733adf3771fa6cace9 - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/bazel/setup@616a50d0b747031b7ea052733adf3771fa6cace9 - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/bazel/configure-remote@616a50d0b747031b7ea052733adf3771fa6cace9 with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -188,13 +188,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@616a50d0b747031b7ea052733adf3771fa6cace9 - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/bazel/setup@616a50d0b747031b7ea052733adf3771fa6cace9 - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/bazel/configure-remote@616a50d0b747031b7ea052733adf3771fa6cace9 with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -208,13 +208,13 @@ jobs: SAUCE_TUNNEL_IDENTIFIER: angular-cli-${{ github.workflow }}-${{ github.run_number }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@616a50d0b747031b7ea052733adf3771fa6cace9 - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/bazel/setup@616a50d0b747031b7ea052733adf3771fa6cace9 - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/bazel/configure-remote@616a50d0b747031b7ea052733adf3771fa6cace9 with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run E2E Browser tests @@ -244,11 +244,11 @@ jobs: CIRCLE_BRANCH: ${{ github.ref_name }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@616a50d0b747031b7ea052733adf3771fa6cace9 - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/bazel/setup@616a50d0b747031b7ea052733adf3771fa6cace9 - run: pnpm admin snapshots --verbose env: SNAPSHOT_BUILDS_GITHUB_TOKEN: ${{ secrets.SNAPSHOT_BUILDS_GITHUB_TOKEN }} diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 0b070c5aae16..9c9cda1ad80d 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -23,12 +23,12 @@ jobs: with: persist-credentials: false - name: Initialize CodeQL - uses: github/codeql-action/init@45cbd0c69e560cd9e7cd7f8c32362050c9b7ded2 # v4.32.2 + uses: github/codeql-action/init@38697555549f1db7851b81482ff19f1fa5c4fedc # v4.34.1 with: languages: javascript-typescript build-mode: none config-file: .github/codeql/config.yml - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@45cbd0c69e560cd9e7cd7f8c32362050c9b7ded2 # v4.32.2 + uses: github/codeql-action/analyze@38697555549f1db7851b81482ff19f1fa5c4fedc # v4.34.1 with: category: '/language:javascript-typescript' diff --git a/.github/workflows/dev-infra.yml b/.github/workflows/dev-infra.yml index d8d2f0b7bb6c..bf29d1e38ae4 100644 --- a/.github/workflows/dev-infra.yml +++ b/.github/workflows/dev-infra.yml @@ -3,6 +3,8 @@ name: DevInfra on: pull_request_target: types: [opened, synchronize, reopened] + issues: + types: [opened, reopened] # Declare default permissions as read only. permissions: @@ -10,16 +12,24 @@ permissions: jobs: labels: + if: github.event_name == 'pull_request_target' runs-on: ubuntu-latest steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: angular/dev-infra/github-actions/pull-request-labeling@469708f109a90884ca403d150d33079a3a5a8769 + - uses: angular/dev-infra/github-actions/labeling/pull-request@616a50d0b747031b7ea052733adf3771fa6cace9 with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} post_approval_changes: + if: github.event_name == 'pull_request_target' runs-on: ubuntu-latest steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: angular/dev-infra/github-actions/post-approval-changes@469708f109a90884ca403d150d33079a3a5a8769 + - uses: angular/dev-infra/github-actions/post-approval-changes@616a50d0b747031b7ea052733adf3771fa6cace9 with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} + issue_labels: + if: github.event_name == 'issues' + runs-on: ubuntu-latest + steps: + - uses: angular/dev-infra/github-actions/labeling/issue@616a50d0b747031b7ea052733adf3771fa6cace9 + with: + angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} + google-generative-ai-key: ${{ secrets.GOOGLE_GENERATIVE_AI_KEY }} diff --git a/.github/workflows/feature-requests.yml b/.github/workflows/feature-requests.yml index 4e22f1a5eda8..b77551c5d2a8 100644 --- a/.github/workflows/feature-requests.yml +++ b/.github/workflows/feature-requests.yml @@ -16,6 +16,6 @@ jobs: if: github.repository == 'angular/angular-cli' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/feature-request@469708f109a90884ca403d150d33079a3a5a8769 + - uses: angular/dev-infra/github-actions/feature-request@616a50d0b747031b7ea052733adf3771fa6cace9 with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} diff --git a/.github/workflows/perf.yml b/.github/workflows/perf.yml index 9dbf67608b8c..675676394863 100644 --- a/.github/workflows/perf.yml +++ b/.github/workflows/perf.yml @@ -23,7 +23,7 @@ jobs: workflows: ${{ steps.workflows.outputs.workflows }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@616a50d0b747031b7ea052733adf3771fa6cace9 - name: Install node modules run: pnpm install --frozen-lockfile - id: workflows @@ -38,9 +38,9 @@ jobs: workflow: ${{ fromJSON(needs.list.outputs.workflows) }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@616a50d0b747031b7ea052733adf3771fa6cace9 - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/bazel/setup@616a50d0b747031b7ea052733adf3771fa6cace9 - name: Install node modules run: pnpm install --frozen-lockfile # We utilize the google-github-actions/auth action to allow us to get an active credential using workflow diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 12195b663fda..9235d910ea5c 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -23,7 +23,7 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 + - uses: dorny/paths-filter@d1c1ffe0248fe513906c8e24db8ea791d46f8590 # v3.0.3 id: filter with: filters: | @@ -34,11 +34,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@616a50d0b747031b7ea052733adf3771fa6cace9 - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/bazel/setup@616a50d0b747031b7ea052733adf3771fa6cace9 - name: Setup ESLint Caching - uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 + uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 with: path: .eslintcache key: ${{ runner.os }}-${{ hashFiles('.eslintrc.json') }} @@ -66,17 +66,17 @@ jobs: # it has been merged. run: pnpm ng-dev format changed --check ${{ github.event.pull_request.base.sha }} - name: Check Package Licenses - uses: angular/dev-infra/github-actions/linting/licenses@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/linting/licenses@616a50d0b747031b7ea052733adf3771fa6cace9 build: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@616a50d0b747031b7ea052733adf3771fa6cace9 - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/bazel/setup@616a50d0b747031b7ea052733adf3771fa6cace9 - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/bazel/configure-remote@616a50d0b747031b7ea052733adf3771fa6cace9 - name: Install node modules run: pnpm install --frozen-lockfile - name: Build release targets @@ -93,11 +93,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@616a50d0b747031b7ea052733adf3771fa6cace9 - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/bazel/setup@616a50d0b747031b7ea052733adf3771fa6cace9 - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/bazel/configure-remote@616a50d0b747031b7ea052733adf3771fa6cace9 - name: Install node modules run: pnpm install --frozen-lockfile - name: Run module and package tests @@ -114,13 +114,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@616a50d0b747031b7ea052733adf3771fa6cace9 - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/bazel/setup@616a50d0b747031b7ea052733adf3771fa6cace9 - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/bazel/configure-remote@616a50d0b747031b7ea052733adf3771fa6cace9 - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=6 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.${{ matrix.subset }}_node${{ matrix.node }} @@ -128,11 +128,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@616a50d0b747031b7ea052733adf3771fa6cace9 - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/bazel/setup@616a50d0b747031b7ea052733adf3771fa6cace9 - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/bazel/configure-remote@616a50d0b747031b7ea052733adf3771fa6cace9 - name: Install node modules run: pnpm install --frozen-lockfile - name: Build E2E tests for Windows on Linux @@ -156,7 +156,7 @@ jobs: runs-on: windows-2025 steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@616a50d0b747031b7ea052733adf3771fa6cace9 - name: Install node modules run: pnpm install --frozen-lockfile - name: Download built Windows E2E tests @@ -183,13 +183,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@616a50d0b747031b7ea052733adf3771fa6cace9 - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/bazel/setup@616a50d0b747031b7ea052733adf3771fa6cace9 - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/bazel/configure-remote@616a50d0b747031b7ea052733adf3771fa6cace9 - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=3 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.${{ matrix.subset }}_node${{ matrix.node }} @@ -205,12 +205,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@616a50d0b747031b7ea052733adf3771fa6cace9 - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/bazel/setup@616a50d0b747031b7ea052733adf3771fa6cace9 - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@469708f109a90884ca403d150d33079a3a5a8769 + uses: angular/dev-infra/github-actions/bazel/configure-remote@616a50d0b747031b7ea052733adf3771fa6cace9 - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=6 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.snapshots.${{ matrix.subset }}_node${{ matrix.node }} diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 4c9465d0cf9b..f31e15c10d1f 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -46,6 +46,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: 'Upload to code-scanning' - uses: github/codeql-action/upload-sarif@45cbd0c69e560cd9e7cd7f8c32362050c9b7ded2 # v4.32.2 + uses: github/codeql-action/upload-sarif@38697555549f1db7851b81482ff19f1fa5c4fedc # v4.34.1 with: sarif_file: results.sarif diff --git a/.monorepo.json b/.monorepo.json index 4d5face644df..96877fada26e 100644 --- a/.monorepo.json +++ b/.monorepo.json @@ -62,7 +62,11 @@ "@angular-devkit/architect-cli": { "name": "Architect CLI", "section": "Tooling", - "snapshotRepo": "angular/angular-devkit-architect-cli-builds" + "snapshotRepo": "angular/angular-devkit-architect-cli-builds", + "deprecated": { + "version": ">=0.2102.0", + "message": "The Architect CLI is now available directly via '@angular-devkit/architect'." + } }, "@angular-devkit/build-angular": { "name": "Build Angular", diff --git a/.ng-dev/release.mjs b/.ng-dev/release.mjs index 2aadf9db122c..7790637ed329 100644 --- a/.ng-dev/release.mjs +++ b/.ng-dev/release.mjs @@ -8,7 +8,11 @@ import { releasePackages } from '../scripts/packages.mts'; */ export const release = { representativeNpmPackage: '@angular/cli', - npmPackages: releasePackages.map(({ name, experimental }) => ({ name, experimental })), + npmPackages: releasePackages.map(({ name, experimental, deprecated }) => ({ + name, + experimental, + deprecated, + })), buildPackages: async () => { // The `performNpmReleaseBuild` function is loaded at runtime to avoid loading additional // files and dependencies unless a build is required. diff --git a/.nvmrc b/.nvmrc index 85e502778f62..db49bb14d78e 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -22.22.0 +22.22.2 diff --git a/CHANGELOG.md b/CHANGELOG.md index b11c764b3618..a6e5f434a182 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,131 +1,259 @@ - + -# 19.2.20 (2026-02-13) +# 21.2.6 (2026-04-01) -### @angular-devkit/build-angular +### @angular/cli -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ------------------------- | -| [0e5421ba7](https://github.com/angular/angular-cli/commit/0e5421ba78814cf11e4d4510e930eaacc6458662) | fix | update webpack to 5.105.0 | +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------- | +| [ea14f28cc](https://github.com/angular/angular-cli/commit/ea14f28ccfc6e5534eaef516bf1bfbe21582da04) | fix | fix sourceRoot resolution for MCP projects tool | + +### @angular/build + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------- | +| [9136eb376](https://github.com/angular/angular-cli/commit/9136eb37630d6315891b3c881cd0ba4037c3254c) | fix | ensure transitive SCSS partial errors are tracked in watch mode | +| [8186faa11](https://github.com/angular/angular-cli/commit/8186faa117803ffb6ac8e2c4cd6ab7873502308d) | fix | ensure Vitest mock patching is executed only once | +| [107d1a9e2](https://github.com/angular/angular-cli/commit/107d1a9e26fc59c7878254e563758818866f0f6e) | fix | preserve error stack traces during prerendering | +| [b7f457253](https://github.com/angular/angular-cli/commit/b7f4572533675729e87532bdc23509feb2f3a28d) | fix | scope CHROME_BIN executable path to individual playwright instances | - + + +# 21.2.5 (2026-03-27) + +### @angular/cli -# 21.2.0-next.2 (2026-02-11) +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------- | +| [cadf9b201](https://github.com/angular/angular-cli/commit/cadf9b201bd1055a6e3cc016eb01e0196b028080) | feat | support custom port in MCP devserver start tool | + +### @angular/ssr + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ---------------------------------------------------- | +| [bbc255419](https://github.com/angular/angular-cli/commit/bbc255419b346e5152391b47f310922f86e9e383) | fix | allow underscores in host validation | +| [b1fe66a7f](https://github.com/angular/angular-cli/commit/b1fe66a7f8650ce021b4070394bc31848fc64ca5) | fix | patch Headers.forEach in cloneRequestAndPatchHeaders | + + + + + +# 21.2.4 (2026-03-26) + +### @angular/cli + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ---------------------------------------------- | +| [a7787d092](https://github.com/angular/angular-cli/commit/a7787d0925559fe7731034856a872708bcfb78be) | fix | restore console methods after logger completes | ### @angular/build -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------------- | -| [cad7a7c0f](https://github.com/angular/angular-cli/commit/cad7a7c0ff3778f04820a99ad0aa9d74f1067fd5) | feat | run vitest browser with playwright with OS theme | -| [8ae7f59e6](https://github.com/angular/angular-cli/commit/8ae7f59e6f988489fda8c1346e3d2c3768d7a5f0) | fix | correctly resolve absolute setup file paths in Vitest | -| [fd5cb28c8](https://github.com/angular/angular-cli/commit/fd5cb28c8082417288a896b89bde659bb0dc92e2) | fix | explicitly fail when using Vitest runtime mocking | +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------- | +| [7170599ab](https://github.com/angular/angular-cli/commit/7170599ab237691d9208c410363ef7e4ee50db2c) | fix | deduplicate and merge coverage excludes with vitest | +| [c73f13797](https://github.com/angular/angular-cli/commit/c73f13797afe57fcc98faf6361085e1dd5afae9b) | fix | prevent reporter duplicates by explicitly overriding Vitest configuration | +| [956ccaa71](https://github.com/angular/angular-cli/commit/956ccaa71ea8a3626e4139cf7e2f26ee637feeed) | fix | remove default for unit-test coverage option | +| [36978db7e](https://github.com/angular/angular-cli/commit/36978db7e494e4e5612aa2a8384199eeca7c4c2d) | fix | warn about performance of test.exclude in vitest configuration | +| [6ec36f5be](https://github.com/angular/angular-cli/commit/6ec36f5bee05d97c10ca8d91d5746621ffb1fdb9) | fix | warn when vitest watch config conflicts with builder | + +### @angular/ssr + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------- | +| [9bdf782c8](https://github.com/angular/angular-cli/commit/9bdf782c838ab5820ec905d689a62ffc3b3cabe3) | fix | apply forwarded prefix and vary header in accept-language redirects | +| [628c58672](https://github.com/angular/angular-cli/commit/628c586728748e1c367fa7e363299eb79b1566ca) | fix | support '\*' in allowedHosts and warn about security risks | - + -# 21.1.4 (2026-02-11) +# 21.2.3 (2026-03-18) + +### @angular/cli + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------ | +| [1505164bb](https://github.com/angular/angular-cli/commit/1505164bb2703254a2b25a76c7b3a1ff2fd76a85) | fix | use parsed package name for migrate-only updates | ### @angular/build +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------ | +| [75fa94cad](https://github.com/angular/angular-cli/commit/75fa94cad26b0947e687ef94d50653cb7651d18c) | fix | alias createRequire banner import to avoid duplicate binding | +| [d009aa1ec](https://github.com/angular/angular-cli/commit/d009aa1ec7411b67b61b81003eb6181cde6f306f) | fix | only use external packages for polyfills when no local files are present | + +### @angular/ssr + | Commit | Type | Description | | --------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------------- | -| [7a9dd6b47](https://github.com/angular/angular-cli/commit/7a9dd6b47e2191862c64355b10abaeead189759f) | fix | correctly resolve absolute setup file paths in Vitest | +| [f3e0e82c2](https://github.com/angular/angular-cli/commit/f3e0e82c2cecc3d9ebb5b8acc6e64d2d88c4efbd) | fix | disallow x-forwarded-prefix starting with a backslash | +| [b8bcd59b4](https://github.com/angular/angular-cli/commit/b8bcd59b40496369a57de0b0b39d85f323af30c7) | fix | ensure unique values in redirect response Vary header | +| [84385411d](https://github.com/angular/angular-cli/commit/84385411d4542d60d635aea9063c1fd751deb607) | fix | support custom headers in redirect responses | - + -# 20.3.16 (2026-02-09) +# 21.2.2 (2026-03-11) ### @angular/cli -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------ | -| [656888a25](https://github.com/angular/angular-cli/commit/656888a250af060c110ae87024b0e475b079c23d) | fix | update dependency @modelcontextprotocol/sdk to v1.26.0 | +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------------------- | +| [8447d9132](https://github.com/angular/angular-cli/commit/8447d913280a8fa09a842d11193ce77527d0f7a6) | fix | conditionally quote package names when adding dependencies based on host requirements | +| [d2f209823](https://github.com/angular/angular-cli/commit/d2f209823a524a6effde4910017547675c7a6166) | fix | preserve exact version in ng add when requested | +| [28f4d684a](https://github.com/angular/angular-cli/commit/28f4d684ae12f0e0860bf0ace8851fdddad1c068) | perf | avoid redundant package version resolution in ng add | + +### @angular/build + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------- | +| [06010294f](https://github.com/angular/angular-cli/commit/06010294f8fe7a4843f802aafba51703ce810f61) | fix | allow any `CHROME_BIN` for vitest playwright provider | +| [8dec0c62b](https://github.com/angular/angular-cli/commit/8dec0c62ba40af339f4fd0fa34f20cbed545cd71) | fix | normalize line endings for CSP hash generation | +| [58688ebd7](https://github.com/angular/angular-cli/commit/58688ebd727fe295adcb538a33b525867caf82bd) | fix | pass process environment variables to prerender workers | +| [4ca61647f](https://github.com/angular/angular-cli/commit/4ca61647f208ec0ab9bc06f64583696b0619c259) | fix | resolve assets correctly during i18n prerendering | - + -# 21.2.0-next.1 (2026-02-05) +# 21.2.1 (2026-03-05) ### @angular/cli -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ---------------------------------------------------------- | -| [91b9d281f](https://github.com/angular/angular-cli/commit/91b9d281fc88a242aa6e5dd5495e275990d926ef) | feat | integrate file formatting into update migrations | -| [6f29a8c35](https://github.com/angular/angular-cli/commit/6f29a8c35abb8928d4e7ea01958192dd2a83491d) | fix | renamed files by their new path in the schematic workflow | -| [bc363af8b](https://github.com/angular/angular-cli/commit/bc363af8bc40f117a4e35ec9eb7eedf69f5b5b37) | perf | optimize package manager discovery with stat-based probing | +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------ | +| [ae4c28d00](https://github.com/angular/angular-cli/commit/ae4c28d0083d948489f4ba38c571b7f955400226) | fix | correct dev dependency detection logic in `ng add` | +| [465073bc1](https://github.com/angular/angular-cli/commit/465073bc1b2b0e9fa594698651a9e0afe747a74a) | fix | disable npm update notifier in package manager host | +| [36270634f](https://github.com/angular/angular-cli/commit/36270634f6ff5ab15896a8c2b345659511a8a276) | fix | ensure group members are updated to targeted version | +| [d87dba6af](https://github.com/angular/angular-cli/commit/d87dba6af1116de0838d8683cd69fd31ed9811fd) | fix | ignore unknown files when formatting schematic changes | ### @schematics/angular -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ---------------------------------------------------------------- | -| [5d1df50d8](https://github.com/angular/angular-cli/commit/5d1df50d8b84b453570ae5fd9ab6f949bbc11649) | fix | add actionable feedback to vitest-browser schematic | -| [51fc77828](https://github.com/angular/angular-cli/commit/51fc77828a33fdf35051b7e18d79ad43f90cba1d) | fix | warn when production configuration is missing for service worker | +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------------------------- | +| [72d466aa0](https://github.com/angular/angular-cli/commit/72d466aa04d4d0cc4d654410bcb6dd44f0de3357) | fix | prevent adding test dependencies when minimal option is enabled | + +### @angular-devkit/build-angular + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------- | +| [0019d1c8e](https://github.com/angular/angular-cli/commit/0019d1c8e1494295a754063dbf936e1cd40d05bd) | fix | update copy-webpack-plugin to v14.0.0 | ### @angular/build -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | -------------------------------------------------- | -| [ece30f235](https://github.com/angular/angular-cli/commit/ece30f2359c2dc794b0c9272447f623a121e88b0) | feat | add headless option to unit-test builder | -| [1f114a9e8](https://github.com/angular/angular-cli/commit/1f114a9e8b9bddd53e01016a2d7cb211a04eee48) | fix | bundle setup files in unit-test builder for Vitest | +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------------ | +| [6ad860863](https://github.com/angular/angular-cli/commit/6ad8608636ad48ae140cc7299a32e0358c761fcc) | fix | bundle polyfills to preserve execution order in dev server | +| [d17397375](https://github.com/angular/angular-cli/commit/d1739737564fbcc3e4c5a6c3369046cccf0f6120) | fix | conditionally allow `vi.mock` for non-relative imports | +| [0d49f86ed](https://github.com/angular/angular-cli/commit/0d49f86edf5592f0266c6d6689ab4d55b27b2d8d) | fix | resolve style include paths relative to `ng-package.json` in unit-test builder | +| [584f6a2d9](https://github.com/angular/angular-cli/commit/584f6a2d95ac4bdd9f20d918c6700ea79227cc92) | fix | treat empty browsers array as undefined in unit-test builder | +| [6699cdc9b](https://github.com/angular/angular-cli/commit/6699cdc9bfbabc3de2ff0cf03acfd6989dc5596c) | perf | fix memory leak in `ng serve` with i18n | + +### @angular/ssr + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ---------------------------------------------------- | +| [43a9dfa66](https://github.com/angular/angular-cli/commit/43a9dfa663c386217c9a654f0e80af74823fcf6a) | fix | improve header validation logic | +| [dee3717b3](https://github.com/angular/angular-cli/commit/dee3717b3faae9ea75d0a5e53c925f915949b8d0) | fix | introduce DI token to signal route discovery process | - + -# 21.1.3 (2026-02-05) +# 21.2.0 (2026-02-25) + +### @angular/cli + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------------------------------------------- | +| [0dd04f289](https://github.com/angular/angular-cli/commit/0dd04f289e555a4a8af7bdadabe300da74701e3b) | feat | add markdown files to Prettier's formatting list | +| [fbae1b6ab](https://github.com/angular/angular-cli/commit/fbae1b6ab384186ae69e804c54815cea80e6a600) | feat | automatic formatting files modified by schematics | +| [91b9d281f](https://github.com/angular/angular-cli/commit/91b9d281fc88a242aa6e5dd5495e275990d926ef) | feat | integrate file formatting into update migrations | +| [98a24d040](https://github.com/angular/angular-cli/commit/98a24d0401f36f484dc9c4d8b0f5284ffa524f19) | feat | standardize MCP tools around workspace/project options | +| [d9cd609c5](https://github.com/angular/angular-cli/commit/d9cd609c5d13fe492b1f31973d9be518f8529387) | fix | correctly parse scoped packages in yarn classic list output | +| [5b05f2500](https://github.com/angular/angular-cli/commit/5b05f25005621828565585692b1d7a67c5f0fec8) | fix | enable shell option for Prettier execution on Windows platforms | +| [25b8a157d](https://github.com/angular/angular-cli/commit/25b8a157df70fb0d2c4e6c5438a50ec12e3abc0c) | fix | quote complex range specifiers in package manager | +| [6f29a8c35](https://github.com/angular/angular-cli/commit/6f29a8c35abb8928d4e7ea01958192dd2a83491d) | fix | renamed files by their new path in the schematic workflow | +| [201a036f2](https://github.com/angular/angular-cli/commit/201a036f204a6940f70a36a507a4a53d144b5768) | fix | simplify Angular version compatibility checks and add special handling for local builds of new major versions | +| [cdd26bb66](https://github.com/angular/angular-cli/commit/cdd26bb66d8ab334f76323c2b5cae1aa8ce815f6) | fix | validate package manager version using `semver.valid` and throw an error if invalid | +| [bc363af8b](https://github.com/angular/angular-cli/commit/bc363af8bc40f117a4e35ec9eb7eedf69f5b5b37) | perf | optimize package manager discovery with stat-based probing | ### @schematics/angular -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ---------------------------------------------------------------- | -| [a18196a10](https://github.com/angular/angular-cli/commit/a18196a1096e5eb69cf64102943781d34c4389bf) | fix | warn when production configuration is missing for service worker | +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------------------------------------------- | +| [aa7381efd](https://github.com/angular/angular-cli/commit/aa7381efd213eff70a8004731a7e2b06a60cb8c2) | feat | add a '.prettierrc' file to generated workspaces and add Prettier as dev dependency | +| [f80db6fb7](https://github.com/angular/angular-cli/commit/f80db6fb714aa326f6ed03a8a51090ca59ad0955) | feat | add ng-add support for Vitest browser providers | +| [5d1df50d8](https://github.com/angular/angular-cli/commit/5d1df50d8b84b453570ae5fd9ab6f949bbc11649) | fix | add actionable feedback to vitest-browser schematic | + +### @angular/build + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | -------------------------------------------------------- | +| [ece30f235](https://github.com/angular/angular-cli/commit/ece30f2359c2dc794b0c9272447f623a121e88b0) | feat | add headless option to unit-test builder | +| [cad7a7c0f](https://github.com/angular/angular-cli/commit/cad7a7c0ff3778f04820a99ad0aa9d74f1067fd5) | feat | run vitest browser with playwright with OS theme | +| [0b4982720](https://github.com/angular/angular-cli/commit/0b4982720e111bf5029bcf97f7e0ce2658c42d43) | fix | adjust sourcemap sources when Vitest wrapper is bypassed | +| [1f114a9e8](https://github.com/angular/angular-cli/commit/1f114a9e8b9bddd53e01016a2d7cb211a04eee48) | fix | bundle setup files in unit-test builder for Vitest | +| [fd5cb28c8](https://github.com/angular/angular-cli/commit/fd5cb28c8082417288a896b89bde659bb0dc92e2) | fix | explicitly fail when using Vitest runtime mocking | +| [dc899e8a5](https://github.com/angular/angular-cli/commit/dc899e8a530979de8e9579f2281b681e6f737a62) | fix | normalize `allowedHosts` in dev-server | +| [26bbea12f](https://github.com/angular/angular-cli/commit/26bbea12f872c18e59de05d3c51cc11dd0a09cda) | fix | serve extensionless assets without transformation | + + + + + +# 19.2.20 (2026-02-13) ### @angular-devkit/build-angular -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ----------------------------------- | -| [6d05d27ca](https://github.com/angular/angular-cli/commit/6d05d27ca097b16efb139bcee1c45b1b51dfe746) | fix | address Node.js deprecation DEP0190 | +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------- | +| [0e5421ba7](https://github.com/angular/angular-cli/commit/0e5421ba78814cf11e4d4510e930eaacc6458662) | fix | update webpack to 5.105.0 | - + -# 21.2.0-next.0 (2026-01-28) +# 21.1.4 (2026-02-11) + +### @angular/build + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------------- | +| [7a9dd6b47](https://github.com/angular/angular-cli/commit/7a9dd6b47e2191862c64355b10abaeead189759f) | fix | correctly resolve absolute setup file paths in Vitest | + + + + + +# 20.3.16 (2026-02-09) ### @angular/cli -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------------------------- | -| [0dd04f289](https://github.com/angular/angular-cli/commit/0dd04f289e555a4a8af7bdadabe300da74701e3b) | feat | add markdown files to Prettier's formatting list | -| [fbae1b6ab](https://github.com/angular/angular-cli/commit/fbae1b6ab384186ae69e804c54815cea80e6a600) | feat | automatic formatting files modified by schematics | -| [98a24d040](https://github.com/angular/angular-cli/commit/98a24d0401f36f484dc9c4d8b0f5284ffa524f19) | feat | standardize MCP tools around workspace/project options | -| [d9cd609c5](https://github.com/angular/angular-cli/commit/d9cd609c5d13fe492b1f31973d9be518f8529387) | fix | correctly parse scoped packages in yarn classic list output | -| [5b05f2500](https://github.com/angular/angular-cli/commit/5b05f25005621828565585692b1d7a67c5f0fec8) | fix | enable shell option for Prettier execution on Windows platforms | +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------ | +| [656888a25](https://github.com/angular/angular-cli/commit/656888a250af060c110ae87024b0e475b079c23d) | fix | update dependency @modelcontextprotocol/sdk to v1.26.0 | + + + + + +# 21.1.3 (2026-02-05) ### @schematics/angular -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------------------------------------------- | -| [aa7381efd](https://github.com/angular/angular-cli/commit/aa7381efd213eff70a8004731a7e2b06a60cb8c2) | feat | add a '.prettierrc' file to generated workspaces and add Prettier as dev dependency | -| [f80db6fb7](https://github.com/angular/angular-cli/commit/f80db6fb714aa326f6ed03a8a51090ca59ad0955) | feat | add ng-add support for Vitest browser providers | +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ---------------------------------------------------------------- | +| [a18196a10](https://github.com/angular/angular-cli/commit/a18196a1096e5eb69cf64102943781d34c4389bf) | fix | warn when production configuration is missing for service worker | ### @angular-devkit/build-angular | Commit | Type | Description | | --------------------------------------------------------------------------------------------------- | ---- | ----------------------------------- | -| [b4a8d198c](https://github.com/angular/angular-cli/commit/b4a8d198c78aaf0cac7671f26162ce5818a5704c) | fix | address Node.js deprecation DEP0190 | - -### @angular/build - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | -------------------------------------------------------- | -| [0b4982720](https://github.com/angular/angular-cli/commit/0b4982720e111bf5029bcf97f7e0ce2658c42d43) | fix | adjust sourcemap sources when Vitest wrapper is bypassed | +| [6d05d27ca](https://github.com/angular/angular-cli/commit/6d05d27ca097b16efb139bcee1c45b1b51dfe746) | fix | address Node.js deprecation DEP0190 | @@ -2401,7 +2529,6 @@ - Protractor is no longer supported. Protractor was marked end-of-life in August 2023 (see https://protractortest.org/). Projects still relying on Protractor should consider migrating to another E2E testing framework, several support solid migration paths from Protractor. - - https://angular.dev/tools/cli/end-to-end - https://blog.angular.dev/the-state-of-end-to-end-testing-with-angular-d175f751cb9c @@ -6036,7 +6163,6 @@ Alan Agius, Charles Lyding and Doug Parker ### @angular/cli - Several changes to the `ng analytics` command syntax. - - `ng analytics project ` has been replaced with `ng analytics ` - `ng analytics ` has been replaced with `ng analytics --global` @@ -6066,7 +6192,6 @@ Alan Agius, Charles Lyding and Doug Parker - `browser` and `karma` builders `script` and `styles` options input files extensions are now validated. Valid extensions for `scripts` are: - - `.js` - `.cjs` - `.mjs` @@ -6075,7 +6200,6 @@ Alan Agius, Charles Lyding and Doug Parker - `.mjsx` Valid extensions for `styles` are: - - `.css` - `.less` - `.sass` diff --git a/MODULE.bazel b/MODULE.bazel index e218349c3d69..c2d2294e87a4 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -5,56 +5,57 @@ module( ) bazel_dep(name = "platforms", version = "1.0.0") -bazel_dep(name = "yq.bzl", version = "0.3.4") +bazel_dep(name = "yq.bzl", version = "0.3.5") bazel_dep(name = "rules_nodejs", version = "6.7.3") -bazel_dep(name = "aspect_rules_js", version = "2.9.2") -bazel_dep(name = "aspect_rules_ts", version = "3.8.4") +bazel_dep(name = "aspect_rules_js", version = "3.0.3") +bazel_dep(name = "aspect_rules_ts", version = "3.8.7") bazel_dep(name = "rules_pkg", version = "1.2.0") -bazel_dep(name = "rules_cc", version = "0.2.16") -bazel_dep(name = "aspect_bazel_lib", version = "2.22.5") +bazel_dep(name = "rules_cc", version = "0.2.17") +bazel_dep(name = "jq.bzl", version = "0.6.1") +bazel_dep(name = "bazel_lib", version = "3.2.2") bazel_dep(name = "bazel_skylib", version = "1.9.0") -bazel_dep(name = "aspect_rules_esbuild", version = "0.25.0") -bazel_dep(name = "aspect_rules_jasmine", version = "2.0.2") +bazel_dep(name = "aspect_rules_esbuild", version = "0.25.1") +bazel_dep(name = "aspect_rules_jasmine", version = "2.0.4") bazel_dep(name = "rules_angular") git_override( module_name = "rules_angular", - commit = "d746c4f75e42cffe389d1ab077f4639be2bc78d1", - remote = "https://github.com/devversion/rules_angular.git", + commit = "32ce54318d9ec5d84269d4acecbc39944cd8b5e7", + remote = "https://github.com/angular/rules_angular.git", ) bazel_dep(name = "devinfra") git_override( module_name = "devinfra", - commit = "469708f109a90884ca403d150d33079a3a5a8769", + commit = "616a50d0b747031b7ea052733adf3771fa6cace9", remote = "https://github.com/angular/dev-infra.git", ) bazel_dep(name = "rules_sass") git_override( module_name = "rules_sass", - commit = "1184a80751a21af8348f308abc5b38a41f26850e", - remote = "https://github.com/devversion/rules_sass.git", + commit = "13918bec49cd183a591e3781d1d08044b4aa9f61", + remote = "https://github.com/angular/rules_sass.git", ) bazel_dep(name = "rules_browsers") git_override( module_name = "rules_browsers", - commit = "e08ae33c679d07b3b2fcc136658b787a81995bc5", - remote = "https://github.com/devversion/rules_browsers.git", + commit = "afdc95c1ce8ed9ff0cb94f829b7fc988c43dd783", + remote = "https://github.com/angular/rules_browsers.git", ) node = use_extension("@rules_nodejs//nodejs:extensions.bzl", "node") node.toolchain( node_repositories = { - "22.22.0-darwin_arm64": ("node-v22.22.0-darwin-arm64.tar.gz", "node-v22.22.0-darwin-arm64", "5ed4db0fcf1eaf84d91ad12462631d73bf4576c1377e192d222e48026a902640"), - "22.22.0-darwin_amd64": ("node-v22.22.0-darwin-x64.tar.gz", "node-v22.22.0-darwin-x64", "5ea50c9d6dea3dfa3abb66b2656f7a4e1c8cef23432b558d45fb538c7b5dedce"), - "22.22.0-linux_arm64": ("node-v22.22.0-linux-arm64.tar.xz", "node-v22.22.0-linux-arm64", "1bf1eb9ee63ffc4e5d324c0b9b62cf4a289f44332dfef9607cea1a0d9596ba6f"), - "22.22.0-linux_ppc64le": ("node-v22.22.0-linux-ppc64le.tar.xz", "node-v22.22.0-linux-ppc64le", "d83b9957431cc18e1fc143a4b99f89cde7b8a18f53ef392231b4336afd058865"), - "22.22.0-linux_s390x": ("node-v22.22.0-linux-s390x.tar.xz", "node-v22.22.0-linux-s390x", "5aa0e520689448c4233e8d73f284e8e0634fdcd32b479735698494be5641f3e4"), - "22.22.0-linux_amd64": ("node-v22.22.0-linux-x64.tar.xz", "node-v22.22.0-linux-x64", "9aa8e9d2298ab68c600bd6fb86a6c13bce11a4eca1ba9b39d79fa021755d7c37"), - "22.22.0-windows_amd64": ("node-v22.22.0-win-x64.zip", "node-v22.22.0-win-x64", "c97fa376d2becdc8863fcd3ca2dd9a83a9f3468ee7ccf7a6d076ec66a645c77a"), + "22.22.2-darwin_arm64": ("node-v22.22.2-darwin-arm64.tar.gz", "node-v22.22.2-darwin-arm64", "db4b275b83736df67533529a18cc55de2549a8329ace6c7bcc68f8d22d3c9000"), + "22.22.2-darwin_amd64": ("node-v22.22.2-darwin-x64.tar.gz", "node-v22.22.2-darwin-x64", "12a6abb9c2902cf48a21120da13f87fde1ed1b71a13330712949e8db818708ba"), + "22.22.2-linux_arm64": ("node-v22.22.2-linux-arm64.tar.xz", "node-v22.22.2-linux-arm64", "e9e1930fd321a470e29bb68f30318bf58e3ecb4acb4f1533fb19c58328a091fe"), + "22.22.2-linux_ppc64le": ("node-v22.22.2-linux-ppc64le.tar.xz", "node-v22.22.2-linux-ppc64le", "14045b5a5030d35ca0030fb7e870bd11a651eb9b57323ebc0021e8d78ac6bac9"), + "22.22.2-linux_s390x": ("node-v22.22.2-linux-s390x.tar.xz", "node-v22.22.2-linux-s390x", "9e4a07c291b8949289c6ea8ee61b1d14666a4810feae776a8d1eb1f57e03a2fb"), + "22.22.2-linux_amd64": ("node-v22.22.2-linux-x64.tar.xz", "node-v22.22.2-linux-x64", "88fd1ce767091fd8d4a99fdb2356e98c819f93f3b1f8663853a2dee9b438068a"), + "22.22.2-windows_amd64": ("node-v22.22.2-win-x64.zip", "node-v22.22.2-win-x64", "7c93e9d92bf68c07182b471aa187e35ee6cd08ef0f24ab060dfff605fcc1c57c"), }, - node_version = "22.22.0", + node_version = "22.22.2", ) use_repo( node, @@ -110,8 +111,8 @@ use_repo( pnpm = use_extension("@aspect_rules_js//npm:extensions.bzl", "pnpm") pnpm.pnpm( name = "pnpm", - pnpm_version = "10.29.3", - pnpm_version_integrity = "sha512-SY4ftMylqgbB3PJhHm+vxQly/+cYmZjECekN50VmREKY/+Q+bNKs3Hdboap8xeCSqLcFTIEbqMV3D4RpPTPS3A==", + pnpm_version = "10.33.0", + pnpm_version_integrity = "sha512-EFaLtKavtYyes2MNqQzJUWQXq+vT+rvmc58K55VyjaFJHp21pUTHatjrdXD1xLs9bGN7LLQb/c20f6gjyGSTGQ==", ) use_repo(pnpm, "pnpm") @@ -155,6 +156,14 @@ npm.npm_translate_lock( npmrc = "//:.npmrc", pnpm_lock = "//:pnpm-lock.yaml", ) + +# This is needed as by default `.md` files are excluded from the npm package. +# But @angular/core includes best-practices.md file. +# See: https://github.com/aspect-build/rules_js/blob/786a74a158dd36ed073188b0e506c423cd05501a/npm/private/exclude_package_contents_presets.bzl#L29 +npm.npm_exclude_package_contents( + package = "@angular/core", + presets = [], +) use_repo(npm, "npm") rules_ts_ext = use_extension("@aspect_rules_ts//ts:extensions.bzl", "ext") @@ -180,5 +189,4 @@ register_toolchains( "@devinfra//bazel/git-toolchain:git_macos_arm64_toolchain", "@devinfra//bazel/git-toolchain:git_windows_toolchain", "//tools/toolchains:dummy_cc_windows_no_exec_toolchain", - "//tools/toolchains:node24_windows_no_exec_toolchain", ) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 8af79006afc6..ae7e8f3a44c6 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -18,22 +18,15 @@ "https://bcr.bazel.build/modules/aspect_bazel_lib/2.22.5/source.json": "ac2c3213df8f985785f1d0aeb7f0f73d5324e6e67d593d9b9470fb74a25d4a9b", "https://bcr.bazel.build/modules/aspect_bazel_lib/2.7.7/MODULE.bazel": "491f8681205e31bb57892d67442ce448cda4f472a8e6b3dc062865e29a64f89c", "https://bcr.bazel.build/modules/aspect_bazel_lib/2.8.1/MODULE.bazel": "812d2dd42f65dca362152101fbec418029cc8fd34cbad1a2fde905383d705838", - "https://bcr.bazel.build/modules/aspect_bazel_lib/2.9.3/MODULE.bazel": "66baf724dbae7aff4787bf2245cc188d50cb08e07789769730151c0943587c14", - "https://bcr.bazel.build/modules/aspect_rules_esbuild/0.25.0/MODULE.bazel": "5fef5ec709c837312823f9bcf0f276661e2cb48ad52f17c4e01176bbf1e9bf58", - "https://bcr.bazel.build/modules/aspect_rules_esbuild/0.25.0/source.json": "5e42968c6d23ab8bd95c02634b16864d866334347827cb6a8425b86c11cc4363", - "https://bcr.bazel.build/modules/aspect_rules_jasmine/2.0.2/MODULE.bazel": "45f054400ff242c4433f6d7f20f6123a9a72739cb7a1f44247d738db1644f46c", - "https://bcr.bazel.build/modules/aspect_rules_jasmine/2.0.2/source.json": "3ed399a5654259a822448f9cdbf21f6c738f16ccd7f89249c7507e374cbdd1e3", + "https://bcr.bazel.build/modules/aspect_rules_esbuild/0.25.1/MODULE.bazel": "9b931b3e483bd8eedb6966bda6df07d801f70ccb4896231b4e5e711b5130f3aa", + "https://bcr.bazel.build/modules/aspect_rules_esbuild/0.25.1/source.json": "a0b72e23ed06113f3878cb635d586b4045ef37750983467af72fe0315c3a2fcd", + "https://bcr.bazel.build/modules/aspect_rules_jasmine/2.0.4/MODULE.bazel": "fbb819eb8b7e5d7f67fdd38f7cecb413e287594cd666ce192c72c8828527775a", + "https://bcr.bazel.build/modules/aspect_rules_jasmine/2.0.4/source.json": "81ffb708333cd98ec3c0b4cc004f4d5cf92a16914b5196a2892c45141bba7cff", "https://bcr.bazel.build/modules/aspect_rules_js/2.0.0/MODULE.bazel": "b45b507574aa60a92796e3e13c195cd5744b3b8aff516a9c0cb5ae6a048161c5", - "https://bcr.bazel.build/modules/aspect_rules_js/2.4.2/MODULE.bazel": "0d01db38b96d25df7ed952a5e96eac4b3802723d146961974bf020f6dd07591d", - "https://bcr.bazel.build/modules/aspect_rules_js/2.6.2/MODULE.bazel": "ed2a871f4ab8fbde0cab67c425745069d84ea64b64313fa1a2954017326511f5", - "https://bcr.bazel.build/modules/aspect_rules_js/2.9.2/MODULE.bazel": "93fd5b85e6e912fb0712cbab453c43271d4ea33a093f84fd587638fbc9f8c145", - "https://bcr.bazel.build/modules/aspect_rules_js/2.9.2/source.json": "4bff7c03ab387b60deb15649ba575688e62f2a71a7544cbc7a660b19ec473808", - "https://bcr.bazel.build/modules/aspect_rules_ts/3.6.3/MODULE.bazel": "d09db394970f076176ce7bab5b5fa7f0d560fd4f30b8432ea5e2c2570505b130", - "https://bcr.bazel.build/modules/aspect_rules_ts/3.7.0/MODULE.bazel": "5aace216caf88638950ef061245d23c36f57c8359e56e97f02a36f70bb09c50f", - "https://bcr.bazel.build/modules/aspect_rules_ts/3.8.3/MODULE.bazel": "a26c28ebcd0c0d50ab0708ac21fa48bd2dced3a4dad4c31a2fa48588b42ad762", - "https://bcr.bazel.build/modules/aspect_rules_ts/3.8.4/MODULE.bazel": "a50254ac3add6232d0f9f93103836f9afaf614315589a13abf74183982c4101d", - "https://bcr.bazel.build/modules/aspect_rules_ts/3.8.4/source.json": "f786e0763f3ea5de7ea6d4c4e38fccb48bf4d9c5eafaf95091c0e1590502510e", - "https://bcr.bazel.build/modules/aspect_tools_telemetry/0.2.3/MODULE.bazel": "20f53b145f40957a51077ae90b37b7ce83582a1daf9350349f0f86179e19dd0d", + "https://bcr.bazel.build/modules/aspect_rules_js/3.0.3/MODULE.bazel": "28a30e8fc33bf64a67835d64d124f6e05a7d59648dcb27b110fb3502f761e503", + "https://bcr.bazel.build/modules/aspect_rules_js/3.0.3/source.json": "bb8fff9a304452e1042af9522ad1d54d6f1d1fdf71c5127deadb6fd156654193", + "https://bcr.bazel.build/modules/aspect_rules_ts/3.8.7/MODULE.bazel": "830f8a53bb9f1139c24006a90ddc0230481326d69fa847eb00daf8eaae118724", + "https://bcr.bazel.build/modules/aspect_rules_ts/3.8.7/source.json": "95549d64e28f3e4e3648cc037cefdac01ec3b0f58fced2409c286784e82ad0f0", "https://bcr.bazel.build/modules/aspect_tools_telemetry/0.2.6/MODULE.bazel": "cafb8781ad591bc57cc765dca5fefab08cf9f65af363d162b79d49205c7f8af7", "https://bcr.bazel.build/modules/aspect_tools_telemetry/0.2.8/MODULE.bazel": "aa975a83e72bcaac62ee61ab12b788ea324a1d05c4aab28aadb202f647881679", "https://bcr.bazel.build/modules/aspect_tools_telemetry/0.3.3/MODULE.bazel": "37c764292861c2f70314efa9846bb6dbb44fc0308903b3285da6528305450183", @@ -49,19 +42,20 @@ "https://bcr.bazel.build/modules/bazel_features/1.30.0/MODULE.bazel": "a14b62d05969a293b80257e72e597c2da7f717e1e69fa8b339703ed6731bec87", "https://bcr.bazel.build/modules/bazel_features/1.34.0/MODULE.bazel": "e8475ad7c8965542e0c7aac8af68eb48c4af904be3d614b6aa6274c092c2ea1e", "https://bcr.bazel.build/modules/bazel_features/1.39.0/MODULE.bazel": "28739425c1fc283c91931619749c832b555e60bcd1010b40d8441ce0a5cf726d", - "https://bcr.bazel.build/modules/bazel_features/1.39.0/source.json": "f63cbeb4c602098484d57001e5a07d31cb02bbccde9b5e2c9bf0b29d05283e93", "https://bcr.bazel.build/modules/bazel_features/1.4.1/MODULE.bazel": "e45b6bb2350aff3e442ae1111c555e27eac1d915e77775f6fdc4b351b758b5d7", + "https://bcr.bazel.build/modules/bazel_features/1.41.0/MODULE.bazel": "6e0f87fafed801273c371d41e22a15a6f8abf83fdd7f87d5e44ad317b94433d0", + "https://bcr.bazel.build/modules/bazel_features/1.41.0/source.json": "8fd525b31b0883c47e0593443cdd10219b94a7556b3195fc02d75c86c66cfe30", "https://bcr.bazel.build/modules/bazel_features/1.9.0/MODULE.bazel": "885151d58d90d8d9c811eb75e3288c11f850e1d6b481a8c9f766adee4712358b", "https://bcr.bazel.build/modules/bazel_features/1.9.1/MODULE.bazel": "8f679097876a9b609ad1f60249c49d68bfab783dd9be012faf9d82547b14815a", - "https://bcr.bazel.build/modules/bazel_lib/3.0.0-beta.1/MODULE.bazel": "407729e232f611c3270005b016b437005daa7b1505826798ea584169a476e878", + "https://bcr.bazel.build/modules/bazel_lib/3.0.0-rc.0/MODULE.bazel": "d6e00979a98ac14ada5e31c8794708b41434d461e7e7ca39b59b765e6d233b18", "https://bcr.bazel.build/modules/bazel_lib/3.0.0/MODULE.bazel": "22b70b80ac89ad3f3772526cd9feee2fa412c2b01933fea7ed13238a448d370d", - "https://bcr.bazel.build/modules/bazel_lib/3.0.0/source.json": "895f21909c6fba01d7c17914bb6c8e135982275a1b18cdaa4e62272217ef1751", + "https://bcr.bazel.build/modules/bazel_lib/3.2.2/MODULE.bazel": "e2c890c8a515d6bca9c66d47718aa9e44b458fde64ec7204b8030bf2d349058c", + "https://bcr.bazel.build/modules/bazel_lib/3.2.2/source.json": "9e84e115c20e14652c5c21401ae85ff4daa8702e265b5c0b3bf89353f17aa212", "https://bcr.bazel.build/modules/bazel_skylib/1.0.3/MODULE.bazel": "bcb0fd896384802d1ad283b4e4eb4d718eebd8cb820b0a2c3a347fb971afd9d8", "https://bcr.bazel.build/modules/bazel_skylib/1.1.1/MODULE.bazel": "1add3e7d93ff2e6998f9e118022c84d163917d912f5afafb3058e3d2f1545b5e", "https://bcr.bazel.build/modules/bazel_skylib/1.2.0/MODULE.bazel": "44fe84260e454ed94ad326352a698422dbe372b21a1ac9f3eab76eb531223686", "https://bcr.bazel.build/modules/bazel_skylib/1.2.1/MODULE.bazel": "f35baf9da0efe45fa3da1696ae906eea3d615ad41e2e3def4aeb4e8bc0ef9a7a", "https://bcr.bazel.build/modules/bazel_skylib/1.3.0/MODULE.bazel": "20228b92868bf5cfc41bda7afc8a8ba2a543201851de39d990ec957b513579c5", - "https://bcr.bazel.build/modules/bazel_skylib/1.4.0/MODULE.bazel": "2ab127ef8d56a739a99bb2ce00ec4c7d1ecc7977d4370c0ca6efd0d8f03d6d99", "https://bcr.bazel.build/modules/bazel_skylib/1.4.1/MODULE.bazel": "a0dcb779424be33100dcae821e9e27e4f2901d9dfd5333efe5ac6a8d7ab75e1d", "https://bcr.bazel.build/modules/bazel_skylib/1.4.2/MODULE.bazel": "3bd40978e7a1fac911d5989e6b09d8f64921865a45822d8b09e815eaa726a651", "https://bcr.bazel.build/modules/bazel_skylib/1.5.0/MODULE.bazel": "32880f5e2945ce6a03d1fbd588e9198c0a959bb42297b2cfaf1685b7bc32e138", @@ -75,14 +69,17 @@ "https://bcr.bazel.build/modules/buildozer/7.1.2/MODULE.bazel": "2e8dd40ede9c454042645fd8d8d0cd1527966aa5c919de86661e62953cd73d84", "https://bcr.bazel.build/modules/buildozer/7.1.2/source.json": "c9028a501d2db85793a6996205c8de120944f50a0d570438fcae0457a5f9d1f8", "https://bcr.bazel.build/modules/gawk/5.3.2.bcr.1/MODULE.bazel": "cdf8cbe5ee750db04b78878c9633cc76e80dcf4416cbe982ac3a9222f80713c8", - "https://bcr.bazel.build/modules/gawk/5.3.2.bcr.1/source.json": "fa7b512dfcb5eafd90ce3959cf42a2a6fe96144ebbb4b3b3928054895f2afac2", + "https://bcr.bazel.build/modules/gawk/5.3.2.bcr.3/MODULE.bazel": "f1b7bb2dd53e8f2ef984b39485ec8a44e9076dda5c4b8efd2fb4c6a6e856a31d", + "https://bcr.bazel.build/modules/gawk/5.3.2.bcr.3/source.json": "ebe931bfe362e4b41e59ee00a528db6074157ff2ced92eb9e970acab2e1089c9", "https://bcr.bazel.build/modules/google_benchmark/1.8.2/MODULE.bazel": "a70cf1bba851000ba93b58ae2f6d76490a9feb74192e57ab8e8ff13c34ec50cb", "https://bcr.bazel.build/modules/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4", "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/MODULE.bazel": "22c31a561553727960057361aa33bf20fb2e98584bc4fec007906e27053f80c6", "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/source.json": "41e9e129f80d8c8bf103a7acc337b76e54fad1214ac0a7084bf24f4cd924b8b4", "https://bcr.bazel.build/modules/googletest/1.14.0/MODULE.bazel": "cfbcbf3e6eac06ef9d85900f64424708cc08687d1b527f0ef65aa7517af8118f", "https://bcr.bazel.build/modules/jq.bzl/0.1.0/MODULE.bazel": "2ce69b1af49952cd4121a9c3055faa679e748ce774c7f1fda9657f936cae902f", - "https://bcr.bazel.build/modules/jq.bzl/0.1.0/source.json": "746bf13cac0860f091df5e4911d0c593971cd8796b5ad4e809b2f8e133eee3d5", + "https://bcr.bazel.build/modules/jq.bzl/0.4.0/MODULE.bazel": "a7b39b37589f2b0dad53fd6c1ccaabbdb290330caa920d7ef3e6aad068cd4ab2", + "https://bcr.bazel.build/modules/jq.bzl/0.6.1/MODULE.bazel": "f30c46e0a08a9f7566a8bf60a43d48abea960cd7f57b315b01e2762f1537eb52", + "https://bcr.bazel.build/modules/jq.bzl/0.6.1/source.json": "9ca9e2f90baa6a5bb0a49626ed9528554ec83165adf47b39792673ecc7feda22", "https://bcr.bazel.build/modules/jsoncpp/1.9.5/MODULE.bazel": "31271aedc59e815656f5736f282bb7509a97c7ecb43e927ac1a37966e0578075", "https://bcr.bazel.build/modules/jsoncpp/1.9.5/source.json": "4108ee5085dd2885a341c7fab149429db457b3169b86eb081fa245eadf69169d", "https://bcr.bazel.build/modules/libpfm/4.11.0/MODULE.bazel": "45061ff025b301940f1e30d2c16bea596c25b176c8b6b3087e92615adbd52902", @@ -105,6 +102,7 @@ "https://bcr.bazel.build/modules/protobuf/29.0/MODULE.bazel": "319dc8bf4c679ff87e71b1ccfb5a6e90a6dbc4693501d471f48662ac46d04e4e", "https://bcr.bazel.build/modules/protobuf/29.0/source.json": "b857f93c796750eef95f0d61ee378f3420d00ee1dd38627b27193aa482f4f981", "https://bcr.bazel.build/modules/protobuf/3.19.0/MODULE.bazel": "6b5fbb433f760a99a22b18b6850ed5784ef0e9928a72668b66e4d7ccd47db9b0", + "https://bcr.bazel.build/modules/protobuf/3.19.6/MODULE.bazel": "9233edc5e1f2ee276a60de3eaa47ac4132302ef9643238f23128fea53ea12858", "https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/MODULE.bazel": "88af1c246226d87e65be78ed49ecd1e6f5e98648558c14ce99176da041dc378e", "https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/source.json": "be4789e951dd5301282729fe3d4938995dc4c1a81c2ff150afc9f1b0504c6022", "https://bcr.bazel.build/modules/re2/2023-09-01/MODULE.bazel": "cb3d511531b16cfc78a225a9e2136007a48cf8a677e4264baeab57fe78a80206", @@ -123,7 +121,9 @@ "https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5", "https://bcr.bazel.build/modules/rules_cc/0.1.1/MODULE.bazel": "2f0222a6f229f0bf44cd711dc13c858dad98c62d52bd51d8fc3a764a83125513", "https://bcr.bazel.build/modules/rules_cc/0.2.16/MODULE.bazel": "9242fa89f950c6ef7702801ab53922e99c69b02310c39fb6e62b2bd30df2a1d4", - "https://bcr.bazel.build/modules/rules_cc/0.2.16/source.json": "d03d5cde49376d87e14ec14b666c56075e5e3926930327fd5d0484a1ff2ac1cc", + "https://bcr.bazel.build/modules/rules_cc/0.2.17/MODULE.bazel": "1849602c86cb60da8613d2de887f9566a6d354a6df6d7009f9d04a14402f9a84", + "https://bcr.bazel.build/modules/rules_cc/0.2.17/source.json": "3832f45d145354049137c0090df04629d9c2b5493dc5c2bf46f1834040133a07", + "https://bcr.bazel.build/modules/rules_cc/0.2.4/MODULE.bazel": "1ff1223dfd24f3ecf8f028446d4a27608aa43c3f41e346d22838a4223980b8cc", "https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6", "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel": "40c97d1144356f52905566c55811f13b299453a14ac7769dfba2ac38192337a8", "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/source.json": "c8b1e2c717646f1702290959a3302a178fb639d987ab61d548105019f11e527e", @@ -157,10 +157,7 @@ "https://bcr.bazel.build/modules/rules_license/1.0.0/MODULE.bazel": "a7fda60eefdf3d8c827262ba499957e4df06f659330bbe6cdbdb975b768bb65c", "https://bcr.bazel.build/modules/rules_license/1.0.0/source.json": "a52c89e54cc311196e478f8382df91c15f7a2bfdf4c6cd0e2675cc2ff0b56efb", "https://bcr.bazel.build/modules/rules_nodejs/6.2.0/MODULE.bazel": "ec27907f55eb34705adb4e8257952162a2d4c3ed0f0b3b4c3c1aad1fac7be35e", - "https://bcr.bazel.build/modules/rules_nodejs/6.3.0/MODULE.bazel": "45345e4aba35dd6e4701c1eebf5a4e67af4ed708def9ebcdc6027585b34ee52d", - "https://bcr.bazel.build/modules/rules_nodejs/6.3.3/MODULE.bazel": "b66eadebd10f1f1b25f52f95ab5213a57e82c37c3f656fcd9a57ad04d2264ce7", "https://bcr.bazel.build/modules/rules_nodejs/6.5.0/MODULE.bazel": "546d0cf79f36f9f6e080816045f97234b071c205f4542e3351bd4424282a8810", - "https://bcr.bazel.build/modules/rules_nodejs/6.5.2/MODULE.bazel": "7f9ea68a0ce6d82905ce9f74e76ab8a8b4531ed4c747018c9d76424ad0b3370d", "https://bcr.bazel.build/modules/rules_nodejs/6.7.3/MODULE.bazel": "c22a48b2a0dbf05a9dc5f83837bbc24c226c1f6e618de3c3a610044c9f336056", "https://bcr.bazel.build/modules/rules_nodejs/6.7.3/source.json": "a3f966f4415a8a6545e560ee5449eac95cc633f96429d08e87c87775c72f5e09", "https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc", @@ -196,15 +193,16 @@ "https://bcr.bazel.build/modules/stardoc/0.7.2/source.json": "58b029e5e901d6802967754adf0a9056747e8176f017cfe3607c0851f4d42216", "https://bcr.bazel.build/modules/tar.bzl/0.2.1/MODULE.bazel": "52d1c00a80a8cc67acbd01649e83d8dd6a9dc426a6c0b754a04fe8c219c76468", "https://bcr.bazel.build/modules/tar.bzl/0.5.1/MODULE.bazel": "7c2eb3dcfc53b0f3d6f9acdfd911ca803eaf92aadf54f8ca6e4c1f3aee288351", - "https://bcr.bazel.build/modules/tar.bzl/0.8.1/MODULE.bazel": "6ffe8907ed4c555bc94bd35a5a01411cc4470c6dace84f9cf487815409e077d1", - "https://bcr.bazel.build/modules/tar.bzl/0.8.1/source.json": "835f83b482facf6205ad8708cf2b2f6524d1d7b1075a90fe9bb540da761d6d2e", + "https://bcr.bazel.build/modules/tar.bzl/0.6.0/MODULE.bazel": "a3584b4edcfafcabd9b0ef9819808f05b372957bbdff41601429d5fd0aac2e7c", + "https://bcr.bazel.build/modules/tar.bzl/0.9.0/MODULE.bazel": "452a22d7f02b1c9d7a22ab25edf20f46f3e1101f0f67dc4bfbf9a474ddf02445", + "https://bcr.bazel.build/modules/tar.bzl/0.9.0/source.json": "c732760a374831a2cf5b08839e4be75017196b4d796a5aa55235272ee17cd839", "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43", "https://bcr.bazel.build/modules/yq.bzl/0.1.1/MODULE.bazel": "9039681f9bcb8958ee2c87ffc74bdafba9f4369096a2b5634b88abc0eaefa072", - "https://bcr.bazel.build/modules/yq.bzl/0.2.0/MODULE.bazel": "6f3a675677db8885be4d607fde14cc51829715e3a879fb016eb9bf336786ce6d", "https://bcr.bazel.build/modules/yq.bzl/0.3.2/MODULE.bazel": "0384efa70e8033d842ea73aa4b7199fa099709e236a7264345c03937166670b6", - "https://bcr.bazel.build/modules/yq.bzl/0.3.4/MODULE.bazel": "d3a270662f5d766cd7229732d65a5a5bc485240c3007343dd279edfb60c9ae27", - "https://bcr.bazel.build/modules/yq.bzl/0.3.4/source.json": "786dafdc2843722da3416e4343ee1a05237227f068590779a6e8496a2064c0f9", + "https://bcr.bazel.build/modules/yq.bzl/0.3.5/MODULE.bazel": "130c603e54be717bdf84100210f06598a0d2b4b4e01888fb01b70f50f41767ec", + "https://bcr.bazel.build/modules/yq.bzl/0.3.5/source.json": "1ae7bdc03cb26aaa8bd2bceadf65e90d90f0b2d03008ba9a0564da2e21396c39", "https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0", + "https://bcr.bazel.build/modules/zlib/1.2.12/MODULE.bazel": "3b1a8834ada2a883674be8cbd36ede1b6ec481477ada359cd2d3ddc562340b27", "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/MODULE.bazel": "eec517b5bbe5492629466e11dae908d043364302283de25581e3eb944326c4ca", "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/source.json": "22bc55c47af97246cfc093d0acf683a7869377de362b5d1c552c2c2e16b7a806", "https://bcr.bazel.build/modules/zlib/1.3.1/MODULE.bazel": "751c9940dcfe869f5f7274e1295422a34623555916eb98c174c1e945594bf198" @@ -213,8 +211,8 @@ "moduleExtensions": { "@@aspect_rules_esbuild+//esbuild:extensions.bzl%esbuild": { "general": { - "bzlTransitiveDigest": "c4i5gawrp4Au9UMb55EzQCePYwkrFqD9tFBN7GdHG5g=", - "usagesDigest": "ToTaCONCN/E05krnHXLM1kpV1zrHNxHrGpUip973II4=", + "bzlTransitiveDigest": "GnYkDpVOnWnYv+xwyhEi0qjk3Lvp4Wei30PeSIQF5vM=", + "usagesDigest": "6We6zwGoawD9YXqMI0KPaxEKJTnamXBsuOekhFS2D40=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, "envVariables": {}, @@ -269,11 +267,11 @@ "npm__esbuild_0.19.9": { "repoRuleId": "@@aspect_rules_js+//npm/private:npm_import.bzl%npm_import_rule", "attributes": { + "key": "npm__esbuild_0.19.9", "package": "esbuild", "version": "0.19.9", "root_package": "", "link_workspace": "", - "link_packages": {}, "integrity": "sha512-U9CHtKSy+EpPsEBa+/A2gMs/h3ylBC0H0KSqIg7tpztHerLi6nrrcoUJAkNCEPumx8yJ+Byic4BVwHgRbN0TBg==", "url": "", "commit": "", @@ -288,20 +286,23 @@ "npm_auth_password": "", "lifecycle_hooks": [], "extra_build_content": "", + "generate_package_json_bzl": false, "generate_bzl_library_targets": false, "extract_full_archive": false, - "exclude_package_contents": [] + "exclude_package_contents": [], + "exclude_package_contents_presets": [] } }, "npm__esbuild_0.19.9__links": { - "repoRuleId": "@@aspect_rules_js+//npm/private:npm_import.bzl%npm_import_links", + "repoRuleId": "@@aspect_rules_js+//npm/private:npm_import.bzl%npm_import_links_rule", "attributes": { + "key": "npm__esbuild_0.19.9", "package": "esbuild", "version": "0.19.9", - "dev": false, "root_package": "", - "link_packages": {}, "deps": {}, + "deps_oss": {}, + "deps_cpus": {}, "transitive_closure": {}, "lifecycle_build_target": false, "lifecycle_hooks_env": [], @@ -314,31 +315,12 @@ "//visibility:public" ], "replace_package": "", - "exclude_package_contents": [] + "exclude_package_contents": [], + "exclude_package_contents_presets": [] } } }, "recordedRepoMappingEntries": [ - [ - "aspect_bazel_lib+", - "bazel_lib", - "bazel_lib+" - ], - [ - "aspect_bazel_lib+", - "bazel_skylib", - "bazel_skylib+" - ], - [ - "aspect_bazel_lib+", - "bazel_tools", - "bazel_tools" - ], - [ - "aspect_bazel_lib+", - "tar.bzl", - "tar.bzl+" - ], [ "aspect_rules_esbuild+", "aspect_rules_js", @@ -354,11 +336,6 @@ "bazel_skylib", "bazel_skylib+" ], - [ - "aspect_rules_js+", - "aspect_bazel_lib", - "aspect_bazel_lib+" - ], [ "aspect_rules_js+", "aspect_rules_js", @@ -371,162 +348,33 @@ ], [ "aspect_rules_js+", - "bazel_lib", - "bazel_lib+" - ], - [ - "aspect_rules_js+", - "bazel_skylib", - "bazel_skylib+" + "bazel_features", + "bazel_features+" ], [ "aspect_rules_js+", - "bazel_tools", - "bazel_tools" - ], - [ - "bazel_lib+", - "bazel_skylib", - "bazel_skylib+" - ], - [ - "bazel_lib+", - "bazel_tools", - "bazel_tools" - ], - [ - "tar.bzl+", "bazel_lib", "bazel_lib+" ], [ - "tar.bzl+", - "bazel_skylib", - "bazel_skylib+" - ], - [ - "tar.bzl+", - "tar.bzl", - "tar.bzl+" - ] - ] - } - }, - "@@aspect_rules_js+//npm:extensions.bzl%pnpm": { - "general": { - "bzlTransitiveDigest": "HC+l+mTivq1p/KbcVQ+iV5QwYR+oKESJh827FY68SH8=", - "usagesDigest": "PvqSdyUvIknVzZ66q+9FjDqiPWbKoaSj5J3EB+Z3ZAs=", - "recordedFileInputs": {}, - "recordedDirentsInputs": {}, - "envVariables": {}, - "generatedRepoSpecs": { - "pnpm": { - "repoRuleId": "@@aspect_rules_js+//npm/private:npm_import.bzl%npm_import_rule", - "attributes": { - "package": "pnpm", - "version": "10.29.3", - "root_package": "", - "link_workspace": "", - "link_packages": {}, - "integrity": "sha512-SY4ftMylqgbB3PJhHm+vxQly/+cYmZjECekN50VmREKY/+Q+bNKs3Hdboap8xeCSqLcFTIEbqMV3D4RpPTPS3A==", - "url": "", - "commit": "", - "patch_args": [ - "-p0" - ], - "patches": [], - "custom_postinstall": "", - "npm_auth": "", - "npm_auth_basic": "", - "npm_auth_username": "", - "npm_auth_password": "", - "lifecycle_hooks": [], - "extra_build_content": "load(\"@aspect_rules_js//js:defs.bzl\", \"js_binary\")\njs_binary(name = \"pnpm\", data = glob([\"package/**\"]), entry_point = \"package/dist/pnpm.cjs\", visibility = [\"//visibility:public\"])", - "generate_bzl_library_targets": false, - "extract_full_archive": true, - "exclude_package_contents": [] - } - }, - "pnpm__links": { - "repoRuleId": "@@aspect_rules_js+//npm/private:npm_import.bzl%npm_import_links", - "attributes": { - "package": "pnpm", - "version": "10.29.3", - "dev": false, - "root_package": "", - "link_packages": {}, - "deps": {}, - "transitive_closure": {}, - "lifecycle_build_target": false, - "lifecycle_hooks_env": [], - "lifecycle_hooks_execution_requirements": [ - "no-sandbox" - ], - "lifecycle_hooks_use_default_shell_env": false, - "bins": {}, - "package_visibility": [ - "//visibility:public" - ], - "replace_package": "", - "exclude_package_contents": [] - } - } - }, - "recordedRepoMappingEntries": [ - [ - "aspect_bazel_lib+", - "bazel_lib", - "bazel_lib+" - ], - [ - "aspect_bazel_lib+", + "aspect_rules_js+", "bazel_skylib", "bazel_skylib+" ], [ - "aspect_bazel_lib+", + "aspect_rules_js+", "bazel_tools", "bazel_tools" ], - [ - "aspect_bazel_lib+", - "tar.bzl", - "tar.bzl+" - ], [ "aspect_rules_js+", - "aspect_bazel_lib", - "aspect_bazel_lib+" + "protobuf", + "protobuf+" ], [ "aspect_rules_js+", - "aspect_rules_js", - "aspect_rules_js+" - ], - [ - "aspect_rules_js+", - "aspect_tools_telemetry_report", - "aspect_tools_telemetry++telemetry+aspect_tools_telemetry_report" - ], - [ - "aspect_rules_js+", - "bazel_features", - "bazel_features+" - ], - [ - "aspect_rules_js+", - "bazel_lib", - "bazel_lib+" - ], - [ - "aspect_rules_js+", - "bazel_skylib", - "bazel_skylib+" - ], - [ - "aspect_rules_js+", - "bazel_tools", - "bazel_tools" + "tar.bzl", + "tar.bzl+" ], [ "bazel_features+", @@ -538,6 +386,11 @@ "bazel_features_version", "bazel_features++version_extension+bazel_features_version" ], + [ + "bazel_lib+", + "bazel_lib", + "bazel_lib+" + ], [ "bazel_lib+", "bazel_skylib", @@ -548,6 +401,11 @@ "bazel_tools", "bazel_tools" ], + [ + "protobuf+", + "proto_bazel_features", + "bazel_features+" + ], [ "tar.bzl+", "bazel_lib", @@ -568,11 +426,9 @@ }, "@@aspect_rules_ts+//ts:extensions.bzl%ext": { "general": { - "bzlTransitiveDigest": "QDTi1Wl/eEY4IgbXjRhegUQfHj+bB8ZEVyiSGLZc6qo=", - "usagesDigest": "aaqqxEFKCRGFkeAf0pKmXvZZTLGYIk3pQsDFG28ZbNg=", - "recordedFileInputs": { - "@@rules_browsers+//package.json": "84dc1ba9b1c667a25894e97218bd8f247d54f24bb694efb397a881be3c06a4c5" - }, + "bzlTransitiveDigest": "GbfZLeEI0W26fAQ89dUljyLGSAkzkr3CkF+VDQ0IFlI=", + "usagesDigest": "6j6Q6JXHp4faBWfj1+kQVqEjMSZnJZwfbQoEdHVj1ks=", + "recordedFileInputs": {}, "recordedDirentsInputs": {}, "envVariables": {}, "generatedRepoSpecs": { @@ -589,8 +445,8 @@ "rules_angular_npm_typescript": { "repoRuleId": "@@aspect_rules_ts+//ts/private:npm_repositories.bzl%http_archive_version", "attributes": { - "version": "5.9.2", - "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", + "version": "5.9.3", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "urls": [ "https://registry.npmjs.org/typescript/-/typescript-{}.tgz" ] @@ -609,9 +465,8 @@ "npm_rules_browsers_typescript": { "repoRuleId": "@@aspect_rules_ts+//ts/private:npm_repositories.bzl%http_archive_version", "attributes": { - "version": "", - "version_from": "@@rules_browsers+//:package.json", - "integrity": "", + "version": "5.9.3", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "urls": [ "https://registry.npmjs.org/typescript/-/typescript-{}.tgz" ] @@ -635,7 +490,7 @@ "@@aspect_tools_telemetry+//:extension.bzl%telemetry": { "general": { "bzlTransitiveDigest": "cl5A2O84vDL6Tt+Qga8FCj1DUDGqn+e7ly5rZ+4xvcc=", - "usagesDigest": "PRLGsERE1Dznyx/OIAl7BPo8mzMvOklnNnZ8zdCpPTE=", + "usagesDigest": "Htk4MyL4d05V7Kpv8OWMQ8y+7IkUx9BOmnhlLXYMO80=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, "envVariables": {}, @@ -644,10 +499,10 @@ "repoRuleId": "@@aspect_tools_telemetry+//:extension.bzl%tel_repository", "attributes": { "deps": { - "aspect_rules_js": "2.9.2", - "aspect_rules_ts": "3.8.4", - "aspect_rules_esbuild": "0.25.0", - "aspect_rules_jasmine": "2.0.2", + "aspect_rules_js": "3.0.3", + "aspect_rules_ts": "3.8.7", + "aspect_rules_esbuild": "0.25.1", + "aspect_rules_jasmine": "2.0.4", "aspect_tools_telemetry": "0.3.3" } } @@ -669,7 +524,7 @@ }, "@@pybind11_bazel+//:python_configure.bzl%extension": { "general": { - "bzlTransitiveDigest": "c9ZWWeXeu6bctL4/SsY2otFWyeFN0JJ20+ymGyJZtWk=", + "bzlTransitiveDigest": "D2/qWHU6yQFwRG7Bb+caqrYMha5avsASao2vERrxK24=", "usagesDigest": "fycyB39YnXIJkfWCIXLUKJMZzANcuLy9ZE73hRucjFk=", "recordedFileInputs": { "@@pybind11_bazel+//MODULE.bazel": "88af1c246226d87e65be78ed49ecd1e6f5e98648558c14ce99176da041dc378e" @@ -704,7 +559,7 @@ "@@rules_angular+//setup:extensions.bzl%rules_angular": { "general": { "bzlTransitiveDigest": "fkaH7HMicL3g7/NDaFzlq39kcLopMyQ3KdbDn+5CRzA=", - "usagesDigest": "ZinuLP7QHxaW5achD0Vz19qElMu4r2LvGvh96Z5zYlA=", + "usagesDigest": "it5nR/3UaQWj2eaaMj+EnoZuL2z/AeTuz7uOnqd+nxo=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, "envVariables": {}, @@ -720,7 +575,7 @@ "repoRuleId": "@@rules_angular+//setup:repositories.bzl%configurable_deps_repo", "attributes": { "angular_compiler_cli": "@@rules_angular+//:node_modules/@angular/compiler-cli", - "typescript": "@@rules_angular+//:node_modules/typescript-local" + "typescript": "@@rules_angular+//:node_modules/typescript" } }, "dev_infra_rules_angular_configurable_deps": { @@ -736,8 +591,8 @@ }, "@@rules_browsers+//browsers:extensions.bzl%browsers": { "general": { - "bzlTransitiveDigest": "agkaLQ8wE1r/5IX6pkERzFxI/z0M42Em+ICNO6TXsVo=", - "usagesDigest": "FS7q5WaIwg3KirS3njhuPFkTIBYvDaTInVGrlzu0XL8=", + "bzlTransitiveDigest": "Bm6fiKpWy96aLohOlLCP36ARVxRLZm/R+smhsb2HzmI=", + "usagesDigest": "FmXYJVoVJlnfUU8x8gObSvu4qWcco/9Faw61aC/wBF0=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, "envVariables": {}, @@ -745,9 +600,9 @@ "rules_browsers_chrome_linux": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "0a2ff0fc9eb5958b7b420f20e3968f424be7423fef89739e71565a48aa073a57", + "sha256": "1ac33f89306327af43be159c03ca4a26486de0858f42fe52394acdef50364143", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/145.0.7586.0/linux64/chrome-headless-shell-linux64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/147.0.7687.0/linux64/chrome-headless-shell-linux64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-linux64/chrome-headless-shell" @@ -763,9 +618,9 @@ "rules_browsers_chrome_mac": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "e6076b1201d86f74c5eab982a239d5af83e66b1aa4d780bcb792698790e01d87", + "sha256": "169ff49c465cfda52931395e61861e146dfc5013e92c01ca792db5acea858d0b", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/145.0.7586.0/mac-x64/chrome-headless-shell-mac-x64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/147.0.7687.0/mac-x64/chrome-headless-shell-mac-x64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-mac-x64/chrome-headless-shell" @@ -781,9 +636,9 @@ "rules_browsers_chrome_mac_arm": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "b74dbcf5543d916b02d0a133e2e7c6a4de251f06733f72c2c15ea8c42213f63b", + "sha256": "aeaaaaa4d68193a21bed04c44ddeb1230232707b4ea1d845a92925787509cd8e", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/145.0.7586.0/mac-arm64/chrome-headless-shell-mac-arm64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/147.0.7687.0/mac-arm64/chrome-headless-shell-mac-arm64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-mac-arm64/chrome-headless-shell" @@ -799,9 +654,9 @@ "rules_browsers_chrome_win64": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "df1e612dc3b1615e182a1f11821052995913c39df37caa52699de21a68d030d2", + "sha256": "4d6d79bcbcb22084df6e3a3d3a2caff67d6c0fa488d63f0c7ec1526f9553db8c", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/145.0.7586.0/win64/chrome-headless-shell-win64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/147.0.7687.0/win64/chrome-headless-shell-win64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-win64/chrome-headless-shell.exe" @@ -817,9 +672,9 @@ "rules_browsers_chromedriver_linux": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "69c504306399d979a2766fea603c3fb9d3d87d46c75bddc9f2a049b4f636d57c", + "sha256": "0607ccf6810a07ae08cac6443beac8b23f88dd53c7f1e0299e22d65f7cd2d020", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/145.0.7586.0/linux64/chromedriver-linux64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/147.0.7687.0/linux64/chromedriver-linux64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-linux64/chromedriver" @@ -833,9 +688,9 @@ "rules_browsers_chromedriver_mac": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "5fc9d6f594fc5f2568a15145f25116dd8e9c9a60baa8da4bb21a17650fb00e7e", + "sha256": "0f512a9dd683ed4c41e609d8d02c07807497dbad3ab2f95f0d583486be7b8cff", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/145.0.7586.0/mac-x64/chromedriver-mac-x64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/147.0.7687.0/mac-x64/chromedriver-mac-x64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-mac-x64/chromedriver" @@ -849,9 +704,9 @@ "rules_browsers_chromedriver_mac_arm": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "14e92294c2c3639ca4e7d27e850588b619d698e2f8905cee368f07db2e1bf1e9", + "sha256": "7d6fc6d17de1733eb6739d1ea16d085c8df1568bcf9fa0d130c2784b27f38268", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/145.0.7586.0/mac-arm64/chromedriver-mac-arm64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/147.0.7687.0/mac-arm64/chromedriver-mac-arm64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-mac-arm64/chromedriver" @@ -865,9 +720,9 @@ "rules_browsers_chromedriver_win64": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "cf641d2e176db95bcc158cd90eafd347ad4928fa0458a5f3bfd56c6d983e70db", + "sha256": "f4e9fb7bbf692fde7979b24e8d737b3cef4baafbc7a370e5d0abc4a8450fd830", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/145.0.7586.0/win64/chromedriver-win64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/147.0.7687.0/win64/chromedriver-win64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-win64/chromedriver.exe" @@ -881,9 +736,9 @@ "rules_browsers_firefox_linux": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "8d56f479cc398a537a60a3fa20dca92d8a41925113d3a67f534881a4e4d7e344", + "sha256": "f055b9c0d7346a10d22edc7f10e08679af2ea495367381ab2be9cab3ec6add97", "urls": [ - "https://archive.mozilla.org/pub/firefox/releases/146.0/linux-x86_64/en-US/firefox-146.0.tar.xz" + "https://archive.mozilla.org/pub/firefox/releases/147.0/linux-x86_64/en-US/firefox-147.0.tar.xz" ], "named_files": { "FIREFOX": "firefox/firefox" @@ -897,9 +752,9 @@ "rules_browsers_firefox_mac": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "4b1645313887972d466cd82166ea571485c2c40a167f84624e3f3ca739993cc9", + "sha256": "48485e2068bc726e2f30cf5855fc2da1fc75c1272bc243a5394f428ffae3ba35", "urls": [ - "https://archive.mozilla.org/pub/firefox/releases/146.0/mac/en-US/Firefox%20146.0.dmg" + "https://archive.mozilla.org/pub/firefox/releases/147.0/mac/en-US/Firefox%20147.0.dmg" ], "named_files": { "FIREFOX": "Firefox.app/Contents/MacOS/firefox" @@ -913,9 +768,9 @@ "rules_browsers_firefox_mac_arm": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "4b1645313887972d466cd82166ea571485c2c40a167f84624e3f3ca739993cc9", + "sha256": "48485e2068bc726e2f30cf5855fc2da1fc75c1272bc243a5394f428ffae3ba35", "urls": [ - "https://archive.mozilla.org/pub/firefox/releases/146.0/mac/en-US/Firefox%20146.0.dmg" + "https://archive.mozilla.org/pub/firefox/releases/147.0/mac/en-US/Firefox%20147.0.dmg" ], "named_files": { "FIREFOX": "Firefox.app/Contents/MacOS/firefox" @@ -929,9 +784,9 @@ "rules_browsers_firefox_win64": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "216870c89648f32450cfefb5cec417fcd66d480d5dc83f894bf99f5fd7f38dbb", + "sha256": "36ff9e150875aa48a0af9eec3eb67f66dddd8efac5c743265371a72ae3e796c4", "urls": [ - "https://archive.mozilla.org/pub/firefox/releases/146.0/win64/en-US/Firefox%20Setup%20146.0.exe" + "https://archive.mozilla.org/pub/firefox/releases/147.0/win64/en-US/Firefox%20Setup%20147.0.exe" ], "named_files": { "FIREFOX": "core/firefox.exe" @@ -948,7 +803,7 @@ }, "@@rules_fuzzing+//fuzzing/private:extensions.bzl%non_module_dependencies": { "general": { - "bzlTransitiveDigest": "WHRlQQnxW7e7XMRBhq7SARkDarLDOAbg6iLaJpk5QYM=", + "bzlTransitiveDigest": "4LouzhF/yT117s7peGnNs9ROomiJXC6Zl5R0oI21jho=", "usagesDigest": "wy6ISK6UOcBEjj/mvJ/S3WeXoO67X+1llb9yPyFtPgc=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, @@ -1031,7 +886,7 @@ }, "@@rules_kotlin+//src/main/starlark/core/repositories:bzlmod_setup.bzl%rules_kotlin_extensions": { "general": { - "bzlTransitiveDigest": "rL/34P1aFDq2GqVC2zCFgQ8nTuOC6ziogocpvG50Qz8=", + "bzlTransitiveDigest": "nvW/NrBXlAmiQw99EMGKkLaD2KbNp2mQDlxdfpr+0Ls=", "usagesDigest": "QI2z8ZUR+mqtbwsf2fLqYdJAkPOHdOV+tF2yVAUgRzw=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, @@ -1096,7 +951,7 @@ "@@rules_nodejs+//nodejs:extensions.bzl%node": { "general": { "bzlTransitiveDigest": "4pUxCNc22K4I+6+4Nxu52Hur12tFRfa1JMsN5mdDv60=", - "usagesDigest": "6UAmdIABVpqhlkQ3A3NGscf00ds9dFEt+lei3DibyqM=", + "usagesDigest": "sQiW0V9N31hjPrg9r9iPXH5IdB4YKwYtLhn7G+osx1o=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, "envVariables": {}, @@ -1106,46 +961,46 @@ "attributes": { "node_download_auth": {}, "node_repositories": { - "22.22.0-darwin_arm64": [ - "node-v22.22.0-darwin-arm64.tar.gz", - "node-v22.22.0-darwin-arm64", - "5ed4db0fcf1eaf84d91ad12462631d73bf4576c1377e192d222e48026a902640" + "22.22.2-darwin_arm64": [ + "node-v22.22.2-darwin-arm64.tar.gz", + "node-v22.22.2-darwin-arm64", + "db4b275b83736df67533529a18cc55de2549a8329ace6c7bcc68f8d22d3c9000" ], - "22.22.0-darwin_amd64": [ - "node-v22.22.0-darwin-x64.tar.gz", - "node-v22.22.0-darwin-x64", - "5ea50c9d6dea3dfa3abb66b2656f7a4e1c8cef23432b558d45fb538c7b5dedce" + "22.22.2-darwin_amd64": [ + "node-v22.22.2-darwin-x64.tar.gz", + "node-v22.22.2-darwin-x64", + "12a6abb9c2902cf48a21120da13f87fde1ed1b71a13330712949e8db818708ba" ], - "22.22.0-linux_arm64": [ - "node-v22.22.0-linux-arm64.tar.xz", - "node-v22.22.0-linux-arm64", - "1bf1eb9ee63ffc4e5d324c0b9b62cf4a289f44332dfef9607cea1a0d9596ba6f" + "22.22.2-linux_arm64": [ + "node-v22.22.2-linux-arm64.tar.xz", + "node-v22.22.2-linux-arm64", + "e9e1930fd321a470e29bb68f30318bf58e3ecb4acb4f1533fb19c58328a091fe" ], - "22.22.0-linux_ppc64le": [ - "node-v22.22.0-linux-ppc64le.tar.xz", - "node-v22.22.0-linux-ppc64le", - "d83b9957431cc18e1fc143a4b99f89cde7b8a18f53ef392231b4336afd058865" + "22.22.2-linux_ppc64le": [ + "node-v22.22.2-linux-ppc64le.tar.xz", + "node-v22.22.2-linux-ppc64le", + "14045b5a5030d35ca0030fb7e870bd11a651eb9b57323ebc0021e8d78ac6bac9" ], - "22.22.0-linux_s390x": [ - "node-v22.22.0-linux-s390x.tar.xz", - "node-v22.22.0-linux-s390x", - "5aa0e520689448c4233e8d73f284e8e0634fdcd32b479735698494be5641f3e4" + "22.22.2-linux_s390x": [ + "node-v22.22.2-linux-s390x.tar.xz", + "node-v22.22.2-linux-s390x", + "9e4a07c291b8949289c6ea8ee61b1d14666a4810feae776a8d1eb1f57e03a2fb" ], - "22.22.0-linux_amd64": [ - "node-v22.22.0-linux-x64.tar.xz", - "node-v22.22.0-linux-x64", - "9aa8e9d2298ab68c600bd6fb86a6c13bce11a4eca1ba9b39d79fa021755d7c37" + "22.22.2-linux_amd64": [ + "node-v22.22.2-linux-x64.tar.xz", + "node-v22.22.2-linux-x64", + "88fd1ce767091fd8d4a99fdb2356e98c819f93f3b1f8663853a2dee9b438068a" ], - "22.22.0-windows_amd64": [ - "node-v22.22.0-win-x64.zip", - "node-v22.22.0-win-x64", - "c97fa376d2becdc8863fcd3ca2dd9a83a9f3468ee7ccf7a6d076ec66a645c77a" + "22.22.2-windows_amd64": [ + "node-v22.22.2-win-x64.zip", + "node-v22.22.2-win-x64", + "7c93e9d92bf68c07182b471aa187e35ee6cd08ef0f24ab060dfff605fcc1c57c" ] }, "node_urls": [ "https://nodejs.org/dist/v{version}/{filename}" ], - "node_version": "22.22.0", + "node_version": "22.22.2", "include_headers": false, "platform": "linux_amd64" } @@ -1155,46 +1010,46 @@ "attributes": { "node_download_auth": {}, "node_repositories": { - "22.22.0-darwin_arm64": [ - "node-v22.22.0-darwin-arm64.tar.gz", - "node-v22.22.0-darwin-arm64", - "5ed4db0fcf1eaf84d91ad12462631d73bf4576c1377e192d222e48026a902640" + "22.22.2-darwin_arm64": [ + "node-v22.22.2-darwin-arm64.tar.gz", + "node-v22.22.2-darwin-arm64", + "db4b275b83736df67533529a18cc55de2549a8329ace6c7bcc68f8d22d3c9000" ], - "22.22.0-darwin_amd64": [ - "node-v22.22.0-darwin-x64.tar.gz", - "node-v22.22.0-darwin-x64", - "5ea50c9d6dea3dfa3abb66b2656f7a4e1c8cef23432b558d45fb538c7b5dedce" + "22.22.2-darwin_amd64": [ + "node-v22.22.2-darwin-x64.tar.gz", + "node-v22.22.2-darwin-x64", + "12a6abb9c2902cf48a21120da13f87fde1ed1b71a13330712949e8db818708ba" ], - "22.22.0-linux_arm64": [ - "node-v22.22.0-linux-arm64.tar.xz", - "node-v22.22.0-linux-arm64", - "1bf1eb9ee63ffc4e5d324c0b9b62cf4a289f44332dfef9607cea1a0d9596ba6f" + "22.22.2-linux_arm64": [ + "node-v22.22.2-linux-arm64.tar.xz", + "node-v22.22.2-linux-arm64", + "e9e1930fd321a470e29bb68f30318bf58e3ecb4acb4f1533fb19c58328a091fe" ], - "22.22.0-linux_ppc64le": [ - "node-v22.22.0-linux-ppc64le.tar.xz", - "node-v22.22.0-linux-ppc64le", - "d83b9957431cc18e1fc143a4b99f89cde7b8a18f53ef392231b4336afd058865" + "22.22.2-linux_ppc64le": [ + "node-v22.22.2-linux-ppc64le.tar.xz", + "node-v22.22.2-linux-ppc64le", + "14045b5a5030d35ca0030fb7e870bd11a651eb9b57323ebc0021e8d78ac6bac9" ], - "22.22.0-linux_s390x": [ - "node-v22.22.0-linux-s390x.tar.xz", - "node-v22.22.0-linux-s390x", - "5aa0e520689448c4233e8d73f284e8e0634fdcd32b479735698494be5641f3e4" + "22.22.2-linux_s390x": [ + "node-v22.22.2-linux-s390x.tar.xz", + "node-v22.22.2-linux-s390x", + "9e4a07c291b8949289c6ea8ee61b1d14666a4810feae776a8d1eb1f57e03a2fb" ], - "22.22.0-linux_amd64": [ - "node-v22.22.0-linux-x64.tar.xz", - "node-v22.22.0-linux-x64", - "9aa8e9d2298ab68c600bd6fb86a6c13bce11a4eca1ba9b39d79fa021755d7c37" + "22.22.2-linux_amd64": [ + "node-v22.22.2-linux-x64.tar.xz", + "node-v22.22.2-linux-x64", + "88fd1ce767091fd8d4a99fdb2356e98c819f93f3b1f8663853a2dee9b438068a" ], - "22.22.0-windows_amd64": [ - "node-v22.22.0-win-x64.zip", - "node-v22.22.0-win-x64", - "c97fa376d2becdc8863fcd3ca2dd9a83a9f3468ee7ccf7a6d076ec66a645c77a" + "22.22.2-windows_amd64": [ + "node-v22.22.2-win-x64.zip", + "node-v22.22.2-win-x64", + "7c93e9d92bf68c07182b471aa187e35ee6cd08ef0f24ab060dfff605fcc1c57c" ] }, "node_urls": [ "https://nodejs.org/dist/v{version}/{filename}" ], - "node_version": "22.22.0", + "node_version": "22.22.2", "include_headers": false, "platform": "linux_arm64" } @@ -1204,46 +1059,46 @@ "attributes": { "node_download_auth": {}, "node_repositories": { - "22.22.0-darwin_arm64": [ - "node-v22.22.0-darwin-arm64.tar.gz", - "node-v22.22.0-darwin-arm64", - "5ed4db0fcf1eaf84d91ad12462631d73bf4576c1377e192d222e48026a902640" + "22.22.2-darwin_arm64": [ + "node-v22.22.2-darwin-arm64.tar.gz", + "node-v22.22.2-darwin-arm64", + "db4b275b83736df67533529a18cc55de2549a8329ace6c7bcc68f8d22d3c9000" ], - "22.22.0-darwin_amd64": [ - "node-v22.22.0-darwin-x64.tar.gz", - "node-v22.22.0-darwin-x64", - "5ea50c9d6dea3dfa3abb66b2656f7a4e1c8cef23432b558d45fb538c7b5dedce" + "22.22.2-darwin_amd64": [ + "node-v22.22.2-darwin-x64.tar.gz", + "node-v22.22.2-darwin-x64", + "12a6abb9c2902cf48a21120da13f87fde1ed1b71a13330712949e8db818708ba" ], - "22.22.0-linux_arm64": [ - "node-v22.22.0-linux-arm64.tar.xz", - "node-v22.22.0-linux-arm64", - "1bf1eb9ee63ffc4e5d324c0b9b62cf4a289f44332dfef9607cea1a0d9596ba6f" + "22.22.2-linux_arm64": [ + "node-v22.22.2-linux-arm64.tar.xz", + "node-v22.22.2-linux-arm64", + "e9e1930fd321a470e29bb68f30318bf58e3ecb4acb4f1533fb19c58328a091fe" ], - "22.22.0-linux_ppc64le": [ - "node-v22.22.0-linux-ppc64le.tar.xz", - "node-v22.22.0-linux-ppc64le", - "d83b9957431cc18e1fc143a4b99f89cde7b8a18f53ef392231b4336afd058865" + "22.22.2-linux_ppc64le": [ + "node-v22.22.2-linux-ppc64le.tar.xz", + "node-v22.22.2-linux-ppc64le", + "14045b5a5030d35ca0030fb7e870bd11a651eb9b57323ebc0021e8d78ac6bac9" ], - "22.22.0-linux_s390x": [ - "node-v22.22.0-linux-s390x.tar.xz", - "node-v22.22.0-linux-s390x", - "5aa0e520689448c4233e8d73f284e8e0634fdcd32b479735698494be5641f3e4" + "22.22.2-linux_s390x": [ + "node-v22.22.2-linux-s390x.tar.xz", + "node-v22.22.2-linux-s390x", + "9e4a07c291b8949289c6ea8ee61b1d14666a4810feae776a8d1eb1f57e03a2fb" ], - "22.22.0-linux_amd64": [ - "node-v22.22.0-linux-x64.tar.xz", - "node-v22.22.0-linux-x64", - "9aa8e9d2298ab68c600bd6fb86a6c13bce11a4eca1ba9b39d79fa021755d7c37" + "22.22.2-linux_amd64": [ + "node-v22.22.2-linux-x64.tar.xz", + "node-v22.22.2-linux-x64", + "88fd1ce767091fd8d4a99fdb2356e98c819f93f3b1f8663853a2dee9b438068a" ], - "22.22.0-windows_amd64": [ - "node-v22.22.0-win-x64.zip", - "node-v22.22.0-win-x64", - "c97fa376d2becdc8863fcd3ca2dd9a83a9f3468ee7ccf7a6d076ec66a645c77a" + "22.22.2-windows_amd64": [ + "node-v22.22.2-win-x64.zip", + "node-v22.22.2-win-x64", + "7c93e9d92bf68c07182b471aa187e35ee6cd08ef0f24ab060dfff605fcc1c57c" ] }, "node_urls": [ "https://nodejs.org/dist/v{version}/{filename}" ], - "node_version": "22.22.0", + "node_version": "22.22.2", "include_headers": false, "platform": "linux_s390x" } @@ -1253,46 +1108,46 @@ "attributes": { "node_download_auth": {}, "node_repositories": { - "22.22.0-darwin_arm64": [ - "node-v22.22.0-darwin-arm64.tar.gz", - "node-v22.22.0-darwin-arm64", - "5ed4db0fcf1eaf84d91ad12462631d73bf4576c1377e192d222e48026a902640" + "22.22.2-darwin_arm64": [ + "node-v22.22.2-darwin-arm64.tar.gz", + "node-v22.22.2-darwin-arm64", + "db4b275b83736df67533529a18cc55de2549a8329ace6c7bcc68f8d22d3c9000" ], - "22.22.0-darwin_amd64": [ - "node-v22.22.0-darwin-x64.tar.gz", - "node-v22.22.0-darwin-x64", - "5ea50c9d6dea3dfa3abb66b2656f7a4e1c8cef23432b558d45fb538c7b5dedce" + "22.22.2-darwin_amd64": [ + "node-v22.22.2-darwin-x64.tar.gz", + "node-v22.22.2-darwin-x64", + "12a6abb9c2902cf48a21120da13f87fde1ed1b71a13330712949e8db818708ba" ], - "22.22.0-linux_arm64": [ - "node-v22.22.0-linux-arm64.tar.xz", - "node-v22.22.0-linux-arm64", - "1bf1eb9ee63ffc4e5d324c0b9b62cf4a289f44332dfef9607cea1a0d9596ba6f" + "22.22.2-linux_arm64": [ + "node-v22.22.2-linux-arm64.tar.xz", + "node-v22.22.2-linux-arm64", + "e9e1930fd321a470e29bb68f30318bf58e3ecb4acb4f1533fb19c58328a091fe" ], - "22.22.0-linux_ppc64le": [ - "node-v22.22.0-linux-ppc64le.tar.xz", - "node-v22.22.0-linux-ppc64le", - "d83b9957431cc18e1fc143a4b99f89cde7b8a18f53ef392231b4336afd058865" + "22.22.2-linux_ppc64le": [ + "node-v22.22.2-linux-ppc64le.tar.xz", + "node-v22.22.2-linux-ppc64le", + "14045b5a5030d35ca0030fb7e870bd11a651eb9b57323ebc0021e8d78ac6bac9" ], - "22.22.0-linux_s390x": [ - "node-v22.22.0-linux-s390x.tar.xz", - "node-v22.22.0-linux-s390x", - "5aa0e520689448c4233e8d73f284e8e0634fdcd32b479735698494be5641f3e4" + "22.22.2-linux_s390x": [ + "node-v22.22.2-linux-s390x.tar.xz", + "node-v22.22.2-linux-s390x", + "9e4a07c291b8949289c6ea8ee61b1d14666a4810feae776a8d1eb1f57e03a2fb" ], - "22.22.0-linux_amd64": [ - "node-v22.22.0-linux-x64.tar.xz", - "node-v22.22.0-linux-x64", - "9aa8e9d2298ab68c600bd6fb86a6c13bce11a4eca1ba9b39d79fa021755d7c37" + "22.22.2-linux_amd64": [ + "node-v22.22.2-linux-x64.tar.xz", + "node-v22.22.2-linux-x64", + "88fd1ce767091fd8d4a99fdb2356e98c819f93f3b1f8663853a2dee9b438068a" ], - "22.22.0-windows_amd64": [ - "node-v22.22.0-win-x64.zip", - "node-v22.22.0-win-x64", - "c97fa376d2becdc8863fcd3ca2dd9a83a9f3468ee7ccf7a6d076ec66a645c77a" + "22.22.2-windows_amd64": [ + "node-v22.22.2-win-x64.zip", + "node-v22.22.2-win-x64", + "7c93e9d92bf68c07182b471aa187e35ee6cd08ef0f24ab060dfff605fcc1c57c" ] }, "node_urls": [ "https://nodejs.org/dist/v{version}/{filename}" ], - "node_version": "22.22.0", + "node_version": "22.22.2", "include_headers": false, "platform": "linux_ppc64le" } @@ -1302,46 +1157,46 @@ "attributes": { "node_download_auth": {}, "node_repositories": { - "22.22.0-darwin_arm64": [ - "node-v22.22.0-darwin-arm64.tar.gz", - "node-v22.22.0-darwin-arm64", - "5ed4db0fcf1eaf84d91ad12462631d73bf4576c1377e192d222e48026a902640" + "22.22.2-darwin_arm64": [ + "node-v22.22.2-darwin-arm64.tar.gz", + "node-v22.22.2-darwin-arm64", + "db4b275b83736df67533529a18cc55de2549a8329ace6c7bcc68f8d22d3c9000" ], - "22.22.0-darwin_amd64": [ - "node-v22.22.0-darwin-x64.tar.gz", - "node-v22.22.0-darwin-x64", - "5ea50c9d6dea3dfa3abb66b2656f7a4e1c8cef23432b558d45fb538c7b5dedce" + "22.22.2-darwin_amd64": [ + "node-v22.22.2-darwin-x64.tar.gz", + "node-v22.22.2-darwin-x64", + "12a6abb9c2902cf48a21120da13f87fde1ed1b71a13330712949e8db818708ba" ], - "22.22.0-linux_arm64": [ - "node-v22.22.0-linux-arm64.tar.xz", - "node-v22.22.0-linux-arm64", - "1bf1eb9ee63ffc4e5d324c0b9b62cf4a289f44332dfef9607cea1a0d9596ba6f" + "22.22.2-linux_arm64": [ + "node-v22.22.2-linux-arm64.tar.xz", + "node-v22.22.2-linux-arm64", + "e9e1930fd321a470e29bb68f30318bf58e3ecb4acb4f1533fb19c58328a091fe" ], - "22.22.0-linux_ppc64le": [ - "node-v22.22.0-linux-ppc64le.tar.xz", - "node-v22.22.0-linux-ppc64le", - "d83b9957431cc18e1fc143a4b99f89cde7b8a18f53ef392231b4336afd058865" + "22.22.2-linux_ppc64le": [ + "node-v22.22.2-linux-ppc64le.tar.xz", + "node-v22.22.2-linux-ppc64le", + "14045b5a5030d35ca0030fb7e870bd11a651eb9b57323ebc0021e8d78ac6bac9" ], - "22.22.0-linux_s390x": [ - "node-v22.22.0-linux-s390x.tar.xz", - "node-v22.22.0-linux-s390x", - "5aa0e520689448c4233e8d73f284e8e0634fdcd32b479735698494be5641f3e4" + "22.22.2-linux_s390x": [ + "node-v22.22.2-linux-s390x.tar.xz", + "node-v22.22.2-linux-s390x", + "9e4a07c291b8949289c6ea8ee61b1d14666a4810feae776a8d1eb1f57e03a2fb" ], - "22.22.0-linux_amd64": [ - "node-v22.22.0-linux-x64.tar.xz", - "node-v22.22.0-linux-x64", - "9aa8e9d2298ab68c600bd6fb86a6c13bce11a4eca1ba9b39d79fa021755d7c37" + "22.22.2-linux_amd64": [ + "node-v22.22.2-linux-x64.tar.xz", + "node-v22.22.2-linux-x64", + "88fd1ce767091fd8d4a99fdb2356e98c819f93f3b1f8663853a2dee9b438068a" ], - "22.22.0-windows_amd64": [ - "node-v22.22.0-win-x64.zip", - "node-v22.22.0-win-x64", - "c97fa376d2becdc8863fcd3ca2dd9a83a9f3468ee7ccf7a6d076ec66a645c77a" + "22.22.2-windows_amd64": [ + "node-v22.22.2-win-x64.zip", + "node-v22.22.2-win-x64", + "7c93e9d92bf68c07182b471aa187e35ee6cd08ef0f24ab060dfff605fcc1c57c" ] }, "node_urls": [ "https://nodejs.org/dist/v{version}/{filename}" ], - "node_version": "22.22.0", + "node_version": "22.22.2", "include_headers": false, "platform": "darwin_amd64" } @@ -1351,46 +1206,46 @@ "attributes": { "node_download_auth": {}, "node_repositories": { - "22.22.0-darwin_arm64": [ - "node-v22.22.0-darwin-arm64.tar.gz", - "node-v22.22.0-darwin-arm64", - "5ed4db0fcf1eaf84d91ad12462631d73bf4576c1377e192d222e48026a902640" + "22.22.2-darwin_arm64": [ + "node-v22.22.2-darwin-arm64.tar.gz", + "node-v22.22.2-darwin-arm64", + "db4b275b83736df67533529a18cc55de2549a8329ace6c7bcc68f8d22d3c9000" ], - "22.22.0-darwin_amd64": [ - "node-v22.22.0-darwin-x64.tar.gz", - "node-v22.22.0-darwin-x64", - "5ea50c9d6dea3dfa3abb66b2656f7a4e1c8cef23432b558d45fb538c7b5dedce" + "22.22.2-darwin_amd64": [ + "node-v22.22.2-darwin-x64.tar.gz", + "node-v22.22.2-darwin-x64", + "12a6abb9c2902cf48a21120da13f87fde1ed1b71a13330712949e8db818708ba" ], - "22.22.0-linux_arm64": [ - "node-v22.22.0-linux-arm64.tar.xz", - "node-v22.22.0-linux-arm64", - "1bf1eb9ee63ffc4e5d324c0b9b62cf4a289f44332dfef9607cea1a0d9596ba6f" + "22.22.2-linux_arm64": [ + "node-v22.22.2-linux-arm64.tar.xz", + "node-v22.22.2-linux-arm64", + "e9e1930fd321a470e29bb68f30318bf58e3ecb4acb4f1533fb19c58328a091fe" ], - "22.22.0-linux_ppc64le": [ - "node-v22.22.0-linux-ppc64le.tar.xz", - "node-v22.22.0-linux-ppc64le", - "d83b9957431cc18e1fc143a4b99f89cde7b8a18f53ef392231b4336afd058865" + "22.22.2-linux_ppc64le": [ + "node-v22.22.2-linux-ppc64le.tar.xz", + "node-v22.22.2-linux-ppc64le", + "14045b5a5030d35ca0030fb7e870bd11a651eb9b57323ebc0021e8d78ac6bac9" ], - "22.22.0-linux_s390x": [ - "node-v22.22.0-linux-s390x.tar.xz", - "node-v22.22.0-linux-s390x", - "5aa0e520689448c4233e8d73f284e8e0634fdcd32b479735698494be5641f3e4" + "22.22.2-linux_s390x": [ + "node-v22.22.2-linux-s390x.tar.xz", + "node-v22.22.2-linux-s390x", + "9e4a07c291b8949289c6ea8ee61b1d14666a4810feae776a8d1eb1f57e03a2fb" ], - "22.22.0-linux_amd64": [ - "node-v22.22.0-linux-x64.tar.xz", - "node-v22.22.0-linux-x64", - "9aa8e9d2298ab68c600bd6fb86a6c13bce11a4eca1ba9b39d79fa021755d7c37" + "22.22.2-linux_amd64": [ + "node-v22.22.2-linux-x64.tar.xz", + "node-v22.22.2-linux-x64", + "88fd1ce767091fd8d4a99fdb2356e98c819f93f3b1f8663853a2dee9b438068a" ], - "22.22.0-windows_amd64": [ - "node-v22.22.0-win-x64.zip", - "node-v22.22.0-win-x64", - "c97fa376d2becdc8863fcd3ca2dd9a83a9f3468ee7ccf7a6d076ec66a645c77a" + "22.22.2-windows_amd64": [ + "node-v22.22.2-win-x64.zip", + "node-v22.22.2-win-x64", + "7c93e9d92bf68c07182b471aa187e35ee6cd08ef0f24ab060dfff605fcc1c57c" ] }, "node_urls": [ "https://nodejs.org/dist/v{version}/{filename}" ], - "node_version": "22.22.0", + "node_version": "22.22.2", "include_headers": false, "platform": "darwin_arm64" } @@ -1400,46 +1255,46 @@ "attributes": { "node_download_auth": {}, "node_repositories": { - "22.22.0-darwin_arm64": [ - "node-v22.22.0-darwin-arm64.tar.gz", - "node-v22.22.0-darwin-arm64", - "5ed4db0fcf1eaf84d91ad12462631d73bf4576c1377e192d222e48026a902640" + "22.22.2-darwin_arm64": [ + "node-v22.22.2-darwin-arm64.tar.gz", + "node-v22.22.2-darwin-arm64", + "db4b275b83736df67533529a18cc55de2549a8329ace6c7bcc68f8d22d3c9000" ], - "22.22.0-darwin_amd64": [ - "node-v22.22.0-darwin-x64.tar.gz", - "node-v22.22.0-darwin-x64", - "5ea50c9d6dea3dfa3abb66b2656f7a4e1c8cef23432b558d45fb538c7b5dedce" + "22.22.2-darwin_amd64": [ + "node-v22.22.2-darwin-x64.tar.gz", + "node-v22.22.2-darwin-x64", + "12a6abb9c2902cf48a21120da13f87fde1ed1b71a13330712949e8db818708ba" ], - "22.22.0-linux_arm64": [ - "node-v22.22.0-linux-arm64.tar.xz", - "node-v22.22.0-linux-arm64", - "1bf1eb9ee63ffc4e5d324c0b9b62cf4a289f44332dfef9607cea1a0d9596ba6f" + "22.22.2-linux_arm64": [ + "node-v22.22.2-linux-arm64.tar.xz", + "node-v22.22.2-linux-arm64", + "e9e1930fd321a470e29bb68f30318bf58e3ecb4acb4f1533fb19c58328a091fe" ], - "22.22.0-linux_ppc64le": [ - "node-v22.22.0-linux-ppc64le.tar.xz", - "node-v22.22.0-linux-ppc64le", - "d83b9957431cc18e1fc143a4b99f89cde7b8a18f53ef392231b4336afd058865" + "22.22.2-linux_ppc64le": [ + "node-v22.22.2-linux-ppc64le.tar.xz", + "node-v22.22.2-linux-ppc64le", + "14045b5a5030d35ca0030fb7e870bd11a651eb9b57323ebc0021e8d78ac6bac9" ], - "22.22.0-linux_s390x": [ - "node-v22.22.0-linux-s390x.tar.xz", - "node-v22.22.0-linux-s390x", - "5aa0e520689448c4233e8d73f284e8e0634fdcd32b479735698494be5641f3e4" + "22.22.2-linux_s390x": [ + "node-v22.22.2-linux-s390x.tar.xz", + "node-v22.22.2-linux-s390x", + "9e4a07c291b8949289c6ea8ee61b1d14666a4810feae776a8d1eb1f57e03a2fb" ], - "22.22.0-linux_amd64": [ - "node-v22.22.0-linux-x64.tar.xz", - "node-v22.22.0-linux-x64", - "9aa8e9d2298ab68c600bd6fb86a6c13bce11a4eca1ba9b39d79fa021755d7c37" + "22.22.2-linux_amd64": [ + "node-v22.22.2-linux-x64.tar.xz", + "node-v22.22.2-linux-x64", + "88fd1ce767091fd8d4a99fdb2356e98c819f93f3b1f8663853a2dee9b438068a" ], - "22.22.0-windows_amd64": [ - "node-v22.22.0-win-x64.zip", - "node-v22.22.0-win-x64", - "c97fa376d2becdc8863fcd3ca2dd9a83a9f3468ee7ccf7a6d076ec66a645c77a" + "22.22.2-windows_amd64": [ + "node-v22.22.2-win-x64.zip", + "node-v22.22.2-win-x64", + "7c93e9d92bf68c07182b471aa187e35ee6cd08ef0f24ab060dfff605fcc1c57c" ] }, "node_urls": [ "https://nodejs.org/dist/v{version}/{filename}" ], - "node_version": "22.22.0", + "node_version": "22.22.2", "include_headers": false, "platform": "windows_amd64" } @@ -1449,46 +1304,46 @@ "attributes": { "node_download_auth": {}, "node_repositories": { - "22.22.0-darwin_arm64": [ - "node-v22.22.0-darwin-arm64.tar.gz", - "node-v22.22.0-darwin-arm64", - "5ed4db0fcf1eaf84d91ad12462631d73bf4576c1377e192d222e48026a902640" + "22.22.2-darwin_arm64": [ + "node-v22.22.2-darwin-arm64.tar.gz", + "node-v22.22.2-darwin-arm64", + "db4b275b83736df67533529a18cc55de2549a8329ace6c7bcc68f8d22d3c9000" ], - "22.22.0-darwin_amd64": [ - "node-v22.22.0-darwin-x64.tar.gz", - "node-v22.22.0-darwin-x64", - "5ea50c9d6dea3dfa3abb66b2656f7a4e1c8cef23432b558d45fb538c7b5dedce" + "22.22.2-darwin_amd64": [ + "node-v22.22.2-darwin-x64.tar.gz", + "node-v22.22.2-darwin-x64", + "12a6abb9c2902cf48a21120da13f87fde1ed1b71a13330712949e8db818708ba" ], - "22.22.0-linux_arm64": [ - "node-v22.22.0-linux-arm64.tar.xz", - "node-v22.22.0-linux-arm64", - "1bf1eb9ee63ffc4e5d324c0b9b62cf4a289f44332dfef9607cea1a0d9596ba6f" + "22.22.2-linux_arm64": [ + "node-v22.22.2-linux-arm64.tar.xz", + "node-v22.22.2-linux-arm64", + "e9e1930fd321a470e29bb68f30318bf58e3ecb4acb4f1533fb19c58328a091fe" ], - "22.22.0-linux_ppc64le": [ - "node-v22.22.0-linux-ppc64le.tar.xz", - "node-v22.22.0-linux-ppc64le", - "d83b9957431cc18e1fc143a4b99f89cde7b8a18f53ef392231b4336afd058865" + "22.22.2-linux_ppc64le": [ + "node-v22.22.2-linux-ppc64le.tar.xz", + "node-v22.22.2-linux-ppc64le", + "14045b5a5030d35ca0030fb7e870bd11a651eb9b57323ebc0021e8d78ac6bac9" ], - "22.22.0-linux_s390x": [ - "node-v22.22.0-linux-s390x.tar.xz", - "node-v22.22.0-linux-s390x", - "5aa0e520689448c4233e8d73f284e8e0634fdcd32b479735698494be5641f3e4" + "22.22.2-linux_s390x": [ + "node-v22.22.2-linux-s390x.tar.xz", + "node-v22.22.2-linux-s390x", + "9e4a07c291b8949289c6ea8ee61b1d14666a4810feae776a8d1eb1f57e03a2fb" ], - "22.22.0-linux_amd64": [ - "node-v22.22.0-linux-x64.tar.xz", - "node-v22.22.0-linux-x64", - "9aa8e9d2298ab68c600bd6fb86a6c13bce11a4eca1ba9b39d79fa021755d7c37" + "22.22.2-linux_amd64": [ + "node-v22.22.2-linux-x64.tar.xz", + "node-v22.22.2-linux-x64", + "88fd1ce767091fd8d4a99fdb2356e98c819f93f3b1f8663853a2dee9b438068a" ], - "22.22.0-windows_amd64": [ - "node-v22.22.0-win-x64.zip", - "node-v22.22.0-win-x64", - "c97fa376d2becdc8863fcd3ca2dd9a83a9f3468ee7ccf7a6d076ec66a645c77a" + "22.22.2-windows_amd64": [ + "node-v22.22.2-win-x64.zip", + "node-v22.22.2-win-x64", + "7c93e9d92bf68c07182b471aa187e35ee6cd08ef0f24ab060dfff605fcc1c57c" ] }, "node_urls": [ "https://nodejs.org/dist/v{version}/{filename}" ], - "node_version": "22.22.0", + "node_version": "22.22.2", "include_headers": false, "platform": "windows_arm64" } @@ -1883,7 +1738,7 @@ }, "@@rules_python+//python/extensions:pip.bzl%pip": { "general": { - "bzlTransitiveDigest": "d3ENjFH8qMwmOrkcb3c9JYqQ5hJ6owjfbSr24KY0Ugg=", + "bzlTransitiveDigest": "WViZ5k1A9F8R5wfEe2ArLMFS1g9UmgfbS8Q/7q1/z7o=", "usagesDigest": "AK1R124YPWwAs8z1CQYyjYuci8RO5Ofot+EP5ZCNQDc=", "recordedFileInputs": { "@@protobuf+//python/requirements.txt": "983be60d3cec4b319dcab6d48aeb3f5b2f7c3350f26b3a9e97486c37967c73c5", @@ -4621,7 +4476,7 @@ }, "@@rules_sass+//src/toolchain:extensions.bzl%sass": { "general": { - "bzlTransitiveDigest": "RA58Nyrsn03Z5YmQnpmBw3mqlVck++XIrx34amsqU/E=", + "bzlTransitiveDigest": "mOfuR8PsNuUWEq7JZ4MpIRbwyAGAqrCvkXXGaRNnlPQ=", "usagesDigest": "R0KshhzIouLWuexMUCrl4HY+FUDwlVVgF9Z7UnwyUWA=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, @@ -4677,8 +4532,8 @@ }, "@@yq.bzl+//yq:extensions.bzl%yq": { "general": { - "bzlTransitiveDigest": "tDqk+ntWTdxNAWPDjRY1uITgHbti2jcXR5ZdinltBs0=", - "usagesDigest": "OQwtwmKiZAvI0n0B86XlM4tmQHq4zcjFjAEiRGPhXVI=", + "bzlTransitiveDigest": "UfFMy8CWK4/dVo/tfaSAIYUiDGNAPes5eRllx9O9Q9Q=", + "usagesDigest": "da9wP1gnmr42ci1bT30rSLLWu7O0jJPIkd01GNAM7NE=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, "envVariables": {}, diff --git a/constants.bzl b/constants.bzl index d4be4fc34b84..d9a42e40631f 100644 --- a/constants.bzl +++ b/constants.bzl @@ -3,10 +3,10 @@ RELEASE_ENGINES_NODE = "^20.19.0 || ^22.12.0 || >=24.0.0" RELEASE_ENGINES_NPM = "^6.11.0 || ^7.5.6 || >=8.0.0" RELEASE_ENGINES_YARN = ">= 1.13.0" -NG_PACKAGR_VERSION = "^21.2.0-next.0" -ANGULAR_FW_VERSION = "^21.2.0-next.0" -ANGULAR_FW_PEER_DEP = "^21.0.0 || ^21.2.0-next.0" -NG_PACKAGR_PEER_DEP = "^21.0.0 || ^21.2.0-next.0" +NG_PACKAGR_VERSION = "^21.2.0" +ANGULAR_FW_VERSION = "^21.2.0" +ANGULAR_FW_PEER_DEP = "^21.0.0" +NG_PACKAGR_PEER_DEP = "^21.0.0" # Baseline widely-available date in `YYYY-MM-DD` format which defines Angular's # browser support. This date serves as the source of truth for the Angular CLI's diff --git a/docs/DEVELOPER.md b/docs/DEVELOPER.md index 8204bd7dcbce..075ddbcf9ca3 100644 --- a/docs/DEVELOPER.md +++ b/docs/DEVELOPER.md @@ -56,7 +56,7 @@ project](#building-and-installing-the-cli), then run the desired `ng` command as: ```shell -node --inspect-brk node_modules/.bin/ng ... +node --inspect-brk node_modules/.bin/ng ``` This will trigger a breakpoint as the CLI starts up. You can connect to this diff --git a/goldens/BUILD.bazel b/goldens/BUILD.bazel index 6dbbdd28f25b..711154f524b1 100644 --- a/goldens/BUILD.bazel +++ b/goldens/BUILD.bazel @@ -1,4 +1,4 @@ -load("@aspect_bazel_lib//lib:copy_to_bin.bzl", "copy_to_bin") +load("@bazel_lib//lib:copy_to_bin.bzl", "copy_to_bin") package(default_visibility = ["//visibility:public"]) diff --git a/goldens/public-api/angular/ssr/index.api.md b/goldens/public-api/angular/ssr/index.api.md index 81764fcc1f62..e5d85138b72f 100644 --- a/goldens/public-api/angular/ssr/index.api.md +++ b/goldens/public-api/angular/ssr/index.api.md @@ -6,19 +6,30 @@ import { DefaultExport } from '@angular/router'; import { EnvironmentProviders } from '@angular/core'; +import { InjectionToken } from '@angular/core'; import { Provider } from '@angular/core'; import { Type } from '@angular/core'; // @public export class AngularAppEngine { + constructor(options?: AngularAppEngineOptions); handle(request: Request, requestContext?: unknown): Promise; static ɵallowStaticRouteRender: boolean; + static ɵdisableAllowedHostsCheck: boolean; static ɵhooks: Hooks; } +// @public +export interface AngularAppEngineOptions { + allowedHosts?: readonly string[]; +} + // @public export function createRequestHandler(handler: RequestHandlerFunction): RequestHandlerFunction; +// @public +export const IS_DISCOVERING_ROUTES: InjectionToken; + // @public export enum PrerenderFallback { Client = 1, diff --git a/goldens/public-api/angular/ssr/node/index.api.md b/goldens/public-api/angular/ssr/node/index.api.md index eccb6396938e..2c52c06b47c1 100644 --- a/goldens/public-api/angular/ssr/node/index.api.md +++ b/goldens/public-api/angular/ssr/node/index.api.md @@ -15,8 +15,12 @@ import { Type } from '@angular/core'; // @public export class AngularNodeAppEngine { - constructor(); - handle(request: IncomingMessage | Http2ServerRequest, requestContext?: unknown): Promise; + constructor(options?: AngularNodeAppEngineOptions); + handle(request: IncomingMessage | Http2ServerRequest | Request, requestContext?: unknown): Promise; +} + +// @public +export interface AngularNodeAppEngineOptions extends AngularAppEngineOptions { } // @public @@ -27,6 +31,7 @@ export class CommonEngine { // @public (undocumented) export interface CommonEngineOptions { + allowedHosts?: readonly string[]; bootstrap?: Type<{}> | ((context: BootstrapContext) => Promise); enablePerformanceProfiler?: boolean; providers?: StaticProvider[]; diff --git a/goldens/public-api/angular_devkit/architect/index.api.md b/goldens/public-api/angular_devkit/architect/index.api.md index 0ae8751719b5..747b7010f580 100644 --- a/goldens/public-api/angular_devkit/architect/index.api.md +++ b/goldens/public-api/angular_devkit/architect/index.api.md @@ -530,7 +530,7 @@ export type Target = json.JsonObject & Target_2; export function targetFromTargetString(specifier: string, abbreviatedProjectName?: string, abbreviatedTargetName?: string): Target; // @public -export function targetStringFromTarget({ project, target, configuration }: Target): string; +export function targetStringFromTarget(input: Target): string; // @public export type TypedBuilderProgress = { diff --git a/modules/testing/builder/BUILD.bazel b/modules/testing/builder/BUILD.bazel index 7f542efb0138..4fa8b7ee723b 100644 --- a/modules/testing/builder/BUILD.bazel +++ b/modules/testing/builder/BUILD.bazel @@ -22,6 +22,7 @@ ts_project( ":node_modules/@angular/ssr", ":node_modules/browser-sync", ":node_modules/jsdom", + ":node_modules/ng-packagr", ":node_modules/vitest", ":node_modules/@vitest/coverage-v8", ] + glob(["projects/**/*"]), diff --git a/modules/testing/builder/package.json b/modules/testing/builder/package.json index 47ff33d0cd7d..998158229973 100644 --- a/modules/testing/builder/package.json +++ b/modules/testing/builder/package.json @@ -1,12 +1,13 @@ { "devDependencies": { - "@angular-devkit/core": "workspace:*", "@angular-devkit/architect": "workspace:*", - "@angular/ssr": "workspace:*", "@angular-devkit/build-angular": "workspace:*", - "browser-sync": "3.0.4", + "@angular-devkit/core": "workspace:*", + "@angular/ssr": "workspace:*", "@vitest/coverage-v8": "4.0.18", + "browser-sync": "3.0.4", "jsdom": "28.1.0", + "ng-packagr": "22.0.0-next.1", "rxjs": "7.8.2", "vitest": "4.0.18" } diff --git a/packages/angular_devkit/build_angular/test/hello-world-lib/.gitignore b/modules/testing/builder/projects/hello-world-lib/.gitignore similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-lib/.gitignore rename to modules/testing/builder/projects/hello-world-lib/.gitignore diff --git a/packages/angular_devkit/build_angular/test/hello-world-lib/angular.json b/modules/testing/builder/projects/hello-world-lib/angular.json similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-lib/angular.json rename to modules/testing/builder/projects/hello-world-lib/angular.json diff --git a/packages/angular_devkit/build_angular/test/hello-world-lib/projects/lib/karma.conf.js b/modules/testing/builder/projects/hello-world-lib/projects/lib/karma.conf.js similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-lib/projects/lib/karma.conf.js rename to modules/testing/builder/projects/hello-world-lib/projects/lib/karma.conf.js diff --git a/packages/angular_devkit/build_angular/test/hello-world-lib/projects/lib/ng-package.json b/modules/testing/builder/projects/hello-world-lib/projects/lib/ng-package.json similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-lib/projects/lib/ng-package.json rename to modules/testing/builder/projects/hello-world-lib/projects/lib/ng-package.json diff --git a/packages/angular_devkit/build_angular/test/hello-world-lib/projects/lib/package.json b/modules/testing/builder/projects/hello-world-lib/projects/lib/package.json similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-lib/projects/lib/package.json rename to modules/testing/builder/projects/hello-world-lib/projects/lib/package.json diff --git a/packages/angular_devkit/build_angular/test/hello-world-lib/projects/lib/src/lib/lib.component.spec.ts b/modules/testing/builder/projects/hello-world-lib/projects/lib/src/lib/lib.component.spec.ts similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-lib/projects/lib/src/lib/lib.component.spec.ts rename to modules/testing/builder/projects/hello-world-lib/projects/lib/src/lib/lib.component.spec.ts diff --git a/packages/angular_devkit/build_angular/test/hello-world-lib/projects/lib/src/lib/lib.component.ts b/modules/testing/builder/projects/hello-world-lib/projects/lib/src/lib/lib.component.ts similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-lib/projects/lib/src/lib/lib.component.ts rename to modules/testing/builder/projects/hello-world-lib/projects/lib/src/lib/lib.component.ts diff --git a/packages/angular_devkit/build_angular/test/hello-world-lib/projects/lib/src/lib/lib.service.spec.ts b/modules/testing/builder/projects/hello-world-lib/projects/lib/src/lib/lib.service.spec.ts similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-lib/projects/lib/src/lib/lib.service.spec.ts rename to modules/testing/builder/projects/hello-world-lib/projects/lib/src/lib/lib.service.spec.ts diff --git a/packages/angular_devkit/build_angular/test/hello-world-lib/projects/lib/src/lib/lib.service.ts b/modules/testing/builder/projects/hello-world-lib/projects/lib/src/lib/lib.service.ts similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-lib/projects/lib/src/lib/lib.service.ts rename to modules/testing/builder/projects/hello-world-lib/projects/lib/src/lib/lib.service.ts diff --git a/packages/angular_devkit/build_angular/test/hello-world-lib/projects/lib/src/public-api.ts b/modules/testing/builder/projects/hello-world-lib/projects/lib/src/public-api.ts similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-lib/projects/lib/src/public-api.ts rename to modules/testing/builder/projects/hello-world-lib/projects/lib/src/public-api.ts diff --git a/packages/angular_devkit/build_angular/test/hello-world-lib/projects/lib/tsconfig.lib.json b/modules/testing/builder/projects/hello-world-lib/projects/lib/tsconfig.lib.json similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-lib/projects/lib/tsconfig.lib.json rename to modules/testing/builder/projects/hello-world-lib/projects/lib/tsconfig.lib.json diff --git a/packages/angular_devkit/build_angular/test/hello-world-lib/projects/lib/tsconfig.lib.prod.json b/modules/testing/builder/projects/hello-world-lib/projects/lib/tsconfig.lib.prod.json similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-lib/projects/lib/tsconfig.lib.prod.json rename to modules/testing/builder/projects/hello-world-lib/projects/lib/tsconfig.lib.prod.json diff --git a/packages/angular_devkit/build_angular/test/hello-world-lib/projects/lib/tsconfig.spec.json b/modules/testing/builder/projects/hello-world-lib/projects/lib/tsconfig.spec.json similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-lib/projects/lib/tsconfig.spec.json rename to modules/testing/builder/projects/hello-world-lib/projects/lib/tsconfig.spec.json diff --git a/packages/angular_devkit/build_angular/test/hello-world-lib/tsconfig.json b/modules/testing/builder/projects/hello-world-lib/tsconfig.json similarity index 100% rename from packages/angular_devkit/build_angular/test/hello-world-lib/tsconfig.json rename to modules/testing/builder/projects/hello-world-lib/tsconfig.json diff --git a/package.json b/package.json index 39fba551b317..0ea57d7238b8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@angular/devkit-repo", - "version": "21.2.0-next.2", + "version": "21.2.6", "private": true, "description": "Software Development Kit for Angular", "keywords": [ @@ -26,14 +26,14 @@ }, "repository": { "type": "git", - "url": "https://github.com/angular/angular-cli.git" + "url": "git+https://github.com/angular/angular-cli.git" }, - "packageManager": "pnpm@10.29.3", + "packageManager": "pnpm@10.33.0", "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": "Please use pnpm instead of NPM to install dependencies", "yarn": "Please use pnpm instead of Yarn to install dependencies", - "pnpm": "10.29.3" + "pnpm": "10.33.0" }, "author": "Angular Authors", "license": "MIT", @@ -42,20 +42,20 @@ }, "homepage": "https://github.com/angular/angular-cli", "devDependencies": { - "@angular/animations": "21.2.0-next.3", - "@angular/cdk": "21.2.0-next.4", - "@angular/common": "21.2.0-next.3", - "@angular/compiler": "21.2.0-next.3", - "@angular/compiler-cli": "21.2.0-next.3", - "@angular/core": "21.2.0-next.3", - "@angular/forms": "21.2.0-next.3", - "@angular/localize": "21.2.0-next.3", - "@angular/material": "21.2.0-next.4", - "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#2a5e8e5b5398ae13a8d9a963ac980707313a6c9e", - "@angular/platform-browser": "21.2.0-next.3", - "@angular/platform-server": "21.2.0-next.3", - "@angular/router": "21.2.0-next.3", - "@angular/service-worker": "21.2.0-next.3", + "@angular/animations": "21.2.6", + "@angular/cdk": "21.2.4", + "@angular/common": "21.2.6", + "@angular/compiler": "21.2.6", + "@angular/compiler-cli": "21.2.6", + "@angular/core": "21.2.6", + "@angular/forms": "21.2.6", + "@angular/localize": "21.2.6", + "@angular/material": "21.2.4", + "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#cdbe118e59f59b1ee00ff77a5ccf8c5328248d03", + "@angular/platform-browser": "21.2.6", + "@angular/platform-server": "21.2.6", + "@angular/router": "21.2.6", + "@angular/service-worker": "21.2.6", "@babel/core": "7.29.0", "@bazel/bazelisk": "1.28.1", "@bazel/buildifier": "8.2.1", @@ -66,6 +66,7 @@ "@rollup/plugin-commonjs": "^29.0.0", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "16.0.3", + "@rollup/wasm-node": "4.59.0", "@stylistic/eslint-plugin": "^5.0.0", "@types/babel__core": "7.20.5", "@types/babel__generator": "^7.6.8", @@ -130,9 +131,9 @@ "ts-node": "^10.9.1", "tslib": "2.8.1", "typescript": "5.9.3", - "undici": "7.22.0", + "undici": "7.24.4", "unenv": "^1.10.0", - "verdaccio": "6.2.5", + "verdaccio": "6.2.9", "verdaccio-auth-memory": "^10.0.0", "zone.js": "^0.16.0" }, diff --git a/packages/angular/build/package.json b/packages/angular/build/package.json index c4d847ae5a8e..e04ef0c7b3a3 100644 --- a/packages/angular/build/package.json +++ b/packages/angular/build/package.json @@ -35,14 +35,14 @@ "magic-string": "0.30.21", "mrmime": "2.0.1", "parse5-html-rewriting-stream": "8.0.0", - "picomatch": "4.0.3", + "picomatch": "4.0.4", "piscina": "5.1.4", "rolldown": "1.0.0-rc.4", "sass": "1.97.3", "semver": "7.7.4", "source-map-support": "0.5.21", "tinyglobby": "0.2.15", - "undici": "7.22.0", + "undici": "7.24.4", "vite": "7.3.1", "watchpack": "2.5.1" }, @@ -54,7 +54,7 @@ "@angular/ssr": "workspace:*", "jsdom": "28.1.0", "less": "4.4.2", - "ng-packagr": "21.2.0-next.0", + "ng-packagr": "21.2.2", "postcss": "8.5.6", "rxjs": "7.8.2", "vitest": "4.0.18" diff --git a/packages/angular/build/src/builders/application/execute-build.ts b/packages/angular/build/src/builders/application/execute-build.ts index 0654cd965558..aaddc5b6ef7e 100644 --- a/packages/angular/build/src/builders/application/execute-build.ts +++ b/packages/angular/build/src/builders/application/execute-build.ts @@ -56,6 +56,7 @@ export async function executeBuild( verbose, colors, jsonLogs, + security, } = options; // TODO: Consider integrating into watch mode. Would require full rebuild on target changes. @@ -263,7 +264,7 @@ export async function executeBuild( if (serverEntryPoint) { executionResult.addOutputFile( SERVER_APP_ENGINE_MANIFEST_FILENAME, - generateAngularServerAppEngineManifest(i18nOptions, baseHref), + generateAngularServerAppEngineManifest(i18nOptions, security.allowedHosts, baseHref), BuildOutputFileType.ServerRoot, ); } diff --git a/packages/angular/build/src/builders/application/i18n.ts b/packages/angular/build/src/builders/application/i18n.ts index ae37efa674e4..081be50e7a9f 100644 --- a/packages/angular/build/src/builders/application/i18n.ts +++ b/packages/angular/build/src/builders/application/i18n.ts @@ -123,48 +123,48 @@ export async function inlineI18n( inlineResult.prerenderedRoutes = { ...inlineResult.prerenderedRoutes, ...generatedRoutes }; updatedOutputFiles.push(...localeOutputFiles); } - } finally { - await inliner.close(); - } - // Update the result with all localized files. - executionResult.outputFiles = [ - // Root and SSR entry files are not modified. - ...unModifiedOutputFiles, - // Updated files for each locale. - ...updatedOutputFiles, - ]; - - // Assets are only changed if not using the flat output option - if (!i18nOptions.flatOutput) { - executionResult.assetFiles = updatedAssetFiles; - } - - // Inline any template updates if present - if (executionResult.templateUpdates?.size) { - // The development server only allows a single locale but issue a warning if used programmatically (experimental) - // with multiple locales and template HMR. - if (i18nOptions.inlineLocales.size > 1) { - inlineResult.warnings.push( - `Component HMR updates can only be inlined with a single locale. The first locale will be used.`, - ); + // Update the result with all localized files. + executionResult.outputFiles = [ + // Root and SSR entry files are not modified. + ...unModifiedOutputFiles, + // Updated files for each locale. + ...updatedOutputFiles, + ]; + + // Assets are only changed if not using the flat output option + if (!i18nOptions.flatOutput) { + executionResult.assetFiles = updatedAssetFiles; } - const firstLocale = [...i18nOptions.inlineLocales][0]; - - for (const [id, content] of executionResult.templateUpdates) { - const templateUpdateResult = await inliner.inlineTemplateUpdate( - firstLocale, - i18nOptions.locales[firstLocale].translation, - content, - id, - ); - executionResult.templateUpdates.set(id, templateUpdateResult.code); - inlineResult.errors.push(...templateUpdateResult.errors); - inlineResult.warnings.push(...templateUpdateResult.warnings); + + // Inline any template updates if present + if (executionResult.templateUpdates?.size) { + // The development server only allows a single locale but issue a warning if used programmatically (experimental) + // with multiple locales and template HMR. + if (i18nOptions.inlineLocales.size > 1) { + inlineResult.warnings.push( + `Component HMR updates can only be inlined with a single locale. The first locale will be used.`, + ); + } + const firstLocale = [...i18nOptions.inlineLocales][0]; + + for (const [id, content] of executionResult.templateUpdates) { + const templateUpdateResult = await inliner.inlineTemplateUpdate( + firstLocale, + i18nOptions.locales[firstLocale].translation, + content, + id, + ); + executionResult.templateUpdates.set(id, templateUpdateResult.code); + inlineResult.errors.push(...templateUpdateResult.errors); + inlineResult.warnings.push(...templateUpdateResult.warnings); + } } - } - return inlineResult; + return inlineResult; + } finally { + await inliner.close(); + } } /** diff --git a/packages/angular/build/src/builders/application/options.ts b/packages/angular/build/src/builders/application/options.ts index 83b7ea428f35..4f0d1295a7e3 100644 --- a/packages/angular/build/src/builders/application/options.ts +++ b/packages/angular/build/src/builders/application/options.ts @@ -400,8 +400,9 @@ export async function normalizeOptions( } } - const autoCsp = options.security?.autoCsp; + const { autoCsp, allowedHosts = [] } = options.security ?? {}; const security = { + allowedHosts, autoCsp: autoCsp ? { unsafeEval: autoCsp === true ? false : !!autoCsp.unsafeEval, diff --git a/packages/angular/build/src/builders/application/schema.json b/packages/angular/build/src/builders/application/schema.json index 8db4e6145b3f..5498a21fe004 100644 --- a/packages/angular/build/src/builders/application/schema.json +++ b/packages/angular/build/src/builders/application/schema.json @@ -52,6 +52,14 @@ "type": "object", "additionalProperties": false, "properties": { + "allowedHosts": { + "description": "A list of hostnames that are allowed to access the server-side application. For more information, see https://angular.dev/best-practices/security#preventing-server-side-request-forgery-ssrf.", + "type": "array", + "uniqueItems": true, + "items": { + "type": "string" + } + }, "autoCsp": { "description": "Enables automatic generation of a hash-based Strict Content Security Policy (https://web.dev/articles/strict-csp#choose-hash) based on scripts in index.html. Will default to true once we are out of experimental/preview phases.", "default": false, diff --git a/packages/angular/build/src/builders/application/tests/behavior/rebuild-component_styles_spec.ts b/packages/angular/build/src/builders/application/tests/behavior/rebuild-component_styles_spec.ts index 26ae35a8221f..08b683439684 100644 --- a/packages/angular/build/src/builders/application/tests/behavior/rebuild-component_styles_spec.ts +++ b/packages/angular/build/src/builders/application/tests/behavior/rebuild-component_styles_spec.ts @@ -58,5 +58,85 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => { ]); }); } + + it('rebuilds component after error on rebuild from transitive import', async () => { + harness.useTarget('build', { + ...BASE_OPTIONS, + watch: true, + }); + + await harness.modifyFile('src/app/app.component.ts', (content) => + content.replace('app.component.css', 'app.component.scss'), + ); + await harness.writeFile('src/app/app.component.scss', "@import './a';"); + await harness.writeFile('src/app/a.scss', '$primary: aqua;\\nh1 { color: $primary; }'); + + await harness.executeWithCases([ + async ({ result }) => { + expect(result?.success).toBe(true); + + harness.expectFile('dist/browser/main.js').content.toContain('color: aqua'); + + // Introduce a syntax error + await harness.writeFile( + 'src/app/a.scss', + 'invalid-invalid-invalid\\nh1 { color: $primary; }', + ); + }, + async ({ result }) => { + expect(result?.success).toBe(false); + + // Fix the syntax error + await harness.writeFile('src/app/a.scss', '$primary: blue;\\nh1 { color: $primary; }'); + }, + ({ result }) => { + expect(result?.success).toBe(true); + + harness.expectFile('dist/browser/main.js').content.toContain('color: blue'); + }, + ]); + }); + + it('rebuilds component after error on rebuild from deep transitive import with partials', async () => { + harness.useTarget('build', { + ...BASE_OPTIONS, + watch: true, + }); + + await harness.modifyFile('src/app/app.component.ts', (content) => + content.replace('app.component.css', 'app.component.scss'), + ); + await harness.writeFile('src/app/app.component.scss', "@import './intermediary';"); + await harness.writeFile('src/app/_intermediary.scss', "@import './partial';"); + await harness.writeFile('src/app/_partial.scss', '$primary: aqua;\\nh1 { color: $primary; }'); + + await harness.executeWithCases([ + async ({ result }) => { + expect(result?.success).toBe(true); + + harness.expectFile('dist/browser/main.js').content.toContain('color: aqua'); + + // Introduce a syntax error deeply + await harness.writeFile( + 'src/app/_partial.scss', + 'invalid-invalid-invalid\\nh1 { color: $primary; }', + ); + }, + async ({ result }) => { + expect(result?.success).toBe(false); + + // Fix the syntax error deeply + await harness.writeFile( + 'src/app/_partial.scss', + '$primary: blue;\\nh1 { color: $primary; }', + ); + }, + ({ result }) => { + expect(result?.success).toBe(true); + + harness.expectFile('dist/browser/main.js').content.toContain('color: blue'); + }, + ]); + }); }); }); diff --git a/packages/angular/build/src/builders/dev-server/tests/behavior/build-assets_spec.ts b/packages/angular/build/src/builders/dev-server/tests/behavior/build-assets_spec.ts index f7c7a0acb33a..7d3e1ffc414b 100644 --- a/packages/angular/build/src/builders/dev-server/tests/behavior/build-assets_spec.ts +++ b/packages/angular/build/src/builders/dev-server/tests/behavior/build-assets_spec.ts @@ -21,6 +21,26 @@ describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupT "import {foo} from 'unresolved'; /* a comment */const foo = `bar`;\n\n\n"; describe('Behavior: "browser builder assets"', () => { + it('serves a project extensionless asset unmodified', async () => { + await harness.writeFile('src/extensionless', javascriptFileContent); + + setupTarget(harness, { + assets: ['src/extensionless'], + optimization: { + scripts: true, + }, + }); + + harness.useTarget('serve', { + ...BASE_OPTIONS, + }); + + const { result, response } = await executeOnceAndFetch(harness, 'extensionless'); + + expect(result?.success).toBeTrue(); + expect(await response?.text()).toContain(javascriptFileContent); + }); + it('serves a project JavaScript asset unmodified', async () => { await harness.writeFile('src/extra.js', javascriptFileContent); diff --git a/packages/angular/build/src/builders/dev-server/tests/behavior/build-budgets_spec.ts b/packages/angular/build/src/builders/dev-server/tests/behavior/build-budgets_spec.ts index aee551e78b48..97a68506fcf5 100644 --- a/packages/angular/build/src/builders/dev-server/tests/behavior/build-budgets_spec.ts +++ b/packages/angular/build/src/builders/dev-server/tests/behavior/build-budgets_spec.ts @@ -11,29 +11,25 @@ import { executeDevServer } from '../../index'; import { describeServeBuilder } from '../jasmine-helpers'; import { BASE_OPTIONS, DEV_SERVER_BUILDER_INFO } from '../setup'; -describeServeBuilder( - executeDevServer, - DEV_SERVER_BUILDER_INFO, - (harness, setupTarget, isViteRun) => { - // TODO(fix-vite): currently this is broken in vite. - (isViteRun ? xdescribe : describe)('Behavior: "browser builder budgets"', () => { - beforeEach(() => { - setupTarget(harness, { - // Add a budget error for any file over 100 bytes - budgets: [{ type: BudgetType.All, maximumError: '100b' }], - optimization: true, - }); +describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupTarget) => { + // TODO(fix-vite): currently this is broken in vite. + xdescribe('Behavior: "browser builder budgets"', () => { + beforeEach(() => { + setupTarget(harness, { + // Add a budget error for any file over 100 bytes + budgets: [{ type: BudgetType.All, maximumError: '100b' }], + optimization: true, }); + }); - it('should ignore budgets defined in the "buildTarget" options', async () => { - harness.useTarget('serve', { - ...BASE_OPTIONS, - }); + it('should ignore budgets defined in the "buildTarget" options', async () => { + harness.useTarget('serve', { + ...BASE_OPTIONS, + }); - const { result } = await harness.executeOnce(); + const { result } = await harness.executeOnce(); - expect(result?.success).toBe(true); - }); + expect(result?.success).toBe(true); }); - }, -); + }); +}); diff --git a/packages/angular/build/src/builders/dev-server/tests/behavior/build-conditions_spec.ts b/packages/angular/build/src/builders/dev-server/tests/behavior/build-conditions_spec.ts index 2a7d59d8d574..aef1973d4a48 100644 --- a/packages/angular/build/src/builders/dev-server/tests/behavior/build-conditions_spec.ts +++ b/packages/angular/build/src/builders/dev-server/tests/behavior/build-conditions_spec.ts @@ -15,86 +15,74 @@ import { executeOnceAndFetch } from '../execute-fetch'; import { describeServeBuilder } from '../jasmine-helpers'; import { BASE_OPTIONS, DEV_SERVER_BUILDER_INFO } from '../setup'; -describeServeBuilder( - executeDevServer, - DEV_SERVER_BUILDER_INFO, - (harness, setupTarget, isApplicationBuilder) => { - describe('Behavior: "conditional imports"', () => { - if (!isApplicationBuilder) { - it('requires esbuild', () => { - expect(true).toBeTrue(); - }); - - return; - } - - beforeEach(async () => { - setupTarget(harness); +describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupTarget) => { + describe('Behavior: "conditional imports"', () => { + beforeEach(async () => { + setupTarget(harness); - await setupConditionImport(harness); - }); + await setupConditionImport(harness); + }); - interface ImportsTestCase { - name: string; - mapping: unknown; - output?: string; - } + interface ImportsTestCase { + name: string; + mapping: unknown; + output?: string; + } - const GOOD_TARGET = './src/good.js'; - const BAD_TARGET = './src/bad.js'; + const GOOD_TARGET = './src/good.js'; + const BAD_TARGET = './src/bad.js'; - const testCases: ImportsTestCase[] = [ - { name: 'simple string', mapping: GOOD_TARGET }, - { - name: 'default fallback without matching condition', - mapping: { - 'never': BAD_TARGET, - 'default': GOOD_TARGET, - }, + const testCases: ImportsTestCase[] = [ + { name: 'simple string', mapping: GOOD_TARGET }, + { + name: 'default fallback without matching condition', + mapping: { + 'never': BAD_TARGET, + 'default': GOOD_TARGET, }, - { - name: 'development condition', - mapping: { - 'development': GOOD_TARGET, - 'default': BAD_TARGET, - }, + }, + { + name: 'development condition', + mapping: { + 'development': GOOD_TARGET, + 'default': BAD_TARGET, }, - { - name: 'production condition', - mapping: { - 'production': BAD_TARGET, - 'default': GOOD_TARGET, - }, + }, + { + name: 'production condition', + mapping: { + 'production': BAD_TARGET, + 'default': GOOD_TARGET, }, - { - name: 'browser condition (in browser)', - mapping: { - 'browser': GOOD_TARGET, - 'default': BAD_TARGET, - }, + }, + { + name: 'browser condition (in browser)', + mapping: { + 'browser': GOOD_TARGET, + 'default': BAD_TARGET, }, - ]; + }, + ]; - for (const testCase of testCases) { - describe(testCase.name, () => { - beforeEach(async () => { - await setTargetMapping(harness, testCase.mapping); - }); + for (const testCase of testCases) { + describe(testCase.name, () => { + beforeEach(async () => { + await setTargetMapping(harness, testCase.mapping); + }); - it('resolves to expected target', async () => { - harness.useTarget('serve', { - ...BASE_OPTIONS, - }); + it('resolves to expected target', async () => { + harness.useTarget('serve', { + ...BASE_OPTIONS, + }); - const { result, response } = await executeOnceAndFetch(harness, '/main.js'); + const { result, response } = await executeOnceAndFetch(harness, '/main.js'); - expect(result?.success).toBeTrue(); - const output = await response?.text(); - expect(output).toContain('good-value'); - expect(output).not.toContain('bad-value'); - }); + expect(result?.success).toBeTrue(); + const output = await response?.text(); + expect(output).toContain('good-value'); + expect(output).not.toContain('bad-value'); }); - } - }); - }, -); + }); + } + }); +}); diff --git a/packages/angular/build/src/builders/dev-server/tests/behavior/build_translation_watch_spec.ts b/packages/angular/build/src/builders/dev-server/tests/behavior/build_translation_watch_spec.ts index b7d65e52e966..24dca8a6a5dc 100644 --- a/packages/angular/build/src/builders/dev-server/tests/behavior/build_translation_watch_spec.ts +++ b/packages/angular/build/src/builders/dev-server/tests/behavior/build_translation_watch_spec.ts @@ -12,70 +12,66 @@ import { executeDevServer } from '../../index'; import { describeServeBuilder } from '../jasmine-helpers'; import { BASE_OPTIONS, DEV_SERVER_BUILDER_INFO } from '../setup'; -describeServeBuilder( - executeDevServer, - DEV_SERVER_BUILDER_INFO, - (harness, setupTarget, isViteRun) => { - // TODO(fix-vite): currently this is broken in vite. - (isViteRun ? xdescribe : describe)('Behavior: "i18n translation file watching"', () => { - beforeEach(() => { - harness.useProject('test', { - root: '.', - sourceRoot: 'src', - cli: { - cache: { - enabled: false, - }, +describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupTarget) => { + // TODO(fix-vite): currently this is broken in vite. + xdescribe('Behavior: "i18n translation file watching"', () => { + beforeEach(() => { + harness.useProject('test', { + root: '.', + sourceRoot: 'src', + cli: { + cache: { + enabled: false, }, - i18n: { - locales: { - fr: 'src/locales/messages.fr.xlf', - }, + }, + i18n: { + locales: { + fr: 'src/locales/messages.fr.xlf', }, - }); - - setupTarget(harness, { localize: ['fr'] }); + }, }); - it('watches i18n translation files by default', async () => { - harness.useTarget('serve', { - ...BASE_OPTIONS, - watch: true, - }); + setupTarget(harness, { localize: ['fr'] }); + }); + + it('watches i18n translation files by default', async () => { + harness.useTarget('serve', { + ...BASE_OPTIONS, + watch: true, + }); - await harness.writeFile( - 'src/app/app.component.html', - ` + await harness.writeFile( + 'src/app/app.component.html', + `

Hello {{ title }}!

`, - ); + ); - await harness.writeFile('src/locales/messages.fr.xlf', TRANSLATION_FILE_CONTENT); + await harness.writeFile('src/locales/messages.fr.xlf', TRANSLATION_FILE_CONTENT); - await harness.executeWithCases([ - async ({ result }) => { - expect(result?.success).toBe(true); + await harness.executeWithCases([ + async ({ result }) => { + expect(result?.success).toBe(true); - const mainUrl = new URL('main.js', `${result?.baseUrl}`); - const response = await fetch(mainUrl); - expect(await response?.text()).toContain('Bonjour'); + const mainUrl = new URL('main.js', `${result?.baseUrl}`); + const response = await fetch(mainUrl); + expect(await response?.text()).toContain('Bonjour'); - await harness.modifyFile('src/locales/messages.fr.xlf', (content) => - content.replace('Bonjour', 'Salut'), - ); - }, - async ({ result }) => { - expect(result?.success).toBe(true); + await harness.modifyFile('src/locales/messages.fr.xlf', (content) => + content.replace('Bonjour', 'Salut'), + ); + }, + async ({ result }) => { + expect(result?.success).toBe(true); - const mainUrl = new URL('main.js', `${result?.baseUrl}`); - const response = await fetch(mainUrl); - expect(await response?.text()).toContain('Salut'); - }, - ]); - }); + const mainUrl = new URL('main.js', `${result?.baseUrl}`); + const response = await fetch(mainUrl); + expect(await response?.text()).toContain('Salut'); + }, + ]); }); - }, -); + }); +}); const TRANSLATION_FILE_CONTENT = ` diff --git a/packages/angular/build/src/builders/dev-server/tests/behavior/serve-live-reload-proxies_spec.ts b/packages/angular/build/src/builders/dev-server/tests/behavior/serve-live-reload-proxies_spec.ts index efdd749de258..6c41769d5aea 100644 --- a/packages/angular/build/src/builders/dev-server/tests/behavior/serve-live-reload-proxies_spec.ts +++ b/packages/angular/build/src/builders/dev-server/tests/behavior/serve-live-reload-proxies_spec.ts @@ -133,145 +133,138 @@ async function goToPageAndWaitForWS(page: Page, url: string): Promise { await client.detach(); } -describeServeBuilder( - executeDevServer, - DEV_SERVER_BUILDER_INFO, - (harness, setupTarget, isViteRun) => { - // TODO(fix-vite): currently this is broken in vite. - (isViteRun ? xdescribe : describe)( - 'Behavior: "Dev-server builder live-reload with proxies"', - () => { - let browser: Browser; - let page: Page; +describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupTarget) => { + // TODO(fix-vite): currently this is broken in vite. + xdescribe('Behavior: "Dev-server builder live-reload with proxies"', () => { + let browser: Browser; + let page: Page; - const SERVE_OPTIONS = Object.freeze({ - ...BASE_OPTIONS, - hmr: false, - watch: true, - liveReload: true, - }); + const SERVE_OPTIONS = Object.freeze({ + ...BASE_OPTIONS, + hmr: false, + watch: true, + liveReload: true, + }); - beforeAll(async () => { - browser = await puppeteer.launch({ - // MacOSX users need to set the local binary manually because Chrome has lib files with - // spaces in them which Bazel does not support in runfiles - // See: https://github.com/angular/angular-cli/pull/17624 - // eslint-disable-next-line max-len - // executablePath: '/Users//git/angular-cli/node_modules/puppeteer/.local-chromium/mac-818858/chrome-mac/Chromium.app/Contents/MacOS/Chromium', - ignoreHTTPSErrors: true, - args: ['--no-sandbox', '--disable-gpu'], - }); - }); + beforeAll(async () => { + browser = await puppeteer.launch({ + // MacOSX users need to set the local binary manually because Chrome has lib files with + // spaces in them which Bazel does not support in runfiles + // See: https://github.com/angular/angular-cli/pull/17624 + // eslint-disable-next-line max-len + // executablePath: '/Users//git/angular-cli/node_modules/puppeteer/.local-chromium/mac-818858/chrome-mac/Chromium.app/Contents/MacOS/Chromium', + ignoreHTTPSErrors: true, + args: ['--no-sandbox', '--disable-gpu'], + }); + }); - afterAll(async () => { - await browser.close(); - }); + afterAll(async () => { + await browser.close(); + }); - beforeEach(async () => { - setupTarget(harness, { - polyfills: ['src/polyfills.ts'], - }); + beforeEach(async () => { + setupTarget(harness, { + polyfills: ['src/polyfills.ts'], + }); - page = await browser.newPage(); - }); + page = await browser.newPage(); + }); - afterEach(async () => { - await page.close(); - }); + afterEach(async () => { + await page.close(); + }); - it('works without proxy', async () => { - harness.useTarget('serve', { - ...SERVE_OPTIONS, - }); + it('works without proxy', async () => { + harness.useTarget('serve', { + ...SERVE_OPTIONS, + }); - await harness.writeFile('src/app/app.component.html', '

{{ title }}

'); + await harness.writeFile('src/app/app.component.html', '

{{ title }}

'); - await harness.executeWithCases([ - async ({ result }) => { - expect(result?.success).toBeTrue(); - if (typeof result?.baseUrl !== 'string') { - throw new Error('Expected "baseUrl" to be a string.'); - } + await harness.executeWithCases([ + async ({ result }) => { + expect(result?.success).toBeTrue(); + if (typeof result?.baseUrl !== 'string') { + throw new Error('Expected "baseUrl" to be a string.'); + } - await goToPageAndWaitForWS(page, result.baseUrl); - await harness.modifyFile('src/app/app.component.ts', (content) => - content.replace(`'app'`, `'app-live-reload'`), - ); - }, - async ({ result }) => { - expect(result?.success).toBeTrue(); - const innerText = await page.evaluate(() => document.querySelector('p').innerText); - expect(innerText).toBe('app-live-reload'); - }, - ]); - }); + await goToPageAndWaitForWS(page, result.baseUrl); + await harness.modifyFile('src/app/app.component.ts', (content) => + content.replace(`'app'`, `'app-live-reload'`), + ); + }, + async ({ result }) => { + expect(result?.success).toBeTrue(); + const innerText = await page.evaluate(() => document.querySelector('p').innerText); + expect(innerText).toBe('app-live-reload'); + }, + ]); + }); - it('works without http -> http proxy', async () => { - harness.useTarget('serve', { - ...SERVE_OPTIONS, - }); + it('works without http -> http proxy', async () => { + harness.useTarget('serve', { + ...SERVE_OPTIONS, + }); - await harness.writeFile('src/app/app.component.html', '

{{ title }}

'); + await harness.writeFile('src/app/app.component.html', '

{{ title }}

'); - let proxy: ProxyInstance | undefined; - try { - await harness.executeWithCases([ - async ({ result }) => { - expect(result?.success).toBeTrue(); - if (typeof result?.baseUrl !== 'string') { - throw new Error('Expected "baseUrl" to be a string.'); - } + let proxy: ProxyInstance | undefined; + try { + await harness.executeWithCases([ + async ({ result }) => { + expect(result?.success).toBeTrue(); + if (typeof result?.baseUrl !== 'string') { + throw new Error('Expected "baseUrl" to be a string.'); + } - proxy = await createProxy(result.baseUrl, false); - await goToPageAndWaitForWS(page, proxy.url); - await harness.modifyFile('src/app/app.component.ts', (content) => - content.replace(`'app'`, `'app-live-reload'`), - ); - }, - async ({ result }) => { - expect(result?.success).toBeTrue(); - const innerText = await page.evaluate(() => document.querySelector('p').innerText); - expect(innerText).toBe('app-live-reload'); - }, - ]); - } finally { - proxy?.server.close(); - } - }); + proxy = await createProxy(result.baseUrl, false); + await goToPageAndWaitForWS(page, proxy.url); + await harness.modifyFile('src/app/app.component.ts', (content) => + content.replace(`'app'`, `'app-live-reload'`), + ); + }, + async ({ result }) => { + expect(result?.success).toBeTrue(); + const innerText = await page.evaluate(() => document.querySelector('p').innerText); + expect(innerText).toBe('app-live-reload'); + }, + ]); + } finally { + proxy?.server.close(); + } + }); - it('works without https -> http proxy', async () => { - harness.useTarget('serve', { - ...SERVE_OPTIONS, - }); + it('works without https -> http proxy', async () => { + harness.useTarget('serve', { + ...SERVE_OPTIONS, + }); - await harness.writeFile('src/app/app.component.html', '

{{ title }}

'); + await harness.writeFile('src/app/app.component.html', '

{{ title }}

'); - let proxy: ProxyInstance | undefined; - try { - await harness.executeWithCases([ - async ({ result }) => { - expect(result?.success).toBeTrue(); - if (typeof result?.baseUrl !== 'string') { - throw new Error('Expected "baseUrl" to be a string.'); - } + let proxy: ProxyInstance | undefined; + try { + await harness.executeWithCases([ + async ({ result }) => { + expect(result?.success).toBeTrue(); + if (typeof result?.baseUrl !== 'string') { + throw new Error('Expected "baseUrl" to be a string.'); + } - proxy = await createProxy(result.baseUrl, true); - await goToPageAndWaitForWS(page, proxy.url); - await harness.modifyFile('src/app/app.component.ts', (content) => - content.replace(`'app'`, `'app-live-reload'`), - ); - }, - async ({ result }) => { - expect(result?.success).toBeTrue(); - const innerText = await page.evaluate(() => document.querySelector('p').innerText); - expect(innerText).toBe('app-live-reload'); - }, - ]); - } finally { - proxy?.server.close(); - } - }); - }, - ); - }, -); + proxy = await createProxy(result.baseUrl, true); + await goToPageAndWaitForWS(page, proxy.url); + await harness.modifyFile('src/app/app.component.ts', (content) => + content.replace(`'app'`, `'app-live-reload'`), + ); + }, + async ({ result }) => { + expect(result?.success).toBeTrue(); + const innerText = await page.evaluate(() => document.querySelector('p').innerText); + expect(innerText).toBe('app-live-reload'); + }, + ]); + } finally { + proxy?.server.close(); + } + }); + }); +}); diff --git a/packages/angular/build/src/builders/dev-server/tests/behavior/serve_service-worker_spec.ts b/packages/angular/build/src/builders/dev-server/tests/behavior/serve_service-worker_spec.ts index b3b63c3a3093..10e2cee70465 100644 --- a/packages/angular/build/src/builders/dev-server/tests/behavior/serve_service-worker_spec.ts +++ b/packages/angular/build/src/builders/dev-server/tests/behavior/serve_service-worker_spec.ts @@ -36,180 +36,174 @@ const manifest = { ], }; -describeServeBuilder( - executeDevServer, - DEV_SERVER_BUILDER_INFO, - (harness, setupTarget, isViteRun) => { - describe('Behavior: "dev-server builder serves service worker"', () => { - beforeEach(async () => { - // Application code is not needed for these tests - await harness.writeFile('src/main.ts', ''); - await harness.writeFile('src/polyfills.ts', ''); - - harness.useProject('test', { - root: '.', - sourceRoot: 'src', - cli: { - cache: { - enabled: false, - }, +describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupTarget) => { + describe('Behavior: "dev-server builder serves service worker"', () => { + beforeEach(async () => { + // Application code is not needed for these tests + await harness.writeFile('src/main.ts', ''); + await harness.writeFile('src/polyfills.ts', ''); + + harness.useProject('test', { + root: '.', + sourceRoot: 'src', + cli: { + cache: { + enabled: false, }, - i18n: { - sourceLocale: { - code: 'fr', - }, + }, + i18n: { + sourceLocale: { + code: 'fr', }, - }); + }, + }); + }); + + it('works with service worker', async () => { + setupTarget(harness, { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + serviceWorker: 'ngsw-config.json', + assets: ['src/favicon.ico', 'src/assets'], + styles: ['src/styles.css'], }); - it('works with service worker', async () => { - setupTarget(harness, { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - serviceWorker: (isViteRun ? 'ngsw-config.json' : true) as any, - assets: ['src/favicon.ico', 'src/assets'], - styles: ['src/styles.css'], - }); - - await harness.writeFiles({ - 'ngsw-config.json': JSON.stringify(manifest), - 'src/assets/folder-asset.txt': 'folder-asset.txt', - 'src/styles.css': `body { background: url(./spectrum.png); }`, - }); - - harness.useTarget('serve', { - ...BASE_OPTIONS, - }); - - const { result, response } = await executeOnceAndFetch(harness, '/ngsw.json'); - - expect(result?.success).toBeTrue(); - - expect(await response?.json()).toEqual( - jasmine.objectContaining({ - configVersion: 1, - index: '/index.html', - navigationUrls: [ - { positive: true, regex: '^\\/.*$' }, - { positive: false, regex: '^\\/(?:.+\\/)?[^/]*\\.[^/]*$' }, - { positive: false, regex: '^\\/(?:.+\\/)?[^/]*__[^/]*$' }, - { positive: false, regex: '^\\/(?:.+\\/)?[^/]*__[^/]*\\/.*$' }, - ], - assetGroups: [ - { - name: 'app', - installMode: 'prefetch', - updateMode: 'prefetch', - urls: ['/favicon.ico', '/index.html'], - cacheQueryOptions: { - ignoreVary: true, - }, - patterns: [], + await harness.writeFiles({ + 'ngsw-config.json': JSON.stringify(manifest), + 'src/assets/folder-asset.txt': 'folder-asset.txt', + 'src/styles.css': `body { background: url(./spectrum.png); }`, + }); + + harness.useTarget('serve', { + ...BASE_OPTIONS, + }); + + const { result, response } = await executeOnceAndFetch(harness, '/ngsw.json'); + + expect(result?.success).toBeTrue(); + + expect(await response?.json()).toEqual( + jasmine.objectContaining({ + configVersion: 1, + index: '/index.html', + navigationUrls: [ + { positive: true, regex: '^\\/.*$' }, + { positive: false, regex: '^\\/(?:.+\\/)?[^/]*\\.[^/]*$' }, + { positive: false, regex: '^\\/(?:.+\\/)?[^/]*__[^/]*$' }, + { positive: false, regex: '^\\/(?:.+\\/)?[^/]*__[^/]*\\/.*$' }, + ], + assetGroups: [ + { + name: 'app', + installMode: 'prefetch', + updateMode: 'prefetch', + urls: ['/favicon.ico', '/index.html'], + cacheQueryOptions: { + ignoreVary: true, }, - { - name: 'assets', - installMode: 'lazy', - updateMode: 'prefetch', - urls: ['/assets/folder-asset.txt', '/media/spectrum.png'], - cacheQueryOptions: { - ignoreVary: true, - }, - patterns: [], + patterns: [], + }, + { + name: 'assets', + installMode: 'lazy', + updateMode: 'prefetch', + urls: ['/assets/folder-asset.txt', '/media/spectrum.png'], + cacheQueryOptions: { + ignoreVary: true, }, - ], - dataGroups: [], - hashTable: { - '/favicon.ico': '84161b857f5c547e3699ddfbffc6d8d737542e01', - '/assets/folder-asset.txt': '617f202968a6a81050aa617c2e28e1dca11ce8d4', - '/index.html': isViteRun - ? 'e5b73e6798d2782bf59dd5272d254d5bde364695' - : '9d232e3e13b4605d197037224a2a6303dd337480', - '/media/spectrum.png': '8d048ece46c0f3af4b598a95fd8e4709b631c3c0', + patterns: [], }, - }), - ); + ], + dataGroups: [], + hashTable: { + '/favicon.ico': '84161b857f5c547e3699ddfbffc6d8d737542e01', + '/assets/folder-asset.txt': '617f202968a6a81050aa617c2e28e1dca11ce8d4', + '/index.html': 'e5b73e6798d2782bf59dd5272d254d5bde364695', + '/media/spectrum.png': '8d048ece46c0f3af4b598a95fd8e4709b631c3c0', + }, + }), + ); + }); + + it('works with localize', async () => { + setupTarget(harness, { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + serviceWorker: 'ngsw-config.json' as any, + assets: ['src/favicon.ico', 'src/assets'], + styles: ['src/styles.css'], + localize: ['fr'], }); - it('works with localize', async () => { - setupTarget(harness, { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - serviceWorker: (isViteRun ? 'ngsw-config.json' : true) as any, - assets: ['src/favicon.ico', 'src/assets'], - styles: ['src/styles.css'], - localize: ['fr'], - }); + await harness.writeFiles({ + 'ngsw-config.json': JSON.stringify(manifest), + 'src/assets/folder-asset.txt': 'folder-asset.txt', + 'src/styles.css': `body { background: url(./spectrum.png); }`, + }); + + harness.useTarget('serve', { + ...BASE_OPTIONS, + }); - await harness.writeFiles({ - 'ngsw-config.json': JSON.stringify(manifest), - 'src/assets/folder-asset.txt': 'folder-asset.txt', - 'src/styles.css': `body { background: url(./spectrum.png); }`, - }); + const { result, response } = await executeOnceAndFetch(harness, '/ngsw.json'); - harness.useTarget('serve', { - ...BASE_OPTIONS, - }); + expect(result?.success).toBeTrue(); - const { result, response } = await executeOnceAndFetch(harness, '/ngsw.json'); + expect(await response?.json()).toBeDefined(); + }); - expect(result?.success).toBeTrue(); + // TODO(fix-vite): currently this is broken in vite due to watcher never terminates. + xit('works in watch mode', async () => { + setupTarget(harness, { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + serviceWorker: 'ngsw-config.json' as any, + assets: ['src/favicon.ico', 'src/assets'], + styles: ['src/styles.css'], + }); - expect(await response?.json()).toBeDefined(); + await harness.writeFiles({ + 'ngsw-config.json': JSON.stringify(manifest), + 'src/assets/folder-asset.txt': 'folder-asset.txt', + 'src/styles.css': `body { background: url(./spectrum.png); }`, }); - // TODO(fix-vite): currently this is broken in vite due to watcher never terminates. - (isViteRun ? xit : it)('works in watch mode', async () => { - setupTarget(harness, { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - serviceWorker: (isViteRun ? 'ngsw-config.json' : true) as any, - assets: ['src/favicon.ico', 'src/assets'], - styles: ['src/styles.css'], - }); - - await harness.writeFiles({ - 'ngsw-config.json': JSON.stringify(manifest), - 'src/assets/folder-asset.txt': 'folder-asset.txt', - 'src/styles.css': `body { background: url(./spectrum.png); }`, - }); - - harness.useTarget('serve', { - ...BASE_OPTIONS, - watch: true, - }); - - await harness.executeWithCases([ - async ({ result }) => { - expect(result?.success).toBeTrue(); - const response = await fetch(new URL('ngsw.json', `${result?.baseUrl}`)); - const { hashTable } = (await response.json()) as { hashTable: object }; - const hashTableEntries = Object.keys(hashTable); - - expect(hashTableEntries).toEqual([ - '/assets/folder-asset.txt', - '/favicon.ico', - '/index.html', - '/media/spectrum.png', - ]); - - await harness.writeFile( - 'src/assets/folder-new-asset.txt', - harness.readFile('src/assets/folder-asset.txt'), - ); - }, - async ({ result }) => { - expect(result?.success).toBeTrue(); - const response = await fetch(new URL('ngsw.json', `${result?.baseUrl}`)); - const { hashTable } = (await response.json()) as { hashTable: object }; - const hashTableEntries = Object.keys(hashTable); - - expect(hashTableEntries).toEqual([ - '/assets/folder-asset.txt', - '/assets/folder-new-asset.txt', - '/favicon.ico', - '/index.html', - '/media/spectrum.png', - ]); - }, - ]); + harness.useTarget('serve', { + ...BASE_OPTIONS, + watch: true, }); + + await harness.executeWithCases([ + async ({ result }) => { + expect(result?.success).toBeTrue(); + const response = await fetch(new URL('ngsw.json', `${result?.baseUrl}`)); + const { hashTable } = (await response.json()) as { hashTable: object }; + const hashTableEntries = Object.keys(hashTable); + + expect(hashTableEntries).toEqual([ + '/assets/folder-asset.txt', + '/favicon.ico', + '/index.html', + '/media/spectrum.png', + ]); + + await harness.writeFile( + 'src/assets/folder-new-asset.txt', + harness.readFile('src/assets/folder-asset.txt'), + ); + }, + async ({ result }) => { + expect(result?.success).toBeTrue(); + const response = await fetch(new URL('ngsw.json', `${result?.baseUrl}`)); + const { hashTable } = (await response.json()) as { hashTable: object }; + const hashTableEntries = Object.keys(hashTable); + + expect(hashTableEntries).toEqual([ + '/assets/folder-asset.txt', + '/assets/folder-new-asset.txt', + '/favicon.ico', + '/index.html', + '/media/spectrum.png', + ]); + }, + ]); }); - }, -); + }); +}); diff --git a/packages/angular/build/src/builders/dev-server/tests/jasmine-helpers.ts b/packages/angular/build/src/builders/dev-server/tests/jasmine-helpers.ts index c5a73446cf5a..e680fe0f62ab 100644 --- a/packages/angular/build/src/builders/dev-server/tests/jasmine-helpers.ts +++ b/packages/angular/build/src/builders/dev-server/tests/jasmine-helpers.ts @@ -19,7 +19,6 @@ export function describeServeBuilder( specDefinitions: ( harness: JasmineBuilderHarness, setupTarget: typeof setupApplicationTarget, - isViteRun: true, ) => void, ): void { let optionSchema = optionSchemaCache.get(options.schemaPath); @@ -36,6 +35,6 @@ export function describeServeBuilder( beforeEach(() => host.initialize().toPromise()); afterEach(() => host.restore().toPromise()); - specDefinitions(harness, setupApplicationTarget, true); + specDefinitions(harness, setupApplicationTarget); }); } diff --git a/packages/angular/build/src/builders/dev-server/tests/options/port_spec.ts b/packages/angular/build/src/builders/dev-server/tests/options/port_spec.ts index 83f3a4d1486b..8869dd20dcbb 100644 --- a/packages/angular/build/src/builders/dev-server/tests/options/port_spec.ts +++ b/packages/angular/build/src/builders/dev-server/tests/options/port_spec.ts @@ -26,87 +26,58 @@ function getResultPort(result: Record | undefined): string | un } } -describeServeBuilder( - executeDevServer, - DEV_SERVER_BUILDER_INFO, - (harness, setupTarget, isViteRun) => { - describe('option: "port"', () => { - beforeEach(async () => { - setupTarget(harness); - - // Application code is not needed for these tests - await harness.writeFile('src/main.ts', ''); - }); +describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupTarget) => { + describe('option: "port"', () => { + beforeEach(async () => { + setupTarget(harness); + + // Application code is not needed for these tests + await harness.writeFile('src/main.ts', ''); + }); - it('uses default port (4200) when not present', async () => { - harness.useTarget('serve', { - ...BASE_OPTIONS, - // Base options set port to zero - port: undefined, - }); - - const { result, response, logs } = await executeOnceAndFetch(harness, '/'); - - expect(result?.success).toBeTrue(); - expect(getResultPort(result)).toBe('4200'); - expect(await response?.text()).toContain(''); - - if (!isViteRun) { - expect(logs).toContain( - jasmine.objectContaining({ - message: jasmine.stringMatching(/:4200/), - }), - ); - } + it('uses default port (4200) when not present', async () => { + harness.useTarget('serve', { + ...BASE_OPTIONS, + // Base options set port to zero + port: undefined, }); - it('uses a random free port when set to 0 (zero)', async () => { - harness.useTarget('serve', { - ...BASE_OPTIONS, - port: 0, - }); - - const { result, response, logs } = await executeOnceAndFetch(harness, '/'); - - expect(result?.success).toBeTrue(); - const port = getResultPort(result); - expect(port).not.toBe('4200'); - if (isViteRun) { - // Should not be default Vite port either - expect(port).not.toBe('5173'); - } - - expect(port).toMatch(/\d{4,6}/); - expect(await response?.text()).toContain('<title>'); - - if (!isViteRun) { - expect(logs).toContain( - jasmine.objectContaining({ - message: jasmine.stringMatching(':' + port), - }), - ); - } + const { result, response, logs } = await executeOnceAndFetch(harness, '/'); + + expect(result?.success).toBeTrue(); + expect(getResultPort(result)).toBe('4200'); + expect(await response?.text()).toContain('<title>'); + }); + + it('uses a random free port when set to 0 (zero)', async () => { + harness.useTarget('serve', { + ...BASE_OPTIONS, + port: 0, }); - it('uses specific port when a non-zero number is specified', async () => { - harness.useTarget('serve', { - ...BASE_OPTIONS, - port: 8000, - }); - - const { result, response, logs } = await executeOnceAndFetch(harness, '/'); - - expect(result?.success).toBeTrue(); - expect(getResultPort(result)).toBe('8000'); - expect(await response?.text()).toContain('<title>'); - if (!isViteRun) { - expect(logs).toContain( - jasmine.objectContaining({ - message: jasmine.stringMatching(':8000'), - }), - ); - } + const { result, response, logs } = await executeOnceAndFetch(harness, '/'); + + expect(result?.success).toBeTrue(); + const port = getResultPort(result); + expect(port).not.toBe('4200'); + // Should not be default Vite port either + expect(port).not.toBe('5173'); + + expect(port).toMatch(/\d{4,6}/); + expect(await response?.text()).toContain('<title>'); + }); + + it('uses specific port when a non-zero number is specified', async () => { + harness.useTarget('serve', { + ...BASE_OPTIONS, + port: 8000, }); + + const { result, response, logs } = await executeOnceAndFetch(harness, '/'); + + expect(result?.success).toBeTrue(); + expect(getResultPort(result)).toBe('8000'); + expect(await response?.text()).toContain('<title>'); }); - }, -); + }); +}); diff --git a/packages/angular/build/src/builders/dev-server/tests/options/prebundle_spec.ts b/packages/angular/build/src/builders/dev-server/tests/options/prebundle_spec.ts index 1e7c5fcd7322..80bab96d3bb8 100644 --- a/packages/angular/build/src/builders/dev-server/tests/options/prebundle_spec.ts +++ b/packages/angular/build/src/builders/dev-server/tests/options/prebundle_spec.ts @@ -12,88 +12,84 @@ import { describeServeBuilder } from '../jasmine-helpers'; import { BASE_OPTIONS, DEV_SERVER_BUILDER_INFO } from '../setup'; // TODO: Temporarily disabled pending investigation into test-only Vite not stopping when caching is enabled -describeServeBuilder( - executeDevServer, - DEV_SERVER_BUILDER_INFO, - (harness, setupTarget, isViteRun) => { - // prebundling is not available in webpack - (isViteRun ? xdescribe : xdescribe)('option: "prebundle"', () => { - beforeEach(async () => { - setupTarget(harness); - - harness.useProject('test', { - cli: { - cache: { - enabled: true, - }, +describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupTarget) => { + // prebundling is not available in webpack + xdescribe('option: "prebundle"', () => { + beforeEach(async () => { + setupTarget(harness); + + harness.useProject('test', { + cli: { + cache: { + enabled: true, }, - }); + }, + }); - // Application code is not needed for these tests - await harness.writeFile( - 'src/main.ts', - ` + // Application code is not needed for these tests + await harness.writeFile( + 'src/main.ts', + ` import { VERSION as coreVersion } from '@angular/core'; import { VERSION as platformVersion } from '@angular/platform-browser'; console.log(coreVersion); console.log(platformVersion); `, - ); + ); + }); + + it('should prebundle dependencies when option is not present', async () => { + harness.useTarget('serve', { + ...BASE_OPTIONS, }); - it('should prebundle dependencies when option is not present', async () => { - harness.useTarget('serve', { - ...BASE_OPTIONS, - }); + const { result, content } = await executeOnceAndFetch(harness, '/main.js'); - const { result, content } = await executeOnceAndFetch(harness, '/main.js'); + expect(result?.success).toBeTrue(); + expect(content).toContain('vite/deps/@angular_core.js'); + expect(content).not.toContain('node_modules/@angular/core/'); + }); - expect(result?.success).toBeTrue(); - expect(content).toContain('vite/deps/@angular_core.js'); - expect(content).not.toContain('node_modules/@angular/core/'); + it('should prebundle dependencies when option is set to true', async () => { + harness.useTarget('serve', { + ...BASE_OPTIONS, + prebundle: true, }); - it('should prebundle dependencies when option is set to true', async () => { - harness.useTarget('serve', { - ...BASE_OPTIONS, - prebundle: true, - }); + const { result, content } = await executeOnceAndFetch(harness, '/main.js'); - const { result, content } = await executeOnceAndFetch(harness, '/main.js'); + expect(result?.success).toBeTrue(); + expect(content).toContain('vite/deps/@angular_core.js'); + expect(content).not.toContain('node_modules/@angular/core/'); + }); - expect(result?.success).toBeTrue(); - expect(content).toContain('vite/deps/@angular_core.js'); - expect(content).not.toContain('node_modules/@angular/core/'); + it('should not prebundle dependencies when option is set to false', async () => { + harness.useTarget('serve', { + ...BASE_OPTIONS, + prebundle: false, }); - it('should not prebundle dependencies when option is set to false', async () => { - harness.useTarget('serve', { - ...BASE_OPTIONS, - prebundle: false, - }); + const { result, content } = await executeOnceAndFetch(harness, '/main.js'); - const { result, content } = await executeOnceAndFetch(harness, '/main.js'); + expect(result?.success).toBeTrue(); + expect(content).not.toContain('vite/deps/@angular_core.js'); + expect(content).toContain('node_modules/@angular/core/'); + }); - expect(result?.success).toBeTrue(); - expect(content).not.toContain('vite/deps/@angular_core.js'); - expect(content).toContain('node_modules/@angular/core/'); + it('should not prebundle specified dependency if added to exclude list', async () => { + harness.useTarget('serve', { + ...BASE_OPTIONS, + prebundle: { exclude: ['@angular/platform-browser'] }, }); - it('should not prebundle specified dependency if added to exclude list', async () => { - harness.useTarget('serve', { - ...BASE_OPTIONS, - prebundle: { exclude: ['@angular/platform-browser'] }, - }); + const { result, content } = await executeOnceAndFetch(harness, '/main.js'); - const { result, content } = await executeOnceAndFetch(harness, '/main.js'); - - expect(result?.success).toBeTrue(); - expect(content).toContain('vite/deps/@angular_core.js'); - expect(content).not.toContain('node_modules/@angular/core/'); - expect(content).not.toContain('vite/deps/@angular_platform-browser.js'); - expect(content).toContain('node_modules/@angular/platform-browser/'); - }); + expect(result?.success).toBeTrue(); + expect(content).toContain('vite/deps/@angular_core.js'); + expect(content).not.toContain('node_modules/@angular/core/'); + expect(content).not.toContain('vite/deps/@angular_platform-browser.js'); + expect(content).toContain('node_modules/@angular/platform-browser/'); }); - }, -); + }); +}); diff --git a/packages/angular/build/src/builders/dev-server/tests/options/proxy-config_spec.ts b/packages/angular/build/src/builders/dev-server/tests/options/proxy-config_spec.ts index 78f3323b97cc..1c6dfb60ca9d 100644 --- a/packages/angular/build/src/builders/dev-server/tests/options/proxy-config_spec.ts +++ b/packages/angular/build/src/builders/dev-server/tests/options/proxy-config_spec.ts @@ -12,7 +12,7 @@ import { executeOnceAndFetch } from '../execute-fetch'; import { describeServeBuilder } from '../jasmine-helpers'; import { BASE_OPTIONS, DEV_SERVER_BUILDER_INFO, BuilderHarness } from '../setup'; -describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupTarget, isVite) => { +describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupTarget) => { describe('option: "proxyConfig"', () => { beforeEach(async () => { setupTarget(harness); @@ -236,14 +236,51 @@ describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupT } }); - /** - * **************************************************************************************************** - * ********************************** Below only Vite specific tests ********************************** - * **************************************************************************************************** - */ - if (isVite) { - viteOnlyTests(harness); - } + it('proxies support regexp as context', async () => { + harness.useTarget('serve', { + ...BASE_OPTIONS, + proxyConfig: 'proxy.config.json', + }); + + const proxyServer = await createProxyServer(); + try { + await harness.writeFiles({ + 'proxy.config.json': ` + { "^/api/.*": { "target": "http://127.0.0.1:${proxyServer.address.port}" } } + `, + }); + + const { result, response } = await executeOnceAndFetch(harness, '/api/test'); + + expect(result?.success).toBeTrue(); + expect(await response?.text()).toContain('TEST_API_RETURN'); + } finally { + await proxyServer.close(); + } + }); + + it('proxies support negated regexp as context', async () => { + harness.useTarget('serve', { + ...BASE_OPTIONS, + proxyConfig: 'proxy.config.json', + }); + + const proxyServer = await createProxyServer(); + try { + await harness.writeFiles({ + 'proxy.config.json': ` + { "^\\/(?!something).*": { "target": "http://127.0.0.1:${proxyServer.address.port}" } } + `, + }); + + const { result, response } = await executeOnceAndFetch(harness, '/api/test'); + + expect(result?.success).toBeTrue(); + expect(await response?.text()).toContain('TEST_API_RETURN'); + } finally { + await proxyServer.close(); + } + }); }); }); @@ -270,54 +307,3 @@ async function createProxyServer() { close: () => new Promise<void>((resolve) => proxyServer.close(() => resolve())), }; } - -/** - * Vite specific tests - */ -function viteOnlyTests(harness: BuilderHarness<unknown>): void { - it('proxies support regexp as context', async () => { - harness.useTarget('serve', { - ...BASE_OPTIONS, - proxyConfig: 'proxy.config.json', - }); - - const proxyServer = await createProxyServer(); - try { - await harness.writeFiles({ - 'proxy.config.json': ` - { "^/api/.*": { "target": "http://127.0.0.1:${proxyServer.address.port}" } } - `, - }); - - const { result, response } = await executeOnceAndFetch(harness, '/api/test'); - - expect(result?.success).toBeTrue(); - expect(await response?.text()).toContain('TEST_API_RETURN'); - } finally { - await proxyServer.close(); - } - }); - - it('proxies support negated regexp as context', async () => { - harness.useTarget('serve', { - ...BASE_OPTIONS, - proxyConfig: 'proxy.config.json', - }); - - const proxyServer = await createProxyServer(); - try { - await harness.writeFiles({ - 'proxy.config.json': ` - { "^\\/(?!something).*": { "target": "http://127.0.0.1:${proxyServer.address.port}" } } - `, - }); - - const { result, response } = await executeOnceAndFetch(harness, '/api/test'); - - expect(result?.success).toBeTrue(); - expect(await response?.text()).toContain('TEST_API_RETURN'); - } finally { - await proxyServer.close(); - } - }); -} diff --git a/packages/angular/build/src/builders/dev-server/tests/options/serve-path_spec.ts b/packages/angular/build/src/builders/dev-server/tests/options/serve-path_spec.ts index 7570175c65d2..5917dcc8eeb4 100644 --- a/packages/angular/build/src/builders/dev-server/tests/options/serve-path_spec.ts +++ b/packages/angular/build/src/builders/dev-server/tests/options/serve-path_spec.ts @@ -12,109 +12,105 @@ import { executeOnceAndFetch } from '../execute-fetch'; import { describeServeBuilder } from '../jasmine-helpers'; import { BASE_OPTIONS, DEV_SERVER_BUILDER_INFO } from '../setup'; -describeServeBuilder( - executeDevServer, - DEV_SERVER_BUILDER_INFO, - (harness, setupTarget, isViteRun) => { - describe('option: "servePath"', () => { - beforeEach(async () => { - setupTarget(harness, { - assets: ['src/assets'], - }); - - // Application code is not needed for these tests - await harness.writeFile('src/main.ts', 'console.log("foo");'); +describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupTarget) => { + describe('option: "servePath"', () => { + beforeEach(async () => { + setupTarget(harness, { + assets: ['src/assets'], }); - it('serves application at the root when option is not present', async () => { - harness.useTarget('serve', { - ...BASE_OPTIONS, - }); - - const { result, response } = await executeOnceAndFetch(harness, '/main.js'); + // Application code is not needed for these tests + await harness.writeFile('src/main.ts', 'console.log("foo");'); + }); - expect(result?.success).toBeTrue(); - const baseUrl = new URL(`${result?.baseUrl}`); - expect(baseUrl.pathname).toBe('/'); - expect(await response?.text()).toContain('console.log'); + it('serves application at the root when option is not present', async () => { + harness.useTarget('serve', { + ...BASE_OPTIONS, }); - it('serves application at specified path when option is used', async () => { - harness.useTarget('serve', { - ...BASE_OPTIONS, - servePath: 'test', - }); + const { result, response } = await executeOnceAndFetch(harness, '/main.js'); - const { result, response } = await executeOnceAndFetch(harness, '/test/main.js'); + expect(result?.success).toBeTrue(); + const baseUrl = new URL(`${result?.baseUrl}`); + expect(baseUrl.pathname).toBe('/'); + expect(await response?.text()).toContain('console.log'); + }); - expect(result?.success).toBeTrue(); - const baseUrl = new URL(`${result?.baseUrl}/`); - expect(baseUrl.pathname).toBe('/test/'); - expect(await response?.text()).toContain('console.log'); + it('serves application at specified path when option is used', async () => { + harness.useTarget('serve', { + ...BASE_OPTIONS, + servePath: 'test', }); - // TODO(fix-vite): currently this is broken in vite. - (isViteRun ? xit : it)('does not rewrite from root when option is used', async () => { - harness.useTarget('serve', { - ...BASE_OPTIONS, - servePath: 'test', - }); + const { result, response } = await executeOnceAndFetch(harness, '/test/main.js'); - const { result, response } = await executeOnceAndFetch(harness, '/', { - // fallback processing requires an accept header - request: { headers: { accept: 'text/html' } }, - }); + expect(result?.success).toBeTrue(); + const baseUrl = new URL(`${result?.baseUrl}/`); + expect(baseUrl.pathname).toBe('/test/'); + expect(await response?.text()).toContain('console.log'); + }); - expect(result?.success).toBeTrue(); - expect(response?.status).toBe(404); + // TODO(fix-vite): currently this is broken in vite. + xit('does not rewrite from root when option is used', async () => { + harness.useTarget('serve', { + ...BASE_OPTIONS, + servePath: 'test', }); - it('does not rewrite from path outside serve path when option is used', async () => { - harness.useTarget('serve', { - ...BASE_OPTIONS, - servePath: 'test', - }); + const { result, response } = await executeOnceAndFetch(harness, '/', { + // fallback processing requires an accept header + request: { headers: { accept: 'text/html' } }, + }); - const { result, response } = await executeOnceAndFetch(harness, '/api/', { - // fallback processing requires an accept header - request: { headers: { accept: 'text/html' } }, - }); + expect(result?.success).toBeTrue(); + expect(response?.status).toBe(404); + }); - expect(result?.success).toBeTrue(); - expect(response?.status).toBe(404); + it('does not rewrite from path outside serve path when option is used', async () => { + harness.useTarget('serve', { + ...BASE_OPTIONS, + servePath: 'test', }); - it('rewrites from path inside serve path when option is used', async () => { - harness.useTarget('serve', { - ...BASE_OPTIONS, - servePath: 'test', - }); + const { result, response } = await executeOnceAndFetch(harness, '/api/', { + // fallback processing requires an accept header + request: { headers: { accept: 'text/html' } }, + }); - const { result, response } = await executeOnceAndFetch(harness, '/test/inside', { - // fallback processing requires an accept header - request: { headers: { accept: 'text/html' } }, - }); + expect(result?.success).toBeTrue(); + expect(response?.status).toBe(404); + }); + + it('rewrites from path inside serve path when option is used', async () => { + harness.useTarget('serve', { + ...BASE_OPTIONS, + servePath: 'test', + }); - expect(result?.success).toBeTrue(); - expect(await response?.text()).toContain('<title>'); + const { result, response } = await executeOnceAndFetch(harness, '/test/inside', { + // fallback processing requires an accept header + request: { headers: { accept: 'text/html' } }, }); - it('serves assets at specified path when option is used', async () => { - await harness.writeFile('src/assets/test.txt', 'hello world!'); + expect(result?.success).toBeTrue(); + expect(await response?.text()).toContain('<title>'); + }); - harness.useTarget('serve', { - ...BASE_OPTIONS, - servePath: 'test', - }); + it('serves assets at specified path when option is used', async () => { + await harness.writeFile('src/assets/test.txt', 'hello world!'); - const { result, response } = await executeOnceAndFetch(harness, '/test/assets/test.txt', { - // fallback processing requires an accept header - request: { headers: { accept: 'text/html' } }, - }); + harness.useTarget('serve', { + ...BASE_OPTIONS, + servePath: 'test', + }); - expect(result?.success).toBeTrue(); - expect(await response?.text()).toContain('hello world'); + const { result, response } = await executeOnceAndFetch(harness, '/test/assets/test.txt', { + // fallback processing requires an accept header + request: { headers: { accept: 'text/html' } }, }); + + expect(result?.success).toBeTrue(); + expect(await response?.text()).toContain('hello world'); }); - }, -); + }); +}); diff --git a/packages/angular/build/src/builders/dev-server/vite/index.ts b/packages/angular/build/src/builders/dev-server/vite/index.ts index 8129daac1ba1..557b2d34b52a 100644 --- a/packages/angular/build/src/builders/dev-server/vite/index.ts +++ b/packages/angular/build/src/builders/dev-server/vite/index.ts @@ -9,7 +9,6 @@ import type { BuilderContext } from '@angular-devkit/architect'; import type { Plugin } from 'esbuild'; import assert from 'node:assert'; -import { builtinModules, isBuiltin } from 'node:module'; import { join } from 'node:path'; import type { Connect, ViteDevServer } from 'vite'; import type { ComponentStyleRecord } from '../../../tools/vite/middlewares'; @@ -21,7 +20,6 @@ import { Result, ResultKind } from '../../application/results'; import { OutputHashing } from '../../application/schema'; import { type ApplicationBuilderInternalOptions, - type ExternalResultMetadata, JavaScriptTransformer, getSupportedBrowsers, isZonelessApp, @@ -99,8 +97,20 @@ export async function* serveWithVite( browserOptions.ssr ||= true; } - // Disable auto CSP. + // Vite allowedHost syntax doesn't allow `*.` but `.` acts as `*.` + // Angular SSR supports `*.`. + const allowedHosts = Array.isArray(serverOptions.allowedHosts) + ? serverOptions.allowedHosts.map((host) => (host[0] === '.' ? '*' + host : host)) + : serverOptions.allowedHosts === true + ? ['*'] + : []; + + // Always allow the dev server host + allowedHosts.push(serverOptions.host); + browserOptions.security = { + allowedHosts, + // Disable auto CSP. autoCsp: false, }; diff --git a/packages/angular/build/src/builders/unit-test/builder.ts b/packages/angular/build/src/builders/unit-test/builder.ts index 6f2edd0281d7..690baf74ca3a 100644 --- a/packages/angular/build/src/builders/unit-test/builder.ts +++ b/packages/angular/build/src/builders/unit-test/builder.ts @@ -373,16 +373,15 @@ async function transformNgPackagrOptions( throw new Error(`Could not read ng-package.json at ${ngPackagePath}: ${e.message}`); } - const lib = ngPackageJson['lib'] || {}; - const styleIncludePaths = lib['styleIncludePaths'] || []; - const assets = ngPackageJson['assets'] || []; - const inlineStyleLanguage = ngPackageJson['inlineStyleLanguage']; + const { lib: { styleIncludePaths = [] } = {}, assets = [], inlineStyleLanguage } = ngPackageJson; + + const includePaths = styleIncludePaths.map((includePath: string) => + path.resolve(path.dirname(ngPackagePath), includePath), + ); return { - stylePreprocessorOptions: styleIncludePaths.length - ? { includePaths: styleIncludePaths } - : undefined, + stylePreprocessorOptions: includePaths.length ? { includePaths } : undefined, assets: assets.length ? assets : undefined, - inlineStyleLanguage: typeof inlineStyleLanguage === 'string' ? inlineStyleLanguage : undefined, + inlineStyleLanguage, } as ApplicationBuilderInternalOptions; } diff --git a/packages/angular/build/src/builders/unit-test/options.ts b/packages/angular/build/src/builders/unit-test/options.ts index 72b5f3eb3e8d..0a71f2d642f1 100644 --- a/packages/angular/build/src/builders/unit-test/options.ts +++ b/packages/angular/build/src/builders/unit-test/options.ts @@ -116,7 +116,7 @@ export async function normalizeOptions( buildProgress: progress, reporters: normalizeReporterOption(options.reporters), outputFile: options.outputFile, - browsers, + browsers: browsers?.length ? browsers : undefined, browserViewport: width && height ? { width, height } : undefined, watch, debug: options.debug ?? false, diff --git a/packages/angular/build/src/builders/unit-test/runners/vitest/browser-provider.ts b/packages/angular/build/src/builders/unit-test/runners/vitest/browser-provider.ts index f89848abfbf6..0ca80f4fa60f 100644 --- a/packages/angular/build/src/builders/unit-test/runners/vitest/browser-provider.ts +++ b/packages/angular/build/src/builders/unit-test/runners/vitest/browser-provider.ts @@ -7,7 +7,11 @@ */ import { createRequire } from 'node:module'; -import type { BrowserBuiltinProvider, BrowserConfigOptions } from 'vitest/node'; +import type { + BrowserBuiltinProvider, + BrowserConfigOptions, + BrowserProviderOption, +} from 'vitest/node'; import { assertIsError } from '../../../../utils/error'; export interface BrowserConfiguration { @@ -37,7 +41,13 @@ function findBrowserProvider( return undefined; } -function normalizeBrowserName(browserName: string): { browser: string; headless: boolean } { +export interface BrowserInstanceConfiguration { + browser: string; + headless: boolean; + provider?: BrowserProviderOption; +} + +function normalizeBrowserName(browserName: string): BrowserInstanceConfiguration { // Normalize browser names to match Vitest's expectations for headless but also supports karma's names // e.g., 'ChromeHeadless' -> 'chrome', 'FirefoxHeadless' -> 'firefox' // and 'Chrome' -> 'chrome', 'Firefox' -> 'firefox'. @@ -50,6 +60,67 @@ function normalizeBrowserName(browserName: string): { browser: string; headless: }; } +/** + * Mutates the provided browser instances to apply standard headless execution + * constraints based on the chosen provider, user options, and CI environment presence. + * + * @param instances The normalized browser instances to mutate. + * @param providerName The identifier for the chosen Vitest browser provider. + * @param headless The user-provided headless configuration option. + * @param isCI Whether the current environment is running in CI. + * @returns An array of informational messages generated during evaluation. + */ +export function applyHeadlessConfiguration( + instances: BrowserInstanceConfiguration[], + providerName: BrowserBuiltinProvider | undefined, + headless: boolean | undefined, + isCI: boolean, +): string[] { + const messages: string[] = []; + + if (providerName === 'preview') { + instances.forEach((instance) => { + // Preview mode only supports headed execution + instance.headless = false; + }); + + if (headless) { + messages.push('The "headless" option is ignored when using the "preview" provider.'); + } + } else if (headless !== undefined) { + if (headless) { + const allHeadlessByDefault = isCI || instances.every((i) => i.headless); + if (allHeadlessByDefault) { + messages.push( + 'The "headless" option is unnecessary as all browsers are already configured to run in headless mode.', + ); + } + } + + instances.forEach((instance) => { + instance.headless = headless; + }); + } else if (isCI) { + instances.forEach((instance) => { + instance.headless = true; + }); + } + + return messages; +} + +/** + * Resolves and configures the Vitest browser provider for the unit test builder. + * Dynamically discovers and imports the necessary provider (Playwright, WebdriverIO, or Preview), + * maps the requested browser instances, and applies environment-specific execution logic. + * + * @param browsers An array of requested browser names (e.g., 'chrome', 'firefox'). + * @param headless User-provided configuration for headless execution. + * @param debug Whether the builder is running in watch or debug mode. + * @param projectSourceRoot The root directory of the project being tested for resolving installed packages. + * @param viewport Optional viewport dimensions to apply to the launched browser instances. + * @returns A fully resolved Vitest browser configuration object alongside any generated warning or error messages. + */ export async function setupBrowserConfiguration( browsers: string[] | undefined, headless: boolean | undefined, @@ -79,6 +150,8 @@ export async function setupBrowserConfiguration( ); } + const instances = browsers.map(normalizeBrowserName); + let provider: import('vitest/node').BrowserProviderOption | undefined; if (providerName) { const providerPackage = `@vitest/browser-${providerName}`; @@ -88,29 +161,27 @@ export async function setupBrowserConfiguration( // Validate that the imported module has the expected structure const providerFactory = providerModule[providerName]; if (typeof providerFactory === 'function') { - if ( - providerName === 'playwright' && - process.env['CHROME_BIN']?.includes('rules_browsers') - ) { - // Use the Chrome binary from the 'rules_browsers' toolchain (via CHROME_BIN) - // for Playwright when available to ensure hermetic testing, preventing reliance - // on locally installed or NPM-managed browser versions. - provider = providerFactory({ - launchOptions: { - executablePath: process.env.CHROME_BIN, - }, + if (providerName === 'playwright') { + const executablePath = process.env['CHROME_BIN']; + const baseOptions = { contextOptions: { // Enables `prefer-color-scheme` for Vitest browser instead of `light` colorScheme: null, }, - }); - } else if (providerName === 'playwright') { - provider = providerFactory({ - contextOptions: { - // Enables `prefer-color-scheme` for Vitest browser instead of `light` - colorScheme: null, - }, - }); + }; + + provider = providerFactory(baseOptions); + + if (executablePath) { + for (const instance of instances) { + if (instance.browser === 'chrome' || instance.browser === 'chromium') { + instance.provider = providerFactory({ + ...baseOptions, + launchOptions: { executablePath }, + }); + } + } + } } else { provider = providerFactory(); } @@ -143,36 +214,7 @@ export async function setupBrowserConfiguration( } const isCI = !!process.env['CI']; - const instances = browsers.map(normalizeBrowserName); - const messages: string[] = []; - - if (providerName === 'preview') { - instances.forEach((instance) => { - // Preview mode only supports headed execution - instance.headless = false; - }); - - if (headless) { - messages.push('The "headless" option is ignored when using the "preview" provider.'); - } - } else if (headless !== undefined) { - if (headless) { - const allHeadlessByDefault = isCI || instances.every((i) => i.headless); - if (allHeadlessByDefault) { - messages.push( - 'The "headless" option is unnecessary as all browsers are already configured to run in headless mode.', - ); - } - } - - instances.forEach((instance) => { - instance.headless = headless; - }); - } else if (isCI) { - instances.forEach((instance) => { - instance.headless = true; - }); - } + const messages = applyHeadlessConfiguration(instances, providerName, headless, isCI); const browser = { enabled: true, diff --git a/packages/angular/build/src/builders/unit-test/runners/vitest/browser-provider_spec.ts b/packages/angular/build/src/builders/unit-test/runners/vitest/browser-provider_spec.ts index 66f7254593b0..0dd0778420bd 100644 --- a/packages/angular/build/src/builders/unit-test/runners/vitest/browser-provider_spec.ts +++ b/packages/angular/build/src/builders/unit-test/runners/vitest/browser-provider_spec.ts @@ -9,7 +9,7 @@ import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; -import { setupBrowserConfiguration } from './browser-provider'; +import { applyHeadlessConfiguration, setupBrowserConfiguration } from './browser-provider'; describe('setupBrowserConfiguration', () => { let workspaceRoot: string; @@ -47,8 +47,8 @@ describe('setupBrowserConfiguration', () => { expect(browser?.enabled).toBeTrue(); expect(browser?.instances).toEqual([ - { browser: 'chrome', headless: true }, - { browser: 'firefox', headless: false }, + jasmine.objectContaining({ browser: 'chrome', headless: true }), + jasmine.objectContaining({ browser: 'firefox', headless: false }), ]); }); @@ -66,8 +66,8 @@ describe('setupBrowserConfiguration', () => { ); expect(browser?.instances).toEqual([ - { browser: 'chrome', headless: true }, - { browser: 'firefox', headless: true }, + jasmine.objectContaining({ browser: 'chrome', headless: true }), + jasmine.objectContaining({ browser: 'firefox', headless: true }), ]); } finally { if (originalCI === undefined) { @@ -196,8 +196,8 @@ describe('setupBrowserConfiguration', () => { ); expect(browser?.instances).toEqual([ - { browser: 'chrome', headless: true }, - { browser: 'firefox', headless: true }, + jasmine.objectContaining({ browser: 'chrome', headless: true }), + jasmine.objectContaining({ browser: 'firefox', headless: true }), ]); expect(messages).toEqual([]); }); @@ -215,4 +215,106 @@ describe('setupBrowserConfiguration', () => { 'The "headless" option is unnecessary as all browsers are already configured to run in headless mode.', ]); }); + + describe('CHROME_BIN usage', () => { + let originalChromeBin: string | undefined; + + beforeEach(() => { + originalChromeBin = process.env['CHROME_BIN']; + process.env['CHROME_BIN'] = '/custom/path/to/chrome'; + }); + + afterEach(() => { + if (originalChromeBin === undefined) { + delete process.env['CHROME_BIN']; + } else { + process.env['CHROME_BIN'] = originalChromeBin; + } + }); + + it('should set executablePath on the individual chrome instance', async () => { + const { browser } = await setupBrowserConfiguration( + ['ChromeHeadless', 'Chromium'], + undefined, + false, + workspaceRoot, + undefined, + ); + + // Verify the global provider does NOT have executablePath + // eslint-disable-next-line @typescript-eslint/no-explicit-any + expect((browser?.provider as any)?.options?.launchOptions?.executablePath).toBeUndefined(); + + // Verify the individual instances have executablePath + expect( + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (browser?.instances?.[0]?.provider as any)?.options?.launchOptions?.executablePath, + ).toBe('/custom/path/to/chrome'); + expect( + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (browser?.instances?.[1]?.provider as any)?.options?.launchOptions?.executablePath, + ).toBe('/custom/path/to/chrome'); + }); + + it('should set executablePath for chrome instances but not for others when mixed browsers are requested', async () => { + const { browser } = await setupBrowserConfiguration( + ['ChromeHeadless', 'Firefox'], + undefined, + false, + workspaceRoot, + undefined, + ); + + // Verify the global provider does NOT have executablePath + // eslint-disable-next-line @typescript-eslint/no-explicit-any + expect((browser?.provider as any)?.options?.launchOptions?.executablePath).toBeUndefined(); + + // Verify chrome gets it + expect( + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (browser?.instances?.[0]?.provider as any)?.options?.launchOptions?.executablePath, + ).toBe('/custom/path/to/chrome'); + + // Verify firefox does not + expect(browser?.instances?.[1]?.provider).toBeUndefined(); + }); + }); + + describe('applyHeadlessConfiguration', () => { + it('should set headless false and issue warning when using preview provider with headless true', () => { + const instances = [{ browser: 'chrome', headless: true }]; + const messages = applyHeadlessConfiguration(instances, 'preview', true, false); + + expect(instances[0].headless).toBeFalse(); + expect(messages).toEqual([ + 'The "headless" option is ignored when using the "preview" provider.', + ]); + }); + + it('should force headless mode when headless option is true', () => { + const instances = [{ browser: 'chrome', headless: false }]; + const messages = applyHeadlessConfiguration(instances, 'playwright', true, false); + + expect(instances[0].headless).toBeTrue(); + expect(messages).toEqual([]); + }); + + it('should return information message when headless option is redundant', () => { + const instances = [{ browser: 'chrome', headless: true }]; + const messages = applyHeadlessConfiguration(instances, 'playwright', true, false); + + expect(instances[0].headless).toBeTrue(); + expect(messages).toEqual([ + 'The "headless" option is unnecessary as all browsers are already configured to run in headless mode.', + ]); + }); + + it('should force headless mode in CI environment when headless is undefined', () => { + const instances = [{ browser: 'chrome', headless: false }]; + const messages = applyHeadlessConfiguration(instances, 'playwright', undefined, true); + + expect(instances[0].headless).toBeTrue(); + expect(messages).toEqual([]); + }); + }); }); diff --git a/packages/angular/build/src/builders/unit-test/runners/vitest/build-options.ts b/packages/angular/build/src/builders/unit-test/runners/vitest/build-options.ts index 3aa7e2c8947e..27519844312a 100644 --- a/packages/angular/build/src/builders/unit-test/runners/vitest/build-options.ts +++ b/packages/angular/build/src/builders/unit-test/runners/vitest/build-options.ts @@ -156,13 +156,37 @@ export async function getVitestBuildOptions( const mockPatchContents = ` import { vi } from 'vitest'; - const error = new Error( - 'The "vi.mock" and related methods are not supported with the Angular unit-test system. Please use Angular TestBed for mocking.'); - vi.mock = () => { throw error; }; - vi.doMock = () => { throw error; }; - vi.importMock = () => { throw error; }; - vi.unmock = () => { throw error; }; - vi.doUnmock = () => { throw error; }; + + const ANGULAR_VITEST_MOCK_PATCH = Symbol.for('@angular/cli/vitest-mock-patch'); + if (!globalThis[ANGULAR_VITEST_MOCK_PATCH]) { + globalThis[ANGULAR_VITEST_MOCK_PATCH] = true; + + const error = new Error( + 'The "vi.mock" and related methods are not supported for relative imports with the Angular unit-test system. ' + + 'Please use Angular TestBed for mocking dependencies.' + ); + + // Store original implementations + const { mock, doMock, importMock, unmock, doUnmock } = vi; + + function patch(original) { + return (path, ...args) => { + // Check if the path is a string and starts with a character that indicates a relative path. + if (typeof path === 'string' && /^[./]/.test(path)) { + throw error; + } + + // Call the original function for non-relative paths. + return original(path, ...args); + }; + } + + vi.mock = patch(mock); + vi.doMock = patch(doMock); + vi.importMock = patch(importMock); + vi.unmock = patch(unmock); + vi.doUnmock = patch(doUnmock); + } `; return { diff --git a/packages/angular/build/src/builders/unit-test/runners/vitest/executor.ts b/packages/angular/build/src/builders/unit-test/runners/vitest/executor.ts index 503aa5da9071..cbf9a577c4e4 100644 --- a/packages/angular/build/src/builders/unit-test/runners/vitest/executor.ts +++ b/packages/angular/build/src/builders/unit-test/runners/vitest/executor.ts @@ -27,6 +27,11 @@ import { setupBrowserConfiguration } from './browser-provider'; import { findVitestBaseConfig } from './configuration'; import { createVitestConfigPlugin, createVitestPlugins } from './plugins'; +enum DebugLogLevel { + Info = 1, + Verbose = 2, +} + export class VitestExecutor implements TestExecutor { private vitest: Vitest | undefined; private normalizePath: ((id: string) => string) | undefined; @@ -40,6 +45,7 @@ export class VitestExecutor implements TestExecutor { explicitBrowser: [], explicitServer: [], }; + private readonly debugLevel: number; // This is a reverse map of the entry points created in `build-options.ts`. // It is used by the in-memory provider plugin to map the requested test file @@ -54,19 +60,42 @@ export class VitestExecutor implements TestExecutor { testEntryPointMappings: Map<string, string> | undefined, logger: BuilderContext['logger'], ) { + const level = parseInt(process.env['NG_TEST_LOG'] ?? '0', 10); + this.debugLevel = isNaN(level) ? 0 : level; + this.projectName = projectName; this.options = options; this.logger = logger; + this.debugLog(DebugLogLevel.Info, 'VitestExecutor instantiated.'); + this.debugLog(DebugLogLevel.Verbose, 'NormalizedUnitTestBuilderOptions:', options); + if (testEntryPointMappings) { for (const [entryPoint, testFile] of testEntryPointMappings) { this.testFileToEntryPoint.set(testFile, entryPoint); this.entryPointToTestFile.set(entryPoint + '.js', testFile); } + this.debugLog( + DebugLogLevel.Verbose, + 'Test entry point mappings:', + Object.fromEntries(testEntryPointMappings), + ); } } + private debugLog(level: DebugLogLevel, message: string, data?: object) { + if (this.debugLevel < level) { + return; + } + + const formattedMessage = `[VitestExecutor:${DebugLogLevel[level]}] ${message}`; + // Custom formatting for data object to ensure it's readable + const logData = data ? JSON.stringify(data, null, 2) : ''; + this.logger.info(`${formattedMessage}${logData ? `\n${logData}` : ''}`); + } + async *execute(buildResult: FullResult | IncrementalResult): AsyncIterable<BuilderOutput> { + this.debugLog(DebugLogLevel.Info, `Executing test run (kind: ${buildResult.kind}).`); this.normalizePath ??= (await import('vite')).normalizePath; if (buildResult.kind === ResultKind.Full) { @@ -74,7 +103,20 @@ export class VitestExecutor implements TestExecutor { for (const [path, file] of Object.entries(buildResult.files)) { this.buildResultFiles.set(this.normalizePath(path), file); } + this.debugLog( + DebugLogLevel.Info, + `Full build results received. Total files: ${this.buildResultFiles.size}.`, + ); } else { + this.debugLog( + DebugLogLevel.Info, + `Incremental build results received.` + + `Added: ${buildResult.added.length}, Modified: ${buildResult.modified.length}, Removed: ${buildResult.removed.length}.`, + ); + this.debugLog(DebugLogLevel.Verbose, 'Added files:', buildResult.added); + this.debugLog(DebugLogLevel.Verbose, 'Modified files:', buildResult.modified); + this.debugLog(DebugLogLevel.Verbose, 'Removed files:', buildResult.removed); + for (const file of buildResult.removed) { this.buildResultFiles.delete(this.normalizePath(file.path)); } @@ -84,6 +126,7 @@ export class VitestExecutor implements TestExecutor { } updateExternalMetadata(buildResult, this.externalMetadata, undefined, true); + this.debugLog(DebugLogLevel.Verbose, 'Updated external metadata:', this.externalMetadata); // Reset the exit code to allow for a clean state. // This is necessary because Vitest may set the exit code on failure, which can @@ -103,7 +146,16 @@ export class VitestExecutor implements TestExecutor { // We need to find the original source file path to pass to Vitest. const source = this.entryPointToTestFile.get(modifiedFile); if (source) { + this.debugLog( + DebugLogLevel.Verbose, + `Mapped output file '${modifiedFile}' to source file '${source}' for re-run.`, + ); modifiedSourceFiles.add(source); + } else { + this.debugLog( + DebugLogLevel.Verbose, + `Could not map output file '${modifiedFile}' to a source file. It may not be a test file.`, + ); } vitest.invalidateFile( this.normalizePath(path.join(this.options.workspaceRoot, modifiedFile)), @@ -120,7 +172,11 @@ export class VitestExecutor implements TestExecutor { } if (specsToRerun.length > 0) { + this.debugLog(DebugLogLevel.Info, `Re-running ${specsToRerun.length} test specifications.`); + this.debugLog(DebugLogLevel.Verbose, 'Specs to rerun:', specsToRerun); testResults = await vitest.rerunTestSpecifications(specsToRerun); + } else { + this.debugLog(DebugLogLevel.Info, 'No test specifications to rerun.'); } } @@ -128,20 +184,29 @@ export class VitestExecutor implements TestExecutor { const testModules = testResults?.testModules ?? this.vitest.state.getTestModules(); let success = testModules.every((testModule) => testModule.ok()); + let finalResultReason = 'All tests passed.'; + // Vitest does not return a failure result when coverage thresholds are not met. // Instead, it sets the process exit code to 1. // We check this exit code to determine if the test run should be considered a failure. if (success && process.exitCode === 1) { success = false; + finalResultReason = 'Test run failed due to unmet coverage thresholds.'; // Reset the exit code to prevent it from carrying over to subsequent runs/builds process.exitCode = 0; } + this.debugLog( + DebugLogLevel.Info, + `Test run finished with success: ${success}. Reason: ${finalResultReason}`, + ); yield { success }; } async [Symbol.asyncDispose](): Promise<void> { + this.debugLog(DebugLogLevel.Info, 'Disposing VitestExecutor: Closing Vitest instance.'); await this.vitest?.close(); + this.debugLog(DebugLogLevel.Info, 'Vitest instance closed.'); } private prepareSetupFiles(): string[] { @@ -154,10 +219,13 @@ export class VitestExecutor implements TestExecutor { testSetupFiles.unshift('polyfills.js'); } + this.debugLog(DebugLogLevel.Info, 'Prepared setup files:', testSetupFiles); + return testSetupFiles; } private async initializeVitest(): Promise<Vitest> { + this.debugLog(DebugLogLevel.Info, 'Initializing Vitest.'); const { coverage, reporters, @@ -180,6 +248,10 @@ export class VitestExecutor implements TestExecutor { vitestNodeModule = await import('vitest/node'); } catch (error: unknown) { assertIsError(error); + this.debugLog( + DebugLogLevel.Info, + `Failed to import 'vitest/node'. Error code: ${error.code}`, + ); if (error.code !== 'ERR_MODULE_NOT_FOUND') { throw error; } @@ -198,6 +270,9 @@ export class VitestExecutor implements TestExecutor { browserViewport, ); if (browserOptions.errors?.length) { + this.debugLog(DebugLogLevel.Info, 'Browser configuration errors found.', { + errors: browserOptions.errors, + }); throw new Error(browserOptions.errors.join('\n')); } @@ -206,7 +281,14 @@ export class VitestExecutor implements TestExecutor { this.logger.info(message); } } + this.debugLog(DebugLogLevel.Info, 'Browser configuration complete.', { + config: browserOptions.browser, + }); + this.debugLog( + DebugLogLevel.Info, + `Verifying build results. File count: ${this.buildResultFiles.size}.`, + ); assert( this.buildResultFiles.size > 0, 'buildResult must be available before initializing vitest', @@ -234,6 +316,10 @@ export class VitestExecutor implements TestExecutor { ? await findVitestBaseConfig([projectRoot, workspaceRoot]) : runnerConfig; + this.debugLog(DebugLogLevel.Info, 'External Vitest configuration path:', { + externalConfigPath, + }); + let project = projectName; if (debug && browserOptions.browser?.instances) { if (browserOptions.browser.instances.length > 1) { @@ -245,6 +331,9 @@ export class VitestExecutor implements TestExecutor { // When running browser tests, Vitest appends the browser name to the project identifier. // The project name must match this augmented name to ensure the correct project is targeted. project = `${projectName} (${browserOptions.browser.instances[0].browser})`; + this.debugLog(DebugLogLevel.Info, 'Adjusted project name for debugging with browser:', { + project, + }); } // Filter internal entries and setup files from the include list @@ -255,43 +344,47 @@ export class VitestExecutor implements TestExecutor { !internalEntries.some((internal) => entry.startsWith(internal)) && !setupFileSet.has(entry) ); }); + this.debugLog(DebugLogLevel.Verbose, 'Included test files (after filtering):', include); - return startVitest( - 'test', - undefined, - { - config: externalConfigPath, - root: workspaceRoot, - project, - outputFile, - cache: cacheOptions.enabled ? undefined : false, - testNamePattern: this.options.filter, - watch, - ...(typeof ui === 'boolean' ? { ui } : {}), - ...debugOptions, - }, - { - // Note `.vitest` is auto appended to the path. - cacheDir: cacheOptions.path, - server: { - // Disable the actual file watcher. The boolean watch option above should still - // be enabled as it controls other internal behavior related to rerunning tests. - watch: null, - }, - plugins: [ - await createVitestConfigPlugin({ - browser: browserOptions.browser, - coverage, - projectName, - projectSourceRoot, - optimizeDepsInclude: this.externalMetadata.implicitBrowser, - reporters, - setupFiles: testSetupFiles, - projectPlugins, - include, - }), - ], + const vitestConfig = { + config: externalConfigPath, + root: workspaceRoot, + project, + outputFile, + cache: cacheOptions.enabled ? undefined : (false as const), + testNamePattern: this.options.filter, + watch, + ...(typeof ui === 'boolean' ? { ui } : {}), + ...debugOptions, + }; + const vitestServerConfig = { + // Note `.vitest` is auto appended to the path. + cacheDir: cacheOptions.path, + server: { + // Disable the actual file watcher. The boolean watch option above should still + // be enabled as it controls other internal behavior related to rerunning tests. + watch: null, }, - ); + plugins: [ + await createVitestConfigPlugin({ + browser: browserOptions.browser, + coverage, + projectName, + projectSourceRoot, + optimizeDepsInclude: this.externalMetadata.implicitBrowser, + reporters, + setupFiles: testSetupFiles, + projectPlugins, + include, + watch, + }), + ], + }; + + this.debugLog(DebugLogLevel.Info, 'Calling startVitest with final configuration.'); + this.debugLog(DebugLogLevel.Verbose, 'Vitest config:', vitestConfig); + this.debugLog(DebugLogLevel.Verbose, 'Vitest server config:', vitestServerConfig); + + return startVitest('test', undefined, vitestConfig, vitestServerConfig); } } diff --git a/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts b/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts index 9abe0d7be404..d36f8a05ffa6 100644 --- a/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts +++ b/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts @@ -46,6 +46,7 @@ interface VitestConfigPluginOptions { projectPlugins: Exclude<UserWorkspaceConfig['plugins'], undefined>; include: string[]; optimizeDepsInclude: string[]; + watch: boolean; } async function findTestEnvironment( @@ -81,6 +82,18 @@ export async function createVitestConfigPlugin( async config(config) { const testConfig = config.test; + if (reporters !== undefined) { + delete testConfig?.reporters; + } + + if ( + options.coverage.reporters !== undefined && + testConfig?.coverage && + 'reporter' in testConfig.coverage + ) { + delete testConfig.coverage.reporter; + } + if (testConfig?.projects?.length) { this.warn( 'The "test.projects" option in the Vitest configuration file is not supported. ' + @@ -97,6 +110,22 @@ export async function createVitestConfigPlugin( delete testConfig.include; } + if (testConfig?.watch !== undefined && testConfig.watch !== options.watch) { + this.warn( + `The "test.watch" option in the Vitest configuration file is overridden by the builder's ` + + `watch option. Please use the Angular CLI "--watch" option to enable or disable watch mode.`, + ); + delete testConfig.watch; + } + + if (testConfig?.exclude) { + this.warn( + 'The "test.exclude" option in the Vitest configuration file is evaluated after ' + + 'tests are compiled. For better build performance, please use the Angular CLI ' + + '"exclude" option instead.', + ); + } + // Merge user-defined plugins from the Vitest config with the CLI's internal plugins. if (config.plugins) { const userPlugins = config.plugins.filter( @@ -389,6 +418,9 @@ async function generateCoverageOption( projectName: string, ): Promise<VitestCoverageOption> { let defaultExcludes: string[] = []; + // When a coverage exclude option is provided, Vitest's default coverage excludes + // will be overridden. To retain them, we manually fetch the defaults to append to the + // user's provided exclusions. if (optionsCoverage.exclude) { try { const vitestConfig = await import('vitest/config'); @@ -420,12 +452,15 @@ async function generateCoverageOption( // Special handling for `exclude`/`reporters` due to an undefined value causing upstream failures ...(optionsCoverage.exclude ? { - exclude: [ - // Augment the default exclude https://vitest.dev/config/#coverage-exclude - // with the user defined exclusions - ...optionsCoverage.exclude, - ...defaultExcludes, - ], + exclude: Array.from( + new Set([ + // Augment the default exclude https://vitest.dev/config/#coverage-exclude + // with the user defined exclusions + ...(configCoverage?.exclude || []), + ...optionsCoverage.exclude, + ...defaultExcludes, + ]), + ), } : {}), ...(optionsCoverage.reporters diff --git a/packages/angular/build/src/builders/unit-test/schema.json b/packages/angular/build/src/builders/unit-test/schema.json index 951fd5a29e73..46b9b5fb6276 100644 --- a/packages/angular/build/src/builders/unit-test/schema.json +++ b/packages/angular/build/src/builders/unit-test/schema.json @@ -75,8 +75,7 @@ }, "coverage": { "type": "boolean", - "description": "Enables coverage reporting for tests.", - "default": false + "description": "Enables coverage reporting for tests. If not specified, the coverage configuration from a runner configuration file will be used if present. Otherwise, coverage is disabled by default." }, "coverageInclude": { "type": "array", diff --git a/packages/angular/build/src/builders/unit-test/tests/behavior/runner-config-vitest_spec.ts b/packages/angular/build/src/builders/unit-test/tests/behavior/runner-config-vitest_spec.ts index 603c69f533ea..609d736e00f7 100644 --- a/packages/angular/build/src/builders/unit-test/tests/behavior/runner-config-vitest_spec.ts +++ b/packages/angular/build/src/builders/unit-test/tests/behavior/runner-config-vitest_spec.ts @@ -42,6 +42,21 @@ describeBuilder(execute, UNIT_TEST_BUILDER_INFO, (harness) => { harness.expectFile('vitest-results.xml').toExist(); }); + it('should override reporters defined in runnerConfig file when CLI option is present', async () => { + harness.useTarget('test', { + ...BASE_OPTIONS, + runnerConfig: 'vitest.config.ts', + reporters: ['default'], + }); + + harness.writeFile('vitest.config.ts', VITEST_CONFIG_CONTENT); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + // The CLI option 'default' should override the 'junit' reporter in VITEST_CONFIG_CONTENT + harness.expectFile('vitest-results.xml').toNotExist(); + }); + it('should use custom reportsDirectory defined in runnerConfig file', async () => { harness.useTarget('test', { ...BASE_OPTIONS, @@ -92,6 +107,31 @@ describeBuilder(execute, UNIT_TEST_BUILDER_INFO, (harness) => { harness.expectFile('coverage/test/coverage-final.json').toExist(); }); + it('should enable coverage when set in runnerConfig file without builder option', async () => { + harness.useTarget('test', { + ...BASE_OPTIONS, + runnerConfig: 'vitest.config.ts', + }); + + harness.writeFile( + 'vitest.config.ts', + ` + import { defineConfig } from 'vitest/config'; + export default defineConfig({ + test: { + coverage: { + enabled: true, + }, + }, + }); + `, + ); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + harness.expectFile('coverage/test/coverage-final.json').toExist(); + }); + it('should exclude test files based on runnerConfig file', async () => { harness.useTarget('test', { ...BASE_OPTIONS, @@ -139,6 +179,59 @@ describeBuilder(execute, UNIT_TEST_BUILDER_INFO, (harness) => { expect(results.numPassedTests).toBe(1); }); + it('should correctly merge coverage.exclude arrays from builder and runner options', async () => { + harness.useTarget('test', { + ...BASE_OPTIONS, + coverage: true, + runnerConfig: 'vitest.config.ts', + coverageExclude: ['src/app/cli-excluded.ts'], + }); + + harness.writeFile( + 'vitest.config.ts', + ` + import { defineConfig } from 'vitest/config'; + export default defineConfig({ + test: { + coverage: { + exclude: ['src/app/config-excluded.ts'], + }, + }, + }); + `, + ); + + // Create two files that would normally be covered + harness.writeFile('src/app/cli-excluded.ts', 'export const cliExcluded = true;'); + harness.writeFile('src/app/config-excluded.ts', 'export const configExcluded = true;'); + + // Update the test file to import them so they're picked up by coverage + harness.writeFile( + 'src/app/app.component.spec.ts', + ` + import { test, expect } from 'vitest'; + import './cli-excluded'; + import './config-excluded'; + test('should pass', () => { + expect(true).toBe(true); + }); + `, + ); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + harness.expectFile('coverage/test/coverage-final.json').toExist(); + + const coverageMap = JSON.parse(harness.readFile('coverage/test/coverage-final.json')); + const coveredFiles = Object.keys(coverageMap); + + const hasCliExcluded = coveredFiles.some((f) => f.includes('cli-excluded.ts')); + const hasConfigExcluded = coveredFiles.some((f) => f.includes('config-excluded.ts')); + + expect(hasCliExcluded).withContext('CLI target should be excluded').toBeFalse(); + expect(hasConfigExcluded).withContext('Config file target should be excluded').toBeFalse(); + }); + it('should allow overriding globals to false via runnerConfig file', async () => { harness.useTarget('test', { ...BASE_OPTIONS, @@ -290,6 +383,71 @@ describeBuilder(execute, UNIT_TEST_BUILDER_INFO, (harness) => { // ); }); + it('should warn and ignore "test.watch" option from runnerConfig file', async () => { + harness.useTarget('test', { + ...BASE_OPTIONS, + watch: false, + runnerConfig: 'vitest.config.ts', + }); + + harness.writeFile( + 'vitest.config.ts', + ` + import { defineConfig } from 'vitest/config'; + export default defineConfig({ + test: { + watch: true, + }, + }); + `, + ); + + const { result, logs } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + + // TODO: Re-enable once Vite logs are remapped through build system + // expect(logs).toContain( + // jasmine.objectContaining({ + // level: 'warn', + // message: jasmine.stringMatching( + // 'The "test.watch" option in the Vitest configuration file is overridden by the builder\\'s watch option.', + // ), + // }), + // ); + }); + + it('should warn about performance when "test.exclude" option is in runnerConfig file', async () => { + harness.useTarget('test', { + ...BASE_OPTIONS, + runnerConfig: 'vitest.config.ts', + }); + + harness.writeFile( + 'vitest.config.ts', + ` + import { defineConfig } from 'vitest/config'; + export default defineConfig({ + test: { + exclude: ['src/app/non-existent.spec.ts'], + }, + }); + `, + ); + + const { result, logs } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + + // TODO: Re-enable once Vite logs are remapped through build system + // expect(logs).toContain( + // jasmine.objectContaining({ + // level: 'warn', + // message: jasmine.stringMatching( + // 'The "test.exclude" option in the Vitest configuration file is evaluated after', + // ), + // }), + // ); + }); + it(`should append "test.setupFiles" (string) from runnerConfig to the CLI's setup`, async () => { harness.useTarget('test', { ...BASE_OPTIONS, diff --git a/packages/angular/build/src/builders/unit-test/tests/behavior/vitest-mock-unsupported_spec.ts b/packages/angular/build/src/builders/unit-test/tests/behavior/vitest-mock-unsupported_spec.ts index 30565429f2ca..547d6528d86d 100644 --- a/packages/angular/build/src/builders/unit-test/tests/behavior/vitest-mock-unsupported_spec.ts +++ b/packages/angular/build/src/builders/unit-test/tests/behavior/vitest-mock-unsupported_spec.ts @@ -34,8 +34,35 @@ describeBuilder(execute, UNIT_TEST_BUILDER_INFO, (harness) => { `, ); - const { result, logs } = await harness.executeOnce(); + const { result } = await harness.executeOnce(); expect(result?.success).toBeFalse(); }); + + it('should not fail when vi.mock is used with a non-relative path', async () => { + harness.useTarget('test', { + ...BASE_OPTIONS, + }); + + harness.writeFile( + 'src/app/mock-non-relative.spec.ts', + ` + import { vi } from 'vitest'; + vi.mock('@angular/cdk', () => ({})); + describe('Ignored', () => { it('pass', () => expect(true).toBe(true)); }); + `, + ); + + // Overwrite default to avoid noise + harness.writeFile( + 'src/app/app.component.spec.ts', + ` + import { describe, it, expect } from 'vitest'; + describe('Ignored', () => { it('pass', () => expect(true).toBe(true)); }); + `, + ); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + }); }); }); diff --git a/packages/angular/build/src/private.ts b/packages/angular/build/src/private.ts index 4791a94a42d3..50d57d0e5a01 100644 --- a/packages/angular/build/src/private.ts +++ b/packages/angular/build/src/private.ts @@ -26,6 +26,10 @@ export { buildApplicationInternal } from './builders/application'; export type { ApplicationBuilderInternalOptions } from './builders/application/options'; export { type Result, type ResultFile, ResultKind } from './builders/application/results'; export { serveWithVite } from './builders/dev-server/vite'; +export { + normalizeOptions as normalizeDevServerOptions, + type NormalizedDevServerOptions, +} from './builders/dev-server/options'; // Tools export * from './tools/babel/plugins'; diff --git a/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts b/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts index af4dcaea01fb..1bcb8c40500a 100644 --- a/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts +++ b/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts @@ -220,10 +220,19 @@ export function createCompilerPlugin( if (stylesheetResult.errors) { (result.errors ??= []).push(...stylesheetResult.errors); + const { referencedFiles } = stylesheetResult; + if (referencedFiles) { + referencedFileTracker.add(containingFile, referencedFiles); + if (stylesheetFile) { + referencedFileTracker.add(stylesheetFile, referencedFiles); + } + } + return ''; } const { contents, outputFiles, metafile, referencedFiles } = stylesheetResult; + additionalResults.set(resultSource, { outputFiles, metafile, diff --git a/packages/angular/build/src/tools/esbuild/application-code-bundle.ts b/packages/angular/build/src/tools/esbuild/application-code-bundle.ts index 635faca8c82e..815afa1a1ba8 100644 --- a/packages/angular/build/src/tools/esbuild/application-code-bundle.ts +++ b/packages/angular/build/src/tools/esbuild/application-code-bundle.ts @@ -196,9 +196,14 @@ export function createServerPolyfillBundleOptions( if (isNodePlatform) { // Note: Needed as esbuild does not provide require shims / proxy from ESModules. // See: https://github.com/evanw/esbuild/issues/1921. + // Use an alias to avoid colliding with any `createRequire` import that may + // already exist in the bundled user code. ESBuild processes banner content + // as raw text outside of its module graph, so it cannot deduplicate or + // rename banner imports the way it does for user imports. Without the alias, + // a duplicate `import { createRequire }` binding would cause a runtime error. jsBanner.push( - `import { createRequire } from 'node:module';`, - `globalThis['require'] ??= createRequire(import.meta.url);`, + `import { createRequire as __ngCreateRequire } from 'node:module';`, + `globalThis['require'] ??= __ngCreateRequire(import.meta.url);`, ); } @@ -397,9 +402,14 @@ export function createSsrEntryCodeBundleOptions( if (isNodePlatform) { // Note: Needed as esbuild does not provide require shims / proxy from ESModules. // See: https://github.com/evanw/esbuild/issues/1921. + // Use an alias to avoid colliding with any `createRequire` import that may + // already exist in the bundled user code. ESBuild processes banner content + // as raw text outside of its module graph, so it cannot deduplicate or + // rename banner imports the way it does for user imports. Without the alias, + // a duplicate `import { createRequire }` binding would cause a runtime error. jsBanner.push( - `import { createRequire } from 'node:module';`, - `globalThis['require'] ??= createRequire(import.meta.url);`, + `import { createRequire as __ngCreateRequire } from 'node:module';`, + `globalThis['require'] ??= __ngCreateRequire(import.meta.url);`, ); } @@ -656,12 +666,17 @@ function getEsBuildCommonPolyfillsOptions( ): BuildOptions | undefined { const { jit, workspaceRoot, i18nOptions, externalPackages } = options; - const buildOptions = getEsBuildCommonOptions(options); + let polyfills = options.polyfills ? [...options.polyfills] : []; + + const buildOptions = getEsBuildCommonOptions({ + ...options, + // If any polyfills are local files, disable external packages for the polyfills build. + // This ensures that local files are properly bundled. + externalPackages: polyfills.some(isLocalFile) ? false : externalPackages, + }); buildOptions.splitting = false; buildOptions.plugins ??= []; - let polyfills = options.polyfills ? [...options.polyfills] : []; - // Angular JIT mode requires the runtime compiler if (jit) { polyfills.unshift('@angular/compiler'); @@ -671,10 +686,8 @@ function getEsBuildCommonPolyfillsOptions( // Locale data should go first so that project provided polyfill code can augment if needed. let needLocaleDataPlugin = false; if (i18nOptions.shouldInline) { - if (!externalPackages) { - // Remove localize polyfill when i18n inline transformation have been applied to all the packages. - polyfills = polyfills.filter((path) => !path.startsWith('@angular/localize')); - } + // Remove localize polyfill when i18n inline transformation have been applied to all the packages. + polyfills = polyfills.filter((path) => !path.startsWith('@angular/localize')); // Add locale data for all active locales // TODO: Inject each individually within the inlining process itself @@ -749,3 +762,18 @@ function getEsBuildCommonPolyfillsOptions( function entryFileToWorkspaceRelative(workspaceRoot: string, entryFile: string): string { return './' + toPosixPath(relative(workspaceRoot, entryFile).replace(/.[mc]?ts$/, '')); } + +/** + * Determines if a polyfill path is a local file. + * A local file is defined as a path starting with a `.` or having a TypeScript/JavaScript extension. + * `zone.js` and its subpaths are specifically excluded and treated as packages. + * @param path The polyfill path to check. + * @returns true if the path is a local file; false otherwise. + */ +function isLocalFile(path: string): boolean { + if (path.startsWith('zone.js')) { + return false; + } + + return path[0] === '.' || /\.[mc]?[jt]sx?$/.test(path); +} diff --git a/packages/angular/build/src/tools/vite/middlewares/assets-middleware.ts b/packages/angular/build/src/tools/vite/middlewares/assets-middleware.ts index f0a137f578f8..e0074625afe0 100644 --- a/packages/angular/build/src/tools/vite/middlewares/assets-middleware.ts +++ b/packages/angular/build/src/tools/vite/middlewares/assets-middleware.ts @@ -45,8 +45,8 @@ export function createAngularAssetsMiddleware( // Rewrite all build assets to a vite raw fs URL const asset = assets.get(pathname); if (asset) { - // This is a workaround to serve CSS, JS and TS files without Vite transformations. - if (JS_TS_REGEXP.test(extension) || CSS_PREPROCESSOR_REGEXP.test(extension)) { + // This is a workaround to serve extensionless, CSS, JS and TS files without Vite transformations. + if (!extension || JS_TS_REGEXP.test(extension) || CSS_PREPROCESSOR_REGEXP.test(extension)) { const contents = readFileSync(asset.source); const etag = `W/${createHash('sha256').update(contents).digest('hex')}`; if (checkAndHandleEtag(req, res, etag)) { diff --git a/packages/angular/build/src/tools/vite/middlewares/ssr-middleware.ts b/packages/angular/build/src/tools/vite/middlewares/ssr-middleware.ts index 4b0a8d8390f1..a26fa8e5e257 100644 --- a/packages/angular/build/src/tools/vite/middlewares/ssr-middleware.ts +++ b/packages/angular/build/src/tools/vite/middlewares/ssr-middleware.ts @@ -90,6 +90,10 @@ export async function createAngularSsrExternalMiddleware( '@angular/ssr/node' as string )) as typeof import('@angular/ssr/node', { with: { 'resolution-mode': 'import' } }); + // Disable host check if allowed hosts is true meaning allow all hosts. + const { allowedHosts } = server.config.server; + const disableAllowedHostsCheck = allowedHosts === true; + return function angularSsrExternalMiddleware( req: Connect.IncomingMessage, res: ServerResponse, @@ -123,6 +127,7 @@ export async function createAngularSsrExternalMiddleware( } if (cachedAngularAppEngine !== AngularAppEngine) { + AngularAppEngine.ɵdisableAllowedHostsCheck = disableAllowedHostsCheck; AngularAppEngine.ɵallowStaticRouteRender = true; AngularAppEngine.ɵhooks.on('html:transform:pre', async ({ html, url }) => { const processedHtml = await server.transformIndexHtml(url.pathname, html); diff --git a/packages/angular/build/src/utils/index-file/auto-csp.ts b/packages/angular/build/src/utils/index-file/auto-csp.ts index c50e0bfce3f2..0e1dfe3ed916 100644 --- a/packages/angular/build/src/utils/index-file/auto-csp.ts +++ b/packages/angular/build/src/utils/index-file/auto-csp.ts @@ -52,12 +52,7 @@ function isJavascriptMimeType(mimeType: string): boolean { * @returns whether to add the script tag to the dynamically loaded script tag */ function shouldDynamicallyLoadScriptTagBasedOnType(scriptType: string | undefined): boolean { - return ( - scriptType === undefined || - scriptType === '' || - scriptType === 'module' || - isJavascriptMimeType(scriptType) - ); + return !scriptType || scriptType === 'module' || isJavascriptMimeType(scriptType); } /** @@ -67,7 +62,11 @@ function shouldDynamicallyLoadScriptTagBasedOnType(scriptType: string | undefine * @returns The hash of the text formatted appropriately for CSP. */ export function hashTextContent(scriptText: string): string { - const hash = crypto.createHash(HASH_FUNCTION).update(scriptText, 'utf-8').digest('base64'); + // Normalize CRLF to LF to ensure consistent since the rewriter might normalize the line endings. + const hash = crypto + .createHash(HASH_FUNCTION) + .update(scriptText.replace(/\r\n?/g, '\n'), 'utf-8') + .digest('base64'); return `'${HASH_FUNCTION}-${hash}'`; } diff --git a/packages/angular/build/src/utils/index-file/auto-csp_spec.ts b/packages/angular/build/src/utils/index-file/auto-csp_spec.ts index 1ec5f2ab06aa..efbd338233ad 100644 --- a/packages/angular/build/src/utils/index-file/auto-csp_spec.ts +++ b/packages/angular/build/src/utils/index-file/auto-csp_spec.ts @@ -15,13 +15,13 @@ const getCsps = (html: string) => { ).map((m) => m[1]); // Only capture group. }; -const ONE_HASH_CSP = +const CSP_SINGLE_HASH_REGEX = /script-src 'strict-dynamic' 'sha256-[^']+' https: 'unsafe-inline';object-src 'none';base-uri 'self';/; -const TWO_HASH_CSP = +const CSP_TWO_HASHES_REGEX = /script-src 'strict-dynamic' (?:'sha256-[^']+' ){2}https: 'unsafe-inline';object-src 'none';base-uri 'self';/; -const FOUR_HASH_CSP = +const CSP_FOUR_HASHES_REGEX = /script-src 'strict-dynamic' (?:'sha256-[^']+' ){4}https: 'unsafe-inline';object-src 'none';base-uri 'self';/; describe('auto-csp', () => { @@ -38,8 +38,8 @@ describe('auto-csp', () => { `); const csps = getCsps(result); - expect(csps.length).toBe(1); - expect(csps[0]).toMatch(ONE_HASH_CSP); + expect(csps).toHaveSize(1); + expect(csps[0]).toMatch(CSP_SINGLE_HASH_REGEX); expect(csps[0]).toContain(hashTextContent("console.log('foo');")); }); @@ -56,8 +56,8 @@ describe('auto-csp', () => { `); const csps = getCsps(result); - expect(csps.length).toBe(1); - expect(csps[0]).toMatch(ONE_HASH_CSP); + expect(csps).toHaveSize(1); + expect(csps[0]).toMatch(CSP_SINGLE_HASH_REGEX); expect(result).toContain(`var scripts = [['./main.js', '', false, false]];`); }); @@ -74,8 +74,8 @@ describe('auto-csp', () => { `); const csps = getCsps(result); - expect(csps.length).toBe(1); - expect(csps[0]).toMatch(ONE_HASH_CSP); + expect(csps).toHaveSize(1); + expect(csps[0]).toMatch(CSP_SINGLE_HASH_REGEX); // Our loader script appears after the HTML text content. expect(result).toMatch( /Some text<\/div>\s*<script>\s*var scripts = \[\['.\/main.js', '', false, false\]\];/, @@ -99,8 +99,8 @@ describe('auto-csp', () => { `); const csps = getCsps(result); - expect(csps.length).toBe(1); - expect(csps[0]).toMatch(TWO_HASH_CSP); + expect(csps).toHaveSize(1); + expect(csps[0]).toMatch(CSP_TWO_HASHES_REGEX); expect(result).toContain( // eslint-disable-next-line max-len `var scripts = [['./main1.js', '', false, false],['./main2.js', '', true, false],['./main3.js', 'module', true, true]];`, @@ -108,7 +108,7 @@ describe('auto-csp', () => { // Head loader script is in the head. expect(result).toContain(`</script></head>`); // Only two loader scripts are created. - expect(Array.from(result.matchAll(/<script>/g)).length).toEqual(2); + expect(Array.from(result.matchAll(/<script>/gi)).length).toEqual(2); }); it('should rewrite source scripts with weird URLs', async () => { @@ -127,8 +127,8 @@ describe('auto-csp', () => { `); const csps = getCsps(result); - expect(csps.length).toBe(1); - expect(csps[0]).toMatch(ONE_HASH_CSP); + expect(csps).toHaveSize(1); + expect(csps[0]).toMatch(CSP_SINGLE_HASH_REGEX); // & encodes correctly expect(result).toContain(`'/foo&bar'`); // Impossible to escape a string and create invalid loader JS with a ' @@ -158,9 +158,9 @@ describe('auto-csp', () => { `); const csps = getCsps(result); - expect(csps.length).toBe(1); + expect(csps).toHaveSize(1); // Exactly four hashes for the four scripts that remain (inline, loader, inline, loader). - expect(csps[0]).toMatch(FOUR_HASH_CSP); + expect(csps[0]).toMatch(CSP_FOUR_HASHES_REGEX); expect(csps[0]).toContain(hashTextContent("console.log('foo');")); expect(csps[0]).toContain(hashTextContent("console.log('bar');")); // Loader script for main.js and main2.js appear after 'foo' and before 'bar'. @@ -174,7 +174,7 @@ describe('auto-csp', () => { /console.log\('bar'\);<\/script>\s*<script>\s*var scripts = \[\['.\/main3.js', '', false, false\],\['.\/main4.js', '', false, false\]\];/, ); // Exactly 4 scripts should be left. - expect(Array.from(result.matchAll(/<script>/g)).length).toEqual(4); + expect(Array.from(result.matchAll(/<script>/gi)).length).toEqual(4); }); it('should write a loader script that appends to head', async () => { @@ -190,8 +190,8 @@ describe('auto-csp', () => { `); const csps = getCsps(result); - expect(csps.length).toBe(1); - expect(csps[0]).toMatch(ONE_HASH_CSP); + expect(csps).toHaveSize(1); + expect(csps[0]).toMatch(CSP_SINGLE_HASH_REGEX); expect(result).toContain( // eslint-disable-next-line max-len @@ -200,6 +200,25 @@ describe('auto-csp', () => { // Head loader script is in the head. expect(result).toContain(`</script></head>`); // Only one loader script is created. - expect(Array.from(result.matchAll(/<script>/g)).length).toEqual(1); + expect(Array.from(result.matchAll(/<script>/gi)).length).toEqual(1); + }); + + it('should rewrite a single inline script with CRLF', async () => { + const result = await autoCsp(` + <html> + <head> + </head> + <body> + <script>\r\nconsole.log('foo');\r\n</script> + <div>Some text </div> + </body> + </html>\r\n + `); + + const csps = getCsps(result); + expect(result).not.toContain(`\r\n`); + expect(csps).toHaveSize(1); + expect(csps[0]).toMatch(CSP_SINGLE_HASH_REGEX); + expect(csps[0]).toContain(hashTextContent(`\r\nconsole.log('foo');\r\n`)); }); }); diff --git a/packages/angular/build/src/utils/server-rendering/manifest.ts b/packages/angular/build/src/utils/server-rendering/manifest.ts index b01bff38b58f..34c2e334b52c 100644 --- a/packages/angular/build/src/utils/server-rendering/manifest.ts +++ b/packages/angular/build/src/utils/server-rendering/manifest.ts @@ -53,11 +53,13 @@ function escapeUnsafeChars(str: string): string { * * @param i18nOptions - The internationalization options for the application build. This * includes settings for inlining locales and determining the output structure. + * @param allowedHosts - A list of hosts that are allowed to access the server-side application. * @param baseHref - The base HREF for the application. This is used to set the base URL * for all relative URLs in the application. */ export function generateAngularServerAppEngineManifest( i18nOptions: NormalizedApplicationBuildOptions['i18nOptions'], + allowedHosts: string[], baseHref: string | undefined, ): string { const entryPoints: Record<string, string> = {}; @@ -84,6 +86,7 @@ export function generateAngularServerAppEngineManifest( const manifestContent = ` export default { basePath: '${basePath}', + allowedHosts: ${JSON.stringify(allowedHosts, undefined, 2)}, supportedLocales: ${JSON.stringify(supportedLocales, undefined, 2)}, entryPoints: { ${Object.entries(entryPoints) diff --git a/packages/angular/build/src/utils/server-rendering/prerender.ts b/packages/angular/build/src/utils/server-rendering/prerender.ts index f33f851f10c4..1033a7575f88 100644 --- a/packages/angular/build/src/utils/server-rendering/prerender.ts +++ b/packages/angular/build/src/utils/server-rendering/prerender.ts @@ -96,7 +96,9 @@ export async function prerenderPages( const assetsReversed: Record</** Destination */ string, /** Source */ string> = {}; for (const { source, destination } of assets) { - assetsReversed[addLeadingSlash(toPosixPath(destination))] = source; + // Assets are not stored with baseHref when using i18n, + // we append the base href so that requests are resolved correctly. + assetsReversed[joinUrlParts(baseHref, toPosixPath(destination))] = source; } // Get routes to prerender @@ -114,8 +116,12 @@ export async function prerenderPages( sourcemap, outputMode, ).catch((err) => { + assertIsError(err); + return { - errors: [`An error occurred while extracting routes.\n\n${err.message ?? err.stack ?? err}`], + errors: [ + `An error occurred while extracting routes.\n\n${err.stack ?? err.message ?? err.code ?? err}`, + ], serializedRouteTree: [], appShellRoute: undefined, }; @@ -225,6 +231,10 @@ async function renderPages( hasSsrEntry: !!outputFilesForWorker['server.mjs'], } as RenderWorkerData, execArgv: workerExecArgv, + env: { + ...process.env, + 'NG_ALLOWED_HOSTS': 'localhost', + }, }); try { @@ -259,8 +269,9 @@ async function renderPages( } }) .catch((err) => { + assertIsError(err); errors.push( - `An error occurred while prerendering route '${route}'.\n\n${err.message ?? err.stack ?? err.code ?? err}`, + `An error occurred while prerendering route '${route}'.\n\n${err.stack ?? err.message ?? err.code ?? err}`, ); void renderWorker.destroy(); }); @@ -337,6 +348,10 @@ async function getAllRoutes( hasSsrEntry: !!outputFilesForWorker['server.mjs'], } as RoutesExtractorWorkerData, execArgv: workerExecArgv, + env: { + ...process.env, + 'NG_ALLOWED_HOSTS': 'localhost', + }, }); try { @@ -361,7 +376,7 @@ async function getAllRoutes( return { errors: [ - `An error occurred while extracting routes.\n\n${err.message ?? err.stack ?? err.code ?? err}`, + `An error occurred while extracting routes.\n\n${err.stack ?? err.message ?? err.code ?? err}`, ], serializedRouteTree: [], }; diff --git a/packages/angular/build/src/utils/version.ts b/packages/angular/build/src/utils/version.ts index 51f493bfe993..b9bbf5cd03b8 100644 --- a/packages/angular/build/src/utils/version.ts +++ b/packages/angular/build/src/utils/version.ts @@ -37,18 +37,35 @@ export function assertCompatibleAngularVersion(projectRoot: string): void | neve process.exit(2); } + const angularCoreSemVer = new SemVer(angularPkgJson['version']); + const { version, build, raw } = angularCoreSemVer; const supportedAngularSemver = '0.0.0-ANGULAR-FW-PEER-DEP'; - if (angularPkgJson['version'] === '0.0.0' || supportedAngularSemver.startsWith('0.0.0')) { + + if (version.startsWith('0.0.0') || supportedAngularSemver.startsWith('0.0.0')) { // Internal CLI and FW testing version. return; } - const angularVersion = new SemVer(angularPkgJson['version']); + if (build.length && version.endsWith('.0.0-next.0')) { + // Special handle for local builds only when it's prerelease of major version and it's the 0th version. + // This happends when we are bumping to a new major version. and the cli has not releated a verion. + + // Example: + // raw: '22.0.0-next.0+sha-c7dc705-with-local-changes', + // major: 22, + // minor: 0, + // patch: 0, + // prerelease: [ 'next', 0 ], + // build: [ 'sha-c7dc705-with-local-changes' ], + // version: '22.0.0-next.0' + + return; + } - if (!satisfies(angularVersion, supportedAngularSemver, { includePrerelease: true })) { + if (!satisfies(angularCoreSemVer, supportedAngularSemver, { includePrerelease: true })) { console.error( `Error: The current version of "@angular/build" supports Angular versions ${supportedAngularSemver},\n` + - `but detected Angular version ${angularVersion} instead.\n` + + `but detected Angular version ${raw} instead.\n` + 'Please visit the link below to find instructions on how to update Angular.\nhttps://update.angular.dev/', ); diff --git a/packages/angular/build/src/utils/worker-pool.ts b/packages/angular/build/src/utils/worker-pool.ts index 78db4302ef1a..907de66ba02f 100644 --- a/packages/angular/build/src/utils/worker-pool.ts +++ b/packages/angular/build/src/utils/worker-pool.ts @@ -26,7 +26,9 @@ export class WorkerPool extends Piscina { // Enable compile code caching if enabled for the main process (only exists on Node.js v22.8+). // Skip if running inside Bazel via a RUNFILES environment variable check. The cache does not work // well with Bazel's hermeticity requirements. - const compileCacheDirectory = process.env['RUNFILES'] ? undefined : getCompileCacheDir?.(); + const compileCacheDirectory = process.env['JS_BINARY__RUNFILES'] + ? undefined + : getCompileCacheDir?.(); if (compileCacheDirectory) { if (typeof piscinaOptions.env === 'object') { piscinaOptions.env['NODE_COMPILE_CACHE'] = compileCacheDirectory; diff --git a/packages/angular/cli/bin/bootstrap.js b/packages/angular/cli/bin/bootstrap.js index 18d1ed73160c..6b1a18db4d42 100644 --- a/packages/angular/cli/bin/bootstrap.js +++ b/packages/angular/cli/bin/bootstrap.js @@ -19,9 +19,9 @@ */ // Enable on-disk code caching if available (Node.js 22.8+) -// Skip if running inside Bazel via a RUNFILES environment variable check and no explicit cache +// Skip if running inside Bazel via a JS_BINARY__RUNFILES environment variable check and no explicit cache // location defined. The default cache location does not work well with Bazel's hermeticity requirements. -if (!process.env['RUNFILES'] || process.env['NODE_COMPILE_CACHE']) { +if (!process.env['JS_BINARY__RUNFILES'] || process.env['NODE_COMPILE_CACHE']) { try { const { enableCompileCache } = require('node:module'); diff --git a/packages/angular/cli/lib/cli/index.ts b/packages/angular/cli/lib/cli/index.ts index ac7591e43630..13d43df34b17 100644 --- a/packages/angular/cli/lib/cli/index.ts +++ b/packages/angular/cli/lib/cli/index.ts @@ -44,6 +44,7 @@ export default async function (options: { cliArgs: string[] }) { }; const logger = new logging.IndentLogger('cli-main-logger'); const logInfo = console.log; + const logWarn = console.warn; const logError = console.error; const useColor = supportColor(); @@ -113,5 +114,11 @@ export default async function (options: { cliArgs: string[] }) { } finally { logger.complete(); await loggerFinished; + + // Restore original console methods so that late consumers + // (e.g. process.on('exit') handlers) still produce output. + console.log = console.info = logInfo; + console.warn = logWarn; + console.error = logError; } } diff --git a/packages/angular/cli/package.json b/packages/angular/cli/package.json index 2dc97162e59f..03b9d7e0a175 100644 --- a/packages/angular/cli/package.json +++ b/packages/angular/cli/package.json @@ -4,7 +4,7 @@ "description": "CLI tool for Angular", "main": "lib/cli/index.js", "bin": { - "ng": "./bin/ng.js" + "ng": "bin/ng.js" }, "keywords": [ "angular", @@ -13,7 +13,7 @@ ], "repository": { "type": "git", - "url": "https://github.com/angular/angular-cli.git" + "url": "git+https://github.com/angular/angular-cli.git" }, "author": "Angular Authors", "license": "MIT", diff --git a/packages/angular/cli/src/command-builder/utilities/json-schema_spec.ts b/packages/angular/cli/src/command-builder/utilities/json-schema_spec.ts index d311373d69f0..11228e4adca0 100644 --- a/packages/angular/cli/src/command-builder/utilities/json-schema_spec.ts +++ b/packages/angular/cli/src/command-builder/utilities/json-schema_spec.ts @@ -9,7 +9,7 @@ import { JsonObject, schema } from '@angular-devkit/core'; import yargs from 'yargs'; -import { addSchemaOptionsToCommand, parseJsonSchemaToOptions } from './json-schema'; +import { Option, addSchemaOptionsToCommand, parseJsonSchemaToOptions } from './json-schema'; describe('parseJsonSchemaToOptions', () => { describe('without required fields in schema', () => { @@ -21,10 +21,9 @@ describe('parseJsonSchemaToOptions', () => { }; let localYargs: yargs.Argv<unknown>; - beforeEach(async () => { - // Create a fresh yargs for each call. The yargs object is stateful and - // calling .parse multiple times on the same instance isn't safe. - localYargs = yargs().exitProcess(false).strict().fail(false).wrap(1_000); + let options: Option[]; + + beforeAll(async () => { const jsonSchema = { 'type': 'object', 'properties': { @@ -118,12 +117,20 @@ describe('parseJsonSchemaToOptions', () => { }, }, }; + const registry = new schema.CoreSchemaRegistry(); - const options = await parseJsonSchemaToOptions( + options = await parseJsonSchemaToOptions( registry, jsonSchema as unknown as JsonObject, false, ); + }); + + beforeEach(async () => { + // Create a fresh yargs for each call. The yargs object is stateful and + // calling .parse multiple times on the same instance isn't safe. + localYargs = yargs().exitProcess(false).strict().fail(false).wrap(1_000); + addSchemaOptionsToCommand(localYargs, options, true); }); @@ -138,7 +145,15 @@ describe('parseJsonSchemaToOptions', () => { }); describe('type=array, enum', () => { - it('parses valid option value', async () => { + it('parses valid option value when specified once', async () => { + expect(await parse(['--arrayWithChoices', 'always', 'never'])).toEqual( + jasmine.objectContaining({ + 'arrayWithChoices': ['always', 'never'], + }), + ); + }); + + it('parses valid option value when specified multiple times', async () => { expect( await parse(['--arrayWithChoices', 'always', '--arrayWithChoices', 'never']), ).toEqual( @@ -160,7 +175,15 @@ describe('parseJsonSchemaToOptions', () => { }); describe('type=array, enum in oneOf', () => { - it('parses valid option value', async () => { + it('parses valid option value when specified once', async () => { + expect(await parse(['--arrayWithChoicesInOneOf', 'default', 'verbose'])).toEqual( + jasmine.objectContaining({ + 'arrayWithChoicesInOneOf': ['default', 'verbose'], + }), + ); + }); + + it('parses valid option value when specified multiple times', async () => { expect( await parse([ '--arrayWithChoicesInOneOf', @@ -183,7 +206,15 @@ describe('parseJsonSchemaToOptions', () => { }); describe('type=array, anyOf', () => { - it('parses valid option value', async () => { + it('parses valid option value when specified once', async () => { + expect(await parse(['--arrayWithComplexAnyOf', 'default', 'something-else'])).toEqual( + jasmine.objectContaining({ + 'arrayWithComplexAnyOf': ['default', 'something-else'], + }), + ); + }); + + it('parses valid option value when specified multiple times', async () => { expect( await parse([ '--arrayWithComplexAnyOf', diff --git a/packages/angular/cli/src/commands/add/cli.ts b/packages/angular/cli/src/commands/add/cli.ts index a27c6405f18f..c022c35bd1b2 100644 --- a/packages/angular/cli/src/commands/add/cli.ts +++ b/packages/angular/cli/src/commands/add/cli.ts @@ -44,6 +44,7 @@ interface AddCommandArgs extends SchematicsCommandArgs { interface AddCommandTaskContext { packageIdentifier: npa.Result; + isExactVersion: boolean; savePackage?: NgAddSaveDependency; collectionName?: string; executeSchematic: AddCommandModule['executeSchematic']; @@ -185,6 +186,7 @@ export default class AddCommandModule const taskContext = { packageIdentifier, + isExactVersion: packageIdentifier.type === 'version', executeSchematic: this.executeSchematic.bind(this), getPeerDependencyConflicts: this.getPeerDependencyConflicts.bind(this), dryRun: options.dryRun, @@ -489,12 +491,9 @@ export default class AddCommandModule let manifest; try { - manifest = await this.context.packageManager.getManifest( - context.packageIdentifier.toString(), - { - registry, - }, - ); + manifest = await this.context.packageManager.getManifest(context.packageIdentifier, { + registry, + }); } catch (e) { assertIsError(e); throw new CommandError( @@ -508,6 +507,17 @@ export default class AddCommandModule ); } + // Avoid fully resolving the package version from the registry again in later steps + if (context.packageIdentifier.registry) { + assert(context.packageIdentifier.name, 'Registry package identifier must have a name'); + context.packageIdentifier = npa.resolve( + context.packageIdentifier.name, + // `save-prefix` option is ignored by some package managers so the caret is needed to ensure + // that the value in the project package.json is correct. + (context.isExactVersion ? '' : '^') + manifest.version, + ); + } + context.hasSchematics = !!manifest.schematics; context.savePackage = manifest['ng-add']?.save; context.collectionName = manifest.name; @@ -583,7 +593,7 @@ export default class AddCommandModule await packageManager.add( packageIdentifier.toString(), 'none', - savePackage !== 'dependencies', + savePackage === 'devDependencies', false, true, { diff --git a/packages/angular/cli/src/commands/mcp/host.ts b/packages/angular/cli/src/commands/mcp/host.ts index 1ff0bb9724b3..94ac449fe356 100644 --- a/packages/angular/cli/src/commands/mcp/host.ts +++ b/packages/angular/cli/src/commands/mcp/host.ts @@ -118,6 +118,11 @@ export interface Host { * Finds an available TCP port on the system. */ getAvailablePort(): Promise<number>; + + /** + * Checks whether a TCP port is available on the system. + */ + isPortAvailable(port: number): Promise<boolean>; } /** @@ -236,4 +241,16 @@ export const LocalWorkspaceHost: Host = { }); }); }, + + isPortAvailable(port: number): Promise<boolean> { + return new Promise((resolve) => { + const server = createServer(); + server.once('error', () => resolve(false)); + server.listen(port, () => { + server.close(() => { + resolve(true); + }); + }); + }); + }, }; diff --git a/packages/angular/cli/src/commands/mcp/testing/mock-host.ts b/packages/angular/cli/src/commands/mcp/testing/mock-host.ts index 29f41c24e101..ce2e5177ffab 100644 --- a/packages/angular/cli/src/commands/mcp/testing/mock-host.ts +++ b/packages/angular/cli/src/commands/mcp/testing/mock-host.ts @@ -21,4 +21,5 @@ export class MockHost implements Host { resolveModule = jasmine.createSpy('resolveRequest').and.returnValue('/dev/null'); spawn = jasmine.createSpy('spawn'); getAvailablePort = jasmine.createSpy('getAvailablePort'); + isPortAvailable = jasmine.createSpy('isPortAvailable').and.resolveTo(true); } diff --git a/packages/angular/cli/src/commands/mcp/testing/test-utils.ts b/packages/angular/cli/src/commands/mcp/testing/test-utils.ts index 7afcd695dd7d..1bdf2ef416a5 100644 --- a/packages/angular/cli/src/commands/mcp/testing/test-utils.ts +++ b/packages/angular/cli/src/commands/mcp/testing/test-utils.ts @@ -27,6 +27,9 @@ export function createMockHost(): MockHost { getAvailablePort: jasmine .createSpy<Host['getAvailablePort']>('getAvailablePort') .and.resolveTo(0), + isPortAvailable: jasmine + .createSpy<Host['isPortAvailable']>('isPortAvailable') + .and.resolveTo(true), } as unknown as MockHost; } diff --git a/packages/angular/cli/src/commands/mcp/tools/devserver/devserver-start.ts b/packages/angular/cli/src/commands/mcp/tools/devserver/devserver-start.ts index 272bf6800300..f5f413cfad30 100644 --- a/packages/angular/cli/src/commands/mcp/tools/devserver/devserver-start.ts +++ b/packages/angular/cli/src/commands/mcp/tools/devserver/devserver-start.ts @@ -15,6 +15,13 @@ import { type McpToolContext, type McpToolDeclaration, declareTool } from '../to const devserverStartToolInputSchema = z.object({ ...workspaceAndProjectOptions, + port: z + .number() + .optional() + .describe( + 'The port number to run the server on. If not provided, a random available port will be chosen. ' + + 'It is recommended to reuse port numbers across calls within the same workspace to maintain consistency.', + ), }); export type DevserverStartToolInput = z.infer<typeof devserverStartToolInputSchema>; @@ -53,7 +60,17 @@ export async function startDevserver(input: DevserverStartToolInput, context: Mc }); } - const port = await context.host.getAvailablePort(); + let port: number; + if (input.port) { + if (!(await context.host.isPortAvailable(input.port))) { + throw new Error( + `Port ${input.port} is unavailable. Try calling this tool again without the 'port' parameter to auto-assign a free port.`, + ); + } + port = input.port; + } else { + port = await context.host.getAvailablePort(); + } devserver = new LocalDevserver({ host: context.host, @@ -87,14 +104,18 @@ the first build completes. background. * **Get Initial Build Logs:** Once a dev server has started, use the "devserver.wait_for_build" tool to ensure it's alive. If there are any build errors, "devserver.wait_for_build" would provide them back and you can give them to the user or rely on them to propose a fix. -* **Get Updated Build Logs:** Important: as long as a devserver is alive (i.e. "devserver.stop" wasn't called), after every time you make a - change to the workspace, re-run "devserver.wait_for_build" to see whether the change was successfully built and wait for the devserver to - be updated. +* **Get Updated Build Logs:** Important: as long as a devserver is alive (i.e. "devserver.stop" wasn't called), after every time you + make a change to the workspace, re-run "devserver.wait_for_build" to see whether the change was successfully built and wait for the + devserver to be updated. </Use Cases> <Operational Notes> * This tool manages development servers by itself. It maintains at most a single dev server instance for each project in the monorepo. * This is an asynchronous operation. Subsequent commands can be ran while the server is active. * Use 'devserver.stop' to gracefully shut down the server and access the full log output. +* **Keeping the Server Alive**: It is often better to keep the server alive between tool calls if you expect the user to request more + changes or run more tests, as it saves time on restarts and maintains the file watcher state. You must still call + 'devserver.wait_for_build' after every change to see whether the change was successfully built and be sure that that app was updated. +* **Consistent Ports**: If making multiple calls, it is recommended to reuse the port you got from the first call for subsequent ones. </Operational Notes> `, isReadOnly: true, diff --git a/packages/angular/cli/src/commands/mcp/tools/devserver/devserver_spec.ts b/packages/angular/cli/src/commands/mcp/tools/devserver/devserver_spec.ts index 93c6b367cb70..52a66902e2ef 100644 --- a/packages/angular/cli/src/commands/mcp/tools/devserver/devserver_spec.ts +++ b/packages/angular/cli/src/commands/mcp/tools/devserver/devserver_spec.ts @@ -64,6 +64,31 @@ describe('Serve Tools', () => { expect(mockProcess.kill).toHaveBeenCalled(); }); + it('should use the provided port number', async () => { + const startResult = await startDevserver({ port: 54321 }, mockContext); + expect(startResult.structuredContent.message).toBe( + `Development server for project 'my-app' started and watching for workspace changes.`, + ); + expect(mockHost.spawn).toHaveBeenCalledWith('ng', ['serve', 'my-app', '--port=54321'], { + stdio: 'pipe', + cwd: '/test', + }); + expect(mockHost.getAvailablePort).not.toHaveBeenCalled(); + }); + + it('should throw an error if the provided port is taken', async () => { + mockHost.isPortAvailable.and.resolveTo(false); + + try { + await startDevserver({ port: 55555 }, mockContext); + fail('Should have thrown an error'); + } catch (e) { + expect((e as Error).message).toContain( + "Port 55555 is unavailable. Try calling this tool again without the 'port' parameter to auto-assign a free port.", + ); + } + }); + it('should wait for a build to complete', async () => { await startDevserver({}, mockContext); diff --git a/packages/angular/cli/src/commands/mcp/tools/projects.ts b/packages/angular/cli/src/commands/mcp/tools/projects.ts index 8c6eb5d332f6..c53adb7828df 100644 --- a/packages/angular/cli/src/commands/mcp/tools/projects.ts +++ b/packages/angular/cli/src/commands/mcp/tools/projects.ts @@ -467,7 +467,7 @@ async function loadAndParseWorkspace( const projects = []; const workspaceRoot = dirname(configFile); for (const [name, project] of ws.projects.entries()) { - const sourceRoot = posix.join(project.root, project.sourceRoot ?? 'src'); + const sourceRoot = project.sourceRoot ?? posix.join(project.root, 'src'); const fullSourceRoot = join(workspaceRoot, sourceRoot); const unitTestFramework = getUnitTestFramework(project.targets.get('test')); const styleLanguage = await getProjectStyleLanguage(project, ws, fullSourceRoot); diff --git a/packages/angular/cli/src/commands/update/cli.ts b/packages/angular/cli/src/commands/update/cli.ts index 9f990845b59b..52efcb1c11d5 100644 --- a/packages/angular/cli/src/commands/update/cli.ts +++ b/packages/angular/cli/src/commands/update/cli.ts @@ -265,7 +265,7 @@ export default class UpdateCommandModule extends CommandModule<UpdateCommandArgs return options.migrateOnly ? this.migrateOnly( workflow, - (options.packages ?? [])[0], + packages[0].name as string, rootDependencies, options, packageManager, diff --git a/packages/angular/cli/src/commands/update/long-description.md b/packages/angular/cli/src/commands/update/long-description.md index 612971de0c4d..1771f7ffe1de 100644 --- a/packages/angular/cli/src/commands/update/long-description.md +++ b/packages/angular/cli/src/commands/update/long-description.md @@ -13,10 +13,10 @@ ng update @angular/cli@^<major_version> @angular/core@^<major_version> ``` We recommend that you always update to the latest patch version, as it contains fixes we released since the initial major release. -For example, use the following command to take the latest 10.x.x version and use that to update. +For example, use the following command to take the latest 21.x.x version and use that to update. ``` -ng update @angular/cli@^10 @angular/core@^10 +ng update @angular/cli@^21 @angular/core@^21 ``` -For detailed information and guidance on updating your application, see the interactive [Angular Update Guide](https://update.angular.dev/). +For detailed information and guidance on updating your application, see the interactive [Angular Update Guide](/update-guide). diff --git a/packages/angular/cli/src/commands/update/schematic/index.ts b/packages/angular/cli/src/commands/update/schematic/index.ts index 73fd3e342a5a..45ce0a212153 100644 --- a/packages/angular/cli/src/commands/update/schematic/index.ts +++ b/packages/angular/cli/src/commands/update/schematic/index.ts @@ -884,6 +884,13 @@ export default function (options: UpdateSchema): Rule { lastPackagesSize = packages.size; npmPackageJsonMap.forEach((npmPackageJson) => { _addPackageGroup(tree, packages, npmDeps, npmPackageJson, logger); + }); + } while (packages.size > lastPackagesSize); + + // This is done in seperate loop to ensure that package groups are added before peer dependencies. + do { + lastPackagesSize = packages.size; + npmPackageJsonMap.forEach((npmPackageJson) => { _addPeerDependencies(tree, packages, npmDeps, npmPackageJson, npmPackageJsonMap, logger); }); } while (packages.size > lastPackagesSize); diff --git a/packages/angular/cli/src/commands/update/schematic/index_spec.ts b/packages/angular/cli/src/commands/update/schematic/index_spec.ts index 3954e3c78254..11b2a0b5855e 100644 --- a/packages/angular/cli/src/commands/update/schematic/index_spec.ts +++ b/packages/angular/cli/src/commands/update/schematic/index_spec.ts @@ -335,4 +335,57 @@ describe('@schematics/update', () => { const resultTreeContent = resultTree.readContent('/package.json'); expect(resultTreeContent.endsWith('}')).toBeTrue(); }); + + it('updates group members to the same version as the targeted package', async () => { + const packageJsonContent = `{ + "name": "test", + "dependencies": { + "@angular/cdk": "^19.2.19", + "@angular/common": "^19.2.0", + "@angular/compiler": "^19.2.0", + "@angular/core": "^19.2.0", + "@angular/forms": "^19.2.0", + "@angular/platform-browser": "^19.2.0", + "@angular/platform-browser-dynamic": "^19.2.0", + "@angular/router": "^19.2.0", + "rxjs": "~7.8.0", + "tslib": "^2.3.0", + "zone.js": "~0.15.0" + }, + "devDependencies": { + "@angular-devkit/build-angular": "^19.2.21", + "@angular/cli": "^19.2.21", + "@angular/compiler-cli": "^19.2.0", + "typescript": "~5.7.2" + } + }`; + + const inputTree = new UnitTestTree( + new HostTree( + new virtualFs.test.TestHost({ + '/package.json': packageJsonContent, + }), + ), + ); + + const resultTree = await schematicRunner.runSchematic( + 'update', + { force: true, packages: ['@angular/cli@20', '@angular/cdk@20', '@angular/core@20'] }, + inputTree, + ); + + const { devDependencies, dependencies } = resultTree.readJson('/package.json') as { + devDependencies: Record<string, string>; + dependencies: Record<string, string>; + }; + + const version20Regexp = /^\^20.\d+.\d+$/; + + expect(devDependencies['typescript']).toMatch(/5\.9\.\d+/); + expect(devDependencies['@angular/cli']).toMatch(version20Regexp); + expect(devDependencies['@angular/compiler-cli']).toMatch(version20Regexp); + expect(dependencies['@angular/cdk']).toMatch(version20Regexp); + expect(dependencies['@angular/common']).toMatch(version20Regexp); + expect(dependencies['@angular/core']).toMatch(version20Regexp); + }); }); diff --git a/packages/angular/cli/src/package-managers/host.ts b/packages/angular/cli/src/package-managers/host.ts index 433b54414f69..cee68015f677 100644 --- a/packages/angular/cli/src/package-managers/host.ts +++ b/packages/angular/cli/src/package-managers/host.ts @@ -24,6 +24,12 @@ import { PackageManagerError } from './error'; * An abstraction layer for side-effectful operations. */ export interface Host { + /** + * Whether shell quoting is required for package manager specifiers. + * This is typically true on Windows, where commands are executed in a shell. + */ + readonly requiresQuoting?: boolean; + /** * Creates a directory. * @param path The path to the directory. @@ -101,6 +107,7 @@ export interface Host { */ export const NodeJS_HOST: Host = { stat, + requiresQuoting: platform() === 'win32', mkdir, readFile: (path: string) => readFile(path, { encoding: 'utf8' }), copyFile: (src, dest) => copyFile(src, dest, constants.COPYFILE_FICLONE), @@ -130,6 +137,9 @@ export const NodeJS_HOST: Host = { env: { ...process.env, ...options.env, + // NPM updater notifier will prevents the child process from closing until it timeout after 3 minutes. + NO_UPDATE_NOTIFIER: '1', + NPM_CONFIG_UPDATE_NOTIFIER: 'false', }, } satisfies SpawnOptions; const childProcess = isWin32 diff --git a/packages/angular/cli/src/package-managers/package-manager.ts b/packages/angular/cli/src/package-managers/package-manager.ts index fd3b0a663a79..0dfb89e57371 100644 --- a/packages/angular/cli/src/package-managers/package-manager.ts +++ b/packages/angular/cli/src/package-managers/package-manager.ts @@ -14,7 +14,7 @@ import { join, relative, resolve } from 'node:path'; import npa from 'npm-package-arg'; -import { maxSatisfying } from 'semver'; +import { maxSatisfying, valid } from 'semver'; import { PackageManagerError } from './error'; import { Host } from './host'; import { Logger } from './logger'; @@ -34,7 +34,7 @@ const METADATA_FIELDS = ['name', 'dist-tags', 'versions', 'time'] as const; * This is a performance optimization to avoid downloading unnecessary data. * These fields are the ones required by the CLI for operations like `ng add` and `ng update`. */ -const MANIFEST_FIELDS = [ +export const MANIFEST_FIELDS = [ 'name', 'version', 'deprecated', @@ -323,7 +323,9 @@ export class PackageManager { ignoreScripts ? this.descriptor.ignoreScriptsFlag : '', ].filter((flag) => flag); - const args = [this.descriptor.addCommand, packageName, ...flags]; + const specifier = this.host.requiresQuoting ? `"${packageName}"` : packageName; + const args = [this.descriptor.addCommand, specifier, ...flags]; + await this.#run(args, options); this.#dependencyCache = null; @@ -370,6 +372,10 @@ export class PackageManager { const { stdout } = await this.#run(this.descriptor.versionCommand); this.#version = stdout.trim(); + if (!valid(this.#version)) { + throw new Error(`Invalid semver version for ${this.name}: "${this.#version}"`); + } + return this.#version; } @@ -440,7 +446,9 @@ export class PackageManager { version: string, options: { timeout?: number; registry?: string; bypassCache?: boolean } = {}, ): Promise<PackageManifest | null> { - const specifier = `${packageName}@${version}`; + const specifier = this.host.requiresQuoting + ? `"${packageName}@${version}"` + : `${packageName}@${version}`; const commandArgs = [...this.descriptor.getManifestCommand, specifier]; const formatter = this.descriptor.viewCommandFieldArgFormatter; if (formatter) { diff --git a/packages/angular/cli/src/package-managers/package-manager_spec.ts b/packages/angular/cli/src/package-managers/package-manager_spec.ts index 802f50fa66ab..8d439d9b3b75 100644 --- a/packages/angular/cli/src/package-managers/package-manager_spec.ts +++ b/packages/angular/cli/src/package-managers/package-manager_spec.ts @@ -6,20 +6,54 @@ * found in the LICENSE file at https://angular.dev/license */ -import { Host } from './host'; -import { PackageManager } from './package-manager'; +import { MANIFEST_FIELDS, PackageManager } from './package-manager'; import { SUPPORTED_PACKAGE_MANAGERS } from './package-manager-descriptor'; import { MockHost } from './testing/mock-host'; describe('PackageManager', () => { - let host: Host; + let host: MockHost; let runCommandSpy: jasmine.Spy; const descriptor = SUPPORTED_PACKAGE_MANAGERS['npm']; beforeEach(() => { host = new MockHost(); runCommandSpy = spyOn(host, 'runCommand').and.resolveTo({ stdout: '1.2.3', stderr: '' }); - host.runCommand = runCommandSpy; + }); + + describe('getRegistryManifest', () => { + it('should quote complex range specifiers when required by the host', async () => { + // Simulate a quoting host + Object.assign(host, { requiresQuoting: true }); + + const pm = new PackageManager(host, '/tmp', descriptor); + const manifest = { name: 'foo', version: '1.0.0' }; + runCommandSpy.and.resolveTo({ stdout: JSON.stringify(manifest), stderr: '' }); + + await pm.getRegistryManifest('foo', '>=1.0.0 <2.0.0'); + + expect(runCommandSpy).toHaveBeenCalledWith( + descriptor.binary, + [...descriptor.getManifestCommand, '"foo@>=1.0.0 <2.0.0"', ...MANIFEST_FIELDS], + jasmine.anything(), + ); + }); + + it('should NOT quote complex range specifiers when not required by the host', async () => { + // Simulate a non-quoting host + Object.assign(host, { requiresQuoting: false }); + + const pm = new PackageManager(host, '/tmp', descriptor); + const manifest = { name: 'foo', version: '1.0.0' }; + runCommandSpy.and.resolveTo({ stdout: JSON.stringify(manifest), stderr: '' }); + + await pm.getRegistryManifest('foo', '>=1.0.0 <2.0.0'); + + expect(runCommandSpy).toHaveBeenCalledWith( + descriptor.binary, + [...descriptor.getManifestCommand, 'foo@>=1.0.0 <2.0.0', ...MANIFEST_FIELDS], + jasmine.anything(), + ); + }); }); describe('getVersion', () => { diff --git a/packages/angular/cli/src/package-managers/testing/mock-host.ts b/packages/angular/cli/src/package-managers/testing/mock-host.ts index ae4476c6501d..46e71be3cf60 100644 --- a/packages/angular/cli/src/package-managers/testing/mock-host.ts +++ b/packages/angular/cli/src/package-managers/testing/mock-host.ts @@ -14,6 +14,7 @@ import { Host } from '../host'; * This class allows for simulating a file system in memory. */ export class MockHost implements Host { + readonly requiresQuoting = false; private readonly fs = new Map<string, string[] | true>(); constructor(files: Record<string, string[] | true> = {}) { diff --git a/packages/angular/cli/src/utilities/prettier.ts b/packages/angular/cli/src/utilities/prettier.ts index e481d94a8b89..e2e516b82367 100644 --- a/packages/angular/cli/src/utilities/prettier.ts +++ b/packages/angular/cli/src/utilities/prettier.ts @@ -44,7 +44,7 @@ export async function formatFiles(cwd: string, files: Set<string>): Promise<void await execFileAsync( process.execPath, - [prettierCliPath, '--write', '--no-error-on-unmatched-pattern', ...files], + [prettierCliPath, '--write', '--no-error-on-unmatched-pattern', '--ignore-unknown', ...files], { cwd, shell: false, diff --git a/packages/angular/create/package.json b/packages/angular/create/package.json index a5ad3fce4ff9..e20338df9e30 100644 --- a/packages/angular/create/package.json +++ b/packages/angular/create/package.json @@ -9,7 +9,7 @@ "code generation", "schematics" ], - "bin": "./src/index.js", + "bin": "src/index.js", "dependencies": { "@angular/cli": "0.0.0-PLACEHOLDER" } diff --git a/packages/angular/ssr/BUILD.bazel b/packages/angular/ssr/BUILD.bazel index 16498600f603..ec6187173fbf 100644 --- a/packages/angular/ssr/BUILD.bazel +++ b/packages/angular/ssr/BUILD.bazel @@ -20,7 +20,7 @@ ts_project( ), args = [ "--lib", - "dom,es2022", + "dom.iterable,dom,es2022", ], data = [ "//packages/angular/ssr/third_party/beasties:beasties_bundled", diff --git a/packages/angular/ssr/node/public_api.ts b/packages/angular/ssr/node/public_api.ts index 81932873a440..89900f95cc5c 100644 --- a/packages/angular/ssr/node/public_api.ts +++ b/packages/angular/ssr/node/public_api.ts @@ -12,7 +12,7 @@ export { type CommonEngineOptions, } from './src/common-engine/common-engine'; -export { AngularNodeAppEngine } from './src/app-engine'; +export { AngularNodeAppEngine, type AngularNodeAppEngineOptions } from './src/app-engine'; export { createNodeRequestHandler, type NodeRequestHandlerFunction } from './src/handler'; export { writeResponseToNodeResponse } from './src/response'; diff --git a/packages/angular/ssr/node/src/app-engine.ts b/packages/angular/ssr/node/src/app-engine.ts index 8edac0ef69c6..29eb1fd366ab 100644 --- a/packages/angular/ssr/node/src/app-engine.ts +++ b/packages/angular/ssr/node/src/app-engine.ts @@ -9,9 +9,16 @@ import { AngularAppEngine } from '@angular/ssr'; import type { IncomingMessage } from 'node:http'; import type { Http2ServerRequest } from 'node:http2'; +import { AngularAppEngineOptions } from '../../src/app-engine'; +import { getAllowedHostsFromEnv } from './environment-options'; import { attachNodeGlobalErrorHandlers } from './errors'; import { createWebRequestFromNodeRequest } from './request'; +/** + * Options for the Angular Node.js server application engine. + */ +export interface AngularNodeAppEngineOptions extends AngularAppEngineOptions {} + /** * Angular server application engine. * Manages Angular server applications (including localized ones), handles rendering requests, @@ -21,9 +28,18 @@ import { createWebRequestFromNodeRequest } from './request'; * application to ensure consistent handling of rendering requests and resource management. */ export class AngularNodeAppEngine { - private readonly angularAppEngine = new AngularAppEngine(); + private readonly angularAppEngine: AngularAppEngine; + + /** + * Creates a new instance of the Angular Node.js server application engine. + * @param options Options for the Angular Node.js server application engine. + */ + constructor(options?: AngularNodeAppEngineOptions) { + this.angularAppEngine = new AngularAppEngine({ + ...options, + allowedHosts: [...getAllowedHostsFromEnv(), ...(options?.allowedHosts ?? [])], + }); - constructor() { attachNodeGlobalErrorHandlers(); } @@ -31,21 +47,36 @@ export class AngularNodeAppEngine { * Handles an incoming HTTP request by serving prerendered content, performing server-side rendering, * or delivering a static file for client-side rendered routes based on the `RenderMode` setting. * - * This method adapts Node.js's `IncomingMessage` or `Http2ServerRequest` + * This method adapts Node.js's `IncomingMessage`, `Http2ServerRequest` or `Request` * to a format compatible with the `AngularAppEngine` and delegates the handling logic to it. * - * @param request - The incoming HTTP request (`IncomingMessage` or `Http2ServerRequest`). + * @param request - The incoming HTTP request (`IncomingMessage`, `Http2ServerRequest` or `Request`). * @param requestContext - Optional context for rendering, such as metadata associated with the request. * @returns A promise that resolves to the resulting HTTP response object, or `null` if no matching Angular route is found. * * @remarks A request to `https://www.example.com/page/index.html` will serve or render the Angular route * corresponding to `https://www.example.com/page`. + * + * @remarks + * To prevent potential Server-Side Request Forgery (SSRF), this function verifies the hostname + * of the `request.url` against a list of authorized hosts. + * If the hostname is not recognized and `allowedHosts` is not empty, a Client-Side Rendered (CSR) version of the + * page is returned otherwise a 400 Bad Request is returned. + * + * Resolution: + * Authorize your hostname by configuring `allowedHosts` in `angular.json` in: + * `projects.[project-name].architect.build.options.security.allowedHosts`. + * Alternatively, you can define the allowed hostname via the environment variable `process.env['NG_ALLOWED_HOSTS']` + * or pass it directly through the configuration options of `AngularNodeAppEngine`. + * + * For more information see: https://angular.dev/best-practices/security#preventing-server-side-request-forgery-ssrf */ async handle( - request: IncomingMessage | Http2ServerRequest, + request: IncomingMessage | Http2ServerRequest | Request, requestContext?: unknown, ): Promise<Response | null> { - const webRequest = createWebRequestFromNodeRequest(request); + const webRequest = + request instanceof Request ? request : createWebRequestFromNodeRequest(request); return this.angularAppEngine.handle(webRequest, requestContext); } diff --git a/packages/angular/ssr/node/src/common-engine/common-engine.ts b/packages/angular/ssr/node/src/common-engine/common-engine.ts index 673156ee6b43..1c130d9abe86 100644 --- a/packages/angular/ssr/node/src/common-engine/common-engine.ts +++ b/packages/angular/ssr/node/src/common-engine/common-engine.ts @@ -12,6 +12,8 @@ import { renderApplication, renderModule, ɵSERVER_CONTEXT } from '@angular/plat import * as fs from 'node:fs'; import { dirname, join, normalize, resolve } from 'node:path'; import { URL } from 'node:url'; +import { validateUrl } from '../../../src/utils/validation'; +import { getAllowedHostsFromEnv } from '../environment-options'; import { attachNodeGlobalErrorHandlers } from '../errors'; import { CommonEngineInlineCriticalCssProcessor } from './inline-css-processor'; import { @@ -31,6 +33,9 @@ export interface CommonEngineOptions { /** Enable request performance profiling data collection and printing the results in the server console. */ enablePerformanceProfiler?: boolean; + + /** A set of hostnames that are allowed to access the server. */ + allowedHosts?: readonly string[]; } export interface CommonEngineRenderOptions { @@ -64,8 +69,14 @@ export class CommonEngine { private readonly templateCache = new Map<string, string>(); private readonly inlineCriticalCssProcessor = new CommonEngineInlineCriticalCssProcessor(); private readonly pageIsSSG = new Map<string, boolean>(); + private readonly allowedHosts: ReadonlySet<string>; + + constructor(private options?: CommonEngineOptions) { + this.allowedHosts = new Set([ + ...getAllowedHostsFromEnv(), + ...(this.options?.allowedHosts ?? []), + ]); - constructor(private options?: CommonEngineOptions | undefined) { attachNodeGlobalErrorHandlers(); } @@ -74,6 +85,40 @@ export class CommonEngine { * render options */ async render(opts: CommonEngineRenderOptions): Promise<string> { + const { url } = opts; + + if (url && URL.canParse(url)) { + const urlObj = new URL(url); + try { + validateUrl(urlObj, this.allowedHosts); + } catch (error) { + const isAllowedHostConfigured = this.allowedHosts.size > 0; + // eslint-disable-next-line no-console + console.error( + `ERROR: ${(error as Error).message}` + + 'Please provide a list of allowed hosts in the "allowedHosts" option in the "CommonEngine" constructor.', + isAllowedHostConfigured + ? '' + : '\nFalling back to client side rendering. This will become a 400 Bad Request in a future major version.', + ); + + if (!isAllowedHostConfigured) { + // Fallback to CSR to avoid a breaking change. + // TODO(alanagius): Return a 400 and remove this fallback in the next major version (v22). + let document = opts.document; + if (!document && opts.documentFilePath) { + document = opts.document ?? (await this.getDocument(opts.documentFilePath)); + } + + if (document) { + return document; + } + } + + throw error; + } + } + const enablePerformanceProfiler = this.options?.enablePerformanceProfiler; const runMethod = enablePerformanceProfiler diff --git a/packages/angular/ssr/node/src/environment-options.ts b/packages/angular/ssr/node/src/environment-options.ts new file mode 100644 index 000000000000..b18dcd08ebe6 --- /dev/null +++ b/packages/angular/ssr/node/src/environment-options.ts @@ -0,0 +1,29 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +/** + * Retrieves the list of allowed hosts from the environment variable `NG_ALLOWED_HOSTS`. + * @returns An array of allowed hosts. + */ +export function getAllowedHostsFromEnv(): ReadonlyArray<string> { + const allowedHosts: string[] = []; + const envNgAllowedHosts = process.env['NG_ALLOWED_HOSTS']; + if (!envNgAllowedHosts) { + return allowedHosts; + } + + const hosts = envNgAllowedHosts.split(','); + for (const host of hosts) { + const trimmed = host.trim(); + if (trimmed.length > 0) { + allowedHosts.push(trimmed); + } + } + + return allowedHosts; +} diff --git a/packages/angular/ssr/node/src/request.ts b/packages/angular/ssr/node/src/request.ts index 32d90d0029fc..402ec29ba56d 100644 --- a/packages/angular/ssr/node/src/request.ts +++ b/packages/angular/ssr/node/src/request.ts @@ -8,6 +8,7 @@ import type { IncomingHttpHeaders, IncomingMessage } from 'node:http'; import type { Http2ServerRequest } from 'node:http2'; +import { getFirstHeaderValue } from '../../src/utils/validation'; /** * A set containing all the pseudo-headers defined in the HTTP/2 specification. @@ -103,21 +104,3 @@ export function createRequestUrl(nodeRequest: IncomingMessage | Http2ServerReque return new URL(`${protocol}://${hostnameWithPort}${originalUrl ?? url}`); } - -/** - * Extracts the first value from a multi-value header string. - * - * @param value - A string or an array of strings representing the header values. - * If it's a string, values are expected to be comma-separated. - * @returns The first trimmed value from the multi-value header, or `undefined` if the input is invalid or empty. - * - * @example - * ```typescript - * getFirstHeaderValue("value1, value2, value3"); // "value1" - * getFirstHeaderValue(["value1", "value2"]); // "value1" - * getFirstHeaderValue(undefined); // undefined - * ``` - */ -function getFirstHeaderValue(value: string | string[] | undefined): string | undefined { - return value?.toString().split(',', 1)[0]?.trim(); -} diff --git a/packages/angular/ssr/package.json b/packages/angular/ssr/package.json index af829b8adc1e..9d9cf4650c44 100644 --- a/packages/angular/ssr/package.json +++ b/packages/angular/ssr/package.json @@ -29,12 +29,12 @@ }, "devDependencies": { "@angular-devkit/schematics": "workspace:*", - "@angular/common": "21.2.0-next.3", - "@angular/compiler": "21.2.0-next.3", - "@angular/core": "21.2.0-next.3", - "@angular/platform-browser": "21.2.0-next.3", - "@angular/platform-server": "21.2.0-next.3", - "@angular/router": "21.2.0-next.3", + "@angular/common": "21.2.6", + "@angular/compiler": "21.2.6", + "@angular/core": "21.2.6", + "@angular/platform-browser": "21.2.6", + "@angular/platform-server": "21.2.6", + "@angular/router": "21.2.6", "@schematics/angular": "workspace:*", "beasties": "0.4.1" }, @@ -42,6 +42,6 @@ "schematics": "./schematics/collection.json", "repository": { "type": "git", - "url": "https://github.com/angular/angular-cli.git" + "url": "git+https://github.com/angular/angular-cli.git" } } diff --git a/packages/angular/ssr/public_api.ts b/packages/angular/ssr/public_api.ts index e685f4ceabe3..eb05be266588 100644 --- a/packages/angular/ssr/public_api.ts +++ b/packages/angular/ssr/public_api.ts @@ -8,7 +8,7 @@ export * from './private_export'; -export { AngularAppEngine } from './src/app-engine'; +export { AngularAppEngine, type AngularAppEngineOptions } from './src/app-engine'; export { createRequestHandler, type RequestHandlerFunction } from './src/handler'; export { @@ -24,3 +24,5 @@ export { type ServerRouteServer, type ServerRouteCommon, } from './src/routes/route-config'; + +export { IS_DISCOVERING_ROUTES } from './src/routes/ng-routes'; diff --git a/packages/angular/ssr/src/app-engine.ts b/packages/angular/ssr/src/app-engine.ts index 0cb728e8535d..4074b44098d8 100644 --- a/packages/angular/ssr/src/app-engine.ts +++ b/packages/angular/ssr/src/app-engine.ts @@ -10,7 +10,19 @@ import type { AngularServerApp, getOrCreateAngularServerApp } from './app'; import { Hooks } from './hooks'; import { getPotentialLocaleIdFromUrl, getPreferredLocale } from './i18n'; import { EntryPointExports, getAngularAppEngineManifest } from './manifest'; +import { createRedirectResponse } from './utils/redirect'; import { joinUrlParts } from './utils/url'; +import { cloneRequestAndPatchHeaders, validateRequest } from './utils/validation'; + +/** + * Options for the Angular server application engine. + */ +export interface AngularAppEngineOptions { + /** + * A set of allowed hostnames for the server application. + */ + allowedHosts?: readonly string[]; +} /** * Angular server application engine. @@ -31,6 +43,15 @@ export class AngularAppEngine { */ static ɵallowStaticRouteRender = false; + /** + * A flag to enable or disable the allowed hosts check. + * + * Typically used during development to avoid the allowed hosts check. + * + * @private + */ + static ɵdisableAllowedHostsCheck = false; + /** * Hooks for extending or modifying the behavior of the server application. * These hooks are used by the Angular CLI when running the development server and @@ -45,6 +66,11 @@ export class AngularAppEngine { */ private readonly manifest = getAngularAppEngineManifest(); + /** + * A set of allowed hostnames for the server application. + */ + private readonly allowedHosts: ReadonlySet<string>; + /** * A map of supported locales from the server application's manifest. */ @@ -57,6 +83,29 @@ export class AngularAppEngine { */ private readonly entryPointsCache = new Map<string, Promise<EntryPointExports>>(); + /** + * Creates a new instance of the Angular server application engine. + * @param options Options for the Angular server application engine. + */ + constructor(options?: AngularAppEngineOptions) { + this.allowedHosts = this.getAllowedHosts(options); + } + + private getAllowedHosts(options: AngularAppEngineOptions | undefined): ReadonlySet<string> { + const allowedHosts = new Set([...(options?.allowedHosts ?? []), ...this.manifest.allowedHosts]); + + if (allowedHosts.has('*')) { + // eslint-disable-next-line no-console + console.warn( + 'Allowing all hosts via "*" is a security risk. This configuration should only be used when ' + + 'validation for "Host" and "X-Forwarded-Host" headers is performed in another layer, such as a load balancer or reverse proxy. ' + + 'For more information see: https://angular.dev/best-practices/security#preventing-server-side-request-forgery-ssrf', + ); + } + + return allowedHosts; + } + /** * Handles an incoming HTTP request by serving prerendered content, performing server-side rendering, * or delivering a static file for client-side rendered routes based on the `RenderMode` setting. @@ -67,17 +116,53 @@ export class AngularAppEngine { * * @remarks A request to `https://www.example.com/page/index.html` will serve or render the Angular route * corresponding to `https://www.example.com/page`. + * + * @remarks + * To prevent potential Server-Side Request Forgery (SSRF), this function verifies the hostname + * of the `request.url` against a list of authorized hosts. + * If the hostname is not recognized and `allowedHosts` is not empty, a Client-Side Rendered (CSR) version of the + * page is returned otherwise a 400 Bad Request is returned. + * Resolution: + * Authorize your hostname by configuring `allowedHosts` in `angular.json` in: + * `projects.[project-name].architect.build.options.security.allowedHosts`. + * Alternatively, you pass it directly through the configuration options of `AngularAppEngine`. + * + * For more information see: https://angular.dev/best-practices/security#preventing-server-side-request-forgery-ssrf */ async handle(request: Request, requestContext?: unknown): Promise<Response | null> { - const serverApp = await this.getAngularServerAppForRequest(request); + const allowedHost = this.allowedHosts; + const disableAllowedHostsCheck = AngularAppEngine.ɵdisableAllowedHostsCheck; + + try { + validateRequest(request, allowedHost, disableAllowedHostsCheck); + } catch (error) { + return this.handleValidationError(error as Error, request); + } + // Clone request with patched headers to prevent unallowed host header access. + const { request: securedRequest, onError: onHeaderValidationError } = disableAllowedHostsCheck + ? { request, onError: null } + : cloneRequestAndPatchHeaders(request, allowedHost); + + const serverApp = await this.getAngularServerAppForRequest(securedRequest); if (serverApp) { - return serverApp.handle(request, requestContext); + const promises: Promise<Response | null>[] = []; + if (onHeaderValidationError) { + promises.push( + onHeaderValidationError.then((error) => + this.handleValidationError(error, securedRequest), + ), + ); + } + + promises.push(serverApp.handle(securedRequest, requestContext)); + + return Promise.race(promises); } if (this.supportedLocales.length > 1) { // Redirect to the preferred language if i18n is enabled. - return this.redirectBasedOnAcceptLanguage(request); + return this.redirectBasedOnAcceptLanguage(securedRequest); } return null; @@ -110,13 +195,14 @@ export class AngularAppEngine { if (preferredLocale) { const subPath = supportedLocales[preferredLocale]; if (subPath !== undefined) { - return new Response(null, { - status: 302, // Use a 302 redirect as language preference may change. - headers: { - 'Location': joinUrlParts(pathname, subPath), - 'Vary': 'Accept-Language', - }, - }); + const prefix = request.headers.get('X-Forwarded-Prefix') ?? ''; + + return createRedirectResponse( + joinUrlParts(prefix, pathname, subPath), + 302, + // Use a 302 redirect as language preference may change. + { 'Vary': 'Accept-Language' }, + ); } } @@ -201,4 +287,42 @@ export class AngularAppEngine { return this.getEntryPointExports(potentialLocale) ?? this.getEntryPointExports(''); } + + /** + * Handles validation errors by logging the error and returning an appropriate response. + * + * @param error - The validation error to handle. + * @param request - The HTTP request that caused the validation error. + * @returns A promise that resolves to a `Response` object with a 400 status code if allowed hosts are configured, + * or `null` if allowed hosts are not configured (in which case the request is served client-side). + */ + private async handleValidationError(error: Error, request: Request): Promise<Response | null> { + const isAllowedHostConfigured = this.allowedHosts.size > 0; + const errorMessage = error.message; + + // eslint-disable-next-line no-console + console.error( + `ERROR: Bad Request ("${request.url}").\n` + + errorMessage + + (isAllowedHostConfigured + ? '' + : '\nFalling back to client side rendering. This will become a 400 Bad Request in a future major version.') + + '\n\nFor more information, see https://angular.dev/best-practices/security#preventing-server-side-request-forgery-ssrf', + ); + + if (isAllowedHostConfigured) { + // Allowed hosts has been configured incorrectly, thus we can return a 400 bad request. + return new Response(errorMessage, { + status: 400, + statusText: 'Bad Request', + headers: { 'Content-Type': 'text/plain' }, + }); + } + + // Fallback to CSR to avoid a breaking change. + // TODO(alanagius): Return a 400 and remove this fallback in the next major version (v22). + const serverApp = await this.getAngularServerAppForRequest(request); + + return serverApp?.serveClientSidePage() ?? null; + } } diff --git a/packages/angular/ssr/src/app.ts b/packages/angular/ssr/src/app.ts index 96afaa44c8d6..1f4fa30f237a 100644 --- a/packages/angular/ssr/src/app.ts +++ b/packages/angular/ssr/src/app.ts @@ -190,7 +190,7 @@ export class AngularServerApp { return null; } - const { redirectTo, status, renderMode } = matchedRoute; + const { redirectTo, status, renderMode, headers } = matchedRoute; if (redirectTo !== undefined) { return createRedirectResponse( @@ -199,6 +199,7 @@ export class AngularServerApp { buildPathWithParams(redirectTo, url.pathname), ), status, + headers, ); } @@ -352,7 +353,7 @@ export class AngularServerApp { } if (result.redirectTo) { - return createRedirectResponse(result.redirectTo, responseInit.status); + return createRedirectResponse(result.redirectTo, responseInit.status, headers); } if (renderMode === RenderMode.Prerender) { @@ -484,6 +485,27 @@ export class AngularServerApp { return html; } + + /** + * Serves the client-side version of the application. + * TODO(alanagius): Remove this method in version 22. + * @internal + */ + async serveClientSidePage(): Promise<Response> { + const { + manifest: { locale }, + assets, + } = this; + + const html = await assets.getServerAsset('index.csr.html').text(); + + return new Response(html, { + headers: new Headers({ + 'Content-Type': 'text/html;charset=UTF-8', + ...(locale !== undefined ? { 'Content-Language': locale } : {}), + }), + }); + } } let angularServerApp: AngularServerApp | undefined; diff --git a/packages/angular/ssr/src/manifest.ts b/packages/angular/ssr/src/manifest.ts index 0de603bba104..21ded49b3e10 100644 --- a/packages/angular/ssr/src/manifest.ts +++ b/packages/angular/ssr/src/manifest.ts @@ -6,7 +6,6 @@ * found in the LICENSE file at https://angular.dev/license */ -import type { BootstrapContext } from '@angular/platform-browser'; import type { SerializableRouteTreeNode } from './routes/route-tree'; import { AngularBootstrap } from './utils/ng'; @@ -74,6 +73,11 @@ export interface AngularAppEngineManifest { * - `value`: The url segment associated with that locale. */ readonly supportedLocales: Readonly<Record<string, string>>; + + /** + * A readonly array of allowed hostnames. + */ + readonly allowedHosts: Readonly<string[]>; } /** diff --git a/packages/angular/ssr/src/routes/ng-routes.ts b/packages/angular/ssr/src/routes/ng-routes.ts index b60e704371a4..438e8450d331 100644 --- a/packages/angular/ssr/src/routes/ng-routes.ts +++ b/packages/angular/ssr/src/routes/ng-routes.ts @@ -11,6 +11,7 @@ import { ApplicationRef, Compiler, EnvironmentInjector, + InjectionToken, Injector, createEnvironmentInjector, runInInjectionContext, @@ -23,6 +24,7 @@ import { Router, ɵloadChildren as loadChildrenHelper, } from '@angular/router'; + import { ServerAssets } from '../assets'; import { Console } from '../console'; import { AngularAppManifest, getAngularAppManifest } from '../manifest'; @@ -39,6 +41,22 @@ import { } from './route-config'; import { RouteTree, RouteTreeNodeMetadata } from './route-tree'; +/** + * A DI token that indicates whether the application is in the process of discovering routes. + * + * This token is provided with the value `true` when route discovery is active, allowing other + * parts of the application to conditionally execute logic. For example, it can be used to + * disable features or behaviors that are not necessary or might interfere with the route + * discovery process. + */ +export const IS_DISCOVERING_ROUTES = new InjectionToken<boolean>( + typeof ngDevMode === 'undefined' || ngDevMode ? 'IS_DISCOVERING_ROUTES' : '', + { + providedIn: 'platform', + factory: () => false, + }, +); + interface Route extends AngularRoute { ɵentryName?: string; } @@ -623,6 +641,10 @@ export async function getRoutesFromAngularRouterConfig( provide: ɵENABLE_ROOT_COMPONENT_BOOTSTRAP, useValue: false, }, + { + provide: IS_DISCOVERING_ROUTES, + useValue: true, + }, ]); try { diff --git a/packages/angular/ssr/src/utils/redirect.ts b/packages/angular/ssr/src/utils/redirect.ts index 18ca3f92b819..79fb10f424dc 100644 --- a/packages/angular/ssr/src/utils/redirect.ts +++ b/packages/angular/ssr/src/utils/redirect.ts @@ -27,9 +27,14 @@ export function isValidRedirectResponseCode(code: number): boolean { * @param location - The URL to which the response should redirect. * @param status - The HTTP status code for the redirection. Defaults to 302 (Found). * See: https://developer.mozilla.org/en-US/docs/Web/API/Response/redirect_static#status + * @param headers - Additional headers to include in the response. * @returns A `Response` object representing the HTTP redirect. */ -export function createRedirectResponse(location: string, status = 302): Response { +export function createRedirectResponse( + location: string, + status = 302, + headers?: Record<string, string>, +): Response { if (ngDevMode && !isValidRedirectResponseCode(status)) { throw new Error( `Invalid redirect status code: ${status}. ` + @@ -37,10 +42,30 @@ export function createRedirectResponse(location: string, status = 302): Response ); } + const resHeaders = new Headers(headers); + if (ngDevMode && resHeaders.has('location')) { + // eslint-disable-next-line no-console + console.warn( + `Location header "${resHeaders.get('location')}" will ignored and set to "${location}".`, + ); + } + + // Ensure unique values for Vary header + const varyArray = resHeaders.get('Vary')?.split(',') ?? []; + const varySet = new Set(['X-Forwarded-Prefix']); + for (const vary of varyArray) { + const value = vary.trim(); + + if (value) { + varySet.add(value); + } + } + + resHeaders.set('Vary', [...varySet].join(', ')); + resHeaders.set('Location', location); + return new Response(null, { status, - headers: { - 'Location': location, - }, + headers: resHeaders, }); } diff --git a/packages/angular/ssr/src/utils/url.ts b/packages/angular/ssr/src/utils/url.ts index 1fa756e19c19..d5e7c9ac2814 100644 --- a/packages/angular/ssr/src/utils/url.ts +++ b/packages/angular/ssr/src/utils/url.ts @@ -95,26 +95,32 @@ export function addTrailingSlash(url: string): string { * ``` */ export function joinUrlParts(...parts: string[]): string { - const normalizeParts: string[] = []; + const normalizedParts: string[] = []; + for (const part of parts) { if (part === '') { // Skip any empty parts continue; } - let normalizedPart = part; - if (part[0] === '/') { - normalizedPart = normalizedPart.slice(1); + let start = 0; + let end = part.length; + + // Use "Pointers" to avoid intermediate slices + while (start < end && part[start] === '/') { + start++; } - if (part.at(-1) === '/') { - normalizedPart = normalizedPart.slice(0, -1); + + while (end > start && part[end - 1] === '/') { + end--; } - if (normalizedPart !== '') { - normalizeParts.push(normalizedPart); + + if (start < end) { + normalizedParts.push(part.slice(start, end)); } } - return addLeadingSlash(normalizeParts.join('/')); + return addLeadingSlash(normalizedParts.join('/')); } /** diff --git a/packages/angular/ssr/src/utils/validation.ts b/packages/angular/ssr/src/utils/validation.ts new file mode 100644 index 000000000000..e8af64ed9943 --- /dev/null +++ b/packages/angular/ssr/src/utils/validation.ts @@ -0,0 +1,289 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +/** + * The set of headers that should be validated for host header injection attacks. + */ +const HOST_HEADERS_TO_VALIDATE: ReadonlySet<string> = new Set(['host', 'x-forwarded-host']); + +/** + * Regular expression to validate that the port is a numeric value. + */ +const VALID_PORT_REGEX = /^\d+$/; + +/** + * Regular expression to validate that the protocol is either http or https (case-insensitive). + */ +const VALID_PROTO_REGEX = /^https?$/i; + +/** + * Regular expression to validate that the host is a valid hostname. + */ +const VALID_HOST_REGEX = /^[a-z0-9_.-]+(:[0-9]+)?$/i; + +/** + * Regular expression to validate that the prefix is valid. + */ +const INVALID_PREFIX_REGEX = /^(?:\\|\/[/\\])|(?:^|[/\\])\.\.?(?:[/\\]|$)/; + +/** + * Extracts the first value from a multi-value header string. + * + * @param value - A string or an array of strings representing the header values. + * If it's a string, values are expected to be comma-separated. + * @returns The first trimmed value from the multi-value header, or `undefined` if the input is invalid or empty. + * + * @example + * ```typescript + * getFirstHeaderValue("value1, value2, value3"); // "value1" + * getFirstHeaderValue(["value1", "value2"]); // "value1" + * getFirstHeaderValue(undefined); // undefined + * ``` + */ +export function getFirstHeaderValue( + value: string | string[] | undefined | null, +): string | undefined { + return value?.toString().split(',', 1)[0]?.trim(); +} + +/** + * Validates a request. + * + * @param request - The incoming `Request` object to validate. + * @param allowedHosts - A set of allowed hostnames. + * @param disableHostCheck - Whether to disable the host check. + * @throws Error if any of the validated headers contain invalid values. + */ +export function validateRequest( + request: Request, + allowedHosts: ReadonlySet<string>, + disableHostCheck: boolean, +): void { + validateHeaders(request); + + if (!disableHostCheck) { + validateUrl(new URL(request.url), allowedHosts); + } +} + +/** + * Validates that the hostname of a given URL is allowed. + * + * @param url - The URL object to validate. + * @param allowedHosts - A set of allowed hostnames. + * @throws Error if the hostname is not in the allowlist. + */ +export function validateUrl(url: URL, allowedHosts: ReadonlySet<string>): void { + const { hostname } = url; + if (!isHostAllowed(hostname, allowedHosts)) { + throw new Error(`URL with hostname "${hostname}" is not allowed.`); + } +} + +/** + * Clones a request and patches the `get` method of the request headers to validate the host headers. + * @param request - The request to validate. + * @param allowedHosts - A set of allowed hostnames. + * @returns An object containing the cloned request and a promise that resolves to an error + * if any of the validated headers contain invalid values. + */ +export function cloneRequestAndPatchHeaders( + request: Request, + allowedHosts: ReadonlySet<string>, +): { request: Request; onError: Promise<Error> } { + let onError: (value: Error) => void; + const onErrorPromise = new Promise<Error>((resolve) => { + onError = resolve; + }); + + const clonedReq = new Request(request.clone(), { + signal: request.signal, + }); + + const headers = clonedReq.headers; + + const originalGet = headers.get; + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + (headers.get as typeof originalGet) = function (name) { + const value = originalGet.call(headers, name); + if (!value) { + return value; + } + + validateHeader(name, value, allowedHosts, onError); + + return value; + }; + + const originalValues = headers.values; + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + (headers.values as typeof originalValues) = function () { + for (const name of HOST_HEADERS_TO_VALIDATE) { + validateHeader(name, originalGet.call(headers, name), allowedHosts, onError); + } + + return originalValues.call(headers); + }; + + const originalEntries = headers.entries; + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + (headers.entries as typeof originalEntries) = function () { + const iterator = originalEntries.call(headers); + + return { + next() { + const result = iterator.next(); + if (!result.done) { + const [key, value] = result.value; + validateHeader(key, value, allowedHosts, onError); + } + + return result; + }, + [Symbol.iterator]() { + return this; + }, + }; + }; + + const originalForEach = headers.forEach; + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + (headers.forEach as typeof originalForEach) = function (callback, thisArg) { + originalForEach.call( + headers, + (value, key, parent) => { + validateHeader(key, value, allowedHosts, onError); + callback.call(thisArg, value, key, parent); + }, + thisArg, + ); + }; + + // Ensure for...of loops use the new patched entries + (headers[Symbol.iterator] as typeof originalEntries) = headers.entries; + + return { request: clonedReq, onError: onErrorPromise }; +} + +/** + * Validates a specific header value against the allowed hosts. + * @param name - The name of the header to validate. + * @param value - The value of the header to validate. + * @param allowedHosts - A set of allowed hostnames. + * @param onError - A callback function to call if the header value is invalid. + * @throws Error if the header value is invalid. + */ +function validateHeader( + name: string, + value: string | null, + allowedHosts: ReadonlySet<string>, + onError: (value: Error) => void, +): void { + if (!value) { + return; + } + + if (!HOST_HEADERS_TO_VALIDATE.has(name.toLowerCase())) { + return; + } + + try { + verifyHostAllowed(name, value, allowedHosts); + } catch (error) { + onError(error as Error); + + throw error; + } +} + +/** + * Validates a specific host header value against the allowed hosts. + * + * @param headerName - The name of the header to validate (e.g., 'host', 'x-forwarded-host'). + * @param headerValue - The value of the header to validate. + * @param allowedHosts - A set of allowed hostnames. + * @throws Error if the header value is invalid or the hostname is not in the allowlist. + */ +function verifyHostAllowed( + headerName: string, + headerValue: string, + allowedHosts: ReadonlySet<string>, +): void { + const value = getFirstHeaderValue(headerValue); + if (!value) { + return; + } + + const url = `http://${value}`; + if (!URL.canParse(url)) { + throw new Error(`Header "${headerName}" contains an invalid value and cannot be parsed.`); + } + + const { hostname } = new URL(url); + if (!isHostAllowed(hostname, allowedHosts)) { + throw new Error(`Header "${headerName}" with value "${value}" is not allowed.`); + } +} + +/** + * Checks if the hostname is allowed. + * @param hostname - The hostname to check. + * @param allowedHosts - A set of allowed hostnames. + * @returns `true` if the hostname is allowed, `false` otherwise. + */ +function isHostAllowed(hostname: string, allowedHosts: ReadonlySet<string>): boolean { + if (allowedHosts.has('*') || allowedHosts.has(hostname)) { + return true; + } + + for (const allowedHost of allowedHosts) { + if (!allowedHost.startsWith('*.')) { + continue; + } + + const domain = allowedHost.slice(1); + if (hostname.endsWith(domain)) { + return true; + } + } + + return false; +} + +/** + * Validates the headers of an incoming request. + * + * @param request - The incoming `Request` object containing the headers to validate. + * @throws Error if any of the validated headers contain invalid values. + */ +function validateHeaders(request: Request): void { + const headers = request.headers; + for (const headerName of HOST_HEADERS_TO_VALIDATE) { + const headerValue = getFirstHeaderValue(headers.get(headerName)); + if (headerValue && !VALID_HOST_REGEX.test(headerValue)) { + throw new Error(`Header "${headerName}" contains characters that are not allowed.`); + } + } + + const xForwardedPort = getFirstHeaderValue(headers.get('x-forwarded-port')); + if (xForwardedPort && !VALID_PORT_REGEX.test(xForwardedPort)) { + throw new Error('Header "x-forwarded-port" must be a numeric value.'); + } + + const xForwardedProto = getFirstHeaderValue(headers.get('x-forwarded-proto')); + if (xForwardedProto && !VALID_PROTO_REGEX.test(xForwardedProto)) { + throw new Error('Header "x-forwarded-proto" must be either "http" or "https".'); + } + + const xForwardedPrefix = getFirstHeaderValue(headers.get('x-forwarded-prefix')); + if (xForwardedPrefix && INVALID_PREFIX_REGEX.test(xForwardedPrefix)) { + throw new Error( + 'Header "x-forwarded-prefix" must not start with "\\" or multiple "/" or contain ".", ".." path segments.', + ); + } +} diff --git a/packages/angular/ssr/test/app-engine_spec.ts b/packages/angular/ssr/test/app-engine_spec.ts index b08931b9400b..60dd6b2cec7b 100644 --- a/packages/angular/ssr/test/app-engine_spec.ts +++ b/packages/angular/ssr/test/app-engine_spec.ts @@ -11,13 +11,26 @@ import '@angular/compiler'; /* eslint-enable import/no-unassigned-import */ -import { Component } from '@angular/core'; +import { Component, REQUEST, inject } from '@angular/core'; import { destroyAngularServerApp, getOrCreateAngularServerApp } from '../src/app'; import { AngularAppEngine } from '../src/app-engine'; import { setAngularAppEngineManifest } from '../src/manifest'; import { RenderMode } from '../src/routes/route-config'; import { setAngularAppTestingManifest } from './testing-utils'; +@Component({ + selector: 'app-home', + template: 'Home works', +}) +class TestHomeComponent { + private request = inject(REQUEST); + constructor() { + // Force header access to trigger validation + this.request?.headers.get('host'); + this.request?.headers.get('x-forwarded-host'); + } +} + function createEntryPoint(locale: string) { return async () => { @Component({ @@ -81,6 +94,7 @@ describe('AngularAppEngine', () => { describe('Localized app', () => { beforeAll(() => { setAngularAppEngineManifest({ + allowedHosts: ['example.com'], // Note: Although we are testing only one locale, we need to configure two or more // to ensure that we test a different code path. entryPoints: { @@ -146,7 +160,21 @@ describe('AngularAppEngine', () => { const response = await appEngine.handle(request); expect(response?.status).toBe(302); expect(response?.headers.get('Location')).toBe('/it'); - expect(response?.headers.get('Vary')).toBe('Accept-Language'); + expect(response?.headers.get('Vary')).toBe('X-Forwarded-Prefix, Accept-Language'); + }); + + it('should include forwarded prefix in locale redirect location when present', async () => { + const request = new Request('https://example.com', { + headers: { + 'Accept-Language': 'it', + 'X-Forwarded-Prefix': '/app', + }, + }); + + const response = await appEngine.handle(request); + expect(response?.status).toBe(302); + expect(response?.headers.get('Location')).toBe('/app/it'); + expect(response?.headers.get('Vary')).toBe('X-Forwarded-Prefix, Accept-Language'); }); it('should return null for requests to file-like resources in a locale', async () => { @@ -160,6 +188,7 @@ describe('AngularAppEngine', () => { describe('Localized app with single locale', () => { beforeAll(() => { setAngularAppEngineManifest({ + allowedHosts: ['example.com'], entryPoints: { it: createEntryPoint('it'), }, @@ -226,6 +255,7 @@ describe('AngularAppEngine', () => { class HomeComponent {} setAngularAppEngineManifest({ + allowedHosts: ['example.com'], entryPoints: { '': async () => { setAngularAppTestingManifest( @@ -270,4 +300,201 @@ describe('AngularAppEngine', () => { expect(await response?.text()).toContain('Home works'); }); }); + + describe('Invalid host headers', () => { + let consoleErrorSpy: jasmine.Spy; + + describe('with allowed hosts configured', () => { + beforeAll(() => { + setAngularAppEngineManifest({ + allowedHosts: ['example.com'], + entryPoints: { + '': async () => { + setAngularAppTestingManifest( + [{ path: 'home', component: TestHomeComponent }], + [{ path: '**', renderMode: RenderMode.Server }], + ); + + return { + ɵgetOrCreateAngularServerApp: getOrCreateAngularServerApp, + ɵdestroyAngularServerApp: destroyAngularServerApp, + }; + }, + }, + basePath: '/', + supportedLocales: { 'en-US': '' }, + }); + + appEngine = new AngularAppEngine(); + }); + + beforeEach(() => { + consoleErrorSpy = spyOn(console, 'error'); + }); + + it('should return 400 when disallowed host', async () => { + const request = new Request('https://evil.com'); + const response = await appEngine.handle(request); + expect(response).not.toBeNull(); + expect(response?.status).toBe(400); + expect(await response?.text()).toContain('URL with hostname "evil.com" is not allowed.'); + expect(consoleErrorSpy).toHaveBeenCalledWith( + jasmine.stringMatching('URL with hostname "evil.com" is not allowed.'), + ); + }); + + it('should return 400 when disallowed host header', async () => { + const request = new Request('https://example.com/home', { + headers: { 'host': 'evil.com' }, + }); + const response = await appEngine.handle(request); + expect(response).not.toBeNull(); + expect(response?.status).toBe(400); + expect(await response?.text()).toContain( + 'Header "host" with value "evil.com" is not allowed.', + ); + expect(consoleErrorSpy).toHaveBeenCalledWith( + jasmine.stringMatching('Header "host" with value "evil.com" is not allowed.'), + ); + }); + + it('should return 400 when disallowed x-forwarded-host header', async () => { + const request = new Request('https://example.com/home', { + headers: { 'x-forwarded-host': 'evil.com' }, + }); + const response = await appEngine.handle(request); + expect(response).not.toBeNull(); + expect(response?.status).toBe(400); + expect(await response?.text()).toContain( + 'Header "x-forwarded-host" with value "evil.com" is not allowed.', + ); + expect(consoleErrorSpy).toHaveBeenCalledWith( + jasmine.stringMatching('Header "x-forwarded-host" with value "evil.com" is not allowed.'), + ); + }); + + it('should return 400 when host with path separator', async () => { + const request = new Request('https://example.com/home', { + headers: { 'host': 'example.com/evil' }, + }); + const response = await appEngine.handle(request); + expect(response).not.toBeNull(); + expect(response?.status).toBe(400); + expect(await response?.text()).toContain( + 'Header "host" contains characters that are not allowed.', + ); + expect(consoleErrorSpy).toHaveBeenCalledWith( + jasmine.stringMatching('Header "host" contains characters that are not allowed.'), + ); + }); + }); + + describe('without allowed hosts configured', () => { + beforeAll(() => { + setAngularAppEngineManifest({ + allowedHosts: [], + entryPoints: { + '': async () => { + setAngularAppTestingManifest( + [{ path: 'home', component: TestHomeComponent }], + [{ path: '**', renderMode: RenderMode.Server }], + ); + + return { + ɵgetOrCreateAngularServerApp: getOrCreateAngularServerApp, + ɵdestroyAngularServerApp: destroyAngularServerApp, + }; + }, + }, + basePath: '/', + supportedLocales: { 'en-US': '' }, + }); + + appEngine = new AngularAppEngine(); + }); + + beforeEach(() => { + consoleErrorSpy = spyOn(console, 'error'); + }); + + it('should log error and fallback to CSR when disallowed host', async () => { + const request = new Request('https://example.com'); + const response = await appEngine.handle(request); + expect(response).not.toBeNull(); + expect(await response?.text()).toContain('<title>CSR page'); + expect(consoleErrorSpy).toHaveBeenCalledWith( + jasmine.stringMatching('URL with hostname "example.com" is not allowed.'), + ); + }); + + it('should log error and fallback to CSR when host with path separator', async () => { + const request = new Request('https://example.com/home', { + headers: { 'host': 'example.com/evil' }, + }); + const response = await appEngine.handle(request); + expect(response).not.toBeNull(); + expect(await response?.text()).toContain('CSR page'); + expect(consoleErrorSpy).toHaveBeenCalledWith( + jasmine.stringMatching('Header "host" contains characters that are not allowed.'), + ); + }); + }); + }); + + describe('Disable host check', () => { + let consoleErrorSpy: jasmine.Spy; + + beforeAll(() => { + setAngularAppEngineManifest({ + allowedHosts: ['example.com'], + entryPoints: { + '': async () => { + setAngularAppTestingManifest( + [{ path: 'home', component: TestHomeComponent }], + [{ path: '**', renderMode: RenderMode.Server }], + ); + + return { + ɵgetOrCreateAngularServerApp: getOrCreateAngularServerApp, + ɵdestroyAngularServerApp: destroyAngularServerApp, + }; + }, + }, + basePath: '/', + supportedLocales: { 'en-US': '' }, + }); + + appEngine = new AngularAppEngine(); + + AngularAppEngine.ɵdisableAllowedHostsCheck = true; + }); + + afterAll(() => { + AngularAppEngine.ɵdisableAllowedHostsCheck = false; + }); + + beforeEach(() => { + consoleErrorSpy = spyOn(console, 'error'); + }); + + it('should allow requests to disallowed hosts', async () => { + const request = new Request('https://evil.com/home'); + const response = await appEngine.handle(request); + expect(response).toBeDefined(); + expect(response?.status).toBe(200); + expect(await response?.text()).toContain('Home works'); + expect(consoleErrorSpy).not.toHaveBeenCalled(); + }); + + it('should allow requests with disallowed host header', async () => { + const request = new Request('https://example.com/home', { + headers: { 'host': 'evil.com' }, + }); + const response = await appEngine.handle(request); + expect(response).toBeDefined(); + expect(response?.status).toBe(200); + expect(await response?.text()).toContain('Home works'); + expect(consoleErrorSpy).not.toHaveBeenCalled(); + }); + }); }); diff --git a/packages/angular/ssr/test/npm_package/BUILD.bazel b/packages/angular/ssr/test/npm_package/BUILD.bazel index ae1694d8caac..cbf2c2623025 100644 --- a/packages/angular/ssr/test/npm_package/BUILD.bazel +++ b/packages/angular/ssr/test/npm_package/BUILD.bazel @@ -1,4 +1,4 @@ -load("@aspect_bazel_lib//lib:write_source_files.bzl", "write_source_file") +load("@bazel_lib//lib:write_source_files.bzl", "write_source_file") load("//tools:defaults.bzl", "jasmine_test", "ts_project") ts_project( diff --git a/packages/angular/ssr/test/routes/ng-routes_spec.ts b/packages/angular/ssr/test/routes/ng-routes_spec.ts index 324abe8c4d29..1532eb337faa 100644 --- a/packages/angular/ssr/test/routes/ng-routes_spec.ts +++ b/packages/angular/ssr/test/routes/ng-routes_spec.ts @@ -18,7 +18,7 @@ import { provideRouter, withEnabledBlockingInitialNavigation, } from '@angular/router'; -import { extractRoutesAndCreateRouteTree } from '../../src/routes/ng-routes'; +import { IS_DISCOVERING_ROUTES, extractRoutesAndCreateRouteTree } from '../../src/routes/ng-routes'; import { PrerenderFallback, RenderMode } from '../../src/routes/route-config'; import { setAngularAppTestingManifest } from '../testing-utils'; @@ -790,4 +790,26 @@ describe('extractRoutesAndCreateRouteTree', () => { { route: '/home', renderMode: RenderMode.Server }, ]); }); + + it('should provide `IS_DISCOVERING_ROUTES` as `true` during route discovery', async () => { + let isDiscoveringRoutes: boolean | undefined; + + setAngularAppTestingManifest( + [ + { + path: 'lazy', + loadChildren: () => { + isDiscoveringRoutes = inject(IS_DISCOVERING_ROUTES); + + return []; + }, + }, + ], + [{ path: '**', renderMode: RenderMode.Server }], + ); + + await extractRoutesAndCreateRouteTree({ url }); + + expect(isDiscoveringRoutes).toBeTrue(); + }); }); diff --git a/packages/angular/ssr/test/utils/redirect_spec.ts b/packages/angular/ssr/test/utils/redirect_spec.ts new file mode 100644 index 000000000000..b26edd458ac3 --- /dev/null +++ b/packages/angular/ssr/test/utils/redirect_spec.ts @@ -0,0 +1,67 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { createRedirectResponse } from '../../src/utils/redirect'; + +describe('Redirect Utils', () => { + describe('createRedirectResponse', () => { + it('should create a redirect response with default status 302', () => { + const response = createRedirectResponse('/home'); + expect(response.status).toBe(302); + expect(response.headers.get('Location')).toBe('/home'); + expect(response.headers.get('Vary')).toBe('X-Forwarded-Prefix'); + }); + + it('should create a redirect response with a custom status', () => { + const response = createRedirectResponse('/home', 301); + expect(response.status).toBe(301); + expect(response.headers.get('Location')).toBe('/home'); + }); + + it('should allow providing additional headers', () => { + const response = createRedirectResponse('/home', 302, { 'X-Custom': 'value' }); + expect(response.headers.get('X-Custom')).toBe('value'); + expect(response.headers.get('Location')).toBe('/home'); + expect(response.headers.get('Vary')).toBe('X-Forwarded-Prefix'); + }); + + it('should append to Vary header instead of overriding it', () => { + const response = createRedirectResponse('/home', 302, { + 'Location': '/evil', + 'Vary': 'Host', + }); + expect(response.headers.get('Location')).toBe('/home'); + expect(response.headers.get('Vary')).toBe('X-Forwarded-Prefix, Host'); + }); + + it('should NOT add duplicate X-Forwarded-Prefix if already present in Vary header', () => { + const response = createRedirectResponse('/home', 302, { + 'Vary': 'X-Forwarded-Prefix, Host', + }); + expect(response.headers.get('Vary')).toBe('X-Forwarded-Prefix, Host'); + }); + + it('should warn if Location header is provided in extra headers in dev mode', () => { + // @ts-expect-error accessing global + globalThis.ngDevMode = true; + const warnSpy = spyOn(console, 'warn'); + createRedirectResponse('/home', 302, { 'Location': '/evil' }); + expect(warnSpy).toHaveBeenCalledWith( + 'Location header "/evil" will ignored and set to "/home".', + ); + }); + + it('should throw error for invalid redirect status code in dev mode', () => { + // @ts-expect-error accessing global + globalThis.ngDevMode = true; + expect(() => createRedirectResponse('/home', 200)).toThrowError( + /Invalid redirect status code: 200/, + ); + }); + }); +}); diff --git a/packages/angular/ssr/test/utils/url_spec.ts b/packages/angular/ssr/test/utils/url_spec.ts index 9a7a7cb3ad49..a108c7ff1df6 100644 --- a/packages/angular/ssr/test/utils/url_spec.ts +++ b/packages/angular/ssr/test/utils/url_spec.ts @@ -100,6 +100,18 @@ describe('URL Utils', () => { it('should handle an all-empty URL parts', () => { expect(joinUrlParts('', '')).toBe('/'); }); + + it('should normalize parts with multiple leading and trailing slashes', () => { + expect(joinUrlParts('//path//', '///to///', '//resource//')).toBe('/path/to/resource'); + }); + + it('should handle a single part', () => { + expect(joinUrlParts('path')).toBe('/path'); + }); + + it('should handle parts containing only slashes', () => { + expect(joinUrlParts('//', '///')).toBe('/'); + }); }); describe('stripIndexHtmlFromURL', () => { diff --git a/packages/angular/ssr/test/utils/validation_spec.ts b/packages/angular/ssr/test/utils/validation_spec.ts new file mode 100644 index 000000000000..5c4b6e8cd121 --- /dev/null +++ b/packages/angular/ssr/test/utils/validation_spec.ts @@ -0,0 +1,364 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { + cloneRequestAndPatchHeaders, + getFirstHeaderValue, + validateRequest, + validateUrl, +} from '../../src/utils/validation'; + +describe('Validation Utils', () => { + describe('getFirstHeaderValue', () => { + it('should return the first value from a comma-separated string', () => { + expect(getFirstHeaderValue('value1, value2')).toBe('value1'); + }); + + it('should return the value if it is a single string', () => { + expect(getFirstHeaderValue('value1')).toBe('value1'); + }); + + it('should return the first value from an array of strings', () => { + expect(getFirstHeaderValue(['value1', 'value2'])).toBe('value1'); + }); + + it('should return undefined for null or undefined', () => { + expect(getFirstHeaderValue(null)).toBeUndefined(); + expect(getFirstHeaderValue(undefined)).toBeUndefined(); + }); + + it('should return empty string for empty string input', () => { + expect(getFirstHeaderValue('')).toBe(''); + }); + }); + + describe('validateUrl', () => { + const allowedHosts = new Set(['example.com', '*.google.com']); + + it('should pass for allowed hostname', () => { + expect(() => validateUrl(new URL('http://example.com'), allowedHosts)).not.toThrow(); + }); + + it('should pass for wildcard allowed hostname', () => { + expect(() => validateUrl(new URL('http://foo.google.com'), allowedHosts)).not.toThrow(); + }); + + it('should throw for disallowed hostname', () => { + expect(() => validateUrl(new URL('http://evil.com'), allowedHosts)).toThrowError( + /URL with hostname "evil.com" is not allowed/, + ); + }); + + it('should match subdomains for wildcard', () => { + expect(() => validateUrl(new URL('http://sub.foo.google.com'), allowedHosts)).not.toThrow(); + }); + + it('should not match base domain for wildcard (*.google.com vs google.com)', () => { + // Logic: hostname.endsWith('.google.com') -> 'google.com'.endsWith('.google.com') is false + expect(() => validateUrl(new URL('http://google.com'), allowedHosts)).toThrowError( + /URL with hostname "google.com" is not allowed/, + ); + }); + + it('should pass for all hostnames when "*" is used', () => { + const allowedHosts = new Set(['*']); + expect(() => validateUrl(new URL('http://example.com'), allowedHosts)).not.toThrow(); + expect(() => validateUrl(new URL('http://google.com'), allowedHosts)).not.toThrow(); + expect(() => validateUrl(new URL('http://evil.com'), allowedHosts)).not.toThrow(); + }); + }); + + describe('validateRequest', () => { + const allowedHosts = new Set(['example.com']); + + it('should pass for valid request', () => { + const req = new Request('http://example.com', { + headers: { + 'x-forwarded-port': '443', + 'x-forwarded-proto': 'https', + }, + }); + + expect(() => validateRequest(req, allowedHosts, false)).not.toThrow(); + }); + + it('should pass for valid request when disableHostCheck is true', () => { + const req = new Request('http://evil.com'); + + expect(() => validateRequest(req, allowedHosts, true)).not.toThrow(); + }); + + it('should throw if URL hostname is invalid', () => { + const req = new Request('http://evil.com'); + + expect(() => validateRequest(req, allowedHosts, false)).toThrowError( + /URL with hostname "evil.com" is not allowed/, + ); + }); + + it('should throw if x-forwarded-port is invalid', () => { + const req = new Request('http://example.com', { + headers: { 'x-forwarded-port': 'abc' }, + }); + + expect(() => validateRequest(req, allowedHosts, false)).toThrowError( + 'Header "x-forwarded-port" must be a numeric value.', + ); + }); + + it('should throw if x-forwarded-proto is invalid', () => { + const req = new Request('http://example.com', { + headers: { 'x-forwarded-proto': 'ftp' }, + }); + expect(() => validateRequest(req, allowedHosts, false)).toThrowError( + 'Header "x-forwarded-proto" must be either "http" or "https".', + ); + }); + + it('should pass for valid x-forwarded-proto (case-insensitive)', () => { + const req = new Request('http://example.com', { + headers: { 'x-forwarded-proto': 'HTTP' }, + }); + expect(() => validateRequest(req, allowedHosts, false)).not.toThrow(); + }); + + it('should throw if host contains path separators', () => { + const req = new Request('http://example.com', { + headers: { 'host': 'example.com/bad' }, + }); + expect(() => validateRequest(req, allowedHosts, false)).toThrowError( + 'Header "host" contains characters that are not allowed.', + ); + }); + + it('should throw if host contains invalid characters', () => { + const req = new Request('http://example.com', { + headers: { 'host': 'example.com?query=1' }, + }); + expect(() => validateRequest(req, allowedHosts, false)).toThrowError( + 'Header "host" contains characters that are not allowed.', + ); + }); + + it('should throw if x-forwarded-host contains path separators', () => { + const req = new Request('http://example.com', { + headers: { 'x-forwarded-host': 'example.com/bad' }, + }); + expect(() => validateRequest(req, allowedHosts, false)).toThrowError( + 'Header "x-forwarded-host" contains characters that are not allowed.', + ); + }); + + it('should throw error if x-forwarded-prefix starts with a backslash or multiple slashes', () => { + const inputs = ['//evil', '\\\\evil', '/\\evil', '\\/evil', '\\evil']; + + for (const prefix of inputs) { + const request = new Request('https://example.com', { + headers: { + 'x-forwarded-prefix': prefix, + }, + }); + + expect(() => validateRequest(request, allowedHosts, false)) + .withContext(`Prefix: "${prefix}"`) + .toThrowError( + 'Header "x-forwarded-prefix" must not start with "\\" or multiple "/" or contain ".", ".." path segments.', + ); + } + }); + + it('should throw error if x-forwarded-prefix contains dot segments', () => { + const inputs = [ + '/./', + '/../', + '/foo/./bar', + '/foo/../bar', + '/.', + '/..', + './', + '../', + '.\\', + '..\\', + '/foo/.\\bar', + '/foo/..\\bar', + '.', + '..', + ]; + + for (const prefix of inputs) { + const request = new Request('https://example.com', { + headers: { + 'x-forwarded-prefix': prefix, + }, + }); + + expect(() => validateRequest(request, allowedHosts, false)) + .withContext(`Prefix: "${prefix}"`) + .toThrowError( + 'Header "x-forwarded-prefix" must not start with "\\" or multiple "/" or contain ".", ".." path segments.', + ); + } + }); + + it('should validate x-forwarded-prefix with valid dot usage', () => { + const inputs = ['/foo.bar', '/foo.bar/baz', '/v1.2', '/.well-known']; + + for (const prefix of inputs) { + const request = new Request('https://example.com', { + headers: { + 'x-forwarded-prefix': prefix, + }, + }); + + expect(() => validateRequest(request, allowedHosts, false)) + .withContext(`Prefix: "${prefix}"`) + .not.toThrow(); + } + }); + }); + + describe('cloneRequestAndPatchHeaders', () => { + const allowedHosts = new Set(['example.com', '*.valid.com']); + + it('should validate host header when accessed via get()', async () => { + const req = new Request('http://example.com', { + headers: { 'host': 'evil.com' }, + }); + const { request: secured, onError } = cloneRequestAndPatchHeaders(req, allowedHosts); + + expect(() => secured.headers.get('host')).toThrowError( + 'Header "host" with value "evil.com" is not allowed.', + ); + await expectAsync(onError).toBeResolvedTo( + jasmine.objectContaining({ + message: jasmine.stringMatching('Header "host" with value "evil.com" is not allowed'), + }), + ); + }); + + it('should allow valid host header', () => { + const req = new Request('http://example.com', { + headers: { 'host': 'example.com' }, + }); + const { request: secured } = cloneRequestAndPatchHeaders(req, allowedHosts); + expect(secured.headers.get('host')).toBe('example.com'); + }); + + it('should allow any host header when "*" is used', () => { + const allowedHosts = new Set(['*']); + const req = new Request('http://example.com', { + headers: { 'host': 'evil.com' }, + }); + const { request: secured } = cloneRequestAndPatchHeaders(req, allowedHosts); + expect(secured.headers.get('host')).toBe('evil.com'); + }); + + it('should validate x-forwarded-host header', async () => { + const req = new Request('http://example.com', { + headers: { 'x-forwarded-host': 'evil.com' }, + }); + const { request: secured, onError } = cloneRequestAndPatchHeaders(req, allowedHosts); + + expect(() => secured.headers.get('x-forwarded-host')).toThrowError( + 'Header "x-forwarded-host" with value "evil.com" is not allowed.', + ); + await expectAsync(onError).toBeResolvedTo( + jasmine.objectContaining({ + message: jasmine.stringMatching( + 'Header "x-forwarded-host" with value "evil.com" is not allowed', + ), + }), + ); + }); + + it('should allow accessing other headers without validation', () => { + const req = new Request('http://example.com', { + headers: { 'accept': 'application/json' }, + }); + const { request: secured } = cloneRequestAndPatchHeaders(req, allowedHosts); + + expect(secured.headers.get('accept')).toBe('application/json'); + }); + + it('should validate headers when iterating with entries()', async () => { + const req = new Request('http://example.com', { + headers: { 'host': 'evil.com' }, + }); + const { request: secured, onError } = cloneRequestAndPatchHeaders(req, allowedHosts); + + expect(() => { + for (const _ of secured.headers.entries()) { + // access the header to trigger the validation + } + }).toThrowError('Header "host" with value "evil.com" is not allowed.'); + + await expectAsync(onError).toBeResolvedTo( + jasmine.objectContaining({ + message: jasmine.stringMatching('Header "host" with value "evil.com" is not allowed.'), + }), + ); + }); + + it('should validate headers when iterating with values()', async () => { + const req = new Request('http://example.com', { + headers: { 'host': 'evil.com' }, + }); + const { request: secured, onError } = cloneRequestAndPatchHeaders(req, allowedHosts); + + expect(() => { + for (const _ of secured.headers.values()) { + // access the header to trigger the validation + } + }).toThrowError('Header "host" with value "evil.com" is not allowed.'); + + await expectAsync(onError).toBeResolvedTo( + jasmine.objectContaining({ + message: jasmine.stringMatching('Header "host" with value "evil.com" is not allowed.'), + }), + ); + }); + + it('should validate headers when iterating with for...of', async () => { + const req = new Request('http://example.com', { + headers: { 'host': 'evil.com' }, + }); + const { request: secured, onError } = cloneRequestAndPatchHeaders(req, allowedHosts); + + expect(() => { + for (const _ of secured.headers) { + // access the header to trigger the validation + } + }).toThrowError('Header "host" with value "evil.com" is not allowed.'); + + await expectAsync(onError).toBeResolvedTo( + jasmine.objectContaining({ + message: jasmine.stringMatching('Header "host" with value "evil.com" is not allowed.'), + }), + ); + }); + + it('should validate headers when iterating with forEach()', async () => { + const req = new Request('http://example.com', { + headers: { 'host': 'evil.com' }, + }); + const { request: secured, onError } = cloneRequestAndPatchHeaders(req, allowedHosts); + + expect(() => { + secured.headers.forEach(() => { + // access the header to trigger the validation + }); + }).toThrowError('Header "host" with value "evil.com" is not allowed.'); + + await expectAsync(onError).toBeResolvedTo( + jasmine.objectContaining({ + message: jasmine.stringMatching('Header "host" with value "evil.com" is not allowed.'), + }), + ); + }); + }); +}); diff --git a/packages/angular/ssr/third_party/beasties/BUILD.bazel b/packages/angular/ssr/third_party/beasties/BUILD.bazel index 3e8be4267570..b88771871810 100644 --- a/packages/angular/ssr/third_party/beasties/BUILD.bazel +++ b/packages/angular/ssr/third_party/beasties/BUILD.bazel @@ -1,5 +1,5 @@ load("@aspect_rules_js//js:defs.bzl", "js_library") -load("@npm//:rollup/package_json.bzl", rollup = "bin") +load("@npm//:@rollup/wasm-node/package_json.bzl", rollup = "bin") package(default_visibility = ["//visibility:public"]) diff --git a/packages/angular_devkit/architect/package.json b/packages/angular_devkit/architect/package.json index c3f51752bc0c..6cdaa6e5ddac 100644 --- a/packages/angular_devkit/architect/package.json +++ b/packages/angular_devkit/architect/package.json @@ -4,7 +4,7 @@ "description": "Angular Build Facade", "experimental": true, "bin": { - "architect": "./bin/cli.js" + "architect": "bin/cli.js" }, "main": "src/index.js", "typings": "src/index.d.ts", diff --git a/packages/angular_devkit/build_angular/BUILD.bazel b/packages/angular_devkit/build_angular/BUILD.bazel index 6e4fba869d9f..fc8011cc1078 100644 --- a/packages/angular_devkit/build_angular/BUILD.bazel +++ b/packages/angular_devkit/build_angular/BUILD.bazel @@ -219,9 +219,6 @@ ts_project( "src/builders/**/*_spec.ts", ], ), - data = [ - "//packages/angular_devkit/build_angular/test/hello-world-lib", - ], deps = [ ":build_angular", ":build_angular_test_utils", @@ -290,9 +287,6 @@ ts_project( "src/**/*_spec.ts", ], ), - data = [ - "//packages/angular_devkit/build_angular/test/hello-world-lib", - ], deps = [ ":build_angular", ":node_modules/@angular-devkit/architect", @@ -353,7 +347,8 @@ LARGE_SPECS = { "//:node_modules/@angular/animations", ], }, - "ng-packagr": {}, + "ng-packagr": { + }, "browser": { "shards": 10, "size": "large", diff --git a/packages/angular_devkit/build_angular/package.json b/packages/angular_devkit/build_angular/package.json index f557d8362da9..f4e7f207c2ec 100644 --- a/packages/angular_devkit/build_angular/package.json +++ b/packages/angular_devkit/build_angular/package.json @@ -23,10 +23,10 @@ "@discoveryjs/json-ext": "0.6.3", "@ngtools/webpack": "workspace:0.0.0-PLACEHOLDER", "ansi-colors": "4.1.3", - "autoprefixer": "10.4.24", + "autoprefixer": "10.4.27", "babel-loader": "10.0.0", "browserslist": "^4.26.0", - "copy-webpack-plugin": "13.0.1", + "copy-webpack-plugin": "14.0.0", "css-loader": "7.1.3", "esbuild-wasm": "0.27.3", "http-proxy-middleware": "3.0.5", @@ -40,7 +40,7 @@ "mini-css-extract-plugin": "2.10.0", "open": "11.0.0", "ora": "9.3.0", - "picomatch": "4.0.3", + "picomatch": "4.0.4", "piscina": "5.1.4", "postcss": "8.5.6", "postcss-loader": "8.2.0", @@ -68,8 +68,8 @@ "@angular/ssr": "workspace:*", "@web/test-runner": "0.20.2", "browser-sync": "3.0.4", - "ng-packagr": "21.2.0-next.0", - "undici": "7.22.0" + "ng-packagr": "21.2.2", + "undici": "7.24.4" }, "peerDependencies": { "@angular/core": "0.0.0-ANGULAR-FW-PEER-DEP", diff --git a/packages/angular_devkit/build_angular/src/builders/ng-packagr/index.ts b/packages/angular_devkit/build_angular/src/builders/ng-packagr/index.ts index 2062e4cad595..42533a33aa0d 100644 --- a/packages/angular_devkit/build_angular/src/builders/ng-packagr/index.ts +++ b/packages/angular_devkit/build_angular/src/builders/ng-packagr/index.ts @@ -9,6 +9,7 @@ import { purgeStaleBuildCache } from '@angular/build/private'; import { BuilderContext, BuilderOutput, createBuilder } from '@angular-devkit/architect'; import type { NgPackagrOptions } from 'ng-packagr'; +import { createRequire } from 'node:module'; import { join, resolve } from 'node:path'; import { Observable, catchError, from, map, of, switchMap } from 'rxjs'; import { normalizeCacheOptions } from '../../utils/normalize-cache'; @@ -27,7 +28,9 @@ export function execute( await purgeStaleBuildCache(context); const root = context.workspaceRoot; - const packager = (await import('ng-packagr')).ngPackagr(); + const workspaceRequire = createRequire(root + '/'); + const ngPackagePath = workspaceRequire.resolve('ng-packagr'); + const packager = (await import(ngPackagePath)).ngPackagr(); packager.forProject(resolve(root, options.project)); diff --git a/packages/angular_devkit/build_angular/src/builders/ng-packagr/works_spec.ts b/packages/angular_devkit/build_angular/src/builders/ng-packagr/works_spec.ts index 4bf1ac2dec91..90581f9d9437 100644 --- a/packages/angular_devkit/build_angular/src/builders/ng-packagr/works_spec.ts +++ b/packages/angular_devkit/build_angular/src/builders/ng-packagr/works_spec.ts @@ -20,7 +20,10 @@ import { import { debounceTime, map, take, tap } from 'rxjs'; describe('NgPackagr Builder', () => { - const workspaceRoot = join(normalize(__dirname), `../../../test/hello-world-lib/`); + const workspaceRoot = join( + normalize(__dirname), + `../../../../../../modules/testing/builder/projects/hello-world-lib/`, + ); const host = new TestProjectHost(workspaceRoot); let architect: Architect; diff --git a/packages/angular_devkit/build_angular/src/builders/ssr-dev-server/index.ts b/packages/angular_devkit/build_angular/src/builders/ssr-dev-server/index.ts index 8ec879993e4f..e919f188e0bf 100644 --- a/packages/angular_devkit/build_angular/src/builders/ssr-dev-server/index.ts +++ b/packages/angular_devkit/build_angular/src/builders/ssr-dev-server/index.ts @@ -115,7 +115,13 @@ export function execute( return of([b, s]); } - return startNodeServer(s, nodeServerPort, context.logger, !!options.inspect).pipe( + return startNodeServer( + s, + nodeServerPort, + options.host, + context.logger, + !!options.inspect, + ).pipe( map(() => [b, s]), catchError((err) => { context.logger.error(`A server error has occurred.\n${mapErrorToMessage(err)}`); @@ -217,12 +223,13 @@ export function log( function startNodeServer( serverOutput: BuilderOutput, port: number, + host: string | undefined, logger: logging.LoggerApi, inspectMode = false, ): Observable { const outputPath = serverOutput.outputPath as string; const path = join(outputPath, 'main.js'); - const env = { ...process.env, PORT: '' + port }; + const env = { ...process.env, PORT: '' + port, NG_ALLOWED_HOSTS: host ?? 'localhost' }; const args = ['--enable-source-maps', `"${path}"`]; if (inspectMode) { diff --git a/packages/angular_devkit/build_angular/src/builders/ssr-dev-server/specs/proxy_spec.ts b/packages/angular_devkit/build_angular/src/builders/ssr-dev-server/specs/proxy_spec.ts index cbde961e59e4..425aad21dada 100644 --- a/packages/angular_devkit/build_angular/src/builders/ssr-dev-server/specs/proxy_spec.ts +++ b/packages/angular_devkit/build_angular/src/builders/ssr-dev-server/specs/proxy_spec.ts @@ -52,11 +52,12 @@ describe('Serve SSR Builder', () => { })); server.use((req, res, next) => { + const { protocol, originalUrl, baseUrl, headers } = req; commonEngine .render({ bootstrap: AppServerModule, documentFilePath: indexHtml, - url: req.originalUrl, + url: \`\${protocol}://\${headers.host}\${originalUrl}\`, publicPath: distFolder, }) .then((html) => res.send(html)) diff --git a/packages/angular_devkit/build_angular/src/builders/ssr-dev-server/specs/ssl_spec.ts b/packages/angular_devkit/build_angular/src/builders/ssr-dev-server/specs/ssl_spec.ts index 7651b2387c16..e61117812bbe 100644 --- a/packages/angular_devkit/build_angular/src/builders/ssr-dev-server/specs/ssl_spec.ts +++ b/packages/angular_devkit/build_angular/src/builders/ssr-dev-server/specs/ssl_spec.ts @@ -52,11 +52,12 @@ describe('Serve SSR Builder', () => { })); server.use((req, res, next) => { + const { protocol, originalUrl, baseUrl, headers } = req; commonEngine .render({ bootstrap: AppServerModule, documentFilePath: indexHtml, - url: req.originalUrl, + url: \`\${protocol}://\${headers.host}\${originalUrl}\`, publicPath: distFolder, }) .then((html) => res.send(html)) diff --git a/packages/angular_devkit/build_angular/src/builders/ssr-dev-server/specs/works_spec.ts b/packages/angular_devkit/build_angular/src/builders/ssr-dev-server/specs/works_spec.ts index 64c56024f089..c8c70d148e63 100644 --- a/packages/angular_devkit/build_angular/src/builders/ssr-dev-server/specs/works_spec.ts +++ b/packages/angular_devkit/build_angular/src/builders/ssr-dev-server/specs/works_spec.ts @@ -51,11 +51,12 @@ describe('Serve SSR Builder', () => { })); server.use((req, res, next) => { + const { protocol, originalUrl, baseUrl, headers } = req; commonEngine .render({ bootstrap: AppServerModule, documentFilePath: indexHtml, - url: req.originalUrl, + url: \`\${protocol}://\${headers.host}\${originalUrl}\`, publicPath: distFolder, }) .then((html) => res.send(html)) diff --git a/packages/angular_devkit/build_angular/test/hello-world-lib/BUILD.bazel b/packages/angular_devkit/build_angular/test/hello-world-lib/BUILD.bazel deleted file mode 100644 index 0eef93e382cd..000000000000 --- a/packages/angular_devkit/build_angular/test/hello-world-lib/BUILD.bazel +++ /dev/null @@ -1,21 +0,0 @@ -load("@aspect_bazel_lib//lib:copy_to_bin.bzl", "copy_to_bin") -load("@aspect_rules_js//npm:defs.bzl", "npm_link_package") - -# Note: Link the package into node modules for testing. Notably, tests -# of a package generally don't use the associated npm package, to e.g. allow for relative -# imports, but here this is an exception as the package needs to be resolvable at runtime -# to replicate a CLI environment. -npm_link_package( - name = "node_modules/@angular-devkit/build-angular", - src = "//packages/angular_devkit/build_angular:pkg", - package = "@angular-devkit/build-angular", - root_package = package_name(), -) - -copy_to_bin( - name = "hello-world-lib", - srcs = glob(["**/*"]) + [ - ":node_modules/@angular-devkit/build-angular", - ], - visibility = ["//packages/angular_devkit/build_angular:__pkg__"], -) diff --git a/packages/angular_devkit/core/package.json b/packages/angular_devkit/core/package.json index df7555968b65..fe4a5a13032a 100644 --- a/packages/angular_devkit/core/package.json +++ b/packages/angular_devkit/core/package.json @@ -28,7 +28,7 @@ "ajv": "8.18.0", "ajv-formats": "3.0.1", "jsonc-parser": "3.3.1", - "picomatch": "4.0.3", + "picomatch": "4.0.4", "rxjs": "7.8.2", "source-map": "0.7.6" }, diff --git a/packages/angular_devkit/schematics/tasks/repo-init/executor.ts b/packages/angular_devkit/schematics/tasks/repo-init/executor.ts index 97b2b12a3619..607e1bfc5cba 100644 --- a/packages/angular_devkit/schematics/tasks/repo-init/executor.ts +++ b/packages/angular_devkit/schematics/tasks/repo-init/executor.ts @@ -29,7 +29,6 @@ export default function ( const errorStream = ignoreErrorStream ? 'ignore' : process.stderr; const spawnOptions: SpawnOptions = { stdio: [process.stdin, outputStream, errorStream], - shell: true, cwd: path.join(rootDirectory, options.workingDirectory || ''), env: { ...process.env, @@ -41,7 +40,7 @@ export default function ( }; return new Promise((resolve, reject) => { - spawn(`git ${args.join(' ')}`, spawnOptions).on('close', (code: number) => { + spawn('git', args, spawnOptions).on('close', (code: number) => { if (code === 0) { resolve(); } else { @@ -82,7 +81,7 @@ export default function ( if (options.commit) { const message = options.message || 'initial commit'; - await execute(['commit', `-m "${message}"`]); + await execute(['commit', '-m', message]); } context.logger.info('Successfully initialized git.'); diff --git a/packages/angular_devkit/schematics_cli/package.json b/packages/angular_devkit/schematics_cli/package.json index 0b49edc35c55..aa4cc416b7f0 100644 --- a/packages/angular_devkit/schematics_cli/package.json +++ b/packages/angular_devkit/schematics_cli/package.json @@ -4,7 +4,7 @@ "description": "Angular Schematics - CLI", "homepage": "https://github.com/angular/angular-cli", "bin": { - "schematics": "./bin/schematics.js" + "schematics": "bin/schematics.js" }, "keywords": [ "blueprints", diff --git a/packages/angular_devkit/schematics_cli/test/BUILD.bazel b/packages/angular_devkit/schematics_cli/test/BUILD.bazel index 29eb34e8b7ea..b2ab6ee89d12 100644 --- a/packages/angular_devkit/schematics_cli/test/BUILD.bazel +++ b/packages/angular_devkit/schematics_cli/test/BUILD.bazel @@ -17,7 +17,6 @@ npm_link_package( name = "node_modules/@angular-devkit/schematics-cli", src = "//packages/angular_devkit/schematics_cli:pkg", package = "@angular-devkit/schematics-cli", - root_package = package_name(), ) jasmine_test( diff --git a/packages/ngtools/webpack/package.json b/packages/ngtools/webpack/package.json index ef531d078cea..53c41569bd15 100644 --- a/packages/ngtools/webpack/package.json +++ b/packages/ngtools/webpack/package.json @@ -13,7 +13,7 @@ ], "repository": { "type": "git", - "url": "https://github.com/angular/angular-cli.git" + "url": "git+https://github.com/angular/angular-cli.git" }, "author": "angular", "bugs": { @@ -27,8 +27,8 @@ }, "devDependencies": { "@angular-devkit/core": "workspace:0.0.0-PLACEHOLDER", - "@angular/compiler": "21.2.0-next.3", - "@angular/compiler-cli": "21.2.0-next.3", + "@angular/compiler": "21.2.6", + "@angular/compiler-cli": "21.2.6", "typescript": "5.9.3", "webpack": "5.105.2" } diff --git a/packages/schematics/angular/application/files/common-files/src/app/app__suffix__.html.template b/packages/schematics/angular/application/files/common-files/src/app/app__suffix__.html.template index 7d9cf8841c9d..37512bbc01e5 100644 --- a/packages/schematics/angular/application/files/common-files/src/app/app__suffix__.html.template +++ b/packages/schematics/angular/application/files/common-files/src/app/app__suffix__.html.template @@ -42,6 +42,8 @@ box-sizing: border-box; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; + display: block; + height: 100dvh; } h1 { diff --git a/packages/schematics/angular/application/index.ts b/packages/schematics/angular/application/index.ts index e84a40530032..730debc71a8e 100644 --- a/packages/schematics/angular/application/index.ts +++ b/packages/schematics/angular/application/index.ts @@ -187,7 +187,7 @@ function addDependenciesToPackageJson(options: ApplicationOptions): Rule { ); } - if (!options.skipTests) { + if (!options.skipTests && !options.minimal) { rules.push(...addTestRunnerDependencies(options.testRunner, !!options.skipInstall)); } diff --git a/packages/schematics/angular/application/index_spec.ts b/packages/schematics/angular/application/index_spec.ts index 215664398b8e..0fe4d142dc4a 100644 --- a/packages/schematics/angular/application/index_spec.ts +++ b/packages/schematics/angular/application/index_spec.ts @@ -167,6 +167,18 @@ describe('Application Schematic', () => { ); }); + it(`should not add test dependencies with "minimal" enabled`, async () => { + const tree = await schematicRunner.runSchematic( + 'application', + { ...defaultOptions, minimal: true }, + workspaceTree, + ); + + const packageJson = JSON.parse(tree.readContent('package.json')); + expect(packageJson.devDependencies['vitest']).toBeUndefined(); + expect(packageJson.devDependencies['jsdom']).toBeUndefined(); + }); + it('should install npm dependencies when `skipInstall` is false', async () => { await schematicRunner.runSchematic( 'application', diff --git a/packages/schematics/angular/application/schema.json b/packages/schematics/angular/application/schema.json index f047232c23cc..83df1b163873 100644 --- a/packages/schematics/angular/application/schema.json +++ b/packages/schematics/angular/application/schema.json @@ -21,13 +21,13 @@ "x-prompt": "What name would you like to use for the application?" }, "inlineStyle": { - "description": "Include the styles for the root component directly within the `app.component.ts` file. Only CSS styles can be included inline. By default, a separate stylesheet file (e.g., `app.component.css`) is created.", + "description": "Include the styles for the root component directly within the `app.ts` file. Only CSS styles can be included inline. By default, a separate stylesheet file (e.g., `app.css`) is created.", "type": "boolean", "alias": "s", "x-user-analytics": "ep.ng_inline_style" }, "inlineTemplate": { - "description": "Include the HTML template for the root component directly within the `app.component.ts` file. By default, a separate template file (e.g., `app.component.html`) is created.", + "description": "Include the HTML template for the root component directly within the `app.ts` file. By default, a separate template file (e.g., `app.html`) is created.", "type": "boolean", "alias": "t", "x-user-analytics": "ep.ng_inline_template" diff --git a/packages/schematics/angular/ng-new/schema.json b/packages/schematics/angular/ng-new/schema.json index 3bbb0eb3dee4..30957b9342c1 100644 --- a/packages/schematics/angular/ng-new/schema.json +++ b/packages/schematics/angular/ng-new/schema.json @@ -59,13 +59,13 @@ "default": "projects" }, "inlineStyle": { - "description": "Include the styles for the initial application's root component directly within the `app.component.ts` file. By default, a separate stylesheet file (e.g., `app.component.css`) is created.", + "description": "Include the styles for the initial application's root component directly within the `app.ts` file. By default, a separate stylesheet file (e.g., `app.css`) is created.", "type": "boolean", "alias": "s", "x-user-analytics": "ep.ng_inline_style" }, "inlineTemplate": { - "description": "Include the HTML template for the initial application's root component directly within the `app.component.ts` file. By default, a separate template file (e.g., `app.component.html`) is created.", + "description": "Include the HTML template for the initial application's root component directly within the `app.ts` file. By default, a separate template file (e.g., `app.html`) is created.", "type": "boolean", "alias": "t", "x-user-analytics": "ep.ng_inline_template" diff --git a/packages/schematics/angular/ssr/files/server-builder/server.ts.template b/packages/schematics/angular/ssr/files/server-builder/server.ts.template index 7327c26532ea..8d6a9660dfae 100644 --- a/packages/schematics/angular/ssr/files/server-builder/server.ts.template +++ b/packages/schematics/angular/ssr/files/server-builder/server.ts.template @@ -13,7 +13,9 @@ export function app(): express.Express { ? join(distFolder, 'index.original.html') : join(distFolder, 'index.html'); - const commonEngine = new CommonEngine(); + const commonEngine = new CommonEngine({ + allowedHosts: [/* Configure your hosts here */] + }); server.set('view engine', 'html'); server.set('views', distFolder); diff --git a/packages/schematics/angular/ssr/index.ts b/packages/schematics/angular/ssr/index.ts index 6e27eab47cd5..49e57d523268 100644 --- a/packages/schematics/angular/ssr/index.ts +++ b/packages/schematics/angular/ssr/index.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ -import { isJsonObject } from '@angular-devkit/core'; +import { JsonObject, isJsonObject } from '@angular-devkit/core'; import { Rule, RuleFactory, @@ -206,6 +206,10 @@ function updateApplicationBuilderWorkspaceConfigRule( buildTarget.options = { ...buildTarget.options, + security: { + ...((buildTarget.options?.security as JsonObject | undefined) ?? {}), + allowedHosts: [], + }, outputPath, outputMode: 'server', ssr: { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 65a1b3421df4..82eace251863 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,47 +20,47 @@ importers: built: true devDependencies: '@angular/animations': - specifier: 21.2.0-next.3 - version: 21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0)) + specifier: 21.2.6 + version: 21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1)) '@angular/cdk': - specifier: 21.2.0-next.4 - version: 21.2.0-next.4(@angular/common@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(rxjs@7.8.2))(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(@angular/platform-browser@21.2.0-next.3(@angular/animations@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0)))(@angular/common@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(rxjs@7.8.2))(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0)))(rxjs@7.8.2) + specifier: 21.2.4 + version: 21.2.4(@angular/common@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(@angular/platform-browser@21.2.6(@angular/animations@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1)))(@angular/common@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1)))(rxjs@7.8.2) '@angular/common': - specifier: 21.2.0-next.3 - version: 21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(rxjs@7.8.2) + specifier: 21.2.6 + version: 21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2) '@angular/compiler': - specifier: 21.2.0-next.3 - version: 21.2.0-next.3 + specifier: 21.2.6 + version: 21.2.6 '@angular/compiler-cli': - specifier: 21.2.0-next.3 - version: 21.2.0-next.3(@angular/compiler@21.2.0-next.3)(typescript@5.9.3) + specifier: 21.2.6 + version: 21.2.6(@angular/compiler@21.2.6)(typescript@5.9.3) '@angular/core': - specifier: 21.2.0-next.3 - version: 21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0) + specifier: 21.2.6 + version: 21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1) '@angular/forms': - specifier: 21.2.0-next.3 - version: 21.2.0-next.3(@angular/common@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(rxjs@7.8.2))(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(@angular/platform-browser@21.2.0-next.3(@angular/animations@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0)))(@angular/common@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(rxjs@7.8.2))(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0)))(rxjs@7.8.2) + specifier: 21.2.6 + version: 21.2.6(@angular/common@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(@angular/platform-browser@21.2.6(@angular/animations@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1)))(@angular/common@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1)))(rxjs@7.8.2) '@angular/localize': - specifier: 21.2.0-next.3 - version: 21.2.0-next.3(@angular/compiler-cli@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(typescript@5.9.3))(@angular/compiler@21.2.0-next.3) + specifier: 21.2.6 + version: 21.2.6(@angular/compiler-cli@21.2.6(@angular/compiler@21.2.6)(typescript@5.9.3))(@angular/compiler@21.2.6) '@angular/material': - specifier: 21.2.0-next.4 - version: 21.2.0-next.4(75d10325bbcfc22e53b1e47f427450d8) + specifier: 21.2.4 + version: 21.2.4(2045f7bd5f6e95e11cc97fff9a766245) '@angular/ng-dev': - specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#2a5e8e5b5398ae13a8d9a963ac980707313a6c9e - version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/2a5e8e5b5398ae13a8d9a963ac980707313a6c9e(@modelcontextprotocol/sdk@1.26.0(zod@4.3.6)) + specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#cdbe118e59f59b1ee00ff77a5ccf8c5328248d03 + version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/cdbe118e59f59b1ee00ff77a5ccf8c5328248d03(@modelcontextprotocol/sdk@1.26.0(zod@4.3.6)) '@angular/platform-browser': - specifier: 21.2.0-next.3 - version: 21.2.0-next.3(@angular/animations@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0)))(@angular/common@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(rxjs@7.8.2))(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0)) + specifier: 21.2.6 + version: 21.2.6(@angular/animations@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1)))(@angular/common@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1)) '@angular/platform-server': - specifier: 21.2.0-next.3 - version: 21.2.0-next.3(@angular/common@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(rxjs@7.8.2))(@angular/compiler@21.2.0-next.3)(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(@angular/platform-browser@21.2.0-next.3(@angular/animations@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0)))(@angular/common@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(rxjs@7.8.2))(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0)))(rxjs@7.8.2) + specifier: 21.2.6 + version: 21.2.6(@angular/common@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/compiler@21.2.6)(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(@angular/platform-browser@21.2.6(@angular/animations@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1)))(@angular/common@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1)))(rxjs@7.8.2) '@angular/router': - specifier: 21.2.0-next.3 - version: 21.2.0-next.3(@angular/common@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(rxjs@7.8.2))(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(@angular/platform-browser@21.2.0-next.3(@angular/animations@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0)))(@angular/common@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(rxjs@7.8.2))(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0)))(rxjs@7.8.2) + specifier: 21.2.6 + version: 21.2.6(@angular/common@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(@angular/platform-browser@21.2.6(@angular/animations@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1)))(@angular/common@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1)))(rxjs@7.8.2) '@angular/service-worker': - specifier: 21.2.0-next.3 - version: 21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(rxjs@7.8.2) + specifier: 21.2.6 + version: 21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2) '@babel/core': specifier: 7.29.0 version: 7.29.0 @@ -84,16 +84,19 @@ importers: version: 6.0.0(rollup@4.57.1) '@rollup/plugin-commonjs': specifier: ^29.0.0 - version: 29.0.0(rollup@4.57.1) + version: 29.0.2(rollup@4.57.1) '@rollup/plugin-json': specifier: ^6.1.0 version: 6.1.0(rollup@4.57.1) '@rollup/plugin-node-resolve': specifier: 16.0.3 version: 16.0.3(rollup@4.57.1) + '@rollup/wasm-node': + specifier: 4.59.0 + version: 4.59.0 '@stylistic/eslint-plugin': specifier: ^5.0.0 - version: 5.8.0(eslint@9.39.2(jiti@2.6.1)) + version: 5.10.0(eslint@9.39.2(jiti@2.6.1)) '@types/babel__core': specifier: 7.20.5 version: 7.20.5 @@ -129,10 +132,10 @@ importers: version: 3.0.0(esbuild@0.27.3) '@types/lodash': specifier: ^4.17.0 - version: 4.17.23 + version: 4.17.24 '@types/node': specifier: ^22.12.0 - version: 22.19.11 + version: 22.19.15 '@types/npm-package-arg': specifier: ^6.1.0 version: 6.1.4 @@ -267,7 +270,7 @@ importers: version: 6.3.0(rollup@4.57.1)(typescript@5.9.3) rollup-plugin-sourcemaps2: specifier: 0.5.4 - version: 0.5.4(@types/node@22.19.11)(rollup@4.57.1) + version: 0.5.4(@types/node@22.19.15)(rollup@4.57.1) semver: specifier: 7.7.4 version: 7.7.4 @@ -276,7 +279,7 @@ importers: version: 0.5.21 ts-node: specifier: ^10.9.1 - version: 10.9.2(@types/node@22.19.11)(typescript@5.9.3) + version: 10.9.2(@types/node@22.19.15)(typescript@5.9.3) tslib: specifier: 2.8.1 version: 2.8.1 @@ -284,20 +287,20 @@ importers: specifier: 5.9.3 version: 5.9.3 undici: - specifier: 7.22.0 - version: 7.22.0 + specifier: 7.24.4 + version: 7.24.4 unenv: specifier: ^1.10.0 version: 1.10.0 verdaccio: - specifier: 6.2.5 - version: 6.2.5(encoding@0.1.13) + specifier: 6.2.9 + version: 6.2.9(encoding@0.1.13) verdaccio-auth-memory: specifier: ^10.0.0 version: 10.3.1 zone.js: specifier: ^0.16.0 - version: 0.16.0 + version: 0.16.1 modules/testing/builder: devDependencies: @@ -315,19 +318,22 @@ importers: version: link:../../../packages/angular/ssr '@vitest/coverage-v8': specifier: 4.0.18 - version: 4.0.18(vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@24.10.9)(jiti@2.6.1)(jsdom@28.1.0)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + version: 4.0.18(vitest@4.0.18(@opentelemetry/api@1.9.1)(@types/node@24.12.0)(jiti@2.6.1)(jsdom@28.1.0)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.3)) browser-sync: specifier: 3.0.4 version: 3.0.4(bufferutil@4.1.0)(utf-8-validate@6.0.6) jsdom: specifier: 28.1.0 version: 28.1.0 + ng-packagr: + specifier: 22.0.0-next.1 + version: 22.0.0-next.1(@angular/compiler-cli@21.2.6(@angular/compiler@21.2.6)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3) rxjs: specifier: 7.8.2 version: 7.8.2 vitest: specifier: 4.0.18 - version: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@24.10.9)(jiti@2.6.1)(jsdom@28.1.0)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + version: 4.0.18(@opentelemetry/api@1.9.1)(@types/node@24.12.0)(jiti@2.6.1)(jsdom@28.1.0)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.3) packages/angular/build: dependencies: @@ -348,10 +354,10 @@ importers: version: 7.24.7 '@inquirer/confirm': specifier: 5.1.21 - version: 5.1.21(@types/node@24.10.9) + version: 5.1.21(@types/node@24.12.0) '@vitejs/plugin-basic-ssl': specifier: 2.1.4 - version: 2.1.4(vite@7.3.1(@types/node@24.10.9)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + version: 2.1.4(vite@7.3.1(@types/node@24.12.0)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.3)) beasties: specifier: 0.4.1 version: 0.4.1 @@ -383,8 +389,8 @@ importers: specifier: 8.0.0 version: 8.0.0 picomatch: - specifier: 4.0.3 - version: 4.0.3 + specifier: 4.0.4 + version: 4.0.4 piscina: specifier: 5.1.4 version: 5.1.4 @@ -404,11 +410,11 @@ importers: specifier: 0.2.15 version: 0.2.15 undici: - specifier: 7.22.0 - version: 7.22.0 + specifier: 7.24.4 + version: 7.24.4 vite: specifier: 7.3.1 - version: 7.3.1(@types/node@24.10.9)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + version: 7.3.1(@types/node@24.12.0)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.3) watchpack: specifier: 2.5.1 version: 2.5.1 @@ -426,8 +432,8 @@ importers: specifier: 4.4.2 version: 4.4.2 ng-packagr: - specifier: 21.2.0-next.0 - version: 21.2.0-next.0(@angular/compiler-cli@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3) + specifier: 21.2.2 + version: 21.2.2(@angular/compiler-cli@21.2.6(@angular/compiler@21.2.6)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3) postcss: specifier: 8.5.6 version: 8.5.6 @@ -436,7 +442,7 @@ importers: version: 7.8.2 vitest: specifier: 4.0.18 - version: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@24.10.9)(jiti@2.6.1)(jsdom@28.1.0)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + version: 4.0.18(@opentelemetry/api@1.9.1)(@types/node@24.12.0)(jiti@2.6.1)(jsdom@28.1.0)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.3) optionalDependencies: lmdb: specifier: 3.5.1 @@ -455,10 +461,10 @@ importers: version: link:../../angular_devkit/schematics '@inquirer/prompts': specifier: 7.10.1 - version: 7.10.1(@types/node@24.10.9) + version: 7.10.1(@types/node@24.12.0) '@listr2/prompt-adapter-inquirer': specifier: 3.0.5 - version: 3.0.5(@inquirer/prompts@7.10.1(@types/node@24.10.9))(@types/node@24.10.9)(listr2@9.0.5) + version: 3.0.5(@inquirer/prompts@7.10.1(@types/node@24.12.0))(@types/node@24.12.0)(listr2@9.0.5) '@modelcontextprotocol/sdk': specifier: 1.26.0 version: 1.26.0(zod@4.3.6) @@ -521,23 +527,23 @@ importers: specifier: workspace:* version: link:../../angular_devkit/schematics '@angular/common': - specifier: 21.2.0-next.3 - version: 21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(rxjs@7.8.2) + specifier: 21.2.6 + version: 21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2) '@angular/compiler': - specifier: 21.2.0-next.3 - version: 21.2.0-next.3 + specifier: 21.2.6 + version: 21.2.6 '@angular/core': - specifier: 21.2.0-next.3 - version: 21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0) + specifier: 21.2.6 + version: 21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1) '@angular/platform-browser': - specifier: 21.2.0-next.3 - version: 21.2.0-next.3(@angular/animations@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0)))(@angular/common@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(rxjs@7.8.2))(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0)) + specifier: 21.2.6 + version: 21.2.6(@angular/animations@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1)))(@angular/common@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1)) '@angular/platform-server': - specifier: 21.2.0-next.3 - version: 21.2.0-next.3(@angular/common@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(rxjs@7.8.2))(@angular/compiler@21.2.0-next.3)(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(@angular/platform-browser@21.2.0-next.3(@angular/animations@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0)))(@angular/common@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(rxjs@7.8.2))(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0)))(rxjs@7.8.2) + specifier: 21.2.6 + version: 21.2.6(@angular/common@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/compiler@21.2.6)(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(@angular/platform-browser@21.2.6(@angular/animations@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1)))(@angular/common@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1)))(rxjs@7.8.2) '@angular/router': - specifier: 21.2.0-next.3 - version: 21.2.0-next.3(@angular/common@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(rxjs@7.8.2))(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(@angular/platform-browser@21.2.0-next.3(@angular/animations@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0)))(@angular/common@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(rxjs@7.8.2))(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0)))(rxjs@7.8.2) + specifier: 21.2.6 + version: 21.2.6(@angular/common@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(@angular/platform-browser@21.2.6(@angular/animations@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1)))(@angular/common@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1)))(rxjs@7.8.2) '@schematics/angular': specifier: workspace:* version: link:../../schematics/angular @@ -614,8 +620,8 @@ importers: specifier: 4.1.3 version: 4.1.3 autoprefixer: - specifier: 10.4.24 - version: 10.4.24(postcss@8.5.6) + specifier: 10.4.27 + version: 10.4.27(postcss@8.5.6) babel-loader: specifier: 10.0.0 version: 10.0.0(@babel/core@7.29.0)(webpack@5.105.2(esbuild@0.27.3)) @@ -623,8 +629,8 @@ importers: specifier: ^4.26.0 version: 4.28.1 copy-webpack-plugin: - specifier: 13.0.1 - version: 13.0.1(webpack@5.105.2(esbuild@0.27.3)) + specifier: 14.0.0 + version: 14.0.0(webpack@5.105.2(esbuild@0.27.3)) css-loader: specifier: 7.1.3 version: 7.1.3(webpack@5.105.2(esbuild@0.27.3)) @@ -665,8 +671,8 @@ importers: specifier: 9.3.0 version: 9.3.0 picomatch: - specifier: 4.0.3 - version: 4.0.3 + specifier: 4.0.4 + version: 4.0.4 piscina: specifier: 5.1.4 version: 5.1.4 @@ -735,11 +741,11 @@ importers: specifier: 3.0.4 version: 3.0.4(bufferutil@4.1.0)(utf-8-validate@6.0.6) ng-packagr: - specifier: 21.2.0-next.0 - version: 21.2.0-next.0(@angular/compiler-cli@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3) + specifier: 21.2.2 + version: 21.2.2(@angular/compiler-cli@21.2.6(@angular/compiler@21.2.6)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3) undici: - specifier: 7.22.0 - version: 7.22.0 + specifier: 7.24.4 + version: 7.24.4 optionalDependencies: esbuild: specifier: 0.27.3 @@ -779,8 +785,8 @@ importers: specifier: 3.3.1 version: 3.3.1 picomatch: - specifier: 4.0.3 - version: 4.0.3 + specifier: 4.0.4 + version: 4.0.4 rxjs: specifier: 7.8.2 version: 7.8.2 @@ -820,7 +826,7 @@ importers: version: link:../schematics '@inquirer/prompts': specifier: 7.10.1 - version: 7.10.1(@types/node@24.10.9) + version: 7.10.1(@types/node@24.12.0) packages/ngtools/webpack: devDependencies: @@ -828,11 +834,11 @@ importers: specifier: workspace:0.0.0-PLACEHOLDER version: link:../../angular_devkit/core '@angular/compiler': - specifier: 21.2.0-next.3 - version: 21.2.0-next.3 + specifier: 21.2.6 + version: 21.2.6 '@angular/compiler-cli': - specifier: 21.2.0-next.3 - version: 21.2.0-next.3(@angular/compiler@21.2.0-next.3)(typescript@5.9.3) + specifier: 21.2.6 + version: 21.2.6(@angular/compiler@21.2.6)(typescript@5.9.3) typescript: specifier: 5.9.3 version: 5.9.3 @@ -944,47 +950,47 @@ packages: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} - '@angular/animations@21.2.0-next.3': - resolution: {integrity: sha512-DTiRWm2aBlX+uVS1K3PnEbJZ4SQbWBPTl898lUYJ79WArPaHoTtrBurZ5zcGA6R5OyBfAvv3MvU0qZtihFIMoA==} + '@angular/animations@21.2.6': + resolution: {integrity: sha512-SPzTOlkyVagPdb7OMe9hw3dnpMGq2p/nADatzNfRUMXwit8AU8VaiPIrFRsCD52sAL1zDDj60gKsk/dprzIyFA==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} peerDependencies: - '@angular/core': 21.2.0-next.3 + '@angular/core': 21.2.6 - '@angular/cdk@21.2.0-next.4': - resolution: {integrity: sha512-GbcDW+qeSV4QlPQojGh5jCPATGfClCYnZhEGLXfabfEy/uhKGehILW37FK4VRhLdZKW9nMTs7w436jaovh84/A==} + '@angular/cdk@21.2.4': + resolution: {integrity: sha512-Zv+q9Z/wVWTt0ckuO3gnU7PbpCLTr1tKPEsofLGGzDufA5/85aBLn2UiLcjlY6wQ+V3EMqANhGo/8XJgvBEYFA==} peerDependencies: - '@angular/common': ^21.0.0-0 || ^21.1.0-0 || ^21.2.0-0 || ^21.3.0-0 || ^22.0.0-0 - '@angular/core': ^21.0.0-0 || ^21.1.0-0 || ^21.2.0-0 || ^21.3.0-0 || ^22.0.0-0 - '@angular/platform-browser': ^21.0.0-0 || ^21.1.0-0 || ^21.2.0-0 || ^21.3.0-0 || ^22.0.0-0 + '@angular/common': ^21.0.0 || ^22.0.0 + '@angular/core': ^21.0.0 || ^22.0.0 + '@angular/platform-browser': ^21.0.0 || ^22.0.0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/common@21.2.0-next.3': - resolution: {integrity: sha512-7Mfsk/ahcKqvPFW1e9IMnfyvsyGKARIORdVxI8r/05N+Bt1aeW6iZbteEqM2cCEFZ4UqWjkaqdlBZndevqfqsA==} + '@angular/common@21.2.6': + resolution: {integrity: sha512-2FcpZ1h6AZ4JwCIlnpHCYrbRTGQTOj/RFXkuX/qw7K6cFmJGfWFMmr++xWtHZEvUddfbR9hqDo+v1mkqEKE/Kw==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} peerDependencies: - '@angular/core': 21.2.0-next.3 + '@angular/core': 21.2.6 rxjs: ^6.5.3 || ^7.4.0 - '@angular/compiler-cli@21.2.0-next.3': - resolution: {integrity: sha512-q3OUWuK/mspdxRfPQq2RPnGosq7yYzWzK+FikEYHv9I2pPTqt1cXWArWzknLouxs2zVaRhpaqXreCGtBeicYwg==} + '@angular/compiler-cli@21.2.6': + resolution: {integrity: sha512-CiPmat4+D+hWXMTAY++09WeII/5D0r6iTjdLdaTq8tlo0uJcrOlazib4CpA94kJ2CRdzfhmC1H+ttwBI1xIlTg==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} hasBin: true peerDependencies: - '@angular/compiler': 21.2.0-next.3 - typescript: '>=5.9 <6.0' + '@angular/compiler': 21.2.6 + typescript: '>=5.9 <6.1' peerDependenciesMeta: typescript: optional: true - '@angular/compiler@21.2.0-next.3': - resolution: {integrity: sha512-vMNEt+qFt4+k7lGoalHqmxgB6XiEWUTG7UaT9BkcU5Ezs64RLfkLVSGd0MNAuE2RL1gOa0/wvIl11yv0pD2T7g==} + '@angular/compiler@21.2.6': + resolution: {integrity: sha512-shGkb/aAIPbG8oSYkVJ0msGlRdDVcJBVaUVx2KenMltifQjfLn5N8DFMAzOR6haaA3XeugFExxKqmvySjrVq+A==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} - '@angular/core@21.2.0-next.3': - resolution: {integrity: sha512-9cieyRQ3DIWANEQ1DfjOuZS8EdzcPzaikO1Vi81hNmsr7an8yok0oRXfonkkudFUtAE0Xl6B1wYyD4FZ3ig47g==} + '@angular/core@21.2.6': + resolution: {integrity: sha512-svgK5DhFlQlS+sMybXftn08rHHRiDGY/uIKT5LZUaKgyffnkPb8uClpMIW0NzANtU8qs8pwgDZFoJw85Ia3oqQ==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} peerDependencies: - '@angular/compiler': 21.2.0-next.3 + '@angular/compiler': 21.2.6 rxjs: ^6.5.3 || ^7.4.0 zone.js: ~0.15.0 || ~0.16.0 peerDependenciesMeta: @@ -993,78 +999,79 @@ packages: zone.js: optional: true - '@angular/forms@21.2.0-next.3': - resolution: {integrity: sha512-YHrLsKO1fozXw0jptI3kwCc5w13DRQzf/Q8ajmtu+o2oy1NjYuoPlRyTBuIufThYKgBqC2ZfWOCWkOa8gyyKQA==} + '@angular/forms@21.2.6': + resolution: {integrity: sha512-i8BoWxBAm0g2xOMcQ8wTdj07gqMPIFYIyefCOo0ezcGj5XhYjd+C2UrYnKsup0aMZqqEAO1l2aZbmfHx9xLheQ==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} peerDependencies: - '@angular/common': 21.2.0-next.3 - '@angular/core': 21.2.0-next.3 - '@angular/platform-browser': 21.2.0-next.3 + '@angular/common': 21.2.6 + '@angular/core': 21.2.6 + '@angular/platform-browser': 21.2.6 rxjs: ^6.5.3 || ^7.4.0 - '@angular/localize@21.2.0-next.3': - resolution: {integrity: sha512-348iYNZ5PrnjxiSVuPE9XomIWrZNYOPPDq/3VVVTl/f9G+iwmHGfCJ1GsGxwg31DRu3X6ZFKw4IBqUyfLJaJiQ==} + '@angular/localize@21.2.6': + resolution: {integrity: sha512-+nScGHruNCUiGz9nbNyFLO0Wg5dGZt+PBH/9wvzCxe1A+VhyiRSNCTD9hjcjsjtK3WPTRPd+Vo1s2URn+fgD4A==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} hasBin: true peerDependencies: - '@angular/compiler': 21.2.0-next.3 - '@angular/compiler-cli': 21.2.0-next.3 + '@angular/compiler': 21.2.6 + '@angular/compiler-cli': 21.2.6 - '@angular/material@21.2.0-next.4': - resolution: {integrity: sha512-mUNP2z/FehBfmdDtQNznXO/jjOm7FPCc0DBqdXsTgIyeHqf9UitwC6huBzSmzN8Kq/v/ftDp04Ph+Jjbp/6VaA==} + '@angular/material@21.2.4': + resolution: {integrity: sha512-YzkPjgZezdsDeAhSm3zix2h+ohApwaRUMG8ea/75XR1eSkT1n3N7qZaHC8HDkhPYApk8a951RDxsTiiAidnGqg==} peerDependencies: - '@angular/cdk': 21.2.0-next.4 - '@angular/common': ^21.0.0-0 || ^21.1.0-0 || ^21.2.0-0 || ^21.3.0-0 || ^22.0.0-0 - '@angular/core': ^21.0.0-0 || ^21.1.0-0 || ^21.2.0-0 || ^21.3.0-0 || ^22.0.0-0 - '@angular/forms': ^21.0.0-0 || ^21.1.0-0 || ^21.2.0-0 || ^21.3.0-0 || ^22.0.0-0 - '@angular/platform-browser': ^21.0.0-0 || ^21.1.0-0 || ^21.2.0-0 || ^21.3.0-0 || ^22.0.0-0 + '@angular/cdk': 21.2.4 + '@angular/common': ^21.0.0 || ^22.0.0 + '@angular/core': ^21.0.0 || ^22.0.0 + '@angular/forms': ^21.0.0 || ^22.0.0 + '@angular/platform-browser': ^21.0.0 || ^22.0.0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/2a5e8e5b5398ae13a8d9a963ac980707313a6c9e': - resolution: {tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/2a5e8e5b5398ae13a8d9a963ac980707313a6c9e} - version: 0.0.0-469708f109a90884ca403d150d33079a3a5a8769 + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/cdbe118e59f59b1ee00ff77a5ccf8c5328248d03': + resolution: {tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/cdbe118e59f59b1ee00ff77a5ccf8c5328248d03} + version: 0.0.0-d69b99aeae90df28c37c57176a69995b3b60df1b hasBin: true - '@angular/platform-browser@21.2.0-next.3': - resolution: {integrity: sha512-YsKkQaZ4jPs/xicQ9baJ0hlSLfKfsBsXrwNBw7XjvnyinU8tlB707KZ0eThyx9FSoLeBO2FgrWM75NTiEd2Rvg==} + '@angular/platform-browser@21.2.6': + resolution: {integrity: sha512-LW1vPXVHvy71LBahn+fSzPlWQl25kJIdcXq+ptG7HsMVgbPQ3/vvkKXAHYaRdppLGCFL+v+3dQGHYLNLiYL9qg==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} peerDependencies: - '@angular/animations': 21.2.0-next.3 - '@angular/common': 21.2.0-next.3 - '@angular/core': 21.2.0-next.3 + '@angular/animations': 21.2.6 + '@angular/common': 21.2.6 + '@angular/core': 21.2.6 peerDependenciesMeta: '@angular/animations': optional: true - '@angular/platform-server@21.2.0-next.3': - resolution: {integrity: sha512-ETjC41XcL0m19hONZebrGNKqOTFqtuz2qP6I5g4JKS6jDJ5aLx9ERtcq+ALnuEmPICcR7rbGzMigM2WTDTdZ0A==} + '@angular/platform-server@21.2.6': + resolution: {integrity: sha512-IatXqKzRRT8H1UolijS3Lv3SgthH5w3qHe5ZpQADYi9NIaIvtVMnDH3kIxWGhepjMtvUz235J3E6FrPer6mNZA==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} peerDependencies: - '@angular/common': 21.2.0-next.3 - '@angular/compiler': 21.2.0-next.3 - '@angular/core': 21.2.0-next.3 - '@angular/platform-browser': 21.2.0-next.3 + '@angular/common': 21.2.6 + '@angular/compiler': 21.2.6 + '@angular/core': 21.2.6 + '@angular/platform-browser': 21.2.6 rxjs: ^6.5.3 || ^7.4.0 - '@angular/router@21.2.0-next.3': - resolution: {integrity: sha512-NHokfVBqk8Elei9AtWreWdrm6oThwCbJZEbi3MqKJBEKCo33BEtZuv3QrwrbpNb+Pnm5RJVYMK4Z0sXvt/qohg==} + '@angular/router@21.2.6': + resolution: {integrity: sha512-0ajhkKYeOqHQEEH88+Q0HrheR3helwTvdTqD/0gTaapCe+HOoC+SYwmzzsYP2zwAxBNQEg4JHOGKQ30X9/gwgw==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} peerDependencies: - '@angular/common': 21.2.0-next.3 - '@angular/core': 21.2.0-next.3 - '@angular/platform-browser': 21.2.0-next.3 + '@angular/common': 21.2.6 + '@angular/core': 21.2.6 + '@angular/platform-browser': 21.2.6 rxjs: ^6.5.3 || ^7.4.0 - '@angular/service-worker@21.2.0-next.3': - resolution: {integrity: sha512-52Z2plR7926tBS/2nCIYLLXuXcwZ1ByJeoMHXfMXNEx4uM0vbMlcALqkCB/pvrehCtqLlT/8Ec0paHk/uE0jcw==} + '@angular/service-worker@21.2.6': + resolution: {integrity: sha512-RSFspGPBCDU1fEPTTRXarF6vszYEh+d8DXA/o6Bdo4U3+bFCEjekfe2PjHHA2hTaagxR7Ow44gcYWxR7RnNjrA==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} hasBin: true peerDependencies: - '@angular/core': 21.2.0-next.3 + '@angular/core': 21.2.6 rxjs: ^6.5.3 || ^7.4.0 - '@asamuzakjp/css-color@4.1.2': - resolution: {integrity: sha512-NfBUvBaYgKIuq6E/RBLY1m0IohzNHAYyaJGuTK79Z23uNwmz2jl1mPsC5ZxCCxylinKhT1Amn5oNTlx1wN8cQg==} + '@asamuzakjp/css-color@5.1.1': + resolution: {integrity: sha512-iGWN8E45Ws0XWx3D44Q1t6vX2LqhCKcwfmwBYCDsFrYFS6m4q/Ks61L2veETaLv+ckDC6+dTETJoaAAb7VjLiw==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} '@asamuzakjp/dom-selector@6.8.1': resolution: {integrity: sha512-MvRz1nCqW0fsy8Qz4dnLIvhOlMzqDVBabZx6lH+YywFDdjXhMY37SmpV1XFX3JzG5GWHn63j6HX6QPr3lZXHvQ==} @@ -1108,8 +1115,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-define-polyfill-provider@0.6.6': - resolution: {integrity: sha512-mOAsxeeKkUKayvZR3HeTYD/fICpCPLJrU5ZjelT/PA6WHtNDBOE436YiaEUvHN454bRM3CebhDsIpieCc4texA==} + '@babel/helper-define-polyfill-provider@0.6.8': + resolution: {integrity: sha512-47UwBLPpQi1NoWzLuHNjRoHlYXMwIJoBf7MFou6viC/sIHWYygpvr0B6IAyh5sBdA2nr2LPIRww8lfaUVQINBA==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 @@ -1175,12 +1182,12 @@ packages: resolution: {integrity: sha512-z+PwLziMNBeSQJonizz2AGnndLsP2DeGHIxDAn+wdHOGuo4Fo1x1HBPPXeE9TAOPHNNWQKCSlA2VZyYyyibDnQ==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.28.6': - resolution: {integrity: sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==} + '@babel/helpers@7.29.2': + resolution: {integrity: sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==} engines: {node: '>=6.9.0'} - '@babel/parser@7.29.0': - resolution: {integrity: sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==} + '@babel/parser@7.29.2': + resolution: {integrity: sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==} engines: {node: '>=6.0.0'} hasBin: true @@ -1597,12 +1604,12 @@ packages: resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} engines: {node: '>=0.1.90'} - '@conventional-changelog/git-client@1.0.1': - resolution: {integrity: sha512-PJEqBwAleffCMETaVm/fUgHldzBE35JFk3/9LL6NUA5EXa3qednu+UT6M7E5iBu3zIQZCULYIiZ90fBYHt6xUw==} + '@conventional-changelog/git-client@2.6.0': + resolution: {integrity: sha512-T+uPDciKf0/ioNNDpMGc8FDsehJClZP0yR3Q5MN6wE/Y/1QZ7F+80OgznnTCOlMEG4AV0LvH2UJi3C/nBnaBUg==} engines: {node: '>=18'} peerDependencies: conventional-commits-filter: ^5.0.0 - conventional-commits-parser: ^6.0.0 + conventional-commits-parser: ^6.3.0 peerDependenciesMeta: conventional-commits-filter: optional: true @@ -1613,8 +1620,8 @@ packages: resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} - '@csstools/color-helpers@6.0.1': - resolution: {integrity: sha512-NmXRccUJMk2AWA5A7e5a//3bCIMyOu2hAtdRYrhPPHjDxINuCwX1w6rnIZ4xjLcp0ayv6h8Pc3X0eJUGiAAXHQ==} + '@csstools/color-helpers@6.0.2': + resolution: {integrity: sha512-LMGQLS9EuADloEFkcTBR3BwV/CGHV7zyDxVRtVDTwdI2Ca4it0CCVTT9wCkxSgokjE5Ho41hEPgb8OEUwoXr6Q==} engines: {node: '>=20.19.0'} '@csstools/css-calc@3.1.1': @@ -1624,8 +1631,8 @@ packages: '@csstools/css-parser-algorithms': ^4.0.0 '@csstools/css-tokenizer': ^4.0.0 - '@csstools/css-color-parser@4.0.1': - resolution: {integrity: sha512-vYwO15eRBEkeF6xjAno/KQ61HacNhfQuuU/eGwH67DplL0zD5ZixUa563phQvUelA07yDczIXdtmYojCphKJcw==} + '@csstools/css-color-parser@4.0.2': + resolution: {integrity: sha512-0GEfbBLmTFf0dJlpsNU7zwxRIH0/BGEMuXLTCvFYxuL1tNhqzTbtnFICyJLTNK4a+RechKP75e7w42ClXSnJQw==} engines: {node: '>=20.19.0'} peerDependencies: '@csstools/css-parser-algorithms': ^4.0.0 @@ -1637,30 +1644,26 @@ packages: peerDependencies: '@csstools/css-tokenizer': ^4.0.0 - '@csstools/css-syntax-patches-for-csstree@1.0.27': - resolution: {integrity: sha512-sxP33Jwg1bviSUXAV43cVYdmjt2TLnLXNqCWl9xmxHawWVjGz/kEbdkr7F9pxJNBN2Mh+dq0crgItbW6tQvyow==} + '@csstools/css-syntax-patches-for-csstree@1.1.2': + resolution: {integrity: sha512-5GkLzz4prTIpoyeUiIu3iV6CSG3Plo7xRVOFPKI7FVEJ3mZ0A8SwK0XU3Gl7xAkiQ+mDyam+NNp875/C5y+jSA==} + peerDependencies: + css-tree: ^3.2.1 + peerDependenciesMeta: + css-tree: + optional: true '@csstools/css-tokenizer@4.0.0': resolution: {integrity: sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==} engines: {node: '>=20.19.0'} - '@cypress/request@3.0.9': - resolution: {integrity: sha512-I3l7FdGRXluAS44/0NguwWlO83J18p0vlr2FYHrJkWdNYhgVoiYo61IXPqaOsL+vNxU1ZqMACzItGK3/KKDsdw==} + '@cypress/request@3.0.10': + resolution: {integrity: sha512-hauBrOdvu08vOsagkZ/Aju5XuiZx6ldsLfByg1htFeldhex+PeMrYauANzFsMJeAA0+dyPLbDoX2OYuvVoLDkQ==} engines: {node: '>= 6'} '@discoveryjs/json-ext@0.6.3': resolution: {integrity: sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ==} engines: {node: '>=14.17.0'} - '@emnapi/core@1.8.1': - resolution: {integrity: sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==} - - '@emnapi/runtime@1.8.1': - resolution: {integrity: sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==} - - '@emnapi/wasi-threads@1.1.0': - resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} - '@esbuild/aix-ppc64@0.27.3': resolution: {integrity: sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==} engines: {node: '>=18'} @@ -1836,8 +1839,8 @@ packages: eslint: optional: true - '@eslint/config-array@0.21.1': - resolution: {integrity: sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==} + '@eslint/config-array@0.21.2': + resolution: {integrity: sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/config-helpers@0.4.2': @@ -1848,8 +1851,8 @@ packages: resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/core@1.1.0': - resolution: {integrity: sha512-/nr9K9wkr3P1EzFTdFdMoLuo1PmIxjmwvPozwoSodjNBdefGujXQUF93u1DDZpEaTuDvMsIQddsd35BwtrW9Xw==} + '@eslint/core@1.1.1': + resolution: {integrity: sha512-QUPblTtE51/7/Zhfv8BDwO0qkkzQL7P/aWWbqcf4xWLEYn1oKjdO0gglQBB4GAsu7u6wjijbCmzsUTy6mnk6oQ==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} '@eslint/eslintrc@3.3.3': @@ -1868,8 +1871,8 @@ packages: resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@exodus/bytes@1.14.1': - resolution: {integrity: sha512-OhkBFWI6GcRMUroChZiopRiSp2iAMvEBK47NhJooDqz1RERO4QuZIZnjP63TXX8GAiLABkYmX+fuQsdJ1dd2QQ==} + '@exodus/bytes@1.15.0': + resolution: {integrity: sha512-UY0nlA+feH81UGSHv92sLEPLCeZFjXOuHhrIo0HQydScuQc8s0A7kL/UdgwgDq8g8ilksmuoF35YVTNphV2aBQ==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} peerDependencies: '@noble/hashes': ^1.8.0 || ^2.0.0 @@ -1877,28 +1880,28 @@ packages: '@noble/hashes': optional: true - '@firebase/ai@2.7.0': - resolution: {integrity: sha512-PwpCz+TtAMWICM7uQNO0mkSPpUKwrMV4NSwHkbVKDvPKoaQmSlO96vIz+Suw2Ao1EaUUsxYb5LGImHWt/fSnRQ==} + '@firebase/ai@2.10.0': + resolution: {integrity: sha512-1lI6HomyoO/8RSJb6ItyHLpHnB2z27m5F4aX/Vpi1nhwWoxdNjkq+6UQOykHyCE0KairojOE5qQ20i1tnF0nNA==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x '@firebase/app-types': 0.x - '@firebase/analytics-compat@0.2.25': - resolution: {integrity: sha512-fdzoaG0BEKbqksRDhmf4JoyZf16Wosrl0Y7tbZtJyVDOOwziE0vrFjmZuTdviL0yhak+Nco6rMsUUbkbD+qb6Q==} + '@firebase/analytics-compat@0.2.27': + resolution: {integrity: sha512-ZObpYpAxL6JfgH7GnvlDD0sbzGZ0o4nijV8skatV9ZX49hJtCYbFqaEcPYptT94rgX1KUoKEderC7/fa7hybtw==} peerDependencies: '@firebase/app-compat': 0.x '@firebase/analytics-types@0.8.3': resolution: {integrity: sha512-VrIp/d8iq2g501qO46uGz3hjbDb8xzYMrbu8Tp0ovzIzrvJZ2fvmj649gTjge/b7cCCcjT0H37g1gVtlNhnkbg==} - '@firebase/analytics@0.10.19': - resolution: {integrity: sha512-3wU676fh60gaiVYQEEXsbGS4HbF2XsiBphyvvqDbtC1U4/dO4coshbYktcCHq+HFaGIK07iHOh4pME0hEq1fcg==} + '@firebase/analytics@0.10.21': + resolution: {integrity: sha512-j2y2q65BlgLGB5Pwjhv/Jopw2X/TBTzvAtI5z/DSp56U4wBj7LfhBfzbdCtFPges+Wz0g55GdoawXibOH5jGng==} peerDependencies: '@firebase/app': 0.x - '@firebase/app-check-compat@0.4.0': - resolution: {integrity: sha512-UfK2Q8RJNjYM/8MFORltZRG9lJj11k0nW84rrffiKvcJxLf1jf6IEjCIkCamykHE73C6BwqhVfhIBs69GXQV0g==} + '@firebase/app-check-compat@0.4.2': + resolution: {integrity: sha512-M91NhxqbSkI0ChkJWy69blC+rPr6HEgaeRllddSaU1pQ/7IiegeCQM9pPDIgvWnwnBSzKhUHpe6ro/jhJ+cvzw==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app-compat': 0.x @@ -1909,25 +1912,25 @@ packages: '@firebase/app-check-types@0.5.3': resolution: {integrity: sha512-hyl5rKSj0QmwPdsAxrI5x1otDlByQ7bvNvVt8G/XPO2CSwE++rmSVf3VEhaeOR4J8ZFaF0Z0NDSmLejPweZ3ng==} - '@firebase/app-check@0.11.0': - resolution: {integrity: sha512-XAvALQayUMBJo58U/rxW02IhsesaxxfWVmVkauZvGEz3vOAjMEQnzFlyblqkc2iAaO82uJ2ZVyZv9XzPfxjJ6w==} + '@firebase/app-check@0.11.2': + resolution: {integrity: sha512-jcXQVMHAQ5AEKzVD5C7s5fmAYeFOuN6lAJeNTgZK2B9aLnofWaJt8u1A8Idm8gpsBBYSaY3cVyeH5SWMOVPBLQ==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x - '@firebase/app-compat@0.5.7': - resolution: {integrity: sha512-MO+jfap8IBZQ+K8L2QCiHObyMgpYHrxo4Hc7iJgfb9hjGRW/z1y6LWVdT9wBBK+VJ7cRP2DjAiWQP+thu53hHA==} + '@firebase/app-compat@0.5.10': + resolution: {integrity: sha512-tFmBuZL0/v1h6eyKRgWI58ucft6dEJmAi9nhPUXoAW4ZbPSTlnsh31AuEwUoRTz+wwRk9gmgss9GZV05ZM9Kug==} engines: {node: '>=20.0.0'} '@firebase/app-types@0.9.3': resolution: {integrity: sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw==} - '@firebase/app@0.14.7': - resolution: {integrity: sha512-o3ZfnOx0AWBD5n/36p2zPoB0rDDxQP8H/A60zDLvvfRLtW8b3LfCyV97GKpJaAVV1JMMl/BC89EDzMyzxFZxTw==} + '@firebase/app@0.14.10': + resolution: {integrity: sha512-PlPhdtjgWUra+LImQTnXOUqUa/jcufZhizdR93ZjlQSS3ahCtDTG6pJw7j0OwFal18DQjICXfeVNsUUrcNisfA==} engines: {node: '>=20.0.0'} - '@firebase/auth-compat@0.6.2': - resolution: {integrity: sha512-8UhCzF6pav9bw/eXA8Zy1QAKssPRYEYXaWagie1ewLTwHkXv6bKp/j6/IwzSYQP67sy/BMFXIFaCCsoXzFLr7A==} + '@firebase/auth-compat@0.6.4': + resolution: {integrity: sha512-2pj8m/hnqXvMLfC0Mk+fORVTM5DQPkS6l8JpMgtoAWGVgCmYnoWdFMaNWtKbmCxBEyvMA3FlnCJyzrUSMWTfuA==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app-compat': 0.x @@ -1941,8 +1944,8 @@ packages: '@firebase/app-types': 0.x '@firebase/util': 1.x - '@firebase/auth@1.12.0': - resolution: {integrity: sha512-zkvLpsrxynWHk07qGrUDfCSqKf4AvfZGEqJ7mVCtYGjNNDbGE71k0Yn84rg8QEZu4hQw1BC0qDEHzpNVBcSVmA==} + '@firebase/auth@1.12.2': + resolution: {integrity: sha512-CZJL8V10Vzibs+pDTXdQF+hot1IigIoqF4a4lA/qr5Deo1srcefiyIfgg28B67Lk7IxZhwfJMuI+1bu2xBmV0A==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x @@ -1951,28 +1954,28 @@ packages: '@react-native-async-storage/async-storage': optional: true - '@firebase/component@0.7.0': - resolution: {integrity: sha512-wR9En2A+WESUHexjmRHkqtaVH94WLNKt6rmeqZhSLBybg4Wyf0Umk04SZsS6sBq4102ZsDBFwoqMqJYj2IoDSg==} + '@firebase/component@0.7.2': + resolution: {integrity: sha512-iyVDGc6Vjx7Rm0cAdccLH/NG6fADsgJak/XW9IA2lPf8AjIlsemOpFGKczYyPHxm4rnKdR8z6sK4+KEC7NwmEg==} engines: {node: '>=20.0.0'} - '@firebase/data-connect@0.3.12': - resolution: {integrity: sha512-baPddcoNLj/+vYo+HSJidJUdr5W4OkhT109c5qhR8T1dJoZcyJpkv/dFpYlw/VJ3dV66vI8GHQFrmAZw/xUS4g==} + '@firebase/data-connect@0.5.0': + resolution: {integrity: sha512-G3GYHpWNJJ95502RQLApzw0jaG3pScHl+J/2MdxIuB51xtHnkRL6KvIAP3fFF1drUewWJHOnDA1U+q4Evf3KSw==} peerDependencies: '@firebase/app': 0.x - '@firebase/database-compat@2.1.0': - resolution: {integrity: sha512-8nYc43RqxScsePVd1qe1xxvWNf0OBnbwHxmXJ7MHSuuTVYFO3eLyLW3PiCKJ9fHnmIz4p4LbieXwz+qtr9PZDg==} + '@firebase/database-compat@2.1.2': + resolution: {integrity: sha512-j4A6IhVZbgxAzT6gJJC2PfOxYCK9SrDrUO7nTM4EscTYtKkAkzsbKoCnDdjFapQfnsncvPWjqVTr/0PffUwg3g==} engines: {node: '>=20.0.0'} - '@firebase/database-types@1.0.16': - resolution: {integrity: sha512-xkQLQfU5De7+SPhEGAXFBnDryUWhhlFXelEg2YeZOQMCdoe7dL64DDAd77SQsR+6uoXIZY5MB4y/inCs4GTfcw==} + '@firebase/database-types@1.0.18': + resolution: {integrity: sha512-yOY8IC2go9lfbVDMiy2ATun4EB2AFwocPaQADwMN/RHRUAZSM4rlAV7PGbWPSG/YhkJ2A9xQAiAENgSua9G5Fg==} - '@firebase/database@1.1.0': - resolution: {integrity: sha512-gM6MJFae3pTyNLoc9VcJNuaUDej0ctdjn3cVtILo3D5lpp0dmUHHLFN/pUKe7ImyeB1KAvRlEYxvIHNF04Filg==} + '@firebase/database@1.1.2': + resolution: {integrity: sha512-lP96CMjMPy/+d1d9qaaHjHHdzdwvEOuyyLq9ehX89e2XMKwS1jHNzYBO+42bdSumuj5ukPbmnFtViZu8YOMT+w==} engines: {node: '>=20.0.0'} - '@firebase/firestore-compat@0.4.4': - resolution: {integrity: sha512-JvxxIgi+D5v9BecjLA1YomdyF7LA6CXhJuVK10b4GtRrB3m2O2hT1jJWbKYZYHUAjTaajkvnos+4U5VNxqkI2w==} + '@firebase/firestore-compat@0.4.7': + resolution: {integrity: sha512-Et4XxtGnjp0Q9tmaEMETnY5GHJ8gQ9+RN6sSTT4ETWKmym2d6gIjarw0rCQcx+7BrWVYLEIOAXSXysl0b3xnUA==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app-compat': 0.x @@ -1983,14 +1986,14 @@ packages: '@firebase/app-types': 0.x '@firebase/util': 1.x - '@firebase/firestore@4.10.0': - resolution: {integrity: sha512-fgF6EbpoagGWh5Vwfu/7/jYgBFwUCwTlPNVF/aSjHcoEDRXpRsIqVfAFTp1LD+dWAUcAKEK3h+osk8spMJXtxA==} + '@firebase/firestore@4.13.0': + resolution: {integrity: sha512-7i4cVNJXTMim7/P7UsNim0DwyLPk4QQ3y1oSNzv4l0ykJOKYCiFMOuEeUxUYvrReXDJxWHrT/4XMeVQm+13rRw==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x - '@firebase/functions-compat@0.4.1': - resolution: {integrity: sha512-AxxUBXKuPrWaVNQ8o1cG1GaCAtXT8a0eaTDfqgS5VsRYLAR0ALcfqDLwo/QyijZj1w8Qf8n3Qrfy/+Im245hOQ==} + '@firebase/functions-compat@0.4.3': + resolution: {integrity: sha512-BxkEwWgx1of0tKaao/r2VR6WBLk/RAiyztatiONPrPE8gkitFkOnOCxf8i9cUyA5hX5RGt5H30uNn25Q6QNEmQ==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app-compat': 0.x @@ -1998,14 +2001,14 @@ packages: '@firebase/functions-types@0.6.3': resolution: {integrity: sha512-EZoDKQLUHFKNx6VLipQwrSMh01A1SaL3Wg6Hpi//x6/fJ6Ee4hrAeswK99I5Ht8roiniKHw4iO0B1Oxj5I4plg==} - '@firebase/functions@0.13.1': - resolution: {integrity: sha512-sUeWSb0rw5T+6wuV2o9XNmh9yHxjFI9zVGFnjFi+n7drTEWpl7ZTz1nROgGrSu472r+LAaj+2YaSicD4R8wfbw==} + '@firebase/functions@0.13.3': + resolution: {integrity: sha512-csO7ckK3SSs+NUZW1nms9EK7ckHe/1QOjiP8uAkCYa7ND18s44vjE9g3KxEeIUpyEPqZaX1EhJuFyZjHigAcYw==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x - '@firebase/installations-compat@0.2.19': - resolution: {integrity: sha512-khfzIY3EI5LePePo7vT19/VEIH1E3iYsHknI/6ek9T8QCozAZshWT9CjlwOzZrKvTHMeNcbpo/VSOSIWDSjWdQ==} + '@firebase/installations-compat@0.2.21': + resolution: {integrity: sha512-zahIUkaVKbR8zmTeBHkdfaVl6JGWlhVoSjF7CVH33nFqD3SlPEpEEegn2GNT5iAfsVdtlCyJJ9GW4YKjq+RJKQ==} peerDependencies: '@firebase/app-compat': 0.x @@ -2014,8 +2017,8 @@ packages: peerDependencies: '@firebase/app-types': 0.x - '@firebase/installations@0.6.19': - resolution: {integrity: sha512-nGDmiwKLI1lerhwfwSHvMR9RZuIH5/8E3kgUWnVRqqL7kGVSktjLTWEMva7oh5yxQ3zXfIlIwJwMcaM5bK5j8Q==} + '@firebase/installations@0.6.21': + resolution: {integrity: sha512-xGFGTeICJZ5vhrmmDukeczIcFULFXybojML2+QSDFoKj5A7zbGN7KzFGSKNhDkIxpjzsYG9IleJyUebuAcmqWA==} peerDependencies: '@firebase/app': 0.x @@ -2023,47 +2026,47 @@ packages: resolution: {integrity: sha512-cGskaAvkrnh42b3BA3doDWeBmuHFO/Mx5A83rbRDYakPjO9bJtRL3dX7javzc2Rr/JHZf4HlterTW2lUkfeN4g==} engines: {node: '>=20.0.0'} - '@firebase/messaging-compat@0.2.23': - resolution: {integrity: sha512-SN857v/kBUvlQ9X/UjAqBoQ2FEaL1ZozpnmL1ByTe57iXkmnVVFm9KqAsTfmf+OEwWI4kJJe9NObtN/w22lUgg==} + '@firebase/messaging-compat@0.2.25': + resolution: {integrity: sha512-eoOQqGLtRlseTdiemTN44LlHZpltK5gnhq8XVUuLgtIOG+odtDzrz2UoTpcJWSzaJQVxNLb/x9f39tHdDM4N4w==} peerDependencies: '@firebase/app-compat': 0.x '@firebase/messaging-interop-types@0.2.3': resolution: {integrity: sha512-xfzFaJpzcmtDjycpDeCUj0Ge10ATFi/VHVIvEEjDNc3hodVBQADZ7BWQU7CuFpjSHE+eLuBI13z5F/9xOoGX8Q==} - '@firebase/messaging@0.12.23': - resolution: {integrity: sha512-cfuzv47XxqW4HH/OcR5rM+AlQd1xL/VhuaeW/wzMW1LFrsFcTn0GND/hak1vkQc2th8UisBcrkVcQAnOnKwYxg==} + '@firebase/messaging@0.12.25': + resolution: {integrity: sha512-7RhDwoDHlOK1/ou0/LeubxmjcngsTjDdrY/ssg2vwAVpUuVAhQzQvuCAOYxcX5wNC1zCgQ54AP1vdngBwbCmOQ==} peerDependencies: '@firebase/app': 0.x - '@firebase/performance-compat@0.2.22': - resolution: {integrity: sha512-xLKxaSAl/FVi10wDX/CHIYEUP13jXUjinL+UaNXT9ByIvxII5Ne5150mx6IgM8G6Q3V+sPiw9C8/kygkyHUVxg==} + '@firebase/performance-compat@0.2.24': + resolution: {integrity: sha512-YRlejH8wLt7ThWao+HXoKUHUrZKGYq+otxkPS+8nuE5PeN1cBXX7NAJl9ueuUkBwMIrnKdnDqL/voHXxDAAt3g==} peerDependencies: '@firebase/app-compat': 0.x '@firebase/performance-types@0.2.3': resolution: {integrity: sha512-IgkyTz6QZVPAq8GSkLYJvwSLr3LS9+V6vNPQr0x4YozZJiLF5jYixj0amDtATf1X0EtYHqoPO48a9ija8GocxQ==} - '@firebase/performance@0.7.9': - resolution: {integrity: sha512-UzybENl1EdM2I1sjYm74xGt/0JzRnU/0VmfMAKo2LSpHJzaj77FCLZXmYQ4oOuE+Pxtt8Wy2BVJEENiZkaZAzQ==} + '@firebase/performance@0.7.11': + resolution: {integrity: sha512-V3uAhrz7IYJuji+OgT3qYTGKxpek/TViXti9OSsUJ4AexZ3jQjYH5Yrn7JvBxk8MGiSLsC872hh+BxQiPZsm7g==} peerDependencies: '@firebase/app': 0.x - '@firebase/remote-config-compat@0.2.21': - resolution: {integrity: sha512-9+lm0eUycxbu8GO25JfJe4s6R2xlDqlVt0CR6CvN9E6B4AFArEV4qfLoDVRgIEB7nHKwvH2nYRocPWfmjRQTnw==} + '@firebase/remote-config-compat@0.2.23': + resolution: {integrity: sha512-4+KqRRHEUUmKT6tFmnpWATOsaFfmSuBs1jXH8JzVtMLEYqq/WS9IDM92OdefFDSrAA2xGd0WN004z8mKeIIscw==} peerDependencies: '@firebase/app-compat': 0.x '@firebase/remote-config-types@0.5.0': resolution: {integrity: sha512-vI3bqLoF14L/GchtgayMiFpZJF+Ao3uR8WCde0XpYNkSokDpAKca2DxvcfeZv7lZUqkUwQPL2wD83d3vQ4vvrg==} - '@firebase/remote-config@0.8.0': - resolution: {integrity: sha512-sJz7C2VACeE257Z/3kY9Ap2WXbFsgsDLfaGfZmmToKAK39ipXxFan+vzB9CSbF6mP7bzjyzEnqPcMXhAnYE6fQ==} + '@firebase/remote-config@0.8.2': + resolution: {integrity: sha512-5EXqOThV4upjK9D38d/qOSVwOqRhemlaOFk9vCkMNNALeIlwr+4pLjtLNo4qoY8etQmU/1q4aIATE9N8PFqg0g==} peerDependencies: '@firebase/app': 0.x - '@firebase/storage-compat@0.4.0': - resolution: {integrity: sha512-vDzhgGczr1OfcOy285YAPur5pWDEvD67w4thyeCUh6Ys0izN9fNYtA1MJERmNBfqjqu0lg0FM5GLbw0Il21M+g==} + '@firebase/storage-compat@0.4.2': + resolution: {integrity: sha512-R+aB38wxCH5zjIO/xu9KznI7fgiPuZAG98uVm1NcidHyyupGgIDLKigGmRGBZMnxibe/m2oxNKoZpfEbUX2aQQ==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app-compat': 0.x @@ -2074,19 +2077,23 @@ packages: '@firebase/app-types': 0.x '@firebase/util': 1.x - '@firebase/storage@0.14.0': - resolution: {integrity: sha512-xWWbb15o6/pWEw8H01UQ1dC5U3rf8QTAzOChYyCpafV6Xki7KVp3Yaw2nSklUwHEziSWE9KoZJS7iYeyqWnYFA==} + '@firebase/storage@0.14.2': + resolution: {integrity: sha512-o/culaTeJ8GRpKXRJov21rux/n9dRaSOWLebyatFP2sqEdCxQPjVA1H9Z2fzYwQxMIU0JVmC7SPPmU11v7L6vQ==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x - '@firebase/util@1.13.0': - resolution: {integrity: sha512-0AZUyYUfpMNcztR5l09izHwXkZpghLgCUaAGjtMwXnCg3bj4ml5VgiwqOMOxJ+Nw4qN/zJAaOQBcJ7KGkWStqQ==} + '@firebase/util@1.15.0': + resolution: {integrity: sha512-AmWf3cHAOMbrCPG4xdPKQaj5iHnyYfyLKZxwz+Xf55bqKbpAmcYifB4jQinT2W9XhDRHISOoPyBOariJpCG6FA==} engines: {node: '>=20.0.0'} '@firebase/webchannel-wrapper@1.0.5': resolution: {integrity: sha512-+uGNN7rkfn41HLO0vekTFhTxk61eKa8mTpRGLO0QSqlQdKvIoGAvLp3ppdVIWbTGYJWM6Kp0iN+PjMIOcnVqTw==} + '@gar/promise-retry@1.0.3': + resolution: {integrity: sha512-GmzA9ckNokPypTg10pgpeHNQe7ph+iIKKmhKu3Ob9ANkswreCx7R3cKmY781K8QK3AqVL3xVh9A42JvIAbkkSA==} + engines: {node: ^20.17.0 || >=22.9.0} + '@glideapps/ts-necessities@2.2.3': resolution: {integrity: sha512-gXi0awOZLHk3TbW55GZLCPP6O+y/b5X1pBXKBVckFONSwF1z1E5ND2BGJsghQFah+pW7pkkyFb2VhUQI2qhL5w==} @@ -2118,8 +2125,8 @@ packages: resolution: {integrity: sha512-IJn+8A3QZJfe7FUtWqHVNo3xJs7KFpurCWGWCiCz3oEh+BkRymKZ1QxfAbU2yGMDzTytLGQ2IV6T2r3cuo75/w==} engines: {node: '>=18'} - '@google/genai@1.38.0': - resolution: {integrity: sha512-V/4CQVQGovvGHuS73lwJwHKR9x33kCij3zz/ReEQ4A7RJaV0U7m4k1mvYhFk55cGZdF5JLKu2S9BTaFuEs5xTA==} + '@google/genai@1.47.0': + resolution: {integrity: sha512-0VV7AaXm5rQu3oRHNZNEubRAOL2lv5u+YA72eWnDwcOx3B1jFRbvtgL4drRHlocRHOnludvr3xmbQGbR+/RQAQ==} engines: {node: '>=20.0.0'} peerDependencies: '@modelcontextprotocol/sdk': ^1.25.2 @@ -2151,8 +2158,8 @@ packages: '@harperfast/extended-iterable@1.0.3': resolution: {integrity: sha512-sSAYhQca3rDWtQUHSAPeO7axFIUJOI6hn1gjRC5APVE1a90tuyT8f5WIgRsFhhWA7htNkju2veB9eWL6YHi/Lw==} - '@hono/node-server@1.19.9': - resolution: {integrity: sha512-vHL6w3ecZsky+8P5MD+eFfaGTyCeOHUIFYMGpQGbrBTSmNNoxv0if69rEZ5giu36weC5saFuznL411gRX7bJDw==} + '@hono/node-server@1.19.11': + resolution: {integrity: sha512-dr8/3zEaB+p0D2n/IUrlPF1HZm586qgJNXK1a9fhg/PzdtkK7Ksd5l312tJX2yBuALqDYBlG20QEbayqPyxn+g==} engines: {node: '>=18.14.1'} peerDependencies: hono: ^4 @@ -2177,8 +2184,8 @@ packages: resolution: {integrity: sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==} engines: {node: '>=18'} - '@inquirer/ansi@2.0.3': - resolution: {integrity: sha512-g44zhR3NIKVs0zUesa4iMzExmZpLUdTLRMCStqX3GE5NT6VkPcxQGJ+uC8tDgBUC/vB1rUhUd55cOf++4NZcmw==} + '@inquirer/ansi@2.0.4': + resolution: {integrity: sha512-DpcZrQObd7S0R/U3bFdkcT5ebRwbTTC4D3tCc1vsJizmgPLxNJBo+AAFmrZwe8zk30P2QzgzGWZ3Q9uJwWuhIg==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} '@inquirer/checkbox@4.3.2': @@ -2190,8 +2197,8 @@ packages: '@types/node': optional: true - '@inquirer/checkbox@5.0.6': - resolution: {integrity: sha512-qLZ1gOpsqsieB5k98GQ9bWYggvMsCXTc7HUwhEQpTsxFQYGthqR9UysCwqB7L9h47THYdXhJegnYb1IqURMjng==} + '@inquirer/checkbox@5.1.2': + resolution: {integrity: sha512-PubpMPO2nJgMufkoB3P2wwxNXEMUXnBIKi/ACzDUYfaoPuM7gSTmuxJeMscoLVEsR4qqrCMf5p0SiYGWnVJ8kw==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} peerDependencies: '@types/node': '>=18' @@ -2208,8 +2215,8 @@ packages: '@types/node': optional: true - '@inquirer/confirm@6.0.6': - resolution: {integrity: sha512-9ZkrGYiWnOKQPc3xfLIORE3lZW1qvtgRoJcoqopr5zssBn7yk4yONmzGynEOjc16FnUXzkAejj/I29BbfcoUfQ==} + '@inquirer/confirm@6.0.10': + resolution: {integrity: sha512-tiNyA73pgpQ0FQ7axqtoLUe4GDYjNCDcVsbgcA5anvwg2z6i+suEngLKKJrWKJolT//GFPZHwN30binDIHgSgQ==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} peerDependencies: '@types/node': '>=18' @@ -2226,8 +2233,8 @@ packages: '@types/node': optional: true - '@inquirer/core@11.1.3': - resolution: {integrity: sha512-TBAGPDGvpwFSQ4nkawQzq5/X7DhElANjvKeUtcjpVnBIfuH/OEu4M+79R3+bGPtwxST4DOIGRtF933mUH2bRVw==} + '@inquirer/core@11.1.7': + resolution: {integrity: sha512-1BiBNDk9btIwYIzNZpkikIHXWeNzNncJePPqwDyVMhXhD1ebqbpn1mKGctpoqAbzywZfdG0O4tvmsGIcOevAPQ==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} peerDependencies: '@types/node': '>=18' @@ -2244,8 +2251,8 @@ packages: '@types/node': optional: true - '@inquirer/editor@5.0.6': - resolution: {integrity: sha512-dxTi/TB29NaW18u0pQl3B140695izGUMzr340a4Yhxll3oa0/iwxl6C88sX9LDUPFaaM4FDASEMnLm8XVk2VVg==} + '@inquirer/editor@5.0.10': + resolution: {integrity: sha512-VJx4XyaKea7t8hEApTw5dxeIyMtWXre2OiyJcICCRZI4hkoHsMoCnl/KbUnJJExLbH9csLLHMVR144ZhFE1CwA==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} peerDependencies: '@types/node': '>=18' @@ -2262,8 +2269,8 @@ packages: '@types/node': optional: true - '@inquirer/expand@5.0.6': - resolution: {integrity: sha512-HmgMzFdMk/gmPXfuFy4xgWkyIVbdH81otQkrFbhklFZcGauwDFD1EbgmZdgmYCN5pWhSEnYIadg1kysLgPIYag==} + '@inquirer/expand@5.0.10': + resolution: {integrity: sha512-fC0UHJPXsTRvY2fObiwuQYaAnHrp3aDqfwKUJSdfpgv18QUG054ezGbaRNStk/BKD5IPijeMKWej8VV8O5Q/eQ==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} peerDependencies: '@types/node': '>=18' @@ -2280,8 +2287,8 @@ packages: '@types/node': optional: true - '@inquirer/external-editor@2.0.3': - resolution: {integrity: sha512-LgyI7Agbda74/cL5MvA88iDpvdXI2KuMBCGRkbCl2Dg1vzHeOgs+s0SDcXV7b+WZJrv2+ERpWSM65Fpi9VfY3w==} + '@inquirer/external-editor@2.0.4': + resolution: {integrity: sha512-Prenuv9C1PHj2Itx0BcAOVBTonz02Hc2Nd2DbU67PdGUaqn0nPCnV34oDyyoaZHnmfRxkpuhh/u51ThkrO+RdA==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} peerDependencies: '@types/node': '>=18' @@ -2293,8 +2300,8 @@ packages: resolution: {integrity: sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==} engines: {node: '>=18'} - '@inquirer/figures@2.0.3': - resolution: {integrity: sha512-y09iGt3JKoOCBQ3w4YrSJdokcD8ciSlMIWsD+auPu+OZpfxLuyz+gICAQ6GCBOmJJt4KEQGHuZSVff2jiNOy7g==} + '@inquirer/figures@2.0.4': + resolution: {integrity: sha512-eLBsjlS7rPS3WEhmOmh1znQ5IsQrxWzxWDxO51e4urv+iVrSnIHbq4zqJIOiyNdYLa+BVjwOtdetcQx1lWPpiQ==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} '@inquirer/input@4.3.1': @@ -2306,8 +2313,8 @@ packages: '@types/node': optional: true - '@inquirer/input@5.0.6': - resolution: {integrity: sha512-RZsJcjMJA3QNI9q9OiAi1fAom+Pb8on6alJB1Teh5jjKaiG5C79P69cG955ZRfgPdxTmI4uyhf33+94Xj7xWig==} + '@inquirer/input@5.0.10': + resolution: {integrity: sha512-nvZ6qEVeX/zVtZ1dY2hTGDQpVGD3R7MYPLODPgKO8Y+RAqxkrP3i/3NwF3fZpLdaMiNuK0z2NaYIx9tPwiSegQ==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} peerDependencies: '@types/node': '>=18' @@ -2324,8 +2331,8 @@ packages: '@types/node': optional: true - '@inquirer/number@4.0.6': - resolution: {integrity: sha512-owMkAY+gR0BggomDTL+Z22x/yfE4ocFrmNyJacOiaDVA/d+iL4IWyk7Ds7JEuDMxuhHFB46Dubdxg1uiD7GlCA==} + '@inquirer/number@4.0.10': + resolution: {integrity: sha512-Ht8OQstxiS3APMGjHV0aYAjRAysidWdwurWEo2i8yI5xbhOBWqizT0+MU1S2GCcuhIBg+3SgWVjEoXgfhY+XaA==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} peerDependencies: '@types/node': '>=18' @@ -2342,8 +2349,8 @@ packages: '@types/node': optional: true - '@inquirer/password@5.0.6': - resolution: {integrity: sha512-c4BT4SB79iYwPhtGVBSvrlTnn4oFSYnwocafmktpay8RK75T2c2+fLlR0i1Cxw0QOhdy/YULdmpHoy1sOrPzvA==} + '@inquirer/password@5.0.10': + resolution: {integrity: sha512-QbNyvIE8q2GTqKLYSsA8ATG+eETo+m31DSR0+AU7x3d2FhaTWzqQek80dj3JGTo743kQc6mhBR0erMjYw5jQ0A==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} peerDependencies: '@types/node': '>=18' @@ -2360,8 +2367,8 @@ packages: '@types/node': optional: true - '@inquirer/prompts@8.2.0': - resolution: {integrity: sha512-rqTzOprAj55a27jctS3vhvDDJzYXsr33WXTjODgVOru21NvBo9yIgLIAf7SBdSV0WERVly3dR6TWyp7ZHkvKFA==} + '@inquirer/prompts@8.3.2': + resolution: {integrity: sha512-yFroiSj2iiBFlm59amdTvAcQFvWS6ph5oKESls/uqPBect7rTU2GbjyZO2DqxMGuIwVA8z0P4K6ViPcd/cp+0w==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} peerDependencies: '@types/node': '>=18' @@ -2378,8 +2385,8 @@ packages: '@types/node': optional: true - '@inquirer/rawlist@5.2.2': - resolution: {integrity: sha512-ld2EhLlf3fsBv7QfxR31NdBecGdS6eeFFZ+Nx88ApjtifeCEc9TNrw8x5tGe+gd6HG1ERczOb4B/bMojiGIp1g==} + '@inquirer/rawlist@5.2.6': + resolution: {integrity: sha512-jfw0MLJ5TilNsa9zlJ6nmRM0ZFVZhhTICt4/6CU2Dv1ndY7l3sqqo1gIYZyMMDw0LvE1u1nzJNisfHEhJIxq5w==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} peerDependencies: '@types/node': '>=18' @@ -2396,8 +2403,8 @@ packages: '@types/node': optional: true - '@inquirer/search@4.1.2': - resolution: {integrity: sha512-kdGbbbWYKldWxpxodKYPmFl/ctBi3DjWlA4LX48jXtqJ7NEeoEKlyFTbE4xNEFcGDi15tvaxRLzCV4A53zqYIw==} + '@inquirer/search@4.1.6': + resolution: {integrity: sha512-3/6kTRae98hhDevENScy7cdFEuURnSpM3JbBNg8yfXLw88HgTOl+neUuy/l9W0No5NzGsLVydhBzTIxZP7yChQ==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} peerDependencies: '@types/node': '>=18' @@ -2414,8 +2421,8 @@ packages: '@types/node': optional: true - '@inquirer/select@5.0.6': - resolution: {integrity: sha512-9DyVbNCo4q0C3CkGd6zW0SW3NQuuk4Hy0NSbP6zErz2YNWF4EHHJCRzcV34/CDQLraeAQXbHYlMofuUrs6BBZQ==} + '@inquirer/select@5.1.2': + resolution: {integrity: sha512-kTK8YIkHV+f02y7bWCh7E0u2/11lul5WepVTclr3UMBtBr05PgcZNWfMa7FY57ihpQFQH/spLMHTcr0rXy50tA==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} peerDependencies: '@types/node': '>=18' @@ -2432,8 +2439,8 @@ packages: '@types/node': optional: true - '@inquirer/type@4.0.3': - resolution: {integrity: sha512-cKZN7qcXOpj1h+1eTTcGDVLaBIHNMT1Rz9JqJP5MnEJ0JhgVWllx7H/tahUp5YEK1qaByH2Itb8wLG/iScD5kw==} + '@inquirer/type@4.0.4': + resolution: {integrity: sha512-PamArxO3cFJZoOzspzo6cxVlLeIftyBsZw/S9bKY5DzxqJVZgjoj1oP8d0rskKtp7sZxBycsoer1g6UeJV1BBA==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} peerDependencies: '@types/node': '>=18' @@ -2441,22 +2448,10 @@ packages: '@types/node': optional: true - '@isaacs/balanced-match@4.0.1': - resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} - engines: {node: 20 || >=22} - - '@isaacs/brace-expansion@5.0.1': - resolution: {integrity: sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ==} - engines: {node: 20 || >=22} - '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} - '@isaacs/cliui@9.0.0': - resolution: {integrity: sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==} - engines: {node: '>=18'} - '@isaacs/fs-minipass@4.0.1': resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} engines: {node: '>=18.0.0'} @@ -2529,50 +2524,50 @@ packages: peerDependencies: tslib: '2' - '@jsonjoy.com/fs-core@4.56.10': - resolution: {integrity: sha512-PyAEA/3cnHhsGcdY+AmIU+ZPqTuZkDhCXQ2wkXypdLitSpd6d5Ivxhnq4wa2ETRWFVJGabYynBWxIijOswSmOw==} + '@jsonjoy.com/fs-core@4.57.1': + resolution: {integrity: sha512-YrEi/ZPmgc+GfdO0esBF04qv8boK9Dg9WpRQw/+vM8Qt3nnVIJWIa8HwZ/LXVZ0DB11XUROM8El/7yYTJX+WtA==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-fsa@4.56.10': - resolution: {integrity: sha512-/FVK63ysNzTPOnCCcPoPHt77TOmachdMS422txM4KhxddLdbW1fIbFMYH0AM0ow/YchCyS5gqEjKLNyv71j/5Q==} + '@jsonjoy.com/fs-fsa@4.57.1': + resolution: {integrity: sha512-ooEPvSW/HQDivPDPZMibHGKZf/QS4WRir1czGZmXmp3MsQqLECZEpN0JobrD8iV9BzsuwdIv+PxtWX9WpPLsIA==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node-builtins@4.56.10': - resolution: {integrity: sha512-uUnKz8R0YJyKq5jXpZtkGV9U0pJDt8hmYcLRrPjROheIfjMXsz82kXMgAA/qNg0wrZ1Kv+hrg7azqEZx6XZCVw==} + '@jsonjoy.com/fs-node-builtins@4.57.1': + resolution: {integrity: sha512-XHkFKQ5GSH3uxm8c3ZYXVrexGdscpWKIcMWKFQpMpMJc8gA3AwOMBJXJlgpdJqmrhPyQXxaY9nbkNeYpacC0Og==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node-to-fsa@4.56.10': - resolution: {integrity: sha512-oH+O6Y4lhn9NyG6aEoFwIBNKZeYy66toP5LJcDOMBgL99BKQMUf/zWJspdRhMdn/3hbzQsZ8EHHsuekbFLGUWw==} + '@jsonjoy.com/fs-node-to-fsa@4.57.1': + resolution: {integrity: sha512-pqGHyWWzNck4jRfaGV39hkqpY5QjRUQ/nRbNT7FYbBa0xf4bDG+TE1Gt2KWZrSkrkZZDE3qZUjYMbjwSliX6pg==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node-utils@4.56.10': - resolution: {integrity: sha512-8EuPBgVI2aDPwFdaNQeNpHsyqPi3rr+85tMNG/lHvQLiVjzoZsvxA//Xd8aB567LUhy4QS03ptT+unkD/DIsNg==} + '@jsonjoy.com/fs-node-utils@4.57.1': + resolution: {integrity: sha512-vp+7ZzIB8v43G+GLXTS4oDUSQmhAsRz532QmmWBbdYA20s465JvwhkSFvX9cVTqRRAQg+vZ7zWDaIEh0lFe2gw==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node@4.56.10': - resolution: {integrity: sha512-7R4Gv3tkUdW3dXfXiOkqxkElxKNVdd8BDOWC0/dbERd0pXpPY+s2s1Mino+aTvkGrFPiY+mmVxA7zhskm4Ue4Q==} + '@jsonjoy.com/fs-node@4.57.1': + resolution: {integrity: sha512-3YaKhP8gXEKN+2O49GLNfNb5l2gbnCFHyAaybbA2JkkbQP3dpdef7WcUaHAulg/c5Dg4VncHsA3NWAUSZMR5KQ==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-print@4.56.10': - resolution: {integrity: sha512-JW4fp5mAYepzFsSGrQ48ep8FXxpg4niFWHdF78wDrFGof7F3tKDJln72QFDEn/27M1yHd4v7sKHHVPh78aWcEw==} + '@jsonjoy.com/fs-print@4.57.1': + resolution: {integrity: sha512-Ynct7ZJmfk6qoXDOKfpovNA36ITUx8rChLmRQtW08J73VOiuNsU8PB6d/Xs7fxJC2ohWR3a5AqyjmLojfrw5yw==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-snapshot@4.56.10': - resolution: {integrity: sha512-DkR6l5fj7+qj0+fVKm/OOXMGfDFCGXLfyHkORH3DF8hxkpDgIHbhf/DwncBMs2igu/ST7OEkexn1gIqoU6Y+9g==} + '@jsonjoy.com/fs-snapshot@4.57.1': + resolution: {integrity: sha512-/oG8xBNFMbDXTq9J7vepSA1kerS5vpgd3p5QZSPd+nX59uwodGJftI51gDYyHRpP57P3WCQf7LHtBYPqwUg2Bg==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' @@ -2698,8 +2693,8 @@ packages: cpu: [x64] os: [win32] - '@mswjs/interceptors@0.39.8': - resolution: {integrity: sha512-2+BzZbjRO7Ct61k8fMNHEtoKjeWI9pIlHFTqBwZ5icHpqszIgEZbjb1MW5Z0+bITTCTl3gk4PDBxs9tA/csXvA==} + '@mswjs/interceptors@0.41.3': + resolution: {integrity: sha512-cXu86tF4VQVfwz8W1SPbhoRyHJkti6mjH/XJIxp40jhO4j2k1m4KYrEykxqWPkFF3vrK4rgQppBh//AwyGSXPA==} engines: {node: '>=18'} '@napi-rs/nice-android-arm-eabi@1.1.1': @@ -2815,8 +2810,11 @@ packages: resolution: {integrity: sha512-xJIPs+bYuc9ASBl+cvGsKbGrJmS6fAKaSZCnT0lhahT5rhA2VVy9/EcIgd2JhtEuFOJNx7UHNn/qiTPTY4nrQw==} engines: {node: '>= 10'} - '@napi-rs/wasm-runtime@1.1.1': - resolution: {integrity: sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==} + '@napi-rs/wasm-runtime@1.1.2': + resolution: {integrity: sha512-sNXv5oLJ7ob93xkZ1XnxisYhGYXfaG9f65/ZgYuAu3qt7b3NadcOEhLvx28hv31PgX8SZJRYrAIPQilQmFpLVw==} + peerDependencies: + '@emnapi/core': ^1.7.1 + '@emnapi/runtime': ^1.7.1 '@noble/hashes@1.4.0': resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} @@ -2842,8 +2840,8 @@ packages: resolution: {integrity: sha512-7OsC1gNORBEawOa5+j2pXN9vsicaIOH5cPXxoR6fJOmH6/EXpJB2CajXOu1fPRFun2m1lktEFX11+P89hqO/og==} engines: {node: ^20.17.0 || >=22.9.0} - '@npmcli/git@7.0.1': - resolution: {integrity: sha512-+XTFxK2jJF/EJJ5SoAzXk3qwIDfvFc5/g+bD274LZ7uY7LE8sTfG6Z8rOanPl2ZEvZWqNvmEdtXC25cE54VcoA==} + '@npmcli/git@7.0.2': + resolution: {integrity: sha512-oeolHDjExNAJAnlYP2qzNjMX/Xi9bmu78C9dIGr4xjobrSKbuMYCph8lTzn4vnW3NjIqVmw/f8BCfouqyJXlRg==} engines: {node: ^20.17.0 || >=22.9.0} '@npmcli/installed-package-contents@4.0.0': @@ -2855,8 +2853,8 @@ packages: resolution: {integrity: sha512-uuG5HZFXLfyFKqg8QypsmgLQW7smiRjVc45bqD/ofZZcR/uxEjgQU8qDPv0s9TEeMUiAAU/GC5bR6++UdTirIQ==} engines: {node: ^20.17.0 || >=22.9.0} - '@npmcli/package-json@7.0.4': - resolution: {integrity: sha512-0wInJG3j/K40OJt/33ax47WfWMzZTm6OQxB9cDhTt5huCP2a9g2GnlsxmfN+PulItNPIpPrZ+kfwwUil7eHcZQ==} + '@npmcli/package-json@7.0.5': + resolution: {integrity: sha512-iVuTlG3ORq2iaVa1IWUxAO/jIp77tUKBhoMjuzYW2kL4MLN1bi/ofqkZ7D7OOwh8coAx1/S2ge0rMdGv8sLSOQ==} engines: {node: ^20.17.0 || >=22.9.0} '@npmcli/promise-spawn@9.0.1': @@ -2867,12 +2865,12 @@ packages: resolution: {integrity: sha512-gOBg5YHMfZy+TfHArfVogwgfBeQnKbbGo3pSUyK/gSI0AVu+pEiDVcKlQb0D8Mg1LNRZILZ6XG8I5dJ4KuAd9Q==} engines: {node: ^20.17.0 || >=22.9.0} - '@npmcli/run-script@10.0.3': - resolution: {integrity: sha512-ER2N6itRkzWbbtVmZ9WKaWxVlKlOeBFF1/7xx+KA5J1xKa4JjUwBdb6tDpk0v1qA+d+VDwHI9qmLcXSWcmi+Rw==} + '@npmcli/run-script@10.0.4': + resolution: {integrity: sha512-mGUWr1uMnf0le2TwfOZY4SFxZGXGfm4Jtay/nwAa2FLNAKXUoUwaGwBMNH36UHPtinWfTSJ3nqFQr0091CxVGg==} engines: {node: ^20.17.0 || >=22.9.0} - '@octokit/auth-app@8.1.2': - resolution: {integrity: sha512-db8VO0PqXxfzI6GdjtgEFHY9tzqUql5xMFXYA12juq8TeTgPAuiiP3zid4h50lwlIP457p5+56PnJOgd2GGBuw==} + '@octokit/auth-app@8.2.0': + resolution: {integrity: sha512-vVjdtQQwomrZ4V46B9LaCsxsySxGoHsyw6IYBov/TqJVROrlYdyNgw5q6tQbB7KZt53v1l1W53RiqTvpzL907g==} engines: {node: '>= 20'} '@octokit/auth-oauth-app@9.0.3': @@ -2895,8 +2893,8 @@ packages: resolution: {integrity: sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q==} engines: {node: '>= 20'} - '@octokit/endpoint@11.0.2': - resolution: {integrity: sha512-4zCpzP1fWc7QlqunZ5bSEjxc6yLAlRTnDwKtgXfcI/FxxGoqedDG8V2+xJ60bV2kODqcGB+nATdtap/XYq2NZQ==} + '@octokit/endpoint@11.0.3': + resolution: {integrity: sha512-FWFlNxghg4HrXkD3ifYbS/IdL/mDHjh9QcsNyhQjN8dplUoZbejsdpmuqdA76nxj2xoWPs7p8uX2SNr9rYu0Ag==} engines: {node: '>= 20'} '@octokit/graphql-schema@15.26.1': @@ -2939,8 +2937,8 @@ packages: resolution: {integrity: sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw==} engines: {node: '>= 20'} - '@octokit/request@10.0.7': - resolution: {integrity: sha512-v93h0i1yu4idj8qFPZwjehoJx4j3Ntn+JhXsdJrG9pYaX6j/XRz2RmasMUHtNgQD39nrv/VwTWSqK0RNXR8upA==} + '@octokit/request@10.0.8': + resolution: {integrity: sha512-SJZNwY9pur9Agf7l87ywFi14W+Hd9Jg6Ifivsd33+/bGUQIjNujdFiXII2/qSlN2ybqUHfp5xpekMEjIBTjlSw==} engines: {node: '>= 20'} '@octokit/rest@22.0.1': @@ -2959,24 +2957,24 @@ packages: '@open-draft/until@2.1.0': resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==} - '@opentelemetry/api@1.9.0': - resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==} + '@opentelemetry/api@1.9.1': + resolution: {integrity: sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==} engines: {node: '>=8.0.0'} - '@opentelemetry/context-async-hooks@2.5.1': - resolution: {integrity: sha512-MHbu8XxCHcBn6RwvCt2Vpn1WnLMNECfNKYB14LI5XypcgH4IE0/DiVifVR9tAkwPMyLXN8dOoPJfya3IryLQVw==} + '@opentelemetry/context-async-hooks@2.6.1': + resolution: {integrity: sha512-XHzhwRNkBpeP8Fs/qjGrAf9r9PRv67wkJQ/7ZPaBQQ68DYlTBBx5MF9LvPx7mhuXcDessKK2b+DcxqwpgkcivQ==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' - '@opentelemetry/core@2.5.1': - resolution: {integrity: sha512-Dwlc+3HAZqpgTYq0MUyZABjFkcrKTePwuiFVLjahGD8cx3enqihmpAmdgNFO1R4m/sIe5afjJrA25Prqy4NXlA==} + '@opentelemetry/core@2.6.1': + resolution: {integrity: sha512-8xHSGWpJP9wBxgBpnqGL0R3PbdWQndL1Qp50qrg71+B28zK5OQmUgcDKLJgzyAAV38t4tOyLMGDD60LneR5W8g==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' - '@opentelemetry/semantic-conventions@1.39.0': - resolution: {integrity: sha512-R5R9tb2AXs2IRLNKLBJDynhkfmx7mX0vi8NkhZb3gUkPWHn6HXk5J8iQ/dql0U3ApfWym4kXXmBDRGO+oeOfjg==} + '@opentelemetry/semantic-conventions@1.40.0': + resolution: {integrity: sha512-cifvXDhcqMwwTlTK04GBNeIe7yyo28Mfby85QXFe1Yk8nmi36Ab/5UQwptOx84SsoGNRg+EVSjwzfSZMy6pmlw==} engines: {node: '>=14'} '@oxc-project/types@0.113.0': @@ -3111,20 +3109,20 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} - '@pnpm/crypto.hash@1000.2.1': - resolution: {integrity: sha512-Kgo3bgYbdKkC5xFvvQshbHa+Nru7k50D91+yyq7enp4Ur2EMp4wg5oXleaC5xu5hC9A/1eSCRI8npCioplxG4A==} + '@pnpm/crypto.hash@1000.2.2': + resolution: {integrity: sha512-W8pLZvXWLlGG5p0Z2nCvtBhlM6uuTcbAbsS15wlGS31jBBJKJW2udLoFeM7qfWPo7E2PqRPGxca7APpVYAjJhw==} engines: {node: '>=18.12'} '@pnpm/crypto.polyfill@1000.1.0': resolution: {integrity: sha512-tNe7a6U4rCpxLMBaR0SIYTdjxGdL0Vwb3G1zY8++sPtHSvy7qd54u8CIB0Z+Y6t5tc9pNYMYCMwhE/wdSY7ltg==} engines: {node: '>=18.12'} - '@pnpm/dependency-path@1001.1.9': - resolution: {integrity: sha512-C1V4H54GyMfLL47q93PmdVRJkJyNVEE6Ht6cFrMSsjgsR7fxXWqjlem7OaA9MMjSTBB/d/g9mV4xZnoT/HAkDQ==} + '@pnpm/dependency-path@1001.1.10': + resolution: {integrity: sha512-PNImtV2SmNTDpLi4HdN86tJPmsOeIxm4VhmxgBVsMrJPEBfkNEWFcflR3wU6XVn/26g9qWdvlNHaawtCjeB93Q==} engines: {node: '>=18.12'} - '@pnpm/graceful-fs@1000.0.1': - resolution: {integrity: sha512-JnzaAVFJIEgwTcB55eww8N3h5B6qJdZqDA2wYkSK+OcTvvMSQb9c2STMhBP6GfkWygG1fs3w8D7JRx9SPZnxJg==} + '@pnpm/graceful-fs@1000.1.0': + resolution: {integrity: sha512-EsMX4slK0qJN2AR0/AYohY5m0HQNYGMNe+jhN74O994zp22/WbX+PbkIKyw3UQn39yQm2+z6SgwklDxbeapsmQ==} engines: {node: '>=18.12'} '@pnpm/types@1001.3.0': @@ -3161,8 +3159,8 @@ packages: '@protobufjs/utf8@1.1.0': resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} - '@puppeteer/browsers@2.12.1': - resolution: {integrity: sha512-fXa6uXLxfslBlus3MEpW8S6S9fe5RwmAE5Gd8u3krqOwnkZJV3/lQJiY3LaFdTctLLqJtyMgEUGkbDnRNf6vbQ==} + '@puppeteer/browsers@2.13.0': + resolution: {integrity: sha512-46BZJYJjc/WwmKjsvDFykHtXrtomsCIrwYQPOP7VfMJoZY2bsDF9oROBABR3paDjDcmkUye1Pb1BqdcdiipaWA==} engines: {node: '>=18'} hasBin: true @@ -3259,8 +3257,8 @@ packages: rollup: optional: true - '@rollup/plugin-commonjs@29.0.0': - resolution: {integrity: sha512-U2YHaxR2cU/yAiwKJtJRhnyLk7cifnQw0zUpISsocBDoHDJn+HTV74ABqnwr5bEgWUwFZC9oFL6wLe21lHu5eQ==} + '@rollup/plugin-commonjs@29.0.2': + resolution: {integrity: sha512-S/ggWH1LU7jTyi9DxZOKyxpVd4hF/OZ0JrEbeLjXk/DFXwRny0tjD2c992zOUYQobLrVkRVMDdmHP16HKP7GRg==} engines: {node: '>=16.0.0 || 14 >= 14.17'} peerDependencies: rollup: ^2.68.0||^3.0.0||^4.0.0 @@ -3451,8 +3449,8 @@ packages: cpu: [x64] os: [win32] - '@rollup/wasm-node@4.57.1': - resolution: {integrity: sha512-b0rcJH8ykEanfgTeDtlPubhphIUOx0oaAek+3hizTaFkoC1FBSTsY0GixwB4D5HZ5r3Gt2yI9c8M13OcW/kW5A==} + '@rollup/wasm-node@4.59.0': + resolution: {integrity: sha512-cKB/Pe05aJWQYw3UFS79Id+KVXdExBxWful0+CSl24z3ukwOgBSy6l39XZNwfm3vCh/fpUrAAs+T7PsJ6dC8NA==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -3463,26 +3461,34 @@ packages: resolution: {integrity: sha512-NwCl5Y0V6Di0NexvkTqdoVfmjTaQwoLM236r89KEojGmq/jMls8S+zb7yOwAPdXvbwfKDlP+lmXgAL4vKSQT+A==} engines: {node: ^20.17.0 || >=22.9.0} - '@sigstore/core@3.1.0': - resolution: {integrity: sha512-o5cw1QYhNQ9IroioJxpzexmPjfCe7gzafd2RY3qnMpxr4ZEja+Jad/U8sgFpaue6bOaF+z7RVkyKVV44FN+N8A==} + '@sigstore/core@3.2.0': + resolution: {integrity: sha512-kxHrDQ9YgfrWUSXU0cjsQGv8JykOFZQ9ErNKbFPWzk3Hgpwu8x2hHrQ9IdA8yl+j9RTLTC3sAF3Tdq1IQCP4oA==} engines: {node: ^20.17.0 || >=22.9.0} '@sigstore/protobuf-specs@0.5.0': resolution: {integrity: sha512-MM8XIwUjN2bwvCg1QvrMtbBmpcSHrkhFSCu1D11NyPvDQ25HEc4oG5/OcQfd/Tlf/OxmKWERDj0zGE23jQaMwA==} engines: {node: ^18.17.0 || >=20.5.0} - '@sigstore/sign@4.1.0': - resolution: {integrity: sha512-Vx1RmLxLGnSUqx/o5/VsCjkuN5L7y+vxEEwawvc7u+6WtX2W4GNa7b9HEjmcRWohw/d6BpATXmvOwc78m+Swdg==} + '@sigstore/sign@4.1.1': + resolution: {integrity: sha512-Hf4xglukg0XXQ2RiD5vSoLjdPe8OBUPA8XeVjUObheuDcWdYWrnH/BNmxZCzkAy68MzmNCxXLeurJvs6hcP2OQ==} engines: {node: ^20.17.0 || >=22.9.0} - '@sigstore/tuf@4.0.1': - resolution: {integrity: sha512-OPZBg8y5Vc9yZjmWCHrlWPMBqW5yd8+wFNl+thMdtcWz3vjVSoJQutF8YkrzI0SLGnkuFof4HSsWUhXrf219Lw==} + '@sigstore/tuf@4.0.2': + resolution: {integrity: sha512-TCAzTy0xzdP79EnxSjq9KQ3eaR7+FmudLC6eRKknVKZbV7ZNlGLClAAQb/HMNJ5n2OBNk2GT1tEmU0xuPr+SLQ==} engines: {node: ^20.17.0 || >=22.9.0} '@sigstore/verify@3.1.0': resolution: {integrity: sha512-mNe0Iigql08YupSOGv197YdHpPPr+EzDZmfCgMc7RPNaZTw5aLN01nBl6CHJOh3BGtnMIj83EeN4butBchc8Ag==} engines: {node: ^20.17.0 || >=22.9.0} + '@simple-libs/child-process-utils@1.0.2': + resolution: {integrity: sha512-/4R8QKnd/8agJynkNdJmNw2MBxuFTRcNFnE5Sg/G+jkSsV8/UBgULMzhizWWW42p8L5H7flImV2ATi79Ove2Tw==} + engines: {node: '>=18'} + + '@simple-libs/stream-utils@1.2.0': + resolution: {integrity: sha512-KxXvfapcixpz6rVEB6HPjOUZT22yN6v0vI0urQSk1L8MlEWPDFCZkhw2xmkyoTGYeFw7tWTZd7e3lVzRZRN/EA==} + engines: {node: '>=18'} + '@sindresorhus/is@4.6.0': resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} engines: {node: '>=10'} @@ -3493,20 +3499,16 @@ packages: '@standard-schema/spec@1.1.0': resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} - '@stylistic/eslint-plugin@5.8.0': - resolution: {integrity: sha512-WNPVF/FfBAjyi3OA7gok8swRiImNLKI4dmV3iK/GC/0xSJR7eCzBFsw9hLZVgb1+MYNLy7aDsjohxN1hA/FIfQ==} + '@stylistic/eslint-plugin@5.10.0': + resolution: {integrity: sha512-nPK52ZHvot8Ju/0A4ucSX1dcPV2/1clx0kLcH5wDmrE4naKso7TUC/voUyU1O9OTKTrR6MYip6LP0ogEMQ9jPQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: '>=9.0.0' + eslint: ^9.0.0 || ^10.0.0 '@szmarczak/http-timer@4.0.6': resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==} engines: {node: '>=10'} - '@tootallnate/once@2.0.0': - resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} - engines: {node: '>= 10'} - '@tootallnate/quickjs-emscripten@0.23.0': resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==} @@ -3632,9 +3634,6 @@ packages: '@types/folder-hash@4.0.4': resolution: {integrity: sha512-c+PwHm51Dw3fXM8SDK+93PO3oXdk4XNouCCvV67lj4aijRkZz5g67myk+9wqWWnyv3go6q96hT6ywcd3XtoZiQ==} - '@types/git-raw-commits@5.0.1': - resolution: {integrity: sha512-sd4kgxJbuZF0RDy6cX7KlKSGiwqB1mqn8nriUbxt5e1F+MO/N4hJlhaYn0Omw4g2biClFpT5Mre07x7OkGt8tg==} - '@types/graceful-fs@4.1.9': resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} @@ -3692,8 +3691,8 @@ packages: '@types/loader-utils@3.0.0': resolution: {integrity: sha512-oOi4OGpiLUbb+Q/cN9FIkkDFgOpOGZ2cUAzb5i03wrGstnG6Syx1WDMhSiB5rcP10XX7cw7Uev8mv++/aplnNg==} - '@types/lodash@4.17.23': - resolution: {integrity: sha512-RDvF6wTulMPjrNdCoYRC8gNR880JNGT8uB+REUpC2Ns4pRqQJhGz90wh7rgdXDPpCczF3VGktDuFGVnz8zP7HA==} + '@types/lodash@4.17.24': + resolution: {integrity: sha512-gIW7lQLZbue7lRSWEFql49QJJWThrTFFeIMJdp3eH4tKoxm1OvEPg02rm4wCCSHS0cL3/Fizimb35b7k8atwsQ==} '@types/micromatch@2.3.35': resolution: {integrity: sha512-J749bHo/Zu56w0G0NI/IGHLQPiSsjx//0zJhfEVAN95K/xM5C8ZDmhkXtU3qns0sBOao7HuQzr8XV1/2o5LbXA==} @@ -3704,11 +3703,11 @@ packages: '@types/node-fetch@2.6.13': resolution: {integrity: sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==} - '@types/node@22.19.11': - resolution: {integrity: sha512-BH7YwL6rA93ReqeQS1c4bsPpcfOmJasG+Fkr6Y59q83f9M1WcBRHR2vM+P9eOisYRcN3ujQoiZY8uk5W+1WL8w==} + '@types/node@22.19.15': + resolution: {integrity: sha512-F0R/h2+dsy5wJAUe3tAU6oqa2qbWY5TpNfL/RGmo1y38hiyO1w3x2jPtt76wmuaJI4DQnOBu21cNXQ2STIUUWg==} - '@types/node@24.10.9': - resolution: {integrity: sha512-ne4A0IpG3+2ETuREInjPNhUGis1SFjv1d5asp8MzEAGtOZeTeHVDOYqOgqfhvseqg/iXty2hjBf1zAOb7RNiNw==} + '@types/node@24.12.0': + resolution: {integrity: sha512-GYDxsZi3ChgmckRT9HPU0WEhKLP08ev/Yfcq2AstjrDASOYCSXeyjDsHg4v5t4jOj7cyDX3vmprafKlWIG9MXQ==} '@types/npm-package-arg@6.1.4': resolution: {integrity: sha512-vDgdbMy2QXHnAruzlv68pUtXCjmqUk3WrBAsRboRovsOmxbfn/WiYCjmecyKjGztnMps5dWp4Uq2prp+Ilo17Q==} @@ -3740,8 +3739,8 @@ packages: '@types/q@0.0.32': resolution: {integrity: sha512-qYi3YV9inU/REEfxwVcGZzbS3KG/Xs90lv0Pr+lDtuVjBPGd1A+eciXzVSaRvLify132BfcvhvEjeVahrUl0Ug==} - '@types/qs@6.14.0': - resolution: {integrity: sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==} + '@types/qs@6.15.0': + resolution: {integrity: sha512-JawvT8iBVWpzTrz3EGw9BTQFg3BQNmwERdKE22vlTxawwtbyUSlMppvZYKLZzB5zgACXdXxbD3m1bXaMqP/9ow==} '@types/range-parser@1.2.7': resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} @@ -3752,6 +3751,9 @@ packages: '@types/responselike@1.0.0': resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==} + '@types/retry@0.12.0': + resolution: {integrity: sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==} + '@types/retry@0.12.2': resolution: {integrity: sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==} @@ -3854,6 +3856,10 @@ packages: resolution: {integrity: sha512-ujT0Je8GI5BJWi+/mMoR0wxwVEQaxM+pi30xuMiJETlX80OPovb2p9E8ss87gnSVtYXtJoU9U1Cowcr6w2FE0w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/types@8.57.2': + resolution: {integrity: sha512-/iZM6FnM4tnx9csuTxspMW4BOSegshwX5oBDznJ7S4WggL7Vczz5d2W11ecc4vRrQMQHXRSxzrCsyG5EsPPTbA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/typescript-estree@8.55.0': resolution: {integrity: sha512-EwrH67bSWdx/3aRQhCoxDaHM+CrZjotc2UCCpEDVqfCE+7OjKAGWNY2HsCSTEVvWH2clYQK8pdeLp42EVs+xQw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -4089,9 +4095,10 @@ packages: '@webassemblyjs/wast-printer@1.14.1': resolution: {integrity: sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==} - '@xmldom/xmldom@0.8.11': - resolution: {integrity: sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw==} + '@xmldom/xmldom@0.8.12': + resolution: {integrity: sha512-9k/gHF6n/pAi/9tqr3m3aqkuiNosYTurLLUtc7xQ9sxB/wm7WPygCv8GYa6mS0fLJEHhqMC1ATYhz++U/lRHqg==} engines: {node: '>=10.0.0'} + deprecated: this version has critical issues, please update to the latest version '@xtuc/ieee754@1.2.0': resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} @@ -4133,12 +4140,12 @@ packages: peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - acorn-walk@8.3.4: - resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} + acorn-walk@8.3.5: + resolution: {integrity: sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==} engines: {node: '>=0.4.0'} - acorn@8.15.0: - resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} + acorn@8.16.0: + resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} engines: {node: '>=0.4.0'} hasBin: true @@ -4178,8 +4185,8 @@ packages: peerDependencies: ajv: ^8.8.2 - ajv@6.12.6: - resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + ajv@6.14.0: + resolution: {integrity: sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==} ajv@8.17.1: resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} @@ -4250,8 +4257,8 @@ packages: resolution: {integrity: sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==} engines: {node: '>=6'} - array-back@6.2.2: - resolution: {integrity: sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==} + array-back@6.2.3: + resolution: {integrity: sha512-SGDvmg6QTYiTxCBkYVmThcoa67uLl35pyzRHdpCGBOcqFy6BtwnphoFPk7LhJshD+Yk1Kt35WGWeZPTgwR4Fhw==} engines: {node: '>=12.17'} array-buffer-byte-length@1.0.2: @@ -4328,8 +4335,8 @@ packages: resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==} engines: {node: '>=4'} - ast-v8-to-istanbul@0.3.11: - resolution: {integrity: sha512-Qya9fkoofMjCBNVdWINMjB5KZvkYfaO9/anwkWnjxibpWUxo5iHl2sOdP7/uAqaRuUYuoo8rDwnbaaKVFxoUvw==} + ast-v8-to-istanbul@0.3.12: + resolution: {integrity: sha512-BRRC8VRZY2R4Z4lFIL35MwNXmwVqBityvOIwETtsCSwvjl0IdgFsy9NhdaA6j74nUdtJJlIypeRhpDam19Wq3g==} astral-regex@2.0.0: resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} @@ -4356,8 +4363,8 @@ packages: resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} engines: {node: '>=8.0.0'} - autoprefixer@10.4.24: - resolution: {integrity: sha512-uHZg7N9ULTVbutaIsDRoUkoS8/h3bdsmVJYZ5l3wv8Cp/6UIIoRDm90hZ+BwxUj/hGBEzLxdHNSKuFpn8WOyZw==} + autoprefixer@10.4.27: + resolution: {integrity: sha512-NP9APE+tO+LuJGn7/9+cohklunJsXWiaWEfV3si4Gi/XHDwVNgkwr1J3RQYFIvPy76GmJ9/bW8vyoU1LcxwKHA==} engines: {node: ^10 || ^12 || >=14} hasBin: true peerDependencies: @@ -4373,8 +4380,8 @@ packages: aws4@1.13.2: resolution: {integrity: sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==} - b4a@1.7.4: - resolution: {integrity: sha512-u20zJLDaSWpxaZ+zaAkEIB2dZZ1o+DF4T/MRbmsvGp9nletHOyiai19OzX1fF8xUBYsO1bPXxODvcd0978pnug==} + b4a@1.8.0: + resolution: {integrity: sha512-qRuSmNSkGQaHwNbM7J78Wwy+ghLEYF1zNrSeMxj4Kgw6y33O3mXcQ6Ie9fRvfU/YnxWkOchPXbaLb73TkIsfdg==} peerDependencies: react-native-b4a: '*' peerDependenciesMeta: @@ -4388,8 +4395,8 @@ packages: '@babel/core': ^7.12.0 webpack: '>=5.61.0' - babel-plugin-polyfill-corejs2@0.4.15: - resolution: {integrity: sha512-hR3GwrRwHUfYwGfrisXPIDP3JcYfBrW7wKE7+Au6wDYl7fm/ka1NEII6kORzxNU556JjfidZeBsO10kYvtV1aw==} + babel-plugin-polyfill-corejs2@0.4.17: + resolution: {integrity: sha512-aTyf30K/rqAsNwN76zYrdtx8obu0E4KoUME29B1xj+B3WxgvWkp943vYQ+z8Mv3lw9xHXMHpvSPOBxzAkIa94w==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 @@ -4398,22 +4405,22 @@ packages: peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - babel-plugin-polyfill-corejs3@0.14.0: - resolution: {integrity: sha512-AvDcMxJ34W4Wgy4KBIIePQTAOP1Ie2WFwkQp3dB7FQ/f0lI5+nM96zUnYEOE1P9sEg0es5VCP0HxiWu5fUHZAQ==} + babel-plugin-polyfill-corejs3@0.14.2: + resolution: {integrity: sha512-coWpDLJ410R781Npmn/SIBZEsAetR4xVi0SxLMXPaMO4lSf1MwnkGYMtkFxew0Dn8B3/CpbpYxN0JCgg8mn67g==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - babel-plugin-polyfill-regenerator@0.6.6: - resolution: {integrity: sha512-hYm+XLYRMvupxiQzrvXUj7YyvFFVfv5gI0R71AJzudg1g2AI2vyCPPIFEBjk162/wFzti3inBHo7isWFuEVS/A==} + babel-plugin-polyfill-regenerator@0.6.8: + resolution: {integrity: sha512-M762rNHfSF1EV3SLtnCJXFoQbbIIz0OyRwnCmV0KPC7qosSfCO0QLTSuJX3ayAebubhE6oYBAYPrBA5ljowaZg==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - balanced-match@4.0.2: - resolution: {integrity: sha512-x0K50QvKQ97fdEz2kPehIerj+YTeptKF9hyYkKf6egnwmMWAkADiO0QCzSp0R5xN8FTZgYaBfSaue46Ej62nMg==} - engines: {node: 20 || >=22} + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} bare-events@2.8.2: resolution: {integrity: sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==} @@ -4423,8 +4430,8 @@ packages: bare-abort-controller: optional: true - bare-fs@4.5.4: - resolution: {integrity: sha512-POK4oplfA7P7gqvetNmCs4CNtm9fNsx+IAh7jH7GgU0OJdge2rso0R20TNWVq6VoWcCvsTdlNDaleLHGaKx8CA==} + bare-fs@4.5.6: + resolution: {integrity: sha512-1QovqDrR80Pmt5HPAsMsXTCFcDYr+NSUKW6nd6WO5v0JBmnItc/irNRzm2KOQ5oZ69P37y+AMujNyNtG+1Rggw==} engines: {bare: '>=1.16.0'} peerDependencies: bare-buffer: '*' @@ -4432,26 +4439,29 @@ packages: bare-buffer: optional: true - bare-os@3.6.2: - resolution: {integrity: sha512-T+V1+1srU2qYNBmJCXZkUY5vQ0B4FSlL3QDROnKQYOqeiQR8UbjNHlPa+TIbM4cuidiN9GaTaOZgSEgsvPbh5A==} + bare-os@3.8.4: + resolution: {integrity: sha512-4JboWUl7/2LhgU536tjUszzaVC8/WEWKtyX5crayvlN71ih8+O2SdvBhotQeDsuhhmPZmLCrPBJEcwVPhI/kkQ==} engines: {bare: '>=1.14.0'} bare-path@3.0.0: resolution: {integrity: sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==} - bare-stream@2.7.0: - resolution: {integrity: sha512-oyXQNicV1y8nc2aKffH+BUHFRXmx6VrPzlnaEvMhram0nPBrKcEdcyBg5r08D0i8VxngHFAiVyn1QKXpSG0B8A==} + bare-stream@2.11.0: + resolution: {integrity: sha512-Y/+iQ49fL3rIn6w/AVxI/2+BRrpmzJvdWt5Jv8Za6Ngqc6V227c+pYjYYgLdpR3MwQ9ObVXD0ZrqoBztakM0rw==} peerDependencies: + bare-abort-controller: '*' bare-buffer: '*' bare-events: '*' peerDependenciesMeta: + bare-abort-controller: + optional: true bare-buffer: optional: true bare-events: optional: true - bare-url@2.3.2: - resolution: {integrity: sha512-ZMq4gd9ngV5aTMa5p9+UfY0b3skwhHELaDkhEHetMdX0LRkW9kzaym4oo/Eh+Ghm0CCDuMTsRIGM/ytUc1ZYmw==} + bare-url@2.4.0: + resolution: {integrity: sha512-NSTU5WN+fy/L0DDenfE8SXQna4voXuW0FHM7wH8i3/q9khUSchfPbPezO4zSFMnDGIf9YE+mt/RWhZgNRKRIXA==} base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} @@ -4460,12 +4470,13 @@ packages: resolution: {integrity: sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==} engines: {node: ^4.5.0 || >= 5.9} - baseline-browser-mapping@2.9.19: - resolution: {integrity: sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==} + baseline-browser-mapping@2.10.12: + resolution: {integrity: sha512-qyq26DxfY4awP2gIRXhhLWfwzwI+N5Nxk6iQi8EFizIaWIjqicQTE4sLnZZVdeKPRcVNoJOkkpfzoIYuvCKaIQ==} + engines: {node: '>=6.0.0'} hasBin: true - basic-ftp@5.1.0: - resolution: {integrity: sha512-RkaJzeJKDbaDWTIPiJwubyljaEPwpVWkm9Rt5h9Nd6h7tEXTJ3VB4qxdZBioV7JO5yLUaOKwz7vDOzlncUsegw==} + basic-ftp@5.2.0: + resolution: {integrity: sha512-VoMINM2rqJwJgfdHq6RiUudKt2BV+FY5ZFezP/ypmwayk68+NzzAQy4XXLlqsGD4MCzq3DrmNFD/uUmBJuGoXw==} engines: {node: '>=10.0.0'} batch@0.6.1: @@ -4522,15 +4533,15 @@ packages: boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} - brace-expansion@1.1.12: - resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} + brace-expansion@1.1.13: + resolution: {integrity: sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==} - brace-expansion@2.0.2: - resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} + brace-expansion@2.0.3: + resolution: {integrity: sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==} - brace-expansion@5.0.2: - resolution: {integrity: sha512-Pdk8c9poy+YhOgVWw1JNN22/HcivgKWwpxKq04M/jTmHyCZn12WPJebZxdjSa5TmBqISrUSgNYU3eRORljfCCw==} - engines: {node: 20 || >=22} + brace-expansion@5.0.5: + resolution: {integrity: sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==} + engines: {node: 18 || 20 || >=22} braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} @@ -4596,8 +4607,8 @@ packages: resolution: {integrity: sha512-U1Z/ob71V/bXfVABvNr/Kumf5VyeQRBEm6Txb0PQ6S7V5GpBM3w4Cbqz/xPDicR5tN0uvDifng8C+5qECeGwyQ==} engines: {node: '>=6.0.0'} - cacache@20.0.3: - resolution: {integrity: sha512-3pUp4e8hv07k1QlijZu6Kn7c9+ZpWWk4j3F8N3xPuCExULobqJydKYOTj1FTq58srkJsXvO7LbGAH4C0ZU3WGw==} + cacache@20.0.4: + resolution: {integrity: sha512-M3Lab8NPYlZU2exsL3bMVvMrMqgwCnMWfdZbK28bn3pK6APT/Te/I8hjRPNu1uwORY9a1eEQoifXbKPQMfMTOA==} engines: {node: ^20.17.0 || >=22.9.0} cache-content-type@1.0.1: @@ -4636,8 +4647,8 @@ packages: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} - caniuse-lite@1.0.30001770: - resolution: {integrity: sha512-x/2CLQ1jHENRbHg5PSId2sXq1CIO1CISvwWAj027ltMVG2UNgW+w9oH2+HzgEIRFembL8bUlXtfbBHR1fCg2xw==} + caniuse-lite@1.0.30001782: + resolution: {integrity: sha512-dZcaJLJeDMh4rELYFw1tvSn1bhZWYFOt468FcbHHxx/Z/dFidd1I6ciyFdi3iwfQCyOjqo9upF6lGQYtMiJWxw==} caseless@0.12.0: resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} @@ -4717,8 +4728,8 @@ packages: resolution: {integrity: sha512-bXfOC4QcT1tKXGorxL3wbJm6XJPDqEnij2gQ2m7ESQuE+/z9YFIWnl/5RpTiKWbMq3EVKR4fRLJGn6DVfu0mpw==} engines: {node: '>=18.20'} - cli-truncate@5.1.1: - resolution: {integrity: sha512-SroPvNHxUnk+vIW/dOSfNqdy1sPEFkrTk6TUtqLCnBlo3N7TNYYkzzN7uSD6+jVjrdO4+p8nH7JzH6cIvUem6A==} + cli-truncate@5.2.0: + resolution: {integrity: sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw==} engines: {node: '>=20'} cli-width@4.1.0: @@ -4786,8 +4797,8 @@ packages: resolution: {integrity: sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==} engines: {node: '>=4.0.0'} - command-line-usage@7.0.3: - resolution: {integrity: sha512-PqMLy5+YGwhMh1wS04mVG44oqDsgyLRSKJBdOo1bnYhMKBW65gZF1dRp2OZRhiTjgUHljy99qkO7bsctLaw35Q==} + command-line-usage@7.0.4: + resolution: {integrity: sha512-85UdvzTNx/+s5CkSgBm/0hzP80RFHAa7PsfeADE5ezZF3uHz3/Tqj9gIKGT9PTtpycc3Ua64T0oVulGfKxzfqg==} engines: {node: '>=12.20.0'} commander@14.0.3: @@ -4850,8 +4861,8 @@ packages: resolution: {integrity: sha512-tQMagCOC59EVgNZcC5zl7XqO30Wki9i9J3acbUvkaosCT6JX3EeFwJD7Qqp4MCikRnzS18WXV3BLIQ66ytu6+Q==} engines: {node: '>=18'} - conventional-commits-parser@6.2.1: - resolution: {integrity: sha512-20pyHgnO40rvfI0NGF/xiEoFMkXDtkF8FwHvk5BokoFoCuTQRI8vrNCNFWUOfuolKJMm1tPCHc8GgYEtr1XRNA==} + conventional-commits-parser@6.4.0: + resolution: {integrity: sha512-tvRg7FIBNlyPzjdG8wWRlPHQJJHI7DylhtRGeU9Lq+JuoPh5BKpPRX83ZdLrvXuOSu5Eo/e7SzOQhU4Hd2Miuw==} engines: {node: '>=18'} hasBin: true @@ -4879,14 +4890,14 @@ packages: copy-anything@2.0.6: resolution: {integrity: sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==} - copy-webpack-plugin@13.0.1: - resolution: {integrity: sha512-J+YV3WfhY6W/Xf9h+J1znYuqTye2xkBUIGyTPWuBAT27qajBa5mR4f8WBmfDY3YjRftT2kqZZiLi1qf0H+UOFw==} - engines: {node: '>= 18.12.0'} + copy-webpack-plugin@14.0.0: + resolution: {integrity: sha512-3JLW90aBGeaTLpM7mYQKpnVdgsUZRExY55giiZgLuX/xTQRUs1dOCwbBnWnvY6Q6rfZoXMNwzOQJCSZPppfqXA==} + engines: {node: '>= 20.9.0'} peerDependencies: webpack: ^5.1.0 - core-js-compat@3.48.0: - resolution: {integrity: sha512-OM4cAF3D6VtH/WkLtWvyNC56EZVXsZdU3iqaMG2B4WvYrlqU831pc4UtG5yp0sE9z8Y02wVN7PjW5Zf9Gt0f1Q==} + core-js-compat@3.49.0: + resolution: {integrity: sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==} core-util-is@1.0.2: resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} @@ -4894,16 +4905,12 @@ packages: core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} - cors@2.8.5: - resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} - engines: {node: '>= 0.10'} - cors@2.8.6: resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==} engines: {node: '>= 0.10'} - cosmiconfig@9.0.0: - resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} + cosmiconfig@9.0.1: + resolution: {integrity: sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ==} engines: {node: '>=14'} peerDependencies: typescript: '>=4.9.5' @@ -4939,8 +4946,8 @@ packages: css-select@6.0.0: resolution: {integrity: sha512-rZZVSLle8v0+EY8QAkDWrKhpgt6SA5OtHsgBnsj6ZaLb5dmDVOWUDtQitd9ydxxvEjhewNudS6eTVU7uOyzvXw==} - css-tree@3.1.0: - resolution: {integrity: sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==} + css-tree@3.2.1: + resolution: {integrity: sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} css-what@7.0.0: @@ -4952,8 +4959,8 @@ packages: engines: {node: '>=4'} hasBin: true - cssstyle@6.0.1: - resolution: {integrity: sha512-IoJs7La+oFp/AB033wBStxNOJt4+9hHMxsXUPANcoXL2b3W4DZKghlJ2cI/eyeRZIQ9ysvYEorVhjrcYctWbog==} + cssstyle@6.2.0: + resolution: {integrity: sha512-Fm5NvhYathRnXNVndkUsCCuR63DCLVVwGOOwQw782coXFi5HhkXdu289l59HlXZBawsyNccXfWRYvLzcDCdDig==} engines: {node: '>=20'} custom-event@1.0.1: @@ -5155,8 +5162,8 @@ packages: devtools-protocol@0.0.1045489: resolution: {integrity: sha512-D+PTmWulkuQW4D1NTiCRCFxF7pQPn0hgp4YyX4wAQ6xYXKOadSWPR3ENGDQ47MW/Ewc9v2rpC/UEEGahgBYpSQ==} - devtools-protocol@0.0.1566079: - resolution: {integrity: sha512-MJfAEA1UfVhSs7fbSQOG4czavUp1ajfg6prlAN0+cmfa2zNjaIbvq8VneP7do1WAQQIvgNJWSMeP6UyI90gIlQ==} + devtools-protocol@0.0.1581282: + resolution: {integrity: sha512-nv7iKtNZQshSW2hKzYNr46nM/Cfh5SEvE2oV0/SEGgc9XupIY5ggf84Cz8eJIkBce7S3bmTAauFD6aysMpnqsQ==} di@0.0.1: resolution: {integrity: sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA==} @@ -5227,13 +5234,13 @@ packages: ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - ejs@4.0.1: - resolution: {integrity: sha512-krvQtxc0btwSm/nvnt1UpnaFDFVJpJ0fdckmALpCgShsr/iGYHTnJiUliZTgmzq/UxTX33TtOQVKaNigMQp/6Q==} + ejs@5.0.1: + resolution: {integrity: sha512-COqBPFMxuPTPspXl2DkVYaDS3HtrD1GpzOGkNTJ1IYkifq/r9h8SVEFrjA3D9/VJGOEoMQcrlhpntcSUrM8k6A==} engines: {node: '>=0.12.18'} hasBin: true - electron-to-chromium@1.5.286: - resolution: {integrity: sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==} + electron-to-chromium@1.5.328: + resolution: {integrity: sha512-QNQ5l45DzYytThO21403XN3FvK0hOkWDG8viNf6jqS42msJ8I4tGDSpBCgvDRRPnkffafiwAym2X2eHeGD2V0w==} emoji-regex@10.6.0: resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} @@ -5269,12 +5276,12 @@ packages: resolution: {integrity: sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==} engines: {node: '>=10.0.0'} - engine.io@6.6.5: - resolution: {integrity: sha512-2RZdgEbXmp5+dVbRm0P7HQUImZpICccJy7rN7Tv+SFa55pH+lxnuw6/K1ZxxBfHoYpSkHLAO92oa8O4SwFXA2A==} + engine.io@6.6.6: + resolution: {integrity: sha512-U2SN0w3OpjFRVlrc17E6TMDmH58Xl9rai1MblNjAdwWp07Kk+llmzX0hjDpQdrDGzwmvOtgM5yI+meYX6iZ2xA==} engines: {node: '>=10.2.0'} - enhanced-resolve@5.19.0: - resolution: {integrity: sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==} + enhanced-resolve@5.20.1: + resolution: {integrity: sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA==} engines: {node: '>=10.13.0'} ent@2.2.2: @@ -5545,8 +5552,8 @@ packages: express-rate-limit@5.5.1: resolution: {integrity: sha512-MTjE2eIbHv5DyfuFz4zLYWxpqVhEhkTiwFGuB74Q9CSou2WHO52nlE5y3Zlg6SIsiYUIPj6ifFxnkPz6O3sIUg==} - express-rate-limit@8.2.1: - resolution: {integrity: sha512-PCZEIEIxqwhzw4KF0n7QF4QqruVTcF73O5kFKUnGOyjbCCgizBBiFaYpd/fnBLUMPw/BWw9OsiN7GgrNYr7j6g==} + express-rate-limit@8.3.1: + resolution: {integrity: sha512-D1dKN+cmyPWuvB+G2SREQDzPY1agpBIcTa9sJxOPMCNeH3gwzhqJRDWCXW3gg0y//+LQ/8j52JbMROWyrKdMdw==} engines: {node: '>= 16'} peerDependencies: express: '>= 4.11' @@ -5629,9 +5636,6 @@ packages: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} - filelist@1.0.4: - resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} - fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} @@ -5672,8 +5676,8 @@ packages: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} - firebase@12.8.0: - resolution: {integrity: sha512-S1tCIR3ENecee0tY2cfTHfMkXqkitHfbsvqpCtvsT0Zi9vDB7A4CodAjHfHCjVvu/XtGy1LHLjOasVcF10rCVw==} + firebase@12.11.0: + resolution: {integrity: sha512-W9f3Y+cgQYgF9gvCGxt0upec8zwAtiQVcHuU8MfzUIgVU/9fRQWtu48Geiv1lsigtBz9QHML++Km9xAKO5GB5Q==} flat-cache@4.0.1: resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} @@ -5683,11 +5687,11 @@ packages: resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} hasBin: true - flatted@3.3.3: - resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + flatted@3.4.2: + resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} - folder-hash@4.1.1: - resolution: {integrity: sha512-1ZSlKJSbET3XpglnEXC9g+QF4QRZhqHIjpFfa4pAMfO4tu/XYPafpeHEX6zOFS2EolOIXr0lPh1eSjmdWItX2w==} + folder-hash@4.1.2: + resolution: {integrity: sha512-rjdiHw3ShVonhMZZXvD/I28boUkbJFT/RBsg5MbQQd8e61PhevIwFwmL218/AscBEsW/blH4BC4A+kFeIqHVfw==} engines: {node: '>=10.10.0'} hasBin: true @@ -5773,8 +5777,8 @@ packages: functions-have-names@1.2.3: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} - gaxios@7.1.3: - resolution: {integrity: sha512-YGGyuEdVIjqxkxVH1pUTMY/XtmmsApXrCVv5EU25iX6inEPbV+VakJfLealkBtJN69AQmh1eGOdCl9Sm1UP6XQ==} + gaxios@7.1.4: + resolution: {integrity: sha512-bTIgTsM2bWn3XklZISBTQX7ZSddGW+IO3bMdGaemHZ3tbqExMENHLx6kKZ/KlejgrMtj8q7wBItt51yegqalrA==} engines: {node: '>=18'} gcp-metadata@8.1.2: @@ -5793,8 +5797,8 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} - get-east-asian-width@1.4.0: - resolution: {integrity: sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==} + get-east-asian-width@1.5.0: + resolution: {integrity: sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==} engines: {node: '>=18'} get-intrinsic@1.3.0: @@ -5821,8 +5825,8 @@ packages: resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} engines: {node: '>= 0.4'} - get-tsconfig@4.13.6: - resolution: {integrity: sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==} + get-tsconfig@4.13.7: + resolution: {integrity: sha512-7tN6rFgBlMgpBML5j8typ92BKFi2sFQvIdpAqLA2beia5avZDrMs0FLZiM5etShWq5irVyGcGMEA1jcDaK7A/Q==} get-uri@6.0.5: resolution: {integrity: sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==} @@ -5831,11 +5835,6 @@ packages: getpass@0.1.7: resolution: {integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==} - git-raw-commits@5.0.0: - resolution: {integrity: sha512-I2ZXrXeOc0KrCvC7swqtIFXFN+rbjnC7b2T943tvemIOVNl+XP8YnA9UVwqFhzzLClnSA60KR/qEjLpXzs73Qg==} - engines: {node: '>=18'} - hasBin: true - glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -5858,9 +5857,9 @@ packages: deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me hasBin: true - glob@13.0.3: - resolution: {integrity: sha512-/g3B0mC+4x724v1TgtBlBtt2hPi/EWptsIAmXUx9Z2rvBYleQcsrmaOzd5LyL50jf/Soi83ZDJmw2+XqvH/EeA==} - engines: {node: 20 || >=22} + glob@13.0.6: + resolution: {integrity: sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==} + engines: {node: 18 || 20 || >=22} glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} @@ -5886,8 +5885,8 @@ packages: resolution: {integrity: sha512-HJRTIH2EeH44ka+LWig+EqT2ONSYpVlNfx6pyd592/VF1TbfljJ7elwie7oSwcViLGqOdWocSdu2txwBF9bjmQ==} engines: {node: '>=0.10.0'} - google-auth-library@10.5.0: - resolution: {integrity: sha512-7ABviyMOlX5hIVD60YOfHw4/CxOfBhyduaYB+wbFWCWoni4N7SLcV46hrVRktuBbZjFC9ONyqamZITN7q3n32w==} + google-auth-library@10.6.2: + resolution: {integrity: sha512-e27Z6EThmVNNvtYASwQxose/G57rkRuaRbQyxM2bvYLLX/GqWZ5chWq2EBoUchJbCc57eC9ArzO5wMsEmWftCw==} engines: {node: '>=18'} google-gax@5.0.6: @@ -5915,8 +5914,8 @@ packages: peerDependencies: graphql: ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - graphql@16.12.0: - resolution: {integrity: sha512-DKKrynuQRne0PNpEbzuEdHlYOMksHSUI8Zc9Unei5gTsMNA2/vMpoMz/yKba50pejK56qj98qM0SjYxAKi13gQ==} + graphql@16.13.2: + resolution: {integrity: sha512-5bJ+nf/UCpAjHM8i06fl7eLyVC9iuNAjm9qzkiu2ZGhM0VscSvS6WDPfAwkdkBuoXGM9FJSbKl6wylMwP9Ktig==} engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} grpc-gcp@1.0.1: @@ -5925,10 +5924,6 @@ packages: peerDependencies: protobufjs: '*' - gtoken@8.0.0: - resolution: {integrity: sha512-+CqsMbHPiSTdtSO14O51eMNlrp9N79gmeqmXeouJOhfucAedHw9noVe/n5uJk3tbKE6a+6ZCQg3RPhVhHByAIw==} - engines: {node: '>=18'} - gunzip-maybe@1.4.2: resolution: {integrity: sha512-4haO1M4mLO91PW57BMsDFf75UmwoRX0GkdD+Faw+Lr+r/OZrOCS0pIBwOL1xCKQqnQzbNFGgK2V2CpBUPeFNTw==} hasBin: true @@ -5981,8 +5976,8 @@ packages: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} - hono@4.11.9: - resolution: {integrity: sha512-Eaw2YTGM6WOxA6CXbckaEvslr2Ne4NFsKrvc0v97JD5awbmeBLO5w9Ho9L9kmKonrwF9RJlW6BxT1PVv/agBHQ==} + hono@4.12.9: + resolution: {integrity: sha512-wy3T8Zm2bsEvxKZM5w21VdHDDcwVS1yUFFY6i8UobSsKfFceT7TOwhbhfKsDyx7tYQlmRM5FLpIuYvNFyjctiA==} engines: {node: '>=16.9.0'} hosted-git-info@9.0.2: @@ -6034,10 +6029,6 @@ packages: http-parser-js@0.5.10: resolution: {integrity: sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==} - http-proxy-agent@5.0.0: - resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} - engines: {node: '>= 6'} - http-proxy-agent@7.0.2: resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} engines: {node: '>= 14'} @@ -6143,12 +6134,12 @@ packages: immediate@3.0.6: resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} - immutable@3.8.2: - resolution: {integrity: sha512-15gZoQ38eYjEjxkorfbcgBKBL6R7T459OuK+CpcWt7O3KF4uPCx2tD0uFETlUDIyo+1789crbMhTvQBSR5yBMg==} + immutable@3.8.3: + resolution: {integrity: sha512-AUY/VyX0E5XlibOmWt10uabJzam1zlYjwiEgQSDc5+UIkFNaF9WM0JxXKaNMGf+F/ffUF+7kRKXM9A7C0xXqMg==} engines: {node: '>=0.10.0'} - immutable@5.1.4: - resolution: {integrity: sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA==} + immutable@5.1.5: + resolution: {integrity: sha512-t7xcm2siw+hlUM68I+UEOK+z84RzmN59as9DZ7P1l0994DKUWV7UXBMQZVxaoMSRQ+PBZbHCOoBt7a2wxOMt+A==} import-fresh@3.3.1: resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} @@ -6190,10 +6181,6 @@ packages: resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} engines: {node: '>= 0.4'} - ip-address@10.0.1: - resolution: {integrity: sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==} - engines: {node: '>= 12'} - ip-address@10.1.0: resolution: {integrity: sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==} engines: {node: '>= 12'} @@ -6318,8 +6305,8 @@ packages: resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} engines: {node: '>= 0.4'} - is-network-error@1.3.0: - resolution: {integrity: sha512-6oIwpsgRfnDiyEDLMay/GqCl3HoAtH5+RUKW29gYkL0QA+ipzpDLA16yQs7/RHCSu+BwgbJaOUqa4A99qNVQVw==} + is-network-error@1.3.1: + resolution: {integrity: sha512-6QCxa49rQbmUWLfk0nuGqzql9U8uaV2H6279bRErPBHe/109hCzsLUBUHfbEtvLIHBd6hyXbgedBSHevm43Edw==} engines: {node: '>=16'} is-node-process@1.2.0: @@ -6461,10 +6448,6 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - isexe@3.1.5: - resolution: {integrity: sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w==} - engines: {node: '>=18'} - isexe@4.0.0: resolution: {integrity: sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==} engines: {node: '>=20'} @@ -6503,15 +6486,6 @@ packages: jackspeak@3.4.3: resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} - jackspeak@4.2.3: - resolution: {integrity: sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==} - engines: {node: 20 || >=22} - - jake@10.9.4: - resolution: {integrity: sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==} - engines: {node: '>=10'} - hasBin: true - jasmine-core@2.8.0: resolution: {integrity: sha512-SNkOkS+/jMZvLhuSx1fjhcNWUC/KG6oVyFUGkSBEr9n1axSNduWU8GlI7suaHXr4yxjet6KjrUZxUTE5WzzWwQ==} @@ -6521,8 +6495,8 @@ packages: jasmine-core@5.13.0: resolution: {integrity: sha512-vsYjfh7lyqvZX5QgqKc4YH8phs7g96Z8bsdIFNEU3VqXhlHaq+vov/Fgn/sr6MiUczdZkyXRC3TX369Ll4Nzbw==} - jasmine-core@6.0.0: - resolution: {integrity: sha512-fmBb8aruz2mEIDBUGWOGNmxhXwFJs44SSzwbMcBDqQnNChavPTq3Ra9A6WAn6WdxvxWEdakKTcEb3NzeR3yD1A==} + jasmine-core@6.1.0: + resolution: {integrity: sha512-p/tjBw58O6vxKIWMlrU+yys8lqR3+l3UrqwNTT7wpj+dQ7N4etQekFM8joI+cWzPDYqZf54kN+hLC1+s5TvZvg==} jasmine-reporters@2.5.2: resolution: {integrity: sha512-qdewRUuFOSiWhiyWZX8Yx3YNQ9JG51ntBEO4ekLQRpktxFTwUHy24a86zD/Oi2BRTKksEdfWQZcQFqzjqIkPig==} @@ -6538,8 +6512,8 @@ packages: resolution: {integrity: sha512-oLCXIhEb5e0zzjn9GyuvcuisvLBwUjmgz7a0RNGWKwQtJCDld4m+vwKUpAIJVLB5vbmQFdtKhT86/tIZlJ5gYw==} hasBin: true - jasmine@6.0.0: - resolution: {integrity: sha512-eSPL6LPWT39WwvHSEEbRXuSvioXMTheNhIPaeUT1OPmSprDZwj4S29884DkTx6/tyiOWTWB1N+LdW2ZSg74aEA==} + jasmine@6.1.0: + resolution: {integrity: sha512-WPphPqEMY0uBRMjuhRHoVoxQNvJuxIMqz0yIcJ3k3oYxBedeGoH60/NXNgasxnx2FvfXrq5/r+2wssJ7WE8ABw==} hasBin: true jasminewd2@2.2.0: @@ -6554,8 +6528,8 @@ packages: resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} hasBin: true - jose@6.1.3: - resolution: {integrity: sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ==} + jose@6.2.2: + resolution: {integrity: sha512-d7kPDd34KO/YnzaDOlikGpOurfF0ByC2sEV4cANCtdqLlTfBlw2p14O/5d/zv40gJPbIQxfES3nSx1/oYNyuZQ==} js-base64@3.7.8: resolution: {integrity: sha512-hNngCeKxIUQiEUN3GPJOkz4wF/YvdUdbNL9hsBcMQTkKzboD7T/q3OYOuuPZLUE6dBxSGpwhk5mwuDud7JVAow==} @@ -6618,6 +6592,9 @@ packages: json-stringify-safe@5.0.1: resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + json-with-bigint@3.5.8: + resolution: {integrity: sha512-eq/4KP6K34kwa7TcFdtvnftvHCD9KvHOGGICWwMFc4dOOKF5t4iYqnfLK8otCRCRv06FXOzGGyqE8h8ElMvvdw==} + json5@1.0.2: resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} hasBin: true @@ -6718,12 +6695,12 @@ packages: resolution: {integrity: sha512-UqyYyH5YEXaJrf9S8E23GoJFQZXkBVJ9zYYMPGz919MSX1KuvAcycIuS0ci150HCoPf4XQVhQ84Qf8xRPWxFaQ==} engines: {node: '>= 7.6.0'} - koa@2.16.3: - resolution: {integrity: sha512-zPPuIt+ku1iCpFBRwseMcPYQ1cJL8l60rSmKeOuGfOXyE6YnTBmf2aEFNL2HQGrD0cPcLO/t+v9RTgC+fwEh/g==} + koa@2.16.4: + resolution: {integrity: sha512-3An0GCLDSR34tsCO4H8Tef8Pp2ngtaZDAZnsWJYelqXUK5wyiHvGItgK/xcSkmHLSTn1Jcho1mRQs2ehRzvKKw==} engines: {node: ^4.8.4 || ^6.10.1 || ^7.10.1 || >= 8.1.4} - launch-editor@2.12.0: - resolution: {integrity: sha512-giOHXoOtifjdHqUamwKq6c49GzBdLjvxrd2D+Q4V6uOHopJv7p9VJxikDsQ/CBXZbEITgUqSVHXLTG3VhPP1Dg==} + launch-editor@2.13.2: + resolution: {integrity: sha512-4VVDnbOpLXy/s8rdRCSXb+zfMeFR0WlJWpET1iA9CQdlZDfwyLjUuGQzXU4VeOoey6AicSAluWan7Etga6Kcmg==} less-loader@12.3.1: resolution: {integrity: sha512-JZZmG7gMzoDP3VGeEG8Sh6FW5wygB5jYL7Wp29FFihuRTsIBacqO3LbRPr2yStYD11riVf13selLm/CPFRDBRQ==} @@ -6870,8 +6847,8 @@ packages: lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - lru-cache@11.2.6: - resolution: {integrity: sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==} + lru-cache@11.2.7: + resolution: {integrity: sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==} engines: {node: 20 || >=22} lru-cache@5.1.1: @@ -6902,8 +6879,8 @@ packages: make-error@1.3.6: resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} - make-fetch-happen@15.0.3: - resolution: {integrity: sha512-iyyEpDty1mwW3dGlYXAJqC/azFn5PPvgKVwXayOGBSmKLxhKZ9fg4qIan2ePpp1vJIwfFiO34LAPZgq9SZW9Aw==} + make-fetch-happen@15.0.5: + resolution: {integrity: sha512-uCbIa8jWWmQZt4dSnEStkVC6gdakiinAm4PiGsywIkguF0eWMdcjDz0ECYhUolFU3pFLOev9VNPCEygydXnddg==} engines: {node: ^20.17.0 || >=22.9.0} marky@1.3.0: @@ -6913,8 +6890,8 @@ packages: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} - mdn-data@2.12.2: - resolution: {integrity: sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==} + mdn-data@2.27.1: + resolution: {integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==} media-typer@0.3.0: resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} @@ -6924,8 +6901,8 @@ packages: resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} engines: {node: '>= 0.8'} - memfs@4.56.10: - resolution: {integrity: sha512-eLvzyrwqLHnLYalJP7YZ3wBe79MXktMdfQbvMrVD80K+NhrIukCVBvgP30zTJYEEDh9hZ/ep9z0KOdD7FSHo7w==} + memfs@4.57.1: + resolution: {integrity: sha512-WvzrWPwMQT+PtbX2Et64R4qXKK0fj/8pO85MrUCzymX3twwCiJCdvntW3HdhG1teLJcHDDLIKx5+c3HckWYZtQ==} peerDependencies: tslib: '2' @@ -7011,27 +6988,23 @@ packages: minimalistic-assert@1.0.1: resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} - minimatch@10.1.1: - resolution: {integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==} - engines: {node: 20 || >=22} - - minimatch@10.2.0: - resolution: {integrity: sha512-ugkC31VaVg9cF0DFVoADH12k6061zNZkZON+aX8AWsR9GhPcErkcMBceb6znR8wLERM2AkkOxy2nWRLpT9Jq5w==} - engines: {node: 20 || >=22} - - minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + minimatch@10.2.4: + resolution: {integrity: sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==} + engines: {node: 18 || 20 || >=22} - minimatch@5.1.6: - resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} - engines: {node: '>=10'} + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} minimatch@7.4.6: resolution: {integrity: sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==} engines: {node: '>=10'} - minimatch@9.0.5: - resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + minimatch@7.4.9: + resolution: {integrity: sha512-Brg/fp/iAVDOQoHxkuN5bEYhyQlZhxddI78yWsCbeEwTHXQjlNLtiJDUsp1GIptVqMI7/gkJMz4vVAc01mpoBw==} + engines: {node: '>=10'} + + minimatch@9.0.9: + resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==} engines: {node: '>=16 || 14 >=14.17'} minimist@1.2.8: @@ -7041,12 +7014,12 @@ packages: resolution: {integrity: sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==} engines: {node: '>=16 || 14 >=14.17'} - minipass-fetch@5.0.1: - resolution: {integrity: sha512-yHK8pb0iCGat0lDrs/D6RZmCdaBT64tULXjdxjSMAqoDi18Q3qKEUTHypHQZQd9+FYpIS+lkvpq6C/R6SbUeRw==} + minipass-fetch@5.0.2: + resolution: {integrity: sha512-2d0q2a8eCi2IRg/IGubCNRJoYbA1+YPXAzQVRFmB45gdGZafyivnZ5YSEfo3JikbjGxOdntGFvBQGqaSMXlAFQ==} engines: {node: ^20.17.0 || >=22.9.0} - minipass-flush@1.0.5: - resolution: {integrity: sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==} + minipass-flush@1.0.7: + resolution: {integrity: sha512-TbqTz9cUwWyHS2Dy89P3ocAGUGxKjjLuR9z8w4WUTGAVgEj17/4nhgo2Du56i0Fm3Pm30g4iA8Lcqctc76jCzA==} engines: {node: '>= 8'} minipass-pipeline@1.2.4: @@ -7061,8 +7034,8 @@ packages: resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} engines: {node: '>=8'} - minipass@7.1.2: - resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + minipass@7.1.3: + resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} engines: {node: '>=16 || 14 >=14.17'} minizlib@3.1.0: @@ -7104,16 +7077,16 @@ packages: resolution: {integrity: sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==} hasBin: true - msgpackr@1.11.8: - resolution: {integrity: sha512-bC4UGzHhVvgDNS7kn9tV8fAucIYUBuGojcaLiz7v+P63Lmtm0Xeji8B/8tYKddALXxJLpwIeBmUN3u64C4YkRA==} + msgpackr@1.11.9: + resolution: {integrity: sha512-FkoAAyyA6HM8wL882EcEyFZ9s7hVADSwG9xrVx3dxxNQAtgADTrJoEWivID82Iv1zWDsv/OtbrrcZAzGzOMdNw==} multicast-dns@7.2.5: resolution: {integrity: sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==} hasBin: true - multimatch@7.0.0: - resolution: {integrity: sha512-SYU3HBAdF4psHEL/+jXDKHO95/m5P2RvboHT2Y0WtTttvJLP4H/2WS9WlQPFvF6C8d6SpLw8vjCnQOnVIVOSJQ==} - engines: {node: '>=18'} + multimatch@8.0.0: + resolution: {integrity: sha512-0D10M2/MnEyvoog7tmozlpSqL3HEU1evxUFa3v1dsKYmBDFSP1dLSX4CH2rNjpQ+4Fps8GKmUkCwiKryaKqd9A==} + engines: {node: '>=20'} mute-stream@2.0.0: resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} @@ -7134,8 +7107,8 @@ packages: natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - needle@3.3.1: - resolution: {integrity: sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==} + needle@3.5.0: + resolution: {integrity: sha512-jaQyPKKk2YokHrEg+vFDYxXIHTCBgiZwSHOoVx/8V3GIBS8/VN6NdVRmg8q1ERtPkMvmOvebsgga4sAj5hls/w==} engines: {node: '>= 4.4.x'} hasBin: true @@ -7158,12 +7131,12 @@ packages: resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==} engines: {node: '>= 0.4.0'} - ng-packagr@21.2.0-next.0: - resolution: {integrity: sha512-BkRAqx1ZljIYpBbjDi/+3y8AMo9S19vm8zx3YWpqMAaIpDb7cvsT+Une9b4oyEK/7p+XvWw+LaPVleTAQtQEMQ==} + ng-packagr@21.2.2: + resolution: {integrity: sha512-VO0y7RU3Ik8E14QdrryVyVbTAyqO2MK9W9GrG4e/4N8+ti+DWiBSQmw0tIhnV67lEjQwCccPA3ZBoIn3B1vJ1Q==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} hasBin: true peerDependencies: - '@angular/compiler-cli': ^21.0.0 || ^21.1.0-next || ^21.2.0-next + '@angular/compiler-cli': ^21.0.0 || ^21.2.0-next tailwindcss: ^2.0.0 || ^3.0.0 || ^4.0.0 tslib: ^2.3.0 typescript: '>=5.9 <6.0' @@ -7171,8 +7144,21 @@ packages: tailwindcss: optional: true - nock@14.0.10: - resolution: {integrity: sha512-Q7HjkpyPeLa0ZVZC5qpxBt5EyLczFJ91MEewQiIi9taWuA0KB/MDJlUWtON+7dGouVdADTQsf9RA7TZk6D8VMw==} + ng-packagr@22.0.0-next.1: + resolution: {integrity: sha512-eCmMoX4U1WIv2RWCaYQBD+jEk7rmvAJWMxdLQiA/lt6hd6FwuNKZuzmaI8dT6eMXX7e4vrDrg1zhlPth6qwrBA==} + engines: {node: ^22.22.0 || >=24.13.1} + hasBin: true + peerDependencies: + '@angular/compiler-cli': ^22.0.0-next + tailwindcss: ^2.0.0 || ^3.0.0 || ^4.0.0 + tslib: ^2.3.0 + typescript: '>=5.9 <6.1' + peerDependenciesMeta: + tailwindcss: + optional: true + + nock@14.0.11: + resolution: {integrity: sha512-u5xUnYE+UOOBA6SpELJheMCtj2Laqx15Vl70QxKo43Wz/6nMHXS7PrEioXLjXAwhmawdEMNImwKCcPhBJWbKVw==} engines: {node: '>=18.20.0 <20 || >=20.12.1'} node-addon-api@6.1.0: @@ -7224,8 +7210,8 @@ packages: engines: {node: ^20.17.0 || >=22.9.0} hasBin: true - node-releases@2.0.27: - resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} + node-releases@2.0.36: + resolution: {integrity: sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==} nopt@9.0.0: resolution: {integrity: sha512-Zhq3a+yFKrYwSBluL4H9XP3m3y5uvQkB/09CwDruCiRmR/UJYnn9W4R48ry0uGC70aeTPKLynBtscP9efFFcPw==} @@ -7256,8 +7242,8 @@ packages: resolution: {integrity: sha512-IciCE3SY3uE84Ld8WZU23gAPPV9rIYod4F+rc+vJ7h7cwAJt9Vk6TVsK60ry7Uj3SRS3bqRRIGuTp9YVlk6WNA==} engines: {node: ^20.17.0 || >=22.9.0} - npm-packlist@10.0.3: - resolution: {integrity: sha512-zPukTwJMOu5X5uvm0fztwS5Zxyvmk38H/LfidkOMt3gbZVCyro2cD/ETzwzVPcWZA3JOyPznfUN/nkyFiyUbxg==} + npm-packlist@10.0.4: + resolution: {integrity: sha512-uMW73iajD8hiH4ZBxEV3HC+eTnppIqwakjOYuvgddnalIw2lJguKviK1pcUJDlIWm1wSJkchpDZDSVVsZEYRng==} engines: {node: ^20.17.0 || >=22.9.0} npm-pick-manifest@11.0.3: @@ -7420,6 +7406,10 @@ packages: resolution: {integrity: sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==} engines: {node: '>=8'} + p-retry@4.6.2: + resolution: {integrity: sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==} + engines: {node: '>=8'} + p-retry@6.2.1: resolution: {integrity: sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==} engines: {node: '>=16.17'} @@ -7504,15 +7494,15 @@ packages: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} - path-scurry@2.0.1: - resolution: {integrity: sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==} - engines: {node: 20 || >=22} + path-scurry@2.0.2: + resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==} + engines: {node: 18 || 20 || >=22} - path-to-regexp@0.1.12: - resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==} + path-to-regexp@0.1.13: + resolution: {integrity: sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==} - path-to-regexp@8.3.0: - resolution: {integrity: sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==} + path-to-regexp@8.4.0: + resolution: {integrity: sha512-PuseHIvAnz3bjrM2rGJtSgo1zjgxapTLZ7x2pjhzWwlp4SJQgK3f3iZIQwkpEnBaKz6seKBADpM4B4ySkuYypg==} path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} @@ -7536,12 +7526,12 @@ packages: picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + picomatch@2.3.2: + resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} engines: {node: '>=8.6'} - picomatch@4.0.3: - resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + picomatch@4.0.4: + resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} engines: {node: '>=12'} pify@2.3.0: @@ -7589,8 +7579,8 @@ packages: resolution: {integrity: sha512-4peoBq4Wks0riS0z8741NVv+/8IiTvqnZAr8QGgtdifrtpdXbNw/FxRS1l6NFqm4EMzuS0EDqNNx4XGaz8cuyQ==} engines: {node: '>=18'} - pkijs@3.3.3: - resolution: {integrity: sha512-+KD8hJtqQMYoTuL1bbGOqxb4z+nZkTAwVdNtWwe8Tc2xNbEmdJYIYoc6Qt0uF55e6YW6KuTHw1DjQ18gMhzepw==} + pkijs@3.4.0: + resolution: {integrity: sha512-emEcLuomt2j03vxD54giVB4SxTjnsqkU692xZOZXHDVoYyypEm+b3jpiTcc+Cf+myooc+/Ly0z01jqeNHVgJGw==} engines: {node: '>=16.0.0'} pluralize@8.0.0: @@ -7742,8 +7732,8 @@ packages: pump@2.0.1: resolution: {integrity: sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==} - pump@3.0.3: - resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} + pump@3.0.4: + resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} pumpify@1.5.1: resolution: {integrity: sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==} @@ -7759,8 +7749,8 @@ packages: resolution: {integrity: sha512-MRtTAZfQTluz3U2oU/X2VqVWPcR1+94nbA2V6ZrSZRVEwLqZ8eclZ551qGFQD/vD2PYqHJwWOW/fpC721uznVw==} engines: {node: '>=14.1.0'} - puppeteer-core@24.37.3: - resolution: {integrity: sha512-fokQ8gv+hNgsRWqVuP5rUjGp+wzV5aMTP3fcm8ekNabmLGlJdFHas1OdMscAH9Gzq4Qcf7cfI/Pe6wEcAqQhqg==} + puppeteer-core@24.40.0: + resolution: {integrity: sha512-MWL3XbUCfVgGR0gRsidzT6oKJT2QydPLhMITU6HoVWiiv4gkb6gJi3pcdAa8q4HwjBTbqISOWVP4aJiiyUJvag==} engines: {node: '>=18'} puppeteer@18.2.1: @@ -7787,10 +7777,6 @@ packages: resolution: {integrity: sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==} engines: {node: '>=0.9'} - qs@6.14.0: - resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} - engines: {node: '>=0.6'} - qs@6.14.2: resolution: {integrity: sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==} engines: {node: '>=0.6'} @@ -7816,9 +7802,6 @@ packages: quicktype-core@23.2.6: resolution: {integrity: sha512-asfeSv7BKBNVb9WiYhFRBvBZHcRutPRBwJMxW0pefluK4kkKu4lv0IvZBwFKvw2XygLcL1Rl90zxWDHYgkwCmA==} - randombytes@2.1.0: - resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} - range-parser@1.2.1: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} @@ -8000,6 +7983,13 @@ packages: rollup: ^3.29.4 || ^4 typescript: ^4.5 || ^5.0 + rollup-plugin-dts@6.4.1: + resolution: {integrity: sha512-l//F3Zf7ID5GoOfLfD8kroBjQKEKpy1qfhtAdnpibFZMffPaylrg1CoDC2vGkPeTeyxUe4bVFCln2EFuL7IGGg==} + engines: {node: '>=20'} + peerDependencies: + rollup: ^3.29.4 || ^4 + typescript: ^4.5 || ^5.0 || ^6.0 + rollup-plugin-sourcemaps2@0.5.4: resolution: {integrity: sha512-XK6ITvEsKtUFN1GQbYKoqilwh1yKxTS9BLaFlVsm0IaYUYe3eVnhBWzKP4AHbkBO2BNOheGNlf407K7wCj6Rrw==} engines: {node: '>=18.0.0'} @@ -8086,8 +8076,8 @@ packages: saucelabs@1.5.0: resolution: {integrity: sha512-jlX3FGdWvYf4Q3LFfFWS1QvPg3IGCGWxIc8QBFdPTbpTJnt/v17FHXYVAn7C8sHf1yUXo2c7yIM0isDryfYtHQ==} - sax@1.4.4: - resolution: {integrity: sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==} + sax@1.6.0: + resolution: {integrity: sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==} engines: {node: '>=11.0.0'} saxes@6.0.0: @@ -8140,8 +8130,9 @@ packages: resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} engines: {node: '>= 18'} - serialize-javascript@6.0.2: - resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} + serialize-javascript@7.0.5: + resolution: {integrity: sha512-F4LcB0UqUl1zErq+1nYEEzSHJnIwb3AF2XWB94b+afhrekOUijwooAYqFyRbjYkm2PAKBabx6oYv/xDxNi8IBw==} + engines: {node: '>=20.0.0'} serve-index@1.9.2: resolution: {integrity: sha512-KDj11HScOaLmrPxl70KYNW1PksP4Nb/CLL2yvC+Qd2kHMPEEpfc4Re2e4FOay+bC/+XQl/7zAcWON3JVo5v3KQ==} @@ -8240,6 +8231,10 @@ packages: resolution: {integrity: sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==} engines: {node: '>=18'} + slice-ansi@8.0.0: + resolution: {integrity: sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg==} + engines: {node: '>=20'} + smart-buffer@4.2.0: resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} @@ -8251,8 +8246,8 @@ packages: resolution: {integrity: sha512-uP0bpjWrjQmUt5DTHq9RuoCBdFJF10cdX9X+a368j/Ft0wmaVgxlrjvK3kjvgCODOMMOz9lcaRzxmso0bTWZ/g==} engines: {node: '>=10.0.0'} - socket.io-parser@4.2.5: - resolution: {integrity: sha512-bPMmpy/5WWKHea5Y/jYAP6k74A+hvmRCQaJuJB6I/ML5JZq/KfNieUVo/3Mh7SAqn7TyFdIo6wqYHInG1MU1bQ==} + socket.io-parser@4.2.6: + resolution: {integrity: sha512-asJqbVBDsBCJx0pTqw3WfesSY0iRX+2xzWEWzrpcH7L6fLzrhyF8WPI8UaeM4YCuDfpwA/cgsdugMsmtz8EJeg==} engines: {node: '>=10.0.0'} socket.io@4.8.3: @@ -8304,20 +8299,20 @@ packages: resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} engines: {node: '>= 12'} - spdx-correct@3.2.0: - resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} - spdx-exceptions@2.5.0: resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} spdx-expression-parse@3.0.1: resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + spdx-expression-parse@4.0.0: + resolution: {integrity: sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==} + spdx-expression-validate@2.0.0: resolution: {integrity: sha512-b3wydZLM+Tc6CFvaRDBOF9d76oGIHNCLYFeHbftFXUWjnfZWganmDmvtM5sm1cRwJc/VDBMLyGGrsLFd1vOxbg==} - spdx-license-ids@3.0.22: - resolution: {integrity: sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==} + spdx-license-ids@3.0.23: + resolution: {integrity: sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==} spdy-transport@3.0.0: resolution: {integrity: sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==} @@ -8400,8 +8395,8 @@ packages: resolution: {integrity: sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==} engines: {node: '>=8.0'} - streamx@2.23.0: - resolution: {integrity: sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==} + streamx@2.25.0: + resolution: {integrity: sha512-0nQuG6jf1w+wddNEEXCF4nTg3LtufWINB5eFEN+5TNZW7KWJp6x87+JFL43vaAUPyCfH1wID+mNVyW6OHtFamg==} strict-event-emitter@0.5.1: resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==} @@ -8418,8 +8413,8 @@ packages: resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} engines: {node: '>=18'} - string-width@8.1.1: - resolution: {integrity: sha512-KpqHIdDL9KwYk22wEOg/VIqYbrnLeSApsKT/bSj6Ez7pn3CftUiLAv2Lccpq1ALcpLV9UX1Ppn92npZWu2w/aw==} + string-width@8.2.0: + resolution: {integrity: sha512-6hJPQ8N0V0P3SNmP6h2J99RLuzrWz2gvT7VnK5tKvrNqJoyS9W4/Fb8mo31UiPvy00z7DQXkP2hnKBVav76thw==} engines: {node: '>=20'} string.prototype.trim@1.2.10: @@ -8448,8 +8443,8 @@ packages: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} - strip-ansi@7.1.2: - resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==} + strip-ansi@7.2.0: + resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} engines: {node: '>=12'} strip-bom@3.0.0: @@ -8494,15 +8489,15 @@ packages: resolution: {integrity: sha512-iK5/YhZxq5GO5z8wb0bY1317uDF3Zjpha0QFFLA8/trAoiLbQD0HUbMesEaxyzUgDxi2QlcbM8IvqOlEjgoXBA==} engines: {node: '>=12.17'} - tapable@2.3.0: - resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} + tapable@2.3.2: + resolution: {integrity: sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA==} engines: {node: '>=6'} tar-fs@2.1.1: resolution: {integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==} - tar-fs@3.1.1: - resolution: {integrity: sha512-LZA0oaPOc2fVo82Txf3gw+AkEd38szODlptMYejQUhndHMLQ9M059uXR+AfS7DNo0NpINvSqDsvyaCrBVkptWg==} + tar-fs@3.1.2: + resolution: {integrity: sha512-QGxxTxxyleAdyM3kpFs14ymbYmNFrfY+pHj7Z8FgtbZ7w2//VAgLMac7sT6nRpIHjppXO2AwwEOg0bPFVRcmXw==} tar-stream@2.2.0: resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} @@ -8511,16 +8506,19 @@ packages: tar-stream@3.1.7: resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==} - tar@7.5.9: - resolution: {integrity: sha512-BTLcK0xsDh2+PUe9F6c2TlRp4zOOBMTkoQHQIWSIzI0R7KG46uEwq4OPk2W7bZcprBMsuaeFsqwYr7pjh6CuHg==} + tar@7.5.13: + resolution: {integrity: sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng==} engines: {node: '>=18'} - teeny-request@10.1.0: - resolution: {integrity: sha512-3ZnLvgWF29jikg1sAQ1g0o+lr5JX6sVgYvfUJazn7ZjJroDBUTWp44/+cFVX0bULjv4vci+rBD+oGVAkWqhUbw==} + teeny-request@10.1.2: + resolution: {integrity: sha512-Xj0ZAQ0CeuQn6UxCDPLbFRlgcSTUEyO3+wiepr2grjIjyL/lMMs1Z4OwXn8kLvn/V1OuaEP0UY7Na6UDNNsYrQ==} engines: {node: '>=18'} - terser-webpack-plugin@5.3.16: - resolution: {integrity: sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q==} + teex@1.0.1: + resolution: {integrity: sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==} + + terser-webpack-plugin@5.4.0: + resolution: {integrity: sha512-Bn5vxm48flOIfkdl5CaD2+1CiUVbonWQ3KQPyP7/EuIl9Gbzq/gQFOzaMFUEgVjB1396tcK0SG8XcNJ/2kDH8g==} engines: {node: '>= 10.13.0'} peerDependencies: '@swc/core': '*' @@ -8540,11 +8538,11 @@ packages: engines: {node: '>=10'} hasBin: true - text-decoder@1.2.6: - resolution: {integrity: sha512-27FeW5GQFDfw0FpwMQhMagB7BztOOlmjcSRi97t2oplhKVTZtp0DZbSegSaXS5IIC6mxMvBG4AR1Sgc6BX3CQg==} + text-decoder@1.2.7: + resolution: {integrity: sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==} - thingies@2.5.0: - resolution: {integrity: sha512-s+2Bwztg6PhWUD7XMfeYm5qliDdSiZm7M7n8KjTkIsm3l/2lgVRc2/Gx/v+ZX8lT4FMA+i8aQvhcWylldc+ZNw==} + thingies@2.6.0: + resolution: {integrity: sha512-rMHRjmlFLM1R96UYPvpmnc3LYtdFrT33JIB7L9hetGue1qAPfn1N2LJeEjxUSidu1Iku+haLZXDuEXUHNGO/lg==} engines: {node: '>=10.18'} peerDependencies: tslib: ^2 @@ -8570,30 +8568,30 @@ packages: tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} - tinyexec@1.0.2: - resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} + tinyexec@1.0.4: + resolution: {integrity: sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw==} engines: {node: '>=18'} tinyglobby@0.2.15: resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} - tinyrainbow@3.0.3: - resolution: {integrity: sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==} + tinyrainbow@3.1.0: + resolution: {integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==} engines: {node: '>=14.0.0'} tldts-core@6.1.86: resolution: {integrity: sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==} - tldts-core@7.0.23: - resolution: {integrity: sha512-0g9vrtDQLrNIiCj22HSe9d4mLVG3g5ph5DZ8zCKBr4OtrspmNB6ss7hVyzArAeE88ceZocIEGkyW1Ime7fxPtQ==} + tldts-core@7.0.27: + resolution: {integrity: sha512-YQ7uPjgWUibIK6DW5lrKujGwUKhLevU4hcGbP5O6TcIUb+oTjJYJVWPS4nZsIHrEEEG6myk/oqAJUEQmpZrHsg==} tldts@6.1.86: resolution: {integrity: sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==} hasBin: true - tldts@7.0.23: - resolution: {integrity: sha512-ASdhgQIBSay0R/eXggAkQ53G4nTJqTXqC2kbaBbdDwM7SkjyZyO0OaaN1/FH7U/yCeqOHDwFO5j8+Os/IS1dXw==} + tldts@7.0.27: + resolution: {integrity: sha512-I4FZcVFcqCRuT0ph6dCDpPuO4Xgzvh+spkcTr1gK7peIvxWauoloVO0vuy1FQnijT63ss6AsHB6+OIM4aXHbPg==} hasBin: true tmp@0.0.30: @@ -8624,8 +8622,8 @@ packages: resolution: {integrity: sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==} engines: {node: '>=16'} - tough-cookie@6.0.0: - resolution: {integrity: sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w==} + tough-cookie@6.0.1: + resolution: {integrity: sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw==} engines: {node: '>=16'} tr46@0.0.3: @@ -8649,8 +8647,8 @@ packages: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} hasBin: true - ts-api-utils@2.4.0: - resolution: {integrity: sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==} + ts-api-utils@2.5.0: + resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} engines: {node: '>=18.12'} peerDependencies: typescript: '>=4.8.4' @@ -8746,8 +8744,8 @@ packages: typed-graphqlify@3.1.6: resolution: {integrity: sha512-Snlg1ZrokbkQuemOb4xjWWCJrNcOMeb2Ii0/BwMfwLCcJVNjygyqhrFkrYNvi4gDrwWFrGE0TvxxM+Slym2JMg==} - typed-query-selector@2.12.0: - resolution: {integrity: sha512-SbklCd1F0EiZOyPiW192rrHZzZ5sBijB6xM+cpmrwDqObvdtunOHHIk9fCGsoK5JVIYXoyEp4iEdE3upFH3PAg==} + typed-query-selector@2.12.1: + resolution: {integrity: sha512-uzR+FzI8qrUEIu96oaeBJmd9E7CFEiQ3goA5qCVgc4s5llSubcfGHq9yUstZx/k4s9dXHVKsE35YWoFyvEqEHA==} typescript@5.9.3: resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} @@ -8782,15 +8780,15 @@ packages: unbzip2-stream@1.4.3: resolution: {integrity: sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==} - undici-types@7.22.0: - resolution: {integrity: sha512-RKZvifiL60xdsIuC80UY0dq8Z7DbJUV8/l2hOVbyZAxBzEeQU4Z58+4ZzJ6WN2Lidi9KzT5EbiGX+PI/UGYuRw==} + undici-types@7.24.6: + resolution: {integrity: sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==} - undici@6.23.0: - resolution: {integrity: sha512-VfQPToRA5FZs/qJxLIinmU59u0r7LXqoJkCzinq3ckNJp3vKEh7jTWN589YQ5+aoAC/TGRLyJLCPKcLQbM8r9g==} + undici@6.24.1: + resolution: {integrity: sha512-sC+b0tB1whOCzbtlx20fx3WgCXwkW627p4EA9uM+/tNNPkSS+eSEld6pAs9nDv7WbY1UUljBMYPtu9BCOrCWKA==} engines: {node: '>=18.17'} - undici@7.22.0: - resolution: {integrity: sha512-RqslV2Us5BrllB+JeiZnK4peryVTndy9Dnqq62S3yYRRTj0tFQCwEniUy2167skdGOy3vqRzEvl1Dm4sV2ReDg==} + undici@7.24.4: + resolution: {integrity: sha512-BM/JzwwaRXxrLdElV2Uo6cTLEjhSb3WXboncJamZ15NgUURmvlXvxa6xkwIOILIjPNo9i8ku136ZvWV0Uly8+w==} engines: {node: '>=20.18.1'} unenv@1.10.0: @@ -8818,14 +8816,6 @@ packages: unicode-trie@2.0.0: resolution: {integrity: sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==} - unique-filename@5.0.0: - resolution: {integrity: sha512-2RaJTAvAb4owyjllTfXzFClJ7WsGxlykkPvCr9pA//LD9goVq+m4PPAeBgNodGZ7nSrntT/auWpJ6Y5IFXcfjg==} - engines: {node: ^20.17.0 || >=22.9.0} - - unique-slug@6.0.0: - resolution: {integrity: sha512-4Lup7Ezn8W3d52/xBhZBVdx323ckxa7DEvd9kPQHppTkLoJXw6ltrBCyj5pnrxj0qKDxYMJ56CoxNuFCscdTiw==} - engines: {node: ^20.17.0 || >=22.9.0} - universal-github-app-jwt@2.2.2: resolution: {integrity: sha512-dcmbeSrOdTnsjGjUfAlqNDJrhxXizjAz94ija9Qw8YkZ1uu0d+GoZzyH+Jb9tIIqvGsadUfwg+22k5aDqqwzbw==} @@ -8882,9 +8872,6 @@ packages: resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} engines: {node: '>=10.12.0'} - validate-npm-package-license@3.0.4: - resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} - validate-npm-package-name@7.0.2: resolution: {integrity: sha512-hVDIBwsRruT73PbK7uP5ebUt+ezEtCmzZz3F59BSr2F6OVFnJ/6h8liuvdLrQ88Xmnk6/+xGGuq+pG9WwTuy3A==} engines: {node: ^20.17.0 || >=22.9.0} @@ -8909,8 +8896,8 @@ packages: resolution: {integrity: sha512-JBYCaSTQSUws/EXOqNrh7iOyWPrGLTYSeufCS3Y6BOCJbfDiy2Nh8PbstoZn/L9ZbzUesjPPiIZ4Ou3eUaK0Mw==} engines: {node: '>=18'} - verdaccio@6.2.5: - resolution: {integrity: sha512-sIek+ZF0a1aaRwHo9I5vbONGXzcAgbf5psEmbGVMG9M/MslblIae2wdehG6a2lSxsk4B9c8Ar0j/ZmliTjiStA==} + verdaccio@6.2.9: + resolution: {integrity: sha512-w1LYqM/wuvtiUedF9eSTsIC1yEI0nShIX48OqG1R6xzS4eEt0Pe1NYl5oPC/d7UyVSOufpjE8QVgd1CqauyhXQ==} engines: {node: '>=18'} hasBin: true @@ -9106,8 +9093,8 @@ packages: resolution: {integrity: sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==} engines: {node: '>=18'} - whatwg-url@16.0.0: - resolution: {integrity: sha512-9CcxtEKsf53UFwkSUZjG+9vydAsFO4lFHBpJUtjBcoJOCJpKnSJNwCw813zrYJHpCJ7sgfbtOe0V5Ku7Pa1XMQ==} + whatwg-url@16.0.1: + resolution: {integrity: sha512-1to4zXBxmXHV3IiSSEInrreIlu02vUOvrhxJJH5vcxYTBDAx51cqZiKdyTxlecdKNSjj8EcxGBxNf6Vg+945gw==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} whatwg-url@5.0.0: @@ -9141,11 +9128,6 @@ packages: engines: {node: '>= 8'} hasBin: true - which@6.0.0: - resolution: {integrity: sha512-f+gEpIKMR9faW/JgAgPK1D7mekkFoqbmiwvNzuhsHetni20QSgzg9Vhn0g2JSJkkfehQnqdUAx7/e15qS1lPxg==} - engines: {node: ^20.17.0 || >=22.9.0} - hasBin: true - which@6.0.1: resolution: {integrity: sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==} engines: {node: ^20.17.0 || >=22.9.0} @@ -9213,8 +9195,8 @@ packages: utf-8-validate: optional: true - ws@8.19.0: - resolution: {integrity: sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==} + ws@8.20.0: + resolution: {integrity: sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -9289,8 +9271,8 @@ packages: resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} engines: {node: '>=18'} - yaml@2.8.2: - resolution: {integrity: sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==} + yaml@2.8.3: + resolution: {integrity: sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==} engines: {node: '>= 14.6'} hasBin: true @@ -9349,10 +9331,10 @@ packages: resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==} engines: {node: '>=18'} - zod-to-json-schema@3.25.1: - resolution: {integrity: sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==} + zod-to-json-schema@3.25.2: + resolution: {integrity: sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==} peerDependencies: - zod: ^3.25 || ^4 + zod: ^3.25.28 || ^4 zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} @@ -9360,8 +9342,8 @@ packages: zod@4.3.6: resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} - zone.js@0.16.0: - resolution: {integrity: sha512-LqLPpIQANebrlxY6jKcYKdgN5DTXyyHAKnnWWjE5pPfEQ4n7j5zn7mOEEpwNZVKGqx3kKKmvplEmoBrvpgROTA==} + zone.js@0.16.1: + resolution: {integrity: sha512-dpvY17vxYIW3+bNrP0ClUlaiY0CiIRK3tnoLaGoQsQcY9/I/NpzIWQ7tQNhbV7LacQMpCII6wVzuL3tuWOyfuA==} snapshots: @@ -9379,7 +9361,7 @@ snapshots: '@actions/http-client@4.0.0': dependencies: tunnel: 0.0.6 - undici: 6.23.0 + undici: 6.24.1 '@actions/io@3.0.2': {} @@ -9472,29 +9454,29 @@ snapshots: '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 - '@angular/animations@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))': + '@angular/animations@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))': dependencies: - '@angular/core': 21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0) + '@angular/core': 21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1) tslib: 2.8.1 - '@angular/cdk@21.2.0-next.4(@angular/common@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(rxjs@7.8.2))(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(@angular/platform-browser@21.2.0-next.3(@angular/animations@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0)))(@angular/common@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(rxjs@7.8.2))(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0)))(rxjs@7.8.2)': + '@angular/cdk@21.2.4(@angular/common@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(@angular/platform-browser@21.2.6(@angular/animations@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1)))(@angular/common@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1)))(rxjs@7.8.2)': dependencies: - '@angular/common': 21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(rxjs@7.8.2) - '@angular/core': 21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0) - '@angular/platform-browser': 21.2.0-next.3(@angular/animations@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0)))(@angular/common@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(rxjs@7.8.2))(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0)) + '@angular/common': 21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2) + '@angular/core': 21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1) + '@angular/platform-browser': 21.2.6(@angular/animations@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1)))(@angular/common@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1)) parse5: 8.0.0 rxjs: 7.8.2 tslib: 2.8.1 - '@angular/common@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(rxjs@7.8.2)': + '@angular/common@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2)': dependencies: - '@angular/core': 21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0) + '@angular/core': 21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/compiler-cli@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(typescript@5.9.3)': + '@angular/compiler-cli@21.2.6(@angular/compiler@21.2.6)(typescript@5.9.3)': dependencies: - '@angular/compiler': 21.2.0-next.3 + '@angular/compiler': 21.2.6 '@babel/core': 7.29.0 '@jridgewell/sourcemap-codec': 1.5.5 chokidar: 5.0.0 @@ -9508,31 +9490,31 @@ snapshots: transitivePeerDependencies: - supports-color - '@angular/compiler@21.2.0-next.3': + '@angular/compiler@21.2.6': dependencies: tslib: 2.8.1 - '@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0)': + '@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1)': dependencies: rxjs: 7.8.2 tslib: 2.8.1 optionalDependencies: - '@angular/compiler': 21.2.0-next.3 - zone.js: 0.16.0 + '@angular/compiler': 21.2.6 + zone.js: 0.16.1 - '@angular/forms@21.2.0-next.3(@angular/common@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(rxjs@7.8.2))(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(@angular/platform-browser@21.2.0-next.3(@angular/animations@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0)))(@angular/common@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(rxjs@7.8.2))(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0)))(rxjs@7.8.2)': + '@angular/forms@21.2.6(@angular/common@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(@angular/platform-browser@21.2.6(@angular/animations@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1)))(@angular/common@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1)))(rxjs@7.8.2)': dependencies: - '@angular/common': 21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(rxjs@7.8.2) - '@angular/core': 21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0) - '@angular/platform-browser': 21.2.0-next.3(@angular/animations@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0)))(@angular/common@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(rxjs@7.8.2))(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0)) + '@angular/common': 21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2) + '@angular/core': 21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1) + '@angular/platform-browser': 21.2.6(@angular/animations@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1)))(@angular/common@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1)) '@standard-schema/spec': 1.1.0 rxjs: 7.8.2 tslib: 2.8.1 - '@angular/localize@21.2.0-next.3(@angular/compiler-cli@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(typescript@5.9.3))(@angular/compiler@21.2.0-next.3)': + '@angular/localize@21.2.6(@angular/compiler-cli@21.2.6(@angular/compiler@21.2.6)(typescript@5.9.3))(@angular/compiler@21.2.6)': dependencies: - '@angular/compiler': 21.2.0-next.3 - '@angular/compiler-cli': 21.2.0-next.3(@angular/compiler@21.2.0-next.3)(typescript@5.9.3) + '@angular/compiler': 21.2.6 + '@angular/compiler-cli': 21.2.6(@angular/compiler@21.2.6)(typescript@5.9.3) '@babel/core': 7.29.0 '@types/babel__core': 7.20.5 tinyglobby: 0.2.15 @@ -9540,24 +9522,25 @@ snapshots: transitivePeerDependencies: - supports-color - '@angular/material@21.2.0-next.4(75d10325bbcfc22e53b1e47f427450d8)': + '@angular/material@21.2.4(2045f7bd5f6e95e11cc97fff9a766245)': dependencies: - '@angular/cdk': 21.2.0-next.4(@angular/common@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(rxjs@7.8.2))(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(@angular/platform-browser@21.2.0-next.3(@angular/animations@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0)))(@angular/common@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(rxjs@7.8.2))(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0)))(rxjs@7.8.2) - '@angular/common': 21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(rxjs@7.8.2) - '@angular/core': 21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0) - '@angular/forms': 21.2.0-next.3(@angular/common@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(rxjs@7.8.2))(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(@angular/platform-browser@21.2.0-next.3(@angular/animations@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0)))(@angular/common@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(rxjs@7.8.2))(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0)))(rxjs@7.8.2) - '@angular/platform-browser': 21.2.0-next.3(@angular/animations@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0)))(@angular/common@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(rxjs@7.8.2))(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0)) + '@angular/cdk': 21.2.4(@angular/common@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(@angular/platform-browser@21.2.6(@angular/animations@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1)))(@angular/common@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1)))(rxjs@7.8.2) + '@angular/common': 21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2) + '@angular/core': 21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1) + '@angular/forms': 21.2.6(@angular/common@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(@angular/platform-browser@21.2.6(@angular/animations@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1)))(@angular/common@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1)))(rxjs@7.8.2) + '@angular/platform-browser': 21.2.6(@angular/animations@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1)))(@angular/common@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1)) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/2a5e8e5b5398ae13a8d9a963ac980707313a6c9e(@modelcontextprotocol/sdk@1.26.0(zod@4.3.6))': + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/cdbe118e59f59b1ee00ff77a5ccf8c5328248d03(@modelcontextprotocol/sdk@1.26.0(zod@4.3.6))': dependencies: '@actions/core': 3.0.0 + '@conventional-changelog/git-client': 2.6.0(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.4.0) '@google-cloud/spanner': 8.0.0(supports-color@10.2.2) - '@google/genai': 1.38.0(@modelcontextprotocol/sdk@1.26.0(zod@4.3.6))(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) - '@inquirer/prompts': 8.2.0(@types/node@24.10.9) - '@inquirer/type': 4.0.3(@types/node@24.10.9) - '@octokit/auth-app': 8.1.2 + '@google/genai': 1.47.0(@modelcontextprotocol/sdk@1.26.0(zod@4.3.6))(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) + '@inquirer/prompts': 8.3.2(@types/node@24.12.0) + '@inquirer/type': 4.0.4(@types/node@24.12.0) + '@octokit/auth-app': 8.2.0 '@octokit/core': 7.0.6 '@octokit/graphql': 9.0.3 '@octokit/graphql-schema': 15.26.1 @@ -9567,14 +9550,13 @@ snapshots: '@octokit/request-error': 7.1.0 '@octokit/rest': 22.0.1 '@octokit/types': 16.0.0 - '@pnpm/dependency-path': 1001.1.9 + '@pnpm/dependency-path': 1001.1.10 '@types/cli-progress': 3.11.6 '@types/ejs': 3.1.5 '@types/events': 3.0.3 '@types/folder-hash': 4.0.4 - '@types/git-raw-commits': 5.0.1 '@types/jasmine': 6.0.0 - '@types/node': 24.10.9 + '@types/node': 24.12.0 '@types/semver': 7.7.1 '@types/which': 3.0.4 '@types/yargs': 17.0.35 @@ -9583,81 +9565,80 @@ snapshots: bufferutil: 4.1.0 cli-progress: 3.12.0 conventional-commits-filter: 5.0.0 - conventional-commits-parser: 6.2.1 - ejs: 4.0.1 + conventional-commits-parser: 6.4.0 + ejs: 5.0.1 encoding: 0.1.13 fast-glob: 3.3.3 - firebase: 12.8.0 - folder-hash: 4.1.1(supports-color@10.2.2) - git-raw-commits: 5.0.0(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.2.1) - jasmine: 6.0.0 - jasmine-core: 6.0.0 + firebase: 12.11.0 + folder-hash: 4.1.2(supports-color@10.2.2) + jasmine: 6.1.0 + jasmine-core: 6.1.0 jasmine-reporters: 2.5.2 jsonc-parser: 3.3.1 - minimatch: 10.1.1 - multimatch: 7.0.0 - nock: 14.0.10 - semver: 7.7.3 + minimatch: 10.2.4 + multimatch: 8.0.0 + nock: 14.0.11 + semver: 7.7.4 supports-color: 10.2.2 tsx: 4.21.0 typed-graphqlify: 3.1.6 typescript: 5.9.3 utf-8-validate: 6.0.6 - which: 6.0.0 - yaml: 2.8.2 + which: 6.0.1 + yaml: 2.8.3 yargs: 18.0.0 zod: 4.3.6 transitivePeerDependencies: - '@modelcontextprotocol/sdk' - '@react-native-async-storage/async-storage' - '@angular/platform-browser@21.2.0-next.3(@angular/animations@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0)))(@angular/common@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(rxjs@7.8.2))(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))': + '@angular/platform-browser@21.2.6(@angular/animations@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1)))(@angular/common@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))': dependencies: - '@angular/common': 21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(rxjs@7.8.2) - '@angular/core': 21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0) + '@angular/common': 21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2) + '@angular/core': 21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1) tslib: 2.8.1 optionalDependencies: - '@angular/animations': 21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0)) + '@angular/animations': 21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1)) - '@angular/platform-server@21.2.0-next.3(@angular/common@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(rxjs@7.8.2))(@angular/compiler@21.2.0-next.3)(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(@angular/platform-browser@21.2.0-next.3(@angular/animations@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0)))(@angular/common@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(rxjs@7.8.2))(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0)))(rxjs@7.8.2)': + '@angular/platform-server@21.2.6(@angular/common@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/compiler@21.2.6)(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(@angular/platform-browser@21.2.6(@angular/animations@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1)))(@angular/common@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1)))(rxjs@7.8.2)': dependencies: - '@angular/common': 21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(rxjs@7.8.2) - '@angular/compiler': 21.2.0-next.3 - '@angular/core': 21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0) - '@angular/platform-browser': 21.2.0-next.3(@angular/animations@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0)))(@angular/common@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(rxjs@7.8.2))(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0)) + '@angular/common': 21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2) + '@angular/compiler': 21.2.6 + '@angular/core': 21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1) + '@angular/platform-browser': 21.2.6(@angular/animations@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1)))(@angular/common@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1)) rxjs: 7.8.2 tslib: 2.8.1 xhr2: 0.2.1 - '@angular/router@21.2.0-next.3(@angular/common@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(rxjs@7.8.2))(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(@angular/platform-browser@21.2.0-next.3(@angular/animations@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0)))(@angular/common@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(rxjs@7.8.2))(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0)))(rxjs@7.8.2)': + '@angular/router@21.2.6(@angular/common@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(@angular/platform-browser@21.2.6(@angular/animations@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1)))(@angular/common@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1)))(rxjs@7.8.2)': dependencies: - '@angular/common': 21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(rxjs@7.8.2) - '@angular/core': 21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0) - '@angular/platform-browser': 21.2.0-next.3(@angular/animations@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0)))(@angular/common@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(rxjs@7.8.2))(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0)) + '@angular/common': 21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2) + '@angular/core': 21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1) + '@angular/platform-browser': 21.2.6(@angular/animations@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1)))(@angular/common@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2))(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1)) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/service-worker@21.2.0-next.3(@angular/core@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0))(rxjs@7.8.2)': + '@angular/service-worker@21.2.6(@angular/core@21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1))(rxjs@7.8.2)': dependencies: - '@angular/core': 21.2.0-next.3(@angular/compiler@21.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.0) + '@angular/core': 21.2.6(@angular/compiler@21.2.6)(rxjs@7.8.2)(zone.js@0.16.1) rxjs: 7.8.2 tslib: 2.8.1 - '@asamuzakjp/css-color@4.1.2': + '@asamuzakjp/css-color@5.1.1': dependencies: '@csstools/css-calc': 3.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) - '@csstools/css-color-parser': 4.0.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-color-parser': 4.0.2(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - lru-cache: 11.2.6 + lru-cache: 11.2.7 '@asamuzakjp/dom-selector@6.8.1': dependencies: '@asamuzakjp/nwsapi': 2.3.9 bidi-js: 1.0.3 - css-tree: 3.1.0 + css-tree: 3.2.1 is-potential-custom-element-name: 1.0.1 - lru-cache: 11.2.6 + lru-cache: 11.2.7 '@asamuzakjp/nwsapi@2.3.9': {} @@ -9675,8 +9656,8 @@ snapshots: '@babel/generator': 7.29.1 '@babel/helper-compilation-targets': 7.28.6 '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) - '@babel/helpers': 7.28.6 - '@babel/parser': 7.29.0 + '@babel/helpers': 7.29.2 + '@babel/parser': 7.29.2 '@babel/template': 7.28.6 '@babel/traverse': 7.29.0 '@babel/types': 7.29.0 @@ -9691,7 +9672,7 @@ snapshots: '@babel/generator@7.29.1': dependencies: - '@babel/parser': 7.29.0 + '@babel/parser': 7.29.2 '@babel/types': 7.29.0 '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 @@ -9729,7 +9710,7 @@ snapshots: regexpu-core: 6.4.0 semver: 6.3.1 - '@babel/helper-define-polyfill-provider@0.6.6(@babel/core@7.29.0)': + '@babel/helper-define-polyfill-provider@0.6.8(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 '@babel/helper-compilation-targets': 7.28.6 @@ -9814,12 +9795,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helpers@7.28.6': + '@babel/helpers@7.29.2': dependencies: '@babel/template': 7.28.6 '@babel/types': 7.29.0 - '@babel/parser@7.29.0': + '@babel/parser@7.29.2': dependencies: '@babel/types': 7.29.0 @@ -10165,9 +10146,9 @@ snapshots: '@babel/core': 7.29.0 '@babel/helper-module-imports': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - babel-plugin-polyfill-corejs2: 0.4.15(@babel/core@7.29.0) + babel-plugin-polyfill-corejs2: 0.4.17(@babel/core@7.29.0) babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.29.0) - babel-plugin-polyfill-regenerator: 0.6.6(@babel/core@7.29.0) + babel-plugin-polyfill-regenerator: 0.6.8(@babel/core@7.29.0) semver: 6.3.1 transitivePeerDependencies: - supports-color @@ -10291,10 +10272,10 @@ snapshots: '@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.29.0) '@babel/plugin-transform-unicode-sets-regex': 7.28.6(@babel/core@7.29.0) '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.29.0) - babel-plugin-polyfill-corejs2: 0.4.15(@babel/core@7.29.0) - babel-plugin-polyfill-corejs3: 0.14.0(@babel/core@7.29.0) - babel-plugin-polyfill-regenerator: 0.6.6(@babel/core@7.29.0) - core-js-compat: 3.48.0 + babel-plugin-polyfill-corejs2: 0.4.17(@babel/core@7.29.0) + babel-plugin-polyfill-corejs3: 0.14.2(@babel/core@7.29.0) + babel-plugin-polyfill-regenerator: 0.6.8(@babel/core@7.29.0) + core-js-compat: 3.49.0 semver: 6.3.1 transitivePeerDependencies: - supports-color @@ -10311,7 +10292,7 @@ snapshots: '@babel/template@7.28.6': dependencies: '@babel/code-frame': 7.29.0 - '@babel/parser': 7.29.0 + '@babel/parser': 7.29.2 '@babel/types': 7.29.0 '@babel/traverse@7.29.0': @@ -10319,7 +10300,7 @@ snapshots: '@babel/code-frame': 7.29.0 '@babel/generator': 7.29.1 '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.29.0 + '@babel/parser': 7.29.2 '@babel/template': 7.28.6 '@babel/types': 7.29.0 debug: 4.4.3(supports-color@10.2.2) @@ -10339,32 +10320,33 @@ snapshots: '@bramus/specificity@2.4.2': dependencies: - css-tree: 3.1.0 + css-tree: 3.2.1 '@colors/colors@1.5.0': {} - '@conventional-changelog/git-client@1.0.1(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.2.1)': + '@conventional-changelog/git-client@2.6.0(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.4.0)': dependencies: - '@types/semver': 7.7.1 + '@simple-libs/child-process-utils': 1.0.2 + '@simple-libs/stream-utils': 1.2.0 semver: 7.7.4 optionalDependencies: conventional-commits-filter: 5.0.0 - conventional-commits-parser: 6.2.1 + conventional-commits-parser: 6.4.0 '@cspotcode/source-map-support@0.8.1': dependencies: '@jridgewell/trace-mapping': 0.3.9 - '@csstools/color-helpers@6.0.1': {} + '@csstools/color-helpers@6.0.2': {} '@csstools/css-calc@3.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': dependencies: '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/css-color-parser@4.0.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': + '@csstools/css-color-parser@4.0.2(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': dependencies: - '@csstools/color-helpers': 6.0.1 + '@csstools/color-helpers': 6.0.2 '@csstools/css-calc': 3.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 @@ -10373,11 +10355,13 @@ snapshots: dependencies: '@csstools/css-tokenizer': 4.0.0 - '@csstools/css-syntax-patches-for-csstree@1.0.27': {} + '@csstools/css-syntax-patches-for-csstree@1.1.2(css-tree@3.2.1)': + optionalDependencies: + css-tree: 3.2.1 '@csstools/css-tokenizer@4.0.0': {} - '@cypress/request@3.0.9': + '@cypress/request@3.0.10': dependencies: aws-sign2: 0.7.0 aws4: 1.13.2 @@ -10392,7 +10376,7 @@ snapshots: json-stringify-safe: 5.0.1 mime-types: 2.1.35 performance-now: 2.1.0 - qs: 6.14.0 + qs: 6.14.2 safe-buffer: 5.2.1 tough-cookie: 5.1.2 tunnel-agent: 0.6.0 @@ -10400,22 +10384,6 @@ snapshots: '@discoveryjs/json-ext@0.6.3': {} - '@emnapi/core@1.8.1': - dependencies: - '@emnapi/wasi-threads': 1.1.0 - tslib: 2.8.1 - optional: true - - '@emnapi/runtime@1.8.1': - dependencies: - tslib: 2.8.1 - optional: true - - '@emnapi/wasi-threads@1.1.0': - dependencies: - tslib: 2.8.1 - optional: true - '@esbuild/aix-ppc64@0.27.3': optional: true @@ -10503,15 +10471,15 @@ snapshots: '@eslint/compat@2.0.2(eslint@9.39.2(jiti@2.6.1))': dependencies: - '@eslint/core': 1.1.0 + '@eslint/core': 1.1.1 optionalDependencies: eslint: 9.39.2(jiti@2.6.1) - '@eslint/config-array@0.21.1': + '@eslint/config-array@0.21.2': dependencies: '@eslint/object-schema': 2.1.7 debug: 4.4.3(supports-color@10.2.2) - minimatch: 3.1.2 + minimatch: 3.1.5 transitivePeerDependencies: - supports-color @@ -10523,20 +10491,20 @@ snapshots: dependencies: '@types/json-schema': 7.0.15 - '@eslint/core@1.1.0': + '@eslint/core@1.1.1': dependencies: '@types/json-schema': 7.0.15 '@eslint/eslintrc@3.3.3': dependencies: - ajv: 6.12.6 + ajv: 6.14.0 debug: 4.4.3(supports-color@10.2.2) espree: 10.4.0 globals: 14.0.0 ignore: 5.3.2 import-fresh: 3.3.1 js-yaml: 4.1.1 - minimatch: 3.1.2 + minimatch: 3.1.5 strip-json-comments: 3.1.1 transitivePeerDependencies: - supports-color @@ -10550,48 +10518,48 @@ snapshots: '@eslint/core': 0.17.0 levn: 0.4.1 - '@exodus/bytes@1.14.1': {} + '@exodus/bytes@1.15.0': {} - '@firebase/ai@2.7.0(@firebase/app-types@0.9.3)(@firebase/app@0.14.7)': + '@firebase/ai@2.10.0(@firebase/app-types@0.9.3)(@firebase/app@0.14.10)': dependencies: - '@firebase/app': 0.14.7 + '@firebase/app': 0.14.10 '@firebase/app-check-interop-types': 0.3.3 '@firebase/app-types': 0.9.3 - '@firebase/component': 0.7.0 + '@firebase/component': 0.7.2 '@firebase/logger': 0.5.0 - '@firebase/util': 1.13.0 + '@firebase/util': 1.15.0 tslib: 2.8.1 - '@firebase/analytics-compat@0.2.25(@firebase/app-compat@0.5.7)(@firebase/app@0.14.7)': + '@firebase/analytics-compat@0.2.27(@firebase/app-compat@0.5.10)(@firebase/app@0.14.10)': dependencies: - '@firebase/analytics': 0.10.19(@firebase/app@0.14.7) + '@firebase/analytics': 0.10.21(@firebase/app@0.14.10) '@firebase/analytics-types': 0.8.3 - '@firebase/app-compat': 0.5.7 - '@firebase/component': 0.7.0 - '@firebase/util': 1.13.0 + '@firebase/app-compat': 0.5.10 + '@firebase/component': 0.7.2 + '@firebase/util': 1.15.0 tslib: 2.8.1 transitivePeerDependencies: - '@firebase/app' '@firebase/analytics-types@0.8.3': {} - '@firebase/analytics@0.10.19(@firebase/app@0.14.7)': + '@firebase/analytics@0.10.21(@firebase/app@0.14.10)': dependencies: - '@firebase/app': 0.14.7 - '@firebase/component': 0.7.0 - '@firebase/installations': 0.6.19(@firebase/app@0.14.7) + '@firebase/app': 0.14.10 + '@firebase/component': 0.7.2 + '@firebase/installations': 0.6.21(@firebase/app@0.14.10) '@firebase/logger': 0.5.0 - '@firebase/util': 1.13.0 + '@firebase/util': 1.15.0 tslib: 2.8.1 - '@firebase/app-check-compat@0.4.0(@firebase/app-compat@0.5.7)(@firebase/app@0.14.7)': + '@firebase/app-check-compat@0.4.2(@firebase/app-compat@0.5.10)(@firebase/app@0.14.10)': dependencies: - '@firebase/app-check': 0.11.0(@firebase/app@0.14.7) + '@firebase/app-check': 0.11.2(@firebase/app@0.14.10) '@firebase/app-check-types': 0.5.3 - '@firebase/app-compat': 0.5.7 - '@firebase/component': 0.7.0 + '@firebase/app-compat': 0.5.10 + '@firebase/component': 0.7.2 '@firebase/logger': 0.5.0 - '@firebase/util': 1.13.0 + '@firebase/util': 1.15.0 tslib: 2.8.1 transitivePeerDependencies: - '@firebase/app' @@ -10600,39 +10568,39 @@ snapshots: '@firebase/app-check-types@0.5.3': {} - '@firebase/app-check@0.11.0(@firebase/app@0.14.7)': + '@firebase/app-check@0.11.2(@firebase/app@0.14.10)': dependencies: - '@firebase/app': 0.14.7 - '@firebase/component': 0.7.0 + '@firebase/app': 0.14.10 + '@firebase/component': 0.7.2 '@firebase/logger': 0.5.0 - '@firebase/util': 1.13.0 + '@firebase/util': 1.15.0 tslib: 2.8.1 - '@firebase/app-compat@0.5.7': + '@firebase/app-compat@0.5.10': dependencies: - '@firebase/app': 0.14.7 - '@firebase/component': 0.7.0 + '@firebase/app': 0.14.10 + '@firebase/component': 0.7.2 '@firebase/logger': 0.5.0 - '@firebase/util': 1.13.0 + '@firebase/util': 1.15.0 tslib: 2.8.1 '@firebase/app-types@0.9.3': {} - '@firebase/app@0.14.7': + '@firebase/app@0.14.10': dependencies: - '@firebase/component': 0.7.0 + '@firebase/component': 0.7.2 '@firebase/logger': 0.5.0 - '@firebase/util': 1.13.0 + '@firebase/util': 1.15.0 idb: 7.1.1 tslib: 2.8.1 - '@firebase/auth-compat@0.6.2(@firebase/app-compat@0.5.7)(@firebase/app-types@0.9.3)(@firebase/app@0.14.7)': + '@firebase/auth-compat@0.6.4(@firebase/app-compat@0.5.10)(@firebase/app-types@0.9.3)(@firebase/app@0.14.10)': dependencies: - '@firebase/app-compat': 0.5.7 - '@firebase/auth': 1.12.0(@firebase/app@0.14.7) - '@firebase/auth-types': 0.13.0(@firebase/app-types@0.9.3)(@firebase/util@1.13.0) - '@firebase/component': 0.7.0 - '@firebase/util': 1.13.0 + '@firebase/app-compat': 0.5.10 + '@firebase/auth': 1.12.2(@firebase/app@0.14.10) + '@firebase/auth-types': 0.13.0(@firebase/app-types@0.9.3)(@firebase/util@1.15.0) + '@firebase/component': 0.7.2 + '@firebase/util': 1.15.0 tslib: 2.8.1 transitivePeerDependencies: - '@firebase/app' @@ -10641,115 +10609,115 @@ snapshots: '@firebase/auth-interop-types@0.2.4': {} - '@firebase/auth-types@0.13.0(@firebase/app-types@0.9.3)(@firebase/util@1.13.0)': + '@firebase/auth-types@0.13.0(@firebase/app-types@0.9.3)(@firebase/util@1.15.0)': dependencies: '@firebase/app-types': 0.9.3 - '@firebase/util': 1.13.0 + '@firebase/util': 1.15.0 - '@firebase/auth@1.12.0(@firebase/app@0.14.7)': + '@firebase/auth@1.12.2(@firebase/app@0.14.10)': dependencies: - '@firebase/app': 0.14.7 - '@firebase/component': 0.7.0 + '@firebase/app': 0.14.10 + '@firebase/component': 0.7.2 '@firebase/logger': 0.5.0 - '@firebase/util': 1.13.0 + '@firebase/util': 1.15.0 tslib: 2.8.1 - '@firebase/component@0.7.0': + '@firebase/component@0.7.2': dependencies: - '@firebase/util': 1.13.0 + '@firebase/util': 1.15.0 tslib: 2.8.1 - '@firebase/data-connect@0.3.12(@firebase/app@0.14.7)': + '@firebase/data-connect@0.5.0(@firebase/app@0.14.10)': dependencies: - '@firebase/app': 0.14.7 + '@firebase/app': 0.14.10 '@firebase/auth-interop-types': 0.2.4 - '@firebase/component': 0.7.0 + '@firebase/component': 0.7.2 '@firebase/logger': 0.5.0 - '@firebase/util': 1.13.0 + '@firebase/util': 1.15.0 tslib: 2.8.1 - '@firebase/database-compat@2.1.0': + '@firebase/database-compat@2.1.2': dependencies: - '@firebase/component': 0.7.0 - '@firebase/database': 1.1.0 - '@firebase/database-types': 1.0.16 + '@firebase/component': 0.7.2 + '@firebase/database': 1.1.2 + '@firebase/database-types': 1.0.18 '@firebase/logger': 0.5.0 - '@firebase/util': 1.13.0 + '@firebase/util': 1.15.0 tslib: 2.8.1 - '@firebase/database-types@1.0.16': + '@firebase/database-types@1.0.18': dependencies: '@firebase/app-types': 0.9.3 - '@firebase/util': 1.13.0 + '@firebase/util': 1.15.0 - '@firebase/database@1.1.0': + '@firebase/database@1.1.2': dependencies: '@firebase/app-check-interop-types': 0.3.3 '@firebase/auth-interop-types': 0.2.4 - '@firebase/component': 0.7.0 + '@firebase/component': 0.7.2 '@firebase/logger': 0.5.0 - '@firebase/util': 1.13.0 + '@firebase/util': 1.15.0 faye-websocket: 0.11.4 tslib: 2.8.1 - '@firebase/firestore-compat@0.4.4(@firebase/app-compat@0.5.7)(@firebase/app-types@0.9.3)(@firebase/app@0.14.7)': + '@firebase/firestore-compat@0.4.7(@firebase/app-compat@0.5.10)(@firebase/app-types@0.9.3)(@firebase/app@0.14.10)': dependencies: - '@firebase/app-compat': 0.5.7 - '@firebase/component': 0.7.0 - '@firebase/firestore': 4.10.0(@firebase/app@0.14.7) - '@firebase/firestore-types': 3.0.3(@firebase/app-types@0.9.3)(@firebase/util@1.13.0) - '@firebase/util': 1.13.0 + '@firebase/app-compat': 0.5.10 + '@firebase/component': 0.7.2 + '@firebase/firestore': 4.13.0(@firebase/app@0.14.10) + '@firebase/firestore-types': 3.0.3(@firebase/app-types@0.9.3)(@firebase/util@1.15.0) + '@firebase/util': 1.15.0 tslib: 2.8.1 transitivePeerDependencies: - '@firebase/app' - '@firebase/app-types' - '@firebase/firestore-types@3.0.3(@firebase/app-types@0.9.3)(@firebase/util@1.13.0)': + '@firebase/firestore-types@3.0.3(@firebase/app-types@0.9.3)(@firebase/util@1.15.0)': dependencies: '@firebase/app-types': 0.9.3 - '@firebase/util': 1.13.0 + '@firebase/util': 1.15.0 - '@firebase/firestore@4.10.0(@firebase/app@0.14.7)': + '@firebase/firestore@4.13.0(@firebase/app@0.14.10)': dependencies: - '@firebase/app': 0.14.7 - '@firebase/component': 0.7.0 + '@firebase/app': 0.14.10 + '@firebase/component': 0.7.2 '@firebase/logger': 0.5.0 - '@firebase/util': 1.13.0 + '@firebase/util': 1.15.0 '@firebase/webchannel-wrapper': 1.0.5 '@grpc/grpc-js': 1.9.15 '@grpc/proto-loader': 0.7.15 tslib: 2.8.1 - '@firebase/functions-compat@0.4.1(@firebase/app-compat@0.5.7)(@firebase/app@0.14.7)': + '@firebase/functions-compat@0.4.3(@firebase/app-compat@0.5.10)(@firebase/app@0.14.10)': dependencies: - '@firebase/app-compat': 0.5.7 - '@firebase/component': 0.7.0 - '@firebase/functions': 0.13.1(@firebase/app@0.14.7) + '@firebase/app-compat': 0.5.10 + '@firebase/component': 0.7.2 + '@firebase/functions': 0.13.3(@firebase/app@0.14.10) '@firebase/functions-types': 0.6.3 - '@firebase/util': 1.13.0 + '@firebase/util': 1.15.0 tslib: 2.8.1 transitivePeerDependencies: - '@firebase/app' '@firebase/functions-types@0.6.3': {} - '@firebase/functions@0.13.1(@firebase/app@0.14.7)': + '@firebase/functions@0.13.3(@firebase/app@0.14.10)': dependencies: - '@firebase/app': 0.14.7 + '@firebase/app': 0.14.10 '@firebase/app-check-interop-types': 0.3.3 '@firebase/auth-interop-types': 0.2.4 - '@firebase/component': 0.7.0 + '@firebase/component': 0.7.2 '@firebase/messaging-interop-types': 0.2.3 - '@firebase/util': 1.13.0 + '@firebase/util': 1.15.0 tslib: 2.8.1 - '@firebase/installations-compat@0.2.19(@firebase/app-compat@0.5.7)(@firebase/app-types@0.9.3)(@firebase/app@0.14.7)': + '@firebase/installations-compat@0.2.21(@firebase/app-compat@0.5.10)(@firebase/app-types@0.9.3)(@firebase/app@0.14.10)': dependencies: - '@firebase/app-compat': 0.5.7 - '@firebase/component': 0.7.0 - '@firebase/installations': 0.6.19(@firebase/app@0.14.7) + '@firebase/app-compat': 0.5.10 + '@firebase/component': 0.7.2 + '@firebase/installations': 0.6.21(@firebase/app@0.14.10) '@firebase/installations-types': 0.5.3(@firebase/app-types@0.9.3) - '@firebase/util': 1.13.0 + '@firebase/util': 1.15.0 tslib: 2.8.1 transitivePeerDependencies: - '@firebase/app' @@ -10759,11 +10727,11 @@ snapshots: dependencies: '@firebase/app-types': 0.9.3 - '@firebase/installations@0.6.19(@firebase/app@0.14.7)': + '@firebase/installations@0.6.21(@firebase/app@0.14.10)': dependencies: - '@firebase/app': 0.14.7 - '@firebase/component': 0.7.0 - '@firebase/util': 1.13.0 + '@firebase/app': 0.14.10 + '@firebase/component': 0.7.2 + '@firebase/util': 1.15.0 idb: 7.1.1 tslib: 2.8.1 @@ -10771,105 +10739,107 @@ snapshots: dependencies: tslib: 2.8.1 - '@firebase/messaging-compat@0.2.23(@firebase/app-compat@0.5.7)(@firebase/app@0.14.7)': + '@firebase/messaging-compat@0.2.25(@firebase/app-compat@0.5.10)(@firebase/app@0.14.10)': dependencies: - '@firebase/app-compat': 0.5.7 - '@firebase/component': 0.7.0 - '@firebase/messaging': 0.12.23(@firebase/app@0.14.7) - '@firebase/util': 1.13.0 + '@firebase/app-compat': 0.5.10 + '@firebase/component': 0.7.2 + '@firebase/messaging': 0.12.25(@firebase/app@0.14.10) + '@firebase/util': 1.15.0 tslib: 2.8.1 transitivePeerDependencies: - '@firebase/app' '@firebase/messaging-interop-types@0.2.3': {} - '@firebase/messaging@0.12.23(@firebase/app@0.14.7)': + '@firebase/messaging@0.12.25(@firebase/app@0.14.10)': dependencies: - '@firebase/app': 0.14.7 - '@firebase/component': 0.7.0 - '@firebase/installations': 0.6.19(@firebase/app@0.14.7) + '@firebase/app': 0.14.10 + '@firebase/component': 0.7.2 + '@firebase/installations': 0.6.21(@firebase/app@0.14.10) '@firebase/messaging-interop-types': 0.2.3 - '@firebase/util': 1.13.0 + '@firebase/util': 1.15.0 idb: 7.1.1 tslib: 2.8.1 - '@firebase/performance-compat@0.2.22(@firebase/app-compat@0.5.7)(@firebase/app@0.14.7)': + '@firebase/performance-compat@0.2.24(@firebase/app-compat@0.5.10)(@firebase/app@0.14.10)': dependencies: - '@firebase/app-compat': 0.5.7 - '@firebase/component': 0.7.0 + '@firebase/app-compat': 0.5.10 + '@firebase/component': 0.7.2 '@firebase/logger': 0.5.0 - '@firebase/performance': 0.7.9(@firebase/app@0.14.7) + '@firebase/performance': 0.7.11(@firebase/app@0.14.10) '@firebase/performance-types': 0.2.3 - '@firebase/util': 1.13.0 + '@firebase/util': 1.15.0 tslib: 2.8.1 transitivePeerDependencies: - '@firebase/app' '@firebase/performance-types@0.2.3': {} - '@firebase/performance@0.7.9(@firebase/app@0.14.7)': + '@firebase/performance@0.7.11(@firebase/app@0.14.10)': dependencies: - '@firebase/app': 0.14.7 - '@firebase/component': 0.7.0 - '@firebase/installations': 0.6.19(@firebase/app@0.14.7) + '@firebase/app': 0.14.10 + '@firebase/component': 0.7.2 + '@firebase/installations': 0.6.21(@firebase/app@0.14.10) '@firebase/logger': 0.5.0 - '@firebase/util': 1.13.0 + '@firebase/util': 1.15.0 tslib: 2.8.1 web-vitals: 4.2.4 - '@firebase/remote-config-compat@0.2.21(@firebase/app-compat@0.5.7)(@firebase/app@0.14.7)': + '@firebase/remote-config-compat@0.2.23(@firebase/app-compat@0.5.10)(@firebase/app@0.14.10)': dependencies: - '@firebase/app-compat': 0.5.7 - '@firebase/component': 0.7.0 + '@firebase/app-compat': 0.5.10 + '@firebase/component': 0.7.2 '@firebase/logger': 0.5.0 - '@firebase/remote-config': 0.8.0(@firebase/app@0.14.7) + '@firebase/remote-config': 0.8.2(@firebase/app@0.14.10) '@firebase/remote-config-types': 0.5.0 - '@firebase/util': 1.13.0 + '@firebase/util': 1.15.0 tslib: 2.8.1 transitivePeerDependencies: - '@firebase/app' '@firebase/remote-config-types@0.5.0': {} - '@firebase/remote-config@0.8.0(@firebase/app@0.14.7)': + '@firebase/remote-config@0.8.2(@firebase/app@0.14.10)': dependencies: - '@firebase/app': 0.14.7 - '@firebase/component': 0.7.0 - '@firebase/installations': 0.6.19(@firebase/app@0.14.7) + '@firebase/app': 0.14.10 + '@firebase/component': 0.7.2 + '@firebase/installations': 0.6.21(@firebase/app@0.14.10) '@firebase/logger': 0.5.0 - '@firebase/util': 1.13.0 + '@firebase/util': 1.15.0 tslib: 2.8.1 - '@firebase/storage-compat@0.4.0(@firebase/app-compat@0.5.7)(@firebase/app-types@0.9.3)(@firebase/app@0.14.7)': + '@firebase/storage-compat@0.4.2(@firebase/app-compat@0.5.10)(@firebase/app-types@0.9.3)(@firebase/app@0.14.10)': dependencies: - '@firebase/app-compat': 0.5.7 - '@firebase/component': 0.7.0 - '@firebase/storage': 0.14.0(@firebase/app@0.14.7) - '@firebase/storage-types': 0.8.3(@firebase/app-types@0.9.3)(@firebase/util@1.13.0) - '@firebase/util': 1.13.0 + '@firebase/app-compat': 0.5.10 + '@firebase/component': 0.7.2 + '@firebase/storage': 0.14.2(@firebase/app@0.14.10) + '@firebase/storage-types': 0.8.3(@firebase/app-types@0.9.3)(@firebase/util@1.15.0) + '@firebase/util': 1.15.0 tslib: 2.8.1 transitivePeerDependencies: - '@firebase/app' - '@firebase/app-types' - '@firebase/storage-types@0.8.3(@firebase/app-types@0.9.3)(@firebase/util@1.13.0)': + '@firebase/storage-types@0.8.3(@firebase/app-types@0.9.3)(@firebase/util@1.15.0)': dependencies: '@firebase/app-types': 0.9.3 - '@firebase/util': 1.13.0 + '@firebase/util': 1.15.0 - '@firebase/storage@0.14.0(@firebase/app@0.14.7)': + '@firebase/storage@0.14.2(@firebase/app@0.14.10)': dependencies: - '@firebase/app': 0.14.7 - '@firebase/component': 0.7.0 - '@firebase/util': 1.13.0 + '@firebase/app': 0.14.10 + '@firebase/component': 0.7.2 + '@firebase/util': 1.15.0 tslib: 2.8.1 - '@firebase/util@1.13.0': + '@firebase/util@1.15.0': dependencies: tslib: 2.8.1 '@firebase/webchannel-wrapper@1.0.5': {} + '@gar/promise-retry@1.0.3': {} + '@glideapps/ts-necessities@2.2.3': {} '@google-cloud/common@6.0.0(supports-color@10.2.2)': @@ -10879,10 +10849,10 @@ snapshots: arrify: 2.0.1 duplexify: 4.1.3 extend: 3.0.2 - google-auth-library: 10.5.0(supports-color@10.2.2) + google-auth-library: 10.6.2(supports-color@10.2.2) html-entities: 2.6.0 retry-request: 8.0.2(supports-color@10.2.2) - teeny-request: 10.1.0(supports-color@10.2.2) + teeny-request: 10.1.2(supports-color@10.2.2) transitivePeerDependencies: - supports-color @@ -10903,10 +10873,10 @@ snapshots: '@google-cloud/projectify': 5.0.0 '@google-cloud/promisify': 5.0.0 '@grpc/proto-loader': 0.7.15 - '@opentelemetry/api': 1.9.0 - '@opentelemetry/context-async-hooks': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/core': 2.5.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.39.0 + '@opentelemetry/api': 1.9.1 + '@opentelemetry/context-async-hooks': 2.6.1(@opentelemetry/api@1.9.1) + '@opentelemetry/core': 2.6.1(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 '@types/big.js': 6.2.2 '@types/stack-trace': 0.0.33 big.js: 7.0.1 @@ -10914,7 +10884,7 @@ snapshots: duplexify: 4.1.3 events-intercept: 2.0.0 extend: 3.0.2 - google-auth-library: 10.5.0(supports-color@10.2.2) + google-auth-library: 10.6.2(supports-color@10.2.2) google-gax: 5.0.6(supports-color@10.2.2) grpc-gcp: 1.0.1(protobufjs@7.5.4) is: 3.3.2 @@ -10926,16 +10896,17 @@ snapshots: split-array-stream: 2.0.0 stack-trace: 0.0.10 stream-events: 1.0.5 - teeny-request: 10.1.0(supports-color@10.2.2) + teeny-request: 10.1.2(supports-color@10.2.2) through2: 4.0.2 transitivePeerDependencies: - supports-color - '@google/genai@1.38.0(@modelcontextprotocol/sdk@1.26.0(zod@4.3.6))(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6)': + '@google/genai@1.47.0(@modelcontextprotocol/sdk@1.26.0(zod@4.3.6))(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6)': dependencies: - google-auth-library: 10.5.0(supports-color@10.2.2) + google-auth-library: 10.6.2(supports-color@10.2.2) + p-retry: 4.6.2 protobufjs: 7.5.4 - ws: 8.19.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + ws: 8.20.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) optionalDependencies: '@modelcontextprotocol/sdk': 1.26.0(zod@4.3.6) transitivePeerDependencies: @@ -10951,7 +10922,7 @@ snapshots: '@grpc/grpc-js@1.9.15': dependencies: '@grpc/proto-loader': 0.7.15 - '@types/node': 22.19.11 + '@types/node': 22.19.15 '@grpc/proto-loader@0.7.15': dependencies: @@ -10972,9 +10943,9 @@ snapshots: '@harperfast/extended-iterable@1.0.3': optional: true - '@hono/node-server@1.19.9(hono@4.11.9)': + '@hono/node-server@1.19.11(hono@4.12.9)': dependencies: - hono: 4.11.9 + hono: 4.12.9 '@humanfs/core@0.19.1': {} @@ -10989,268 +10960,260 @@ snapshots: '@inquirer/ansi@1.0.2': {} - '@inquirer/ansi@2.0.3': {} + '@inquirer/ansi@2.0.4': {} - '@inquirer/checkbox@4.3.2(@types/node@24.10.9)': + '@inquirer/checkbox@4.3.2(@types/node@24.12.0)': dependencies: '@inquirer/ansi': 1.0.2 - '@inquirer/core': 10.3.2(@types/node@24.10.9) + '@inquirer/core': 10.3.2(@types/node@24.12.0) '@inquirer/figures': 1.0.15 - '@inquirer/type': 3.0.10(@types/node@24.10.9) + '@inquirer/type': 3.0.10(@types/node@24.12.0) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 24.10.9 + '@types/node': 24.12.0 - '@inquirer/checkbox@5.0.6(@types/node@24.10.9)': + '@inquirer/checkbox@5.1.2(@types/node@24.12.0)': dependencies: - '@inquirer/ansi': 2.0.3 - '@inquirer/core': 11.1.3(@types/node@24.10.9) - '@inquirer/figures': 2.0.3 - '@inquirer/type': 4.0.3(@types/node@24.10.9) + '@inquirer/ansi': 2.0.4 + '@inquirer/core': 11.1.7(@types/node@24.12.0) + '@inquirer/figures': 2.0.4 + '@inquirer/type': 4.0.4(@types/node@24.12.0) optionalDependencies: - '@types/node': 24.10.9 + '@types/node': 24.12.0 - '@inquirer/confirm@5.1.21(@types/node@24.10.9)': + '@inquirer/confirm@5.1.21(@types/node@24.12.0)': dependencies: - '@inquirer/core': 10.3.2(@types/node@24.10.9) - '@inquirer/type': 3.0.10(@types/node@24.10.9) + '@inquirer/core': 10.3.2(@types/node@24.12.0) + '@inquirer/type': 3.0.10(@types/node@24.12.0) optionalDependencies: - '@types/node': 24.10.9 + '@types/node': 24.12.0 - '@inquirer/confirm@6.0.6(@types/node@24.10.9)': + '@inquirer/confirm@6.0.10(@types/node@24.12.0)': dependencies: - '@inquirer/core': 11.1.3(@types/node@24.10.9) - '@inquirer/type': 4.0.3(@types/node@24.10.9) + '@inquirer/core': 11.1.7(@types/node@24.12.0) + '@inquirer/type': 4.0.4(@types/node@24.12.0) optionalDependencies: - '@types/node': 24.10.9 + '@types/node': 24.12.0 - '@inquirer/core@10.3.2(@types/node@24.10.9)': + '@inquirer/core@10.3.2(@types/node@24.12.0)': dependencies: '@inquirer/ansi': 1.0.2 '@inquirer/figures': 1.0.15 - '@inquirer/type': 3.0.10(@types/node@24.10.9) + '@inquirer/type': 3.0.10(@types/node@24.12.0) cli-width: 4.1.0 mute-stream: 2.0.0 signal-exit: 4.1.0 wrap-ansi: 6.2.0 yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 24.10.9 + '@types/node': 24.12.0 - '@inquirer/core@11.1.3(@types/node@24.10.9)': + '@inquirer/core@11.1.7(@types/node@24.12.0)': dependencies: - '@inquirer/ansi': 2.0.3 - '@inquirer/figures': 2.0.3 - '@inquirer/type': 4.0.3(@types/node@24.10.9) + '@inquirer/ansi': 2.0.4 + '@inquirer/figures': 2.0.4 + '@inquirer/type': 4.0.4(@types/node@24.12.0) cli-width: 4.1.0 fast-wrap-ansi: 0.2.0 mute-stream: 3.0.0 signal-exit: 4.1.0 optionalDependencies: - '@types/node': 24.10.9 + '@types/node': 24.12.0 - '@inquirer/editor@4.2.23(@types/node@24.10.9)': + '@inquirer/editor@4.2.23(@types/node@24.12.0)': dependencies: - '@inquirer/core': 10.3.2(@types/node@24.10.9) - '@inquirer/external-editor': 1.0.3(@types/node@24.10.9) - '@inquirer/type': 3.0.10(@types/node@24.10.9) + '@inquirer/core': 10.3.2(@types/node@24.12.0) + '@inquirer/external-editor': 1.0.3(@types/node@24.12.0) + '@inquirer/type': 3.0.10(@types/node@24.12.0) optionalDependencies: - '@types/node': 24.10.9 + '@types/node': 24.12.0 - '@inquirer/editor@5.0.6(@types/node@24.10.9)': + '@inquirer/editor@5.0.10(@types/node@24.12.0)': dependencies: - '@inquirer/core': 11.1.3(@types/node@24.10.9) - '@inquirer/external-editor': 2.0.3(@types/node@24.10.9) - '@inquirer/type': 4.0.3(@types/node@24.10.9) + '@inquirer/core': 11.1.7(@types/node@24.12.0) + '@inquirer/external-editor': 2.0.4(@types/node@24.12.0) + '@inquirer/type': 4.0.4(@types/node@24.12.0) optionalDependencies: - '@types/node': 24.10.9 + '@types/node': 24.12.0 - '@inquirer/expand@4.0.23(@types/node@24.10.9)': + '@inquirer/expand@4.0.23(@types/node@24.12.0)': dependencies: - '@inquirer/core': 10.3.2(@types/node@24.10.9) - '@inquirer/type': 3.0.10(@types/node@24.10.9) + '@inquirer/core': 10.3.2(@types/node@24.12.0) + '@inquirer/type': 3.0.10(@types/node@24.12.0) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 24.10.9 + '@types/node': 24.12.0 - '@inquirer/expand@5.0.6(@types/node@24.10.9)': + '@inquirer/expand@5.0.10(@types/node@24.12.0)': dependencies: - '@inquirer/core': 11.1.3(@types/node@24.10.9) - '@inquirer/type': 4.0.3(@types/node@24.10.9) + '@inquirer/core': 11.1.7(@types/node@24.12.0) + '@inquirer/type': 4.0.4(@types/node@24.12.0) optionalDependencies: - '@types/node': 24.10.9 + '@types/node': 24.12.0 - '@inquirer/external-editor@1.0.3(@types/node@24.10.9)': + '@inquirer/external-editor@1.0.3(@types/node@24.12.0)': dependencies: chardet: 2.1.1 iconv-lite: 0.7.2 optionalDependencies: - '@types/node': 24.10.9 + '@types/node': 24.12.0 - '@inquirer/external-editor@2.0.3(@types/node@24.10.9)': + '@inquirer/external-editor@2.0.4(@types/node@24.12.0)': dependencies: chardet: 2.1.1 iconv-lite: 0.7.2 optionalDependencies: - '@types/node': 24.10.9 + '@types/node': 24.12.0 '@inquirer/figures@1.0.15': {} - '@inquirer/figures@2.0.3': {} + '@inquirer/figures@2.0.4': {} - '@inquirer/input@4.3.1(@types/node@24.10.9)': + '@inquirer/input@4.3.1(@types/node@24.12.0)': dependencies: - '@inquirer/core': 10.3.2(@types/node@24.10.9) - '@inquirer/type': 3.0.10(@types/node@24.10.9) + '@inquirer/core': 10.3.2(@types/node@24.12.0) + '@inquirer/type': 3.0.10(@types/node@24.12.0) optionalDependencies: - '@types/node': 24.10.9 + '@types/node': 24.12.0 - '@inquirer/input@5.0.6(@types/node@24.10.9)': + '@inquirer/input@5.0.10(@types/node@24.12.0)': dependencies: - '@inquirer/core': 11.1.3(@types/node@24.10.9) - '@inquirer/type': 4.0.3(@types/node@24.10.9) + '@inquirer/core': 11.1.7(@types/node@24.12.0) + '@inquirer/type': 4.0.4(@types/node@24.12.0) optionalDependencies: - '@types/node': 24.10.9 + '@types/node': 24.12.0 - '@inquirer/number@3.0.23(@types/node@24.10.9)': + '@inquirer/number@3.0.23(@types/node@24.12.0)': dependencies: - '@inquirer/core': 10.3.2(@types/node@24.10.9) - '@inquirer/type': 3.0.10(@types/node@24.10.9) + '@inquirer/core': 10.3.2(@types/node@24.12.0) + '@inquirer/type': 3.0.10(@types/node@24.12.0) optionalDependencies: - '@types/node': 24.10.9 + '@types/node': 24.12.0 - '@inquirer/number@4.0.6(@types/node@24.10.9)': + '@inquirer/number@4.0.10(@types/node@24.12.0)': dependencies: - '@inquirer/core': 11.1.3(@types/node@24.10.9) - '@inquirer/type': 4.0.3(@types/node@24.10.9) + '@inquirer/core': 11.1.7(@types/node@24.12.0) + '@inquirer/type': 4.0.4(@types/node@24.12.0) optionalDependencies: - '@types/node': 24.10.9 + '@types/node': 24.12.0 - '@inquirer/password@4.0.23(@types/node@24.10.9)': + '@inquirer/password@4.0.23(@types/node@24.12.0)': dependencies: '@inquirer/ansi': 1.0.2 - '@inquirer/core': 10.3.2(@types/node@24.10.9) - '@inquirer/type': 3.0.10(@types/node@24.10.9) + '@inquirer/core': 10.3.2(@types/node@24.12.0) + '@inquirer/type': 3.0.10(@types/node@24.12.0) optionalDependencies: - '@types/node': 24.10.9 + '@types/node': 24.12.0 - '@inquirer/password@5.0.6(@types/node@24.10.9)': + '@inquirer/password@5.0.10(@types/node@24.12.0)': dependencies: - '@inquirer/ansi': 2.0.3 - '@inquirer/core': 11.1.3(@types/node@24.10.9) - '@inquirer/type': 4.0.3(@types/node@24.10.9) + '@inquirer/ansi': 2.0.4 + '@inquirer/core': 11.1.7(@types/node@24.12.0) + '@inquirer/type': 4.0.4(@types/node@24.12.0) optionalDependencies: - '@types/node': 24.10.9 - - '@inquirer/prompts@7.10.1(@types/node@24.10.9)': - dependencies: - '@inquirer/checkbox': 4.3.2(@types/node@24.10.9) - '@inquirer/confirm': 5.1.21(@types/node@24.10.9) - '@inquirer/editor': 4.2.23(@types/node@24.10.9) - '@inquirer/expand': 4.0.23(@types/node@24.10.9) - '@inquirer/input': 4.3.1(@types/node@24.10.9) - '@inquirer/number': 3.0.23(@types/node@24.10.9) - '@inquirer/password': 4.0.23(@types/node@24.10.9) - '@inquirer/rawlist': 4.1.11(@types/node@24.10.9) - '@inquirer/search': 3.2.2(@types/node@24.10.9) - '@inquirer/select': 4.4.2(@types/node@24.10.9) + '@types/node': 24.12.0 + + '@inquirer/prompts@7.10.1(@types/node@24.12.0)': + dependencies: + '@inquirer/checkbox': 4.3.2(@types/node@24.12.0) + '@inquirer/confirm': 5.1.21(@types/node@24.12.0) + '@inquirer/editor': 4.2.23(@types/node@24.12.0) + '@inquirer/expand': 4.0.23(@types/node@24.12.0) + '@inquirer/input': 4.3.1(@types/node@24.12.0) + '@inquirer/number': 3.0.23(@types/node@24.12.0) + '@inquirer/password': 4.0.23(@types/node@24.12.0) + '@inquirer/rawlist': 4.1.11(@types/node@24.12.0) + '@inquirer/search': 3.2.2(@types/node@24.12.0) + '@inquirer/select': 4.4.2(@types/node@24.12.0) optionalDependencies: - '@types/node': 24.10.9 - - '@inquirer/prompts@8.2.0(@types/node@24.10.9)': - dependencies: - '@inquirer/checkbox': 5.0.6(@types/node@24.10.9) - '@inquirer/confirm': 6.0.6(@types/node@24.10.9) - '@inquirer/editor': 5.0.6(@types/node@24.10.9) - '@inquirer/expand': 5.0.6(@types/node@24.10.9) - '@inquirer/input': 5.0.6(@types/node@24.10.9) - '@inquirer/number': 4.0.6(@types/node@24.10.9) - '@inquirer/password': 5.0.6(@types/node@24.10.9) - '@inquirer/rawlist': 5.2.2(@types/node@24.10.9) - '@inquirer/search': 4.1.2(@types/node@24.10.9) - '@inquirer/select': 5.0.6(@types/node@24.10.9) + '@types/node': 24.12.0 + + '@inquirer/prompts@8.3.2(@types/node@24.12.0)': + dependencies: + '@inquirer/checkbox': 5.1.2(@types/node@24.12.0) + '@inquirer/confirm': 6.0.10(@types/node@24.12.0) + '@inquirer/editor': 5.0.10(@types/node@24.12.0) + '@inquirer/expand': 5.0.10(@types/node@24.12.0) + '@inquirer/input': 5.0.10(@types/node@24.12.0) + '@inquirer/number': 4.0.10(@types/node@24.12.0) + '@inquirer/password': 5.0.10(@types/node@24.12.0) + '@inquirer/rawlist': 5.2.6(@types/node@24.12.0) + '@inquirer/search': 4.1.6(@types/node@24.12.0) + '@inquirer/select': 5.1.2(@types/node@24.12.0) optionalDependencies: - '@types/node': 24.10.9 + '@types/node': 24.12.0 - '@inquirer/rawlist@4.1.11(@types/node@24.10.9)': + '@inquirer/rawlist@4.1.11(@types/node@24.12.0)': dependencies: - '@inquirer/core': 10.3.2(@types/node@24.10.9) - '@inquirer/type': 3.0.10(@types/node@24.10.9) + '@inquirer/core': 10.3.2(@types/node@24.12.0) + '@inquirer/type': 3.0.10(@types/node@24.12.0) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 24.10.9 + '@types/node': 24.12.0 - '@inquirer/rawlist@5.2.2(@types/node@24.10.9)': + '@inquirer/rawlist@5.2.6(@types/node@24.12.0)': dependencies: - '@inquirer/core': 11.1.3(@types/node@24.10.9) - '@inquirer/type': 4.0.3(@types/node@24.10.9) + '@inquirer/core': 11.1.7(@types/node@24.12.0) + '@inquirer/type': 4.0.4(@types/node@24.12.0) optionalDependencies: - '@types/node': 24.10.9 + '@types/node': 24.12.0 - '@inquirer/search@3.2.2(@types/node@24.10.9)': + '@inquirer/search@3.2.2(@types/node@24.12.0)': dependencies: - '@inquirer/core': 10.3.2(@types/node@24.10.9) + '@inquirer/core': 10.3.2(@types/node@24.12.0) '@inquirer/figures': 1.0.15 - '@inquirer/type': 3.0.10(@types/node@24.10.9) + '@inquirer/type': 3.0.10(@types/node@24.12.0) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 24.10.9 + '@types/node': 24.12.0 - '@inquirer/search@4.1.2(@types/node@24.10.9)': + '@inquirer/search@4.1.6(@types/node@24.12.0)': dependencies: - '@inquirer/core': 11.1.3(@types/node@24.10.9) - '@inquirer/figures': 2.0.3 - '@inquirer/type': 4.0.3(@types/node@24.10.9) + '@inquirer/core': 11.1.7(@types/node@24.12.0) + '@inquirer/figures': 2.0.4 + '@inquirer/type': 4.0.4(@types/node@24.12.0) optionalDependencies: - '@types/node': 24.10.9 + '@types/node': 24.12.0 - '@inquirer/select@4.4.2(@types/node@24.10.9)': + '@inquirer/select@4.4.2(@types/node@24.12.0)': dependencies: '@inquirer/ansi': 1.0.2 - '@inquirer/core': 10.3.2(@types/node@24.10.9) + '@inquirer/core': 10.3.2(@types/node@24.12.0) '@inquirer/figures': 1.0.15 - '@inquirer/type': 3.0.10(@types/node@24.10.9) + '@inquirer/type': 3.0.10(@types/node@24.12.0) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 24.10.9 + '@types/node': 24.12.0 - '@inquirer/select@5.0.6(@types/node@24.10.9)': + '@inquirer/select@5.1.2(@types/node@24.12.0)': dependencies: - '@inquirer/ansi': 2.0.3 - '@inquirer/core': 11.1.3(@types/node@24.10.9) - '@inquirer/figures': 2.0.3 - '@inquirer/type': 4.0.3(@types/node@24.10.9) + '@inquirer/ansi': 2.0.4 + '@inquirer/core': 11.1.7(@types/node@24.12.0) + '@inquirer/figures': 2.0.4 + '@inquirer/type': 4.0.4(@types/node@24.12.0) optionalDependencies: - '@types/node': 24.10.9 + '@types/node': 24.12.0 - '@inquirer/type@3.0.10(@types/node@24.10.9)': + '@inquirer/type@3.0.10(@types/node@24.12.0)': optionalDependencies: - '@types/node': 24.10.9 + '@types/node': 24.12.0 - '@inquirer/type@4.0.3(@types/node@24.10.9)': + '@inquirer/type@4.0.4(@types/node@24.12.0)': optionalDependencies: - '@types/node': 24.10.9 - - '@isaacs/balanced-match@4.0.1': {} - - '@isaacs/brace-expansion@5.0.1': - dependencies: - '@isaacs/balanced-match': 4.0.1 + '@types/node': 24.12.0 '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 string-width-cjs: string-width@4.2.3 - strip-ansi: 7.1.2 + strip-ansi: 7.2.0 strip-ansi-cjs: strip-ansi@6.0.1 wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 - '@isaacs/cliui@9.0.0': {} - '@isaacs/fs-minipass@4.0.1': dependencies: - minipass: 7.1.2 + minipass: 7.1.3 '@istanbuljs/schema@0.1.3': {} @@ -11311,58 +11274,58 @@ snapshots: dependencies: tslib: 2.8.1 - '@jsonjoy.com/fs-core@4.56.10(tslib@2.8.1)': + '@jsonjoy.com/fs-core@4.57.1(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-node-builtins': 4.56.10(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.56.10(tslib@2.8.1) - thingies: 2.5.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.1(tslib@2.8.1) + thingies: 2.6.0(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-fsa@4.56.10(tslib@2.8.1)': + '@jsonjoy.com/fs-fsa@4.57.1(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-core': 4.56.10(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.56.10(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.56.10(tslib@2.8.1) - thingies: 2.5.0(tslib@2.8.1) + '@jsonjoy.com/fs-core': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.1(tslib@2.8.1) + thingies: 2.6.0(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-node-builtins@4.56.10(tslib@2.8.1)': + '@jsonjoy.com/fs-node-builtins@4.57.1(tslib@2.8.1)': dependencies: tslib: 2.8.1 - '@jsonjoy.com/fs-node-to-fsa@4.56.10(tslib@2.8.1)': + '@jsonjoy.com/fs-node-to-fsa@4.57.1(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-fsa': 4.56.10(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.56.10(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.56.10(tslib@2.8.1) + '@jsonjoy.com/fs-fsa': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.1(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-node-utils@4.56.10(tslib@2.8.1)': + '@jsonjoy.com/fs-node-utils@4.57.1(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-node-builtins': 4.56.10(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.1(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-node@4.56.10(tslib@2.8.1)': + '@jsonjoy.com/fs-node@4.57.1(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-core': 4.56.10(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.56.10(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.56.10(tslib@2.8.1) - '@jsonjoy.com/fs-print': 4.56.10(tslib@2.8.1) - '@jsonjoy.com/fs-snapshot': 4.56.10(tslib@2.8.1) + '@jsonjoy.com/fs-core': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-print': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-snapshot': 4.57.1(tslib@2.8.1) glob-to-regex.js: 1.2.0(tslib@2.8.1) - thingies: 2.5.0(tslib@2.8.1) + thingies: 2.6.0(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-print@4.56.10(tslib@2.8.1)': + '@jsonjoy.com/fs-print@4.57.1(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-node-utils': 4.56.10(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.1(tslib@2.8.1) tree-dump: 1.1.0(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-snapshot@4.56.10(tslib@2.8.1)': + '@jsonjoy.com/fs-snapshot@4.57.1(tslib@2.8.1)': dependencies: '@jsonjoy.com/buffers': 17.67.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.56.10(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.1(tslib@2.8.1) '@jsonjoy.com/json-pack': 17.67.0(tslib@2.8.1) '@jsonjoy.com/util': 17.67.0(tslib@2.8.1) tslib: 2.8.1 @@ -11375,7 +11338,7 @@ snapshots: '@jsonjoy.com/json-pointer': 1.0.2(tslib@2.8.1) '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) hyperdyperid: 1.2.0 - thingies: 2.5.0(tslib@2.8.1) + thingies: 2.6.0(tslib@2.8.1) tree-dump: 1.1.0(tslib@2.8.1) tslib: 2.8.1 @@ -11387,7 +11350,7 @@ snapshots: '@jsonjoy.com/json-pointer': 17.67.0(tslib@2.8.1) '@jsonjoy.com/util': 17.67.0(tslib@2.8.1) hyperdyperid: 1.2.0 - thingies: 2.5.0(tslib@2.8.1) + thingies: 2.6.0(tslib@2.8.1) tree-dump: 1.1.0(tslib@2.8.1) tslib: 2.8.1 @@ -11416,10 +11379,10 @@ snapshots: '@leichtgewicht/ip-codec@2.0.5': {} - '@listr2/prompt-adapter-inquirer@3.0.5(@inquirer/prompts@7.10.1(@types/node@24.10.9))(@types/node@24.10.9)(listr2@9.0.5)': + '@listr2/prompt-adapter-inquirer@3.0.5(@inquirer/prompts@7.10.1(@types/node@24.12.0))(@types/node@24.12.0)(listr2@9.0.5)': dependencies: - '@inquirer/prompts': 7.10.1(@types/node@24.10.9) - '@inquirer/type': 3.0.10(@types/node@24.10.9) + '@inquirer/prompts': 7.10.1(@types/node@24.12.0) + '@inquirer/type': 3.0.10(@types/node@24.12.0) listr2: 9.0.5 transitivePeerDependencies: - '@types/node' @@ -11447,7 +11410,7 @@ snapshots: '@modelcontextprotocol/sdk@1.26.0(zod@4.3.6)': dependencies: - '@hono/node-server': 1.19.9(hono@4.11.9) + '@hono/node-server': 1.19.11(hono@4.12.9) ajv: 8.18.0 ajv-formats: 3.0.1(ajv@8.18.0) content-type: 1.0.5 @@ -11456,14 +11419,14 @@ snapshots: eventsource: 3.0.7 eventsource-parser: 3.0.6 express: 5.2.1 - express-rate-limit: 8.2.1(express@5.2.1) - hono: 4.11.9 - jose: 6.1.3 + express-rate-limit: 8.3.1(express@5.2.1) + hono: 4.12.9 + jose: 6.2.2 json-schema-typed: 8.0.2 pkce-challenge: 5.0.1 raw-body: 3.0.2 zod: 4.3.6 - zod-to-json-schema: 3.25.1(zod@4.3.6) + zod-to-json-schema: 3.25.2(zod@4.3.6) transitivePeerDependencies: - supports-color @@ -11485,7 +11448,7 @@ snapshots: '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3': optional: true - '@mswjs/interceptors@0.39.8': + '@mswjs/interceptors@0.41.3': dependencies: '@open-draft/deferred-promise': 2.2.0 '@open-draft/logger': 0.3.0 @@ -11566,10 +11529,8 @@ snapshots: '@napi-rs/nice-win32-x64-msvc': 1.1.1 optional: true - '@napi-rs/wasm-runtime@1.1.1': + '@napi-rs/wasm-runtime@1.1.2': dependencies: - '@emnapi/core': 1.8.1 - '@emnapi/runtime': 1.8.1 '@tybys/wasm-util': 0.10.1 optional: true @@ -11590,9 +11551,9 @@ snapshots: '@npmcli/agent@4.0.0': dependencies: agent-base: 7.1.4 - http-proxy-agent: 7.0.2 + http-proxy-agent: 7.0.2(supports-color@10.2.2) https-proxy-agent: 7.0.6(supports-color@10.2.2) - lru-cache: 11.2.6 + lru-cache: 11.2.7 socks-proxy-agent: 8.0.5 transitivePeerDependencies: - supports-color @@ -11601,14 +11562,14 @@ snapshots: dependencies: semver: 7.7.4 - '@npmcli/git@7.0.1': + '@npmcli/git@7.0.2': dependencies: + '@gar/promise-retry': 1.0.3 '@npmcli/promise-spawn': 9.0.1 ini: 6.0.0 - lru-cache: 11.2.6 + lru-cache: 11.2.7 npm-pick-manifest: 11.0.3 proc-log: 6.1.0 - promise-retry: 2.0.1 semver: 7.7.4 which: 6.0.1 @@ -11619,15 +11580,15 @@ snapshots: '@npmcli/node-gyp@5.0.0': {} - '@npmcli/package-json@7.0.4': + '@npmcli/package-json@7.0.5': dependencies: - '@npmcli/git': 7.0.1 - glob: 13.0.3 + '@npmcli/git': 7.0.2 + glob: 13.0.6 hosted-git-info: 9.0.2 json-parse-even-better-errors: 5.0.0 proc-log: 6.1.0 semver: 7.7.4 - validate-npm-package-license: 3.0.4 + spdx-expression-parse: 4.0.0 '@npmcli/promise-spawn@9.0.1': dependencies: @@ -11635,22 +11596,21 @@ snapshots: '@npmcli/redact@4.0.0': {} - '@npmcli/run-script@10.0.3': + '@npmcli/run-script@10.0.4': dependencies: '@npmcli/node-gyp': 5.0.0 - '@npmcli/package-json': 7.0.4 + '@npmcli/package-json': 7.0.5 '@npmcli/promise-spawn': 9.0.1 node-gyp: 12.2.0 proc-log: 6.1.0 - which: 6.0.1 transitivePeerDependencies: - supports-color - '@octokit/auth-app@8.1.2': + '@octokit/auth-app@8.2.0': dependencies: '@octokit/auth-oauth-app': 9.0.3 '@octokit/auth-oauth-user': 6.0.2 - '@octokit/request': 10.0.7 + '@octokit/request': 10.0.8 '@octokit/request-error': 7.1.0 '@octokit/types': 16.0.0 toad-cache: 3.7.0 @@ -11661,14 +11621,14 @@ snapshots: dependencies: '@octokit/auth-oauth-device': 8.0.3 '@octokit/auth-oauth-user': 6.0.2 - '@octokit/request': 10.0.7 + '@octokit/request': 10.0.8 '@octokit/types': 16.0.0 universal-user-agent: 7.0.3 '@octokit/auth-oauth-device@8.0.3': dependencies: '@octokit/oauth-methods': 6.0.2 - '@octokit/request': 10.0.7 + '@octokit/request': 10.0.8 '@octokit/types': 16.0.0 universal-user-agent: 7.0.3 @@ -11676,7 +11636,7 @@ snapshots: dependencies: '@octokit/auth-oauth-device': 8.0.3 '@octokit/oauth-methods': 6.0.2 - '@octokit/request': 10.0.7 + '@octokit/request': 10.0.8 '@octokit/types': 16.0.0 universal-user-agent: 7.0.3 @@ -11686,25 +11646,25 @@ snapshots: dependencies: '@octokit/auth-token': 6.0.0 '@octokit/graphql': 9.0.3 - '@octokit/request': 10.0.7 + '@octokit/request': 10.0.8 '@octokit/request-error': 7.1.0 '@octokit/types': 16.0.0 before-after-hook: 4.0.0 universal-user-agent: 7.0.3 - '@octokit/endpoint@11.0.2': + '@octokit/endpoint@11.0.3': dependencies: '@octokit/types': 16.0.0 universal-user-agent: 7.0.3 '@octokit/graphql-schema@15.26.1': dependencies: - graphql: 16.12.0 - graphql-tag: 2.12.6(graphql@16.12.0) + graphql: 16.13.2 + graphql-tag: 2.12.6(graphql@16.13.2) '@octokit/graphql@9.0.3': dependencies: - '@octokit/request': 10.0.7 + '@octokit/request': 10.0.8 '@octokit/types': 16.0.0 universal-user-agent: 7.0.3 @@ -11713,7 +11673,7 @@ snapshots: '@octokit/oauth-methods@6.0.2': dependencies: '@octokit/oauth-authorization-url': 8.0.0 - '@octokit/request': 10.0.7 + '@octokit/request': 10.0.8 '@octokit/request-error': 7.1.0 '@octokit/types': 16.0.0 @@ -11737,12 +11697,13 @@ snapshots: dependencies: '@octokit/types': 16.0.0 - '@octokit/request@10.0.7': + '@octokit/request@10.0.8': dependencies: - '@octokit/endpoint': 11.0.2 + '@octokit/endpoint': 11.0.3 '@octokit/request-error': 7.1.0 '@octokit/types': 16.0.0 fast-content-type-parse: 3.0.0 + json-with-bigint: 3.5.8 universal-user-agent: 7.0.3 '@octokit/rest@22.0.1': @@ -11765,18 +11726,18 @@ snapshots: '@open-draft/until@2.1.0': {} - '@opentelemetry/api@1.9.0': {} + '@opentelemetry/api@1.9.1': {} - '@opentelemetry/context-async-hooks@2.5.1(@opentelemetry/api@1.9.0)': + '@opentelemetry/context-async-hooks@2.6.1(@opentelemetry/api@1.9.1)': dependencies: - '@opentelemetry/api': 1.9.0 + '@opentelemetry/api': 1.9.1 - '@opentelemetry/core@2.5.1(@opentelemetry/api@1.9.0)': + '@opentelemetry/core@2.6.1(@opentelemetry/api@1.9.1)': dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/semantic-conventions': 1.39.0 + '@opentelemetry/api': 1.9.1 + '@opentelemetry/semantic-conventions': 1.40.0 - '@opentelemetry/semantic-conventions@1.39.0': {} + '@opentelemetry/semantic-conventions@1.40.0': {} '@oxc-project/types@0.113.0': {} @@ -11824,7 +11785,7 @@ snapshots: detect-libc: 2.1.2 is-glob: 4.0.3 node-addon-api: 7.1.1 - picomatch: 4.0.3 + picomatch: 4.0.4 optionalDependencies: '@parcel/watcher-android-arm64': 2.5.6 '@parcel/watcher-darwin-arm64': 2.5.6 @@ -11936,21 +11897,21 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true - '@pnpm/crypto.hash@1000.2.1': + '@pnpm/crypto.hash@1000.2.2': dependencies: '@pnpm/crypto.polyfill': 1000.1.0 - '@pnpm/graceful-fs': 1000.0.1 + '@pnpm/graceful-fs': 1000.1.0 ssri: 10.0.5 '@pnpm/crypto.polyfill@1000.1.0': {} - '@pnpm/dependency-path@1001.1.9': + '@pnpm/dependency-path@1001.1.10': dependencies: - '@pnpm/crypto.hash': 1000.2.1 + '@pnpm/crypto.hash': 1000.2.2 '@pnpm/types': 1001.3.0 semver: 7.7.4 - '@pnpm/graceful-fs@1000.0.1': + '@pnpm/graceful-fs@1000.1.0': dependencies: graceful-fs: 4.2.11 @@ -11979,14 +11940,14 @@ snapshots: '@protobufjs/utf8@1.1.0': {} - '@puppeteer/browsers@2.12.1': + '@puppeteer/browsers@2.13.0': dependencies: debug: 4.4.3(supports-color@10.2.2) extract-zip: 2.0.1 progress: 2.0.3 proxy-agent: 6.5.0 semver: 7.7.4 - tar-fs: 3.1.1 + tar-fs: 3.1.2 yargs: 17.7.2 transitivePeerDependencies: - bare-abort-controller @@ -12026,7 +11987,10 @@ snapshots: '@rolldown/binding-wasm32-wasi@1.0.0-rc.4': dependencies: - '@napi-rs/wasm-runtime': 1.1.1 + '@napi-rs/wasm-runtime': 1.1.2 + transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' optional: true '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.4': @@ -12041,15 +12005,15 @@ snapshots: optionalDependencies: rollup: 4.57.1 - '@rollup/plugin-commonjs@29.0.0(rollup@4.57.1)': + '@rollup/plugin-commonjs@29.0.2(rollup@4.57.1)': dependencies: '@rollup/pluginutils': 5.3.0(rollup@4.57.1) commondir: 1.0.1 estree-walker: 2.0.2 - fdir: 6.5.0(picomatch@4.0.3) + fdir: 6.5.0(picomatch@4.0.4) is-reference: 1.2.1 magic-string: 0.30.21 - picomatch: 4.0.3 + picomatch: 4.0.4 optionalDependencies: rollup: 4.57.1 @@ -12083,7 +12047,7 @@ snapshots: dependencies: '@types/estree': 1.0.8 estree-walker: 2.0.2 - picomatch: 4.0.3 + picomatch: 4.0.4 optionalDependencies: rollup: 4.57.1 @@ -12091,7 +12055,7 @@ snapshots: dependencies: '@types/estree': 1.0.8 estree-walker: 2.0.2 - picomatch: 4.0.3 + picomatch: 4.0.4 optionalDependencies: rollup: 4.57.1 @@ -12170,7 +12134,7 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.57.1': optional: true - '@rollup/wasm-node@4.57.1': + '@rollup/wasm-node@4.59.0': dependencies: '@types/estree': 1.0.8 optionalDependencies: @@ -12182,22 +12146,22 @@ snapshots: dependencies: '@sigstore/protobuf-specs': 0.5.0 - '@sigstore/core@3.1.0': {} + '@sigstore/core@3.2.0': {} '@sigstore/protobuf-specs@0.5.0': {} - '@sigstore/sign@4.1.0': + '@sigstore/sign@4.1.1': dependencies: + '@gar/promise-retry': 1.0.3 '@sigstore/bundle': 4.0.0 - '@sigstore/core': 3.1.0 + '@sigstore/core': 3.2.0 '@sigstore/protobuf-specs': 0.5.0 - make-fetch-happen: 15.0.3 + make-fetch-happen: 15.0.5 proc-log: 6.1.0 - promise-retry: 2.0.1 transitivePeerDependencies: - supports-color - '@sigstore/tuf@4.0.1': + '@sigstore/tuf@4.0.2': dependencies: '@sigstore/protobuf-specs': 0.5.0 tuf-js: 4.1.0 @@ -12207,31 +12171,35 @@ snapshots: '@sigstore/verify@3.1.0': dependencies: '@sigstore/bundle': 4.0.0 - '@sigstore/core': 3.1.0 + '@sigstore/core': 3.2.0 '@sigstore/protobuf-specs': 0.5.0 + '@simple-libs/child-process-utils@1.0.2': + dependencies: + '@simple-libs/stream-utils': 1.2.0 + + '@simple-libs/stream-utils@1.2.0': {} + '@sindresorhus/is@4.6.0': {} '@socket.io/component-emitter@3.1.2': {} '@standard-schema/spec@1.1.0': {} - '@stylistic/eslint-plugin@5.8.0(eslint@9.39.2(jiti@2.6.1))': + '@stylistic/eslint-plugin@5.10.0(eslint@9.39.2(jiti@2.6.1))': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@2.6.1)) - '@typescript-eslint/types': 8.55.0 + '@typescript-eslint/types': 8.57.2 eslint: 9.39.2(jiti@2.6.1) eslint-visitor-keys: 4.2.1 espree: 10.4.0 estraverse: 5.3.0 - picomatch: 4.0.3 + picomatch: 4.0.4 '@szmarczak/http-timer@4.0.6': dependencies: defer-to-connect: 2.0.1 - '@tootallnate/once@2.0.0': {} - '@tootallnate/quickjs-emscripten@0.23.0': {} '@tsconfig/node10@1.0.12': {} @@ -12247,7 +12215,7 @@ snapshots: '@tufjs/models@4.1.0': dependencies: '@tufjs/canonical-json': 2.0.0 - minimatch: 10.2.0 + minimatch: 10.2.4 '@tybys/wasm-util@0.10.1': dependencies: @@ -12256,13 +12224,13 @@ snapshots: '@types/accepts@1.3.7': dependencies: - '@types/node': 22.19.11 + '@types/node': 22.19.15 '@types/babel__code-frame@7.27.0': {} '@types/babel__core@7.20.5': dependencies: - '@babel/parser': 7.29.0 + '@babel/parser': 7.29.2 '@babel/types': 7.29.0 '@types/babel__generator': 7.27.0 '@types/babel__template': 7.4.4 @@ -12274,7 +12242,7 @@ snapshots: '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.29.0 + '@babel/parser': 7.29.2 '@babel/types': 7.29.0 '@types/babel__traverse@7.28.0': @@ -12286,16 +12254,16 @@ snapshots: '@types/body-parser@1.19.6': dependencies: '@types/connect': 3.4.38 - '@types/node': 22.19.11 + '@types/node': 22.19.15 '@types/bonjour@3.5.13': dependencies: - '@types/node': 22.19.11 + '@types/node': 22.19.15 '@types/browser-sync@2.29.1': dependencies: '@types/micromatch': 2.3.35 - '@types/node': 22.19.11 + '@types/node': 22.19.15 '@types/serve-static': 2.2.0 chokidar: 3.6.0 @@ -12306,23 +12274,23 @@ snapshots: '@types/cli-progress@3.11.6': dependencies: - '@types/node': 22.19.11 + '@types/node': 22.19.15 '@types/co-body@6.1.3': dependencies: - '@types/node': 22.19.11 - '@types/qs': 6.14.0 + '@types/node': 22.19.15 + '@types/qs': 6.15.0 '@types/command-line-args@5.2.3': {} '@types/connect-history-api-fallback@1.5.4': dependencies: '@types/express-serve-static-core': 4.19.8 - '@types/node': 22.19.11 + '@types/node': 22.19.15 '@types/connect@3.4.38': dependencies: - '@types/node': 22.19.11 + '@types/node': 22.19.15 '@types/content-disposition@0.5.9': {} @@ -12333,11 +12301,11 @@ snapshots: '@types/connect': 3.4.38 '@types/express': 5.0.6 '@types/keygrip': 1.0.6 - '@types/node': 22.19.11 + '@types/node': 22.19.15 '@types/cors@2.8.19': dependencies: - '@types/node': 22.19.11 + '@types/node': 22.19.15 '@types/debounce@1.2.4': {} @@ -12345,7 +12313,7 @@ snapshots: '@types/duplexify@3.6.5': dependencies: - '@types/node': 22.19.11 + '@types/node': 22.19.15 '@types/ejs@3.1.5': {} @@ -12365,15 +12333,15 @@ snapshots: '@types/express-serve-static-core@4.19.8': dependencies: - '@types/node': 22.19.11 - '@types/qs': 6.14.0 + '@types/node': 22.19.15 + '@types/qs': 6.15.0 '@types/range-parser': 1.2.7 '@types/send': 1.2.1 '@types/express-serve-static-core@5.1.1': dependencies: - '@types/node': 22.19.11 - '@types/qs': 6.14.0 + '@types/node': 22.19.15 + '@types/qs': 6.15.0 '@types/range-parser': 1.2.7 '@types/send': 1.2.1 @@ -12381,7 +12349,7 @@ snapshots: dependencies: '@types/body-parser': 1.19.6 '@types/express-serve-static-core': 4.19.8 - '@types/qs': 6.14.0 + '@types/qs': 6.15.0 '@types/serve-static': 1.15.10 '@types/express@5.0.6': @@ -12392,13 +12360,9 @@ snapshots: '@types/folder-hash@4.0.4': {} - '@types/git-raw-commits@5.0.1': - dependencies: - '@types/node': 22.19.11 - '@types/graceful-fs@4.1.9': dependencies: - '@types/node': 22.19.11 + '@types/node': 22.19.15 '@types/http-assert@1.5.6': {} @@ -12406,7 +12370,7 @@ snapshots: '@types/http-proxy@1.17.17': dependencies: - '@types/node': 22.19.11 + '@types/node': 22.19.15 '@types/ini@4.1.1': {} @@ -12434,7 +12398,7 @@ snapshots: '@types/karma@6.3.9': dependencies: - '@types/node': 22.19.11 + '@types/node': 22.19.15 log4js: 6.9.1 transitivePeerDependencies: - supports-color @@ -12454,13 +12418,13 @@ snapshots: '@types/http-errors': 2.0.5 '@types/keygrip': 1.0.6 '@types/koa-compose': 3.2.9 - '@types/node': 22.19.11 + '@types/node': 22.19.15 '@types/less@3.0.8': {} '@types/loader-utils@3.0.0(esbuild@0.27.3)': dependencies: - '@types/node': 22.19.11 + '@types/node': 22.19.15 webpack: 5.105.2(esbuild@0.27.3) transitivePeerDependencies: - '@swc/core' @@ -12468,7 +12432,7 @@ snapshots: - uglify-js - webpack-cli - '@types/lodash@4.17.23': {} + '@types/lodash@4.17.24': {} '@types/micromatch@2.3.35': dependencies: @@ -12478,22 +12442,22 @@ snapshots: '@types/node-fetch@2.6.13': dependencies: - '@types/node': 22.19.11 + '@types/node': 22.19.15 form-data: 4.0.5 - '@types/node@22.19.11': + '@types/node@22.19.15': dependencies: - undici-types: 7.22.0 + undici-types: 7.24.6 - '@types/node@24.10.9': + '@types/node@24.12.0': dependencies: - undici-types: 7.22.0 + undici-types: 7.24.6 '@types/npm-package-arg@6.1.4': {} '@types/npm-registry-fetch@8.0.9': dependencies: - '@types/node': 22.19.11 + '@types/node': 22.19.15 '@types/node-fetch': 2.6.13 '@types/npm-package-arg': 6.1.4 '@types/npmlog': 7.0.0 @@ -12501,11 +12465,11 @@ snapshots: '@types/npmlog@7.0.0': dependencies: - '@types/node': 22.19.11 + '@types/node': 22.19.15 '@types/pacote@11.1.8': dependencies: - '@types/node': 22.19.11 + '@types/node': 22.19.15 '@types/npm-registry-fetch': 8.0.9 '@types/npmlog': 7.0.0 '@types/ssri': 7.1.5 @@ -12518,16 +12482,16 @@ snapshots: '@types/progress@2.0.7': dependencies: - '@types/node': 22.19.11 + '@types/node': 22.19.15 '@types/pumpify@1.4.5': dependencies: '@types/duplexify': 3.6.5 - '@types/node': 22.19.11 + '@types/node': 22.19.15 '@types/q@0.0.32': {} - '@types/qs@6.14.0': {} + '@types/qs@6.15.0': {} '@types/range-parser@1.2.7': {} @@ -12535,7 +12499,9 @@ snapshots: '@types/responselike@1.0.0': dependencies: - '@types/node': 22.19.11 + '@types/node': 22.19.15 + + '@types/retry@0.12.0': {} '@types/retry@0.12.2': {} @@ -12546,11 +12512,11 @@ snapshots: '@types/send@0.17.6': dependencies: '@types/mime': 1.3.5 - '@types/node': 22.19.11 + '@types/node': 22.19.15 '@types/send@1.2.1': dependencies: - '@types/node': 22.19.11 + '@types/node': 22.19.15 '@types/serve-index@1.9.4': dependencies: @@ -12559,42 +12525,42 @@ snapshots: '@types/serve-static@1.15.10': dependencies: '@types/http-errors': 2.0.5 - '@types/node': 22.19.11 + '@types/node': 22.19.15 '@types/send': 0.17.6 '@types/serve-static@2.2.0': dependencies: '@types/http-errors': 2.0.5 - '@types/node': 22.19.11 + '@types/node': 22.19.15 '@types/sockjs@0.3.36': dependencies: - '@types/node': 22.19.11 + '@types/node': 22.19.15 '@types/ssri@7.1.5': dependencies: - '@types/node': 22.19.11 + '@types/node': 22.19.15 '@types/stack-trace@0.0.33': {} '@types/tar-stream@3.1.4': dependencies: - '@types/node': 22.19.11 + '@types/node': 22.19.15 '@types/watchpack@2.4.5': dependencies: '@types/graceful-fs': 4.1.9 - '@types/node': 22.19.11 + '@types/node': 22.19.15 '@types/which@3.0.4': {} '@types/ws@7.4.7': dependencies: - '@types/node': 22.19.11 + '@types/node': 22.19.15 '@types/ws@8.18.1': dependencies: - '@types/node': 22.19.11 + '@types/node': 22.19.15 '@types/yargs-parser@21.0.3': {} @@ -12606,7 +12572,7 @@ snapshots: '@types/yauzl@2.10.3': dependencies: - '@types/node': 22.19.11 + '@types/node': 22.19.15 optional: true '@typescript-eslint/eslint-plugin@8.55.0(@typescript-eslint/parser@8.55.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': @@ -12620,7 +12586,7 @@ snapshots: eslint: 9.39.2(jiti@2.6.1) ignore: 7.0.5 natural-compare: 1.4.0 - ts-api-utils: 2.4.0(typescript@5.9.3) + ts-api-utils: 2.5.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -12662,13 +12628,15 @@ snapshots: '@typescript-eslint/utils': 8.55.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) debug: 4.4.3(supports-color@10.2.2) eslint: 9.39.2(jiti@2.6.1) - ts-api-utils: 2.4.0(typescript@5.9.3) + ts-api-utils: 2.5.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color '@typescript-eslint/types@8.55.0': {} + '@typescript-eslint/types@8.57.2': {} + '@typescript-eslint/typescript-estree@8.55.0(typescript@5.9.3)': dependencies: '@typescript-eslint/project-service': 8.55.0(typescript@5.9.3) @@ -12676,10 +12644,10 @@ snapshots: '@typescript-eslint/types': 8.55.0 '@typescript-eslint/visitor-keys': 8.55.0 debug: 4.4.3(supports-color@10.2.2) - minimatch: 9.0.5 + minimatch: 9.0.9 semver: 7.7.4 tinyglobby: 0.2.15 - ts-api-utils: 2.4.0(typescript@5.9.3) + ts-api-utils: 2.5.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -12857,23 +12825,23 @@ snapshots: lodash: 4.17.21 minimatch: 7.4.6 - '@vitejs/plugin-basic-ssl@2.1.4(vite@7.3.1(@types/node@24.10.9)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + '@vitejs/plugin-basic-ssl@2.1.4(vite@7.3.1(@types/node@24.12.0)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.3))': dependencies: - vite: 7.3.1(@types/node@24.10.9)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@24.12.0)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.3) - '@vitest/coverage-v8@4.0.18(vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@24.10.9)(jiti@2.6.1)(jsdom@28.1.0)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + '@vitest/coverage-v8@4.0.18(vitest@4.0.18(@opentelemetry/api@1.9.1)(@types/node@24.12.0)(jiti@2.6.1)(jsdom@28.1.0)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.3))': dependencies: '@bcoe/v8-coverage': 1.0.2 '@vitest/utils': 4.0.18 - ast-v8-to-istanbul: 0.3.11 + ast-v8-to-istanbul: 0.3.12 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 istanbul-reports: 3.2.0 magicast: 0.5.2 obug: 2.1.1 std-env: 3.10.0 - tinyrainbow: 3.0.3 - vitest: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@24.10.9)(jiti@2.6.1)(jsdom@28.1.0)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + tinyrainbow: 3.1.0 + vitest: 4.0.18(@opentelemetry/api@1.9.1)(@types/node@24.12.0)(jiti@2.6.1)(jsdom@28.1.0)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.3) '@vitest/expect@4.0.18': dependencies: @@ -12882,19 +12850,19 @@ snapshots: '@vitest/spy': 4.0.18 '@vitest/utils': 4.0.18 chai: 6.2.2 - tinyrainbow: 3.0.3 + tinyrainbow: 3.1.0 - '@vitest/mocker@4.0.18(vite@7.3.1(@types/node@24.10.9)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + '@vitest/mocker@4.0.18(vite@7.3.1(@types/node@24.12.0)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.3))': dependencies: '@vitest/spy': 4.0.18 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.3.1(@types/node@24.10.9)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@24.12.0)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.3) '@vitest/pretty-format@4.0.18': dependencies: - tinyrainbow: 3.0.3 + tinyrainbow: 3.1.0 '@vitest/runner@4.0.18': dependencies: @@ -12912,7 +12880,7 @@ snapshots: '@vitest/utils@4.0.18': dependencies: '@vitest/pretty-format': 4.0.18 - tinyrainbow: 3.0.3 + tinyrainbow: 3.1.0 '@web/browser-logs@0.4.1': dependencies: @@ -12931,14 +12899,14 @@ snapshots: get-stream: 6.0.1 is-stream: 2.0.1 isbinaryfile: 5.0.7 - koa: 2.16.3 + koa: 2.16.4 koa-etag: 4.0.0 koa-send: 5.0.1 koa-static: 5.0.0 lru-cache: 8.0.5 mime-types: 2.1.35 parse5: 6.0.1 - picomatch: 2.3.1 + picomatch: 2.3.2 ws: 7.5.10(bufferutil@4.1.0) transitivePeerDependencies: - bufferutil @@ -12967,7 +12935,7 @@ snapshots: '@web/dev-server-rollup': 0.6.4(bufferutil@4.1.0) camelcase: 6.3.0 command-line-args: 5.2.1 - command-line-usage: 7.0.3 + command-line-usage: 7.0.4 debounce: 1.2.1 deepmerge: 4.3.1 internal-ip: 6.2.0 @@ -12989,7 +12957,7 @@ snapshots: '@web/test-runner-core': 0.13.4(bufferutil@4.1.0) '@web/test-runner-coverage-v8': 0.8.0(bufferutil@4.1.0) chrome-launcher: 0.15.2 - puppeteer-core: 24.37.3(bufferutil@4.1.0) + puppeteer-core: 24.40.0(bufferutil@4.1.0) transitivePeerDependencies: - bare-abort-controller - bare-buffer @@ -13033,7 +13001,7 @@ snapshots: nanocolors: 0.2.13 nanoid: 3.3.11 open: 8.4.2 - picomatch: 2.3.1 + picomatch: 2.3.2 source-map: 0.7.6 transitivePeerDependencies: - bufferutil @@ -13045,7 +13013,7 @@ snapshots: '@web/test-runner-core': 0.13.4(bufferutil@4.1.0) istanbul-lib-coverage: 3.2.2 lru-cache: 8.0.5 - picomatch: 2.3.1 + picomatch: 2.3.2 v8-to-istanbul: 9.3.0 transitivePeerDependencies: - bufferutil @@ -13071,7 +13039,7 @@ snapshots: '@web/test-runner-mocha': 0.9.0(bufferutil@4.1.0) camelcase: 6.3.0 command-line-args: 5.2.1 - command-line-usage: 7.0.3 + command-line-usage: 7.0.4 convert-source-map: 2.0.0 diff: 5.2.2 globby: 11.1.0 @@ -13162,7 +13130,7 @@ snapshots: '@webassemblyjs/ast': 1.14.1 '@xtuc/long': 4.2.2 - '@xmldom/xmldom@0.8.11': {} + '@xmldom/xmldom@0.8.12': {} '@xtuc/ieee754@1.2.0': {} @@ -13191,19 +13159,19 @@ snapshots: mime-types: 3.0.2 negotiator: 1.0.0 - acorn-import-phases@1.0.4(acorn@8.15.0): + acorn-import-phases@1.0.4(acorn@8.16.0): dependencies: - acorn: 8.15.0 + acorn: 8.16.0 - acorn-jsx@5.3.2(acorn@8.15.0): + acorn-jsx@5.3.2(acorn@8.16.0): dependencies: - acorn: 8.15.0 + acorn: 8.16.0 - acorn-walk@8.3.4: + acorn-walk@8.3.5: dependencies: - acorn: 8.15.0 + acorn: 8.16.0 - acorn@8.15.0: {} + acorn@8.16.0: {} adjust-sourcemap-loader@4.0.0: dependencies: @@ -13216,7 +13184,7 @@ snapshots: dependencies: es6-promisify: 5.0.0 - agent-base@6.0.2(supports-color@10.2.2): + agent-base@6.0.2: dependencies: debug: 4.4.3(supports-color@10.2.2) transitivePeerDependencies: @@ -13237,7 +13205,7 @@ snapshots: ajv: 8.18.0 fast-deep-equal: 3.1.3 - ajv@6.12.6: + ajv@6.14.0: dependencies: fast-deep-equal: 3.1.3 fast-json-stable-stringify: 2.1.0 @@ -13304,7 +13272,7 @@ snapshots: anymatch@3.1.3: dependencies: normalize-path: 3.0.0 - picomatch: 2.3.1 + picomatch: 2.3.2 apache-md5@1.1.8: {} @@ -13314,7 +13282,7 @@ snapshots: array-back@3.1.0: {} - array-back@6.2.2: {} + array-back@6.2.3: {} array-buffer-byte-length@1.0.2: dependencies: @@ -13402,7 +13370,7 @@ snapshots: dependencies: tslib: 2.8.1 - ast-v8-to-istanbul@0.3.11: + ast-v8-to-istanbul@0.3.12: dependencies: '@jridgewell/trace-mapping': 0.3.31 estree-walker: 3.0.3 @@ -13424,10 +13392,10 @@ snapshots: atomic-sleep@1.0.0: {} - autoprefixer@10.4.24(postcss@8.5.6): + autoprefixer@10.4.27(postcss@8.5.6): dependencies: browserslist: 4.28.1 - caniuse-lite: 1.0.30001770 + caniuse-lite: 1.0.30001782 fraction.js: 5.3.4 picocolors: 1.1.1 postcss: 8.5.6 @@ -13441,7 +13409,7 @@ snapshots: aws4@1.13.2: {} - b4a@1.7.4: {} + b4a@1.8.0: {} babel-loader@10.0.0(@babel/core@7.29.0)(webpack@5.105.2(esbuild@0.27.3)): dependencies: @@ -13449,11 +13417,11 @@ snapshots: find-up: 5.0.0 webpack: 5.105.2(esbuild@0.27.3) - babel-plugin-polyfill-corejs2@0.4.15(@babel/core@7.29.0): + babel-plugin-polyfill-corejs2@0.4.17(@babel/core@7.29.0): dependencies: '@babel/compat-data': 7.29.0 '@babel/core': 7.29.0 - '@babel/helper-define-polyfill-provider': 0.6.6(@babel/core@7.29.0) + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.0) semver: 6.3.1 transitivePeerDependencies: - supports-color @@ -13461,65 +13429,63 @@ snapshots: babel-plugin-polyfill-corejs3@0.13.0(@babel/core@7.29.0): dependencies: '@babel/core': 7.29.0 - '@babel/helper-define-polyfill-provider': 0.6.6(@babel/core@7.29.0) - core-js-compat: 3.48.0 + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.0) + core-js-compat: 3.49.0 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-corejs3@0.14.0(@babel/core@7.29.0): + babel-plugin-polyfill-corejs3@0.14.2(@babel/core@7.29.0): dependencies: '@babel/core': 7.29.0 - '@babel/helper-define-polyfill-provider': 0.6.6(@babel/core@7.29.0) - core-js-compat: 3.48.0 + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.0) + core-js-compat: 3.49.0 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-regenerator@0.6.6(@babel/core@7.29.0): + babel-plugin-polyfill-regenerator@0.6.8(@babel/core@7.29.0): dependencies: '@babel/core': 7.29.0 - '@babel/helper-define-polyfill-provider': 0.6.6(@babel/core@7.29.0) + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.0) transitivePeerDependencies: - supports-color balanced-match@1.0.2: {} - balanced-match@4.0.2: - dependencies: - jackspeak: 4.2.3 + balanced-match@4.0.4: {} bare-events@2.8.2: {} - bare-fs@4.5.4: + bare-fs@4.5.6: dependencies: bare-events: 2.8.2 bare-path: 3.0.0 - bare-stream: 2.7.0(bare-events@2.8.2) - bare-url: 2.3.2 + bare-stream: 2.11.0(bare-events@2.8.2) + bare-url: 2.4.0 fast-fifo: 1.3.2 transitivePeerDependencies: - bare-abort-controller - react-native-b4a optional: true - bare-os@3.6.2: + bare-os@3.8.4: optional: true bare-path@3.0.0: dependencies: - bare-os: 3.6.2 + bare-os: 3.8.4 optional: true - bare-stream@2.7.0(bare-events@2.8.2): + bare-stream@2.11.0(bare-events@2.8.2): dependencies: - streamx: 2.23.0 + streamx: 2.25.0 + teex: 1.0.1 optionalDependencies: bare-events: 2.8.2 transitivePeerDependencies: - - bare-abort-controller - react-native-b4a optional: true - bare-url@2.3.2: + bare-url@2.4.0: dependencies: bare-path: 3.0.0 optional: true @@ -13528,9 +13494,9 @@ snapshots: base64id@2.0.0: {} - baseline-browser-mapping@2.9.19: {} + baseline-browser-mapping@2.10.12: {} - basic-ftp@5.1.0: {} + basic-ftp@5.2.0: {} batch@0.6.1: {} @@ -13614,18 +13580,18 @@ snapshots: boolbase@1.0.0: {} - brace-expansion@1.1.12: + brace-expansion@1.1.13: dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 - brace-expansion@2.0.2: + brace-expansion@2.0.3: dependencies: balanced-match: 1.0.2 - brace-expansion@5.0.2: + brace-expansion@5.0.5: dependencies: - balanced-match: 4.0.2 + balanced-match: 4.0.4 braces@3.0.3: dependencies: @@ -13644,7 +13610,7 @@ snapshots: async-each-series: 0.1.1 chalk: 4.1.2 connect-history-api-fallback: 1.6.0 - immutable: 3.8.2 + immutable: 3.8.3 server-destroy: 1.0.1 socket.io-client: 4.8.3(bufferutil@4.1.0)(utf-8-validate@6.0.6) stream-throttle: 0.1.3 @@ -13669,7 +13635,7 @@ snapshots: fresh: 0.5.2 fs-extra: 3.0.1 http-proxy: 1.18.1(debug@4.4.3) - immutable: 3.8.2 + immutable: 3.8.3 micromatch: 4.0.8 opn: 5.3.0 portscanner: 2.2.0 @@ -13695,10 +13661,10 @@ snapshots: browserslist@4.28.1: dependencies: - baseline-browser-mapping: 2.9.19 - caniuse-lite: 1.0.30001770 - electron-to-chromium: 1.5.286 - node-releases: 2.0.27 + baseline-browser-mapping: 2.10.12 + caniuse-lite: 1.0.30001782 + electron-to-chromium: 1.5.328 + node-releases: 2.0.36 update-browserslist-db: 1.2.3(browserslist@4.28.1) browserstack@1.6.1: @@ -13737,19 +13703,18 @@ snapshots: bytestreamjs@2.0.1: {} - cacache@20.0.3: + cacache@20.0.4: dependencies: '@npmcli/fs': 5.0.0 fs-minipass: 3.0.3 - glob: 13.0.3 - lru-cache: 11.2.6 - minipass: 7.1.2 + glob: 13.0.6 + lru-cache: 11.2.7 + minipass: 7.1.3 minipass-collect: 2.0.1 - minipass-flush: 1.0.5 + minipass-flush: 1.0.7 minipass-pipeline: 1.2.4 p-map: 7.0.4 ssri: 13.0.1 - unique-filename: 5.0.0 cache-content-type@1.0.1: dependencies: @@ -13791,7 +13756,7 @@ snapshots: camelcase@6.3.0: {} - caniuse-lite@1.0.30001770: {} + caniuse-lite@1.0.30001782: {} caseless@0.12.0: {} @@ -13852,7 +13817,7 @@ snapshots: chrome-launcher@0.15.2: dependencies: - '@types/node': 22.19.11 + '@types/node': 22.19.15 escape-string-regexp: 4.0.0 is-wsl: 2.2.0 lighthouse-logger: 1.4.2 @@ -13861,9 +13826,9 @@ snapshots: chrome-trace-event@1.0.4: {} - chromium-bidi@14.0.0(devtools-protocol@0.0.1566079): + chromium-bidi@14.0.0(devtools-protocol@0.0.1581282): dependencies: - devtools-protocol: 0.0.1566079 + devtools-protocol: 0.0.1581282 mitt: 3.0.1 zod: 3.25.76 @@ -13881,10 +13846,10 @@ snapshots: cli-spinners@3.4.0: {} - cli-truncate@5.1.1: + cli-truncate@5.2.0: dependencies: - slice-ansi: 7.1.2 - string-width: 8.1.1 + slice-ansi: 8.0.0 + string-width: 8.2.0 cli-width@4.1.0: {} @@ -13913,7 +13878,7 @@ snapshots: cliui@9.0.1: dependencies: string-width: 7.2.0 - strip-ansi: 7.1.2 + strip-ansi: 7.2.0 wrap-ansi: 9.0.2 clone-deep@4.0.1: @@ -13961,9 +13926,9 @@ snapshots: lodash.camelcase: 4.3.0 typical: 4.0.0 - command-line-usage@7.0.3: + command-line-usage@7.0.4: dependencies: - array-back: 6.2.2 + array-back: 6.2.3 chalk-template: 0.4.0 table-layout: 4.1.1 typical: 7.3.0 @@ -14028,8 +13993,9 @@ snapshots: conventional-commits-filter@5.0.0: {} - conventional-commits-parser@6.2.1: + conventional-commits-parser@6.4.0: dependencies: + '@simple-libs/stream-utils': 1.2.0 meow: 13.2.0 convert-source-map@1.9.0: {} @@ -14051,16 +14017,16 @@ snapshots: dependencies: is-what: 3.14.1 - copy-webpack-plugin@13.0.1(webpack@5.105.2(esbuild@0.27.3)): + copy-webpack-plugin@14.0.0(webpack@5.105.2(esbuild@0.27.3)): dependencies: glob-parent: 6.0.2 normalize-path: 3.0.0 schema-utils: 4.3.3 - serialize-javascript: 6.0.2 + serialize-javascript: 7.0.5 tinyglobby: 0.2.15 webpack: 5.105.2(esbuild@0.27.3) - core-js-compat@3.48.0: + core-js-compat@3.49.0: dependencies: browserslist: 4.28.1 @@ -14068,17 +14034,12 @@ snapshots: core-util-is@1.0.3: {} - cors@2.8.5: - dependencies: - object-assign: 4.1.1 - vary: 1.1.2 - cors@2.8.6: dependencies: object-assign: 4.1.1 vary: 1.1.2 - cosmiconfig@9.0.0(typescript@5.9.3): + cosmiconfig@9.0.1(typescript@5.9.3): dependencies: env-paths: 2.2.1 import-fresh: 3.3.1 @@ -14128,21 +14089,21 @@ snapshots: domutils: 3.2.2 nth-check: 2.1.1 - css-tree@3.1.0: + css-tree@3.2.1: dependencies: - mdn-data: 2.12.2 + mdn-data: 2.27.1 source-map-js: 1.2.1 css-what@7.0.0: {} cssesc@3.0.0: {} - cssstyle@6.0.1: + cssstyle@6.2.0: dependencies: - '@asamuzakjp/css-color': 4.1.2 - '@csstools/css-syntax-patches-for-csstree': 1.0.27 - css-tree: 3.1.0 - lru-cache: 11.2.6 + '@asamuzakjp/css-color': 5.1.1 + '@csstools/css-syntax-patches-for-csstree': 1.1.2(css-tree@3.2.1) + css-tree: 3.2.1 + lru-cache: 11.2.7 custom-event@1.0.1: {} @@ -14157,7 +14118,7 @@ snapshots: data-urls@7.0.0: dependencies: whatwg-mimetype: 5.0.0 - whatwg-url: 16.0.0 + whatwg-url: 16.0.1 transitivePeerDependencies: - '@noble/hashes' @@ -14297,7 +14258,7 @@ snapshots: devtools-protocol@0.0.1045489: {} - devtools-protocol@0.0.1566079: {} + devtools-protocol@0.0.1581282: {} di@0.0.1: {} @@ -14383,11 +14344,9 @@ snapshots: ee-first@1.1.1: {} - ejs@4.0.1: - dependencies: - jake: 10.9.4 + ejs@5.0.1: {} - electron-to-chromium@1.5.286: {} + electron-to-chromium@1.5.328: {} emoji-regex@10.6.0: {} @@ -14423,10 +14382,11 @@ snapshots: engine.io-parser@5.2.3: {} - engine.io@6.6.5(bufferutil@4.1.0)(utf-8-validate@6.0.6): + engine.io@6.6.6(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: '@types/cors': 2.8.19 - '@types/node': 22.19.11 + '@types/node': 22.19.15 + '@types/ws': 8.18.1 accepts: 1.3.8 base64id: 2.0.0 cookie: 0.7.2 @@ -14439,10 +14399,10 @@ snapshots: - supports-color - utf-8-validate - enhanced-resolve@5.19.0: + enhanced-resolve@5.20.1: dependencies: graceful-fs: 4.2.11 - tapable: 2.3.0 + tapable: 2.3.2 ent@2.2.2: dependencies: @@ -14656,7 +14616,7 @@ snapshots: hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 - minimatch: 3.1.2 + minimatch: 3.1.5 object.fromentries: 2.0.8 object.groupby: 1.0.3 object.values: 1.2.1 @@ -14688,7 +14648,7 @@ snapshots: dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@2.6.1)) '@eslint-community/regexpp': 4.12.2 - '@eslint/config-array': 0.21.1 + '@eslint/config-array': 0.21.2 '@eslint/config-helpers': 0.4.2 '@eslint/core': 0.17.0 '@eslint/eslintrc': 3.3.3 @@ -14698,7 +14658,7 @@ snapshots: '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.3 '@types/estree': 1.0.8 - ajv: 6.12.6 + ajv: 6.14.0 chalk: 4.1.2 cross-spawn: 7.0.6 debug: 4.4.3(supports-color@10.2.2) @@ -14717,7 +14677,7 @@ snapshots: is-glob: 4.0.3 json-stable-stringify-without-jsonify: 1.0.1 lodash.merge: 4.6.2 - minimatch: 3.1.2 + minimatch: 3.1.5 natural-compare: 1.4.0 optionator: 0.9.4 optionalDependencies: @@ -14727,8 +14687,8 @@ snapshots: espree@10.4.0: dependencies: - acorn: 8.15.0 - acorn-jsx: 5.3.2(acorn@8.15.0) + acorn: 8.16.0 + acorn-jsx: 5.3.2(acorn@8.16.0) eslint-visitor-keys: 4.2.1 esprima@4.0.1: {} @@ -14797,10 +14757,10 @@ snapshots: express-rate-limit@5.5.1: {} - express-rate-limit@8.2.1(express@5.2.1): + express-rate-limit@8.3.1(express@5.2.1): dependencies: express: 5.2.1 - ip-address: 10.0.1 + ip-address: 10.1.0 express@4.22.1: dependencies: @@ -14823,7 +14783,7 @@ snapshots: methods: 1.1.2 on-finished: 2.4.1 parseurl: 1.3.3 - path-to-regexp: 0.1.12 + path-to-regexp: 0.1.13 proxy-addr: 2.0.7 qs: 6.14.2 range-parser: 1.2.1 @@ -14927,9 +14887,9 @@ snapshots: dependencies: pend: 1.2.0 - fdir@6.5.0(picomatch@4.0.3): + fdir@6.5.0(picomatch@4.0.4): optionalDependencies: - picomatch: 4.0.3 + picomatch: 4.0.4 fetch-blob@3.2.0: dependencies: @@ -14940,10 +14900,6 @@ snapshots: dependencies: flat-cache: 4.0.1 - filelist@1.0.4: - dependencies: - minimatch: 5.1.6 - fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -15016,52 +14972,52 @@ snapshots: locate-path: 6.0.0 path-exists: 4.0.0 - firebase@12.8.0: + firebase@12.11.0: dependencies: - '@firebase/ai': 2.7.0(@firebase/app-types@0.9.3)(@firebase/app@0.14.7) - '@firebase/analytics': 0.10.19(@firebase/app@0.14.7) - '@firebase/analytics-compat': 0.2.25(@firebase/app-compat@0.5.7)(@firebase/app@0.14.7) - '@firebase/app': 0.14.7 - '@firebase/app-check': 0.11.0(@firebase/app@0.14.7) - '@firebase/app-check-compat': 0.4.0(@firebase/app-compat@0.5.7)(@firebase/app@0.14.7) - '@firebase/app-compat': 0.5.7 + '@firebase/ai': 2.10.0(@firebase/app-types@0.9.3)(@firebase/app@0.14.10) + '@firebase/analytics': 0.10.21(@firebase/app@0.14.10) + '@firebase/analytics-compat': 0.2.27(@firebase/app-compat@0.5.10)(@firebase/app@0.14.10) + '@firebase/app': 0.14.10 + '@firebase/app-check': 0.11.2(@firebase/app@0.14.10) + '@firebase/app-check-compat': 0.4.2(@firebase/app-compat@0.5.10)(@firebase/app@0.14.10) + '@firebase/app-compat': 0.5.10 '@firebase/app-types': 0.9.3 - '@firebase/auth': 1.12.0(@firebase/app@0.14.7) - '@firebase/auth-compat': 0.6.2(@firebase/app-compat@0.5.7)(@firebase/app-types@0.9.3)(@firebase/app@0.14.7) - '@firebase/data-connect': 0.3.12(@firebase/app@0.14.7) - '@firebase/database': 1.1.0 - '@firebase/database-compat': 2.1.0 - '@firebase/firestore': 4.10.0(@firebase/app@0.14.7) - '@firebase/firestore-compat': 0.4.4(@firebase/app-compat@0.5.7)(@firebase/app-types@0.9.3)(@firebase/app@0.14.7) - '@firebase/functions': 0.13.1(@firebase/app@0.14.7) - '@firebase/functions-compat': 0.4.1(@firebase/app-compat@0.5.7)(@firebase/app@0.14.7) - '@firebase/installations': 0.6.19(@firebase/app@0.14.7) - '@firebase/installations-compat': 0.2.19(@firebase/app-compat@0.5.7)(@firebase/app-types@0.9.3)(@firebase/app@0.14.7) - '@firebase/messaging': 0.12.23(@firebase/app@0.14.7) - '@firebase/messaging-compat': 0.2.23(@firebase/app-compat@0.5.7)(@firebase/app@0.14.7) - '@firebase/performance': 0.7.9(@firebase/app@0.14.7) - '@firebase/performance-compat': 0.2.22(@firebase/app-compat@0.5.7)(@firebase/app@0.14.7) - '@firebase/remote-config': 0.8.0(@firebase/app@0.14.7) - '@firebase/remote-config-compat': 0.2.21(@firebase/app-compat@0.5.7)(@firebase/app@0.14.7) - '@firebase/storage': 0.14.0(@firebase/app@0.14.7) - '@firebase/storage-compat': 0.4.0(@firebase/app-compat@0.5.7)(@firebase/app-types@0.9.3)(@firebase/app@0.14.7) - '@firebase/util': 1.13.0 + '@firebase/auth': 1.12.2(@firebase/app@0.14.10) + '@firebase/auth-compat': 0.6.4(@firebase/app-compat@0.5.10)(@firebase/app-types@0.9.3)(@firebase/app@0.14.10) + '@firebase/data-connect': 0.5.0(@firebase/app@0.14.10) + '@firebase/database': 1.1.2 + '@firebase/database-compat': 2.1.2 + '@firebase/firestore': 4.13.0(@firebase/app@0.14.10) + '@firebase/firestore-compat': 0.4.7(@firebase/app-compat@0.5.10)(@firebase/app-types@0.9.3)(@firebase/app@0.14.10) + '@firebase/functions': 0.13.3(@firebase/app@0.14.10) + '@firebase/functions-compat': 0.4.3(@firebase/app-compat@0.5.10)(@firebase/app@0.14.10) + '@firebase/installations': 0.6.21(@firebase/app@0.14.10) + '@firebase/installations-compat': 0.2.21(@firebase/app-compat@0.5.10)(@firebase/app-types@0.9.3)(@firebase/app@0.14.10) + '@firebase/messaging': 0.12.25(@firebase/app@0.14.10) + '@firebase/messaging-compat': 0.2.25(@firebase/app-compat@0.5.10)(@firebase/app@0.14.10) + '@firebase/performance': 0.7.11(@firebase/app@0.14.10) + '@firebase/performance-compat': 0.2.24(@firebase/app-compat@0.5.10)(@firebase/app@0.14.10) + '@firebase/remote-config': 0.8.2(@firebase/app@0.14.10) + '@firebase/remote-config-compat': 0.2.23(@firebase/app-compat@0.5.10)(@firebase/app@0.14.10) + '@firebase/storage': 0.14.2(@firebase/app@0.14.10) + '@firebase/storage-compat': 0.4.2(@firebase/app-compat@0.5.10)(@firebase/app-types@0.9.3)(@firebase/app@0.14.10) + '@firebase/util': 1.15.0 transitivePeerDependencies: - '@react-native-async-storage/async-storage' flat-cache@4.0.1: dependencies: - flatted: 3.3.3 + flatted: 3.4.2 keyv: 4.5.4 flat@5.0.2: {} - flatted@3.3.3: {} + flatted@3.4.2: {} - folder-hash@4.1.1(supports-color@10.2.2): + folder-hash@4.1.2(supports-color@10.2.2): dependencies: debug: 4.4.0(supports-color@10.2.2) - minimatch: 7.4.6 + minimatch: 7.4.9 transitivePeerDependencies: - supports-color @@ -15124,7 +15080,7 @@ snapshots: fs-minipass@3.0.3: dependencies: - minipass: 7.1.2 + minipass: 7.1.3 fs.realpath@1.0.0: {} @@ -15144,18 +15100,17 @@ snapshots: functions-have-names@1.2.3: {} - gaxios@7.1.3(supports-color@10.2.2): + gaxios@7.1.4(supports-color@10.2.2): dependencies: extend: 3.0.2 https-proxy-agent: 7.0.6(supports-color@10.2.2) node-fetch: 3.3.2 - rimraf: 5.0.10 transitivePeerDependencies: - supports-color gcp-metadata@8.1.2(supports-color@10.2.2): dependencies: - gaxios: 7.1.3(supports-color@10.2.2) + gaxios: 7.1.4(supports-color@10.2.2) google-logging-utils: 1.1.3 json-bigint: 1.0.0 transitivePeerDependencies: @@ -15167,7 +15122,7 @@ snapshots: get-caller-file@2.0.5: {} - get-east-asian-width@1.4.0: {} + get-east-asian-width@1.5.0: {} get-intrinsic@1.3.0: dependencies: @@ -15191,7 +15146,7 @@ snapshots: get-stream@5.2.0: dependencies: - pump: 3.0.3 + pump: 3.0.4 get-stream@6.0.1: {} @@ -15201,13 +15156,13 @@ snapshots: es-errors: 1.3.0 get-intrinsic: 1.3.0 - get-tsconfig@4.13.6: + get-tsconfig@4.13.7: dependencies: resolve-pkg-maps: 1.0.0 get-uri@6.0.5: dependencies: - basic-ftp: 5.1.0 + basic-ftp: 5.2.0 data-uri-to-buffer: 6.0.2 debug: 4.4.3(supports-color@10.2.2) transitivePeerDependencies: @@ -15217,14 +15172,6 @@ snapshots: dependencies: assert-plus: 1.0.0 - git-raw-commits@5.0.0(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.2.1): - dependencies: - '@conventional-changelog/git-client': 1.0.1(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.2.1) - meow: 13.2.0 - transitivePeerDependencies: - - conventional-commits-filter - - conventional-commits-parser - glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -15243,23 +15190,23 @@ snapshots: dependencies: foreground-child: 3.3.1 jackspeak: 3.4.3 - minimatch: 9.0.5 - minipass: 7.1.2 + minimatch: 9.0.9 + minipass: 7.1.3 package-json-from-dist: 1.0.1 path-scurry: 1.11.1 - glob@13.0.3: + glob@13.0.6: dependencies: - minimatch: 10.2.0 - minipass: 7.1.2 - path-scurry: 2.0.1 + minimatch: 10.2.4 + minipass: 7.1.3 + path-scurry: 2.0.2 glob@7.2.3: dependencies: fs.realpath: 1.0.0 inflight: 1.0.6 inherits: 2.0.4 - minimatch: 3.1.2 + minimatch: 3.1.5 once: 1.4.0 path-is-absolute: 1.0.1 @@ -15290,14 +15237,13 @@ snapshots: pify: 2.3.0 pinkie-promise: 2.0.1 - google-auth-library@10.5.0(supports-color@10.2.2): + google-auth-library@10.6.2(supports-color@10.2.2): dependencies: base64-js: 1.5.1 ecdsa-sig-formatter: 1.0.11 - gaxios: 7.1.3(supports-color@10.2.2) + gaxios: 7.1.4(supports-color@10.2.2) gcp-metadata: 8.1.2(supports-color@10.2.2) google-logging-utils: 1.1.3 - gtoken: 8.0.0(supports-color@10.2.2) jws: 4.0.1 transitivePeerDependencies: - supports-color @@ -15307,7 +15253,7 @@ snapshots: '@grpc/grpc-js': 1.14.3 '@grpc/proto-loader': 0.8.0 duplexify: 4.1.3 - google-auth-library: 10.5.0(supports-color@10.2.2) + google-auth-library: 10.6.2(supports-color@10.2.2) google-logging-utils: 1.1.3 node-fetch: 3.3.2 object-hash: 3.0.0 @@ -15339,25 +15285,18 @@ snapshots: graceful-fs@4.2.11: {} - graphql-tag@2.12.6(graphql@16.12.0): + graphql-tag@2.12.6(graphql@16.13.2): dependencies: - graphql: 16.12.0 + graphql: 16.13.2 tslib: 2.8.1 - graphql@16.12.0: {} + graphql@16.13.2: {} grpc-gcp@1.0.1(protobufjs@7.5.4): dependencies: '@grpc/grpc-js': 1.14.3 protobufjs: 7.5.4 - gtoken@8.0.0(supports-color@10.2.2): - dependencies: - gaxios: 7.1.3(supports-color@10.2.2) - jws: 4.0.1 - transitivePeerDependencies: - - supports-color - gunzip-maybe@1.4.2: dependencies: browserify-zlib: 0.1.4 @@ -15382,7 +15321,7 @@ snapshots: har-validator@5.1.5: dependencies: - ajv: 6.12.6 + ajv: 6.14.0 har-schema: 2.0.0 has-ansi@2.0.0: @@ -15411,11 +15350,11 @@ snapshots: dependencies: function-bind: 1.1.2 - hono@4.11.9: {} + hono@4.12.9: {} hosted-git-info@9.0.2: dependencies: - lru-cache: 11.2.6 + lru-cache: 11.2.7 hpack.js@2.1.6: dependencies: @@ -15426,7 +15365,7 @@ snapshots: html-encoding-sniffer@6.0.0: dependencies: - '@exodus/bytes': 1.14.1 + '@exodus/bytes': 1.15.0 transitivePeerDependencies: - '@noble/hashes' @@ -15483,15 +15422,7 @@ snapshots: http-parser-js@0.5.10: {} - http-proxy-agent@5.0.0(supports-color@10.2.2): - dependencies: - '@tootallnate/once': 2.0.0 - agent-base: 6.0.2(supports-color@10.2.2) - debug: 4.4.3(supports-color@10.2.2) - transitivePeerDependencies: - - supports-color - - http-proxy-agent@7.0.2: + http-proxy-agent@7.0.2(supports-color@10.2.2): dependencies: agent-base: 7.1.4 debug: 4.4.3(supports-color@10.2.2) @@ -15555,9 +15486,9 @@ snapshots: transitivePeerDependencies: - supports-color - https-proxy-agent@5.0.1(supports-color@10.2.2): + https-proxy-agent@5.0.1: dependencies: - agent-base: 6.0.2(supports-color@10.2.2) + agent-base: 6.0.2 debug: 4.4.3(supports-color@10.2.2) transitivePeerDependencies: - supports-color @@ -15597,7 +15528,7 @@ snapshots: ignore-walk@8.0.0: dependencies: - minimatch: 10.2.0 + minimatch: 10.2.4 ignore@5.3.2: {} @@ -15608,9 +15539,9 @@ snapshots: immediate@3.0.6: {} - immutable@3.8.2: {} + immutable@3.8.3: {} - immutable@5.1.4: {} + immutable@5.1.5: {} import-fresh@3.3.1: dependencies: @@ -15651,8 +15582,6 @@ snapshots: hasown: 2.0.2 side-channel: 1.1.0 - ip-address@10.0.1: {} - ip-address@10.1.0: {} ip-regex@4.3.0: {} @@ -15723,7 +15652,7 @@ snapshots: is-fullwidth-code-point@5.1.0: dependencies: - get-east-asian-width: 1.4.0 + get-east-asian-width: 1.5.0 is-generator-function@1.1.2: dependencies: @@ -15757,7 +15686,7 @@ snapshots: is-negative-zero@2.0.3: {} - is-network-error@1.3.0: {} + is-network-error@1.3.1: {} is-node-process@1.2.0: {} @@ -15873,8 +15802,6 @@ snapshots: isexe@2.0.0: {} - isexe@3.1.5: {} - isexe@4.0.0: {} isobject@3.0.1: {} @@ -15886,7 +15813,7 @@ snapshots: istanbul-lib-instrument@5.2.1: dependencies: '@babel/core': 7.29.0 - '@babel/parser': 7.29.0 + '@babel/parser': 7.29.2 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 6.3.1 @@ -15896,7 +15823,7 @@ snapshots: istanbul-lib-instrument@6.0.3: dependencies: '@babel/core': 7.29.0 - '@babel/parser': 7.29.0 + '@babel/parser': 7.29.2 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 7.7.4 @@ -15928,27 +15855,17 @@ snapshots: optionalDependencies: '@pkgjs/parseargs': 0.11.0 - jackspeak@4.2.3: - dependencies: - '@isaacs/cliui': 9.0.0 - - jake@10.9.4: - dependencies: - async: 3.2.6 - filelist: 1.0.4 - picocolors: 1.1.1 - jasmine-core@2.8.0: {} jasmine-core@4.6.1: {} jasmine-core@5.13.0: {} - jasmine-core@6.0.0: {} + jasmine-core@6.1.0: {} jasmine-reporters@2.5.2: dependencies: - '@xmldom/xmldom': 0.8.11 + '@xmldom/xmldom': 0.8.12 mkdirp: 1.0.4 jasmine-spec-reporter@7.0.0: @@ -15966,23 +15883,23 @@ snapshots: glob: 10.5.0 jasmine-core: 5.13.0 - jasmine@6.0.0: + jasmine@6.1.0: dependencies: '@jasminejs/reporters': 1.0.0 - glob: 13.0.3 - jasmine-core: 6.0.0 + glob: 13.0.6 + jasmine-core: 6.1.0 jasminewd2@2.2.0: {} jest-worker@27.5.1: dependencies: - '@types/node': 22.19.11 + '@types/node': 22.19.15 merge-stream: 2.0.0 supports-color: 8.1.1 jiti@2.6.1: {} - jose@6.1.3: {} + jose@6.2.2: {} js-base64@3.7.8: {} @@ -16001,23 +15918,23 @@ snapshots: '@acemir/cssom': 0.9.31 '@asamuzakjp/dom-selector': 6.8.1 '@bramus/specificity': 2.4.2 - '@exodus/bytes': 1.14.1 - cssstyle: 6.0.1 + '@exodus/bytes': 1.15.0 + cssstyle: 6.2.0 data-urls: 7.0.0 decimal.js: 10.6.0 html-encoding-sniffer: 6.0.0 - http-proxy-agent: 7.0.2 + http-proxy-agent: 7.0.2(supports-color@10.2.2) https-proxy-agent: 7.0.6(supports-color@10.2.2) is-potential-custom-element-name: 1.0.1 parse5: 8.0.0 saxes: 6.0.0 symbol-tree: 3.2.4 - tough-cookie: 6.0.0 - undici: 7.22.0 + tough-cookie: 6.0.1 + undici: 7.24.4 w3c-xmlserializer: 5.0.0 webidl-conversions: 8.0.1 whatwg-mimetype: 5.0.0 - whatwg-url: 16.0.0 + whatwg-url: 16.0.1 xml-name-validator: 5.0.0 transitivePeerDependencies: - '@noble/hashes' @@ -16047,6 +15964,8 @@ snapshots: json-stringify-safe@5.0.1: {} + json-with-bigint@3.5.8: {} + json5@1.0.2: dependencies: minimist: 1.2.8 @@ -16121,7 +16040,7 @@ snapshots: istanbul-lib-report: 3.0.1 istanbul-lib-source-maps: 4.0.1 istanbul-reports: 3.2.0 - minimatch: 3.1.2 + minimatch: 3.1.5 transitivePeerDependencies: - supports-color @@ -16156,7 +16075,7 @@ snapshots: lodash: 4.17.23 log4js: 6.9.1 mime: 2.6.0 - minimatch: 3.1.2 + minimatch: 3.1.5 mkdirp: 0.5.6 qjobs: 1.2.0 range-parser: 1.2.1 @@ -16208,7 +16127,7 @@ snapshots: transitivePeerDependencies: - supports-color - koa@2.16.3: + koa@2.16.4: dependencies: accepts: 1.3.8 cache-content-type: 1.0.1 @@ -16236,7 +16155,7 @@ snapshots: transitivePeerDependencies: - supports-color - launch-editor@2.12.0: + launch-editor@2.13.2: dependencies: picocolors: 1.1.1 shell-quote: 1.8.3 @@ -16258,7 +16177,7 @@ snapshots: image-size: 0.5.5 make-dir: 2.1.0 mime: 1.6.0 - needle: 3.3.1 + needle: 3.5.0 source-map: 0.6.1 levn@0.4.1: @@ -16289,7 +16208,7 @@ snapshots: listr2@9.0.5: dependencies: - cli-truncate: 5.1.1 + cli-truncate: 5.2.0 colorette: 2.0.20 eventemitter3: 5.0.4 log-update: 6.1.0 @@ -16299,7 +16218,7 @@ snapshots: lmdb@3.5.1: dependencies: '@harperfast/extended-iterable': 1.0.3 - msgpackr: 1.11.8 + msgpackr: 1.11.9 node-addon-api: 6.1.0 node-gyp-build-optional-packages: 5.2.2 ordered-binary: 1.6.1 @@ -16381,14 +16300,14 @@ snapshots: ansi-escapes: 7.3.0 cli-cursor: 5.0.0 slice-ansi: 7.1.2 - strip-ansi: 7.1.2 + strip-ansi: 7.2.0 wrap-ansi: 9.0.2 log4js@6.9.1: dependencies: date-format: 4.0.14 debug: 4.4.3(supports-color@10.2.2) - flatted: 3.3.3 + flatted: 3.4.2 rfdc: 1.4.1 streamroller: 3.1.5 transitivePeerDependencies: @@ -16408,7 +16327,7 @@ snapshots: lru-cache@10.4.3: {} - lru-cache@11.2.6: {} + lru-cache@11.2.7: {} lru-cache@5.1.1: dependencies: @@ -16424,7 +16343,7 @@ snapshots: magicast@0.5.2: dependencies: - '@babel/parser': 7.29.0 + '@babel/parser': 7.29.2 '@babel/types': 7.29.0 source-map-js: 1.2.1 @@ -16440,18 +16359,19 @@ snapshots: make-error@1.3.6: {} - make-fetch-happen@15.0.3: + make-fetch-happen@15.0.5: dependencies: + '@gar/promise-retry': 1.0.3 '@npmcli/agent': 4.0.0 - cacache: 20.0.3 + '@npmcli/redact': 4.0.0 + cacache: 20.0.4 http-cache-semantics: 4.2.0 - minipass: 7.1.2 - minipass-fetch: 5.0.1 - minipass-flush: 1.0.5 + minipass: 7.1.3 + minipass-fetch: 5.0.2 + minipass-flush: 1.0.7 minipass-pipeline: 1.2.4 negotiator: 1.0.0 proc-log: 6.1.0 - promise-retry: 2.0.1 ssri: 13.0.1 transitivePeerDependencies: - supports-color @@ -16460,26 +16380,26 @@ snapshots: math-intrinsics@1.1.0: {} - mdn-data@2.12.2: {} + mdn-data@2.27.1: {} media-typer@0.3.0: {} media-typer@1.1.0: {} - memfs@4.56.10(tslib@2.8.1): + memfs@4.57.1(tslib@2.8.1): dependencies: - '@jsonjoy.com/fs-core': 4.56.10(tslib@2.8.1) - '@jsonjoy.com/fs-fsa': 4.56.10(tslib@2.8.1) - '@jsonjoy.com/fs-node': 4.56.10(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.56.10(tslib@2.8.1) - '@jsonjoy.com/fs-node-to-fsa': 4.56.10(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.56.10(tslib@2.8.1) - '@jsonjoy.com/fs-print': 4.56.10(tslib@2.8.1) - '@jsonjoy.com/fs-snapshot': 4.56.10(tslib@2.8.1) + '@jsonjoy.com/fs-core': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-fsa': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-to-fsa': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-print': 4.57.1(tslib@2.8.1) + '@jsonjoy.com/fs-snapshot': 4.57.1(tslib@2.8.1) '@jsonjoy.com/json-pack': 1.21.0(tslib@2.8.1) '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) glob-to-regex.js: 1.2.0(tslib@2.8.1) - thingies: 2.5.0(tslib@2.8.1) + thingies: 2.6.0(tslib@2.8.1) tree-dump: 1.1.0(tslib@2.8.1) tslib: 2.8.1 @@ -16498,7 +16418,7 @@ snapshots: micromatch@4.0.8: dependencies: braces: 3.0.3 - picomatch: 2.3.1 + picomatch: 2.3.2 mime-db@1.52.0: {} @@ -16529,50 +16449,46 @@ snapshots: mini-css-extract-plugin@2.10.0(webpack@5.105.2(esbuild@0.27.3)): dependencies: schema-utils: 4.3.3 - tapable: 2.3.0 + tapable: 2.3.2 webpack: 5.105.2(esbuild@0.27.3) minimalistic-assert@1.0.1: {} - minimatch@10.1.1: - dependencies: - '@isaacs/brace-expansion': 5.0.1 - - minimatch@10.2.0: + minimatch@10.2.4: dependencies: - brace-expansion: 5.0.2 + brace-expansion: 5.0.5 - minimatch@3.1.2: + minimatch@3.1.5: dependencies: - brace-expansion: 1.1.12 + brace-expansion: 1.1.13 - minimatch@5.1.6: + minimatch@7.4.6: dependencies: - brace-expansion: 2.0.2 + brace-expansion: 2.0.3 - minimatch@7.4.6: + minimatch@7.4.9: dependencies: - brace-expansion: 2.0.2 + brace-expansion: 2.0.3 - minimatch@9.0.5: + minimatch@9.0.9: dependencies: - brace-expansion: 2.0.2 + brace-expansion: 2.0.3 minimist@1.2.8: {} minipass-collect@2.0.1: dependencies: - minipass: 7.1.2 + minipass: 7.1.3 - minipass-fetch@5.0.1: + minipass-fetch@5.0.2: dependencies: - minipass: 7.1.2 + minipass: 7.1.3 minipass-sized: 2.0.0 minizlib: 3.1.0 optionalDependencies: - encoding: 0.1.13 + iconv-lite: 0.7.2 - minipass-flush@1.0.5: + minipass-flush@1.0.7: dependencies: minipass: 3.3.6 @@ -16582,17 +16498,17 @@ snapshots: minipass-sized@2.0.0: dependencies: - minipass: 7.1.2 + minipass: 7.1.3 minipass@3.3.6: dependencies: yallist: 4.0.0 - minipass@7.1.2: {} + minipass@7.1.3: {} minizlib@3.1.0: dependencies: - minipass: 7.1.2 + minipass: 7.1.3 mitt@1.2.0: {} @@ -16626,7 +16542,7 @@ snapshots: '@msgpackr-extract/msgpackr-extract-win32-x64': 3.0.3 optional: true - msgpackr@1.11.8: + msgpackr@1.11.9: optionalDependencies: msgpackr-extract: 3.0.3 optional: true @@ -16636,11 +16552,11 @@ snapshots: dns-packet: 5.6.1 thunky: 1.1.0 - multimatch@7.0.0: + multimatch@8.0.0: dependencies: array-differ: 4.0.0 array-union: 3.0.1 - minimatch: 9.0.5 + minimatch: 10.2.4 mute-stream@2.0.0: {} @@ -16652,10 +16568,10 @@ snapshots: natural-compare@1.4.0: {} - needle@3.3.1: + needle@3.5.0: dependencies: iconv-lite: 0.6.3 - sax: 1.4.4 + sax: 1.6.0 optional: true negotiator@0.6.3: {} @@ -16668,12 +16584,41 @@ snapshots: netmask@2.0.2: {} - ng-packagr@21.2.0-next.0(@angular/compiler-cli@21.2.0-next.3(@angular/compiler@21.2.0-next.3)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3): + ng-packagr@21.2.2(@angular/compiler-cli@21.2.6(@angular/compiler@21.2.6)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3): + dependencies: + '@ampproject/remapping': 2.3.0 + '@angular/compiler-cli': 21.2.6(@angular/compiler@21.2.6)(typescript@5.9.3) + '@rollup/plugin-json': 6.1.0(rollup@4.57.1) + '@rollup/wasm-node': 4.59.0 + ajv: 8.18.0 + ansi-colors: 4.1.3 + browserslist: 4.28.1 + chokidar: 5.0.0 + commander: 14.0.3 + dependency-graph: 1.0.0 + esbuild: 0.27.3 + find-cache-directory: 6.0.0 + injection-js: 2.6.1 + jsonc-parser: 3.3.1 + less: 4.4.2 + ora: 9.3.0 + piscina: 5.1.4 + postcss: 8.5.6 + rollup-plugin-dts: 6.4.1(rollup@4.57.1)(typescript@5.9.3) + rxjs: 7.8.2 + sass: 1.97.3 + tinyglobby: 0.2.15 + tslib: 2.8.1 + typescript: 5.9.3 + optionalDependencies: + rollup: 4.57.1 + + ng-packagr@22.0.0-next.1(@angular/compiler-cli@21.2.6(@angular/compiler@21.2.6)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3): dependencies: '@ampproject/remapping': 2.3.0 - '@angular/compiler-cli': 21.2.0-next.3(@angular/compiler@21.2.0-next.3)(typescript@5.9.3) + '@angular/compiler-cli': 21.2.6(@angular/compiler@21.2.6)(typescript@5.9.3) '@rollup/plugin-json': 6.1.0(rollup@4.57.1) - '@rollup/wasm-node': 4.57.1 + '@rollup/wasm-node': 4.59.0 ajv: 8.18.0 ansi-colors: 4.1.3 browserslist: 4.28.1 @@ -16688,7 +16633,7 @@ snapshots: ora: 9.3.0 piscina: 5.1.4 postcss: 8.5.6 - rollup-plugin-dts: 6.3.0(rollup@4.57.1)(typescript@5.9.3) + rollup-plugin-dts: 6.4.1(rollup@4.57.1)(typescript@5.9.3) rxjs: 7.8.2 sass: 1.97.3 tinyglobby: 0.2.15 @@ -16697,9 +16642,9 @@ snapshots: optionalDependencies: rollup: 4.57.1 - nock@14.0.10: + nock@14.0.11: dependencies: - '@mswjs/interceptors': 0.39.8 + '@mswjs/interceptors': 0.41.3 json-stringify-safe: 5.0.1 propagate: 2.0.1 @@ -16743,17 +16688,17 @@ snapshots: env-paths: 2.2.1 exponential-backoff: 3.1.3 graceful-fs: 4.2.11 - make-fetch-happen: 15.0.3 + make-fetch-happen: 15.0.5 nopt: 9.0.0 proc-log: 6.1.0 semver: 7.7.4 - tar: 7.5.9 + tar: 7.5.13 tinyglobby: 0.2.15 which: 6.0.1 transitivePeerDependencies: - supports-color - node-releases@2.0.27: {} + node-releases@2.0.36: {} nopt@9.0.0: dependencies: @@ -16780,7 +16725,7 @@ snapshots: semver: 7.7.4 validate-npm-package-name: 7.0.2 - npm-packlist@10.0.3: + npm-packlist@10.0.4: dependencies: ignore-walk: 8.0.0 proc-log: 6.1.0 @@ -16796,9 +16741,9 @@ snapshots: dependencies: '@npmcli/redact': 4.0.0 jsonparse: 1.3.1 - make-fetch-happen: 15.0.3 - minipass: 7.1.2 - minipass-fetch: 5.0.1 + make-fetch-happen: 15.0.5 + minipass: 7.1.3 + minipass-fetch: 5.0.2 minizlib: 3.1.0 npm-package-arg: 13.0.2 proc-log: 6.1.0 @@ -16926,7 +16871,7 @@ snapshots: is-unicode-supported: 2.1.0 log-symbols: 7.0.1 stdin-discarder: 0.3.1 - string-width: 8.1.1 + string-width: 8.2.0 ordered-binary@1.6.1: optional: true @@ -16972,10 +16917,15 @@ snapshots: eventemitter3: 4.0.7 p-timeout: 3.2.0 + p-retry@4.6.2: + dependencies: + '@types/retry': 0.12.0 + retry: 0.13.1 + p-retry@6.2.1: dependencies: '@types/retry': 0.12.2 - is-network-error: 1.3.0 + is-network-error: 1.3.1 retry: 0.13.1 p-timeout@3.2.0: @@ -16990,7 +16940,7 @@ snapshots: agent-base: 7.1.4 debug: 4.4.3(supports-color@10.2.2) get-uri: 6.0.5 - http-proxy-agent: 7.0.2 + http-proxy-agent: 7.0.2(supports-color@10.2.2) https-proxy-agent: 7.0.6(supports-color@10.2.2) pac-resolver: 7.0.1 socks-proxy-agent: 8.0.5 @@ -17006,23 +16956,23 @@ snapshots: pacote@21.3.1: dependencies: - '@npmcli/git': 7.0.1 + '@npmcli/git': 7.0.2 '@npmcli/installed-package-contents': 4.0.0 - '@npmcli/package-json': 7.0.4 + '@npmcli/package-json': 7.0.5 '@npmcli/promise-spawn': 9.0.1 - '@npmcli/run-script': 10.0.3 - cacache: 20.0.3 + '@npmcli/run-script': 10.0.4 + cacache: 20.0.4 fs-minipass: 3.0.3 - minipass: 7.1.2 + minipass: 7.1.3 npm-package-arg: 13.0.2 - npm-packlist: 10.0.3 + npm-packlist: 10.0.4 npm-pick-manifest: 11.0.3 npm-registry-fetch: 19.1.1 proc-log: 6.1.0 promise-retry: 2.0.1 sigstore: 4.1.0 ssri: 13.0.1 - tar: 7.5.9 + tar: 7.5.13 transitivePeerDependencies: - supports-color @@ -17074,16 +17024,16 @@ snapshots: path-scurry@1.11.1: dependencies: lru-cache: 10.4.3 - minipass: 7.1.2 + minipass: 7.1.3 - path-scurry@2.0.1: + path-scurry@2.0.2: dependencies: - lru-cache: 11.2.6 - minipass: 7.1.2 + lru-cache: 11.2.7 + minipass: 7.1.3 - path-to-regexp@0.1.12: {} + path-to-regexp@0.1.13: {} - path-to-regexp@8.3.0: {} + path-to-regexp@8.4.0: {} path-type@4.0.0: {} @@ -17103,9 +17053,9 @@ snapshots: picocolors@1.1.1: {} - picomatch@2.3.1: {} + picomatch@2.3.2: {} - picomatch@4.0.3: {} + picomatch@4.0.4: {} pify@2.3.0: {} @@ -17155,7 +17105,7 @@ snapshots: dependencies: find-up-simple: 1.0.1 - pkijs@3.3.3: + pkijs@3.4.0: dependencies: '@noble/hashes': 1.4.0 asn1js: 3.0.7 @@ -17182,7 +17132,7 @@ snapshots: postcss-loader@8.2.0(postcss@8.5.6)(typescript@5.9.3)(webpack@5.105.2(esbuild@0.27.3)): dependencies: - cosmiconfig: 9.0.0(typescript@5.9.3) + cosmiconfig: 9.0.1(typescript@5.9.3) jiti: 2.6.1 postcss: 8.5.6 semver: 7.7.4 @@ -17272,7 +17222,7 @@ snapshots: '@protobufjs/path': 1.1.2 '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.0 - '@types/node': 22.19.11 + '@types/node': 22.19.15 long: 5.3.2 protractor@7.0.0: @@ -17304,7 +17254,7 @@ snapshots: dependencies: agent-base: 7.1.4 debug: 4.4.3(supports-color@10.2.2) - http-proxy-agent: 7.0.2 + http-proxy-agent: 7.0.2(supports-color@10.2.2) https-proxy-agent: 7.0.6(supports-color@10.2.2) lru-cache: 7.18.3 pac-proxy-agent: 7.2.0 @@ -17327,7 +17277,7 @@ snapshots: end-of-stream: 1.4.5 once: 1.4.0 - pump@3.0.3: + pump@3.0.4: dependencies: end-of-stream: 1.4.5 once: 1.4.0 @@ -17348,7 +17298,7 @@ snapshots: debug: 4.3.4 devtools-protocol: 0.0.1045489 extract-zip: 2.0.1 - https-proxy-agent: 5.0.1(supports-color@10.2.2) + https-proxy-agent: 5.0.1 proxy-from-env: 1.1.0 rimraf: 3.0.2 tar-fs: 2.1.1 @@ -17360,15 +17310,15 @@ snapshots: - supports-color - utf-8-validate - puppeteer-core@24.37.3(bufferutil@4.1.0): + puppeteer-core@24.40.0(bufferutil@4.1.0): dependencies: - '@puppeteer/browsers': 2.12.1 - chromium-bidi: 14.0.0(devtools-protocol@0.0.1566079) + '@puppeteer/browsers': 2.13.0 + chromium-bidi: 14.0.0(devtools-protocol@0.0.1581282) debug: 4.4.3(supports-color@10.2.2) - devtools-protocol: 0.0.1566079 - typed-query-selector: 2.12.0 + devtools-protocol: 0.0.1581282 + typed-query-selector: 2.12.1 webdriver-bidi-protocol: 0.4.1 - ws: 8.19.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + ws: 8.20.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - bare-abort-controller - bare-buffer @@ -17379,7 +17329,7 @@ snapshots: puppeteer@18.2.1(bufferutil@4.1.0)(encoding@0.1.13): dependencies: - https-proxy-agent: 5.0.1(supports-color@10.2.2) + https-proxy-agent: 5.0.1 progress: 2.0.3 proxy-from-env: 1.1.0 puppeteer-core: 18.2.1(bufferutil@4.1.0)(encoding@0.1.13) @@ -17399,10 +17349,6 @@ snapshots: qjobs@1.2.0: {} - qs@6.14.0: - dependencies: - side-channel: 1.1.0 - qs@6.14.2: dependencies: side-channel: 1.1.0 @@ -17434,14 +17380,10 @@ snapshots: unicode-properties: 1.4.1 urijs: 1.19.11 wordwrap: 1.0.0 - yaml: 2.8.2 + yaml: 2.8.3 transitivePeerDependencies: - encoding - randombytes@2.1.0: - dependencies: - safe-buffer: 5.2.1 - range-parser@1.2.1: {} raw-body@2.5.3: @@ -17492,7 +17434,7 @@ snapshots: readdirp@3.6.0: dependencies: - picomatch: 2.3.1 + picomatch: 2.3.2 readdirp@4.1.2: {} @@ -17604,7 +17546,7 @@ snapshots: resp-modifier@6.0.2: dependencies: debug: 2.6.9 - minimatch: 3.1.2 + minimatch: 3.1.5 transitivePeerDependencies: - supports-color @@ -17625,7 +17567,7 @@ snapshots: retry-request@8.0.2(supports-color@10.2.2): dependencies: extend: 3.0.2 - teeny-request: 10.1.0(supports-color@10.2.2) + teeny-request: 10.1.2(supports-color@10.2.2) transitivePeerDependencies: - supports-color @@ -17667,6 +17609,9 @@ snapshots: '@rolldown/binding-wasm32-wasi': 1.0.0-rc.4 '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.4 '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.4 + transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' rollup-license-plugin@3.1.0: dependencies: @@ -17683,12 +17628,23 @@ snapshots: optionalDependencies: '@babel/code-frame': 7.29.0 - rollup-plugin-sourcemaps2@0.5.4(@types/node@22.19.11)(rollup@4.57.1): + rollup-plugin-dts@6.4.1(rollup@4.57.1)(typescript@5.9.3): + dependencies: + '@jridgewell/remapping': 2.3.5 + '@jridgewell/sourcemap-codec': 1.5.5 + convert-source-map: 2.0.0 + magic-string: 0.30.21 + rollup: 4.57.1 + typescript: 5.9.3 + optionalDependencies: + '@babel/code-frame': 7.29.0 + + rollup-plugin-sourcemaps2@0.5.4(@types/node@22.19.15)(rollup@4.57.1): dependencies: '@rollup/pluginutils': 5.2.0(rollup@4.57.1) rollup: 4.57.1 optionalDependencies: - '@types/node': 22.19.11 + '@types/node': 22.19.15 rollup@4.57.1: dependencies: @@ -17727,7 +17683,7 @@ snapshots: depd: 2.0.0 is-promise: 4.0.0 parseurl: 1.3.3 - path-to-regexp: 8.3.0 + path-to-regexp: 8.4.0 transitivePeerDependencies: - supports-color @@ -17780,7 +17736,7 @@ snapshots: sass@1.97.3: dependencies: chokidar: 4.0.3 - immutable: 5.1.4 + immutable: 5.1.5 source-map-js: 1.2.1 optionalDependencies: '@parcel/watcher': 2.5.6 @@ -17791,7 +17747,7 @@ snapshots: transitivePeerDependencies: - supports-color - sax@1.4.4: {} + sax@1.6.0: {} saxes@6.0.0: dependencies: @@ -17816,7 +17772,7 @@ snapshots: selfsigned@5.5.0: dependencies: '@peculiar/x509': 1.14.3 - pkijs: 3.3.3 + pkijs: 3.4.0 semver@5.7.2: {} @@ -17862,9 +17818,7 @@ snapshots: transitivePeerDependencies: - supports-color - serialize-javascript@6.0.2: - dependencies: - randombytes: 2.1.0 + serialize-javascript@7.0.5: {} serve-index@1.9.2: dependencies: @@ -17977,10 +17931,10 @@ snapshots: sigstore@4.1.0: dependencies: '@sigstore/bundle': 4.0.0 - '@sigstore/core': 3.1.0 + '@sigstore/core': 3.2.0 '@sigstore/protobuf-specs': 0.5.0 - '@sigstore/sign': 4.1.0 - '@sigstore/tuf': 4.0.1 + '@sigstore/sign': 4.1.1 + '@sigstore/tuf': 4.0.2 '@sigstore/verify': 3.1.0 transitivePeerDependencies: - supports-color @@ -17998,6 +17952,11 @@ snapshots: ansi-styles: 6.2.3 is-fullwidth-code-point: 5.1.0 + slice-ansi@8.0.0: + dependencies: + ansi-styles: 6.2.3 + is-fullwidth-code-point: 5.1.0 + smart-buffer@4.2.0: {} socket.io-adapter@2.5.6(bufferutil@4.1.0)(utf-8-validate@6.0.6): @@ -18014,13 +17973,13 @@ snapshots: '@socket.io/component-emitter': 3.1.2 debug: 4.4.3(supports-color@10.2.2) engine.io-client: 6.6.4(bufferutil@4.1.0)(utf-8-validate@6.0.6) - socket.io-parser: 4.2.5 + socket.io-parser: 4.2.6 transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate - socket.io-parser@4.2.5: + socket.io-parser@4.2.6: dependencies: '@socket.io/component-emitter': 3.1.2 debug: 4.4.3(supports-color@10.2.2) @@ -18033,9 +17992,9 @@ snapshots: base64id: 2.0.0 cors: 2.8.6 debug: 4.4.3(supports-color@10.2.2) - engine.io: 6.6.5(bufferutil@4.1.0)(utf-8-validate@6.0.6) + engine.io: 6.6.6(bufferutil@4.1.0)(utf-8-validate@6.0.6) socket.io-adapter: 2.5.6(bufferutil@4.1.0)(utf-8-validate@6.0.6) - socket.io-parser: 4.2.5 + socket.io-parser: 4.2.6 transitivePeerDependencies: - bufferutil - supports-color @@ -18091,23 +18050,23 @@ snapshots: source-map@0.7.6: {} - spdx-correct@3.2.0: - dependencies: - spdx-expression-parse: 3.0.1 - spdx-license-ids: 3.0.22 - spdx-exceptions@2.5.0: {} spdx-expression-parse@3.0.1: dependencies: spdx-exceptions: 2.5.0 - spdx-license-ids: 3.0.22 + spdx-license-ids: 3.0.23 + + spdx-expression-parse@4.0.0: + dependencies: + spdx-exceptions: 2.5.0 + spdx-license-ids: 3.0.23 spdx-expression-validate@2.0.0: dependencies: spdx-expression-parse: 3.0.1 - spdx-license-ids@3.0.22: {} + spdx-license-ids@3.0.23: {} spdy-transport@3.0.0: dependencies: @@ -18155,11 +18114,11 @@ snapshots: ssri@10.0.5: dependencies: - minipass: 7.1.2 + minipass: 7.1.3 ssri@13.0.1: dependencies: - minipass: 7.1.2 + minipass: 7.1.3 stack-trace@0.0.10: {} @@ -18205,11 +18164,11 @@ snapshots: transitivePeerDependencies: - supports-color - streamx@2.23.0: + streamx@2.25.0: dependencies: events-universal: 1.0.1 fast-fifo: 1.3.2 - text-decoder: 1.2.6 + text-decoder: 1.2.7 transitivePeerDependencies: - bare-abort-controller - react-native-b4a @@ -18226,18 +18185,18 @@ snapshots: dependencies: eastasianwidth: 0.2.0 emoji-regex: 9.2.2 - strip-ansi: 7.1.2 + strip-ansi: 7.2.0 string-width@7.2.0: dependencies: emoji-regex: 10.6.0 - get-east-asian-width: 1.4.0 - strip-ansi: 7.1.2 + get-east-asian-width: 1.5.0 + strip-ansi: 7.2.0 - string-width@8.1.1: + string-width@8.2.0: dependencies: - get-east-asian-width: 1.4.0 - strip-ansi: 7.1.2 + get-east-asian-width: 1.5.0 + strip-ansi: 7.2.0 string.prototype.trim@1.2.10: dependencies: @@ -18278,7 +18237,7 @@ snapshots: dependencies: ansi-regex: 5.0.1 - strip-ansi@7.1.2: + strip-ansi@7.2.0: dependencies: ansi-regex: 6.2.2 @@ -18308,24 +18267,24 @@ snapshots: table-layout@4.1.1: dependencies: - array-back: 6.2.2 + array-back: 6.2.3 wordwrapjs: 5.1.1 - tapable@2.3.0: {} + tapable@2.3.2: {} tar-fs@2.1.1: dependencies: chownr: 1.1.4 mkdirp-classic: 0.5.3 - pump: 3.0.3 + pump: 3.0.4 tar-stream: 2.2.0 - tar-fs@3.1.1: + tar-fs@3.1.2: dependencies: - pump: 3.0.3 + pump: 3.0.4 tar-stream: 3.1.7 optionalDependencies: - bare-fs: 4.5.4 + bare-fs: 4.5.6 bare-path: 3.0.0 transitivePeerDependencies: - bare-abort-controller @@ -18342,36 +18301,43 @@ snapshots: tar-stream@3.1.7: dependencies: - b4a: 1.7.4 + b4a: 1.8.0 fast-fifo: 1.3.2 - streamx: 2.23.0 + streamx: 2.25.0 transitivePeerDependencies: - bare-abort-controller - react-native-b4a - tar@7.5.9: + tar@7.5.13: dependencies: '@isaacs/fs-minipass': 4.0.1 chownr: 3.0.0 - minipass: 7.1.2 + minipass: 7.1.3 minizlib: 3.1.0 yallist: 5.0.0 - teeny-request@10.1.0(supports-color@10.2.2): + teeny-request@10.1.2(supports-color@10.2.2): dependencies: - http-proxy-agent: 5.0.0(supports-color@10.2.2) - https-proxy-agent: 5.0.1(supports-color@10.2.2) + http-proxy-agent: 7.0.2(supports-color@10.2.2) + https-proxy-agent: 7.0.6(supports-color@10.2.2) node-fetch: 3.3.2 stream-events: 1.0.5 transitivePeerDependencies: - supports-color - terser-webpack-plugin@5.3.16(esbuild@0.27.3)(webpack@5.105.2(esbuild@0.27.3)): + teex@1.0.1: + dependencies: + streamx: 2.25.0 + transitivePeerDependencies: + - bare-abort-controller + - react-native-b4a + optional: true + + terser-webpack-plugin@5.4.0(esbuild@0.27.3)(webpack@5.105.2(esbuild@0.27.3)): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 schema-utils: 4.3.3 - serialize-javascript: 6.0.2 terser: 5.46.0 webpack: 5.105.2(esbuild@0.27.3) optionalDependencies: @@ -18380,17 +18346,17 @@ snapshots: terser@5.46.0: dependencies: '@jridgewell/source-map': 0.3.11 - acorn: 8.15.0 + acorn: 8.16.0 commander: 2.20.3 source-map-support: 0.5.21 - text-decoder@1.2.6: + text-decoder@1.2.7: dependencies: - b4a: 1.7.4 + b4a: 1.8.0 transitivePeerDependencies: - react-native-b4a - thingies@2.5.0(tslib@2.8.1): + thingies@2.6.0(tslib@2.8.1): dependencies: tslib: 2.8.1 @@ -18415,26 +18381,26 @@ snapshots: tinybench@2.9.0: {} - tinyexec@1.0.2: {} + tinyexec@1.0.4: {} tinyglobby@0.2.15: dependencies: - fdir: 6.5.0(picomatch@4.0.3) - picomatch: 4.0.3 + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 - tinyrainbow@3.0.3: {} + tinyrainbow@3.1.0: {} tldts-core@6.1.86: {} - tldts-core@7.0.23: {} + tldts-core@7.0.27: {} tldts@6.1.86: dependencies: tldts-core: 6.1.86 - tldts@7.0.23: + tldts@7.0.27: dependencies: - tldts-core: 7.0.23 + tldts-core: 7.0.27 tmp@0.0.30: dependencies: @@ -18459,9 +18425,9 @@ snapshots: dependencies: tldts: 6.1.86 - tough-cookie@6.0.0: + tough-cookie@6.0.1: dependencies: - tldts: 7.0.23 + tldts: 7.0.27 tr46@0.0.3: {} @@ -18479,20 +18445,20 @@ snapshots: tree-kill@1.2.2: {} - ts-api-utils@2.4.0(typescript@5.9.3): + ts-api-utils@2.5.0(typescript@5.9.3): dependencies: typescript: 5.9.3 - ts-node@10.9.2(@types/node@22.19.11)(typescript@5.9.3): + ts-node@10.9.2(@types/node@22.19.15)(typescript@5.9.3): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.12 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 22.19.11 - acorn: 8.15.0 - acorn-walk: 8.3.4 + '@types/node': 22.19.15 + acorn: 8.16.0 + acorn-walk: 8.3.5 arg: 4.1.3 create-require: 1.1.1 diff: 4.0.4 @@ -18517,7 +18483,7 @@ snapshots: tsx@4.21.0: dependencies: esbuild: 0.27.3 - get-tsconfig: 4.13.6 + get-tsconfig: 4.13.7 optionalDependencies: fsevents: 2.3.3 @@ -18529,7 +18495,7 @@ snapshots: dependencies: '@tufjs/models': 4.1.0 debug: 4.4.3(supports-color@10.2.2) - make-fetch-happen: 15.0.3 + make-fetch-happen: 15.0.5 transitivePeerDependencies: - supports-color @@ -18597,7 +18563,7 @@ snapshots: typed-graphqlify@3.1.6: {} - typed-query-selector@2.12.0: {} + typed-query-selector@2.12.1: {} typescript@5.9.3: {} @@ -18624,11 +18590,11 @@ snapshots: buffer: 5.7.1 through: 2.3.8 - undici-types@7.22.0: {} + undici-types@7.24.6: {} - undici@6.23.0: {} + undici@6.24.1: {} - undici@7.22.0: {} + undici@7.24.4: {} unenv@1.10.0: dependencies: @@ -18659,14 +18625,6 @@ snapshots: pako: 0.2.9 tiny-inflate: 1.0.3 - unique-filename@5.0.0: - dependencies: - unique-slug: 6.0.0 - - unique-slug@6.0.0: - dependencies: - imurmurhash: 0.1.4 - universal-github-app-jwt@2.2.2: {} universal-user-agent@7.0.3: {} @@ -18709,11 +18667,6 @@ snapshots: '@types/istanbul-lib-coverage': 2.0.6 convert-source-map: 2.0.0 - validate-npm-package-license@3.0.4: - dependencies: - spdx-correct: 3.2.0 - spdx-expression-parse: 3.0.1 - validate-npm-package-name@7.0.2: {} validator@13.15.26: {} @@ -18725,7 +18678,7 @@ snapshots: '@verdaccio/config': 8.0.0-next-8.29 '@verdaccio/core': 8.0.0-next-8.29 express: 4.22.1 - https-proxy-agent: 5.0.1(supports-color@10.2.2) + https-proxy-agent: 5.0.1 node-fetch: 2.6.7(encoding@0.1.13) transitivePeerDependencies: - encoding @@ -18750,9 +18703,9 @@ snapshots: transitivePeerDependencies: - supports-color - verdaccio@6.2.5(encoding@0.1.13): + verdaccio@6.2.9(encoding@0.1.13): dependencies: - '@cypress/request': 3.0.9 + '@cypress/request': 3.0.10 '@verdaccio/auth': 8.0.0-next-8.29 '@verdaccio/config': 8.0.0-next-8.29 '@verdaccio/core': 8.0.0-next-8.29 @@ -18772,14 +18725,14 @@ snapshots: async: 3.2.6 clipanion: 4.0.0-rc.4 compression: 1.8.1 - cors: 2.8.5 + cors: 2.8.6 debug: 4.4.3(supports-color@10.2.2) envinfo: 7.15.0 express: 4.22.1 - lodash: 4.17.21 + lodash: 4.17.23 lru-cache: 7.18.3 mime: 3.0.0 - semver: 7.7.3 + semver: 7.7.4 verdaccio-audit: 13.0.0-next-8.29(encoding@0.1.13) verdaccio-htpasswd: 13.0.0-next-8.29 transitivePeerDependencies: @@ -18794,28 +18747,28 @@ snapshots: core-util-is: 1.0.2 extsprintf: 1.3.0 - vite@7.3.1(@types/node@24.10.9)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): + vite@7.3.1(@types/node@24.12.0)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.3): dependencies: esbuild: 0.27.3 - fdir: 6.5.0(picomatch@4.0.3) - picomatch: 4.0.3 + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 postcss: 8.5.6 rollup: 4.57.1 tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 24.10.9 + '@types/node': 24.12.0 fsevents: 2.3.3 jiti: 2.6.1 less: 4.4.2 sass: 1.97.3 terser: 5.46.0 tsx: 4.21.0 - yaml: 2.8.2 + yaml: 2.8.3 - vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@24.10.9)(jiti@2.6.1)(jsdom@28.1.0)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): + vitest@4.0.18(@opentelemetry/api@1.9.1)(@types/node@24.12.0)(jiti@2.6.1)(jsdom@28.1.0)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.3): dependencies: '@vitest/expect': 4.0.18 - '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@24.10.9)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@24.12.0)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.3)) '@vitest/pretty-format': 4.0.18 '@vitest/runner': 4.0.18 '@vitest/snapshot': 4.0.18 @@ -18826,17 +18779,17 @@ snapshots: magic-string: 0.30.21 obug: 2.1.1 pathe: 2.0.3 - picomatch: 4.0.3 + picomatch: 4.0.4 std-env: 3.10.0 tinybench: 2.9.0 - tinyexec: 1.0.2 + tinyexec: 1.0.4 tinyglobby: 0.2.15 - tinyrainbow: 3.0.3 - vite: 7.3.1(@types/node@24.10.9)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + tinyrainbow: 3.1.0 + vite: 7.3.1(@types/node@24.12.0)(jiti@2.6.1)(less@4.4.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.3) why-is-node-running: 2.3.0 optionalDependencies: - '@opentelemetry/api': 1.9.0 - '@types/node': 24.10.9 + '@opentelemetry/api': 1.9.1 + '@types/node': 24.12.0 jsdom: 28.1.0 transitivePeerDependencies: - jiti @@ -18903,7 +18856,7 @@ snapshots: webpack-dev-middleware@7.4.5(tslib@2.8.1)(webpack@5.105.2(esbuild@0.27.3)): dependencies: colorette: 2.0.20 - memfs: 4.56.10(tslib@2.8.1) + memfs: 4.57.1(tslib@2.8.1) mime-types: 3.0.2 on-finished: 2.4.1 range-parser: 1.2.1 @@ -18933,7 +18886,7 @@ snapshots: graceful-fs: 4.2.11 http-proxy-middleware: 2.0.9(@types/express@4.17.25) ipaddr.js: 2.3.0 - launch-editor: 2.12.0 + launch-editor: 2.13.2 open: 10.2.0 p-retry: 6.2.1 schema-utils: 4.3.3 @@ -18942,7 +18895,7 @@ snapshots: sockjs: 0.3.24 spdy: 4.0.2 webpack-dev-middleware: 7.4.5(tslib@2.8.1)(webpack@5.105.2(esbuild@0.27.3)) - ws: 8.19.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + ws: 8.20.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) optionalDependencies: webpack: 5.105.2(esbuild@0.27.3) transitivePeerDependencies: @@ -18973,11 +18926,11 @@ snapshots: '@webassemblyjs/ast': 1.14.1 '@webassemblyjs/wasm-edit': 1.14.1 '@webassemblyjs/wasm-parser': 1.14.1 - acorn: 8.15.0 - acorn-import-phases: 1.0.4(acorn@8.15.0) + acorn: 8.16.0 + acorn-import-phases: 1.0.4(acorn@8.16.0) browserslist: 4.28.1 chrome-trace-event: 1.0.4 - enhanced-resolve: 5.19.0 + enhanced-resolve: 5.20.1 es-module-lexer: 2.0.0 eslint-scope: 5.1.1 events: 3.3.0 @@ -18988,8 +18941,8 @@ snapshots: mime-types: 2.1.35 neo-async: 2.6.2 schema-utils: 4.3.3 - tapable: 2.3.0 - terser-webpack-plugin: 5.3.16(esbuild@0.27.3)(webpack@5.105.2(esbuild@0.27.3)) + tapable: 2.3.2 + terser-webpack-plugin: 5.4.0(esbuild@0.27.3)(webpack@5.105.2(esbuild@0.27.3)) watchpack: 2.5.1 webpack-sources: 3.3.4 transitivePeerDependencies: @@ -19012,9 +18965,9 @@ snapshots: tr46: 5.1.1 webidl-conversions: 7.0.0 - whatwg-url@16.0.0: + whatwg-url@16.0.1: dependencies: - '@exodus/bytes': 1.14.1 + '@exodus/bytes': 1.15.0 tr46: 6.0.0 webidl-conversions: 8.0.1 transitivePeerDependencies: @@ -19076,10 +19029,6 @@ snapshots: dependencies: isexe: 2.0.0 - which@6.0.0: - dependencies: - isexe: 3.1.5 - which@6.0.1: dependencies: isexe: 4.0.0 @@ -19113,13 +19062,13 @@ snapshots: dependencies: ansi-styles: 6.2.3 string-width: 5.1.2 - strip-ansi: 7.1.2 + strip-ansi: 7.2.0 wrap-ansi@9.0.2: dependencies: ansi-styles: 6.2.3 string-width: 7.2.0 - strip-ansi: 7.1.2 + strip-ansi: 7.2.0 wrappy@1.0.2: {} @@ -19132,7 +19081,7 @@ snapshots: bufferutil: 4.1.0 utf-8-validate: 6.0.6 - ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): + ws@8.20.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): optionalDependencies: bufferutil: 4.1.0 utf-8-validate: 6.0.6 @@ -19156,7 +19105,7 @@ snapshots: xml2js@0.4.23: dependencies: - sax: 1.4.4 + sax: 1.6.0 xmlbuilder: 11.0.1 xmlbuilder@11.0.1: {} @@ -19177,7 +19126,7 @@ snapshots: yallist@5.0.0: {} - yaml@2.8.2: {} + yaml@2.8.3: {} yargs-parser@18.1.3: dependencies: @@ -19248,7 +19197,7 @@ snapshots: yoctocolors@2.1.2: {} - zod-to-json-schema@3.25.1(zod@4.3.6): + zod-to-json-schema@3.25.2(zod@4.3.6): dependencies: zod: 4.3.6 @@ -19256,4 +19205,4 @@ snapshots: zod@4.3.6: {} - zone.js@0.16.0: {} + zone.js@0.16.1: {} diff --git a/renovate.json b/renovate.json index 293a1aa46277..eb69b002b7a7 100644 --- a/renovate.json +++ b/renovate.json @@ -2,7 +2,6 @@ "$schema": "https://docs.renovatebot.com/renovate-schema.json", "baseBranchPatterns": ["main", "21.1.x"], "extends": ["github>angular/dev-infra//renovate-presets/default.json5"], - "ignoreDeps": ["less"], "ignorePaths": ["tests/e2e/assets/**", "tests/schematics/update/packages/**"], "packageRules": [ { diff --git a/scripts/devkit-admin.mts b/scripts/devkit-admin.mts index 0a17df9f45a1..7d8522547100 100644 --- a/scripts/devkit-admin.mts +++ b/scripts/devkit-admin.mts @@ -33,12 +33,16 @@ process.chdir(path.join(scriptDir, '..')); const originalConsole = { ...console }; console.warn = function (...args) { - const [m, ...rest] = args; - originalConsole.warn(styleText(['yellow'], m), ...rest); + if (typeof args[0] === 'string') { + args[0] = styleText(['yellow'], args[0]); + } + originalConsole.warn(...args); }; console.error = function (...args) { - const [m, ...rest] = args; - originalConsole.error(styleText(['red'], m), ...rest); + if (typeof args[0] === 'string') { + args[0] = styleText(['red'], args[0]); + } + originalConsole.error(...args); }; try { @@ -47,6 +51,6 @@ try { process.exitCode = typeof exitCode === 'number' ? exitCode : 0; // eslint-disable-next-line @typescript-eslint/no-explicit-any } catch (err: any) { - console.error(err.stack); + console.error(err.stack ?? err); process.exitCode = 99; } diff --git a/scripts/packages.mts b/scripts/packages.mts index fb556da7dc7a..f76f789fd40b 100644 --- a/scripts/packages.mts +++ b/scripts/packages.mts @@ -13,6 +13,10 @@ import { dirname } from 'node:path'; export interface PackageInfo { name: string; root: string; + deprecated?: { + version: string; + message: string; + }; experimental: boolean; packageJson: Record; } @@ -31,6 +35,7 @@ function getPackages(): PackageInfo[] { packages.push({ name: packageJson.name, experimental: !!packageJson.experimental, + deprecated: monorepoData.packages[packageJson.name].deprecated, root: dirname(pkg), packageJson, }); diff --git a/tests/BUILD.bazel b/tests/BUILD.bazel index 318bf3b965e4..651eccb6dc43 100644 --- a/tests/BUILD.bazel +++ b/tests/BUILD.bazel @@ -1,6 +1,6 @@ -load("@aspect_bazel_lib//lib:directory_path.bzl", "directory_path") +load("@bazel_lib//lib:directory_path.bzl", "directory_path") +load("@npm//:@rollup/wasm-node/package_json.bzl", rollup = "bin") load("@npm//:defs.bzl", "npm_link_all_packages") -load("@npm//:rollup/package_json.bzl", rollup = "bin") load("//tools:defaults.bzl", "ts_project") load(":e2e.bzl", "e2e_suites") @@ -19,8 +19,6 @@ ts_project( deps = [ "//:node_modules/@types/node", "//:node_modules/fast-glob", - "//packages/angular_devkit/core", - "//packages/angular_devkit/core/node", "//tests/e2e/utils", ], ) @@ -31,7 +29,6 @@ rollup.rollup( srcs = [ "rollup.config.mjs", ":runner", - "//:node_modules/@rollup/plugin-alias", "//:node_modules/@rollup/plugin-commonjs", "//:node_modules/@rollup/plugin-json", "//:node_modules/@rollup/plugin-node-resolve", diff --git a/tests/e2e/assets/ssr-project-webpack/package.json b/tests/e2e/assets/ssr-project-webpack/package.json index 9d6b1f7338e8..0482ad3897b0 100644 --- a/tests/e2e/assets/ssr-project-webpack/package.json +++ b/tests/e2e/assets/ssr-project-webpack/package.json @@ -14,14 +14,14 @@ }, "private": true, "dependencies": { - "@angular/animations": "^21.0.0-next.0", - "@angular/common": "^21.0.0-next.0", - "@angular/compiler": "^21.0.0-next.0", - "@angular/core": "^21.0.0-next.0", - "@angular/forms": "^21.0.0-next.0", - "@angular/platform-browser": "^21.0.0-next.0", - "@angular/platform-server": "^21.0.0-next.0", - "@angular/router": "^21.0.0-next.0", + "@angular/animations": "^21.0.0", + "@angular/common": "^21.0.0", + "@angular/compiler": "^21.0.0", + "@angular/core": "^21.0.0", + "@angular/forms": "^21.0.0", + "@angular/platform-browser": "^21.0.0", + "@angular/platform-server": "^21.0.0", + "@angular/router": "^21.0.0", "@angular/ssr": "^21.0.0-next.0", "express": "^4.18.2", "rxjs": "~7.8.0", diff --git a/tests/e2e/tests/build/server-rendering/express-engine-csp-nonce.ts b/tests/e2e/tests/build/server-rendering/express-engine-csp-nonce.ts index 3d6335b48465..409b141bb48a 100644 --- a/tests/e2e/tests/build/server-rendering/express-engine-csp-nonce.ts +++ b/tests/e2e/tests/build/server-rendering/express-engine-csp-nonce.ts @@ -61,6 +61,7 @@ export default async function () { { ...process.env, 'PORT': String(port), + 'NG_ALLOWED_HOSTS': 'localhost', }, ); diff --git a/tests/e2e/tests/build/server-rendering/express-engine-ngmodule.ts b/tests/e2e/tests/build/server-rendering/express-engine-ngmodule.ts index 92e34f7ca3e8..5eaaa9b0e58b 100644 --- a/tests/e2e/tests/build/server-rendering/express-engine-ngmodule.ts +++ b/tests/e2e/tests/build/server-rendering/express-engine-ngmodule.ts @@ -83,6 +83,7 @@ export default async function () { { ...process.env, 'PORT': String(port), + 'NG_ALLOWED_HOSTS': 'localhost', }, ); diff --git a/tests/e2e/tests/build/server-rendering/express-engine-standalone.ts b/tests/e2e/tests/build/server-rendering/express-engine-standalone.ts index 18920e3a5893..4c8d29d9b770 100644 --- a/tests/e2e/tests/build/server-rendering/express-engine-standalone.ts +++ b/tests/e2e/tests/build/server-rendering/express-engine-standalone.ts @@ -50,6 +50,7 @@ export default async function () { { ...process.env, 'PORT': String(port), + 'NG_ALLOWED_HOSTS': 'localhost', }, ); diff --git a/tests/e2e/tests/build/server-rendering/server-routes-output-mode-server-i18n-base-href.ts b/tests/e2e/tests/build/server-rendering/server-routes-output-mode-server-i18n-base-href.ts index 6d0a45459a16..aa6f7e3426ee 100644 --- a/tests/e2e/tests/build/server-rendering/server-routes-output-mode-server-i18n-base-href.ts +++ b/tests/e2e/tests/build/server-rendering/server-routes-output-mode-server-i18n-base-href.ts @@ -111,6 +111,7 @@ async function spawnServer(): Promise { { ...process.env, 'PORT': String(port), + 'NG_ALLOWED_HOSTS': 'localhost', }, ); diff --git a/tests/e2e/tests/build/server-rendering/server-routes-output-mode-server-i18n-sub-path.ts b/tests/e2e/tests/build/server-rendering/server-routes-output-mode-server-i18n-sub-path.ts index 79fc755c4477..7bc323311b4f 100644 --- a/tests/e2e/tests/build/server-rendering/server-routes-output-mode-server-i18n-sub-path.ts +++ b/tests/e2e/tests/build/server-rendering/server-routes-output-mode-server-i18n-sub-path.ts @@ -146,6 +146,7 @@ async function spawnServer(): Promise { { ...process.env, 'PORT': String(port), + 'NG_ALLOWED_HOSTS': 'localhost', }, ); diff --git a/tests/e2e/tests/build/server-rendering/server-routes-output-mode-server-i18n.ts b/tests/e2e/tests/build/server-rendering/server-routes-output-mode-server-i18n.ts index 994d77343d1e..efbff9871bbc 100644 --- a/tests/e2e/tests/build/server-rendering/server-routes-output-mode-server-i18n.ts +++ b/tests/e2e/tests/build/server-rendering/server-routes-output-mode-server-i18n.ts @@ -122,6 +122,7 @@ async function spawnServer(): Promise { { ...process.env, 'PORT': String(port), + 'NG_ALLOWED_HOSTS': 'localhost', }, ); diff --git a/tests/e2e/tests/build/server-rendering/server-routes-output-mode-server-platform-neutral.ts b/tests/e2e/tests/build/server-rendering/server-routes-output-mode-server-platform-neutral.ts index 130ade10ba9f..6fdd1998cdd2 100644 --- a/tests/e2e/tests/build/server-rendering/server-routes-output-mode-server-platform-neutral.ts +++ b/tests/e2e/tests/build/server-rendering/server-routes-output-mode-server-platform-neutral.ts @@ -11,7 +11,6 @@ import { import { updateJsonFile, useSha } from '../../../utils/project'; import { getGlobalVariable } from '../../../utils/env'; import { findFreePort } from '../../../utils/network'; -import { readFile } from 'node:fs/promises'; export default async function () { assert( @@ -98,6 +97,8 @@ export default async function () { const options = buildTarget['options']; options['ssr']['experimentalPlatform'] = 'neutral'; options['outputMode'] = 'server'; + options['security'] ??= {}; + options['security']['allowedHosts'] = ['localhost']; }); await noSilentNg('build'); diff --git a/tests/e2e/tests/build/server-rendering/server-routes-output-mode-server.ts b/tests/e2e/tests/build/server-rendering/server-routes-output-mode-server.ts index 5205d20eeb0a..ff72cb8e8df2 100644 --- a/tests/e2e/tests/build/server-rendering/server-routes-output-mode-server.ts +++ b/tests/e2e/tests/build/server-rendering/server-routes-output-mode-server.ts @@ -206,6 +206,7 @@ async function spawnServer(): Promise { { ...process.env, 'PORT': String(port), + 'NG_ALLOWED_HOSTS': 'localhost', }, ); diff --git a/tests/e2e/tests/build/server-rendering/server-routes-output-mode-static-i18n-http-calls.ts b/tests/e2e/tests/build/server-rendering/server-routes-output-mode-static-i18n-http-calls.ts new file mode 100644 index 000000000000..964c7827c23e --- /dev/null +++ b/tests/e2e/tests/build/server-rendering/server-routes-output-mode-static-i18n-http-calls.ts @@ -0,0 +1,137 @@ +import assert, { match } from 'node:assert'; +import { join } from 'node:path'; +import { readFile, writeMultipleFiles } from '../../../utils/fs'; +import { ng, noSilentNg, silentNg } from '../../../utils/process'; +import { getGlobalVariable } from '../../../utils/env'; +import { installWorkspacePackages, uninstallPackage } from '../../../utils/packages'; +import { useSha } from '../../../utils/project'; +import { langTranslations, setupI18nConfig } from '../../i18n/setup'; + +export default async function () { + assert( + getGlobalVariable('argv')['esbuild'], + 'This test should not be called in the Webpack suite.', + ); + + // Setup project + await setupI18nConfig(); + + // Forcibly remove in case another test doesn't clean itself up. + await uninstallPackage('@angular/ssr'); + await ng('add', '@angular/ssr', '--skip-confirmation', '--skip-install'); + await useSha(); + await installWorkspacePackages(); + + await writeMultipleFiles({ + // Add asset + 'public/media.json': JSON.stringify({ dataFromAssets: true }), + // Update component to do an HTTP call to asset and API. + 'src/app/app.ts': ` + import { ChangeDetectorRef, Component, inject } from '@angular/core'; + import { JsonPipe } from '@angular/common'; + import { RouterOutlet } from '@angular/router'; + import { HttpClient } from '@angular/common/http'; + + @Component({ + selector: 'app-root', + imports: [JsonPipe, RouterOutlet], + template: \` +

{{ assetsData | json }}

+

{{ apiData | json }}

+ + \`, + }) + export class App { + assetsData: any; + apiData: any; + private readonly cdr: ChangeDetectorRef = inject(ChangeDetectorRef); + + constructor() { + const http = inject(HttpClient); + + http.get('media.json').toPromise().then((d) => { + this.assetsData = d; + this.cdr.markForCheck(); + }); + + http.get('/api').toPromise().then((d) => { + this.apiData = d; + this.cdr.markForCheck(); + }); + } + } + `, + // Add http client and route + 'src/app/app.config.ts': ` + import { ApplicationConfig } from '@angular/core'; + import { provideRouter } from '@angular/router'; + + import { Home } from './home/home'; + import { provideClientHydration } from '@angular/platform-browser'; + import { provideHttpClient, withFetch } from '@angular/common/http'; + + export const appConfig: ApplicationConfig = { + providers: [ + provideRouter([{ + path: 'home', + component: Home, + }]), + provideClientHydration(), + provideHttpClient(withFetch()), + ], + }; + `, + 'src/server.ts': ` + import { AngularNodeAppEngine, writeResponseToNodeResponse, isMainModule, createNodeRequestHandler } from '@angular/ssr/node'; + import express from 'express'; + import { join } from 'node:path'; + + export function app(): express.Express { + const server = express(); + const browserDistFolder = join(import.meta.dirname, '../browser'); + const angularNodeAppEngine = new AngularNodeAppEngine(); + + server.get('/api', (req, res) => { + res.json({ dataFromAPI: true }) + }); + + server.use(express.static(browserDistFolder, { + maxAge: '1y', + index: 'index.html' + })); + + server.use((req, res, next) => { + angularNodeAppEngine.handle(req) + .then((response) => response ? writeResponseToNodeResponse(response, res) : next()) + .catch(next); + }); + return server; + } + + const server = app(); + + if (isMainModule(import.meta.url)) { + const port = process.env['PORT'] || 4000; + server.listen(port, (error) => { + if (error) { + throw error; + } + console.log(\`Node Express server listening on http://localhost:\${port}\`); + }); + } + + export const reqHandler = createNodeRequestHandler(server); + `, + }); + + await silentNg('generate', 'component', 'home'); + + await noSilentNg('build', '--output-mode=static'); + + for (const { lang, outputPath } of langTranslations) { + const contents = await readFile(join(outputPath, 'home/index.html')); + match(contents, /

{[\S\s]*"dataFromAssets":[\s\S]*true[\S\s]*}<\/p>/); + match(contents, /

{[\S\s]*"dataFromAPI":[\s\S]*true[\S\s]*}<\/p>/); + match(contents, new RegExp(``)); + } +} diff --git a/tests/e2e/tests/build/server-rendering/server-routes-preload-links.ts b/tests/e2e/tests/build/server-rendering/server-routes-preload-links.ts index f1437392492d..fe316e3cd157 100644 --- a/tests/e2e/tests/build/server-rendering/server-routes-preload-links.ts +++ b/tests/e2e/tests/build/server-rendering/server-routes-preload-links.ts @@ -196,6 +196,7 @@ async function spawnServer(): Promise { { ...process.env, 'PORT': String(port), + 'NG_ALLOWED_HOSTS': 'localhost', }, ); diff --git a/tests/e2e/tests/commands/add/add-material.ts b/tests/e2e/tests/commands/add/add-material.ts index 238e5d94dddb..a7453f035a6f 100644 --- a/tests/e2e/tests/commands/add/add-material.ts +++ b/tests/e2e/tests/commands/add/add-material.ts @@ -1,9 +1,10 @@ import { assertIsError } from '../../../utils/utils'; -import { expectFileToMatch, rimraf } from '../../../utils/fs'; +import { readFile, rimraf } from '../../../utils/fs'; import { getActivePackageManager, uninstallPackage } from '../../../utils/packages'; import { ng } from '../../../utils/process'; import { isPrereleaseCli } from '../../../utils/project'; import { appendFile } from 'node:fs/promises'; +import assert from 'node:assert'; export default async function () { // forcibly remove in case another test doesn't clean itself up @@ -32,7 +33,12 @@ export default async function () { '--verbose', '--skip-confirmation', ); - await expectFileToMatch('package.json', /@angular\/material/); + + const { dependencies } = JSON.parse(await readFile('package.json')); + assert.ok( + dependencies['@angular/material'], + '`@angular/material` was not found added to dependencies', + ); // Clean up existing cdk package // Not doing so can cause adding material to fail if an incompatible cdk is present diff --git a/tests/e2e/tests/mcp/projects-sourceroot-resolution.ts b/tests/e2e/tests/mcp/projects-sourceroot-resolution.ts new file mode 100644 index 000000000000..01ebb8c1ca05 --- /dev/null +++ b/tests/e2e/tests/mcp/projects-sourceroot-resolution.ts @@ -0,0 +1,47 @@ +import { exec, ProcessOutput, silentNpm } from '../../utils/process'; +import { updateJsonFile } from '../../utils/project'; +import assert from 'node:assert/strict'; + +const MCP_INSPECTOR_PACKAGE_NAME = '@modelcontextprotocol/inspector-cli'; +const MCP_INSPECTOR_PACKAGE_VERSION = '0.16.2'; +const MCP_INSPECTOR_COMMAND_NAME = 'mcp-inspector-cli'; + +async function runInspector(...args: string[]): Promise { + return exec(MCP_INSPECTOR_COMMAND_NAME, '--cli', 'npx', '--no', '@angular/cli', 'mcp', ...args); +} + +export default async function () { + await silentNpm( + 'install', + '--ignore-scripts', + '-g', + `${MCP_INSPECTOR_PACKAGE_NAME}@${MCP_INSPECTOR_PACKAGE_VERSION}`, + ); + + try { + // 1. Add a sample project with a non-root path to angular.json + await updateJsonFile('angular.json', (workspaceJson) => { + workspaceJson.projects ??= {}; + workspaceJson.projects['sample-lib'] = { + root: 'projects/sample-lib', + sourceRoot: 'projects/sample-lib/src', + projectType: 'library', + }; + }); + + // 2. Call list_projects + const { stdout } = await runInspector('--method', 'tools/call', '--tool-name', 'list_projects'); + + // 3. Verify output + assert.match(stdout, /"name": "sample-lib"/); + // Assert that sourceRoot is NOT duplicated + assert.match(stdout, /"sourceRoot": "projects\/sample-lib\/src"/); + assert.doesNotMatch(stdout, /"sourceRoot": "projects\/sample-lib\/projects\/sample-lib\/src"/); + } finally { + // 4. Cleanup angular.json + await updateJsonFile('angular.json', (workspaceJson) => { + delete workspaceJson.projects['sample-lib']; + }); + await silentNpm('uninstall', '-g', MCP_INSPECTOR_PACKAGE_NAME); + } +} diff --git a/tests/e2e/tests/vitest/library.ts b/tests/e2e/tests/vitest/library.ts index ba1e31dc38f8..0bb989057279 100644 --- a/tests/e2e/tests/vitest/library.ts +++ b/tests/e2e/tests/vitest/library.ts @@ -1,12 +1,9 @@ import assert from 'node:assert/strict'; import { updateJsonFile } from '../../utils/project'; -import { ng, silentNpm } from '../../utils/process'; -import { createDir, writeFile } from '../../utils/fs'; +import { ng } from '../../utils/process'; +import { appendToFile, createDir, writeFile } from '../../utils/fs'; export default async function (): Promise { - // Install Vitest deps - await silentNpm('install', 'vitest@^4.0.8', 'jsdom@^27.1.0', '--save-dev'); - // Generate a library await ng('generate', 'library', 'my-lib', '--test-runner', 'vitest'); @@ -25,17 +22,10 @@ export default async function (): Promise { // 3. Update the component to use SCSS and import the shared file // Rename CSS to SCSS - await ng( - 'generate', - 'component', - 'styled-comp', - '--project=my-lib', - '--style=scss', - '--skip-import', - ); + await ng('generate', 'component', 'styled-comp', '--project=my-lib', '--style=scss'); - await writeFile( - 'projects/my-lib/src/lib/styled-comp/styled-comp.component.scss', + await appendToFile( + 'projects/my-lib/src/lib/styled-comp/styled-comp.scss', ` @use 'vars'; p { color: vars.$primary-color; } diff --git a/tests/e2e_runner.ts b/tests/e2e_runner.ts index c7a672161b7a..f77d6e367e9b 100644 --- a/tests/e2e_runner.ts +++ b/tests/e2e_runner.ts @@ -1,5 +1,4 @@ import { parseArgs, styleText } from 'node:util'; -import { createConsoleLogger } from '../packages/angular_devkit/core/node'; import glob from 'fast-glob'; import * as path from 'node:path'; import * as fs from 'node:fs'; @@ -110,19 +109,6 @@ if (process.env.CHROME_BIN) { process.env.PATH = process.env.PATH! + delimiter + dirname(process.env.CHROME_BIN!); } -const logger = createConsoleLogger(argv.verbose, process.stdout, process.stderr, { - info: (s) => s, - debug: (s) => s, - warn: (s) => styleText(['bold', 'yellow'], s), - error: (s) => styleText(['bold', 'red'], s), - fatal: (s) => styleText(['bold', 'red'], s), -}); - -const logStack = [logger]; -function lastLogger() { - return logStack.at(-1)!; -} - // Under bazel the compiled file (.js) and types (.d.ts) are available. const SRC_FILE_EXT_RE = /\.js$/; const testGlob = (process.env.TESTBRIDGE_TEST_ONLY ?? argv.glob).replace(/\.ts$/, '.js'); @@ -303,8 +289,7 @@ async function runSteps( printHeader(name, stepIndex, steps.length, type); - // Run the test function with the current file on the logStack. - logStack.push(lastLogger().createChild(absoluteName)); + // Run the test function with the current file. try { await run(absoluteName); } catch (e) { @@ -312,8 +297,6 @@ async function runSteps( console.error(styleText(['red'], `${capsType} "${name}" failed...`)); throw e; - } finally { - logStack.pop(); } console.log('----'); diff --git a/tools/bazel/npm_package.bzl b/tools/bazel/npm_package.bzl index c6ce650d3971..3e2843f37946 100644 --- a/tools/bazel/npm_package.bzl +++ b/tools/bazel/npm_package.bzl @@ -1,8 +1,8 @@ -load("@aspect_bazel_lib//lib:copy_to_bin.bzl", "copy_to_bin") -load("@aspect_bazel_lib//lib:expand_template.bzl", "expand_template") -load("@aspect_bazel_lib//lib:jq.bzl", "jq") -load("@aspect_bazel_lib//lib:utils.bzl", "to_label") load("@aspect_rules_js//npm:defs.bzl", _npm_package = "npm_package") +load("@bazel_lib//lib:copy_to_bin.bzl", "copy_to_bin") +load("@bazel_lib//lib:expand_template.bzl", "expand_template") +load("@bazel_lib//lib:utils.bzl", "to_label") +load("@jq.bzl//jq:jq.bzl", "jq") load("@rules_pkg//:pkg.bzl", "pkg_tar") load("//tools:link_package_json_to_tarballs.bzl", "link_package_json_to_tarballs") load("//tools:snapshot_repo_filter.bzl", "SNAPSHOT_REPO_JQ_FILTER") diff --git a/tools/defaults.bzl b/tools/defaults.bzl index d301591a32ba..3fbde2dcfc52 100644 --- a/tools/defaults.bzl +++ b/tools/defaults.bzl @@ -1,6 +1,6 @@ -load("@aspect_bazel_lib//lib:copy_to_bin.bzl", _copy_to_bin = "copy_to_bin") load("@aspect_rules_jasmine//jasmine:defs.bzl", _jasmine_test = "jasmine_test") load("@aspect_rules_js//js:defs.bzl", _js_binary = "js_binary") +load("@bazel_lib//lib:copy_to_bin.bzl", _copy_to_bin = "copy_to_bin") load("@devinfra//bazel/ts_project:index.bzl", "strict_deps_test") load("@rules_angular//src/ng_examples_db:index.bzl", _ng_examples_db = "ng_examples_db") load("@rules_angular//src/ng_package:index.bzl", _ng_package = "ng_package") diff --git a/tools/link_package_json_to_tarballs.bzl b/tools/link_package_json_to_tarballs.bzl index b01d64669834..4a31cd194bf7 100644 --- a/tools/link_package_json_to_tarballs.bzl +++ b/tools/link_package_json_to_tarballs.bzl @@ -2,8 +2,8 @@ # # Use of this source code is governed by an MIT-style license that can be # found in the LICENSE file at https://angular.dev/license -load("@aspect_bazel_lib//lib:jq.bzl", "jq") -load("@aspect_bazel_lib//lib:utils.bzl", "to_label") +load("@bazel_lib//lib:utils.bzl", "to_label") +load("@jq.bzl//jq:jq.bzl", "jq") def link_package_json_to_tarballs(name, src, pkg_deps, out): """Substitute tar paths into a package.json file for the packages it depends on. diff --git a/tools/test/BUILD.bazel b/tools/test/BUILD.bazel index 5d210ff7ac50..71ef3e3c2794 100644 --- a/tools/test/BUILD.bazel +++ b/tools/test/BUILD.bazel @@ -1,5 +1,5 @@ -load("@aspect_bazel_lib//lib:jq.bzl", "jq") load("@bazel_skylib//rules:diff_test.bzl", "diff_test") +load("@jq.bzl//jq:jq.bzl", "jq") jq( name = "final_package_json", diff --git a/tools/toolchains/BUILD.bazel b/tools/toolchains/BUILD.bazel index 5895884b09be..09bb94865046 100644 --- a/tools/toolchains/BUILD.bazel +++ b/tools/toolchains/BUILD.bazel @@ -1,18 +1,6 @@ load("@rules_cc//cc:defs.bzl", "cc_toolchain") load(":dummy_cc_toolchain.bzl", "dummy_cc_toolchain_config") -# This is needed following https://github.com/bazel-contrib/rules_nodejs/pull/3859 -toolchain( - name = "node24_windows_no_exec_toolchain", - exec_compatible_with = [], - target_compatible_with = [ - "@platforms//os:windows", - "@platforms//cpu:x86_64", - ], - toolchain = "@node24_windows_amd64//:toolchain", - toolchain_type = "@rules_nodejs//nodejs:toolchain_type", -) - # This defines a dummy C++ toolchain for Windows. # Without this, the build fails with "Unable to find a CC toolchain using toolchain resolution". dummy_cc_toolchain_config(name = "dummy_cc_toolchain_config")