diff --git a/.bazelversion b/.bazelversion index 3b6825376add..11f1d47dac93 100644 --- a/.bazelversion +++ b/.bazelversion @@ -1 +1 @@ -8.8.0 +8.8.2 diff --git a/.github/workflows/assistant-to-the-branch-manager.yml b/.github/workflows/assistant-to-the-branch-manager.yml index 30585fa707fd..36436071bbcc 100644 --- a/.github/workflows/assistant-to-the-branch-manager.yml +++ b/.github/workflows/assistant-to-the-branch-manager.yml @@ -18,6 +18,6 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: angular/dev-infra/github-actions/branch-manager@183403ae13b785698eaf13c819dda55b9fed430b # main + - uses: angular/dev-infra/github-actions/branch-manager@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5fad471f1244..7ac65142b622 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@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/setup@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main - 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@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/setup@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main 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@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/setup@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main 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@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/setup@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main 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@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/setup@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -115,9 +115,10 @@ jobs: --config=e2e \ //tests:e2e.webpack_node24 \ //tests:e2e.esbuild_node24 \ - --platforms=tools:windows_x64 + --platforms=tools:windows_x64 \ + --enable_runfiles - name: Store built Windows E2E tests - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: win-e2e-build-artifacts path: | @@ -137,11 +138,11 @@ jobs: runs-on: windows-2025 steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Download built Windows E2E tests - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: win-e2e-build-artifacts path: dist/bin/tests/ @@ -164,13 +165,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/setup@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -188,13 +189,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/setup@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -208,13 +209,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@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/setup@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Start Sauce Connect @@ -245,11 +246,11 @@ jobs: CIRCLE_BRANCH: ${{ github.ref_name }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/setup@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main - run: pnpm admin snapshots --verbose env: SNAPSHOT_BUILDS_GITHUB_TOKEN: ${{ secrets.SNAPSHOT_BUILDS_GITHUB_TOKEN }} diff --git a/.github/workflows/dev-infra.yml b/.github/workflows/dev-infra.yml index bb05d9b3dbfe..75b906a9026e 100644 --- a/.github/workflows/dev-infra.yml +++ b/.github/workflows/dev-infra.yml @@ -16,21 +16,21 @@ jobs: if: github.event_name == 'pull_request_target' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/labeling/pull-request@183403ae13b785698eaf13c819dda55b9fed430b # main + - uses: angular/dev-infra/github-actions/labeling/pull-request@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main 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: angular/dev-infra/github-actions/post-approval-changes@183403ae13b785698eaf13c819dda55b9fed430b # main + - uses: angular/dev-infra/github-actions/post-approval-changes@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main 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@183403ae13b785698eaf13c819dda55b9fed430b # main + - uses: angular/dev-infra/github-actions/labeling/issue@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} google-generative-ai-key: ${{ secrets.GOOGLE_GENERATIVE_AI_KEY }} diff --git a/.github/workflows/perf.yml b/.github/workflows/perf.yml index 504f7e5136ad..ffb6f73455f0 100644 --- a/.github/workflows/perf.yml +++ b/.github/workflows/perf.yml @@ -22,7 +22,7 @@ jobs: workflows: ${{ steps.workflows.outputs.workflows }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main - name: Install node modules run: pnpm install --frozen-lockfile - id: workflows @@ -40,9 +40,9 @@ jobs: workflow: ${{ fromJSON(needs.list.outputs.workflows) }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/setup@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main - 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 8b2baafbd3b4..c82c6b72046f 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -34,9 +34,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/setup@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main - name: Setup ESLint Caching uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: @@ -66,23 +66,23 @@ 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@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/linting/licenses@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main build: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/setup@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Build release targets run: pnpm ng-dev release build - name: Store PR release packages - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: packages path: dist/releases/*.tgz @@ -93,11 +93,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/setup@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main - 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@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/setup@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main - 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@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/setup@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Build E2E tests for Windows on Linux @@ -140,9 +140,10 @@ jobs: pnpm bazel build \ --config=e2e \ //tests:e2e.esbuild_node24 \ - --platforms=tools:windows_x64 + --platforms=tools:windows_x64 \ + --enable_runfiles - name: Store built Windows E2E tests - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: win-e2e-build-artifacts path: | @@ -156,11 +157,11 @@ jobs: runs-on: windows-2025 steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Download built Windows E2E tests - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: name: win-e2e-build-artifacts path: dist/bin/tests/ @@ -183,13 +184,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/setup@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main - 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 +206,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/setup@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@9163c7b18bed28802e04d9c6f9da14e09ee7b79a # main - 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/.nvmrc b/.nvmrc index df6ae3370f9f..b74495a07da3 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -24.21.0 +24.22.2 diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 000000000000..7ed3ec6a1316 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,77 @@ +--- +trigger: always_on +--- + +This is the source code for the Angular CLI and related build tooling. This guide outlines standard practices for AI agents working in this repository. + +## Environment + +- Use `pnpm` for package management. +- Use `pnpm bazel test //target` to run tests. + +## Key Documentation + +- [Developer Guide](docs/DEVELOPER.md): definitive guide for building, debugging, and running test targets. +- [Contributing Guide](CONTRIBUTING.md): general contribution workflows and guidelines. +- [Commit Guidelines](CONTRIBUTING.md#commit): format for commit messages and PR titles. + +## Building + +- Make a local build of all packages: + ```shell + pnpm build --local + ``` + +## Coding Practices + +- **Imports:** + - Always use the `node:` protocol for Node.js built-in imports (e.g., `node:fs`, `node:path`, `node:assert`). + - Prefer named imports (e.g., `import { mkdtemp } from 'node:fs'`) or default imports (`import fs from 'node:fs'`) instead of namespace imports (`import * as fs`). + - Use type-only imports (`import type { ... }`) when importing types to avoid runtime side-effects. +- **Classes:** + - Prefer ECMAScript private fields (`#field`) over TypeScript `private` keywords for encapsulated state. + +## Testing + +- **Temporary Directories (`TEST_TMPDIR`):** + - Tests in this repository only run in Bazel. **ALWAYS** use `process.env['TEST_TMPDIR']` and assert that it is set: + ```ts + import assert from 'node:assert'; + import { mkdtemp } from 'node:fs/promises'; + import { join } from 'node:path'; + + describe('...', () => { + let tempRoot: string; + + beforeAll(async () => { + const baseTmpDir = process.env['TEST_TMPDIR']; + assert(baseTmpDir, 'TEST_TMPDIR is not set'); + tempRoot = await mkdtemp(join(baseTmpDir, 'angular-cli-test-')); + }); + }); + ``` + - **NEVER** use or fallback to `os.tmpdir()`. Bazel executes tests in hermetic sandboxes and sets `TEST_TMPDIR` to an isolated, sandboxed directory. Using `os.tmpdir()` can cause sandboxing failures, permission errors, or file leakage outside the Bazel sandbox. +- **Unit & Integration Tests:** + - Run all unit and integration tests: `pnpm bazel test //packages/...` + - Run a specific unit test target (e.g., `pnpm bazel test //packages/angular/build:test`). Note that package `:test` targets may exclude builder integration tests (such as specs under `**/builders/**/tests/**`). + - Run a specific builder integration test target (e.g., `pnpm bazel test //packages/angular/build:library_integration_tests` or `pnpm bazel test //packages/angular/build:application_integration_tests`). + - Query all test targets: `pnpm bazel query "tests(//packages/...)"` + - Find the exact test target for a specific spec file (using its workspace-relative path, which Bazel resolves as a source file target): `pnpm bazel query "kind(jasmine_test, rdeps(//packages/..., ))"` + - Focus specific tests when debugging: use `fdescribe()` and `fit()`. NEVER commit focused tests to the repository. + - Run tests without sharding when isolating or debugging: use `--config=no-sharding` with a specific test target (e.g., `pnpm bazel test //packages/angular/build:library_integration_tests --config=no-sharding`). + This disables test sharding (`--test_sharding_strategy=disabled`) and flaky test retries (`--flaky_test_attempts=1`). + This is especially useful when isolating test runs or debugging with focused tests (`fit`/`fdescribe`) to avoid empty shard failures and unnecessary re-runs. + Do not use this flag when running broad test suites (such as `//packages/...`), as executing tests without sharding takes significantly longer. +- **End-to-End Tests:** + - Run subset of E2E tests: `pnpm bazel test //tests:e2e_node22 --config=e2e --test_filter=""` + +## Pull Requests + +- Use the `gh` CLI (GitHub CLI) for creating and managing pull requests. +- **Fixup Commits:** + - When addressing review feedback, **ALWAYS** use fixup commits (`git commit --fixup `) instead of amending existing commits. This preserves commit history during review and allows reviewers to easily see incremental changes. + - Only use fixup commits for changes that directly belong to the target commit. Unrelated changes must be made in a separate commit with their own commit message, not as a fixup commit. + - Fixup commits are automatically squashed when merging with `pnpm ng-dev pr merge` or optionally when rebasing with `pnpm ng-dev pr rebase `. +- Use `pnpm ng-dev pr` commands: + - `pnpm ng-dev pr rebase `: Rebase a PR branch on its target branch and optionally squash fixup commits. + - `pnpm ng-dev pr merge `: Merge an approved PR into its targeted branches. diff --git a/CHANGELOG.md b/CHANGELOG.md index f7ae51f6dbe9..769da8da5394 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,245 @@ - + -# 22.2.0-next.7 (2026-09-10) +# 22.2.5 (2026-10-28) + +### @angular/cli + +| Commit | Type | Description | +| ---------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------- | +| [7efeeb9caa](https://github.com/angular/angular-cli/commit/7efeeb9caa2def8023097d8faab405a5e536cd18) | fix | explain how to pick a project when a schematic cannot determine one | +| [ee61e328ac](https://github.com/angular/angular-cli/commit/ee61e328ac8839709ccbcc20d3ecade35e8c05f9) | fix | handle bun registry error output and 404 detection | +| [0d8898c289](https://github.com/angular/angular-cli/commit/0d8898c289cc2e92a539ad5b5bc053890bd76b3d) | fix | support resolving subproject dependencies in bun workspaces | + +### @schematics/angular + +| Commit | Type | Description | +| ---------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------------- | +| [982c3dcbfc](https://github.com/angular/angular-cli/commit/982c3dcbfc248a379d0d5e5549682927bc27a719) | fix | avoid adding web worker snippet to server configuration files | +| [18e5dc6fe8](https://github.com/angular/angular-cli/commit/18e5dc6fe8f4cf54fe2aceed4c430a94ad1737db) | fix | ignore non-workspace stylesheet entries when adding Tailwind | +| [dd18bda9db](https://github.com/angular/angular-cli/commit/dd18bda9dbe267dd79ddc1f7ca435222a17733d1) | fix | include the SSR entry file in the trust-proxy-headers migration | +| [b7e24561e7](https://github.com/angular/angular-cli/commit/b7e24561e71f71a82c82f76267a5f42327d42004) | fix | include the type separator in the class spec import | +| [7f3840c70c](https://github.com/angular/angular-cli/commit/7f3840c70c11c2cbfdb23b6cfa1c65f1cd819785) | fix | keep the default getter access type of spyOnProperty in refactor-jasmine-vitest | +| [eaf2343be4](https://github.com/angular/angular-cli/commit/eaf2343be4c19a84e7525a052de6650115a11a45) | fix | migrate CallInfo returnValue and object in refactor-jasmine-vitest | +| [6680d289cb](https://github.com/angular/angular-cli/commit/6680d289cb88eee720980ce979b384a71f08216a) | fix | migrate spy.calls.first().args in refactor-jasmine-vitest | +| [9cba0da43f](https://github.com/angular/angular-cli/commit/9cba0da43f71bae7c6b01026843b2f312b25e6a5) | fix | set explicit type for the `module --route` component | +| [e9ae950364](https://github.com/angular/angular-cli/commit/e9ae95036491f7223a9989f366d17072fa4ba278) | fix | set explicit type for the app-shell component | + +### @angular-devkit/build-angular + +| Commit | Type | Description | +| ---------------------------------------------------------------------------------------------------- | ---- | -------------------------------------------------------------------------------------------------------------------------------------- | +| [0c4bd19ace](https://github.com/angular/angular-cli/commit/0c4bd19ace75539d43cdf3e870fe557c692f382f) | fix | resolve dev-server `sslKey` and `sslCert` relative to the workspace root ([#34399](https://github.com/angular/angular-cli/pull/34399)) | + +### @angular-devkit/core + +| Commit | Type | Description | +| ---------------------------------------------------------------------------------------------------- | ---- | ---------------------------------------------------------- | +| [ad04d689bb](https://github.com/angular/angular-cli/commit/ad04d689bbcc2778d3a0a006dcf3224da2e08536) | fix | only invoke smart default provider when value is undefined | + +### @angular-devkit/schematics + +| Commit | Type | Description | +| ---------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------------------------------------------------------------------- | +| [e7fd1bd9cb](https://github.com/angular/angular-cli/commit/e7fd1bd9cb831e82db96f985f8cb64325b7cae3b) | fix | support delegating trees in `partition` ([#34539](https://github.com/angular/angular-cli/pull/34539)) | +| [1854c1714d](https://github.com/angular/angular-cli/commit/1854c1714d6c8ec3f66424337a4e8fabb3c30903) | fix | support delegating trees in the `filter` rule ([#34539](https://github.com/angular/angular-cli/pull/34539)) | + +### @angular/build + +| Commit | Type | Description | +| ---------------------------------------------------------------------------------------------------- | ---- | -------------------------------------------------------------------------------------------------------------------------------------- | +| [6d45d1007f](https://github.com/angular/angular-cli/commit/6d45d1007feee82d96cbf8809f20f0481087f5ef) | fix | escape prerender redirect URLs | +| [6298fb89e6](https://github.com/angular/angular-cli/commit/6298fb89e6b4de0c8228dbd9b03dd23e1d816191) | fix | include the oxc-parser WASI binding as an optional dependency | +| [325f6a0f48](https://github.com/angular/angular-cli/commit/325f6a0f4856d60142fd54abf3bb9849e84e8e71) | fix | only require karma-coverage when coverage is enabled | +| [47075bee89](https://github.com/angular/angular-cli/commit/47075bee89bc9df119f0d253f2fbfe97fd4e4725) | fix | resolve dev-server `sslKey` and `sslCert` relative to the workspace root ([#34399](https://github.com/angular/angular-cli/pull/34399)) | +| [db45eed631](https://github.com/angular/angular-cli/commit/db45eed631a9b2bbf8c6fa3e6b852cb4a9a989f9) | fix | serialize server manifest asset paths | +| [5ae6a66edb](https://github.com/angular/angular-cli/commit/5ae6a66edb33df529ba598900785f62055c1ead2) | fix | suggest the istanbul provider in the unit-test V8 browser coverage error | +| [e3134b4cbc](https://github.com/angular/angular-cli/commit/e3134b4cbc136a08e2df080ab29ae5eaca608c13) | fix | warn about unsupported options in the unit-test karma runner | +| [250fae725e](https://github.com/angular/angular-cli/commit/250fae725eb05c5ad10fd02ab8e7b09d3f880f88) | fix | write the stats file in a stable, deterministic order | +| [cda246579e](https://github.com/angular/angular-cli/commit/cda246579ea4f0f668d765ef65c9e56dab5884fe) | perf | avoid duplicate Domino bundling in server bundles | +| [bcdcc09fb7](https://github.com/angular/angular-cli/commit/bcdcc09fb706b60ad8ab0f37a0a79a65e046b6cd) | perf | avoid web worker channel overhead in library parallel compilation | + +### @angular/ssr + +| Commit | Type | Description | +| ---------------------------------------------------------------------------------------------------- | ---- | ---------------------------------------------------------------- | +| [7b9c8d0b5d](https://github.com/angular/angular-cli/commit/7b9c8d0b5d39af7134191d2e2bfd717d375a1eac) | fix | preserve trailing slashes in query and fragment of redirect URLs | + + + + + +# 22.2.4 (2026-10-22) + +### @angular/cli + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | -------------------------------------------------- | +| [63e45bcfe](https://github.com/angular/angular-cli/commit/63e45bcfe711b6e2320db7ee24caba898bb90347) | fix | keep schematic positional arguments in index order | +| [6053771cb](https://github.com/angular/angular-cli/commit/6053771cba3c29a481d21ea6a2f2b9dd279b6db2) | fix | only load autocompletion in interactive shells | + +### @schematics/angular + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------- | +| [eec8dc049](https://github.com/angular/angular-cli/commit/eec8dc049a21e8ee685dd07ed365e43d04802cf5) | fix | apply `viewEncapsulation` to generated application components | +| [3a549925e](https://github.com/angular/angular-cli/commit/3a549925e2adf2101ae635da1e4a9cf0217c13d2) | fix | correct error and warning messages in environments schematic | +| [fe119a7c7](https://github.com/angular/angular-cli/commit/fe119a7c717db7a50d92073dd8d3a2f4726bbd6f) | fix | show routing module suffixes in `findModule` error | +| [36d988001](https://github.com/angular/angular-cli/commit/36d988001e1d36d02a759f2580bd251fff175e07) | fix | skip `webWorkerTsConfig` for unit-test builder test targets | +| [460167cd3](https://github.com/angular/angular-cli/commit/460167cd335b6b4addb9c92d60f56a04ddf9ed5e) | fix | use the generated class name when declaring in an NgModule | + +### @angular/build + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------------------------------------- | +| [c235a9554](https://github.com/angular/angular-cli/commit/c235a9554fb1f5cad734a3fb2df7c4f7e4283f91) | fix | add integrity metadata for all initial chunks beyond the module preload limit | +| [80c7480b4](https://github.com/angular/angular-cli/commit/80c7480b4d574ef2cd178e315288d9bfe821a5ac) | fix | align lazy route entry names with workspace root for SSR modulepreload | +| [b94627706](https://github.com/angular/angular-cli/commit/b9462770643465bd1bf33bc7cdaf2386d0bf9d41) | fix | attach location to Sass errors and guard stack parsing | +| [0dc103735](https://github.com/angular/angular-cli/commit/0dc103735e9cd42007a0b81cf1c2a563f80b94e6) | fix | correct typos and spacing in error and warning messages | +| [3e464c3f5](https://github.com/angular/angular-cli/commit/3e464c3f55d4aa2b7f1cb3d62ee3104c62029a5e) | fix | invalidate Vite module cache for removed dev server output files | +| [7d9ba6280](https://github.com/angular/angular-cli/commit/7d9ba628034866a2ec51a6357f05c9ce426cbb76) | fix | match proxy glob patterns against URL pathname only | +| [3aa7e93cc](https://github.com/angular/angular-cli/commit/3aa7e93ccf898d84d620ff0b46e5a718fa9c3a90) | fix | name the provider packages in the unit-test `browsers` error | +| [e78cf0ae9](https://github.com/angular/angular-cli/commit/e78cf0ae9676e77245de3cae7ae86b42a48a6322) | fix | preserve diagnostic locations at offset 0 and guard empty files | +| [b3baa20c6](https://github.com/angular/angular-cli/commit/b3baa20c6cb5b00c9df4d3d4d072435b324566e2) | fix | support quotes in `styles` and `polyfills` paths | +| [648aff9eb](https://github.com/angular/angular-cli/commit/648aff9ebb54735fab5cc4265200a06c4d531f35) | fix | use component file path in inline stylesheet diagnostic locations | +| [a9bec13b5](https://github.com/angular/angular-cli/commit/a9bec13b58550fc757612c3617aa33eefb776041) | fix | use distinct chunk naming for web worker bundles | +| [a05723948](https://github.com/angular/angular-cli/commit/a057239486e42ec7189f03a61b09e3b0761150c9) | fix | watch only explicitly added paths in chokidar watcher | +| [35702a598](https://github.com/angular/angular-cli/commit/35702a5986dc7ea4f2f2d7f18ef9f8f3b4fd33c2) | perf | avoid reading external component stylesheets twice | + +### @angular/ssr + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ---------------------------------------------------------------------------------------------------------------------- | +| [3beb2551c](https://github.com/angular/angular-cli/commit/3beb2551cc784ed0714070bbd23c1a8bb70e2938) | fix | resolve query parameter placeholders in redirect targets ([#34321](https://github.com/angular/angular-cli/pull/34321)) | +| [ff3f3727a](https://github.com/angular/angular-cli/commit/ff3f3727a9eb18f0b7714646a04b7d3e172c18d7) | fix | resolve route parameters in redirect targets ([#34321](https://github.com/angular/angular-cli/pull/34321)) | +| [d365b0008](https://github.com/angular/angular-cli/commit/d365b0008f0c5bb8bca92e83066999253f409b64) | fix | use only the first value of the `X-Forwarded-Prefix` header | + + + + + +# 22.2.3 (2026-10-15) + +### @angular/cli + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------------------------- | +| [3158e865f](https://github.com/angular/angular-cli/commit/3158e865ffdd828711d645dff16cc17fd26bb58e) | fix | accept multi-digit array indices in ng config | +| [bcff0e76a](https://github.com/angular/angular-cli/commit/bcff0e76adf73cfa32b02c5256490189675cb132) | fix | keep ng version working when the package manager is not installed | +| [5570c91d2](https://github.com/angular/angular-cli/commit/5570c91d2f38764cd841fcce146f1d13fef49b0c) | fix | resolve package name in npm workspace members | + +### @schematics/angular + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------- | +| [881865f36](https://github.com/angular/angular-cli/commit/881865f364b33b36630aa6ab7a129f7ed665cfa7) | fix | keep the workspace build version in the use-application-builder migration | + +### @angular-devkit/schematics + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------- | +| [cf1f3b9d4](https://github.com/angular/angular-cli/commit/cf1f3b9d43177e15cf9a00973e6da3baeaf4b2dd) | fix | avoid stack overflow when chaining many rules | + +### @angular/build + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------- | +| [1d477d6bc](https://github.com/angular/angular-cli/commit/1d477d6bc27159cb0c78288e047fcadfe6fc31d4) | fix | add CSP nonce to stylesheet and modulepreload link elements | +| [fbe208f83](https://github.com/angular/angular-cli/commit/fbe208f8392ec0ce82d597e8b690f146370bdc81) | fix | always use AOT when extracting i18n messages | +| [c1c4216a6](https://github.com/angular/angular-cli/commit/c1c4216a680891b80670660a621d6736c4aecaf0) | fix | coalesce external watcher directories to avoid macOS FSEvents limit | +| [792990bc2](https://github.com/angular/angular-cli/commit/792990bc2eacdcc8ed4de6ef46e58ceeb5fe8741) | fix | disable Vitest fsModuleCache in unit-test builder | +| [82439399c](https://github.com/angular/angular-cli/commit/82439399cbfb4c1d21d1c80d976021efa9e4a39a) | fix | ensure Sass importers return global Promise instances | +| [a818de415](https://github.com/angular/angular-cli/commit/a818de415e933819e7a2e3e679cd0b2d2be734de) | fix | keep Vite server file watcher disabled in Vitest watch mode | +| [91bad469e](https://github.com/angular/angular-cli/commit/91bad469ec5ce7b2dfd07e394b482d2cef411407) | fix | sort discovered unit-test files for deterministic builds | +| [e84db4af7](https://github.com/angular/angular-cli/commit/e84db4af70ca9be490b462e6d8112524dc8eb6d4) | fix | use module.registerHooks() for in-memory ESM loader | +| [a428021b7](https://github.com/angular/angular-cli/commit/a428021b77dbccf404f39712f1c88bed9b8e4272) | perf | avoid invalidating Angular diagnostic cache on stylesheet change | +| [b0ac394a0](https://github.com/angular/angular-cli/commit/b0ac394a063f084d885df67660224b6a25e2c614) | perf | resolve asset patterns concurrently with bounded concurrency | + +### @angular/ssr + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------ | +| [bd09b98fc](https://github.com/angular/angular-cli/commit/bd09b98fcaff4b76c7fd65999b51bfaa942d1858) | fix | preserve preload metadata for nested empty-path routes | +| [a92546892](https://github.com/angular/angular-cli/commit/a925468929c74c30a3e64b361a6dc5d6fdc1006a) | fix | preserve query parameters on relative route redirects | +| [a2b86cc94](https://github.com/angular/angular-cli/commit/a2b86cc94d408ba4c3d422224b58e26b7a68f692) | fix | resolve relative redirects against the parent route | + + + + + +# 22.2.2 (2026-10-07) + +### @angular-devkit/build-angular + +| Commit | Type | Description | +| ---------------------------------------------------------------------------------------------------- | ---- | ---------------------------------------------------- | +| [cfe970c8bc](https://github.com/angular/angular-cli/commit/cfe970c8bcfbc47e9fa1fa6b17e41cdf1d3b30bf) | fix | preserve Host header when proxying in ssr-dev-server | + +### @angular/build + +| Commit | Type | Description | +| ---------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------- | +| [405bfa370a](https://github.com/angular/angular-cli/commit/405bfa370ac3c8f14808d58cfc707b7ff23348c4) | fix | keep the order of glob entries in the proxy configuration | +| [996e47f809](https://github.com/angular/angular-cli/commit/996e47f809a3172486df665bfce6d5c11e652154) | fix | support a string `context` in array-form proxy configurations | + + + + + +# 22.2.1 (2026-10-01) + +### @angular/cli + +| Commit | Type | Description | +| ---------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------------- | +| [db053444e0](https://github.com/angular/angular-cli/commit/db053444e0af22223100f931def9f41d1eea4426) | fix | skip components with a change detection strategy in the zoneless migration tool | + +### @schematics/angular + +| Commit | Type | Description | +| ---------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------- | +| [663c580c86](https://github.com/angular/angular-cli/commit/663c580c86645b5b3a31925154427588e48018ba) | fix | add browsers option to angular.json during vitest browser provider ng-add | + +### @angular-devkit/schematics-cli + +| Commit | Type | Description | +| ---------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------------------------------------------------ | +| [e6350b6f57](https://github.com/angular/angular-cli/commit/e6350b6f57a546f77d38515604d1c1fa46d85d39) | fix | correctly parse inline boolean values in CLI options ([#34201](https://github.com/angular/angular-cli/pull/34201)) | + +### @angular-devkit/architect + +| Commit | Type | Description | +| ---------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------------------------------------------------ | +| [516df4ee6d](https://github.com/angular/angular-cli/commit/516df4ee6d1d07ad8b851ff108595d08ef4d319b) | fix | correctly parse inline boolean values in CLI options ([#34201](https://github.com/angular/angular-cli/pull/34201)) | + +### @angular-devkit/build-angular + +| Commit | Type | Description | +| ---------------------------------------------------------------------------------------------------- | ---- | ---------------------------------------------------- | +| [ac70f86208](https://github.com/angular/angular-cli/commit/ac70f862086343d2d9a36fd7b09b3a3680e907b0) | fix | do not mark standalone expression statements as pure | + +### @angular/build + +| Commit | Type | Description | +| ---------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------------------------------------------------------------------------- | +| [ec9c0b51c2](https://github.com/angular/angular-cli/commit/ec9c0b51c24fd0fba8a7f01dbb0ff25cf520a0d5) | fix | deduplicate spurious chokidar polling change events ([#34188](https://github.com/angular/angular-cli/pull/34188)) | +| [c1b5154180](https://github.com/angular/angular-cli/commit/c1b515418033685a9624140b5eecb6330ec07504) | fix | encode script type in auto-CSP loader | +| [cb4dd71a1b](https://github.com/angular/angular-cli/commit/cb4dd71a1bbf9d7a8273061c54a8997cb725e9e3) | fix | ensure @angular/compiler is loaded for Vitest TestBed initialization | +| [b198044048](https://github.com/angular/angular-cli/commit/b1980440484d809f89e54d04bdeb484ff2db6aae) | fix | preserve nested workspace path for git worktree cache | +| [5194b41531](https://github.com/angular/angular-cli/commit/5194b415314a4fb2435b29dcf42ccffbc26070a9) | fix | prevent chokidar from scanning unimported node_modules in watch mode | +| [37cf399d95](https://github.com/angular/angular-cli/commit/37cf399d95d9376811cd79144bbd517f3efe3d32) | fix | reset component updates on dev-server SSR page request | +| [ddff42cb03](https://github.com/angular/angular-cli/commit/ddff42cb03cd45f1e668794057843f8a98501c0a) | fix | serve emitted HTML assets in dev-server | +| [e3e893682d](https://github.com/angular/angular-cli/commit/e3e893682d501d3135bf3abcb1c74b9598f78017) | fix | watchers outside the workspace via parcel didn't work | +| [d55e899954](https://github.com/angular/angular-cli/commit/d55e899954e677c9d0751ab8e56b0364bf3a3098) | perf | avoid loading compiler-cli and typescript in js transform worker | +| [3d08e5b053](https://github.com/angular/angular-cli/commit/3d08e5b053d50f9101215974039aafcc39f6a9e9) | perf | avoid sharding intermediate files under worker surplus in i18n inliner | +| [5ea36fe8b8](https://github.com/angular/angular-cli/commit/5ea36fe8b8b9732054a3749912018bae71e3b746) | perf | bound aggregate worker allocation across dominant files in i18n inliner | +| [90ee193bd1](https://github.com/angular/angular-cli/commit/90ee193bd188629da762e2f98cb664d8493ed733) | perf | bound concurrent worker allocation for dominant files in i18n inliner | +| [41b353856b](https://github.com/angular/angular-cli/commit/41b353856ba0babc03907701508d7a2b45c96743) | perf | process batch locales sequentially in i18n inliner worker | + + + + + +# 22.2.0 (2026-09-23) ## Deprecations @@ -10,31 +249,63 @@ Disabling code splitting is no longer necessary with Vitest 5, as the issue where shared-module exports were uninitialized in class-field initializers under JSDOM has been resolved. +### @angular/cli + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------------------------- | +| [41555dfb3](https://github.com/angular/angular-cli/commit/41555dfb3b71d08cdfe2853bf2cbeca5b6942f67) | feat | add `--root` command line option to `mcp` command | +| [6e7f809a7](https://github.com/angular/angular-cli/commit/6e7f809a7d66e4b8d260a1c00297812412a926f1) | perf | skip eager yargs help message formatting during command execution | + ### @angular/build -| Commit | Type | Description | -| ---------------------------------------------------------------------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------- | -| [fe2f180fd0](https://github.com/angular/angular-cli/commit/fe2f180fd0c2fa02706353ca6a034d235feb6c59) | fix | add automatic corruption recovery in SQLite cache store | -| [675f1f5274](https://github.com/angular/angular-cli/commit/675f1f5274ff853f153832f7adc69273fa63f0cd) | fix | avoid pure comment pattern in oxc transform | -| [d396324b4e](https://github.com/angular/angular-cli/commit/d396324b4eb3b16640526a64365d953642bc7ca1) | fix | default preloadInitial to false when serviceWorker is enabled | -| [8504cfffcf](https://github.com/angular/angular-cli/commit/8504cfffcfb943fcd8fda62507e4b236e4bf429a) | fix | disable root config extension for inline test project | -| [5d21812aae](https://github.com/angular/angular-cli/commit/5d21812aaedc57cbd9378a99d9747f80c413cdc3) | fix | disable strictPort when port 0 is used in dev-server | -| [54d712f579](https://github.com/angular/angular-cli/commit/54d712f57904d2f612eec27a0507ea298b40915e) | fix | ensure parent directory exists in SQLite cache store | -| [b423bc39cd](https://github.com/angular/angular-cli/commit/b423bc39cd59c73ae79402c6cccdc0ecf1d7aaa1) | fix | use chokidar watcher when followSymlinks is enabled | -| [5a0d226b7c](https://github.com/angular/angular-cli/commit/5a0d226b7ccb945edd234fa0c839994f4876e2ee) | perf | avoid full JSON parsing when updating sourcemap ignore list | -| [482f6d8aab](https://github.com/angular/angular-cli/commit/482f6d8aab289fbd6dc5f9aecdcf7b8e1b6cac4f) | perf | decouple diagnostic type checking from build start | -| [f1afa603b4](https://github.com/angular/angular-cli/commit/f1afa603b48566e45dfb8d95930375a71f0bfa0b) | perf | read rendered module length once per module in chunk optimizer ([#34045](https://github.com/angular/angular-cli/pull/34045)) | -| [0ba4d8e29c](https://github.com/angular/angular-cli/commit/0ba4d8e29c0fb9abe6b07432edfab9e39066ca29) | perf | reduce watcher debounce latency for faster incremental rebuilds | -| [4d11a1334f](https://github.com/angular/angular-cli/commit/4d11a1334ff5fabfe5338cc3de5ce4f45f6afa5f) | perf | selectively compress large entries in SQLite cache store | -| [0a137f98d0](https://github.com/angular/angular-cli/commit/0a137f98d035f3dbd9a5daf1b6999246f73610c8) | perf | share sass directory and resolution caches across stylesheets | -| [d11a663e77](https://github.com/angular/angular-cli/commit/d11a663e77dad3dc9dbb6336e782f23b8a6f595c) | perf | verify cache metadata before reading file and eliminate sqlite read-locks | -| [66bd6bd1ea](https://github.com/angular/angular-cli/commit/66bd6bd1eab41484ed5db38f5545e80de4090b34) | refactor | deprecate splitting option in unit-test builder | +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | -------- | -------------------------------------------------------------------------------- | +| [ad8271320](https://github.com/angular/angular-cli/commit/ad8271320f67c2b1502e446f1e3cb0a05444d04f) | feat | migrate Angular Linker to oxc-parser and magic-string | +| [175273931](https://github.com/angular/angular-cli/commit/175273931ebb0cf08bf62dd1694dbde5ff5229b6) | feat | Support splitting browser and server stats jsonfiles for easier consumption | +| [fe2f180fd](https://github.com/angular/angular-cli/commit/fe2f180fd0c2fa02706353ca6a034d235feb6c59) | fix | add automatic corruption recovery in SQLite cache store | +| [675f1f527](https://github.com/angular/angular-cli/commit/675f1f5274ff853f153832f7adc69273fa63f0cd) | fix | avoid pure comment pattern in oxc transform | +| [d396324b4](https://github.com/angular/angular-cli/commit/d396324b4eb3b16640526a64365d953642bc7ca1) | fix | default preloadInitial to false when serviceWorker is enabled | +| [7e5510e46](https://github.com/angular/angular-cli/commit/7e5510e464eb423d8757ae6f058f73fc17249d81) | fix | disable linker internal source mapping in OXC linker | +| [8504cfffc](https://github.com/angular/angular-cli/commit/8504cfffcfb943fcd8fda62507e4b236e4bf429a) | fix | disable root config extension for inline test project | +| [ee3041325](https://github.com/angular/angular-cli/commit/ee3041325cd2400c26e239e64e14a0e314ab6031) | fix | ensure chokidar watcher is ready before returning | +| [54d712f57](https://github.com/angular/angular-cli/commit/54d712f57904d2f612eec27a0507ea298b40915e) | fix | ensure parent directory exists in SQLite cache store | +| [80acd6236](https://github.com/angular/angular-cli/commit/80acd6236eac6b1b07543583717e94cbd1de1180) | fix | execute setup file hooks for each spec file when coverage is enabled | +| [978351af7](https://github.com/angular/angular-cli/commit/978351af71889d4786a18fec9e193eb5b16af7dd) | fix | include inline component stylesheets in referenced watch files | +| [f47f77f5f](https://github.com/angular/angular-cli/commit/f47f77f5f6db5cda1493652f813c98c26f172ea9) | fix | only compile included test files in unit-test builder | +| [72dc9677c](https://github.com/angular/angular-cli/commit/72dc9677cf743243d6cb22d2b81782022f71356e) | fix | pass load cache to compiler plugin and escape extension regex in polyfills | +| [701bde481](https://github.com/angular/angular-cli/commit/701bde4818439de0e49c99d57dc749b0dd22c4dd) | fix | preserve duplicate bundle filenames across output file types | +| [e4111ae81](https://github.com/angular/angular-cli/commit/e4111ae8180f3cd5800f248c23010844aa1730ad) | fix | prevent memory leaks in parallel compilation and caches | +| [31c045639](https://github.com/angular/angular-cli/commit/31c045639e8bfd114cbd552d83cc70a968fe7f81) | fix | prevent stale bundler caching and correctly resolve load cache | +| [bad31421c](https://github.com/angular/angular-cli/commit/bad31421cbf23339d4fbd389a91d198df405697d) | fix | prevent syntax corruption in linker and oxc transform | +| [0d9851600](https://github.com/angular/angular-cli/commit/0d9851600ca618ccabfc3143a9c552a5448d6eec) | fix | recursively ignore output and cache paths in watch mode | +| [040bc21ec](https://github.com/angular/angular-cli/commit/040bc21ec3d4fa1bdfa8513206f463d89e20d9a1) | fix | scope Sass package resolution caching for stylesheets in node_modules | +| [1fc273279](https://github.com/angular/angular-cli/commit/1fc2732795069ad521645b06a94e5df3a55c3d9c) | fix | support parenthesized expressions in oxc linker | +| [b423bc39c](https://github.com/angular/angular-cli/commit/b423bc39cd59c73ae79402c6cccdc0ecf1d7aaa1) | fix | use chokidar watcher when followSymlinks is enabled | +| [87551ad5c](https://github.com/angular/angular-cli/commit/87551ad5c53f90cbdc68fdb5e47007b9436c7f75) | perf | avoid encoding intermediate source maps before remapping | +| [6ee559ca9](https://github.com/angular/angular-cli/commit/6ee559ca9d209fb4c53de2aaf9918d10e5f062a1) | perf | bypass worker dispatch for files without transform candidates | +| [0589edd9c](https://github.com/angular/angular-cli/commit/0589edd9cdc493ecf34a160cc7b8491618b59f72) | perf | consolidate component stylesheet bundling with shared load result cache | +| [482f6d8aa](https://github.com/angular/angular-cli/commit/482f6d8aab289fbd6dc5f9aecdcf7b8e1b6cac4f) | perf | decouple diagnostic type checking from build start | +| [a877aa7eb](https://github.com/angular/angular-cli/commit/a877aa7ebdbf919d6bc17e6ec0920ca702db0db4) | perf | implement SharedArrayBuffer translation dictionaries for zero-copy worker access | +| [f1cc95943](https://github.com/angular/angular-cli/commit/f1cc959439d8ca11a45d693520c34dd94e0b6548) | perf | implement sliding-window batching and worker translation eviction | +| [d97c8857c](https://github.com/angular/angular-cli/commit/d97c8857c18da02fcc6c69a0ea652cc706c5c9b6) | perf | key Sass package resolutions without containing URL qualification | +| [5cd20e141](https://github.com/angular/angular-cli/commit/5cd20e141ad176c87e4002da2d4ee3755f97cd3e) | perf | only reset Sass worker pool caches when stylesheet files change | +| [1c00edce0](https://github.com/angular/angular-cli/commit/1c00edce02bdd0201546417d71518f78bfb89d34) | perf | optimize sourcemap stripping and loading with buffer fast path | +| [0ba4d8e29](https://github.com/angular/angular-cli/commit/0ba4d8e29c0fb9abe6b07432edfab9e39066ca29) | perf | reduce watcher debounce latency for faster incremental rebuilds | +| [a6ef9cfbe](https://github.com/angular/angular-cli/commit/a6ef9cfbeace725d58c0f7f65640ef6de9b39c33) | perf | replace watchpack with @parcel/watcher and chokidar | +| [4d11a1334](https://github.com/angular/angular-cli/commit/4d11a1334ff5fabfe5338cc3de5ce4f45f6afa5f) | perf | selectively compress large entries in SQLite cache store | +| [0a137f98d](https://github.com/angular/angular-cli/commit/0a137f98d035f3dbd9a5daf1b6999246f73610c8) | perf | share sass directory and resolution caches across stylesheets | +| [f4dad31cc](https://github.com/angular/angular-cli/commit/f4dad31cce41bc3e8ed8767256d9e50a712c3a72) | perf | unify Oxc linking and optimization AST traversal passes | +| [2b85529e8](https://github.com/angular/angular-cli/commit/2b85529e8290c8c916539b5a0336b4efdb68578c) | perf | use iterative post-order AST traversal for OXC transforms | +| [ecbcd87b8](https://github.com/angular/angular-cli/commit/ecbcd87b8857225e4df3df7896b3236d63553f23) | perf | use native sass-embedded compiler daemon | +| [ce83ac0e8](https://github.com/angular/angular-cli/commit/ce83ac0e82981efd9408e07a35315e3cef9e1a36) | perf | use size-weighted task heuristics in i18n inliner | +| [d11a663e7](https://github.com/angular/angular-cli/commit/d11a663e77dad3dc9dbb6336e782f23b8a6f595c) | perf | verify cache metadata before reading file and eliminate sqlite read-locks | +| [66bd6bd1e](https://github.com/angular/angular-cli/commit/66bd6bd1eab41484ed5db38f5545e80de4090b34) | refactor | deprecate splitting option in unit-test builder | ### @angular/ssr -| Commit | Type | Description | -| ---------------------------------------------------------------------------------------------------- | ---- | -------------------------------------------- | -| [23e3d44a7f](https://github.com/angular/angular-cli/commit/23e3d44a7f051cd3bb67700b8d8407f73b7aa7f3) | perf | pre-compile critical CSS plans at build time | +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | -------------------------------------------- | +| [23e3d44a7](https://github.com/angular/angular-cli/commit/23e3d44a7f051cd3bb67700b8d8407f73b7aa7f3) | perf | pre-compile critical CSS plans at build time | @@ -76,40 +347,6 @@ - - -# 22.2.0-next.6 (2026-09-02) - -### @angular/cli - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------ | -| [b37c93329](https://github.com/angular/angular-cli/commit/b37c933299dac37e394d9f4fe0d019052db427a9) | fix | isolate temporary package installations from parent Yarn workspace | - -### @angular/build - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------- | -| [4b8c62a8f](https://github.com/angular/angular-cli/commit/4b8c62a8f1a1d312ef2e1e0df6b7642bf1db5c5f) | fix | add splitting option to unit-test builder | -| [51565d4bc](https://github.com/angular/angular-cli/commit/51565d4bcbd4667c23c607d878f08301afc4c5e3) | fix | enable code splitting for vitest browser tests | -| [5b850fdfc](https://github.com/angular/angular-cli/commit/5b850fdfc7534d33db7ab4a7f1e32e143462eec7) | fix | fail build and exclude routes when prerendering fails | -| [dfa7f03a9](https://github.com/angular/angular-cli/commit/dfa7f03a93b5b24b949aea354bc40f0a91e9582d) | fix | keep dev-server Vite cache worktree-local | -| [135662d9a](https://github.com/angular/angular-cli/commit/135662d9a1de85b42292b26b547160eaca71e5da) | fix | preserve binary values in the SQLite cache store | -| [701bde481](https://github.com/angular/angular-cli/commit/701bde4818439de0e49c99d57dc749b0dd22c4dd) | fix | preserve duplicate bundle filenames across output file types | -| [6ee559ca9](https://github.com/angular/angular-cli/commit/6ee559ca9d209fb4c53de2aaf9918d10e5f062a1) | perf | bypass worker dispatch for files without transform candidates | -| [2b85529e8](https://github.com/angular/angular-cli/commit/2b85529e8290c8c916539b5a0336b4efdb68578c) | perf | use iterative post-order AST traversal for OXC transforms | -| [ecbcd87b8](https://github.com/angular/angular-cli/commit/ecbcd87b8857225e4df3df7896b3236d63553f23) | perf | use native sass-embedded compiler daemon | -| [ce83ac0e8](https://github.com/angular/angular-cli/commit/ce83ac0e82981efd9408e07a35315e3cef9e1a36) | perf | use size-weighted task heuristics in i18n inliner | - -### @angular/ssr - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------------- | -| [4fa81d403](https://github.com/angular/angular-cli/commit/4fa81d403c93a7480301e58630203cb028aebc69) | fix | decode pathname when constructing server asset path | -| [bb72145f9](https://github.com/angular/angular-cli/commit/bb72145f9ab45aee29f523236b3a25cd0813a841) | fix | ensure public directory containment in CommonEngine | - - - # 22.1.7 (2026-09-02) @@ -175,30 +412,6 @@ - - -# 22.2.0-next.5 (2026-08-26) - -### @angular/build - -| Commit | Type | Description | -| ---------------------------------------------------------------------------------------------------- | ---- | -------------------------------------------------------------------------------- | -| [4d0be683b7](https://github.com/angular/angular-cli/commit/4d0be683b780a9a1629dc8f9cddad49153bddabf) | fix | ignore side-effect annotations in unit test builds | -| [e4111ae818](https://github.com/angular/angular-cli/commit/e4111ae8180f3cd5800f248c23010844aa1730ad) | fix | prevent memory leaks in parallel compilation and caches | -| [62999cabf4](https://github.com/angular/angular-cli/commit/62999cabf4d65cf1060598150a77494e147fcc2a) | perf | batch prerender routes and share in-memory server bundles | -| [0589edd9cd](https://github.com/angular/angular-cli/commit/0589edd9cdc493ecf34a160cc7b8491618b59f72) | perf | consolidate component stylesheet bundling with shared load result cache | -| [a877aa7ebd](https://github.com/angular/angular-cli/commit/a877aa7ebdbf919d6bc17e6ec0920ca702db0db4) | perf | implement SharedArrayBuffer translation dictionaries for zero-copy worker access | -| [f1cc959439](https://github.com/angular/angular-cli/commit/f1cc959439d8ca11a45d693520c34dd94e0b6548) | perf | implement sliding-window batching and worker translation eviction | -| [f4dad31cce](https://github.com/angular/angular-cli/commit/f4dad31cce41bc3e8ed8767256d9e50a712c3a72) | perf | unify Oxc linking and optimization AST traversal passes | - -### @angular/ssr - -| Commit | Type | Description | -| ---------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------------- | -| [f8576e3c8b](https://github.com/angular/angular-cli/commit/f8576e3c8bfe3490b1b0b85832b489593a4e43ac) | fix | abort web request signal when node request is aborted | - - - # 22.1.6 (2026-08-26) @@ -242,36 +455,6 @@ - - -# 22.2.0-next.4 (2026-08-19) - -### @angular/cli - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ---------------------------------------------------------------- | -| [34e1e0bb5](https://github.com/angular/angular-cli/commit/34e1e0bb5d5ccf374f51a1b241158f6f2ea0dd42) | fix | enforce MCP roots in get_best_practices tool | -| [2b060630c](https://github.com/angular/angular-cli/commit/2b060630c66ce688b7ecbe51d282955869e5d4b0) | fix | handle errors from isAllowedWorkspacePath in best-practices tool | -| [24fd8fce2](https://github.com/angular/angular-cli/commit/24fd8fce2a3ff035acdc5f3e036eb4ba21f71a76) | fix | throw on out-of-roots workspace in best-practices tool | - -### @schematics/angular - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------ | -| [ce1b60f89](https://github.com/angular/angular-cli/commit/ce1b60f89699c3a76496a0489e5f2b9e4fe62429) | fix | transform fail() to expect.fail() in refactor-jasmine-vitest | - -### @angular/build - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------------------------------------- | -| [175273931](https://github.com/angular/angular-cli/commit/175273931ebb0cf08bf62dd1694dbde5ff5229b6) | feat | Support splitting browser and server stats jsonfiles for easier consumption | -| [1ee0beca7](https://github.com/angular/angular-cli/commit/1ee0beca7b243cc4c06eb42b25d216d7b256b097) | fix | correct misleading error message for top-level await | -| [0ffe2d27f](https://github.com/angular/angular-cli/commit/0ffe2d27f256a5755809fa4788e4adb97c65b806) | fix | disable code splitting for unit test builds | -| [50994d76e](https://github.com/angular/angular-cli/commit/50994d76e59a4b632f1782c51cd60f80c9cd50fb) | fix | preserve integrity and crossorigin in autoCsp loader | -| [d6fd24320](https://github.com/angular/angular-cli/commit/d6fd243207ad1c3e242b8592698afa986320cc6c) | perf | traverse AST with iterative post-order walker in i18n inliner | - - - # 22.1.5 (2026-08-19) @@ -301,54 +484,6 @@ - - -# 22.2.0-next.3 (2026-08-13) - -### @angular/cli - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------------------------------------------------------------------- | -| [7106676e6](https://github.com/angular/angular-cli/commit/7106676e64ee234641b1b3cbd88fc058703d4d3e) | fix | disable searching current directory for bare executable names on Windows | -| [ecf8c0822](https://github.com/angular/angular-cli/commit/ecf8c0822e5d56b44a0be4be8fccb41373135d3e) | fix | serialize configuration as a single argv token in run_target strategies ([#33657](https://github.com/angular/angular-cli/pull/33657)) | -| [2e4dd90c3](https://github.com/angular/angular-cli/commit/2e4dd90c3ae898bf36af42f699c7b7d560bfc66a) | perf | avoid eager module loading during global bootstrap | - -### @schematics/angular - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------- | -| [1161e6c99](https://github.com/angular/angular-cli/commit/1161e6c99992c884e2e0ce9fc295b0e60b2ae1df) | fix | generate CLAUDE.md for Claude Code instead of AGENTS.md | -| [c536ae364](https://github.com/angular/angular-cli/commit/c536ae364975dd0088fd8717464c723a4dcb74e3) | fix | import UrlSegment instead of subPath in guard generator | - -### @angular/build - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------------------------- | -| [04b532772](https://github.com/angular/angular-cli/commit/04b532772f6347d341b182135dee1758616a69d6) | fix | count statically imported chunks in the initial total | -| [2274babb6](https://github.com/angular/angular-cli/commit/2274babb662b8da2189f1ae9faaa528838052c32) | fix | normalize setupFiles paths to POSIX for vitest runner | -| [199a864df](https://github.com/angular/angular-cli/commit/199a864df97fc8c20b8d4e1fc8b891c61140671a) | fix | prevent syntax corruption for Crockford-style enum IIFE | -| [0d9851600](https://github.com/angular/angular-cli/commit/0d9851600ca618ccabfc3143a9c552a5448d6eec) | fix | recursively ignore output and cache paths in watch mode | -| [3eba6f726](https://github.com/angular/angular-cli/commit/3eba6f7269f3b0f8556510d0b668e978ea686c88) | fix | return direct file contents for non-Angular TypeScript files | -| [3c7ac1518](https://github.com/angular/angular-cli/commit/3c7ac1518b062f14409b4d3c6c3e65c956424ad9) | fix | return only lowest version per target engine | -| [3e9fed9a6](https://github.com/angular/angular-cli/commit/3e9fed9a6a1d24f30812ca29ca621d9d9a14496f) | fix | set target for Rolldown dependency prebundling in Vite dev server | -| [87551ad5c](https://github.com/angular/angular-cli/commit/87551ad5c53f90cbdc68fdb5e47007b9436c7f75) | perf | avoid encoding intermediate source maps before remapping | -| [194be2088](https://github.com/angular/angular-cli/commit/194be2088587918ed7b47ed606ea587a7116608a) | perf | avoid encoding the inline source map before remapping | -| [a55a6b78e](https://github.com/angular/angular-cli/commit/a55a6b78e89debb9c93c83375c54f6716bc26c65) | perf | batch last_accessed updates in sqlite cache store | -| [33b305416](https://github.com/angular/angular-cli/commit/33b3054169929dc98f93a758a90da5d26cf522f7) | perf | hash the i18n inline cache key options once per locale | -| [1c00edce0](https://github.com/angular/angular-cli/commit/1c00edce02bdd0201546417d71518f78bfb89d34) | perf | optimize sourcemap stripping and loading with buffer fast path | -| [b6269a816](https://github.com/angular/angular-cli/commit/b6269a8169046a78281808dcf92054140912a77d) | perf | optimize template string size calculation in server manifest | -| [a6ef9cfbe](https://github.com/angular/angular-cli/commit/a6ef9cfbeace725d58c0f7f65640ef6de9b39c33) | perf | replace watchpack with @parcel/watcher and chokidar | -| [596847f89](https://github.com/angular/angular-cli/commit/596847f89913684a84465d004aa3d6c7e1a40b06) | perf | share i18n translations with the inliner workers by reference | -| [19c91e48d](https://github.com/angular/angular-cli/commit/19c91e48d4b8a95a76dfe4bffd105130b416843d) | perf | use Map for chunk asset size lookups in budget calculator | - -### @angular/ssr - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | -------------------------------------------------- | -| [6a3446770](https://github.com/angular/angular-cli/commit/6a3446770a8fbfecc7265eb2a6d764e2f1614b3a) | fix | destroy platform when response stream is cancelled | - - - # 22.1.4 (2026-08-13) @@ -430,54 +565,6 @@ - - -# 22.2.0-next.2 (2026-08-05) - -### @angular/build - -| Commit | Type | Description | -| ---------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------------- | -| [7e5510e464](https://github.com/angular/angular-cli/commit/7e5510e464eb423d8757ae6f058f73fc17249d81) | fix | disable linker internal source mapping in OXC linker | -| [bad31421cb](https://github.com/angular/angular-cli/commit/bad31421cbf23339d4fbd389a91d198df405697d) | fix | prevent syntax corruption in linker and oxc transform | - - - - - -# 22.2.0-next.1 (2026-08-05) - -### @angular/cli - -| Commit | Type | Description | -| ---------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------------------------------------------------------------------------------------------------------- | -| [41555dfb3b](https://github.com/angular/angular-cli/commit/41555dfb3b71d08cdfe2853bf2cbeca5b6942f67) | feat | add `--root` command line option to `mcp` command | -| [035b9d5c9b](https://github.com/angular/angular-cli/commit/035b9d5c9bca624b98e14480f599481f294b49f3) | fix | add packages with built-in schematics to devDependencies only | -| [0ae5690c35](https://github.com/angular/angular-cli/commit/0ae5690c35b9af00f60d4851f1bab4ba5ec8eb19) | fix | always install package during ng add to inspect manifest on disk for schematics ([#33718](https://github.com/angular/angular-cli/pull/33718)) | -| [44ff584b33](https://github.com/angular/angular-cli/commit/44ff584b33830aa839c08feb205f014e4e7b5dca) | fix | correctly report available package updates during bare ng update | -| [1d4f9ebbe9](https://github.com/angular/angular-cli/commit/1d4f9ebbe993a5eb8b23929a3fc55b506597e5aa) | fix | discover migrations from installed packages when omitted by registry metadata ([#33718](https://github.com/angular/angular-cli/pull/33718)) | -| [25034f97ad](https://github.com/angular/angular-cli/commit/25034f97ad1b9a12f4080f646a0e2705425f9726) | fix | normalize Windows drive-letter casing for process.cwd | - -### @angular/build - -| Commit | Type | Description | -| ---------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------------------------------------------- | -| [ad8271320f](https://github.com/angular/angular-cli/commit/ad8271320f67c2b1502e446f1e3cb0a05444d04f) | feat | migrate Angular Linker to oxc-parser and magic-string | -| [4fb12292c2](https://github.com/angular/angular-cli/commit/4fb12292c21498c59836f7c80e4f824bb7751cac) | fix | prevent build process hang on unhandled error ([#33715](https://github.com/angular/angular-cli/pull/33715)) | -| [abd8ec9f3e](https://github.com/angular/angular-cli/commit/abd8ec9f3e11f1410fcb87d0d9d60f56016912fe) | fix | prevent IIFE wrapper interleaving for adjacent classes in minified files | -| [bcadbbef20](https://github.com/angular/angular-cli/commit/bcadbbef2054e897b9d22c1456883fc68f0383c0) | fix | retain watch files on error in load result cache | -| [e1c7193dce](https://github.com/angular/angular-cli/commit/e1c7193dcee1c7f2feb07fdf24a6e0656f29cfaf) | fix | support case-insensitive and alternative license file names | -| [f4a0f846e7](https://github.com/angular/angular-cli/commit/f4a0f846e7d14b5ff58c91d04461ef4a027c56b8) | perf | release build resources early in non-watch mode ([#33715](https://github.com/angular/angular-cli/pull/33715)) | - -### @angular/ssr - -| Commit | Type | Description | -| ---------------------------------------------------------------------------------------------------- | ---- | ---------------------------------------------------------- | -| [b74eef889f](https://github.com/angular/angular-cli/commit/b74eef889f9c8812dcbe116400663fa3d68d6b4f) | fix | settle writeResponseToNodeResponse when client disconnects | -| [33169801c6](https://github.com/angular/angular-cli/commit/33169801c6ed7fc7c7dca2c04008e5d405374983) | perf | avoid buffering request body when sanitizing headers | - - - # 22.1.3 (2026-08-05) @@ -581,24 +668,6 @@ - - -# 22.2.0-next.0 (2026-07-30) - -### @angular/cli - -| Commit | Type | Description | -| ---------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------- | -| [e148a8df93](https://github.com/angular/angular-cli/commit/e148a8df93b309dcd51698b4ce4f9343560edd8e) | fix | support npm 12 metadata array and error formats | - -### @angular/build - -| Commit | Type | Description | -| ---------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------------------------- | -| [6469b5f1f5](https://github.com/angular/angular-cli/commit/6469b5f1f5946415f49000f26bddd88b5647ac3d) | fix | rewrite paths from sandboxed execroots when running under Bazel | - - - # 22.1.0 (2026-07-29) diff --git a/MODULE.bazel b/MODULE.bazel index 470c5e258947..e7835ccd3294 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -6,49 +6,49 @@ module( bazel_dep(name = "platforms", version = "1.1.0") bazel_dep(name = "yq.bzl", version = "0.4.0") -bazel_dep(name = "rules_nodejs", version = "6.7.5") -bazel_dep(name = "aspect_rules_js", version = "3.4.1") +bazel_dep(name = "rules_nodejs", version = "6.7.7") +bazel_dep(name = "aspect_rules_js", version = "3.5.2") bazel_dep(name = "aspect_rules_ts", version = "3.10.1") bazel_dep(name = "rules_pkg", version = "1.3.0") -bazel_dep(name = "rules_cc", version = "0.2.22") -bazel_dep(name = "jq.bzl", version = "0.6.1") +bazel_dep(name = "rules_cc", version = "0.2.27") +bazel_dep(name = "jq.bzl", version = "0.7.1") bazel_dep(name = "bazel_lib", version = "3.7.2") bazel_dep(name = "bazel_skylib", version = "1.9.2") -bazel_dep(name = "aspect_rules_esbuild", version = "0.27.0") +bazel_dep(name = "aspect_rules_esbuild", version = "0.27.1") bazel_dep(name = "aspect_rules_jasmine", version = "2.0.4") bazel_dep(name = "rules_angular") git_override( module_name = "rules_angular", - commit = "5fa856469c642490a6e381a05d7f58f60fad1913", + commit = "ccb8ce17f3c9ee0b7a752b3b5b9aa0643c081857", remote = "https://github.com/angular/rules_angular.git", ) bazel_dep(name = "devinfra") git_override( module_name = "devinfra", - commit = "183403ae13b785698eaf13c819dda55b9fed430b", + commit = "9163c7b18bed28802e04d9c6f9da14e09ee7b79a", remote = "https://github.com/angular/dev-infra.git", ) bazel_dep(name = "rules_browsers") git_override( module_name = "rules_browsers", - commit = "c37398d63f5e990d618d02f4c6fb2fefe40f1a79", + commit = "8c45b59758ba9f6141511f1a167e442944b1353b", remote = "https://github.com/angular/rules_browsers.git", ) node = use_extension("@rules_nodejs//nodejs:extensions.bzl", "node") node.toolchain( node_repositories = { - "24.21.0-darwin_arm64": ("node-v24.21.0-darwin-arm64.tar.gz", "node-v24.21.0-darwin-arm64", "bed7eea5325e1108f32ce5228ddd6a5f0f08a499ee42aa7442aea583702f6057"), - "24.21.0-darwin_amd64": ("node-v24.21.0-darwin-x64.tar.gz", "node-v24.21.0-darwin-x64", "1462cb3b3046b815cf8ea436d3da450ec1a9f11dac7e5a46b0ada5305d7e8097"), - "24.21.0-linux_arm64": ("node-v24.21.0-linux-arm64.tar.xz", "node-v24.21.0-linux-arm64", "6ad1325edbdb5649c379b75a237147a666c95d4f9ae8d340fef2d1575d289ad2"), - "24.21.0-linux_ppc64le": ("node-v24.21.0-linux-ppc64le.tar.xz", "node-v24.21.0-linux-ppc64le", "1936fd64623a2f98d1fb31b456686d10c30e92639899cfefdefa8835d22adccd"), - "24.21.0-linux_s390x": ("node-v24.21.0-linux-s390x.tar.xz", "node-v24.21.0-linux-s390x", "2ef7e2ecbf7a6c2f3d08d106f6b2f279419c6dac89fe91b8cad193af7890082c"), - "24.21.0-linux_amd64": ("node-v24.21.0-linux-x64.tar.xz", "node-v24.21.0-linux-x64", "fd8e59d5a511510f6a298afb548f18c7d2b1be404d8b4a27d94fbe49f56cb2d6"), - "24.21.0-windows_amd64": ("node-v24.21.0-win-x64.zip", "node-v24.21.0-win-x64", "158f7685b44de51f6c0df1d153526cbcd3e1bc739a8dfc607721cef75de9e541"), + "24.22.2-darwin_arm64": ("node-v24.22.2-darwin-arm64.tar.gz", "node-v24.22.2-darwin-arm64", "aa9549349e47dffaa42dcf95d6e06ade8c4bdafc980979883b88767670df385a"), + "24.22.2-darwin_amd64": ("node-v24.22.2-darwin-x64.tar.gz", "node-v24.22.2-darwin-x64", "d5e336d588c45be0c37dbd52cc29895593009ca4997a77a1fd02815131ed0e52"), + "24.22.2-linux_arm64": ("node-v24.22.2-linux-arm64.tar.xz", "node-v24.22.2-linux-arm64", "eb187837a2230d4047161ac0be008584e16b46f726e9c9490ee35dc6b17d9ba8"), + "24.22.2-linux_ppc64le": ("node-v24.22.2-linux-ppc64le.tar.xz", "node-v24.22.2-linux-ppc64le", "5da1205ce97f9718fea9c73cce22b4bf59d7a5d1ed701059104c75ee069ac04b"), + "24.22.2-linux_s390x": ("node-v24.22.2-linux-s390x.tar.xz", "node-v24.22.2-linux-s390x", "66e2640ca1a4ae8dbaac89b47480e7d6d5d0737960dae29eb5043277f494bd88"), + "24.22.2-linux_amd64": ("node-v24.22.2-linux-x64.tar.xz", "node-v24.22.2-linux-x64", "48cc0e21e048790e54c0cf5749c2725005313d652651c40b7a21feb9697aaf75"), + "24.22.2-windows_amd64": ("node-v24.22.2-win-x64.zip", "node-v24.22.2-win-x64", "ca1bff5d8ead13c9f2ea404a176db46bd430704d5b5113734049fa365e7799e2"), }, - node_version = "24.21.0", + node_version = "24.22.2", ) use_repo( node, @@ -131,8 +131,8 @@ use_repo( pnpm = use_extension("@aspect_rules_js//npm:extensions.bzl", "pnpm") pnpm.pnpm( name = "pnpm", - pnpm_version = "12.3.4", - pnpm_version_integrity = "sha512-lhqkH7B32joEpEHZ+OFevAyW2o73ELLrZ7+e58sGEOq9SPH9hfUc/+c4RnhfoPh8VqOocqHYk/hEZ0G1zORUVw==", + pnpm_version = "12.16.1", + pnpm_version_integrity = "sha512-CR0d7nknV1Zhsl2rPCrjHK/BxU1rce1qZgDPDByxBDSkR+rhQBXxsj4ua+3u1535SpMuIWTSgyKA3OP7MvZW0Q==", ) use_repo(pnpm, "pnpm") diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 43e07b4b4f31..e822973982f4 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -10,6 +10,10 @@ "https://bcr.bazel.build/modules/abseil-cpp/20230802.1/MODULE.bazel": "fa92e2eb41a04df73cdabeec37107316f7e5272650f81d6cc096418fe647b915", "https://bcr.bazel.build/modules/abseil-cpp/20240116.1/MODULE.bazel": "37bcdb4440fbb61df6a1c296ae01b327f19e9bb521f9b8e26ec854b6f97309ed", "https://bcr.bazel.build/modules/abseil-cpp/20240116.1/source.json": "9be551b8d4e3ef76875c0d744b5d6a504a27e3ae67bc6b28f46415fd2d2957da", + "https://bcr.bazel.build/modules/apple_support/1.23.1/MODULE.bazel": "53763fed456a968cf919b3240427cf3a9d5481ec5466abc9d5dc51bc70087442", + "https://bcr.bazel.build/modules/apple_support/2.8.0/MODULE.bazel": "c45f5176057092afba0be6c48a9ea02101666802f8be536947e099e94757f8ed", + "https://bcr.bazel.build/modules/apple_support/2.9.1/MODULE.bazel": "fb209b83ed172af587419acb3340389cfe3260669e5f1c05e1ac3974aca614e0", + "https://bcr.bazel.build/modules/apple_support/2.9.1/source.json": "247d9f86d94c546533fb01e6e18b018486f9a6dff5faccae8838ef12e659b2a7", "https://bcr.bazel.build/modules/aspect_bazel_lib/2.0.0/MODULE.bazel": "e118477db5c49419a88d78ebc7a2c2cea9d49600fe0f490c1903324a2c16ecd9", "https://bcr.bazel.build/modules/aspect_bazel_lib/2.14.0/MODULE.bazel": "2b31ffcc9bdc8295b2167e07a757dbbc9ac8906e7028e5170a3708cecaac119f", "https://bcr.bazel.build/modules/aspect_bazel_lib/2.19.2/MODULE.bazel": "30dfabbfae0139b1f0036e01c201dd4c0167da3017f0b7ef3820d78e07622989", @@ -18,21 +22,22 @@ "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_rules_esbuild/0.27.0/MODULE.bazel": "877dafc0b925f8af19e8bc2abed04a757bb565c57c1866e8851ac4d15ed5e6d2", - "https://bcr.bazel.build/modules/aspect_rules_esbuild/0.27.0/source.json": "21f8738b3e62310ef43b7cef4284e1bafd69bd8e4e50251b71b20bbfed4372d8", + "https://bcr.bazel.build/modules/aspect_rules_esbuild/0.27.1/MODULE.bazel": "99c3978959edd9892e4b513831b218a13cc84a0215bfe1b972a1e3a771c4670e", + "https://bcr.bazel.build/modules/aspect_rules_esbuild/0.27.1/source.json": "20f515102cbcd0835d90bb3976b193eb58c2a0c534093c85cfd3bf6f06dba748", "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/3.4.0/MODULE.bazel": "88844ac411e1961f4574a92f3c5be5b20d1c6997778c6b88316c5c3b4b60e284", - "https://bcr.bazel.build/modules/aspect_rules_js/3.4.1/MODULE.bazel": "e46853c134b48bc84c9bb5c4a4c8ae792dcfd5277acac9d90c444d65fa43dd19", - "https://bcr.bazel.build/modules/aspect_rules_js/3.4.1/source.json": "b11f550b53d451800ebd0b4f38a048aea33fbfbd78fb5c77dca847f6b9b47a3b", + "https://bcr.bazel.build/modules/aspect_rules_js/3.5.2/MODULE.bazel": "9e8e4cc25b21a51cf9336aa7bd1a0d8c1c6b508b9f0ae663d617ac4223ebcdb9", + "https://bcr.bazel.build/modules/aspect_rules_js/3.5.2/source.json": "3d11af690a74823879b297ca0ae57c6e73a94ccd944a87fb1a82b1e53e6d8442", "https://bcr.bazel.build/modules/aspect_rules_ts/3.10.1/MODULE.bazel": "035205a7834b0ed9724ed3c4790e12d1c779ef2520d72496ab234e6307715e6c", "https://bcr.bazel.build/modules/aspect_rules_ts/3.10.1/source.json": "d42b6560206adb5524caad2abc40ae0b5b34478dd38184a9f6ea4a5fed848cd6", "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", "https://bcr.bazel.build/modules/aspect_tools_telemetry/0.4.2/MODULE.bazel": "f31aa84151d31e98cffd43eb7217ccff5ec52bdd5f2d10db8f053aeb23342eca", "https://bcr.bazel.build/modules/aspect_tools_telemetry/0.5.1/MODULE.bazel": "9d94e5c22c0019995c0a3216a6abb1717dc3f35acccf4e6267a55d6df38367aa", - "https://bcr.bazel.build/modules/aspect_tools_telemetry/0.5.1/source.json": "dbe0a75bf1f741b18c7b72dd4d205fa5a45c8c135fee15f7fdd1a2b50ba0fdde", + "https://bcr.bazel.build/modules/aspect_tools_telemetry/0.5.2/MODULE.bazel": "c715a5fb6b13a0086c061618f00d033a4ab6d76cbd1083e38d7ca953b5e547f4", + "https://bcr.bazel.build/modules/aspect_tools_telemetry/0.5.2/source.json": "4dd300d44767ad4860098b006dda614e67ab0409ae6ec6e133faad303fe9ede8", "https://bcr.bazel.build/modules/bazel_features/1.1.1/MODULE.bazel": "27b8c79ef57efe08efccbd9dd6ef70d61b4798320b8d3c134fd571f78963dbcd", "https://bcr.bazel.build/modules/bazel_features/1.11.0/MODULE.bazel": "f9382337dd5a474c3b7d334c2f83e50b6eaedc284253334cf823044a26de03e8", "https://bcr.bazel.build/modules/bazel_features/1.15.0/MODULE.bazel": "d38ff6e517149dc509406aca0db3ad1efdd890a85e049585b7234d04238e2a4d", @@ -40,6 +45,7 @@ "https://bcr.bazel.build/modules/bazel_features/1.18.0/MODULE.bazel": "1be0ae2557ab3a72a57aeb31b29be347bcdc5d2b1eb1e70f39e3851a7e97041a", "https://bcr.bazel.build/modules/bazel_features/1.19.0/MODULE.bazel": "59adcdf28230d220f0067b1f435b8537dd033bfff8db21335ef9217919c7fb58", "https://bcr.bazel.build/modules/bazel_features/1.21.0/MODULE.bazel": "675642261665d8eea09989aa3b8afb5c37627f1be178382c320d1b46afba5e3b", + "https://bcr.bazel.build/modules/bazel_features/1.27.0/MODULE.bazel": "621eeee06c4458a9121d1f104efb80f39d34deff4984e778359c60eaf1a8cb65", "https://bcr.bazel.build/modules/bazel_features/1.28.0/MODULE.bazel": "4b4200e6cbf8fa335b2c3f43e1d6ef3e240319c33d43d60cc0fbd4b87ece299d", "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", @@ -83,10 +89,12 @@ "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/hermetic_launcher/0.0.16/MODULE.bazel": "ac8a135156c67b45fff31ca11db0faced1d61890654b96d2c0ea6e8a532a3d9c", + "https://bcr.bazel.build/modules/hermetic_launcher/0.0.16/source.json": "1f96a028cec7ca86995f6ec6f50e410a235528d93216ad8144e98a7f8a4d204c", "https://bcr.bazel.build/modules/jq.bzl/0.1.0/MODULE.bazel": "2ce69b1af49952cd4121a9c3055faa679e748ce774c7f1fda9657f936cae902f", "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/jq.bzl/0.7.1/MODULE.bazel": "2dc4fd806df09b30aa7e0339f141a661f72df6af237f6db1fc4ca5c5045f1772", + "https://bcr.bazel.build/modules/jq.bzl/0.7.1/source.json": "0dbd7febb9361e34247c952e749f21f258b5123126248624c0d921c4592eac96", "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", @@ -100,6 +108,7 @@ "https://bcr.bazel.build/modules/platforms/0.0.6/MODULE.bazel": "ad6eeef431dc52aefd2d77ed20a4b353f8ebf0f4ecdd26a807d2da5aa8cd0615", "https://bcr.bazel.build/modules/platforms/0.0.7/MODULE.bazel": "72fd4a0ede9ee5c021f6a8dd92b503e089f46c227ba2813ff183b71616034814", "https://bcr.bazel.build/modules/platforms/0.0.8/MODULE.bazel": "9f142c03e348f6d263719f5074b21ef3adf0b139ee4c5133e2aa35664da9eb2d", + "https://bcr.bazel.build/modules/platforms/0.0.9/MODULE.bazel": "4a87a60c927b56ddd67db50c89acaa62f4ce2a1d2149ccb63ffd871d5ce29ebc", "https://bcr.bazel.build/modules/platforms/1.0.0/MODULE.bazel": "f05feb42b48f1b3c225e4ccf351f367be0371411a803198ec34a389fb22aa580", "https://bcr.bazel.build/modules/platforms/1.1.0/MODULE.bazel": "1c0c09f5bdcf4b3f924720d2478a3711cb39f4977019ca5988685e5b7e18b3d2", "https://bcr.bazel.build/modules/platforms/1.1.0/source.json": "fcf351c47596c939140ab0d333dfdd08ed1ea6ce33c2fe70c12493a301cf1344", @@ -131,8 +140,10 @@ "https://bcr.bazel.build/modules/rules_cc/0.1.1/MODULE.bazel": "2f0222a6f229f0bf44cd711dc13c858dad98c62d52bd51d8fc3a764a83125513", "https://bcr.bazel.build/modules/rules_cc/0.1.5/MODULE.bazel": "88dfc9361e8b5ae1008ac38f7cdfd45ad738e4fa676a3ad67d19204f045a1fd8", "https://bcr.bazel.build/modules/rules_cc/0.2.16/MODULE.bazel": "9242fa89f950c6ef7702801ab53922e99c69b02310c39fb6e62b2bd30df2a1d4", - "https://bcr.bazel.build/modules/rules_cc/0.2.22/MODULE.bazel": "94df4328edef9e44d38de5e73b037cd348e75e7ae55f4e21bf07878c41a31ebb", - "https://bcr.bazel.build/modules/rules_cc/0.2.22/source.json": "b2d6d6f9c332ce269ad75b89c6f3168d809a66173c9040210fb9bcc733ab42fa", + "https://bcr.bazel.build/modules/rules_cc/0.2.20/MODULE.bazel": "f5c07bce5ddcb99be21a0812ff5aadb439e688b7449c6542152363b2fd859c1a", + "https://bcr.bazel.build/modules/rules_cc/0.2.25/MODULE.bazel": "4a3d4f3606d3b3190be495dbc497acca552807d1d5540661ef0d1658472882e3", + "https://bcr.bazel.build/modules/rules_cc/0.2.27/MODULE.bazel": "99483699eeba3ec1159e938d724134762e748e8dc16dd0d8cbcc3d01a3d19440", + "https://bcr.bazel.build/modules/rules_cc/0.2.27/source.json": "a1e5e45c8a56ec19fadf109ef34abb06979982badf55a504d3f82a1258d83e3f", "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", @@ -169,8 +180,8 @@ "https://bcr.bazel.build/modules/rules_nodejs/6.2.0/MODULE.bazel": "ec27907f55eb34705adb4e8257952162a2d4c3ed0f0b3b4c3c1aad1fac7be35e", "https://bcr.bazel.build/modules/rules_nodejs/6.5.0/MODULE.bazel": "546d0cf79f36f9f6e080816045f97234b071c205f4542e3351bd4424282a8810", "https://bcr.bazel.build/modules/rules_nodejs/6.7.3/MODULE.bazel": "c22a48b2a0dbf05a9dc5f83837bbc24c226c1f6e618de3c3a610044c9f336056", - "https://bcr.bazel.build/modules/rules_nodejs/6.7.5/MODULE.bazel": "97e6794043821d23c013baa4a50fd1c599f2e6ae92b06e2c5f1cd7074fd83e7c", - "https://bcr.bazel.build/modules/rules_nodejs/6.7.5/source.json": "d60ee5a76258b1c8f99545ed24172b44d43ba64ca1a2dfc04371ef203df19fdf", + "https://bcr.bazel.build/modules/rules_nodejs/6.7.7/MODULE.bazel": "e80c95eebba3e38fa28ea0553ec580e4bffbbe8d0e8fa892457fa0e6b616f3d8", + "https://bcr.bazel.build/modules/rules_nodejs/6.7.7/source.json": "60081c2448d70db3c5c0e75f55c0a55a22b2144646c21977c46c4986dacacdb6", "https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc", "https://bcr.bazel.build/modules/rules_pkg/1.0.1/MODULE.bazel": "5b1df97dbc29623bccdf2b0dcd0f5cb08e2f2c9050aab1092fd39a41e82686ff", "https://bcr.bazel.build/modules/rules_pkg/1.3.0/MODULE.bazel": "ae0bdefbacc990c91f843206c90cf0f4be620639a5bf22119043599ba86d51a3", @@ -203,8 +214,8 @@ "https://bcr.bazel.build/modules/stardoc/0.7.2/MODULE.bazel": "fc152419aa2ea0f51c29583fab1e8c99ddefd5b3778421845606ee628629e0e5", "https://bcr.bazel.build/modules/stardoc/0.7.2/source.json": "58b029e5e901d6802967754adf0a9056747e8176f017cfe3607c0851f4d42216", "https://bcr.bazel.build/modules/tar.bzl/0.10.4/MODULE.bazel": "e8f9ff79199e8d9eaad7f1b0a77ad74b30bb82d794b87d8ca942bead5de83ae9", - "https://bcr.bazel.build/modules/tar.bzl/0.10.8/MODULE.bazel": "443884cabe241f640cfef256b1de2ccb116752895532900a4be9500e1124323f", - "https://bcr.bazel.build/modules/tar.bzl/0.10.8/source.json": "4173be64b38e471d92d2eb139a6496311de6de75e710f04edce78c43122c5419", + "https://bcr.bazel.build/modules/tar.bzl/0.10.9/MODULE.bazel": "4636f5f6a7c34d3d0653634ed95a34560426d548c5301c6c5924c885ef737b46", + "https://bcr.bazel.build/modules/tar.bzl/0.10.9/source.json": "30a5cf0a8281adce53ab1c5a4291e88b2c161e2df1feb6cba4ee50556f1748d7", "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/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43", @@ -222,8 +233,8 @@ "moduleExtensions": { "@@aspect_rules_esbuild+//esbuild:extensions.bzl%esbuild": { "general": { - "bzlTransitiveDigest": "ivnb7fuZRAghsUscNSqk/cyy9pTpUKwbi8xOKhgxNbo=", - "usagesDigest": "LZ71sshnfqI8R/HeWwBTwawxIa7KnitayBl2hYrqPo4=", + "bzlTransitiveDigest": "kN5vnPHXKikRq1D9lQHLXMiw9fIFCna1djvCqmKxATE=", + "usagesDigest": "ZqBbSnzAi8ZyBL3PXnAGtDMIdC2pcuieJWMY3/94lvA=", "recordedInputs": [ "REPO_MAPPING:aspect_rules_esbuild+,aspect_rules_js aspect_rules_js+", "REPO_MAPPING:aspect_rules_esbuild+,aspect_tools_telemetry_report aspect_tools_telemetry++telemetry+aspect_tools_telemetry_report", @@ -234,6 +245,7 @@ "REPO_MAPPING:aspect_rules_js+,bazel_lib bazel_lib+", "REPO_MAPPING:aspect_rules_js+,bazel_skylib bazel_skylib+", "REPO_MAPPING:aspect_rules_js+,bazel_tools bazel_tools", + "REPO_MAPPING:aspect_rules_js+,hermetic_launcher hermetic_launcher+", "REPO_MAPPING:aspect_rules_js+,protobuf protobuf+", "REPO_MAPPING:aspect_rules_js+,tar.bzl tar.bzl+", "REPO_MAPPING:bazel_features+,bazel_features_globals bazel_features++version_extension+bazel_features_globals", @@ -354,8 +366,8 @@ }, "@@aspect_tools_telemetry+//:extension.bzl%telemetry": { "general": { - "bzlTransitiveDigest": "zFgbaCUuPzH6bIE7CBHBVCqjWSJ78/WNXisdzXaKSnU=", - "usagesDigest": "2cLMn8ZcqY/6j/zH70TrPob+ENshTw9h48kUHxn1cUM=", + "bzlTransitiveDigest": "ihzLOoAnQP6Y5iSYOhEjvb6uxEbA6ZgH8Qikau2lGRU=", + "usagesDigest": "kuPNffSwgk1i+sotywO3bLAg6FenO9tU6ONemrSgMdk=", "recordedInputs": [ "REPO_MAPPING:aspect_tools_telemetry+,bazel_lib bazel_lib+", "REPO_MAPPING:aspect_tools_telemetry+,bazel_skylib bazel_skylib+", @@ -366,13 +378,13 @@ "repoRuleId": "@@aspect_tools_telemetry+//:extension.bzl%tel_repository", "attributes": { "deps": { - "aspect_rules_js": "3.4.1", + "aspect_rules_js": "3.5.2", "aspect_rules_ts": "3.10.1", - "aspect_rules_esbuild": "0.27.0", + "aspect_rules_esbuild": "0.27.1", "aspect_rules_jasmine": "2.0.4", - "aspect_tools_telemetry": "0.5.1" + "aspect_tools_telemetry": "0.5.2" }, - "last_notice": 0 + "last_notice": 3 } } }, @@ -433,16 +445,16 @@ }, "@@rules_browsers+//browsers:extensions.bzl%browsers": { "general": { - "bzlTransitiveDigest": "eNfcpVF2YJFb8xQfN64Y9PQgMrXYK0ju3uglArt8IO8=", + "bzlTransitiveDigest": "QftNQqECh07sCsgrQDVfPbg8MeVYnYMK+rjB/pT2308=", "usagesDigest": "FmXYJVoVJlnfUU8x8gObSvu4qWcco/9Faw61aC/wBF0=", "recordedInputs": [], "generatedRepoSpecs": { "rules_browsers_chrome_linux": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "ad2e73e1e42c0831930dfd02d4aa8653a5f23f60b0376a5d76ddf8ecd7a41e4b", + "sha256": "a644afcc9103de3c487aa0a9d83518d6ccced427115d7d2517d8f1f9defdc39a", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/155.0.8043.0/linux64/chrome-headless-shell-linux64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/159.0.8138.0/linux64/chrome-headless-shell-linux64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-linux64/chrome-headless-shell" @@ -458,9 +470,9 @@ "rules_browsers_chrome_mac": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "d66b730ed9760ae88b83aca1fa89351ac027ede430be4f5283fabd156198762d", + "sha256": "c996dae9656475ad7da57cce7da6c7a8b4520e7e1de7b018535865363e3bcd05", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/155.0.8043.0/mac-x64/chrome-headless-shell-mac-x64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/159.0.8138.0/mac-x64/chrome-headless-shell-mac-x64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-mac-x64/chrome-headless-shell" @@ -476,9 +488,9 @@ "rules_browsers_chrome_mac_arm": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "44c784c59af60ef62233b6100820ebb8b158e7d105b96c684818f007d6576848", + "sha256": "2a072f54e302847cf118ae788303eae95ba59f0613f6fc72dece62075ed7d395", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/155.0.8043.0/mac-arm64/chrome-headless-shell-mac-arm64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/159.0.8138.0/mac-arm64/chrome-headless-shell-mac-arm64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-mac-arm64/chrome-headless-shell" @@ -494,9 +506,9 @@ "rules_browsers_chrome_win64": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "996537a6c3d31bb5c75ef328af5d4827b5f92c4a36ff7ea250e437eadf46eac0", + "sha256": "726e9367d2836da0f26600bb7eb02fac5012ffd30536f0f187ac0f40edcf7e8e", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/155.0.8043.0/win64/chrome-headless-shell-win64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/159.0.8138.0/win64/chrome-headless-shell-win64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-win64/chrome-headless-shell.exe" @@ -512,9 +524,9 @@ "rules_browsers_chromedriver_linux": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "f1db8caff52251dec46117a2f518a74cd1e4a2abadcbecc0d5bdd49e42175afa", + "sha256": "5f3756c1627014ff5f6e5e99d7d66419b4ee076805e8ea5496163eca3f869602", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/155.0.8043.0/linux64/chromedriver-linux64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/159.0.8138.0/linux64/chromedriver-linux64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-linux64/chromedriver" @@ -528,9 +540,9 @@ "rules_browsers_chromedriver_mac": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "5062675bc868f3f6a1e4850cab72b736a5c17f98f01d610736b8d0a6e009bf54", + "sha256": "337da1f4cd25512e83bc38af8a154903b002012eda5c90b64100a57ad334efcc", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/155.0.8043.0/mac-x64/chromedriver-mac-x64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/159.0.8138.0/mac-x64/chromedriver-mac-x64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-mac-x64/chromedriver" @@ -544,9 +556,9 @@ "rules_browsers_chromedriver_mac_arm": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "04f07a2a13e969f120dbea61eef291dc4e20617a6d424dec20e90f903da0263b", + "sha256": "3c089e69361dbb4e39a343799f9d01c2b28beedb5cc5da668bea137f333faaa0", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/155.0.8043.0/mac-arm64/chromedriver-mac-arm64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/159.0.8138.0/mac-arm64/chromedriver-mac-arm64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-mac-arm64/chromedriver" @@ -560,9 +572,9 @@ "rules_browsers_chromedriver_win64": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "7701074890112ed3b780af26104cb9f57ce68e229ca3076bfade6a1af93730d7", + "sha256": "aaf61ca97f303e043e01a47872ca48a1d6bb4b7b2ee672fde970b6b9f1dd2b5e", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/155.0.8043.0/win64/chromedriver-win64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/159.0.8138.0/win64/chromedriver-win64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-win64/chromedriver.exe" @@ -576,9 +588,9 @@ "rules_browsers_firefox_linux": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "fd9ec3f5f113d0825ca0bd1ab3c0756fbc40241034eefce6743be953bcca7473", + "sha256": "54536fcd120af484d4c56272a5a1cf4af57b9c713d1a3b1e775da192dd541fcd", "urls": [ - "https://archive.mozilla.org/pub/firefox/releases/155.0/linux-x86_64/en-US/firefox-155.0.tar.xz" + "https://archive.mozilla.org/pub/firefox/releases/159.0/linux-x86_64/en-US/firefox-159.0.tar.xz" ], "named_files": { "FIREFOX": "firefox/firefox" @@ -592,9 +604,9 @@ "rules_browsers_firefox_mac": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "3ae135f2023cf0c6cbce3bb757e06564ff8148b1266f682b8eccff0993a1a9f5", + "sha256": "0772404ae6e068d7cc03cecf4bb06a855f10287a77b624ffa41c6d092a64ea13", "urls": [ - "https://archive.mozilla.org/pub/firefox/releases/155.0/mac/en-US/Firefox%20155.0.dmg" + "https://archive.mozilla.org/pub/firefox/releases/159.0/mac/en-US/Firefox%20159.0.dmg" ], "named_files": { "FIREFOX": "Firefox.app/Contents/MacOS/firefox" @@ -608,9 +620,9 @@ "rules_browsers_firefox_mac_arm": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "3ae135f2023cf0c6cbce3bb757e06564ff8148b1266f682b8eccff0993a1a9f5", + "sha256": "0772404ae6e068d7cc03cecf4bb06a855f10287a77b624ffa41c6d092a64ea13", "urls": [ - "https://archive.mozilla.org/pub/firefox/releases/155.0/mac/en-US/Firefox%20155.0.dmg" + "https://archive.mozilla.org/pub/firefox/releases/159.0/mac/en-US/Firefox%20159.0.dmg" ], "named_files": { "FIREFOX": "Firefox.app/Contents/MacOS/firefox" @@ -624,9 +636,9 @@ "rules_browsers_firefox_win64": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "2718d4cc4b2cf089aa8ac370111652bc763838e1d2ed6d635d465fc17ab6327c", + "sha256": "8776887b79925abbdd407fcdfe257d8382b54e24be52a6466426b95a804d6790", "urls": [ - "https://archive.mozilla.org/pub/firefox/releases/155.0/win64/en-US/Firefox%20Setup%20155.0.exe" + "https://archive.mozilla.org/pub/firefox/releases/159.0/win64/en-US/Firefox%20Setup%20159.0.exe" ], "named_files": { "FIREFOX": "core/firefox.exe" @@ -974,7 +986,7 @@ "@@yq.bzl+//yq:extensions.bzl%yq": { "general": { "bzlTransitiveDigest": "lH0oIGWeh0sI6/jlDMTxYo34YKkvNfvwdiMIhfM532I=", - "usagesDigest": "9q9u3esoCq5ywKUTsbBWS8sgD0xhtCRDQhZ6Dsn/qvE=", + "usagesDigest": "bATjzBqZU06dkIkgLewDSi7XlnVuNl3JaLasbWBlvcM=", "recordedInputs": [ "REPO_MAPPING:yq.bzl+,bazel_lib bazel_lib+" ], @@ -1057,8 +1069,11 @@ } }, "facts": { + "@@aspect_rules_js+//npm:extensions.bzl%pnpm": { + "exe:12.16.1": "{\"darwin-arm64\":\"sha512-pVbmIIbhixiLvADLu1WA3TaW8FZy/D72R1De27WbbFx8/2mxvnsTyFVm4fO9kjpjMY7RzJd48CiQ96p8fO3ebQ==\",\"darwin-x64\":\"sha512-xZvQBFqcZjO7vFKTK3XsJpqY6lnBL9EWSLCzVUPq3kZ94+D96gwJCa76xxGNK8Cj32f4eeM91Qg+yNRR4sRpDw==\",\"linux-arm64\":\"sha512-JaRd5gNxwdNGBBkrZFt8bknrK4YmHVJBW0JMhUQ0fJ0dEYp6C2GT9ExaCqOO8EwYEyqM+jpKgJIK+8WFaJy3ew==\",\"linux-arm64-musl\":\"sha512-BJ3mOmcmQgcUo92Ee/WfEOt1pRiv3y2MMAkhEiYHd85UiPpHTfFhv+SpCbALmfExzXk3UlaRtMYwHlkQymc4VA==\",\"linux-x64\":\"sha512-RK//8ZLcXGW8A2k8bQOXZDBN1Qu92zN4dYnG1bzj1zoQ1fkZ6jNzZ1AvXtsfGVma795CJtvoaF5bLXf4l/FIUw==\",\"linux-x64-musl\":\"sha512-PM6ccHCOe/O9SsTflTJTYWfwogJZa6EmUvpnwZgiPguJBddh20wDQKgxUPXf48rDsPm9vMsIij0uHswwwbXL8g==\",\"win32-arm64\":\"sha512-Ox3kNNVxtGw6pK7SVejmeOUgHhUTZgAM7NQQ6cU7frPw3ix9+j7d2MGbRg3fyEFAaKWq8ZAZLTQGcDyLnAu+qA==\",\"win32-x64\":\"sha512-k+FhRJ0ttphFoFIVB1Sk4v76YJAulafmA/Ly57cysesUhhIzVlApeOShUz0jXubKx317TThlEfpQrukldnqORA==\"}" + }, "@@aspect_tools_telemetry+//:extension.bzl%telemetry": { - "notice_version": "2" + "notice_version": "3" } }, "factsVersions": {} diff --git a/SECURITY.md b/SECURITY.md index 0361308689ab..5e6fbc1b4b54 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,3 +1,44 @@ Angular is part of Google [Open Source Software Vulnerability Reward Program](https://bughunters.google.com/about/rules/6521337925468160/google-open-source-software-vulnerability-reward-program-rules). For vulnerabilities in Angular, please submit your report [here](https://bughunters.google.com/report). For more information, check out [Angular's security policy](https://angular.dev/best-practices/security). + +## Policies + +The following defines some team policies around what does and does not constitute a security vulnerability. + +- Prototype pollution is itself a DoS vulnerability. + - An attacker could pollute any symbol into the wrong type and cause an error, nothing we can do will prevent that. + - Therefore we don't care about any DoS vulnerability which relies on prototype pollution as a precondition. +- We trust the user's source code and build-time inputs. + - "A malicious repository can execute untrusted code" is not a viable attack vector. + - A malicious repository could always rebind `node_modules/.bin/ng` to do something malicious, nothing we do can prevent that. + - We assume it is always unsafe to run an untrusted repository outside of a sandbox. + - Build-time configuration (`angular.json`, `routesFile`, environment variables) and values returned by developer-authored build-time functions (such as `getPrerenderParams()`) are considered trusted inputs. Passing unvalidated, untrusted data from an external source (e.g., a CMS or database) into build-time route generation or build configuration is an application-level input validation defect, not a vulnerability in Angular. +- DoS attacks which break only the attacker's client are not security issues. + - Exception: DoS attacks which waste server resources significantly beyond the cost of the attacker's request may be security issues. +- Memory leaks are considered general bugs, not DoS vulnerabilities. + - While any memory leak is technically a DoS vulnerability in SSR, these are generally low enough impact to not be considered security issues. +- Our public API contract is defined by our TS types, any issue which requires breaking those types (ex. via a cast to any) falls outside Angular's support. + - Ex. It may be possible to leak user state by attaching it to some global data structure in SSR, but we do not consider this to be a valid vulnerability if you have to escape TS types to do it. + +## Invariants + +The following are invariants about Angular's technical infrastructure which limit some potential attack vectors. These statements are asserted by humans, not proven in any formal means. However, any security report should assume them to be true unless and until it can conclusively prove them to be false in an attack. If one of these statements invalidates a security report, that report bears the burden of conclusively demonstrating the statement to be false in its reproduction. + +- Zones don't leak across SSR requests (except for the root) + - Every request gets its own Zone, so data stored on the Zone is unique to that user, no intrinsic risk of leaking user data from one request to an attacker's request. +- Injectors are not shared between applications. + - SSR always creates a new ApplicationRef and root services, no intrinsic risk of leaking user data from one request to an attacker's request. + - Exception: Module-scoped data is shared and is a potential vector for data leakage. +- `ngDevMode` / `ngServerMode` are set at compile time in production deployments and cannot be manipulated by attackers. + +## Prioritization Guide + +Angular is not a product, and almost no vulnerability is an exploit in and of itself, given there is nothing to compromise. Angular can only be exploited through a real deployment of a specific application. The vast majority of potential issues do not affect the default `ng new` app, and require additional steps of varying use/misuse of the framework before introducing a vulnerability on that real application. This goes beyond just an attacker finding the right sequence of characters to cause an exploit, and requires a well-intentioned developer to make a legitimate mistake introducing the vulnerability in the first place. Therefore we need to examine prioritization through the lens of how likely a developer is to make that mistake and the severity of what happens when they do. + +- **High:** A vulnerability impacts ~all users of a major feature in common usage such as SSR, hydration, templating, or routing (ex. SSRF via a malicious `Host` header affects all SSR + `HttpClient` users, which is a fairly common use case). +- **Medium:** A vulnerability impacts users interacting with public APIs in their reasonable usage. +- **Low:** A vulnerability impacts users interacting with public APIs misused in an unintended or unreasonable way (ex. vulnerability from unsanitized user input polluting the `APP_ID` value, which should never be user writable). +- **None:** A vulnerability impacts users of private APIs or explicitly unsupported use cases. + +Experimental / developer preview APIs _are not_ exempted from these priorities. While we make no hard guarantees about these APIs publicly, a vulnerability in such features should be raised to our attention and addressed before reaching stability. diff --git a/constants.bzl b/constants.bzl index 143ee7243735..f07e0955fe36 100644 --- a/constants.bzl +++ b/constants.bzl @@ -3,10 +3,10 @@ RELEASE_ENGINES_NODE = "^22.22.3 || ^24.15.0 || >=26.0.0" RELEASE_ENGINES_NPM = "^6.11.0 || ^7.5.6 || >=8.0.0" RELEASE_ENGINES_YARN = ">= 1.13.0" -NG_PACKAGR_VERSION = "^22.2.0-next.0" -ANGULAR_FW_VERSION = "^22.2.0-next.0" -ANGULAR_FW_PEER_DEP = "^22.0.0 || ^22.2.0-next.0" -NG_PACKAGR_PEER_DEP = "^22.0.0 || ^22.2.0-next.0" +NG_PACKAGR_VERSION = "^22.2.0" +ANGULAR_FW_VERSION = "^22.2.0" +ANGULAR_FW_PEER_DEP = "^22.0.0" +NG_PACKAGR_PEER_DEP = "^22.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 35b07adf1e89..ddb8341e662b 100644 --- a/docs/DEVELOPER.md +++ b/docs/DEVELOPER.md @@ -7,9 +7,9 @@ To get started locally, follow these instructions: 1. If you haven't done it already, [make a fork of this repo](https://github.com/angular/angular-cli/fork). 2. If you are on Windows, see [the extra steps needed for contributing on Windows](#windows) 3. Clone to your local computer using `git`. -4. Make sure that you have Node `v20.19.0` or higher installed. See instructions [here](https://nodejs.org/en/download/). +4. Make sure that you have Node `v22.22.3` or higher installed (see `engines` in `package.json`). See instructions [here](https://nodejs.org/en/download/). 5. Install `pnpm`. - - You can install pnpm by running `npm i -g pnpm@9`. + - You can install pnpm by running `npm i -g pnpm@12`. - See detailed instructions [here](https://pnpm.io/installation). 6. Run `pnpm install` from the root of your clone of this project to install dependencies. @@ -78,7 +78,7 @@ There are two different test suites which can be run locally: ### Unit tests - Run all tests: `pnpm bazel test //packages/...` -- Run a subset of the tests, use the full Bazel target example: `pnpm bazel test //packages/schematics/angular:angular_test` +- Run a subset of the tests, use the full Bazel target example: `pnpm bazel test //packages/schematics/angular:test` - For a complete list of test targets use the following Bazel query: `pnpm bazel query "tests(//packages/...)"` When debugging a specific test, change `describe()` or `it()` to `fdescribe()` @@ -166,7 +166,7 @@ You can use the Chrome Devtools to process it. To do so: Adding a package to this repository means running two separate commands: -1. `schematics devkit:package PACKAGE_NAME`. This will update the `.monorepo` file, and create the +1. `schematics devkit:package PACKAGE_NAME`. This will update the `.monorepo.json` file, and create the base files for the new package (package.json, src/index, etc). 1. `pnpm admin templates`. This will update the README and all other template files that might have changed when adding a new package. diff --git a/docs/process/bazel.md b/docs/process/bazel.md index 86542047745e..458d634ba9b6 100644 --- a/docs/process/bazel.md +++ b/docs/process/bazel.md @@ -65,7 +65,7 @@ the reruns of tests that have been marked as `flaky`. The `.bazelrc` includes a config for running tests with remote debugging enabled: ```sh -pnpm bazel test --config=debug //packages/angular/cli:angular-cli_test +pnpm bazel test --config=debug //packages/angular/cli:test # Also disable reruns of failing tests that were marked as flaky: -pnpm bazel test --config=debug --config=no-sharding //packages/angular/cli:angular-cli_test +pnpm bazel test --config=debug --config=no-sharding //packages/angular/cli:test ``` diff --git a/goldens/public-api/angular_devkit/architect/index.api.md b/goldens/public-api/angular_devkit/architect/index.api.md index 747b7010f580..4d486e84e5aa 100644 --- a/goldens/public-api/angular_devkit/architect/index.api.md +++ b/goldens/public-api/angular_devkit/architect/index.api.md @@ -215,7 +215,7 @@ interface JobHandlerContext>; // (undocumented) - readonly scheduler: Scheduler; + readonly scheduler: Scheduler_2; } // @public (undocumented) @@ -399,7 +399,7 @@ declare namespace jobs { Job, ScheduleJobOptions, Registry, - Scheduler, + Scheduler_2 as Scheduler, createJobHandler, createJobFactory, createLoggerJob, @@ -460,7 +460,7 @@ export interface ScheduleOptions { } // @public -interface Scheduler { +interface Scheduler_2 { getDescription(name: JobName): Observable; has(name: JobName): Observable; pause(): () => void; @@ -500,7 +500,7 @@ class SimpleJobRegistry implements Scheduler { +class SimpleScheduler implements Scheduler_2 { constructor(_jobRegistry: Registry, _schemaRegistry?: schema.SchemaRegistry); getDescription(name: JobName): Observable; has(name: JobName): Observable; diff --git a/modules/testing/builder/package.json b/modules/testing/builder/package.json index 3e0dc743f7ea..6d685a79bbf4 100644 --- a/modules/testing/builder/package.json +++ b/modules/testing/builder/package.json @@ -8,7 +8,7 @@ "browser-sync": "3.0.4", "istanbul-lib-instrument": "6.0.3", "jsdom": "30.0.1", - "ng-packagr": "22.2.0-next.5", + "ng-packagr": "22.2.5", "rxjs": "7.8.2", "vitest": "5.0.1" } diff --git a/modules/testing/builder/projects/hello-world-lib/projects/lib/package.json b/modules/testing/builder/projects/hello-world-lib/projects/lib/package.json index c8105b2c16b4..eb52eedada4e 100644 --- a/modules/testing/builder/projects/hello-world-lib/projects/lib/package.json +++ b/modules/testing/builder/projects/hello-world-lib/projects/lib/package.json @@ -2,7 +2,7 @@ "name": "lib", "version": "0.0.1", "peerDependencies": { - "@angular/common": "^22.2.0-next", - "@angular/core": "^22.2.0-next" + "@angular/common": "^22.2.0", + "@angular/core": "^22.2.0" } } \ No newline at end of file diff --git a/modules/testing/builder/src/builder-harness.ts b/modules/testing/builder/src/builder-harness.ts index 67b5f760d148..570939cecd7f 100644 --- a/modules/testing/builder/src/builder-harness.ts +++ b/modules/testing/builder/src/builder-harness.ts @@ -111,7 +111,7 @@ export class BuilderHarness { } } - private resolvePath(path: string): string { + resolvePath(path: string): string { return join(getSystemPath(this.host.root()), path); } diff --git a/package.json b/package.json index 69fd5f4f7f42..8d925814a101 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@angular/devkit-repo", - "version": "22.2.0-next.7", + "version": "22.2.5", "private": true, "description": "Software Development Kit for Angular", "keywords": [ @@ -15,6 +15,7 @@ "bazel": "bazelisk", "test": "bazel test //packages/...", "build": "pnpm --silent admin build", + "benchmark": "node --no-warnings=ExperimentalWarning --experimental-transform-types --expose-gc ./scripts/devkit-admin.mts benchmark", "build-schema": "bazel build //... --build_tag_filters schema --symlink_prefix dist-schema/", "lint": "eslint --cache --max-warnings=0", "templates": "pnpm --silent admin templates", @@ -28,12 +29,12 @@ "type": "git", "url": "git+https://github.com/angular/angular-cli.git" }, - "packageManager": "pnpm@12.4.2", + "packageManager": "pnpm@12.16.1", "engines": { "node": "^22.22.3 || ^24.15.0 || >=26.0.0", "npm": "Please use pnpm instead of NPM to install dependencies", "yarn": "Please use pnpm instead of Yarn to install dependencies", - "pnpm": "12.4.2" + "pnpm": "12.16.1" }, "author": "Angular Authors", "license": "MIT", @@ -42,23 +43,23 @@ }, "homepage": "https://github.com/angular/angular-cli", "dependencies": { - "@angular/compiler-cli": "22.2.0-next.5", + "@angular/compiler-cli": "22.2.4", "typescript": "6.0.3" }, "devDependencies": { - "@angular/animations": "22.2.0-next.5", - "@angular/cdk": "22.2.0-next.4", - "@angular/common": "22.2.0-next.5", - "@angular/compiler": "22.2.0-next.5", - "@angular/core": "22.2.0-next.5", - "@angular/forms": "22.2.0-next.5", - "@angular/localize": "22.2.0-next.5", - "@angular/material": "22.2.0-next.4", - "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#c3d7ed184d71d390d3eacff85f4b2b3f16b82660", - "@angular/platform-browser": "22.2.0-next.5", - "@angular/platform-server": "22.2.0-next.5", - "@angular/router": "22.2.0-next.5", - "@angular/service-worker": "22.2.0-next.5", + "@angular/animations": "22.2.4", + "@angular/cdk": "22.2.5", + "@angular/common": "22.2.4", + "@angular/compiler": "22.2.4", + "@angular/core": "22.2.4", + "@angular/forms": "22.2.4", + "@angular/localize": "22.2.4", + "@angular/material": "22.2.5", + "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#316b8f89d5da8b8e3b58e646581c31b19c229205", + "@angular/platform-browser": "22.2.4", + "@angular/platform-server": "22.2.4", + "@angular/router": "22.2.4", + "@angular/service-worker": "22.2.4", "@babel/core": "8.0.5", "@bazel/bazelisk": "1.28.1", "@bazel/buildifier": "8.2.1", @@ -126,7 +127,7 @@ "semver": "7.8.5", "source-map-support": "0.5.21", "tslib": "2.8.1", - "undici": "8.10.2", + "undici": "8.12.3", "verdaccio": "6.10.3", "verdaccio-auth-memory": "^13.0.0", "zone.js": "^0.16.0" diff --git a/packages/angular/build/BUILD.bazel b/packages/angular/build/BUILD.bazel index 9a4de3b5aa64..b8432b0d8f36 100644 --- a/packages/angular/build/BUILD.bazel +++ b/packages/angular/build/BUILD.bazel @@ -146,8 +146,10 @@ ts_project( ":build", ":node_modules/@angular-devkit/core", ":node_modules/@babel/core", + ":node_modules/@parcel/watcher", ":node_modules/oxc-parser", "//:node_modules/@angular/compiler-cli", + "//:node_modules/@angular/router", "//:node_modules/@types/jasmine", "//:node_modules/esbuild", "//:node_modules/prettier", @@ -290,7 +292,6 @@ jasmine_test( name = "application_integration_tests", size = "medium", data = [":application_integration_test_lib"], - flaky = True, shard_count = 25, ) @@ -302,7 +303,6 @@ jasmine_test( # Force IPv4 to resolve RBE resolution issues "NODE_OPTIONS": "--dns-result-order=ipv4first", }, - flaky = True, shard_count = 10, ) @@ -315,7 +315,6 @@ jasmine_test( # or standardize to avoid complex configuration like this! "PUPPETEER_DOWNLOAD_PATH": "../../../node_modules/puppeteer/downloads", }, - flaky = True, shard_count = 10, ) @@ -323,7 +322,6 @@ jasmine_test( name = "unit-test_integration_tests", size = "medium", data = [":unit-test_integration_test_lib"], - flaky = True, shard_count = 5, ) diff --git a/packages/angular/build/package.json b/packages/angular/build/package.json index 25d640c7619f..9088949b38ad 100644 --- a/packages/angular/build/package.json +++ b/packages/angular/build/package.json @@ -33,20 +33,21 @@ "listr2": "11.1.0", "magic-string": "1.4.1", "mrmime": "2.0.1", - "oxc-parser": "0.150.0", + "oxc-parser": "0.156.0", "parse5-html-rewriting-stream": "8.0.1", "picomatch": "4.0.7", "piscina": "5.3.2", - "rolldown": "1.2.8", + "rolldown": "1.2.16", "sass": "1.104.1", "sass-embedded": "1.104.1", "semver": "7.8.5", "source-map-support": "0.5.21", "tinyglobby": "0.2.17", - "vite": "8.3.0", + "vite": "8.3.5", "xxhash-wasm": "1.1.0" }, "optionalDependencies": { + "@oxc-parser/binding-wasm32-wasi": "0.156.0", "lmdb": "3.5.6" }, "devDependencies": { @@ -57,7 +58,7 @@ "istanbul-lib-instrument": "6.0.3", "jsdom": "30.0.1", "less": "4.9.1", - "ng-packagr": "22.2.0-next.5", + "ng-packagr": "22.2.5", "postcss": "8.5.28", "rollup": "4.63.3", "rxjs": "7.8.2", diff --git a/packages/angular/build/src/builders/application/build-action.ts b/packages/angular/build/src/builders/application/build-action.ts index edd0ae7d22f0..025e3aba7dcc 100644 --- a/packages/angular/build/src/builders/application/build-action.ts +++ b/packages/angular/build/src/builders/application/build-action.ts @@ -7,8 +7,6 @@ */ import { BuilderContext } from '@angular-devkit/architect'; -import { existsSync } from 'node:fs'; -import path from 'node:path'; import { BuildOutputAsset, ExecutionResult, @@ -20,11 +18,9 @@ import { shutdownSassWorkerPool, } from '../../tools/esbuild/stylesheets/sass-language'; import { logMessages, withNoProgress, withSpinner } from '../../tools/esbuild/utils'; -import { ChangedFiles } from '../../tools/esbuild/watcher'; -import { shouldWatchRoot } from '../../utils/environment-options'; import { initializeHash } from '../../utils/hash'; import { NormalizedCachedOptions } from '../../utils/normalize-cache'; -import { toPosixPath } from '../../utils/path'; +import { ChangedFiles } from '../../utils/watcher'; import { NormalizedApplicationBuildOptions, NormalizedOutputOptions } from './options'; import { ComponentUpdateResult, @@ -35,20 +31,6 @@ import { ResultMessage, } from './results'; -// Watch workspace for package manager changes -const packageWatchFiles = [ - // manifest can affect module resolution - 'package.json', - // npm lock file - 'package-lock.json', - // pnpm lock file - 'pnpm-lock.yaml', - // yarn lock file including Yarn PnP manifest files (https://yarnpkg.com/advanced/pnp-spec/) - 'yarn.lock', - '.pnp.cjs', - '.pnp.data.json', -]; - // eslint-disable-next-line max-lines-per-function export async function* runEsBuildBuildAction( action: (rebuildState?: RebuildState) => Promise, @@ -106,7 +88,7 @@ export async function* runEsBuildBuildAction( } } - let watcher: import('../../tools/esbuild/watcher').BuildWatcher | undefined; + let watcher: import('../../utils/watcher').BuildWatcher | undefined; let watchLoopStarted = false; try { // Setup watcher if watch mode enabled @@ -115,55 +97,18 @@ export async function* runEsBuildBuildAction( logger.info('Watch mode enabled. Watching for file changes...'); } - const normalizedOutputBase = toPosixPath(outputOptions.base); - const normalizedCacheBase = toPosixPath(cacheOptions.basePath); - const ignored: string[] = [ - // Ignore the output and cache paths to avoid infinite rebuild cycles - normalizedOutputBase, - `${normalizedOutputBase}/**`, - normalizedCacheBase, - `${normalizedCacheBase}/**`, - `${toPosixPath(workspaceRoot)}/**/.*/**`, - ]; - - if (cacheOptions.localBasePath && cacheOptions.localBasePath !== cacheOptions.basePath) { - const normalizedLocalCacheBase = toPosixPath(cacheOptions.localBasePath); - ignored.push(normalizedLocalCacheBase, `${normalizedLocalCacheBase}/**`); - } - // Setup a watcher - const { createWatcher } = await import('../../tools/esbuild/watcher'); - watcher = await createWatcher({ - polling: typeof poll === 'number', - interval: poll, - followSymlinks: preserveSymlinks, - ignored, - cwd: workspaceRoot, + const { setupWatcher } = await import('../../utils/watcher'); + watcher = await setupWatcher({ + workspaceRoot, + projectRoot, + outputPath: outputOptions.base, + cacheOptions, + poll, + preserveSymlinks, + signal: options.signal, + watchFiles: result.watchFiles, }); - - // Setup abort support - options.signal?.addEventListener('abort', () => void watcher?.close()); - - // Watch the entire project root if 'NG_BUILD_WATCH_ROOT' environment variable is set - if (shouldWatchRoot) { - if (!preserveSymlinks) { - // Ignore all node modules directories to avoid excessive file watchers. - // Package changes are handled below by watching manifest and lock files. - // NOTE: this is not enable when preserveSymlinks is true as this would break `npm link` usages. - ignored.push('**/node_modules/**'); - - watcher.add( - packageWatchFiles - .map((file) => path.join(workspaceRoot, file)) - .filter((file) => existsSync(file)), - ); - } - - watcher.add(projectRoot); - } - - // Watch locations provided by the initial build result - watcher.add(result.watchFiles); } // Output the first build results after setting up the watcher to ensure that any code executed @@ -213,7 +158,10 @@ export async function* runEsBuildBuildAction( // Clear removed files from current watch files changes.removed.forEach((removedPath) => currentWatchFiles.delete(removedPath)); - resetSassWorkerPoolCaches(); + const hasSassChanges = changes.all.some((f) => /\.(scss|sass|css)$/i.test(f)); + if (hasSassChanges) { + resetSassWorkerPoolCaches(); + } const rebuildState = result.createRebuildState(changes); result = await withProgress('Changes detected. Rebuilding...', () => action(rebuildState)); @@ -366,14 +314,15 @@ function* emitOutputResults( } // Initially assume all previous assets files have been removed - const removedAssetFiles = new Map(previousAssetsInfo); + const removedAssetFiles = new Set(previousAssetsInfo); for (const { source, destination } of assetFiles) { - removedAssetFiles.delete(source); + removedAssetFiles.delete(destination); - if (!previousAssetsInfo.has(source)) { + if (!previousAssetsInfo.has(destination)) { incrementalResult.added.push(destination); incrementalResult.background = false; - } else if (changes.modified.has(source)) { + } else if (changes.modified.has(source) || changes.added.has(source)) { + // A file replaced by a rename (e.g. an atomic save) can be reported as added. incrementalResult.modified.push(destination); incrementalResult.background = false; } else { @@ -405,7 +354,7 @@ function* emitOutputResults( path, type, })), - ...Array.from(removedAssetFiles.values(), (path) => ({ + ...Array.from(removedAssetFiles, (path) => ({ path, type: BuildOutputFileType.Browser, })), diff --git a/packages/angular/build/src/builders/application/chunk-optimizer.ts b/packages/angular/build/src/builders/application/chunk-optimizer.ts index db3e1d2f180d..4b9f644f1d5c 100644 --- a/packages/angular/build/src/builders/application/chunk-optimizer.ts +++ b/packages/angular/build/src/builders/application/chunk-optimizer.ts @@ -292,6 +292,21 @@ export async function optimizeChunks( return result; }, + ...(sourcemap + ? { + augmentChunkHash(chunk: { moduleIds: string[] }) { + let hash = ''; + for (const id of chunk.moduleIds) { + const mapHash = maps[id]?.hash; + if (mapHash) { + hash += mapHash; + } + } + + return hash || undefined; + }, + } + : {}), }, ]; diff --git a/packages/angular/build/src/builders/application/execute-build.ts b/packages/angular/build/src/builders/application/execute-build.ts index 379566e4de4d..7fc43de92b00 100644 --- a/packages/angular/build/src/builders/application/execute-build.ts +++ b/packages/angular/build/src/builders/application/execute-build.ts @@ -7,6 +7,7 @@ */ import { BuilderContext } from '@angular-devkit/architect'; +import type { Metafile } from 'esbuild'; import { createAngularCompilation } from '../../tools/angular/compilation'; import { AngularCompilationContext, @@ -20,7 +21,6 @@ import { BuildOutputFileType } from '../../tools/esbuild/bundler-files'; import { checkCommonJSModules } from '../../tools/esbuild/commonjs-checker'; import { LOCALE_DATA_BASE_MODULE } from '../../tools/esbuild/i18n-locale-plugin'; import { extractLicenses } from '../../tools/esbuild/license-extractor'; -import { profileAsync } from '../../tools/esbuild/profiling'; import { transformSupportedBrowsersToTargets } from '../../tools/esbuild/target'; import { calculateEstimatedTransferSizes, @@ -29,6 +29,7 @@ import { } from '../../tools/esbuild/utils'; import { BudgetCalculatorResult, checkBudgets } from '../../utils/bundle-calculator'; import { optimizeChunksThreshold } from '../../utils/environment-options'; +import { profileAsync } from '../../utils/profiling'; import { resolveAssets } from '../../utils/resolve-assets'; import { SERVER_APP_ENGINE_MANIFEST_FILENAME, @@ -43,6 +44,42 @@ import { createComponentStyleBundler, setupBundlerContexts } from './setup-bundl /** The esbuild error text prefix used to detect top-level await errors. */ const TOP_LEVEL_AWAIT_ERROR_TEXT = 'Top-level await is not available in the configured target environment'; + +/** Returns a shallow copy of a record with its keys sorted. */ +function sortObjectKeys>(value: T): T { + const sorted: Record = {}; + for (const key of Object.keys(value).sort()) { + sorted[key] = value[key]; + } + + return sorted as T; +} + +/** + * Serializes a metafile with its dynamic path keys sorted so the stats file is identical across + * builds. Only `inputs`, `outputs`, and each output's `inputs` have dynamic keys; the remaining + * fixed-schema objects are left untouched so V8 keeps its native `JSON.stringify` fast path. + */ +function stableStringify(metafile: Metafile): string { + const outputs: Metafile['outputs'] = {}; + for (const key of Object.keys(metafile.outputs).sort()) { + const output = metafile.outputs[key]; + outputs[key] = { + ...output, + inputs: sortObjectKeys(output.inputs), + }; + } + + return JSON.stringify( + { + inputs: sortObjectKeys(metafile.inputs), + outputs, + }, + null, + 2, + ); +} + // eslint-disable-next-line max-lines-per-function export async function executeBuild( options: NormalizedApplicationBuildOptions, @@ -394,14 +431,14 @@ export async function executeBuild( if (options.stats) { executionResult.addOutputFile( 'browser-stats.json', - JSON.stringify(browserMetafile, null, 2), + stableStringify(browserMetafile), BuildOutputFileType.Root, ); if (serverEntryPoint) { executionResult.addOutputFile( 'server-stats.json', - JSON.stringify(serverMetafile, null, 2), + stableStringify(serverMetafile), BuildOutputFileType.Root, ); } diff --git a/packages/angular/build/src/builders/application/execute-post-bundle.ts b/packages/angular/build/src/builders/application/execute-post-bundle.ts index 07639a43c3e5..99e23bcb30c9 100644 --- a/packages/angular/build/src/builders/application/execute-post-bundle.ts +++ b/packages/angular/build/src/builders/application/execute-post-bundle.ts @@ -18,18 +18,15 @@ import { type InitialFileRecord, createOutputFile, } from '../../tools/esbuild/bundler-files'; -import { generateIndexHtml } from '../../tools/esbuild/index-html-generator'; import { maxWorkers } from '../../utils/environment-options'; import { SERVER_APP_MANIFEST_FILENAME, generateAngularServerAppManifest, } from '../../utils/server-rendering/manifest'; -import { - RouteRenderMode, - WritableSerializableRouteTreeNode, -} from '../../utils/server-rendering/models'; +import { WritableSerializableRouteTreeNode } from '../../utils/server-rendering/models'; import { prerenderPages } from '../../utils/server-rendering/prerender'; import { augmentAppWithServiceWorkerEsbuild } from '../../utils/service-worker'; +import { generateIndexHtml } from './index-html-generator'; import { injectDebugIds } from './inject-debug-ids'; import { INDEX_HTML_CSR, INDEX_HTML_SERVER, NormalizedApplicationBuildOptions } from './options'; import { OutputMode } from './schema'; diff --git a/packages/angular/build/src/builders/application/i18n.ts b/packages/angular/build/src/builders/application/i18n.ts index d4656c046997..839384421f1f 100644 --- a/packages/angular/build/src/builders/application/i18n.ts +++ b/packages/angular/build/src/builders/application/i18n.ts @@ -16,8 +16,8 @@ import { PrerenderedRoutesRecord, } from '../../tools/esbuild/bundler-execution-result'; import { BuildOutputFileType, InitialFileRecord } from '../../tools/esbuild/bundler-files'; -import { I18nInliner } from '../../tools/esbuild/i18n-inliner'; -import { maxWorkers } from '../../utils/environment-options'; +import { I18nInliner } from '../../tools/i18n'; +import { maxInlinerWorkers } from '../../utils/environment-options'; import { loadTranslations } from '../../utils/i18n-options'; import { createTranslationLoader } from '../../utils/load-translations'; import { createProjectResolver } from '../../utils/resolve-project'; @@ -51,7 +51,9 @@ export async function inlineI18n( const inliner = new I18nInliner( { missingTranslation: i18nOptions.missingTranslationBehavior ?? 'warning', - maxConcurrency: workerPool ? undefined : maxWorkers, + maxConcurrency: workerPool + ? Math.min(workerPool.maxThreads, maxInlinerWorkers) + : maxInlinerWorkers, persistentCachePath: cacheOptions.enabled ? cacheOptions.path : undefined, localizeVersion: i18nOptions.localizeVersion, }, diff --git a/packages/angular/build/src/tools/esbuild/index-html-generator.ts b/packages/angular/build/src/builders/application/index-html-generator.ts similarity index 88% rename from packages/angular/build/src/tools/esbuild/index-html-generator.ts rename to packages/angular/build/src/builders/application/index-html-generator.ts index a7ad3fd47e7f..a1c9cbcc9b30 100644 --- a/packages/angular/build/src/tools/esbuild/index-html-generator.ts +++ b/packages/angular/build/src/builders/application/index-html-generator.ts @@ -9,9 +9,13 @@ import assert from 'node:assert'; import { createHash } from 'node:crypto'; import path from 'node:path'; -import { NormalizedApplicationBuildOptions } from '../../builders/application/options'; +import { + BuildOutputFile, + BuildOutputFileType, + InitialFileRecord, +} from '../../tools/esbuild/bundler-files'; import { IndexHtmlGenerator } from '../../utils/index-file/index-html-generator'; -import { BuildOutputFile, BuildOutputFileType, InitialFileRecord } from './bundler-files'; +import { NormalizedApplicationBuildOptions } from './options'; /** * The maximum number of module preload link elements that should be added for @@ -87,8 +91,15 @@ export async function generateIndexHtml( let chunksIntegrity: ReadonlyMap | undefined; if (subresourceIntegrity) { const integrity = new Map(); + // Entry points and module preload hints carry their own integrity attribute. Any other + // initial chunk (e.g. beyond the module preload limit) is only covered by the import map. + const hinted = new Set(hints.map(({ url }) => url)); for (const file of browserOutputFiles) { - if (!file.path.endsWith('.js') || initialFiles.has(file.path)) { + if ( + !file.path.endsWith('.js') || + initialFiles.get(file.path)?.entrypoint || + hinted.has(file.path) + ) { continue; } const hash = createHash('sha384').update(file.contents).digest('base64'); diff --git a/packages/angular/build/src/builders/application/index-html-generator_spec.ts b/packages/angular/build/src/builders/application/index-html-generator_spec.ts new file mode 100644 index 000000000000..db5ed3a2425f --- /dev/null +++ b/packages/angular/build/src/builders/application/index-html-generator_spec.ts @@ -0,0 +1,105 @@ +/** + * @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 assert from 'node:assert'; +import { mkdtemp, rm, writeFile } from 'node:fs/promises'; +import { join } from 'node:path'; +import { + BuildOutputFileType, + InitialFileRecord, + createOutputFile, +} from '../../tools/esbuild/bundler-files'; +import { generateIndexHtml } from './index-html-generator'; +import { NormalizedApplicationBuildOptions } from './options'; + +describe('generateIndexHtml', () => { + let tempDir: string; + + beforeEach(async () => { + const baseTmpDir = process.env['TEST_TMPDIR']; + assert(baseTmpDir, 'TEST_TMPDIR is not set'); + tempDir = await mkdtemp(join(baseTmpDir, 'index-html-generator-spec-')); + await writeFile( + join(tempDir, 'index.html'), + '', + ); + }); + + afterEach(async () => { + await rm(tempDir, { recursive: true, force: true }); + }); + + function createOptions( + subresourceIntegrity: boolean, + preloadInitial = true, + ): NormalizedApplicationBuildOptions { + return { + indexHtmlOptions: { + input: join(tempDir, 'index.html'), + insertionOrder: [['main.js', true]], + preloadInitial, + }, + subresourceIntegrity, + baseHref: '/', + security: {}, + } as unknown as NormalizedApplicationBuildOptions; + } + + it('should add integrity metadata for every initial chunk when there are more than the module preload limit', async () => { + const chunkCount = 15; + const chunks = Array.from({ length: chunkCount }, (_, i) => `chunk-${i}.js`); + const initialFiles = new Map([ + ['main.js', { entrypoint: true, name: 'main', type: 'script', serverFile: false, depth: 0 }], + ...chunks.map( + (chunk, i) => + [chunk, { entrypoint: false, type: 'script', serverFile: false, depth: i + 1 }] as [ + string, + InitialFileRecord, + ], + ), + ]); + const outputFiles = ['main.js', ...chunks].map((path) => + createOutputFile(path, `console.log(${JSON.stringify(path)});`, BuildOutputFileType.Browser), + ); + + const { csrContent, errors } = await generateIndexHtml( + initialFiles, + outputFiles, + createOptions(true), + ); + expect(errors).toHaveSize(0); + + for (const chunk of chunks.slice(0, 10)) { + expect(csrContent).toContain(` { + const initialFiles = new Map([ + ['main.js', { entrypoint: true, name: 'main', type: 'script', serverFile: false, depth: 0 }], + ['chunk-a.js', { entrypoint: false, type: 'script', serverFile: false, depth: 1 }], + ]); + const outputFiles = ['main.js', 'chunk-a.js'].map((path) => + createOutputFile(path, `console.log(${JSON.stringify(path)});`, BuildOutputFileType.Browser), + ); + const options = createOptions(true, false); + + const { csrContent, errors } = await generateIndexHtml(initialFiles, outputFiles, options); + expect(errors).toHaveSize(0); + + expect(csrContent).toContain(`"./${outputFiles[1].path}":`); + expect(csrContent).not.toContain(`"./${outputFiles[0].path}":`); + expect(csrContent).not.toContain('rel="modulepreload"'); + }); +}); diff --git a/packages/angular/build/src/builders/application/options.ts b/packages/angular/build/src/builders/application/options.ts index dc53d55b61f0..9fcdd1f3d118 100644 --- a/packages/angular/build/src/builders/application/options.ts +++ b/packages/angular/build/src/builders/application/options.ts @@ -9,7 +9,6 @@ import type { BuilderContext } from '@angular-devkit/architect'; import type { Plugin } from 'esbuild'; import { access, constants, readFile } from 'node:fs/promises'; -import { createRequire } from 'node:module'; import path from 'node:path'; import { normalizeAssetPatterns, normalizeOptimization, normalizeSourceMaps } from '../../utils'; import { supportColor } from '../../utils/color'; @@ -19,9 +18,8 @@ import { IndexHtmlTransform } from '../../utils/index-file/index-html-generator' import { normalizeCacheOptions } from '../../utils/normalize-cache'; import { canonicalizePath } from '../../utils/path'; import { - SearchDirectory, - findTailwindConfiguration, generateSearchDirectories, + getTailwindConfig, loadPostcssConfiguration, } from '../../utils/postcss-configuration'; import { getProjectRootPaths, normalizeDirectoryPath } from '../../utils/project-metadata'; @@ -140,6 +138,11 @@ interface InternalOptions { * there. Used exclusively for tests and shouldn't be used for other kinds of builds. */ disableCodeSplitting?: boolean; + + /** + * An array of files to restrict the TypeScript compilation root names to. + */ + rootFiles?: string[]; } /** Full set of options for `application` builder. */ @@ -280,7 +283,7 @@ export async function normalizeOptions( // Skip tailwind configuration if postcss is customized const tailwindConfiguration = postcssConfiguration ? undefined - : await getTailwindConfig(searchDirectories, workspaceRoot, context); + : await getTailwindConfig(searchDirectories, workspaceRoot, context.logger); let serverEntryPoint: string | undefined; if (typeof options.server === 'string') { @@ -408,13 +411,13 @@ export async function normalizeOptions( if (appShellOptions || ssrOptions || prerenderOptions) { if (!serverEntryPoint) { throw new Error( - 'The "server" option is required when enabling "ssr", "prerender" or "app-shell".', + 'The "server" option is required when enabling "ssr", "prerender" or "appShell".', ); } if (!indexHtmlOptions) { throw new Error( - 'The "index" option cannot be set to false when enabling "ssr", "prerender" or "app-shell".', + 'The "index" option cannot be set to false when enabling "ssr", "prerender" or "appShell".', ); } } @@ -449,6 +452,7 @@ export async function normalizeOptions( verbose, watch, progress = true, + rootFiles, externalPackages, namedChunks, budgets, @@ -496,6 +500,7 @@ export async function normalizeOptions( workspaceRoot, entryPoints, disableCodeSplitting, + rootFiles: rootFiles?.map((file: string) => path.resolve(workspaceRoot, file)), optimizationOptions, outputOptions, outExtension, @@ -538,36 +543,6 @@ export async function normalizeOptions( }; } -async function getTailwindConfig( - searchDirectories: SearchDirectory[], - workspaceRoot: string, - context: BuilderContext, -): Promise<{ file: string; package: string } | undefined> { - const tailwindConfigurationPath = findTailwindConfiguration(searchDirectories); - - if (!tailwindConfigurationPath) { - return undefined; - } - - // Create a node resolver from the configuration file - const resolver = createRequire(tailwindConfigurationPath); - try { - return { - file: tailwindConfigurationPath, - package: resolver.resolve('tailwindcss'), - }; - } catch { - const relativeTailwindConfigPath = path.relative(workspaceRoot, tailwindConfigurationPath); - context.logger.warn( - `Tailwind CSS configuration file found (${relativeTailwindConfigPath})` + - ` but the 'tailwindcss' package is not installed.` + - ` To enable Tailwind CSS, please install the 'tailwindcss' package.`, - ); - } - - return undefined; -} - /** * Normalize entry point options. To maintain compatibility with the legacy browser builder, we need a single `browser` * option which defines a single entry point. However, we also want to support multiple entry points as an internal option. diff --git a/packages/angular/build/src/builders/application/schema.json b/packages/angular/build/src/builders/application/schema.json index 8458d385a3fc..0c0cd871e2d5 100644 --- a/packages/angular/build/src/builders/application/schema.json +++ b/packages/angular/build/src/builders/application/schema.json @@ -534,7 +534,7 @@ }, "statsJson": { "type": "boolean", - "description": "Generates a 'stats.json' file which can be analyzed with https://esbuild.github.io/analyze/.", + "description": "Generates a 'browser-stats.json' file which can be analyzed with https://esbuild.github.io/analyze/. When server-side rendering is enabled, a 'server-stats.json' file is also generated.", "default": false }, "budgets": { @@ -568,7 +568,7 @@ "oneOf": [ { "type": "boolean", - "description": "Enable prerending of pages of your application during build time." + "description": "Enable prerendering of pages of your application during build time." }, { "type": "object", diff --git a/packages/angular/build/src/builders/application/tests/behavior/chunk-optimization-server_spec.ts b/packages/angular/build/src/builders/application/tests/behavior/chunk-optimization-server_spec.ts index 76ecbbc4329e..18b92e7690a0 100644 --- a/packages/angular/build/src/builders/application/tests/behavior/chunk-optimization-server_spec.ts +++ b/packages/angular/build/src/builders/application/tests/behavior/chunk-optimization-server_spec.ts @@ -151,15 +151,19 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => { .not.toBeNull(); const mapping = JSON.parse(mappingSource![1]) as Record; + const mainServerContent = harness.readFile('dist/server/main.server.mjs'); - // Every lazy route entry point must retain a mapping entry after optimization. + // Every lazy route entry point must retain a mapping entry after optimization + // that matches the ɵentryName emitted into the server bundle. for (const name of LAZY_ROUTE_NAMES) { - const key = Object.keys(mapping).find((entryPoint) => - entryPoint.endsWith(`${name}.component.ts`), - ); - expect(key) - .withContext(`mapping entry for lazy route '${name}' should exist`) + const expectedEntryPoint = `src/app/${name}.component.ts`; + expect(mapping[expectedEntryPoint]) + .withContext(`mapping entry for '${expectedEntryPoint}' should exist`) .toBeDefined(); + + expect(mainServerContent) + .withContext(`main.server.mjs should contain ɵentryName '${expectedEntryPoint}'`) + .toContain(expectedEntryPoint); } // Every browser file referenced by the mapping must exist on disk. diff --git a/packages/angular/build/src/builders/application/tests/behavior/platform-server-domino_spec.ts b/packages/angular/build/src/builders/application/tests/behavior/platform-server-domino_spec.ts new file mode 100644 index 000000000000..df58f1c833c0 --- /dev/null +++ b/packages/angular/build/src/builders/application/tests/behavior/platform-server-domino_spec.ts @@ -0,0 +1,94 @@ +/** + * @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 { buildApplication } from '../../index'; +import { OutputMode, Platform } from '../../schema'; +import { APPLICATION_BUILDER_INFO, BASE_OPTIONS, describeBuilder } from '../setup'; + +/** + * `@angular/platform-server/init` (bundled into the server polyfills) and + * `@angular/platform-server` (bundled into the main server bundle) both import this file. + */ +const DOMINO_BUNDLE = 'third_party/domino/bundled-domino.mjs'; + +/** The property on globalThis where the Domino instance is stored. */ +const DOMINO_GLOBAL_PROPERTY = /(?:ɵ|\\u0275)domino/; + +describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => { + describe('Behavior: "Domino is bundled once for the server"', () => { + beforeEach(async () => { + await harness.modifyFile('src/tsconfig.app.json', (content) => { + const tsConfig = JSON.parse(content); + tsConfig.files ??= []; + tsConfig.files.push('main.server.ts', 'server.ts'); + + return JSON.stringify(tsConfig); + }); + + await harness.writeFile('src/server.ts', `console.log('Hello!');`); + + // The default template uses i18n which requires `@angular/localize` to prerender. + await harness.writeFile('src/app/app.component.html', `

Hello!

`); + }); + + it('shares the server polyfills copy of Domino with the main server bundle', async () => { + harness.useTarget('build', { + ...BASE_OPTIONS, + server: 'src/main.server.ts', + ssr: true, + }); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + + harness.expectFile('dist/server/polyfills.server.mjs').content.toContain(DOMINO_BUNDLE); + harness + .expectFile('dist/server/polyfills.server.mjs') + .content.toMatch(DOMINO_GLOBAL_PROPERTY); + + harness.expectFile('dist/server/main.server.mjs').content.not.toContain(DOMINO_BUNDLE); + harness.expectFile('dist/server/main.server.mjs').content.toMatch(DOMINO_GLOBAL_PROPERTY); + }); + + it('shares the server polyfills copy of Domino when "outputMode" is "server"', async () => { + harness.useTarget('build', { + ...BASE_OPTIONS, + server: 'src/main.server.ts', + ssr: { entry: 'src/server.ts' }, + outputMode: OutputMode.Server, + }); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + + harness.expectFile('dist/server/polyfills.server.mjs').content.toContain(DOMINO_BUNDLE); + harness.expectFile('dist/server/main.server.mjs').content.not.toContain(DOMINO_BUNDLE); + harness.expectFile('dist/server/main.server.mjs').content.toMatch(DOMINO_GLOBAL_PROPERTY); + harness.expectFile('dist/server/server.mjs').content.not.toContain(DOMINO_BUNDLE); + }); + + it('shares the server polyfills copy of Domino when "ssr.platform" is "neutral"', async () => { + harness.useTarget('build', { + ...BASE_OPTIONS, + server: 'src/main.server.ts', + ssr: { entry: 'src/server.ts', platform: Platform.Neutral }, + outputMode: OutputMode.Server, + }); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + + harness.expectFile('dist/server/polyfills.server.mjs').content.toContain(DOMINO_BUNDLE); + harness + .expectFile('dist/server/polyfills.server.mjs') + .content.toMatch(DOMINO_GLOBAL_PROPERTY); + harness.expectFile('dist/server/main.server.mjs').content.not.toContain(DOMINO_BUNDLE); + harness.expectFile('dist/server/main.server.mjs').content.toMatch(DOMINO_GLOBAL_PROPERTY); + }); + }); +}); diff --git a/packages/angular/build/src/builders/application/tests/behavior/rebuild-assets_spec.ts b/packages/angular/build/src/builders/application/tests/behavior/rebuild-assets_spec.ts index 7bfcca94d242..04610625eb09 100644 --- a/packages/angular/build/src/builders/application/tests/behavior/rebuild-assets_spec.ts +++ b/packages/angular/build/src/builders/application/tests/behavior/rebuild-assets_spec.ts @@ -6,6 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ +import { rename } from 'node:fs/promises'; import { buildApplication } from '../../index'; import { APPLICATION_BUILDER_INFO, BASE_OPTIONS, describeBuilder } from '../setup'; @@ -43,6 +44,39 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => { ]); }); + it('emits an asset replaced by renaming another file over it', async () => { + harness.useTarget('build', { + ...BASE_OPTIONS, + assets: [ + { + glob: '**/*', + input: 'public', + }, + ], + watch: true, + // Polling reports a replaced file as modified, while native watchers can report it as added. + poll: undefined, + }); + + await harness.executeWithCases([ + async ({ result }) => { + expect(result?.success).toBeTrue(); + harness.expectFile('dist/browser/asset.txt').content.toContain('foo'); + + // Editors with atomic save write a temporary file and rename it over the original. + await harness.writeFile('asset.txt.tmp', 'bar'); + await rename( + harness.resolvePath('asset.txt.tmp'), + harness.resolvePath('public/asset.txt'), + ); + }, + ({ result }) => { + expect(result?.success).toBeTrue(); + harness.expectFile('dist/browser/asset.txt').content.toContain('bar'); + }, + ]); + }); + it('remove deleted asset from output', async () => { await Promise.all([ harness.writeFile('public/asset-two.txt', 'bar'), @@ -76,5 +110,39 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => { }, ]); }); + + it('remove all outputs of a deleted asset copied to multiple destinations', async () => { + harness.useTarget('build', { + ...BASE_OPTIONS, + assets: [ + { + glob: '**/*', + input: 'public', + }, + { + glob: '**/*', + input: 'public', + output: 'static', + }, + ], + watch: true, + }); + + await harness.executeWithCases([ + async ({ result }) => { + expect(result?.success).toBeTrue(); + harness.expectFile('dist/browser/asset.txt').toExist(); + harness.expectFile('dist/browser/static/asset.txt').toExist(); + + await harness.removeFile('public/asset.txt'); + }, + + ({ result }) => { + expect(result?.success).toBeTrue(); + harness.expectFile('dist/browser/asset.txt').toNotExist(); + harness.expectFile('dist/browser/static/asset.txt').toNotExist(); + }, + ]); + }); }); }); diff --git a/packages/angular/build/src/builders/application/tests/behavior/web-workers-application_spec.ts b/packages/angular/build/src/builders/application/tests/behavior/web-workers-application_spec.ts index 135d5ff68165..10112afd3b6b 100644 --- a/packages/angular/build/src/builders/application/tests/behavior/web-workers-application_spec.ts +++ b/packages/angular/build/src/builders/application/tests/behavior/web-workers-application_spec.ts @@ -57,5 +57,78 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => { // Ensure built worker is referenced in the application code harness.expectFile('dist/browser/main.js').content.toMatch(REFERENCED_WORKER_REGEXP); }); + + it('should emit all chunks referenced by a web worker when chunk optimization is enabled', async () => { + harness.useTarget('build', { + ...BASE_OPTIONS, + optimization: true, + }); + + await harness.writeFile( + 'src/app/shared.ts', + `export function sharedHelper(value: string) { return [value, value.toUpperCase(), value.toLowerCase(), value.repeat(3)].join('-'); }`, + ); + await harness.writeFile( + 'src/app/lazy-a.ts', + `import { sharedHelper } from './shared'; export const a = () => sharedHelper('a');`, + ); + await harness.writeFile( + 'src/app/lazy-b.ts', + `import { sharedHelper } from './shared'; export const b = () => sharedHelper('b');`, + ); + await harness.writeFile('src/app/lazy-c.ts', `export const c = () => 'c';`); + + await harness.writeFile( + 'src/app/worker.ts', + ` + addEventListener('message', async () => { + const [{ a }, { b }] = await Promise.all([import('./lazy-a'), import('./lazy-b')]); + postMessage(a() + b()); + }); + `, + ); + + await harness.writeFile( + 'src/app/app.component.ts', + ` + import { Component } from '@angular/core'; + @Component({ + selector: 'app-root', + standalone: false, + template: '

Worker Test

', + }) + export class AppComponent { + worker = new Worker(new URL('./worker', import.meta.url), { type: 'module' }); + constructor() { + Promise.all([import('./lazy-a'), import('./lazy-b'), import('./lazy-c')]).then(console.log); + } + } + `, + ); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + expect(harness.hasFileMatch('dist/browser', /^worker-chunk-/)).toBeTrue(); + + const mainContent = harness.readFile('dist/browser/main.js'); + const workerMatch = mainContent.match(/(worker-[A-Z0-9]{8}\.js)/); + expect(workerMatch).not.toBeNull(); + + const filesToCheck = new Set(['main.js']); + if (workerMatch) { + filesToCheck.add(workerMatch[1]); + } + + for (const file of filesToCheck) { + expect(harness.hasFile(`dist/browser/${file}`)) + .withContext(`Expected dist/browser/${file} to exist`) + .toBeTrue(); + + const content = harness.readFile(`dist/browser/${file}`); + for (const match of content.matchAll(/(?:from|import)\s*\(?["']\.\/([^"']+\.js)["']\)?/g)) { + filesToCheck.add(match[1]); + } + } + }); }); }); diff --git a/packages/angular/build/src/builders/application/tests/options/app-shell_spec.ts b/packages/angular/build/src/builders/application/tests/options/app-shell_spec.ts index a43d24f19c6d..16f2a27b634c 100644 --- a/packages/angular/build/src/builders/application/tests/options/app-shell_spec.ts +++ b/packages/angular/build/src/builders/application/tests/options/app-shell_spec.ts @@ -170,7 +170,7 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => { indexFileContent.toContain('app-shell works!'); indexFileContent.toContain('p{color:#000}'); indexFileContent.toContain( - ``, + ``, ); indexFileContent.toContain('