diff --git a/.github/workflows/auto-start-ci.yml b/.github/workflows/auto-start-ci.yml index 0a69ff636f25..8c01b0592c2e 100644 --- a/.github/workflows/auto-start-ci.yml +++ b/.github/workflows/auto-start-ci.yml @@ -9,7 +9,7 @@ on: # optimistic, it can take longer to run. # To understand why `schedule` is used instead of other events, refer to # ./doc/contributing/commit-queue.md - - cron: '*/5 * * * *' + - cron: 3/5 * * * * concurrency: ${{ github.workflow }} @@ -51,7 +51,7 @@ jobs: runs-on: ubuntu-slim steps: - name: Install Node.js - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: node-version: ${{ env.NODE_VERSION }} diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 561f8d56813f..b512153621d8 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -78,7 +78,7 @@ jobs: name: '${{ matrix.system }}: with shared libraries' runs-on: ${{ matrix.runner }} steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: repository: ${{ inputs.repo || github.repository }} ref: refs/pull/${{ inputs.pr_id }}/merge @@ -92,7 +92,7 @@ jobs: env: EXPECTED_SHA: ${{ inputs.commit }} - - uses: cachix/install-nix-action@630ae543ea3a38a9a4166f03376c02c50f408342 # v31.11.0 + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 with: extra_nix_config: sandbox = true @@ -195,7 +195,7 @@ jobs: contents: read pull-requests: write steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false sparse-checkout: | @@ -211,7 +211,7 @@ jobs: merge-multiple: true path: raw-results - - uses: cachix/install-nix-action@630ae543ea3a38a9a4166f03376c02c50f408342 # v31.11.0 + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 with: extra_nix_config: sandbox = true diff --git a/.github/workflows/build-shared.yml b/.github/workflows/build-shared.yml index 908116021c27..6b0ef92c3df7 100644 --- a/.github/workflows/build-shared.yml +++ b/.github/workflows/build-shared.yml @@ -53,7 +53,7 @@ jobs: tar xzf tarballs/*.tar.gz -C "$RUNNER_TEMP" echo "TAR_DIR=$RUNNER_TEMP/$(basename tarballs/*.tar.gz .tar.gz)" >> "$GITHUB_ENV" - - uses: cachix/install-nix-action@630ae543ea3a38a9a4166f03376c02c50f408342 # v31.11.0 + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 with: extra_nix_config: sandbox = true diff --git a/.github/workflows/build-tarball.yml b/.github/workflows/build-tarball.yml index 248e64bab776..e173d4a544e0 100644 --- a/.github/workflows/build-tarball.yml +++ b/.github/workflows/build-tarball.yml @@ -76,7 +76,7 @@ jobs: if: github.event.pull_request.draft == false runs-on: ubuntu-slim steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} @@ -104,7 +104,7 @@ jobs: SCCACHE_GHA_ENABLED: ${{ github.base_ref == 'main' || github.ref_name == 'main' }} SCCACHE_IDLE_TIMEOUT: '0' steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false sparse-checkout: .github/actions/install-clang diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 23084c68ac5e..0b83c888ecdc 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -24,19 +24,19 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81 # v4.37.3 + uses: github/codeql-action/init@cdf488f595d80d6e07e03d4674febd5ab45fa938 # v4.37.9 with: languages: ${{ matrix.language }} config-file: ./.github/codeql-config.yml - name: Autobuild - uses: github/codeql-action/autobuild@e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81 # v4.37.3 + uses: github/codeql-action/autobuild@cdf488f595d80d6e07e03d4674febd5ab45fa938 # v4.37.9 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81 # v4.37.3 + uses: github/codeql-action/analyze@cdf488f595d80d6e07e03d4674febd5ab45fa938 # v4.37.9 with: category: /language:${{matrix.language}} diff --git a/.github/workflows/commit-lint.yml b/.github/workflows/commit-lint.yml index 896340ba3a82..5537d1e19c65 100644 --- a/.github/workflows/commit-lint.yml +++ b/.github/workflows/commit-lint.yml @@ -20,13 +20,13 @@ jobs: run: | echo "plusOne=$((${{ github.event.pull_request.commits }} + 1))" >> $GITHUB_OUTPUT echo "minusOne=$((${{ github.event.pull_request.commits }} - 1))" >> $GITHUB_OUTPUT - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: ${{ steps.nb-of-commits.outputs.plusOne }} persist-credentials: false - run: git reset HEAD^2 - name: Install Node.js - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: node-version: ${{ env.NODE_VERSION }} - name: Validate commit message diff --git a/.github/workflows/commit-queue.yml b/.github/workflows/commit-queue.yml index a1d691e9e19f..600dadc17bc4 100644 --- a/.github/workflows/commit-queue.yml +++ b/.github/workflows/commit-queue.yml @@ -11,7 +11,7 @@ on: # be read-only, and the Action won't have access to any other repository # secrets, which it needs to access Jenkins API. schedule: - - cron: '*/5 * * * *' + - cron: 3/5 * * * * concurrency: ${{ github.workflow }} @@ -28,6 +28,7 @@ jobs: if: github.repository == 'nodejs/node' runs-on: ubuntu-slim outputs: + aged_prs: ${{ steps.get_candidate_prs.outputs.aged_prs }} candidates: ${{ steps.get_candidate_prs.outputs.candidates }} steps: - name: Get Pull Request Candidates @@ -50,6 +51,7 @@ jobs: --search "-label:blocked") candidates=$(printf '%s %s\n' "$fast_track_prs" "$aged_prs" | jq -r -s 'reduce .[] as $pr ([]; if index($pr) then . else . + [$pr] end) | join(" ")') + echo "aged_prs=$aged_prs" >> "$GITHUB_OUTPUT" echo "candidates=$candidates" >> "$GITHUB_OUTPUT" env: GH_TOKEN: ${{ github.token }} @@ -64,7 +66,7 @@ jobs: runs-on: ubuntu-slim steps: - name: Install Node.js - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: node-version: ${{ env.NODE_VERSION }} @@ -93,6 +95,7 @@ jobs: curl -fsSLo "$readme" "https://github.com/${GITHUB_REPOSITORY}/raw/${GITHUB_SHA}/README.md" numbers= + lacks_second_approval_prs= # shellcheck disable=SC2086 for pr in $CANDIDATES; do metadata="${RUNNER_TEMP}/metadata-${pr}.json" @@ -139,6 +142,14 @@ jobs: if [ "$metadata_status" -ge 20 ] && [ "$metadata_status" -le 29 ]; then echo "pr ${pr} skipped, not ready to land" echo "reason codes: ${metadata_reason_codes}" + if jq -e ' + (.reasonCodes | index("wait-time")) and + (.pullRequest.labels | index("lacks-second-approval") | not) + ' "$metadata" > /dev/null; then + case " $AGED_PRS " in + *" $pr "*) lacks_second_approval_prs="$lacks_second_approval_prs $pr" ;; + esac + fi continue fi @@ -148,12 +159,28 @@ jobs: done numbers=$(echo "$numbers" | xargs) + lacks_second_approval_prs=$(echo "$lacks_second_approval_prs" | xargs) echo "numbers=$numbers" >> "$GITHUB_OUTPUT" + echo "lacks_second_approval_prs=$lacks_second_approval_prs" >> "$GITHUB_OUTPUT" env: + AGED_PRS: ${{ needs.get_candidate_prs.outputs.aged_prs }} CANDIDATES: ${{ needs.get_candidate_prs.outputs.candidates }} GH_TOKEN: ${{ github.token }} - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - name: Label Pull Requests Lacking a Second Approval + if: steps.get_mergeable_prs.outputs.lacks_second_approval_prs != '' + run: | + # shellcheck disable=SC2086 + for pr in $PULL_REQUESTS; do + if ! gh -R "$GITHUB_REPOSITORY" pr edit "$pr" --add-label 'lacks-second-approval'; then + echo "::warning::Failed to add lacks-second-approval to PR ${pr}" + fi + done + env: + GH_TOKEN: ${{ secrets.GH_USER_TOKEN }} + PULL_REQUESTS: ${{ steps.get_mergeable_prs.outputs.lacks_second_approval_prs }} + + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 if: steps.get_mergeable_prs.outputs.numbers != '' with: # A personal token is required because pushing with GITHUB_TOKEN will diff --git a/.github/workflows/contributor-guidance.yml b/.github/workflows/contributor-guidance.yml new file mode 100644 index 000000000000..e9a99bcb6277 --- /dev/null +++ b/.github/workflows/contributor-guidance.yml @@ -0,0 +1,147 @@ +name: Contributor guidance + +on: + pull_request_target: + types: [opened] + +permissions: {} + +jobs: + contributor: + name: Resolve contributor status + # Use the event only to exclude trusted associations, mannequins, and bots. + # Resolve every potentially external contributor with a privileged API request. + if: >- + github.run_attempt == 1 && + github.repository == 'nodejs/node' && + github.event.pull_request.user.type != 'Bot' && + (github.event.pull_request.author_association == 'CONTRIBUTOR' || + github.event.pull_request.author_association == 'FIRST_TIMER' || + github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR' || + github.event.pull_request.author_association == 'NONE') + runs-on: ubuntu-slim + outputs: + is_first_time: ${{ steps.resolve.outputs.is_first_time }} + should_scan: ${{ steps.resolve.outputs.should_scan }} + steps: + - name: Check author association + id: resolve + env: + GH_TOKEN: ${{ secrets.GH_USER_TOKEN }} + NUMBER: ${{ github.event.pull_request.number }} + run: | + started_at=$SECONDS + # TODO: Remove the retries once privileged API requests are confirmed + # to return the association immediately. + for delay in 0 15 30 60; do + sleep "$delay" + association=$(gh api "/repos/$GITHUB_REPOSITORY/pulls/$NUMBER" \ + --jq '.author_association') + elapsed=$((SECONDS - started_at)) + echo "Author association after ${elapsed}s: $association" + + case "$association" in + FIRST_TIMER|FIRST_TIME_CONTRIBUTOR) + echo 'is_first_time=true' >> "$GITHUB_OUTPUT" + echo 'should_scan=true' >> "$GITHUB_OUTPUT" + exit 0 + ;; + CONTRIBUTOR) + echo 'is_first_time=false' >> "$GITHUB_OUTPUT" + echo 'should_scan=true' >> "$GITHUB_OUTPUT" + exit 0 + ;; + NONE) + ;; + COLLABORATOR|MANNEQUIN|MEMBER|OWNER) + echo 'is_first_time=false' >> "$GITHUB_OUTPUT" + echo 'should_scan=false' >> "$GITHUB_OUTPUT" + exit 0 + ;; + *) + echo "Unexpected author association: $association" >&2 + exit 1 + ;; + esac + done + + # NONE is unresolved, not trusted. Scan without posting the welcome. + echo 'is_first_time=false' >> "$GITHUB_OUTPUT" + echo 'should_scan=true' >> "$GITHUB_OUTPUT" + + guidance: + name: Apply contributor guidance + needs: contributor + if: needs.contributor.outputs.should_scan == 'true' + runs-on: ubuntu-slim + permissions: + contents: read + pull-requests: write + steps: + - name: Scan contributor activity + id: agentscan + # The welcome should still be posted if this advisory scan fails. + continue-on-error: true + uses: MatteoGabriele/agentscan-action@8112fb79b33fafb8506159df20129a34209ac410 # v2.5.0 + with: + github-token: ${{ github.token }} + mode: labels + scan-pull-requests: true + scan-issues: false + auto-close: false + honeypot: false + + - name: Comment with contributor guidance + env: + ADD_CAUTION: >- + ${{ + steps.agentscan.outputs.classification == 'mixed' || + steps.agentscan.outputs.classification == 'automation' || + steps.agentscan.outputs['community-flagged'] == 'true' + }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + IS_FIRST_TIME: ${{ needs.contributor.outputs.is_first_time }} + NUMBER: ${{ github.event.pull_request.number }} + WELCOME_MESSAGE: >2- + Welcome to Node.js, and thank you for your first contribution! + + Before review, please take a moment to read: + + * the [guide for first-time contributors](https://github.com/nodejs/node/blob/HEAD/doc/contributing/first-contributions.md) + * the [contribution and automation policies](https://github.com/nodejs/node/blob/HEAD/CONTRIBUTING.md) + * the [pull request guide](https://github.com/nodejs/node/blob/HEAD/doc/contributing/pull-requests.md) + * the [AI use policy](https://github.com/nodejs/node/blob/HEAD/doc/contributing/ai-guidelines.md) + * the [Code of Conduct](https://github.com/nodejs/admin/blob/HEAD/CODE_OF_CONDUCT.md) + + Please make sure every commit is + [signed off](https://github.com/nodejs/node/blob/HEAD/doc/contributing/pull-requests.md#step-4-commit). + For a first pull request, GitHub Actions require collaborator + approval and Jenkins CI must be started by a collaborator or triager, + so an initial wait is normal. + CAUTION_MESSAGE: >- + > [!CAUTION] + + > AgentScan found account activity patterns that may be consistent with + automation. This is a heuristic, not proof that this pull request was + opened by an agent or violates policy. AI-assisted contributions are + permitted, but automated tooling must not open pull requests without + advance approval, and contributors must personally understand, test, + verify, and take responsibility for every submitted change. See the + [AgentScan analysis](https://agentscan.tools/user/${{ github.event.pull_request.user.login }}), + [AI use policy](https://github.com/nodejs/node/blob/HEAD/doc/contributing/ai-guidelines.md), + and + [automation policy](https://github.com/nodejs/node/blob/HEAD/CONTRIBUTING.md#automation-and-bots) + for additional context. + run: | + if [[ "$IS_FIRST_TIME" == "true" && "$ADD_CAUTION" == "true" ]]; then + body="$WELCOME_MESSAGE"$'\n\n'"$CAUTION_MESSAGE" + elif [[ "$IS_FIRST_TIME" == "true" ]]; then + body="$WELCOME_MESSAGE" + elif [[ "$ADD_CAUTION" == "true" ]]; then + body="$CAUTION_MESSAGE" + else + exit 0 + fi + + printf '%s\n' "$body" | + gh pr comment "$NUMBER" --repo "$GITHUB_REPOSITORY" --body-file - diff --git a/.github/workflows/coverage-linux-without-intl.yml b/.github/workflows/coverage-linux-without-intl.yml index 92c9f3b88217..7a73d69b70ec 100644 --- a/.github/workflows/coverage-linux-without-intl.yml +++ b/.github/workflows/coverage-linux-without-intl.yml @@ -50,7 +50,7 @@ jobs: if: github.event.pull_request.draft == false runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Install Clang ${{ env.CLANG_VERSION }} diff --git a/.github/workflows/coverage-linux.yml b/.github/workflows/coverage-linux.yml index e97b759bc6a4..79c6eaaebc91 100644 --- a/.github/workflows/coverage-linux.yml +++ b/.github/workflows/coverage-linux.yml @@ -50,7 +50,7 @@ jobs: if: github.event.pull_request.draft == false runs-on: ubuntu-24.04-arm steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Install Clang ${{ env.CLANG_VERSION }} diff --git a/.github/workflows/coverage-windows.yml b/.github/workflows/coverage-windows.yml index d0236cd7d609..5da225b17127 100644 --- a/.github/workflows/coverage-windows.yml +++ b/.github/workflows/coverage-windows.yml @@ -72,7 +72,7 @@ jobs: if: github.event.pull_request.draft == false runs-on: windows-2025 steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} diff --git a/.github/workflows/create-release-proposal.yml b/.github/workflows/create-release-proposal.yml index 883bb48b0df2..735b15ffd12f 100644 --- a/.github/workflows/create-release-proposal.yml +++ b/.github/workflows/create-release-proposal.yml @@ -33,14 +33,14 @@ jobs: RELEASE_LINE: ${{ inputs.release-line }} runs-on: ubuntu-slim steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ env.STAGING_BRANCH }} persist-credentials: false # Install dependencies - name: Install Node.js - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: node-version: ${{ env.NODE_VERSION }} diff --git a/.github/workflows/daily-wpt-fyi.yml b/.github/workflows/daily-wpt-fyi.yml index 8dda0ff75d6e..043de271faa9 100644 --- a/.github/workflows/daily-wpt-fyi.yml +++ b/.github/workflows/daily-wpt-fyi.yml @@ -50,7 +50,7 @@ jobs: run: echo "NIGHTLY=$(curl -s https://nodejs.org/download/nightly/index.json | jq -r '[.[] | select(.files[] | contains("linux-arm64"))][0].version')" >> $GITHUB_ENV - name: Install Node.js id: setup-node - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: node-version: ${{ env.NIGHTLY || matrix.node-version }} check-latest: true @@ -62,7 +62,7 @@ jobs: SHORT_SHA=$(node -p 'process.version.split(/-nightly\d{8}/)[1]') echo "NIGHTLY_REF=$(gh api /repos/nodejs/node/commits/$SHORT_SHA --jq '.sha')" >> $GITHUB_ENV - name: Checkout ${{ steps.setup-node.outputs.node-version }} - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false ref: ${{ env.NIGHTLY_REF || steps.setup-node.outputs.node-version }} @@ -78,7 +78,7 @@ jobs: run: rm -rf wpt working-directory: test/fixtures - name: Checkout epochs/daily WPT - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: repository: web-platform-tests/wpt persist-credentials: false @@ -109,7 +109,7 @@ jobs: # version-specific checkout above overwrites .github/actions/ - name: Checkout undici WPT actions if: ${{ env.WPT_REPORT != '' }} - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: sparse-checkout: | .github/actions/undici-wpt-current diff --git a/.github/workflows/daily.yml b/.github/workflows/daily.yml index 6c4b2ec9a4be..b7a616e2df5d 100644 --- a/.github/workflows/daily.yml +++ b/.github/workflows/daily.yml @@ -16,11 +16,11 @@ jobs: if: github.repository == 'nodejs/node' || github.event_name == 'workflow_dispatch' runs-on: ubuntu-24.04-arm steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Use Node.js ${{ env.NODE_VERSION }} - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: node-version: ${{ env.NODE_VERSION }} - name: Build lto diff --git a/.github/workflows/doc.yml b/.github/workflows/doc.yml index 6e5dfe732646..693d9ad3dd24 100644 --- a/.github/workflows/doc.yml +++ b/.github/workflows/doc.yml @@ -24,11 +24,11 @@ jobs: if: github.event.pull_request.draft == false runs-on: ubuntu-slim steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Use Node.js ${{ env.NODE_VERSION }} - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: node-version: ${{ env.NODE_VERSION }} - name: Build diff --git a/.github/workflows/find-inactive-collaborators.yml b/.github/workflows/find-inactive-collaborators.yml index e6e0c7f54f69..8c74fda22428 100644 --- a/.github/workflows/find-inactive-collaborators.yml +++ b/.github/workflows/find-inactive-collaborators.yml @@ -19,13 +19,13 @@ jobs: runs-on: ubuntu-slim steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 persist-credentials: false - name: Use Node.js ${{ env.NODE_VERSION }} - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: node-version: ${{ env.NODE_VERSION }} diff --git a/.github/workflows/find-inactive-tsc.yml b/.github/workflows/find-inactive-tsc.yml index c1804b78d378..d59f26b73b2b 100644 --- a/.github/workflows/find-inactive-tsc.yml +++ b/.github/workflows/find-inactive-tsc.yml @@ -20,13 +20,13 @@ jobs: steps: - name: Checkout the repo - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 persist-credentials: false - name: Clone nodejs/TSC repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 path: .tmp @@ -34,7 +34,7 @@ jobs: repository: nodejs/TSC - name: Use Node.js ${{ env.NODE_VERSION }} - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: node-version: ${{ env.NODE_VERSION }} diff --git a/.github/workflows/license-builder.yml b/.github/workflows/license-builder.yml index a95ee13c45f4..3bdf3fc31dcc 100644 --- a/.github/workflows/license-builder.yml +++ b/.github/workflows/license-builder.yml @@ -17,7 +17,7 @@ jobs: if: github.repository == 'nodejs/node' runs-on: ubuntu-slim steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - run: ./tools/license-builder.sh # Run the license builder tool diff --git a/.github/workflows/lint-release-proposal.yml b/.github/workflows/lint-release-proposal.yml index e8ffab178458..027aee336ace 100644 --- a/.github/workflows/lint-release-proposal.yml +++ b/.github/workflows/lint-release-proposal.yml @@ -23,7 +23,7 @@ jobs: contents: read pull-requests: read steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false fetch-depth: 2 diff --git a/.github/workflows/linters.yml b/.github/workflows/linters.yml index 6917eb995c9e..848fffc117a1 100644 --- a/.github/workflows/linters.yml +++ b/.github/workflows/linters.yml @@ -25,11 +25,11 @@ jobs: if: github.event.pull_request.draft == false runs-on: ubuntu-slim steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Use Node.js ${{ env.NODE_VERSION }} - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: node-version: ${{ env.NODE_VERSION }} - name: Lint addon docs @@ -38,7 +38,7 @@ jobs: if: github.event.pull_request.draft == false runs-on: ubuntu-slim steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} @@ -52,12 +52,12 @@ jobs: if: ${{ github.event.pull_request && github.event.pull_request.draft == false && github.base_ref == github.event.repository.default_branch }} runs-on: ubuntu-slim steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 persist-credentials: false - name: Use Node.js ${{ env.NODE_VERSION }} - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: node-version: ${{ env.NODE_VERSION }} - name: Set up Python ${{ env.PYTHON_VERSION }} @@ -89,11 +89,11 @@ jobs: if: github.event.pull_request.draft == false runs-on: ubuntu-slim steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Use Node.js ${{ env.NODE_VERSION }} - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: node-version: ${{ env.NODE_VERSION }} - name: Lint JavaScript files @@ -137,7 +137,7 @@ jobs: if: github.event.pull_request.draft == false runs-on: ubuntu-slim steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false sparse-checkout: | @@ -163,7 +163,7 @@ jobs: if: github.event.pull_request.draft == false runs-on: ubuntu-slim steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false sparse-checkout: | @@ -186,7 +186,7 @@ jobs: if: github.event.pull_request.draft == false runs-on: ubuntu-slim steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false sparse-checkout: | @@ -202,7 +202,7 @@ jobs: # cannot use ubuntu-24.04-arm here because the docker image is x86 only runs-on: ubuntu-latest steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - uses: mszostok/codeowners-validator@7f3f5e28c6d7b8dfae5731e54ce2272ca384592f @@ -212,7 +212,7 @@ jobs: if: ${{ github.event.pull_request }} runs-on: ubuntu-slim steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 2 persist-credentials: false @@ -227,7 +227,7 @@ jobs: lint-readme: runs-on: ubuntu-slim steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false sparse-checkout: | diff --git a/.github/workflows/nix-changes.yml b/.github/workflows/nix-changes.yml index ed25798152e3..a56cea0936c4 100644 --- a/.github/workflows/nix-changes.yml +++ b/.github/workflows/nix-changes.yml @@ -45,7 +45,7 @@ jobs: name: '${{ matrix.system }}: dependencies diff' runs-on: ${{ matrix.runner }} steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 2 persist-credentials: false @@ -54,7 +54,7 @@ jobs: tools/nix/ sparse-checkout-cone-mode: false - - uses: cachix/install-nix-action@630ae543ea3a38a9a4166f03376c02c50f408342 # v31.11.0 + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 with: extra_nix_config: sandbox = true @@ -103,12 +103,12 @@ jobs: if: github.event.pull_request.draft == false runs-on: ubuntu-slim steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false sparse-checkout: '*.nix' sparse-checkout-cone-mode: false - - uses: cachix/install-nix-action@630ae543ea3a38a9a4166f03376c02c50f408342 # v31.11.0 + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 - name: Lint Nix files run: | nix-shell -I nixpkgs=./tools/nix/pkgs.nix -p 'nixfmt-tree' --run ' diff --git a/.github/workflows/notify-on-push.yml b/.github/workflows/notify-on-push.yml index e709df93a8d7..16bd91bccd2a 100644 --- a/.github/workflows/notify-on-push.yml +++ b/.github/workflows/notify-on-push.yml @@ -32,12 +32,15 @@ jobs: SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} validateCommitMessage: + # If a commit is force-pushed out of the main branch, the `commits` array is + # empty and there are no checks to run. + if: github.event.commits[0] name: Notify on Push on `main` with invalid message # cannot use ubuntu-slim here because rtCamp/action-slack-notify is dockerized runs-on: ubuntu-24.04-arm steps: - name: Install Node.js - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: node-version: ${{ env.NODE_VERSION }} - name: Validate commits diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index f84c91e1a381..5042342ca70c 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -36,12 +36,12 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 + uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs - name: Checkout code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false @@ -76,6 +76,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: Upload to code-scanning - uses: github/codeql-action/upload-sarif@e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81 # v4.37.3 + uses: github/codeql-action/upload-sarif@cdf488f595d80d6e07e03d4674febd5ab45fa938 # v4.37.9 with: sarif_file: results.sarif diff --git a/.github/workflows/stress-test.yml b/.github/workflows/stress-test.yml index 6f1e75813915..1c93d4ba3dda 100644 --- a/.github/workflows/stress-test.yml +++ b/.github/workflows/stress-test.yml @@ -54,7 +54,7 @@ jobs: SCCACHE_GHA_ENABLED: 'true' SCCACHE_IDLE_TIMEOUT: '0' steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false path: node diff --git a/.github/workflows/test-internet.yml b/.github/workflows/test-internet.yml index 7052f014b200..08677618b3d6 100644 --- a/.github/workflows/test-internet.yml +++ b/.github/workflows/test-internet.yml @@ -47,7 +47,7 @@ jobs: if: (github.event_name == 'schedule' && github.repository == 'nodejs/node') || (github.event.pull_request && github.event.pull_request.draft == false) runs-on: ubuntu-24.04-arm steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Install Clang ${{ env.CLANG_VERSION }} diff --git a/.github/workflows/test-linux-perfetto.yml b/.github/workflows/test-linux-perfetto.yml new file mode 100644 index 000000000000..70a92202c1c7 --- /dev/null +++ b/.github/workflows/test-linux-perfetto.yml @@ -0,0 +1,70 @@ +name: Test Linux (with Perfetto) + +on: + workflow_dispatch: + pull_request: + # Only targeting paths specific to the vendored version of Perfetto, `test-shared` + # is taking care of rest of the coverage. + paths: + - .github/workflows/test-linux-perfetto.yml + - common.gypi + - configure.py + - deps/perfetto/** + - node.gyp + - node.gypi + - tools/v8_gypfiles/v8.gyp + types: [opened, synchronize, reopened, ready_for_review] + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +env: + PYTHON_VERSION: '3.14' + FLAKY_TESTS: keep_retrying + CLANG_VERSION: '19' + CC: ${{ (github.base_ref == 'main' || github.ref_name == 'main') && 'sccache' || '' }} clang-19 + CXX: ${{ (github.base_ref == 'main' || github.ref_name == 'main') && 'sccache' || '' }} clang++-19 + SCCACHE_GHA_ENABLED: ${{ github.base_ref == 'main' || github.ref_name == 'main' }} + SCCACHE_IDLE_TIMEOUT: '0' + RUSTC_VERSION: '1.86' + +permissions: + contents: read + +jobs: + test-perfetto: + if: github.event.pull_request.draft == false + runs-on: ubuntu-24.04-arm + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + path: node + - name: Install Clang ${{ env.CLANG_VERSION }} + uses: ./node/.github/actions/install-clang + with: + clang-version: ${{ env.CLANG_VERSION }} + - name: Install Rust ${{ env.RUSTC_VERSION }} + run: | + rustup override set "$RUSTC_VERSION" + rustup --version + - name: Set up Python ${{ env.PYTHON_VERSION }} + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 + with: + python-version: ${{ env.PYTHON_VERSION }} + allow-prereleases: true + - name: Set up sccache + if: github.base_ref == 'main' || github.ref_name == 'main' + uses: Mozilla-Actions/sccache-action@fc920bf0ec8de6ee65d409111f7ec508035751ba # v0.0.11 + with: + version: v0.17.0 + - name: Build + working-directory: node + run: make build-ci -j4 V=1 CONFIG_FLAGS="--error-on-warn --v8-enable-temporal-support --with-perfetto" + - name: Test + working-directory: node + run: make test-ci -j1 V=1 TEST_CI_ARGS="-p actions --measure-flakiness 9" + - name: Ensure running tests did not cause any change in the tree + working-directory: node + run: git add -A && git diff --name-only --exit-code --staged diff --git a/.github/workflows/test-linux-quic.yml b/.github/workflows/test-linux-quic.yml index e1a05cf91859..70aa8d9b04d1 100644 --- a/.github/workflows/test-linux-quic.yml +++ b/.github/workflows/test-linux-quic.yml @@ -47,7 +47,7 @@ jobs: if: github.event.pull_request.draft == false runs-on: ubuntu-24.04-arm steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false path: node diff --git a/.github/workflows/test-linux.yml b/.github/workflows/test-linux.yml index 7681a176139d..408371f3313c 100644 --- a/.github/workflows/test-linux.yml +++ b/.github/workflows/test-linux.yml @@ -60,7 +60,7 @@ jobs: matrix: os: [ubuntu-24.04, ubuntu-24.04-arm] steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false path: node diff --git a/.github/workflows/test-macos.yml b/.github/workflows/test-macos.yml index c53bcde2851c..6954112115ef 100644 --- a/.github/workflows/test-macos.yml +++ b/.github/workflows/test-macos.yml @@ -85,7 +85,7 @@ jobs: SCCACHE_GHA_ENABLED: ${{ github.base_ref == 'main' || github.ref_name == 'main' }} SCCACHE_IDLE_TIMEOUT: '0' steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false path: node diff --git a/.github/workflows/test-shared.yml b/.github/workflows/test-shared.yml index 8a04fe4d74fc..f7483103016f 100644 --- a/.github/workflows/test-shared.yml +++ b/.github/workflows/test-shared.yml @@ -29,10 +29,13 @@ on: - deps/nghttp2/** - deps/ngtcp2/** - deps/openssl/*/** + - deps/perfetto/** - deps/simdjson/** - deps/sqlite/** - deps/uv/** - deps/uvwasi/** + - deps/v8/third_party/abseil-cpp/** + - deps/v8/third_party/highway/** - deps/zlib/** - deps/zstd/** - doc/** @@ -82,10 +85,13 @@ on: - deps/nghttp2/** - deps/ngtcp2/** - deps/openssl/*/** + - deps/perfetto/** - deps/simdjson/** - deps/sqlite/** - deps/uv/** - deps/uvwasi/** + - deps/v8/third_party/abseil-cpp/** + - deps/v8/third_party/highway/** - deps/zlib/** - deps/zstd/** - doc/** @@ -117,7 +123,7 @@ jobs: name: ${{ github.event_name == 'workflow_dispatch' && 'Skipped job' || 'Build slim tarball' }} runs-on: ubuntu-slim steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false @@ -184,7 +190,7 @@ jobs: tar xzf tarballs/*.tar.gz -C "$RUNNER_TEMP" echo "TAR_DIR=$RUNNER_TEMP/$(basename tarballs/*.tar.gz .tar.gz)" >> "$GITHUB_ENV" - - uses: cachix/install-nix-action@630ae543ea3a38a9a4166f03376c02c50f408342 # v31.11.0 + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 with: extra_nix_config: sandbox = true diff --git a/.github/workflows/timezone-update.yml b/.github/workflows/timezone-update.yml index 94961f8ae6ed..481c20da4e05 100644 --- a/.github/workflows/timezone-update.yml +++ b/.github/workflows/timezone-update.yml @@ -21,12 +21,12 @@ jobs: steps: - name: Checkout nodejs/node - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Checkout unicode-org/icu-data - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: path: icu-data persist-credentials: false diff --git a/.github/workflows/tools.yml b/.github/workflows/tools.yml index e80b65315a4a..097902102685 100644 --- a/.github/workflows/tools.yml +++ b/.github/workflows/tools.yml @@ -316,7 +316,7 @@ jobs: tail -n1 temp-output | grep "NEW_VERSION=" >> "$GITHUB_ENV" || true rm temp-output steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 if: github.event_name == 'schedule' || inputs.id == 'all' || inputs.id == matrix.id with: persist-credentials: false @@ -330,7 +330,7 @@ jobs: allow-prereleases: true - name: Set up Nix if: matrix.id == 'nixpkgs-unstable' && (github.event_name == 'schedule' || inputs.id == 'all' || inputs.id == matrix.id) - uses: cachix/install-nix-action@630ae543ea3a38a9a4166f03376c02c50f408342 # v31.11.0 + uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 - run: ${{ matrix.run }} if: github.event_name == 'schedule' || inputs.id == 'all' || inputs.id == matrix.id env: diff --git a/.github/workflows/update-openssl.yml b/.github/workflows/update-openssl.yml index 49f0006526b0..10eb3289a1f7 100644 --- a/.github/workflows/update-openssl.yml +++ b/.github/workflows/update-openssl.yml @@ -15,7 +15,7 @@ jobs: # Cannot use ubuntu-slim here because the update script requires Docker runs-on: ubuntu-latest steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Check and download new OpenSSL version diff --git a/.github/workflows/update-v8.yml b/.github/workflows/update-v8.yml index e365cf770174..8e71e563896b 100644 --- a/.github/workflows/update-v8.yml +++ b/.github/workflows/update-v8.yml @@ -16,7 +16,7 @@ jobs: if: github.repository == 'nodejs/node' runs-on: ubuntu-slim steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Cache node modules and update-v8 @@ -30,7 +30,7 @@ jobs: ~/.npm key: ${{ runner.os }}-build-${{ env.cache-name }} - name: Install Node.js - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: node-version: ${{ env.NODE_VERSION }} - name: Install @node-core/utils diff --git a/.github/workflows/update-wpt.yml b/.github/workflows/update-wpt.yml index 4f752cc18985..7b59a2f137f3 100644 --- a/.github/workflows/update-wpt.yml +++ b/.github/workflows/update-wpt.yml @@ -27,12 +27,12 @@ jobs: subsystem: ${{ fromJSON(github.event.inputs.subsystems || '["url", "urlpattern", "WebCryptoAPI"]') }} steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Install Node.js - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: node-version: ${{ env.NODE_VERSION }} diff --git a/.gitignore b/.gitignore index 2a7ce3337021..9277cdf090f0 100644 --- a/.gitignore +++ b/.gitignore @@ -121,6 +121,7 @@ tools/*/*.i.tmp /*.xml /v8*-tap.json /node_trace.*.log +/node_trace.*.pftrace # coverage related /gcovr /build diff --git a/CHANGELOG.md b/CHANGELOG.md index 617be56138e2..91690bacc4ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,7 +41,8 @@ release. -26.8.1
+26.9.0
+26.8.1
26.8.0
26.7.0
26.6.0
diff --git a/LICENSE b/LICENSE index 9cc3315dd388..67cd2feb69a9 100644 --- a/LICENSE +++ b/LICENSE @@ -2600,29 +2600,6 @@ The externally maintained libraries used by Node.js are: WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ -- large_pages, located at src/large_pages, is licensed as follows: - """ - Copyright (C) 2018 Intel Corporation - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom - the Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES - OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - OR OTHER DEALINGS IN THE SOFTWARE. - """ - - caja, located at lib/internal/freeze_intrinsics.js, is licensed as follows: """ Adapted from SES/Caja - Copyright (C) 2011 Google Inc. diff --git a/Makefile b/Makefile index 4da0900c6fca..afa55b2da33e 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,8 @@ BUILDTYPE ?= Release PYTHON ?= python3 +RUFF ?= tools/pip/site-packages/bin/ruff +YAMLLINT ?= tools/pip/site-packages/bin/yamllint DESTDIR ?= SIGN ?= PREFIX ?= /usr/local @@ -881,6 +883,11 @@ else ifeq ($(OSTYPE),os400) # TODO(@nodejs/web-infra): IBMi is currently hanging during HTML minification $(apidocs_html) $(apidocs_json) out/doc/api/all.html out/doc/api/all.json: @echo "Skipping $@ (not currently supported by $(OSTYPE) machines)" +else ifeq ($(ARCHTYPE),riscv64) +# Many riscv64 environments (except qemu) fail on the wasm steps here +# https://github.com/nodejs/build/issues/4099#issuecomment-4038743335 +$(apidocs_html) $(apidocs_json) out/doc/api/all.html out/doc/api/all.json: + @echo "Skipping $@ (not currently supported by $(DESTCPU) machines)" else $(apidocs_html) $(apidocs_json) out/doc/api/all.html out/doc/api/all.json &: $(apidoc_sources) tools/doc/node_modules | out/doc/api @if [ "$(shell $(node_use_openssl_and_icu))" != "true" ]; then \ @@ -1312,10 +1319,13 @@ ifeq ($(SKIP_SHARED_DEPS), 1) $(RM) -r $(TARNAME)/deps/ngtcp2 find $(TARNAME)/deps/openssl -maxdepth 1 -type f ! -name 'nodejs-openssl.cnf' -exec $(RM) {} + find $(TARNAME)/deps/openssl -mindepth 1 -maxdepth 1 -type d -exec $(RM) -r {} + + $(RM) -r $(TARNAME)/deps/perfetto $(RM) -r $(TARNAME)/deps/simdjson $(RM) -r $(TARNAME)/deps/sqlite $(RM) -r $(TARNAME)/deps/uv $(RM) -r $(TARNAME)/deps/uvwasi + $(RM) -r $(TARNAME)/deps/v8/third_party/abseil-cpp + $(RM) -r $(TARNAME)/deps/v8/third_party/highway $(RM) -r $(TARNAME)/deps/zlib $(RM) -r $(TARNAME)/deps/zstd else @@ -1528,7 +1538,8 @@ format-md: tools/lint-md/node_modules/remark-parse/package.json ## Format the ma LINT_JS_TARGETS = eslint.config.mjs benchmark doc lib test tools run-lint-js = tools/eslint/node_modules/eslint/bin/eslint.js --cache \ - --max-warnings=0 --report-unused-disable-directives $(LINT_JS_TARGETS) + --max-warnings=0 --report-unused-disable-directives \ + --concurrency auto $(LINT_JS_TARGETS) run-lint-js-fix = $(run-lint-js) --fix tools/eslint/node_modules/eslint/bin/eslint.js: tools/eslint/package-lock.json @@ -1555,7 +1566,7 @@ jslint: lint-js run-lint-js-ci = tools/eslint/node_modules/eslint/bin/eslint.js \ --max-warnings=0 --report-unused-disable-directives -f tap \ - -o test-eslint.tap $(LINT_JS_TARGETS) + --concurrency auto -o test-eslint.tap $(LINT_JS_TARGETS) .PHONY: lint-js-ci # On the CI the output is emitted in the TAP format. @@ -1693,15 +1704,15 @@ lint-py-build: ## Build resources needed to lint python files. $(PYTHON) -m pip install --upgrade --system --target tools/pip/site-packages ruff==0.13.1 .PHONY: lint-py lint-py-fix lint-py-fix-unsafe -ifneq ("","$(wildcard tools/pip/site-packages/ruff)") +ifneq ("","$(wildcard $(RUFF))") # Lint the Python code with ruff. lint-py: $(info Running Python linter...) - tools/pip/site-packages/bin/ruff check . + $(RUFF) check . lint-py-fix: - tools/pip/site-packages/bin/ruff check . --fix + $(RUFF) check . --fix lint-py-fix-unsafe: - tools/pip/site-packages/bin/ruff check . --fix --unsafe-fixes + $(RUFF) check . --fix --unsafe-fixes else lint-py lint-py-fix lint-py-fix-unsafe: $(warning Python linting with ruff is not available) @@ -1717,14 +1728,15 @@ lint-yaml-build: ## Build resources needed to lint YAML files. $(PYTHON) -m pip install --upgrade --system -t tools/pip/site-packages yamllint .PHONY: lint-yaml +ifneq ("","$(wildcard $(YAMLLINT))") lint-yaml: ## Lint the YAML files with yamllint. - @if [ -d "tools/pip/site-packages/yamllint" ]; then \ - $(info Running YAML linter...) \ - PYTHONPATH=tools/pip $(PYTHON) -m yamllint .; \ - else \ - echo 'YAML linting with yamllint is not available'; \ - echo "Run 'make lint-yaml-build'"; \ - fi + $(info Running YAML linter...) + PYTHONPATH=tools/pip $(YAMLLINT) . +else +lint-yaml: + $(warning YAML linting with yamllint is not available) + $(warning Run 'make lint-yaml-build') +endif .PHONY: lint .PHONY: lint-ci diff --git a/README.md b/README.md index 3827556a44fb..0376c0e9814c 100644 --- a/README.md +++ b/README.md @@ -800,7 +800,6 @@ that server. gpg --keyserver hkps://keys.openpgp.org --recv-keys 5BE8A3F6C8A5C01D106C0AD820B1A390B168D356 # Antoine du Hamel gpg --keyserver hkps://keys.openpgp.org --recv-keys DD792F5973C6DE52C432CBDAC77ABFA00DDBF2B7 # Juan José Arboleda gpg --keyserver hkps://keys.openpgp.org --recv-keys CC68F5A3106FF448322E48ED27F5E38D5B0A215F # Marco Ippolito -gpg --keyserver hkps://keys.openpgp.org --recv-keys 8FCCA13FEF1D0C2E91008E09770F7A9A5AE15600 # Michaël Zasso gpg --keyserver hkps://keys.openpgp.org --recv-keys 890C08DB8579162FEE0DF9DB8BEAB4DFCF555EF4 # Rafael Gonzaga gpg --keyserver hkps://keys.openpgp.org --recv-keys C82FA3AE1CBEDC6BE46B9360C43CEC45C17AB93C # Richard Lau gpg --keyserver hkps://keys.openpgp.org --recv-keys 108F52B48DB57BB0CC439B2997B01419BD92F80A # Ruy Adorno diff --git a/SECURITY.md b/SECURITY.md index b4239f5fda4e..17d35fd4432f 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -124,12 +124,12 @@ This policy recognizes that experimental platforms may not compile, may not pass the test suite, and do not have the same level of testing and support infrastructure as Tier 1 and Tier 2 platforms. -### Experimental features behind compile-time flags and V8 flags +### Experimental features behind compile-time flags, experimental runtime flags, and V8 flags Node.js includes certain experimental features that are only available when -Node.js is compiled with specific flags. These features are intended for -development, debugging, or testing purposes and are not enabled in official -releases. +Node.js is compiled with specific flags or that are only enabled with experimental +runtime flags. These features are intended for development, debugging, or testing +purposes and are not enabled or supported in official releases. Node.js may also expose V8 features that are controlled by V8 command-line flags (e.g., `--js-staging`, `--max_old_space_size`). These flags @@ -137,8 +137,30 @@ enable or modify V8-level JavaScript engine behavior that is not part of the ECMAScript specification that Node.js implements and is not part of the Node.js documented API surface. +#### Runtime gated experimental features + +Experimental features behind runtime flags can fall into one of three +[categories](https://github.com/nodejs/node/blob/main/doc/api/documentation.md?rgh-link-date=2026-08-21T20%3A28%3A33.000Z#stability-index): + +* 1.0 - Early development. +* 1.1 - Active development. +* 1.2 - Release candidate. + +Security vulnerabilities that only affect experimental features in either the +1.0 or 1.1 stages, and that are gated with an `--experimental-*` runtime flag +requiring explicit opt-in by the user to enable, will **not** be accepted as +valid security issues unless the vulnerability can be exploited in a way that +impacts the security of a stable feature when the associated `--experimental-*` +flag is **not enabled**. + +Security vulnerabilities that affect experimental features in the 1.2 stage are +acceptable as valid security issues. + +#### Compile-time gated experimental features and V8 flags + * Security vulnerabilities that only affect features behind compile-time flags - or V8 flags will **not** be accepted as valid security issues. + or V8 flags _that are not enabled by default_ will **not** be accepted as valid + security issues. * Any issues with these features will be treated as normal bugs. * No CVEs will be issued for issues that only affect compile-time flag or V8 flag features. * Bug bounty rewards are not available for compile-time flag or V8 flag feature issues. @@ -151,6 +173,28 @@ are not part of the Node.js documented API surface, are not enabled by default in production builds, and may have incomplete implementations or missing security hardening. +### Security triage dispositions + +When triaging a report, the project classifies it into one of the following +dispositions: + +* **Vulnerability**: A Node.js defect that is exploitable across a + Node.js-owned security boundary and meets the criteria under + [What constitutes a vulnerability](#what-constitutes-a-vulnerability), + including any applicable DoS criteria. +* **Security-interest bug**: A real Node.js defect, or an API behavior likely + to cause security bugs in applications, that is not itself a vulnerability + under this threat model. These are fixed as regular bugs and do not + automatically receive a CVE, but should still be reported privately first + when they affect a common security control such as protocol interpretation, + permission enforcement, or certificate/TLS decisions. +* **Common bug**: A correctness, robustness, or crash issue without a + Node.js-owned security boundary or a realistic cross-boundary attacker benefit. +* **Invalid / out of scope**: A bug report that meets one of these criteria: + * Cannot be reproduced + * Is not a Node.js defect (e.g., an application bug) + * Is excluded by policy (e.g., experimental features) + ### What constitutes a vulnerability Being able to cause the following through control of the elements that Node.js @@ -329,6 +373,19 @@ the community they pose. * Code is trusted by Node.js. Therefore any scenario that requires a malicious third-party module cannot result in a vulnerability in Node.js. +#### Same-process self-harm + +* Node.js trusts the code it is asked to run. A defect that can only be + triggered by JavaScript, WASM, native, addon, FFI, or dependency code already + executing in the target process is not a Node.js vulnerability merely because + that code can crash, corrupt, or confuse the process it already controls. + This includes forging an internal handle, reflecting or overwriting an + internal `Symbol()`, installing a `Symbol.hasInstance` hook, or reaching into + an internal binding. +* Such issues may still be fixed as common bugs. They become vulnerabilities + only if the same defect is reachable from an element Node.js does not trust + without relying on an application-created boundary. + #### Prototype Pollution Attacks (CWE-1321) * Node.js trusts the inputs provided to it by application code. @@ -445,6 +502,21 @@ resources a Node.js process may access. It is designed to reduce the blast radius of mistakes in trusted application code, **not** to act as a security boundary against intentional misuse or a compromised process. +Permission Model reports are triaged in three lanes: + +* **Vulnerability**: An element Node.js does not trust crosses a Node.js-owned + permission check without trusted code already executing in the protected + process. +* **Security-interest bug**: Trusted application code uses documented, stable + APIs as intended, but Node.js fails to enforce a documented permission + invariant consistently — for example, one API enforces a check that an + equivalent API omits. These are fixed as hardening and are not automatically + CVE-class, because the Permission Model is not a sandbox against malicious + same-process code. +* **Excluded**: Intentional misuse by code already running in the process, + operator-selected flags, a modified `execArgv`/`env`, or any expectation that + the Permission Model sandboxes malicious same-process code. + The following are **not** vulnerabilities in Node.js: * **Operator-controlled flags**: Behavior unlocked by flags the operator @@ -465,9 +537,23 @@ The following are **not** vulnerabilities in Node.js: symlinks that resolve within the allowed list are similarly not considered permission model bypasses. -* **`worker_threads` with modified `execArgv`**: Workers inherit the permission - restrictions of their parent process. Passing an empty or modified `execArgv` - to a worker does not grant it additional permissions. +* **`worker_threads` and the permission model**: Creating a worker is gated by + `--allow-worker`. A worker started with a modified `execArgv` or `env` may + start without inheriting the parent's permission configuration, so the + permission model does not reliably propagate to such workers. Because worker + creation already requires `--allow-worker`, and the Permission Model is not a + sandbox against intentional misuse by trusted code, this is not considered a + vulnerability. Applications that rely on the Permission Model must not grant + `--allow-worker` to code they do not trust. + +#### QUIC and HTTP/3 + +The experimental QUIC and HTTP/3 implementation in Node.js is a complex new +protocol stack and API that is still under active development and should not be +used for production workloads. Reports that only affect QUIC or HTTP/3 are not +considered Node.js vulnerabilities at this time. It is expected that the QUIC +and HTTP/3 implementation will continue to evolve, and security issues will be +addressed as the implementation matures. #### Virtual File System (`node:vfs`) @@ -505,12 +591,6 @@ vulnerability. Node.js validates the structure of Early Hints per the HTTP spec but does not sanitize free-form application data passed to it; that is the application's responsibility. -## Assessing experimental features reports - -Experimental features are eligible for security reports just like any other -stable feature of Node.js. They may also receive the same severity score that a -stable feature would. - ## Receiving security updates Security notifications will be distributed via the following methods. diff --git a/benchmark/README.md b/benchmark/README.md index 2f52a44f251a..78a55fba453f 100644 --- a/benchmark/README.md +++ b/benchmark/README.md @@ -10,6 +10,7 @@ directory, see [the guide on benchmarks](../doc/contributing/writing-and-running ## Table of Contents * [File tree structure](#file-tree-structure) +* [`node:bench` evaluation tools](#nodebench-evaluation-tools) * [Common API](#common-api) ## File tree structure @@ -34,7 +35,7 @@ The actual benchmark scripts should be placed in their corresponding directories. * `_benchmark_progress.js`: implements the progress bar displayed - when running `compare.js` + when running `compare.js` and `scatter.js` * `_cli.js`: parses the command line arguments passed to `compare.js`, `run.js` and `scatter.js` * `_cli.R`: parses the command line arguments passed to `compare.R` @@ -44,15 +45,92 @@ directories. * `common.js`: see [Common API](#common-api). * `compare.js`: command line tool for comparing performance between different Node.js binaries. +* `compare-node-bench.js`: parallel comparison tool for explicit `node:bench` + files. It does not change or invoke `compare.js`. * `compare.R`: R script for statistically analyzing the output of `compare.js` * `run.js`: command line tool for running individual benchmark suite(s). * `scatter.js`: command line tool for comparing the performance between different parameters in benchmark configurations, - for example to analyze the time complexity. + for example to analyze the time complexity. Pass `--analyze` to + summarize the results without R. +* `scatter-node-bench.js`: parallel scatter-data tool for an explicit + `node:bench` file. It does not change or invoke `scatter.js`. * `scatter.R`: R script for visualizing the output of `scatter.js` with scatter plots. +## `node:bench` evaluation tools + +The `compare-node-bench.js` and `scatter-node-bench.js` tools run explicit +`node:bench` files without changing the existing benchmark framework or its +tools. Each repeated observation for a benchmark identity is collected by a +separate process invocation with one measured sample. Benchmarks declared in +the same file still execute serially in that process and can share JIT, garbage +collector, heap, and cache state. This differs from legacy configuration-level +process isolation and must be considered when comparing the frameworks. + +Compare two binaries and analyze the compatible CSV using `compare.R`: + +```console +./node benchmark/compare-node-bench.js \ + --old ./node-main --new ./node-pr --runs 30 -- \ + benchmark/crypto/_create-hash.node-bench.js > compare-node-bench.csv +Rscript benchmark/compare.R < compare-node-bench.csv +``` + +Pass `--analyze` to run the same Welch analysis inline. `--max-regression N` +implies `--analyze` and makes the command fail only when the Holm-Bonferroni +adjusted one-sided p-value against the `N%` threshold is below 0.05 and the full +95% confidence interval is worse than `-N%`. Requiring both conditions prevents +a noisy point estimate from failing a regression gate. + +```console +./node benchmark/compare-node-bench.js \ + --old ./node-main --new ./node-pr --runs 30 \ + --max-regression 5 -- benchmark/crypto/_create-hash.node-bench.js +``` + +Collect parameter data for the parallel buffer benchmark and plot it using +`scatter.R`: + +```console +./node benchmark/scatter-node-bench.js --node ./node --runs 30 -- \ + benchmark/buffers/_buffer-compare-offset.node-bench.js \ + > scatter-node-bench.csv +Rscript benchmark/scatter.R --xaxis size --category method \ + --plot scatter-node-bench.png < scatter-node-bench.csv +``` + +Pass `--analyze` with an x-axis parameter to summarize the samples without R. +The output includes mean and median confidence intervals, skew warnings, an +optional bar chart, and Mann-Whitney U and Cliff's delta comparisons between +consecutive x-axis values. Use `--category` for a second grouping parameter and +`--no-chart` to omit the chart. + +Because configurations in one file share a process, inline analysis averages +aggregated configurations into one value per outer process. Consecutive +x-axis comparisons use alternating, disjoint process sets so the unpaired +Mann-Whitney test does not treat correlated values as independent samples. + +```console +./node benchmark/scatter-node-bench.js --runs 30 --analyze \ + --xaxis size --category method -- \ + benchmark/buffers/_buffer-compare-offset.node-bench.js +``` + +A file passed to `scatter-node-bench.js` must use one logical benchmark name. +Parameter values distinguish its configurations. The tool rejects unstable +identities and names or parameters that would merge unrelated CSV groups. + +The underscore-prefixed benchmark files are parallel ports used to compare the +measurement frameworks. Legacy discovery ignores them, so the original files +remain the source benchmarks for `run.js`, `compare.js`, and `scatter.js`. The +ports use the platform-specific original relative filename as their benchmark +name and preserve parameter column names to keep CSV grouping compatible. For +a direct framework comparison, collect the same number of runs from an +original benchmark with `scatter.js` and from its port with +`scatter-node-bench.js`, then compare their rate distributions. + ## Common API The common.js module is used by benchmarks for consistency across repeated diff --git a/benchmark/_node-bench-analysis.js b/benchmark/_node-bench-analysis.js new file mode 100644 index 000000000000..bf0f7402b791 --- /dev/null +++ b/benchmark/_node-bench-analysis.js @@ -0,0 +1,763 @@ +'use strict'; + +const { createHistogram } = require('node:perf_hooks'); +const { inspect } = require('node:util'); + +function createRateHistogram(rates, scale, figures) { + const histogram = createHistogram({ figures }); + for (const rate of rates) { + const value = Math.max(1, Math.round(rate * scale)); + if (!Number.isSafeInteger(value)) { + throw new RangeError('Benchmark rate is too large for the histogram scale'); + } + histogram.record(value); + } + return histogram; +} + +function holmAdjust(pValues) { + const order = pValues + .map((p, index) => ({ index, p })) + .sort((a, b) => a.p - b.p); + const adjusted = new Array(order.length); + let running = 0; + for (let index = 0; index < order.length; index++) { + running = Math.max( + running, + Math.min(1, (order.length - index) * order[index].p), + ); + adjusted[order[index].index] = running; + } + return adjusted; +} + +function thresholdPValue(oldRates, newHistogram, scale, maxRegression) { + const factor = 1 - maxRegression / 100; + if (factor <= 0) return 1; + const thresholdHistogram = createRateHistogram( + oldRates.map((rate) => rate * factor), scale, 3); + const result = thresholdHistogram.welchTest(newHistogram); + if (Number.isNaN(result.pValue)) return 1; + return result.tStatistic > 0 ? + result.pValue / 2 : 1 - result.pValue / 2; +} + +function isRegressionFailure(row, maxRegression) { + return row.pThresholdAdjusted < 0.05 && + row.improvement + row.ci95 < -maxRegression; +} + +function analyzeCompare(samples, scale, maxRegression) { + const groups = new Map(); + for (const sample of samples) { + let group = groups.get(sample.identity); + if (group === undefined) { + const suffix = sample.configuration === '' ? + '' : ` ${sample.configuration}`; + group = { + name: `${sample.name}${suffix}`, + new: [], + old: [], + }; + groups.set(sample.identity, group); + } + group[sample.binary].push(sample.rate); + } + + const rows = []; + let skipped = 0; + for (const { name, old: oldRates, new: newRates } of groups.values()) { + if (oldRates.length < 2 || newRates.length < 2) { + skipped++; + continue; + } + + const oldHistogram = createRateHistogram(oldRates, scale, 3); + const newHistogram = createRateHistogram(newRates, scale, 3); + const oldMean = oldRates.reduce((sum, rate) => sum + rate, 0) / + oldRates.length; + const newMean = newRates.reduce((sum, rate) => sum + rate, 0) / + newRates.length; + const improvement = ((newMean - oldMean) / oldMean) * 100; + const w95 = oldHistogram.welchTest(newHistogram, { confidence: 0.95 }); + const w99 = oldHistogram.welchTest(newHistogram, { confidence: 0.99 }); + const w999 = oldHistogram.welchTest(newHistogram, { confidence: 0.999 }); + let stars = ''; + if (w95.pValue < 0.001) stars = '***'; + else if (w95.pValue < 0.01) stars = ' **'; + else if (w95.pValue < 0.05) stars = ' *'; + const ciPercent = (result) => { + const half = (result.confidenceInterval.upper - + result.confidenceInterval.lower) / 2; + return (half / (oldMean * scale)) * 100; + }; + const row = { + ci95: ciPercent(w95), + ci99: ciPercent(w99), + ci999: ciPercent(w999), + improvement, + name, + pValue: Number.isNaN(w95.pValue) ? 1 : w95.pValue, + stars, + }; + if (maxRegression !== undefined) { + row.pThreshold = thresholdPValue( + oldRates, newHistogram, scale, maxRegression); + } + rows.push(row); + } + + const adjusted = holmAdjust(rows.map(({ pValue }) => pValue)); + const thresholdAdjusted = maxRegression === undefined ? null : + holmAdjust(rows.map(({ pThreshold }) => pThreshold)); + let underpowered = 0; + for (let index = 0; index < rows.length; index++) { + const row = rows[index]; + row.pAdjusted = adjusted[index]; + if (thresholdAdjusted !== null) { + row.pThresholdAdjusted = thresholdAdjusted[index]; + } + row.inconclusive = maxRegression > 0 && + row.stars.trim() === '' && + row.ci95 > maxRegression; + if (row.inconclusive) underpowered++; + } + + const output = []; + const maxNameLength = rows.reduce( + (maximum, { name }) => Math.max(maximum, name.length), 0); + const pad = (value, length) => + value + ' '.repeat(Math.max(0, length - value.length)); + const padStart = (value, length) => + ' '.repeat(Math.max(0, length - value.length)) + value; + output.push(`${pad('', maxNameLength)} confidence` + + ' improvement accuracy (*) (**) (***)'); + for (const row of rows) { + const improvement = + `${row.improvement >= 0 ? '+' : ''}${row.improvement.toFixed(2)} %`; + output.push( + `${pad(row.name, maxNameLength)} ${pad(row.stars, 10)}` + + ` ${padStart(improvement, 11)}` + + ` ±${row.ci95.toFixed(2)}%` + + ` ±${row.ci99.toFixed(2)}%` + + ` ±${row.ci999.toFixed(2)}%` + + `${row.inconclusive ? ' (inconclusive)' : ''}`, + ); + } + + if (skipped > 0) { + output.push(''); + output.push( + `Note: ${skipped} configuration${skipped === 1 ? ' was' : 's were'}` + + ' skipped because Welch\'s t-test requires at least 2 samples per' + + ' binary. Use --runs 2 or higher.', + ); + } + printCompareChart(output, rows, maxNameLength); + + output.push(''); + output.push( + `Rates were scaled by ${scale}x into HdrHistogram (3 significant figures).`, + 'Use --scale to adjust precision if needed.', + '', + ); + const significant = rows.filter(({ pAdjusted }) => pAdjusted < 0.05).length; + output.push( + 'The confidence markers above are per-benchmark and uncorrected. ' + + `After Holm-Bonferroni correction across ${rows.length} comparison` + + `${rows.length === 1 ? '' : 's'}, ${significant} remain` + + `${significant === 1 ? 's' : ''} significant at 5%.`, + ); + if (maxRegression !== undefined) { + output.push( + `For --max-regression, one-sided p-values against the ` + + `${maxRegression}% threshold were corrected separately.`, + ); + } + + if (maxRegression > 0 && underpowered > 0) { + output.push(''); + output.push( + `Note: ${underpowered} of ${rows.length} comparison` + + `${rows.length === 1 ? '' : 's'} could not resolve an effect as small ` + + `as ${maxRegression}% and are marked (inconclusive). Raise --runs to ` + + 'narrow their confidence intervals.', + ); + } + + const failures = maxRegression !== undefined ? + rows.filter((row) => isRegressionFailure(row, maxRegression)) : []; + if (failures.length > 0) { + output.push(''); + output.push( + `FAIL: ${failures.length} benchmark${failures.length === 1 ? '' : 's'}` + + ` regressed by more than ${maxRegression}% (the 95% interval excludes ` + + `the threshold and its one-sided test is family-wise corrected across ` + + `${rows.length} comparisons):`, + ); + for (const failure of failures) { + output.push( + ` ${failure.name} ${failure.improvement.toFixed(2)}% ` + + `(95% CI up to ${(failure.improvement + failure.ci95).toFixed(2)}%, ` + + `adjusted threshold p=` + + `${failure.pThresholdAdjusted.toExponential(2)})`, + ); + } + } + + return { + failed: failures.length > 0, + output: `${output.join('\n')}\n`, + rows, + }; +} + +function printCompareChart(output, rows, maxNameLength) { + if (rows.length === 0) return; + const width = 40; + const halfWidth = width / 2; + let maximum = 0; + for (const row of rows) { + maximum = Math.max(maximum, Math.abs(row.improvement) + row.ci95); + } + if (maximum === 0) maximum = 1; + const left = `-${maximum.toFixed(1)}%`; + const right = `+${maximum.toFixed(1)}%`; + const centerLabel = '0%'; + const labelPadding = maxNameLength + 5; + output.push(''); + output.push( + ' '.repeat(labelPadding) + left + + ' '.repeat(Math.max( + 0, halfWidth - left.length - Math.floor(centerLabel.length / 2))) + + centerLabel + + ' '.repeat(Math.max( + 0, halfWidth - Math.ceil(centerLabel.length / 2) - right.length)) + + right, + ); + for (const row of rows) { + const center = halfWidth; + const result = center + (row.improvement / maximum) * halfWidth; + const lower = center + + ((row.improvement - row.ci95) / maximum) * halfWidth; + const upper = center + + ((row.improvement + row.ci95) / maximum) * halfWidth; + let bar = ''; + for (let index = 0; index < width; index++) { + const position = index + 0.5; + if (index === Math.floor(center)) { + bar += '|'; + } else if ((row.improvement >= 0 && + position > center && position <= result) || + (row.improvement < 0 && + position < center && position >= result)) { + bar += row.stars === '' ? '▓' : '█'; + } else if (position >= lower && position <= upper) { + bar += '░'; + } else { + bar += ' '; + } + } + const label = `${row.improvement >= 0 ? '+' : ''}` + + `${row.improvement.toFixed(2)}%`; + output.push( + `${row.name.padEnd(maxNameLength)} ${bar} ${label} ${row.stars.trim()}`, + ); + } +} + +function histogramScale(rates) { + let minimum = Infinity; + let maximum = 0; + for (const rate of rates) { + if (rate > 0 && rate < minimum) minimum = rate; + if (rate > maximum) maximum = rate; + } + if (!Number.isFinite(minimum) || maximum === 0) return 1; + let scale = 1; + while (minimum * scale < 1e6 && maximum * scale < 1e15) scale *= 10; + return scale; +} + +function validateScatterParameters(samples, xAxis, category) { + if (category !== undefined && category === xAxis) { + throw new Error('--xaxis and --category must name different parameters'); + } + for (const key of [xAxis, category]) { + if (key === undefined) continue; + if (samples.some(({ params }) => + !Object.hasOwn(params, key))) { + const available = [...new Set(samples.flatMap( + ({ params }) => Object.keys(params)))].sort(); + throw new Error( + `The variable '${key}' is not present in every configuration. ` + + `Available variables: ${available.join(', ')}`, + ); + } + } +} + +function analyzeScatter(samples, xAxis, category, showChart) { + validateScatterParameters(samples, xAxis, category); + + const parameterNames = [...new Set(samples.flatMap( + ({ params }) => Object.keys(params)))]; + const aggregated = parameterNames.filter((name) => { + if (name === xAxis || name === category) return false; + const first = samples[0].params[name]; + return samples.some(({ params }) => params[name] !== first); + }); + const groups = new Map(); + for (const sample of samples) { + const xValue = sample.params[xAxis]; + const categoryValue = category === undefined ? + undefined : sample.params[category]; + const key = valueKey([xValue, categoryValue]); + let group = groups.get(key); + if (group === undefined) { + group = { + categoryValue, + members: [], + observations: new Map(), + xValue, + }; + groups.set(key, group); + } + group.members.push(sample); + let rates = group.observations.get(sample.observation); + if (rates === undefined) { + rates = []; + group.observations.set(sample.observation, rates); + } + rates.push(sample.rate); + } + for (const group of groups.values()) { + group.processRates = [...group.observations].map(([observation, rates]) => ({ + observation, + rate: rates.reduce((sum, rate) => sum + rate, 0) / rates.length, + })); + group.rates = group.processRates.map(({ rate }) => rate); + } + + const scale = histogramScale(samples.map(({ rate }) => rate)); + const compareValues = (a, b) => { + if (typeof a === 'number' && typeof b === 'number') return a - b; + return String(a).localeCompare(String(b)); + }; + const rows = [...groups.values()] + .sort((a, b) => compareValues(a.xValue, b.xValue) || + compareValues(a.categoryValue, b.categoryValue)) + .map((group) => { + const histogram = createRateHistogram(group.rates, scale, 5); + const count = group.rates.length; + const mean = group.rates.reduce((sum, rate) => sum + rate, 0) / count; + const meanInterval = histogram.meanCI(); + const confidenceInterval = count > 1 ? + (meanInterval.upper - meanInterval.lower) / (2 * scale) : NaN; + const medianInterval = histogram.percentileCI(50); + const median = rawMedian(group.rates); + const skewed = count > 1 && + (Math.abs(histogram.skewness) > 1 || + Math.abs(median - mean) > confidenceInterval); + return { + ...group, + confidenceInterval, + count, + histogram, + mean, + median, + medianLower: medianInterval.lower / scale, + medianUpper: medianInterval.upper / scale, + skewed, + }; + }); + + const legend = assignLabels(rows, 'xValue', 'xLabel'); + if (category !== undefined) { + legend.push(...assignLabels(rows, 'categoryValue', 'categoryLabel')); + } + const output = []; + const contamination = new Map(); + for (const variable of aggregated) { + const share = varianceShare([...groups.values()], variable); + contamination.set(variable, share); + const percent = share === 1 ? + '100' : (share >= 0.995 ? '>99' : (share * 100).toFixed(0)); + const suffix = Number.isNaN(share) ? + '' : ` (explains ${percent}% of within-group variance)`; + output.push(`aggregating variable: ${variable}${suffix}`); + } + const dominant = aggregated.filter( + (variable) => contamination.get(variable) > 0.5); + if (dominant.length > 0) { + output.push(''); + wrapOutput( + output, + `${dominant.join(', ')} ${dominant.length === 1 ? 'explains' : 'explain'} ` + + 'most of the spread within each group. Pin the parameter or use it as ' + + '--category; increasing --runs will not remove this source of variance.', + ); + } + if (aggregated.length > 0) output.push(''); + printScatterTable(output, rows, xAxis, category); + if (showChart) printScatterChart(output, rows, xAxis, category); + printScatterComparisons(output, rows, xAxis, category); + if (legend.length > 0) { + output.push('', 'Abbreviated values:'); + for (const { full, label } of legend) { + output.push(` ${label}`, ` = ${full}`); + } + } + const singleSample = rows.filter(({ count }) => count < 2).length; + if (singleSample > 0) { + output.push(''); + wrapOutput( + output, + `Note: ${singleSample} group${singleSample === 1 ? ' has' : 's have'} ` + + 'only one sample, so no confidence interval could be estimated. Use ' + + '--runs 2 or higher.', + ); + } + if (rows.some(({ skewed }) => skewed)) { + output.push(''); + wrapOutput( + output, + '(!) marks groups where the median falls outside the mean confidence ' + + 'interval or the sample is strongly skewed. The median and its interval ' + + 'describe the typical run better for those groups.', + ); + } + return `${output.join('\n')}\n`; +} + +function rawMedian(rates) { + const sorted = [...rates].sort((a, b) => a - b); + const middle = Math.floor(sorted.length / 2); + return sorted.length % 2 === 0 ? + (sorted[middle - 1] + sorted[middle]) / 2 : sorted[middle]; +} + +function valueKey(value) { + return JSON.stringify(value, (_, item) => { + if (typeof item === 'bigint') return { bigint: String(item) }; + return item; + }); +} + +function varianceShare(groups, variable) { + let between = 0; + let total = 0; + for (const group of groups) { + if (group.members.length < 2) continue; + const mean = group.members.reduce( + (sum, sample) => sum + sample.rate, 0) / group.members.length; + const levels = new Map(); + for (const sample of group.members) { + const key = valueKey(sample.params[variable]); + let level = levels.get(key); + if (level === undefined) { + level = { count: 0, sum: 0 }; + levels.set(key, level); + } + level.count++; + level.sum += sample.rate; + } + for (const level of levels.values()) { + between += level.count * ((level.sum / level.count) - mean) ** 2; + } + for (const sample of group.members) total += (sample.rate - mean) ** 2; + } + return total === 0 ? NaN : Math.min(1, between / total); +} + +function effectSizeLabel(delta) { + const absolute = Math.abs(delta); + if (absolute < 0.147) return 'negligible'; + if (absolute < 0.33) return 'small'; + if (absolute < 0.474) return 'medium'; + return 'large'; +} + +const mannWhitneyFloors = new Map(); +function mannWhitneyFloor(firstCount, secondCount) { + const key = `${firstCount},${secondCount}`; + let floor = mannWhitneyFloors.get(key); + if (floor !== undefined) return floor; + const low = createHistogram({ figures: 5 }); + const high = createHistogram({ figures: 5 }); + for (let index = 0; index < firstCount; index++) low.record(10000 + index); + for (let index = 0; index < secondCount; index++) { + high.record(10000 + firstCount + index); + } + floor = high.mannWhitneyTest(low).pValue; + mannWhitneyFloors.set(key, floor); + return floor; +} + +function printScatterComparisons(output, rows, xAxis, category) { + const usable = rows.filter(({ count }) => count > 1); + if (usable.length < 2) return; + const series = new Map(); + for (const row of usable) { + const key = valueKey(row.categoryValue); + if (!series.has(key)) series.set(key, []); + series.get(key).push(row); + } + const sections = []; + let floor = 0; + for (const group of series.values()) { + if (group.length < 2) continue; + const entries = []; + for (let index = 1; index < group.length; index++) { + const previous = group[index - 1]; + const current = group[index]; + // Configurations in one file share a process. Split consecutive groups + // across disjoint outer-process sets so the unpaired test does not treat + // correlated observations as independent. + const parity = index % 2; + const previousRates = previous.processRates + .filter(({ observation }) => observation % 2 === parity) + .map(({ rate }) => rate); + const currentRates = current.processRates + .filter(({ observation }) => observation % 2 !== parity) + .map(({ rate }) => rate); + if (previousRates.length === 0 || currentRates.length === 0) continue; + const comparisonScale = histogramScale([ + ...previousRates, + ...currentRates, + ]); + const previousHistogram = + createRateHistogram(previousRates, comparisonScale, 5); + const currentHistogram = + createRateHistogram(currentRates, comparisonScale, 5); + const { pValue } = currentHistogram.mannWhitneyTest(previousHistogram); + const delta = currentHistogram.cliffsD(previousHistogram); + const previousMean = previousRates.reduce( + (sum, rate) => sum + rate, 0) / previousRates.length; + const currentMean = currentRates.reduce( + (sum, rate) => sum + rate, 0) / currentRates.length; + const change = ((currentMean - previousMean) / previousMean) * 100; + floor = Math.max( + floor, mannWhitneyFloor(previousRates.length, currentRates.length)); + let ratio = ''; + let exponent = ''; + if (typeof previous.xValue === 'number' && + typeof current.xValue === 'number' && + previous.xValue > 0 && current.xValue > 0 && + previous.xValue !== current.xValue && + previousMean > 0 && currentMean > 0) { + const xRatio = current.xValue / previous.xValue; + const value = Math.log(currentMean / previousMean) / Math.log(xRatio); + ratio = `${xRatio.toFixed(1)}x`; + exponent = `${value >= 0 ? '+' : ''}${value.toFixed(2)}`; + } + entries.push( + ` ${previous.xLabel} -> ${current.xLabel}` + + ` ${change >= 0 ? '+' : ''}${change.toFixed(2)}%` + + (exponent === '' ? '' : ` ${ratio} exponent=${exponent}`) + + ` p=${pValue < 1e-4 ? pValue.toExponential(1) : pValue.toFixed(4)}` + + ` delta=${delta >= 0 ? '+' : ''}${delta.toFixed(3)}` + + ` (${effectSizeLabel(delta)})`, + ); + } + if (entries.length > 0) { + sections.push({ + entries, + heading: category === undefined ? + undefined : `${category}=${group[0].categoryLabel}`, + }); + } + } + if (sections.length === 0) return; + output.push('', `Change between consecutive ${xAxis} values ` + + `(Mann-Whitney U on disjoint process sets, Cliff's delta):`); + for (const section of sections) { + output.push(''); + if (section.heading !== undefined) output.push(` ${section.heading}`); + output.push(...section.entries); + } + if (floor >= 0.05) { + output.push(''); + wrapOutput( + output, + `Warning: at this sample size the smallest p-value this test can ` + + `produce is ${floor.toFixed(4)}, so no comparison above can reach ` + + 'significance. Raise --runs.', + ); + } else if (floor >= 0.005) { + output.push(''); + wrapOutput( + output, + `Note: at this sample size the smallest p-value this test can produce ` + + `is ${floor.toFixed(4)}. Raise --runs to strengthen non-significant ` + + 'results.', + ); + } +} + +function formatRate(rate) { + return rate.toLocaleString('en-US', { + maximumFractionDigits: 1, + minimumFractionDigits: 1, + }); +} + +function displayWidth(value) { + return [...value].length; +} + +function pad(value, width, right) { + const padding = ' '.repeat(Math.max(0, width - displayWidth(value))); + return right ? padding + value : value + padding; +} + +function truncateMiddle(value, maximum = 24) { + const characters = [...value]; + if (characters.length <= maximum) return value; + const retained = maximum - 3; + const head = Math.ceil(retained / 2); + const tail = Math.floor(retained / 2); + return `${characters.slice(0, head).join('')}...` + + characters.slice(-tail).join(''); +} + +function assignLabels(rows, valueName, labelName) { + const assigned = new Map(); + const used = new Map(); + const legend = []; + for (const row of rows) { + const key = valueKey(row[valueName]); + let label = assigned.get(key); + if (label === undefined) { + const full = typeof row[valueName] === 'string' ? + inspect(row[valueName]) : String(row[valueName]); + const abbreviated = truncateMiddle(full); + const collisions = used.get(abbreviated) ?? 0; + used.set(abbreviated, collisions + 1); + label = collisions === 0 ? + abbreviated : `${abbreviated}~${collisions + 1}`; + assigned.set(key, label); + if (label !== full) legend.push({ full, label }); + } + row[labelName] = label; + } + return legend; +} + +function printScatterTable(output, rows, xAxis, category) { + const header = [xAxis]; + if (category !== undefined) header.push(category); + header.push( + 'samples', 'rate', 'confidence.interval', 'median', 'median.interval', ''); + const body = rows.map((row) => { + const values = [row.xLabel]; + if (category !== undefined) values.push(row.categoryLabel); + const medianInterval = row.count > 1 ? + `[${(((row.medianLower - row.median) / row.median) * 100).toFixed(2)}%, ` + + `+${(((row.medianUpper - row.median) / row.median) * 100).toFixed(2)}%]` : + 'NA'; + values.push( + String(row.count), + formatRate(row.mean), + Number.isNaN(row.confidenceInterval) ? + 'NA' : + `${formatRate(row.confidenceInterval)} ` + + `(±${((row.confidenceInterval / row.mean) * 100).toFixed(2)}%)`, + formatRate(row.median), + medianInterval, + row.skewed ? '(!)' : '', + ); + return values; + }); + const widths = header.map((value, index) => Math.max( + displayWidth(value), + ...body.map((values) => displayWidth(values[index])), + )); + const right = [typeof rows[0].xValue === 'number']; + if (category !== undefined) { + right.push(typeof rows[0].categoryValue === 'number'); + } + right.push(true, true, true, true, true, false); + const format = (values) => values.map( + (value, index) => pad(value, widths[index], right[index])).join(' ').trimEnd(); + output.push(format(header)); + for (const values of body) output.push(format(values)); +} + +function printScatterChart(output, rows, xAxis, category) { + if (rows.length === 0) return; + const width = 40; + let maximum = 0; + for (const row of rows) { + maximum = Math.max( + maximum, + row.mean + (Number.isNaN(row.confidenceInterval) ? + 0 : row.confidenceInterval), + ); + } + if (maximum === 0) return; + const labels = rows.map((row) => { + let label = `${xAxis}=${row.xLabel}`; + if (category !== undefined) label += ` ${category}=${row.categoryLabel}`; + return truncateMiddle(label, 44); + }); + const labelWidth = Math.max(...labels.map(displayWidth)); + const rateWidth = Math.max(...rows.map(({ mean }) => + displayWidth(formatRate(mean)))); + const axis = formatRate(maximum); + const indent = ' '.repeat(labelWidth + 2); + output.push( + '', + 'Rate in operations/second; longer is faster. │ marks the mean and the', + 'shaded band (░) is its 95% confidence interval.', + '', + `${indent}0${' '.repeat(Math.max(1, width - 1 - displayWidth(axis)))}${axis}`, + `${indent}+${'-'.repeat(width - 2)}+`, + ); + let previous; + for (let index = 0; index < rows.length; index++) { + const row = rows[index]; + if (previous !== undefined && previous !== row.xValue) output.push(''); + previous = row.xValue; + const interval = Number.isNaN(row.confidenceInterval) ? + 0 : row.confidenceInterval; + const end = (row.mean / maximum) * width; + const lower = ((row.mean - interval) / maximum) * width; + const upper = ((row.mean + interval) / maximum) * width; + const meanCell = Math.min(width - 1, Math.floor(end)); + let bar = ''; + for (let cell = 0; cell < width; cell++) { + const position = cell + 0.5; + if (cell === meanCell) bar += '│'; + else if (position >= lower && position <= upper) bar += '░'; + else if (position <= end) bar += '█'; + else bar += ' '; + } + output.push( + `${pad(labels[index], labelWidth, false)} ${bar} ` + + pad(formatRate(row.mean), rateWidth, true), + ); + } +} + +function wrapOutput(output, text, width = 76) { + let line = ''; + for (const word of text.split(/\s+/)) { + if (line === '') line = word; + else if (displayWidth(line) + displayWidth(word) + 1 <= width) { + line += ` ${word}`; + } else { + output.push(line); + line = word; + } + } + if (line !== '') output.push(line); +} + +module.exports = { + analyzeCompare, + analyzeScatter, + holmAdjust, + isRegressionFailure, + validateScatterParameters, +}; diff --git a/benchmark/_node-bench.js b/benchmark/_node-bench.js new file mode 100644 index 000000000000..6c8d1acffdfa --- /dev/null +++ b/benchmark/_node-bench.js @@ -0,0 +1,159 @@ +'use strict'; + +const { spawn } = require('node:child_process'); +const path = require('node:path'); +const { inspect } = require('node:util'); + +function parseInteger(value, defaultValue, name, minimum) { + if (value === undefined) return defaultValue; + if (!/^(?:0|[1-9]\d*)$/.test(value)) { + throw new TypeError(`${name} must be an integer`); + } + const number = Number(value); + if (!Number.isSafeInteger(number) || number < minimum) { + throw new RangeError(`${name} must be at least ${minimum}`); + } + return number; +} + +function parseNumber(value, defaultValue, name, minimum) { + if (value === undefined) return defaultValue; + if (value.trim() === '') throw new TypeError(`${name} must be a number`); + const number = Number(value); + if (!Number.isFinite(number)) throw new TypeError(`${name} must be a number`); + if (number < minimum) { + throw new RangeError(`${name} must be at least ${minimum}`); + } + return number; +} + +function csvEncode(value) { + if (typeof value === 'number' || typeof value === 'boolean') { + return String(value); + } + const string = String(value); + return `"${string.replace(/"/g, '""')}"`; +} + +function formatConfiguration(params) { + return Object.keys(params) + .map((key) => `${key}=${inspect(params[key])}`) + .join(' '); +} + +function durationToSeconds(duration) { + if (!/^\d+$/.test(duration)) { + throw new TypeError(`Invalid benchmark duration '${duration}'`); + } + const padded = duration.padStart(10, '0'); + return `${padded.slice(0, -9)}.${padded.slice(-9)}`; +} + +function runBenchmark(binary, file, options) { + const args = [ + ...options.nodeArgs, + '--no-warnings', + '--bench', + '--bench-reporter=json', + '--bench-samples=1', + `--bench-warmup=${options.warmup}`, + ]; + if (options.namePattern !== undefined) { + args.push(`--bench-name-pattern=${options.namePattern}`); + } + args.push('--', path.resolve(file)); + + return new Promise((resolve, reject) => { + const child = spawn(binary, args, { + env: process.env, + stdio: ['ignore', 'pipe', 'pipe'], + }); + child.stdout.setEncoding('utf8'); + child.stderr.setEncoding('utf8'); + + let stdout = ''; + let stderr = ''; + child.stdout.on('data', (data) => { stdout += data; }); + child.stderr.on('data', (data) => { stderr += data; }); + child.once('error', reject); + child.once('close', (code, signal) => { + let records; + try { + records = stdout.trim().split('\n') + .filter((line) => line.length > 0) + .map((line) => JSON.parse(line)); + } catch (error) { + reject(new Error( + `Could not parse benchmark output from '${binary}': ${error.message}`, + { cause: error }, + )); + return; + } + + const summary = records.findLast( + ({ type }) => type === 'bench:summary')?.data; + if (code !== 0 || signal !== null || summary?.success !== true) { + const diagnostics = records + .filter(({ type }) => type === 'bench:diagnostic') + .map(({ data }) => data.message) + .join('\n'); + const status = signal === null ? `exit code ${code}` : `signal ${signal}`; + const details = stderr || diagnostics; + reject(new Error( + `Benchmark '${file}' failed with ${status}` + + (details ? `:\n${details}` : ''), + )); + return; + } + + const samples = []; + for (const record of records) { + if (record.type !== 'bench:complete' || + record.data.skip !== undefined) { + continue; + } + if (record.data.error !== undefined) { + reject(new Error( + `Benchmark '${record.data.name}' failed: ` + + record.data.error.message, + )); + return; + } + if (record.data.samples.length !== 1) { + reject(new Error( + `Benchmark '${record.data.name}' did not produce exactly one sample`, + )); + return; + } + const sample = record.data.samples[0]; + if (!Number.isFinite(sample.rate)) { + reject(new Error( + `Benchmark '${record.data.name}' produced a non-finite rate`, + )); + return; + } + samples.push({ + configuration: formatConfiguration(record.data.params), + duration: durationToSeconds(sample.duration_ns), + identity: record.data.benchId, + logicalIdentity: JSON.stringify([ + record.data.file, + record.data.parentId, + record.data.name, + ]), + name: record.data.name, + params: record.data.params, + rate: sample.rate, + }); + } + resolve(samples); + }); + }); +} + +module.exports = { + csvEncode, + parseInteger, + parseNumber, + runBenchmark, +}; diff --git a/benchmark/buffers/_buffer-compare-offset.node-bench.js b/benchmark/buffers/_buffer-compare-offset.node-bench.js new file mode 100644 index 000000000000..b16c3a3da7db --- /dev/null +++ b/benchmark/buffers/_buffer-compare-offset.node-bench.js @@ -0,0 +1,37 @@ +'use strict'; + +const { bench } = require('node:bench'); +const path = require('node:path'); + +const methods = ['offset', 'slice']; +const sizes = [16, 512, 4096, 16386]; +const n = 1e6; +const name = path.join('buffers', 'buffer-compare-offset.js'); + +function compareUsingSlice(b0, b1, len, iterations) { + for (let i = 0; i < iterations; i++) + Buffer.compare(b0.slice(1, len), b1.slice(1, len)); +} + +function compareUsingOffset(b0, b1, len, iterations) { + for (let i = 0; i < iterations; i++) + b0.compare(b1, 1, len, 1, len); +} + +for (const method of methods) { + for (const size of sizes) { + const compare = method === 'slice' ? + compareUsingSlice : compareUsingOffset; + + bench(name, { + params: { method, n, size }, + }, (b) => { + b.start(); + compare(Buffer.alloc(size, 'a'), + Buffer.alloc(size, 'b'), + size >> 1, + n); + b.end(n); + }); + } +} diff --git a/benchmark/compare-node-bench.js b/benchmark/compare-node-bench.js new file mode 100644 index 000000000000..295f15f0fdc1 --- /dev/null +++ b/benchmark/compare-node-bench.js @@ -0,0 +1,118 @@ +'use strict'; + +const path = require('node:path'); +const CLI = require('./_cli.js'); +const { analyzeCompare } = require('./_node-bench-analysis.js'); +const { + csvEncode, + parseInteger, + parseNumber, + runBenchmark, +} = require('./_node-bench.js'); + +const cli = new CLI(`usage: ./node compare-node-bench.js [options] [--] ... + Run explicit node:bench files repeatedly with two Node.js binaries. Each + observation runs in a fresh process. Output is compatible with compare.R, + or --analyze can summarize it directly. + + --new binary new Node.js binary (required) + --old binary old Node.js binary (required) + --runs 30 observations per binary + --warmup 0 warmup samples before each observation + --name-pattern pattern only run matching benchmarks + --node-arg argument pass an argument to both binaries (repeatable) + --analyze analyze with Welch's t-test instead of writing CSV + --scale 1000 rate multiplier used for histogram precision + --max-regression N fail if a family-wise significant regression's + 95% confidence interval is entirely beyond N% + (implies --analyze) +`, { arrayArgs: ['node-arg'], boolArgs: ['analyze'] }); + +if (!cli.optional.new || !cli.optional.old || cli.items.length === 0) { + cli.abort(cli.usage); +} + +async function main() { + const runs = parseInteger(cli.optional.runs, 30, '--runs', 1); + const warmup = parseInteger(cli.optional.warmup, 0, '--warmup', 0); + const scale = parseInteger(cli.optional.scale, 1000, '--scale', 1); + const hasMaxRegression = cli.optional['max-regression'] !== undefined; + const maxRegression = parseNumber( + cli.optional['max-regression'], 0, '--max-regression', 0); + const analyze = !!cli.optional.analyze || hasMaxRegression; + const options = { + namePattern: cli.optional['name-pattern'], + nodeArgs: cli.optional['node-arg'], + warmup, + }; + const binaries = [ + { label: 'old', path: cli.optional.old }, + { label: 'new', path: cli.optional.new }, + ]; + const rows = []; + const counts = new Map(); + const csvGroups = new Map(); + + for (const file of cli.items) { + const resolved = path.resolve(file); + for (let run = 0; run < runs; run++) { + const order = run % 2 === 0 ? binaries : [binaries[1], binaries[0]]; + for (const binary of order) { + const samples = await runBenchmark(binary.path, resolved, options); + for (const sample of samples) { + const identity = JSON.stringify([resolved, sample.identity]); + const csvGroup = JSON.stringify([ + sample.name, + sample.configuration, + ]); + const groupedIdentity = csvGroups.get(csvGroup); + if (groupedIdentity !== undefined && groupedIdentity !== identity) { + throw new Error( + `Distinct benchmarks would share the CSV group '${sample.name} ` + + `${sample.configuration}'`, + ); + } + csvGroups.set(csvGroup, identity); + let count = counts.get(identity); + if (count === undefined) { + count = { name: sample.name, new: 0, old: 0 }; + counts.set(identity, count); + } + count[binary.label]++; + rows.push({ binary: binary.label, ...sample }); + } + } + } + } + + if (rows.length === 0) { + throw new Error('No benchmark samples were produced'); + } + for (const count of counts.values()) { + if (count.old !== runs || count.new !== runs) { + throw new Error( + `Benchmark '${count.name}' was not reported by both binaries in every run`, + ); + } + } + + if (analyze) { + const result = analyzeCompare( + rows, scale, hasMaxRegression ? maxRegression : undefined); + process.stdout.write(result.output); + if (result.failed) process.exitCode = 1; + return; + } + + const output = ['"binary","filename","configuration","rate","time"']; + for (const row of rows) { + output.push(`${csvEncode(row.binary)},${csvEncode(row.name)},` + + `${csvEncode(row.configuration)},${row.rate},${row.duration}`); + } + process.stdout.write(`${output.join('\n')}\n`); +} + +main().catch((error) => { + console.error(error.stack); + process.exitCode = 1; +}); diff --git a/benchmark/compare.js b/benchmark/compare.js index 6aaaee7a9190..77874e8af6c1 100644 --- a/benchmark/compare.js +++ b/benchmark/compare.js @@ -159,6 +159,27 @@ if (showProgress) { }); })(kStartOfQueue); +// Holm-Bonferroni step-down adjustment. Controls the probability of *any* +// false positive across the whole comparison set, which is what a pass/fail +// gate needs: an uncorrected suite of 169 comparisons at 5% has a 99.98% +// chance of flagging something that is not there. Uniformly more powerful +// than plain Bonferroni, and makes no assumption about independence. +function holmAdjust(pValues) { + const order = pValues + .map((p, i) => ({ p, i })) + .sort((a, b) => a.p - b.p); + const m = order.length; + const adjusted = new Array(m); + let running = 0; + for (let k = 0; k < m; k++) { + // Step down, enforcing monotonicity so an adjusted value can never be + // smaller than one belonging to a more significant raw p-value. + running = Math.max(running, Math.min(1, (m - k) * order[k].p)); + adjusted[order[k].i] = running; + } + return adjusted; +} + function printAnalysis(results, scale, maxRegression) { const { createHistogram } = require('node:perf_hooks'); @@ -217,6 +238,25 @@ function printAnalysis(results, scale, maxRegression) { if (name.length > maxNameLen) maxNameLen = name.length; } + // Adjust for the size of the comparison set. The raw p-value answers "is + // this one benchmark different", but a suite is read as a whole, so the + // relevant question is "is anything here different". + const adjusted = holmAdjust(rows.map((r) => r.pValue)); + for (let i = 0; i < rows.length; i++) rows[i].pAdjusted = adjusted[i]; + + // A comparison can only rule out an effect it was able to resolve. Where no + // threshold has been given there is no definition of "worth detecting", so + // nothing is claimed. `maxRegression` is exactly such a declaration, so it + // is reused rather than inventing a second constant. + const resolution = maxRegression > 0 ? maxRegression : null; + let underpowered = 0; + for (const row of rows) { + row.inconclusive = resolution !== null && + row.stars.trim() === '' && + row.ci95 > resolution; + if (row.inconclusive) underpowered++; + } + // Print header. const pad = (s, n) => s + ' '.repeat(Math.max(0, n - s.length)); const rpad = (s, n) => ' '.repeat(Math.max(0, n - s.length)) + s; @@ -231,7 +271,8 @@ function printAnalysis(results, scale, maxRegression) { ` ${rpad(imp, 11)}` + ` ±${row.ci95.toFixed(2)}%` + ` ±${row.ci99.toFixed(2)}%` + - ` ±${row.ci999.toFixed(2)}%`, + ` ±${row.ci999.toFixed(2)}%` + + `${row.inconclusive ? ' (inconclusive)' : ''}`, ); } @@ -252,6 +293,7 @@ function printAnalysis(results, scale, maxRegression) { `Rates were scaled by ${scale}x into HdrHistogram (3 significant figures).\n` + `Use --scale to adjust precision if needed.\n`, ); + const anyFamilyWise = rows.filter((r) => r.pAdjusted < 0.05).length; console.log( `Be aware that when doing many comparisons the risk of a false-positive\n` + `result increases. In this case, there are ${rows.length} comparisons, ` + @@ -261,23 +303,56 @@ function printAnalysis(results, scale, maxRegression) { ` ${(rows.length * 0.01).toFixed(2)} false positives, when considering ` + `a 1% risk acceptance (**, ***),\n` + ` ${(rows.length * 0.001).toFixed(2)} false positives, when considering ` + - `a 0.1% risk acceptance (***)`, + `a 0.1% risk acceptance (***)\n` + + `\nThe stars above are per-benchmark and uncorrected. Adjusting for the ` + + `size of\nthis comparison set (Holm-Bonferroni), ${anyFamilyWise} ` + + `comparison${anyFamilyWise === 1 ? '' : 's'} remain${anyFamilyWise === 1 ? 's' : ''} ` + + `significant at 5%.\n--max-regression uses the corrected values.`, ); - // Gate: exit with error if any significant regression exceeds the limit. + // Gate: exit with error if any regression is shown to exceed the limit. if (maxRegression > 0) { + if (underpowered > 0) { + console.log(''); + console.log( + `Note: ${underpowered} of ${rows.length} comparison` + + `${rows.length === 1 ? '' : 's'} could not resolve an effect as ` + + `small as ${maxRegression}%, and are marked (inconclusive). They are ` + + `not\nevidence of no regression -- the samples are too noisy to tell. ` + + `Raise --runs,\nor pin cores with --set CPUSET, to narrow them.`, + ); + } + + // Two conditions, both required. + // + // The confidence interval must lie entirely beyond the threshold. A small + // p-value only says the effect is not exactly zero; claiming it exceeds + // `maxRegression` is a statement about magnitude, so the interval has to + // exclude that magnitude. Testing the point estimate instead systematically + // fires on the noisiest benchmarks, because a large point estimate is + // easiest to obtain when the interval is wide. + // + // The p-value must also survive adjustment for the size of the comparison + // set, so that a suite of hundreds of benchmarks does not fail purely + // because one of them drifted. const failures = rows.filter( - (r) => r.stars.trim() !== '' && r.improvement < -maxRegression, + (r) => r.pAdjusted < 0.05 && r.improvement + r.ci95 < -maxRegression, ); + if (failures.length > 0) { console.log(''); console.log( `FAIL: ${failures.length} benchmark${failures.length === 1 ? '' : 's'}` + - ` showed a statistically significant regression exceeding` + - ` ${maxRegression}%:`, + ` regressed by more than ${maxRegression}%` + + ` (interval excludes the threshold,\n` + + `family-wise corrected across ${rows.length} comparisons):`, ); for (const f of failures) { - console.log(` ${f.name} ${f.improvement.toFixed(2)}%`); + console.log( + ` ${f.name} ${f.improvement.toFixed(2)}% ` + + `(95% CI up to ${(f.improvement + f.ci95).toFixed(2)}%, ` + + `adjusted p=${f.pAdjusted.toExponential(2)})`, + ); } process.exitCode = 1; } diff --git a/benchmark/crypto/_create-hash.node-bench.js b/benchmark/crypto/_create-hash.node-bench.js new file mode 100644 index 000000000000..4481bc6c6527 --- /dev/null +++ b/benchmark/crypto/_create-hash.node-bench.js @@ -0,0 +1,19 @@ +'use strict'; + +const assert = require('node:assert'); +const { bench } = require('node:bench'); +const { createHash } = require('node:crypto'); +const path = require('node:path'); + +const n = 1e5; +const name = path.join('crypto', 'create-hash.js'); + +bench(name, { params: { n } }, (b) => { + const array = []; + for (let i = 0; i < n; ++i) array.push(null); + b.start(); + for (let i = 0; i < n; ++i) + array[i] = createHash('sha1'); + b.end(n); + assert.strictEqual(typeof array[n - 1], 'object'); +}); diff --git a/benchmark/crypto/class-construction.js b/benchmark/crypto/class-construction.js new file mode 100644 index 000000000000..fe03b1a43cd2 --- /dev/null +++ b/benchmark/crypto/class-construction.js @@ -0,0 +1,86 @@ +'use strict'; + +const common = require('../common.js'); +const assert = require('node:assert'); +const crypto = require('node:crypto'); +const fs = require('node:fs'); +const path = require('node:path'); + +const fixtureDir = path.resolve(__dirname, '../../test/fixtures/keys'); +const certificate = fs.readFileSync(path.join(fixtureDir, 'agent1-cert.pem')); +const dhPrime = crypto.getDiffieHellman('modp14').getPrime(); +const key = Buffer.alloc(32, 0x01); +const keyObject = crypto.createSecretKey(key); +const hmacAlgorithm = { name: 'HMAC', hash: 'SHA-256' }; +const keyUsages = ['sign']; +const iv = Buffer.alloc(16, 0x02); + +const iterations = { + Certificate: 1e7, + Cipheriv: 1e5, + Decipheriv: 1e5, + DiffieHellman: 10, + DiffieHellmanGroup: 2e5, + ECDH: 2e5, + Hash: 1e5, + Hmac: 5e4, + KeyObject: 1e5, + Sign: 1e5, + Verify: 1e5, + CryptoKey: 5e4, + X509Certificate: 5e3, +}; + +const bench = common.createBenchmark(main, { + type: Object.keys(iterations), + n: [...new Set(Object.values(iterations))], +}, { + combinationFilter({ type, n }) { + // Benchmark test mode reduces numeric options to 1. + return n === 1 || iterations[type] === n; + }, +}); + +function construct(type) { + switch (type) { + case 'Certificate': + return new crypto.Certificate(); + case 'Cipheriv': + return crypto.createCipheriv('aes-256-ctr', key, iv); + case 'Decipheriv': + return crypto.createDecipheriv('aes-256-ctr', key, iv); + case 'DiffieHellman': + return crypto.createDiffieHellman(dhPrime); + case 'DiffieHellmanGroup': + return crypto.getDiffieHellman('modp14'); + case 'ECDH': + return crypto.createECDH('prime256v1'); + case 'Hash': + return crypto.createHash('sha256'); + case 'Hmac': + return crypto.createHmac('sha256', key); + case 'KeyObject': + return crypto.createSecretKey(key); + case 'Sign': + return crypto.createSign('sha256'); + case 'Verify': + return crypto.createVerify('sha256'); + case 'CryptoKey': + return keyObject.toCryptoKey(hmacAlgorithm, true, keyUsages); + case 'X509Certificate': + return new crypto.X509Certificate(certificate); + default: + throw new Error(`Unsupported class: ${type}`); + } +} + +function main({ type, n }) { + const instances = new Array(n); + + bench.start(); + for (let i = 0; i < n; ++i) + instances[i] = construct(type); + bench.end(n); + + assert.strictEqual(typeof instances[n - 1], 'object'); +} diff --git a/benchmark/crypto/class-methods.js b/benchmark/crypto/class-methods.js new file mode 100644 index 000000000000..9db499b7d1a9 --- /dev/null +++ b/benchmark/crypto/class-methods.js @@ -0,0 +1,206 @@ +'use strict'; + +const common = require('../common.js'); +const crypto = require('node:crypto'); +const fs = require('node:fs'); +const path = require('node:path'); + +const fixtureDir = path.resolve(__dirname, '../../test/fixtures/keys'); +const certificate = fs.readFileSync(path.join(fixtureDir, 'agent1-cert.pem')); +const key = Buffer.alloc(32, 0x01); +const hmacAlgorithm = { name: 'HMAC', hash: 'SHA-256' }; +const keyUsages = ['sign']; +const iv = Buffer.alloc(16, 0x02); +const input = Buffer.alloc(16, 0x03); + +const iterations = { + 'Cipheriv-update': 1e6, + 'Decipheriv-update': 1e6, + 'DiffieHellman-getGenerator': 2e5, + 'DiffieHellmanGroup-getGenerator': 2e6, + 'ECDH-getPrivateKey': 2e6, + 'Hash-update': 5e6, + 'Hmac-update': 5e6, + 'KeyObject-equals': 2e6, + 'KeyObject-symmetricKeySize-first': 1e5, + 'KeyObject-type-first': 1e5, + 'KeyObject-type': 1e8, + 'Sign-update': 5e6, + 'Verify-update': 5e6, + 'CryptoKey-toKeyObject': 2e5, + 'CryptoKey-algorithm-first': 1e5, + 'CryptoKey-extractable-first': 1e5, + 'CryptoKey-type-first': 1e5, + 'CryptoKey-usages-first': 1e5, + 'CryptoKey-type': 1e8, + 'X509Certificate-checkHost': 1e6, + 'X509Certificate-publicKey-first': 5e3, + 'X509Certificate-publicKey': 1e8, + 'X509Certificate-subject-first': 5e3, + 'X509Certificate-subject': 1e8, +}; + +const bench = common.createBenchmark(main, { + operation: Object.keys(iterations), + n: [...new Set(Object.values(iterations))], +}, { + combinationFilter({ operation, n }) { + // Benchmark test mode reduces numeric options to 1. + return n === 1 || iterations[operation] === n; + }, +}); + +function setup(operation) { + switch (operation) { + case 'Cipheriv-update': { + const cipher = crypto.createCipheriv('aes-256-ctr', key, iv); + return { + run: () => cipher.update(input), + finish: () => cipher.final(), + }; + } + case 'Decipheriv-update': { + const decipher = crypto.createDecipheriv('aes-256-ctr', key, iv); + return { + run: () => decipher.update(input), + finish: () => decipher.final(), + }; + } + case 'DiffieHellman-getGenerator': { + const dh = crypto.createDiffieHellman( + crypto.getDiffieHellman('modp14').getPrime()); + return { run: () => dh.getGenerator() }; + } + case 'DiffieHellmanGroup-getGenerator': { + const dh = crypto.getDiffieHellman('modp14'); + return { run: () => dh.getGenerator() }; + } + case 'ECDH-getPrivateKey': { + const ecdh = crypto.createECDH('prime256v1'); + ecdh.generateKeys(); + return { run: () => ecdh.getPrivateKey() }; + } + case 'Hash-update': { + const hash = crypto.createHash('sha256'); + return { + run: () => hash.update(input), + finish: () => hash.digest(), + }; + } + case 'Hmac-update': { + const hmac = crypto.createHmac('sha256', key); + return { + run: () => hmac.update(input), + finish: () => hmac.digest(), + }; + } + case 'KeyObject-equals': { + const keyObject = crypto.createSecretKey(key); + return { run: () => keyObject.equals(keyObject) }; + } + case 'KeyObject-symmetricKeySize-first': { + return { run: () => crypto.createSecretKey(key).symmetricKeySize }; + } + case 'KeyObject-type-first': { + return { run: () => crypto.createSecretKey(key).type }; + } + case 'KeyObject-type': { + const keyObjects = Array.from( + { length: 64 }, () => crypto.createSecretKey(key)); + for (const keyObject of keyObjects) { + if (keyObject.type !== 'secret') + throw new Error('Unexpected KeyObject type'); + } + let index = 0; + return { run: () => keyObjects[index++ & 63].type }; + } + case 'Sign-update': { + const sign = crypto.createSign('sha256'); + return { run: () => sign.update(input) }; + } + case 'Verify-update': { + const verify = crypto.createVerify('sha256'); + return { run: () => verify.update(input) }; + } + case 'CryptoKey-toKeyObject': { + const keyObject = crypto.createSecretKey(key); + const cryptoKey = keyObject.toCryptoKey( + hmacAlgorithm, true, keyUsages); + return { run: () => crypto.KeyObject.from(cryptoKey) }; + } + case 'CryptoKey-algorithm-first': + case 'CryptoKey-extractable-first': + case 'CryptoKey-type-first': + case 'CryptoKey-usages-first': { + const keyObject = crypto.createSecretKey(key); + const property = operation.slice('CryptoKey-'.length, -'-first'.length); + return { + run: () => keyObject.toCryptoKey( + hmacAlgorithm, true, keyUsages)[property], + }; + } + case 'CryptoKey-type': { + const keyObject = crypto.createSecretKey(key); + const cryptoKeys = Array.from( + { length: 64 }, + () => keyObject.toCryptoKey(hmacAlgorithm, true, keyUsages)); + for (const cryptoKey of cryptoKeys) { + if (cryptoKey.type !== 'secret') + throw new Error('Unexpected CryptoKey type'); + } + let index = 0; + return { run: () => cryptoKeys[index++ & 63].type }; + } + case 'X509Certificate-checkHost': { + const x509 = new crypto.X509Certificate(certificate); + return { run: () => x509.checkHost('agent1') }; + } + case 'X509Certificate-publicKey-first': { + return { + run: () => new crypto.X509Certificate(certificate).publicKey, + }; + } + case 'X509Certificate-publicKey': { + const certificates = Array.from( + { length: 64 }, () => new crypto.X509Certificate(certificate)); + for (const x509 of certificates) { + if (x509.publicKey === undefined) + throw new Error('Missing certificate public key'); + } + let index = 0; + return { run: () => certificates[index++ & 63].publicKey }; + } + case 'X509Certificate-subject-first': { + return { + run: () => new crypto.X509Certificate(certificate).subject, + }; + } + case 'X509Certificate-subject': { + const certificates = Array.from( + { length: 64 }, () => new crypto.X509Certificate(certificate)); + for (const x509 of certificates) { + if (x509.subject === undefined) + throw new Error('Missing certificate subject'); + } + let index = 0; + return { run: () => certificates[index++ & 63].subject }; + } + default: + throw new Error(`Unsupported operation: ${operation}`); + } +} + +function main({ operation, n }) { + const state = setup(operation); + let result; + + bench.start(); + for (let i = 0; i < n; ++i) + result = state.run(); + bench.end(n); + + if (state.finish) + state.finish(); + if (result === state) + throw new Error('Unexpected benchmark result'); +} diff --git a/benchmark/crypto/create-cipheriv.js b/benchmark/crypto/create-cipheriv.js new file mode 100644 index 000000000000..7774e393b403 --- /dev/null +++ b/benchmark/crypto/create-cipheriv.js @@ -0,0 +1,62 @@ +'use strict'; + +const common = require('../common.js'); +const assert = require('node:assert'); +const { + createCipheriv, + createDecipheriv, + getCiphers, +} = require('node:crypto'); + +const configurations = { + 'aes-128-cbc': { keyLength: 16, ivLength: 16 }, + 'aes-128-gcm': { keyLength: 16, ivLength: 12 }, + 'aes-128-cbc-cts': { keyLength: 16, ivLength: 16 }, + 'aes-128-wrap-inv': { keyLength: 16, ivLength: 8 }, + 'aes128-wrap-inv': { + keyLength: 16, + ivLength: 8, + warmupCipher: 'aes-128-wrap-inv', + }, +}; + +const ciphers = ['aes-128-cbc', 'aes-128-gcm']; +const availableCiphers = new Set(getCiphers()); +for (const cipher of [ + 'aes-128-cbc-cts', + 'aes-128-wrap-inv', + 'aes128-wrap-inv', +]) { + if (availableCiphers.has(cipher)) { + ciphers.push(cipher); + } +} + +const bench = common.createBenchmark(main, { + n: [1e5], + cipher: ciphers, + operation: ['encrypt', 'decrypt'], +}); + +function main({ n, cipher, operation }) { + const { + keyLength, + ivLength, + warmupCipher = cipher, + } = configurations[cipher]; + const key = Buffer.alloc(keyLength); + const iv = Buffer.alloc(ivLength); + const results = new Array(n); + const method = operation === 'encrypt' ? createCipheriv : createDecipheriv; + + const warmup = method(warmupCipher, key, iv); + assert.strictEqual(typeof warmup, 'object'); + + bench.start(); + for (let i = 0; i < n; ++i) { + results[i] = method(cipher, key, iv); + } + bench.end(n); + + assert.strictEqual(typeof results[n - 1], 'object'); +} diff --git a/benchmark/crypto/ecdh-compute-secret.js b/benchmark/crypto/ecdh-compute-secret.js new file mode 100644 index 000000000000..3061c5b2cc36 --- /dev/null +++ b/benchmark/crypto/ecdh-compute-secret.js @@ -0,0 +1,117 @@ +'use strict'; + +const common = require('../common.js'); +const assert = require('node:assert'); +const crypto = require('node:crypto'); + +const kCurve = 'prime256v1'; +const kPeerPoolSize = 32; +const scenarios = [ + 'first-after-generate', + 'full-lifecycle', + 'reused-local-same-peer', + 'reused-local-peer-pool', +]; + +const bench = common.createBenchmark(main, { + scenario: scenarios, + n: [5_000], +}, { + test: { scenario: 'first-after-generate', n: 1 }, +}); + +function generateContext() { + const context = crypto.createECDH(kCurve); + context.generateKeys(); + return context; +} + +function verifySecret(secret, local, peer) { + assert.deepStrictEqual(secret, peer.computeSecret(local.getPublicKey())); +} + +function firstAfterGenerate(n) { + const peer = generateContext(); + const peerPublicKey = peer.getPublicKey(); + const warmup = generateContext(); + warmup.computeSecret(peerPublicKey); + + const locals = Array.from({ length: n }, generateContext); + const secrets = new Array(n); + + bench.start(); + for (let i = 0; i < n; i++) + secrets[i] = locals[i].computeSecret(peerPublicKey); + bench.end(n); + + verifySecret(secrets[n - 1], locals[n - 1], peer); +} + +function fullLifecycle(n) { + const peer = generateContext(); + const peerPublicKey = peer.getPublicKey(); + const warmup = generateContext(); + warmup.computeSecret(peerPublicKey); + + const locals = new Array(n); + const secrets = new Array(n); + + bench.start(); + for (let i = 0; i < n; i++) { + const local = locals[i] = generateContext(); + secrets[i] = local.computeSecret(peerPublicKey); + } + bench.end(n); + + verifySecret(secrets[n - 1], locals[n - 1], peer); +} + +function reusedLocalSamePeer(n) { + const local = generateContext(); + const peer = generateContext(); + const peerPublicKey = peer.getPublicKey(); + local.computeSecret(peerPublicKey); + + const secrets = new Array(n); + + bench.start(); + for (let i = 0; i < n; i++) + secrets[i] = local.computeSecret(peerPublicKey); + bench.end(n); + + verifySecret(secrets[n - 1], local, peer); +} + +function reusedLocalPeerPool(n) { + const local = generateContext(); + const peers = Array.from( + { length: Math.min(n, kPeerPoolSize) }, + generateContext); + const peerPublicKeys = peers.map((peer) => peer.getPublicKey()); + local.computeSecret(peerPublicKeys[0]); + + const secrets = new Array(n); + + bench.start(); + for (let i = 0; i < n; i++) + secrets[i] = local.computeSecret(peerPublicKeys[i % peers.length]); + bench.end(n); + + const lastPeer = peers[(n - 1) % peers.length]; + verifySecret(secrets[n - 1], local, lastPeer); +} + +function main({ scenario, n }) { + switch (scenario) { + case 'first-after-generate': + return firstAfterGenerate(n); + case 'full-lifecycle': + return fullLifecycle(n); + case 'reused-local-same-peer': + return reusedLocalSamePeer(n); + case 'reused-local-peer-pool': + return reusedLocalPeerPool(n); + default: + throw new Error(`Unsupported scenario: ${scenario}`); + } +} diff --git a/benchmark/crypto/mac.js b/benchmark/crypto/mac.js new file mode 100644 index 000000000000..d1028fa414e6 --- /dev/null +++ b/benchmark/crypto/mac.js @@ -0,0 +1,254 @@ +'use strict'; + +const common = require('../common.js'); +const { hasOpenSSL } = require('../../test/common/crypto.js'); +const assert = require('node:assert'); +const { + createHmac, + createMac, + getMacs, +} = require('node:crypto'); + +if (!hasOpenSSL(3) || + process.features.openssl_is_boringssl || + typeof createMac !== 'function' || + typeof getMacs !== 'function') { + console.log('Skipping: generic MAC API requires OpenSSL >= 3'); + process.exit(0); +} + +const operations = [ + 'get-macs-cold', + 'get-macs-warm', + 'create-cold', + 'create-warm', + 'hmac-lifecycle', + 'mac-lifecycle', + 'mac-stream-lifecycle', + 'update', + 'stream', + 'final-buffer', + 'final-hex', +]; +const configurations = { + 'hmac-sha256': { + algorithm: 'HMAC', + key: Buffer.alloc(32, 0x42), + options: { digest: 'SHA256' }, + }, + 'kmac-128': { + algorithm: 'KMAC-128', + key: Buffer.alloc(32, 0x42), + options: { outputLength: 32 }, + }, +}; + +const bench = common.createBenchmark(main, { + operation: operations, + algorithm: Object.keys(configurations), + length: [0, 64, 4096], + n: [1, 10_000, 20_000, 500_000], +}, { + combinationFilter({ operation, algorithm, length, n }) { + if (operation === 'get-macs-cold') { + return algorithm === 'hmac-sha256' && length === 0 && n === 1; + } + if (operation === 'get-macs-warm') { + return algorithm === 'hmac-sha256' && length === 0 && n === 500_000; + } + if (operation === 'create-cold') + return length === 0 && n === 1; + if (operation === 'create-warm') + return length === 0 && n === 20_000; + if (operation === 'hmac-lifecycle') { + return algorithm === 'hmac-sha256' && n === 10_000; + } + if (operation === 'mac-lifecycle' || + operation === 'mac-stream-lifecycle') { + return n === 10_000; + } + if (operation === 'update' || operation === 'stream') { + return length === 64 && n === 500_000; + } + if (operation === 'final-buffer' || operation === 'final-hex') { + return algorithm === 'hmac-sha256' && + length === 64 && + n === 20_000; + } + return false; + }, + test: { + operation: ['create-cold'], + algorithm: ['hmac-sha256'], + length: [0], + n: [1], + }, +}); + +function main({ operation, algorithm, length, n }) { + const configuration = configurations[algorithm]; + const data = Buffer.alloc(length, 0x61); + + switch (operation) { + case 'get-macs-cold': + measureGetMacs(n, false); + break; + case 'get-macs-warm': + measureGetMacs(n, true); + break; + case 'create-cold': + measureCreate(configuration, n, false); + break; + case 'create-warm': + measureCreate(configuration, n, true); + break; + case 'hmac-lifecycle': + measureHmacLifecycle(configuration, data, n); + break; + case 'mac-lifecycle': + measureMacLifecycle(configuration, data, n); + break; + case 'mac-stream-lifecycle': + measureMacStreamLifecycle(configuration, data, n); + break; + case 'update': + measureUpdate(configuration, data, n); + break; + case 'stream': + measureStream(configuration, data, n); + break; + case 'final-buffer': + measureFinal(configuration, data, n); + break; + case 'final-hex': + measureFinal(configuration, data, n, 'hex'); + break; + default: + throw new Error(`unknown operation: ${operation}`); + } +} + +function measureGetMacs(n, warm) { + if (warm) + getMacs(); + + let result; + bench.start(); + for (let i = 0; i < n; ++i) + result = getMacs(); + bench.end(n); + + assert(Array.isArray(result)); +} + +function measureCreate({ algorithm, key, options }, n, warm) { + if (warm) + createMac(algorithm, key, options).final(); + + const contexts = new Array(n); + bench.start(); + for (let i = 0; i < n; ++i) + contexts[i] = createMac(algorithm, key, options); + bench.end(n); + + assert.strictEqual(typeof contexts[n - 1], 'object'); +} + +function measureHmacLifecycle({ key, options }, data, n) { + createHmac(options.digest, key).update(data).digest(); + + let result; + bench.start(); + for (let i = 0; i < n; ++i) + result = createHmac(options.digest, key).update(data).digest(); + bench.end(n); + + assert(Buffer.isBuffer(result)); +} + +function measureMacLifecycle({ algorithm, key, options }, data, n) { + createMac(algorithm, key, options).update(data).final(); + + let result; + bench.start(); + for (let i = 0; i < n; ++i) + result = createMac(algorithm, key, options).update(data).final(); + bench.end(n); + + assert(Buffer.isBuffer(result)); +} + +function measureMacStreamLifecycle({ algorithm, key, options }, data, n) { + const warmup = createMac(algorithm, key, options); + warmup.end(data); + warmup.read(); + + let result; + bench.start(); + for (let i = 0; i < n; ++i) { + const context = createMac(algorithm, key, options); + context.end(data); + result = context.read(); + } + bench.end(n); + + assert(Buffer.isBuffer(result)); +} + +function measureUpdate({ algorithm, key, options }, data, n) { + const warmup = createMac(algorithm, key, options); + warmup.update(data).final(); + + const context = createMac(algorithm, key, options); + bench.start(); + for (let i = 0; i < n; ++i) + context.update(data); + bench.end(n); + + assert(Buffer.isBuffer(context.final())); +} + +function measureStream({ algorithm, key, options }, data, n) { + const warmup = createMac(algorithm, key, options); + warmup.end(data); + warmup.read(); + + const context = createMac(algorithm, key, options); + bench.start(); + for (let i = 0; i < n; ++i) + context.write(data); + bench.end(n); + + context.end(); + assert(Buffer.isBuffer(context.read())); +} + +function measureFinal({ algorithm, key, options }, data, n, encoding) { + const warmup = createMac(algorithm, key, options).update(data); + if (encoding === undefined) + warmup.final(); + else + warmup.final(encoding); + + const contexts = new Array(n); + for (let i = 0; i < n; ++i) + contexts[i] = createMac(algorithm, key, options).update(data); + + let result; + if (encoding === undefined) { + bench.start(); + for (let i = 0; i < n; ++i) + result = contexts[i].final(); + bench.end(n); + } else { + bench.start(); + for (let i = 0; i < n; ++i) + result = contexts[i].final(encoding); + bench.end(n); + } + + if (encoding === undefined) + assert(Buffer.isBuffer(result)); + else + assert.strictEqual(typeof result, 'string'); +} diff --git a/benchmark/diagnostics_channel/tracing-channel-promise.js b/benchmark/diagnostics_channel/tracing-channel-promise.js new file mode 100644 index 000000000000..594043d63fe4 --- /dev/null +++ b/benchmark/diagnostics_channel/tracing-channel-promise.js @@ -0,0 +1,53 @@ +'use strict'; + +const common = require('../common.js'); +const dc = require('node:diagnostics_channel'); + +const bench = common.createBenchmark(main, { + n: [1e7], + context: ['omitted', 'undefined', 'provided'], + subscribers: [0, 1], +}); + +function noop() {} + +const thenable = { + then(onResolve) { + onResolve(undefined); + }, +}; + +function returnThenable() { + return thenable; +} + +function main({ n, context, subscribers }) { + const channel = dc.tracingChannel('test'); + const providedContext = { __proto__: null }; + + if (subscribers) { + channel.subscribe({ start: noop }); + } + + bench.start(); + switch (context) { + case 'omitted': + for (let i = 0; i < n; i++) { + channel.tracePromise(returnThenable); + } + break; + case 'undefined': + for (let i = 0; i < n; i++) { + channel.tracePromise(returnThenable, undefined); + } + break; + case 'provided': + for (let i = 0; i < n; i++) { + channel.tracePromise(returnThenable, providedContext); + } + break; + default: + throw new Error(`Unsupported context value: ${context}`); + } + bench.end(n); +} diff --git a/benchmark/diagnostics_channel/tracing-channel-sync.js b/benchmark/diagnostics_channel/tracing-channel-sync.js new file mode 100644 index 000000000000..bfd9dd939cc0 --- /dev/null +++ b/benchmark/diagnostics_channel/tracing-channel-sync.js @@ -0,0 +1,43 @@ +'use strict'; + +const common = require('../common.js'); +const dc = require('node:diagnostics_channel'); + +const bench = common.createBenchmark(main, { + n: [1e7], + context: ['omitted', 'undefined', 'provided'], + subscribers: [0, 1], +}); + +function noop() {} + +function main({ n, context, subscribers }) { + const channel = dc.tracingChannel('test'); + const providedContext = { __proto__: null }; + + if (subscribers) { + channel.subscribe({ start: noop }); + } + + bench.start(); + switch (context) { + case 'omitted': + for (let i = 0; i < n; i++) { + channel.traceSync(noop); + } + break; + case 'undefined': + for (let i = 0; i < n; i++) { + channel.traceSync(noop, undefined); + } + break; + case 'provided': + for (let i = 0; i < n; i++) { + channel.traceSync(noop, providedContext); + } + break; + default: + throw new Error(`Unsupported context value: ${context}`); + } + bench.end(n); +} diff --git a/benchmark/ffi/add-64.js b/benchmark/ffi/add-64.js index 1af3de2296a5..d3b8f9e21e03 100644 --- a/benchmark/ffi/add-64.js +++ b/benchmark/ffi/add-64.js @@ -6,8 +6,6 @@ const { libraryPath, ensureFixtureLibrary } = require('./common.js'); const bench = common.createBenchmark(main, { n: [1e7], -}, { - flags: ['--experimental-ffi'], }); ensureFixtureLibrary(); diff --git a/benchmark/ffi/add-f32.js b/benchmark/ffi/add-f32.js index a958e80c1819..afb42a4a48e5 100644 --- a/benchmark/ffi/add-f32.js +++ b/benchmark/ffi/add-f32.js @@ -6,8 +6,6 @@ const { libraryPath, ensureFixtureLibrary } = require('./common.js'); const bench = common.createBenchmark(main, { n: [1e7], -}, { - flags: ['--experimental-ffi'], }); ensureFixtureLibrary(); diff --git a/benchmark/ffi/add-f64.js b/benchmark/ffi/add-f64.js index f4e1dbac4ac3..a4aec85fa935 100644 --- a/benchmark/ffi/add-f64.js +++ b/benchmark/ffi/add-f64.js @@ -6,8 +6,6 @@ const { libraryPath, ensureFixtureLibrary } = require('./common.js'); const bench = common.createBenchmark(main, { n: [1e7], -}, { - flags: ['--experimental-ffi'], }); ensureFixtureLibrary(); diff --git a/benchmark/ffi/add-i16.js b/benchmark/ffi/add-i16.js index 8cd6f989e180..0ce2530d5d33 100644 --- a/benchmark/ffi/add-i16.js +++ b/benchmark/ffi/add-i16.js @@ -6,8 +6,6 @@ const { libraryPath, ensureFixtureLibrary } = require('./common.js'); const bench = common.createBenchmark(main, { n: [1e7], -}, { - flags: ['--experimental-ffi'], }); ensureFixtureLibrary(); diff --git a/benchmark/ffi/add-i32.js b/benchmark/ffi/add-i32.js index 9a77a6f998f7..451c0c4e0836 100644 --- a/benchmark/ffi/add-i32.js +++ b/benchmark/ffi/add-i32.js @@ -6,8 +6,6 @@ const { libraryPath, ensureFixtureLibrary } = require('./common.js'); const bench = common.createBenchmark(main, { n: [1e7], -}, { - flags: ['--experimental-ffi'], }); ensureFixtureLibrary(); diff --git a/benchmark/ffi/add-i64.js b/benchmark/ffi/add-i64.js index 753a300b4394..b72e399d4135 100644 --- a/benchmark/ffi/add-i64.js +++ b/benchmark/ffi/add-i64.js @@ -6,8 +6,6 @@ const { libraryPath, ensureFixtureLibrary } = require('./common.js'); const bench = common.createBenchmark(main, { n: [1e7], -}, { - flags: ['--experimental-ffi'], }); ensureFixtureLibrary(); diff --git a/benchmark/ffi/add-i8.js b/benchmark/ffi/add-i8.js index 9e506b2ad76f..b0b0111f88c7 100644 --- a/benchmark/ffi/add-i8.js +++ b/benchmark/ffi/add-i8.js @@ -6,8 +6,6 @@ const { libraryPath, ensureFixtureLibrary } = require('./common.js'); const bench = common.createBenchmark(main, { n: [1e7], -}, { - flags: ['--experimental-ffi'], }); ensureFixtureLibrary(); diff --git a/benchmark/ffi/add-u16.js b/benchmark/ffi/add-u16.js index 2c1408a355a2..26161815bde7 100644 --- a/benchmark/ffi/add-u16.js +++ b/benchmark/ffi/add-u16.js @@ -6,8 +6,6 @@ const { libraryPath, ensureFixtureLibrary } = require('./common.js'); const bench = common.createBenchmark(main, { n: [1e7], -}, { - flags: ['--experimental-ffi'], }); ensureFixtureLibrary(); diff --git a/benchmark/ffi/add-u64.js b/benchmark/ffi/add-u64.js index 260d24971610..6a021ad5c854 100644 --- a/benchmark/ffi/add-u64.js +++ b/benchmark/ffi/add-u64.js @@ -6,8 +6,6 @@ const { libraryPath, ensureFixtureLibrary } = require('./common.js'); const bench = common.createBenchmark(main, { n: [1e7], -}, { - flags: ['--experimental-ffi'], }); ensureFixtureLibrary(); diff --git a/benchmark/ffi/add-u8.js b/benchmark/ffi/add-u8.js index 3525d4c3d263..3c9512a7869b 100644 --- a/benchmark/ffi/add-u8.js +++ b/benchmark/ffi/add-u8.js @@ -6,8 +6,6 @@ const { libraryPath, ensureFixtureLibrary } = require('./common.js'); const bench = common.createBenchmark(main, { n: [1e7], -}, { - flags: ['--experimental-ffi'], }); ensureFixtureLibrary(); diff --git a/benchmark/ffi/buffer-first-byte-direct.js b/benchmark/ffi/buffer-first-byte-direct.js index 60370419edb7..d09706144702 100644 --- a/benchmark/ffi/buffer-first-byte-direct.js +++ b/benchmark/ffi/buffer-first-byte-direct.js @@ -6,8 +6,6 @@ const { libraryPath, ensureFixtureLibrary } = require('./common.js'); const bench = common.createBenchmark(main, { n: [1e7], -}, { - flags: ['--experimental-ffi'], }); ensureFixtureLibrary(); diff --git a/benchmark/ffi/buffer-first-byte.js b/benchmark/ffi/buffer-first-byte.js index 311cd8e89fac..02b8f190d5e9 100644 --- a/benchmark/ffi/buffer-first-byte.js +++ b/benchmark/ffi/buffer-first-byte.js @@ -6,8 +6,6 @@ const { libraryPath, ensureFixtureLibrary } = require('./common.js'); const bench = common.createBenchmark(main, { n: [1e7], -}, { - flags: ['--experimental-ffi'], }); ensureFixtureLibrary(); diff --git a/benchmark/ffi/buffer-sum-direct.js b/benchmark/ffi/buffer-sum-direct.js index 73b6d149cb76..425832330047 100644 --- a/benchmark/ffi/buffer-sum-direct.js +++ b/benchmark/ffi/buffer-sum-direct.js @@ -6,8 +6,6 @@ const { libraryPath, ensureFixtureLibrary } = require('./common.js'); const bench = common.createBenchmark(main, { n: [1e7], -}, { - flags: ['--experimental-ffi'], }); ensureFixtureLibrary(); diff --git a/benchmark/ffi/buffer-sum.js b/benchmark/ffi/buffer-sum.js index e4108db09a65..fd5ba47363d0 100644 --- a/benchmark/ffi/buffer-sum.js +++ b/benchmark/ffi/buffer-sum.js @@ -6,8 +6,6 @@ const { libraryPath, ensureFixtureLibrary } = require('./common.js'); const bench = common.createBenchmark(main, { n: [1e7], -}, { - flags: ['--experimental-ffi'], }); ensureFixtureLibrary(); diff --git a/benchmark/ffi/get-function.js b/benchmark/ffi/get-function.js index 3c1e2e974ce6..939c1630ab64 100644 --- a/benchmark/ffi/get-function.js +++ b/benchmark/ffi/get-function.js @@ -16,8 +16,6 @@ const { libraryPath, ensureFixtureLibrary } = require('./common.js'); const bench = common.createBenchmark(main, { signature: ['fast', 'slow'], n: [1e3], -}, { - flags: ['--experimental-ffi'], }); ensureFixtureLibrary(); diff --git a/benchmark/ffi/getpid.js b/benchmark/ffi/getpid.js index 8008f407305e..3463a4afe807 100644 --- a/benchmark/ffi/getpid.js +++ b/benchmark/ffi/getpid.js @@ -5,8 +5,6 @@ const ffi = require('node:ffi'); const bench = common.createBenchmark(main, { n: [1e7], -}, { - flags: ['--experimental-ffi'], }); const { lib, functions } = ffi.dlopen(null, { diff --git a/benchmark/ffi/identity-i32.js b/benchmark/ffi/identity-i32.js index 0014d652777f..388645e328a2 100644 --- a/benchmark/ffi/identity-i32.js +++ b/benchmark/ffi/identity-i32.js @@ -6,8 +6,6 @@ const { libraryPath, ensureFixtureLibrary } = require('./common.js'); const bench = common.createBenchmark(main, { n: [1e7], -}, { - flags: ['--experimental-ffi'], }); ensureFixtureLibrary(); diff --git a/benchmark/ffi/invoke-function.js b/benchmark/ffi/invoke-function.js index ae8d5b2ef795..9e461680b7ee 100644 --- a/benchmark/ffi/invoke-function.js +++ b/benchmark/ffi/invoke-function.js @@ -23,7 +23,7 @@ const bench = common.createBenchmark(main, { n: [1e7], symbol: ['call_int_callback', 'sum_8_i32'], }, { - flags: ['--experimental-ffi', '--no-warnings'], + flags: ['--no-warnings'], }); ensureFixtureLibrary(); diff --git a/benchmark/ffi/many-args.js b/benchmark/ffi/many-args.js index bc269ace0c3e..7cd5a4d685ce 100644 --- a/benchmark/ffi/many-args.js +++ b/benchmark/ffi/many-args.js @@ -6,8 +6,6 @@ const { libraryPath, ensureFixtureLibrary } = require('./common.js'); const bench = common.createBenchmark(main, { n: [1e7], -}, { - flags: ['--experimental-ffi'], }); ensureFixtureLibrary(); diff --git a/benchmark/ffi/noop-void.js b/benchmark/ffi/noop-void.js index b9dd68636254..ff606ebb8586 100644 --- a/benchmark/ffi/noop-void.js +++ b/benchmark/ffi/noop-void.js @@ -6,8 +6,6 @@ const { libraryPath, ensureFixtureLibrary } = require('./common.js'); const bench = common.createBenchmark(main, { n: [1e7], -}, { - flags: ['--experimental-ffi'], }); ensureFixtureLibrary(); diff --git a/benchmark/ffi/pointer-bigint.js b/benchmark/ffi/pointer-bigint.js index 9ea01d28490e..6be9577f45b7 100644 --- a/benchmark/ffi/pointer-bigint.js +++ b/benchmark/ffi/pointer-bigint.js @@ -6,8 +6,6 @@ const { libraryPath, ensureFixtureLibrary } = require('./common.js'); const bench = common.createBenchmark(main, { n: [1e7], -}, { - flags: ['--experimental-ffi'], }); ensureFixtureLibrary(); diff --git a/benchmark/ffi/pointer-buffer-direct.js b/benchmark/ffi/pointer-buffer-direct.js index 681800c6e02d..0813e732d6ae 100644 --- a/benchmark/ffi/pointer-buffer-direct.js +++ b/benchmark/ffi/pointer-buffer-direct.js @@ -6,8 +6,6 @@ const { libraryPath, ensureFixtureLibrary } = require('./common.js'); const bench = common.createBenchmark(main, { n: [1e7], -}, { - flags: ['--experimental-ffi'], }); ensureFixtureLibrary(); diff --git a/benchmark/ffi/pointer-buffer.js b/benchmark/ffi/pointer-buffer.js index 4aa038558367..e19a1a035388 100644 --- a/benchmark/ffi/pointer-buffer.js +++ b/benchmark/ffi/pointer-buffer.js @@ -6,8 +6,6 @@ const { libraryPath, ensureFixtureLibrary } = require('./common.js'); const bench = common.createBenchmark(main, { n: [1e7], -}, { - flags: ['--experimental-ffi'], }); ensureFixtureLibrary(); diff --git a/benchmark/ffi/pointer-null.js b/benchmark/ffi/pointer-null.js index c9836b12604e..975e03b739f4 100644 --- a/benchmark/ffi/pointer-null.js +++ b/benchmark/ffi/pointer-null.js @@ -6,8 +6,6 @@ const { libraryPath, ensureFixtureLibrary } = require('./common.js'); const bench = common.createBenchmark(main, { n: [1e7], -}, { - flags: ['--experimental-ffi'], }); ensureFixtureLibrary(); diff --git a/benchmark/ffi/string-equals-hello-buffer-direct.js b/benchmark/ffi/string-equals-hello-buffer-direct.js index 0a4ea8b97112..a05902a54f1f 100644 --- a/benchmark/ffi/string-equals-hello-buffer-direct.js +++ b/benchmark/ffi/string-equals-hello-buffer-direct.js @@ -6,8 +6,6 @@ const { libraryPath, ensureFixtureLibrary } = require('./common.js'); const bench = common.createBenchmark(main, { n: [1e7], -}, { - flags: ['--experimental-ffi'], }); ensureFixtureLibrary(); diff --git a/benchmark/ffi/string-equals-hello-buffer.js b/benchmark/ffi/string-equals-hello-buffer.js index 7757586d472c..eb7839d48508 100644 --- a/benchmark/ffi/string-equals-hello-buffer.js +++ b/benchmark/ffi/string-equals-hello-buffer.js @@ -6,8 +6,6 @@ const { libraryPath, ensureFixtureLibrary } = require('./common.js'); const bench = common.createBenchmark(main, { n: [1e7], -}, { - flags: ['--experimental-ffi'], }); ensureFixtureLibrary(); diff --git a/benchmark/ffi/string-first-char-buffer-direct.js b/benchmark/ffi/string-first-char-buffer-direct.js index 693705c94587..641084cdf632 100644 --- a/benchmark/ffi/string-first-char-buffer-direct.js +++ b/benchmark/ffi/string-first-char-buffer-direct.js @@ -6,8 +6,6 @@ const { libraryPath, ensureFixtureLibrary } = require('./common.js'); const bench = common.createBenchmark(main, { n: [1e7], -}, { - flags: ['--experimental-ffi'], }); ensureFixtureLibrary(); diff --git a/benchmark/ffi/string-first-char-buffer.js b/benchmark/ffi/string-first-char-buffer.js index e8a79ac41ad6..cac665039390 100644 --- a/benchmark/ffi/string-first-char-buffer.js +++ b/benchmark/ffi/string-first-char-buffer.js @@ -6,8 +6,6 @@ const { libraryPath, ensureFixtureLibrary } = require('./common.js'); const bench = common.createBenchmark(main, { n: [1e7], -}, { - flags: ['--experimental-ffi'], }); ensureFixtureLibrary(); diff --git a/benchmark/ffi/string-length-buffer-direct.js b/benchmark/ffi/string-length-buffer-direct.js index cfbb819d8026..b2de28b209e8 100644 --- a/benchmark/ffi/string-length-buffer-direct.js +++ b/benchmark/ffi/string-length-buffer-direct.js @@ -6,8 +6,6 @@ const { libraryPath, ensureFixtureLibrary } = require('./common.js'); const bench = common.createBenchmark(main, { n: [1e7], -}, { - flags: ['--experimental-ffi'], }); ensureFixtureLibrary(); diff --git a/benchmark/ffi/string-length-buffer.js b/benchmark/ffi/string-length-buffer.js index 3b0ea8aef13a..36d11db86420 100644 --- a/benchmark/ffi/string-length-buffer.js +++ b/benchmark/ffi/string-length-buffer.js @@ -6,8 +6,6 @@ const { libraryPath, ensureFixtureLibrary } = require('./common.js'); const bench = common.createBenchmark(main, { n: [1e7], -}, { - flags: ['--experimental-ffi'], }); ensureFixtureLibrary(); diff --git a/benchmark/ffi/string-length-string-direct.js b/benchmark/ffi/string-length-string-direct.js index cfbb819d8026..b2de28b209e8 100644 --- a/benchmark/ffi/string-length-string-direct.js +++ b/benchmark/ffi/string-length-string-direct.js @@ -6,8 +6,6 @@ const { libraryPath, ensureFixtureLibrary } = require('./common.js'); const bench = common.createBenchmark(main, { n: [1e7], -}, { - flags: ['--experimental-ffi'], }); ensureFixtureLibrary(); diff --git a/benchmark/ffi/string-length-string.js b/benchmark/ffi/string-length-string.js index 9cddfdf4e950..23284973405d 100644 --- a/benchmark/ffi/string-length-string.js +++ b/benchmark/ffi/string-length-string.js @@ -6,8 +6,6 @@ const { libraryPath, ensureFixtureLibrary } = require('./common.js'); const bench = common.createBenchmark(main, { n: [1e7], -}, { - flags: ['--experimental-ffi'], }); ensureFixtureLibrary(); diff --git a/benchmark/ffi/sum-3-i32.js b/benchmark/ffi/sum-3-i32.js index 174979183819..9e3f842b54ca 100644 --- a/benchmark/ffi/sum-3-i32.js +++ b/benchmark/ffi/sum-3-i32.js @@ -6,8 +6,6 @@ const { libraryPath, ensureFixtureLibrary } = require('./common.js'); const bench = common.createBenchmark(main, { n: [1e7], -}, { - flags: ['--experimental-ffi'], }); ensureFixtureLibrary(); diff --git a/benchmark/ffi/sum-5-i32.js b/benchmark/ffi/sum-5-i32.js index ecc784a3d045..490691ad2b33 100644 --- a/benchmark/ffi/sum-5-i32.js +++ b/benchmark/ffi/sum-5-i32.js @@ -6,8 +6,6 @@ const { libraryPath, ensureFixtureLibrary } = require('./common.js'); const bench = common.createBenchmark(main, { n: [1e7], -}, { - flags: ['--experimental-ffi'], }); ensureFixtureLibrary(); diff --git a/benchmark/ffi/sum-8-i32.js b/benchmark/ffi/sum-8-i32.js index 8c740030307a..b1d53d693bfa 100644 --- a/benchmark/ffi/sum-8-i32.js +++ b/benchmark/ffi/sum-8-i32.js @@ -6,8 +6,6 @@ const { libraryPath, ensureFixtureLibrary } = require('./common.js'); const bench = common.createBenchmark(main, { n: [1e7], -}, { - flags: ['--experimental-ffi'], }); ensureFixtureLibrary(); diff --git a/benchmark/ffi/sum-buffer.js b/benchmark/ffi/sum-buffer.js index 60e25a854185..da87aa28ebd4 100644 --- a/benchmark/ffi/sum-buffer.js +++ b/benchmark/ffi/sum-buffer.js @@ -7,8 +7,6 @@ const { libraryPath, ensureFixtureLibrary } = require('./common.js'); const bench = common.createBenchmark(main, { size: [64, 1024, 16384], n: [1e6], -}, { - flags: ['--experimental-ffi'], }); ensureFixtureLibrary(); diff --git a/benchmark/fs/bench-cp.js b/benchmark/fs/bench-cp.js new file mode 100644 index 000000000000..ffaeb87705f5 --- /dev/null +++ b/benchmark/fs/bench-cp.js @@ -0,0 +1,33 @@ +'use strict'; + +// fs.promises.cp() of a directory tree. + +const common = require('../common'); +const fs = require('fs'); +const path = require('path'); +const tmpdir = require('../../test/common/tmpdir'); + +const bench = common.createBenchmark(main, { + files: [500], + n: [3], +}); + +function prepareSource(files) { + const src = tmpdir.resolve('cp-src'); + for (let i = 0; i < files; i++) { + const dir = path.join(src, `dir-${i % 10}`, `sub-${i % 7}`); + fs.mkdirSync(dir, { recursive: true }); + fs.writeFileSync(path.join(dir, `file-${i}.js`), 'x'.repeat(1024 + (i % 512))); + } + return src; +} + +async function main({ files, n }) { + tmpdir.refresh(); + const src = prepareSource(files); + bench.start(); + for (let i = 0; i < n; i++) { + await fs.promises.cp(src, tmpdir.resolve(`cp-dest-${i}`), { recursive: true }); + } + bench.end(n); +} diff --git a/benchmark/fs/bench-glob.js b/benchmark/fs/bench-glob.js index 74612701e218..4652a48f5241 100644 --- a/benchmark/fs/bench-glob.js +++ b/benchmark/fs/bench-glob.js @@ -16,6 +16,7 @@ const configs = { dir: ['lib'], pattern: ['**/*', '*.js', '**/**.js'], mode: ['sync', 'promise', 'callback'], + maxDepth: ['default', '2'], recursive: ['true', 'false'], }; @@ -23,8 +24,11 @@ const bench = common.createBenchmark(main, configs); async function main(config) { const fullPath = path.resolve(benchmarkDirectory, config.dir); - const { pattern, recursive, mode } = config; + const { pattern, recursive, mode, maxDepth } = config; const options = { cwd: fullPath, recursive }; + if (maxDepth !== 'default') { + options.maxDepth = Number(maxDepth); + } const callback = (resolve, reject) => { glob(pattern, options, (err, matches) => { if (err) { @@ -44,7 +48,10 @@ async function main(config) { noDead = globSync(pattern, options); break; case 'promise': - noDead = await globAsync(pattern, options); + noDead = []; + for await (const match of globAsync(pattern, options)) { + noDead.push(match); + } break; case 'callback': noDead = await new Promise(callback); diff --git a/benchmark/fs/bench-readdir-recursive.js b/benchmark/fs/bench-readdir-recursive.js new file mode 100644 index 000000000000..6ed56995dcea --- /dev/null +++ b/benchmark/fs/bench-readdir-recursive.js @@ -0,0 +1,47 @@ +'use strict'; + +const common = require('../common'); +const fs = require('fs'); +const path = require('path'); +const assert = require('assert'); + +const bench = common.createBenchmark(main, { + n: [10], + dir: ['lib', 'test/parallel', 'test'], + mode: ['sync', 'callback', 'promise'], + withFileTypes: ['true', 'false'], +}); + +async function main({ n, dir, mode, withFileTypes }) { + withFileTypes = withFileTypes === 'true'; + const fullPath = path.resolve(__dirname, '../../', dir); + const options = { recursive: true, withFileTypes }; + let entries; + + bench.start(); + switch (mode) { + case 'sync': + for (let i = 0; i < n; i++) { + entries = fs.readdirSync(fullPath, options); + } + break; + case 'callback': + for (let i = 0; i < n; i++) { + entries = await new Promise((resolve, reject) => { + fs.readdir(fullPath, options, (err, result) => { + if (err) reject(err); + else resolve(result); + }); + }); + } + break; + case 'promise': + for (let i = 0; i < n; i++) { + entries = await fs.promises.readdir(fullPath, options); + } + break; + } + bench.end(n); + + assert.ok(entries.length > 0); +} diff --git a/benchmark/fs/bench-readdir.js b/benchmark/fs/bench-readdir.js index e276653f4584..8fa0e7a3cbdc 100644 --- a/benchmark/fs/bench-readdir.js +++ b/benchmark/fs/bench-readdir.js @@ -8,18 +8,16 @@ const bench = common.createBenchmark(main, { n: [10], dir: [ 'lib', 'test/parallel'], withFileTypes: ['true', 'false'], - recursive: ['true', 'false'], }); -function main({ n, dir, withFileTypes, recursive }) { +function main({ n, dir, withFileTypes }) { withFileTypes = withFileTypes === 'true'; - recursive = recursive === 'true'; const fullPath = path.resolve(__dirname, '../../', dir); bench.start(); (function r(cntr) { if (cntr-- <= 0) return bench.end(n); - fs.readdir(fullPath, { withFileTypes, recursive }, () => { + fs.readdir(fullPath, { withFileTypes }, () => { r(cntr); }); }(n)); diff --git a/benchmark/fs/bench-readdirSync.js b/benchmark/fs/bench-readdirSync.js index ce34e083cb53..8ae1d061d1f1 100644 --- a/benchmark/fs/bench-readdirSync.js +++ b/benchmark/fs/bench-readdirSync.js @@ -8,17 +8,15 @@ const bench = common.createBenchmark(main, { n: [10], dir: [ 'lib', 'test/parallel'], withFileTypes: ['true', 'false'], - recursive: ['true', 'false'], }); -function main({ n, dir, withFileTypes, recursive }) { +function main({ n, dir, withFileTypes }) { withFileTypes = withFileTypes === 'true'; - recursive = recursive === 'true'; const fullPath = path.resolve(__dirname, '../../', dir); bench.start(); for (let i = 0; i < n; i++) { - fs.readdirSync(fullPath, { withFileTypes, recursive }); + fs.readdirSync(fullPath, { withFileTypes }); } bench.end(n); } diff --git a/benchmark/fs/bench-watch-recursive.js b/benchmark/fs/bench-watch-recursive.js new file mode 100644 index 000000000000..45ed0871718e --- /dev/null +++ b/benchmark/fs/bench-watch-recursive.js @@ -0,0 +1,23 @@ +'use strict'; + +// Setting up (and tearing down) a recursive fs.watch() on a directory tree. +// On Linux and other platforms without a native recursive watcher this is +// implemented in JavaScript on top of per-directory watchers. + +const common = require('../common'); +const fs = require('fs'); +const path = require('path'); + +const bench = common.createBenchmark(main, { + n: [5], + dir: ['lib', 'test/fixtures'], +}); + +function main({ n, dir }) { + const fullPath = path.resolve(__dirname, '../../', dir); + bench.start(); + for (let i = 0; i < n; i++) { + fs.watch(fullPath, { recursive: true }).close(); + } + bench.end(n); +} diff --git a/benchmark/http2/full-duplex.js b/benchmark/http2/full-duplex.js new file mode 100644 index 000000000000..d2fec719f95a --- /dev/null +++ b/benchmark/http2/full-duplex.js @@ -0,0 +1,71 @@ +'use strict'; + +const common = require('../common.js'); +const fixtures = require('../../test/common/fixtures'); + +const bench = common.createBenchmark(main, { + n: [100], + streams: [2], + size: [4 * 1024 * 1024], + // Use the HTTP/2 protocol default. + window: [65535], +}, { + test: { size: 128 * 1024, window: 65535 }, +}); + +function main({ n, streams, size, window }) { + const http2 = require('http2'); + const payload = Buffer.alloc(size); + const server = http2.createSecureServer({ + key: fixtures.readKey('agent1-key.pem'), + cert: fixtures.readKey('agent1-cert.pem'), + settings: { initialWindowSize: window }, + }); + + let completed = 0; + let batches = 0; + + function onTransferComplete() { + if (++completed !== streams * 2) + return; + + if (++batches === n) { + // Report combined upload and download throughput in MiB/s. + bench.end(n * streams * size * 2 / (1024 * 1024)); + client.close(); + server.close(); + return; + } + + startBatch(); + } + + server.on('stream', (stream) => { + stream.resume(); + stream.on('end', onTransferComplete); + stream.respond(); + stream.end(payload); + }); + + let client; + function startBatch() { + completed = 0; + for (let i = 0; i < streams; i++) { + const request = client.request({ ':method': 'POST' }); + request.resume(); + request.on('end', onTransferComplete); + request.end(payload); + } + } + + server.listen(0, () => { + client = http2.connect(`https://localhost:${server.address().port}`, { + rejectUnauthorized: false, + settings: { initialWindowSize: window }, + }); + client.on('connect', () => { + bench.start(); + startBatch(); + }); + }); +} diff --git a/benchmark/misc/startup-core.js b/benchmark/misc/startup-core.js index 414b00176ad2..d673d415b505 100644 --- a/benchmark/misc/startup-core.js +++ b/benchmark/misc/startup-core.js @@ -64,6 +64,7 @@ function main({ n, script, mode }) { const warmup = 3; const state = { n, finished: -warmup }; if (mode === 'worker') { + // eslint-disable-next-line no-global-assign Worker = require('worker_threads').Worker; spawnWorker(script, bench, state); } else { diff --git a/benchmark/module/module-require-source-map.js b/benchmark/module/module-require-source-map.js new file mode 100644 index 000000000000..8353ab39fc82 --- /dev/null +++ b/benchmark/module/module-require-source-map.js @@ -0,0 +1,77 @@ +'use strict'; + +// Loading modules that carry source maps, with source map support enabled. +// This is the cost paid at startup by applications bundled or transpiled with +// source maps; the maps are only consulted if a stack trace is generated. + +const fs = require('fs'); +const path = require('path'); +const common = require('../common.js'); +const tmpdir = require('../../test/common/tmpdir'); +const benchmarkDirectory = tmpdir.resolve('nodejs-benchmark-module-source-map'); + +const bench = common.createBenchmark(main, { + sourceMap: ['none', 'inline', 'external'], + n: [1000], +}, { + setup(configs) { + tmpdir.refresh(); + const maxN = configs.reduce((max, c) => Math.max(max, c.n), 0); + createModules(maxN); + }, +}); + +function moduleSource(i) { + const methods = []; + for (let m = 0; m < 40; m++) { + methods.push(` method${m}(input) { return [].concat(input).map((item) => ({ item, m: ${m}, service: ${i} })); }`); + } + return `'use strict'; +class Service${i} { + constructor(options = {}) { this.options = { retries: 3, ...options }; } +${methods.join('\n')} +} +function helper${i}(list) { return list.filter(Boolean).slice(0, ${i % 7}); } +module.exports = { Service${i}, helper${i} }; +`; +} + +function sourceMapFor(i, source) { + return JSON.stringify({ + version: 3, + file: `${i}.js`, + sources: [`../src/${i}.ts`], + sourcesContent: [source], + names: [], + mappings: 'AAAA;' + 'AACA,MAAM;'.repeat(44), + }); +} + +function createModules(n) { + for (const kind of ['none', 'inline', 'external']) { + const dir = path.join(benchmarkDirectory, kind); + fs.mkdirSync(dir, { recursive: true }); + for (let i = 0; i < n; i++) { + const source = moduleSource(i); + let trailer = ''; + if (kind === 'inline') { + const data = Buffer.from(sourceMapFor(i, source)).toString('base64'); + trailer = `//# sourceMappingURL=data:application/json;base64,${data}\n`; + } else if (kind === 'external') { + fs.writeFileSync(path.join(dir, `${i}.js.map`), sourceMapFor(i, source)); + trailer = `//# sourceMappingURL=${i}.js.map\n`; + } + fs.writeFileSync(path.join(dir, `${i}.js`), source + trailer); + } + } +} + +function main({ sourceMap, n }) { + process.setSourceMapsEnabled(true); + const dir = path.join(benchmarkDirectory, sourceMap); + bench.start(); + for (let i = 0; i < n; i++) { + require(path.join(dir, `${i}.js`)); + } + bench.end(n); +} diff --git a/benchmark/quic/h3-request.js b/benchmark/quic/h3-request.js new file mode 100644 index 000000000000..f96a18407ae1 --- /dev/null +++ b/benchmark/quic/h3-request.js @@ -0,0 +1,150 @@ +'use strict'; + +// Measures a complete HTTP/3 exchange: establish a session, send one request +// and read the whole response. Run in two modes, so the cost of a resumed +// 0-RTT session can be compared against a full handshake. +// +// The 0-RTT mode needs a session ticket, which can only come from an earlier +// connection. That first connection is made during warmup, outside the +// measured region, so what is timed is only the resumed exchange. + +const common = require('../common.js'); +const fixtures = require('../../test/common/fixtures'); +const { createPrivateKey } = require('crypto'); + +const bench = common.createBenchmark(main, { + // '0rtt' resumes from a ticket and sends the request in the very first + // flight; '1rtt' is a fresh session each time. 0-RTT is listed first so + // that it is the mode the benchmark CI test exercises. + mode: ['0rtt', '1rtt'], + n: [500], +}, { flags: ['--experimental-quic', '--experimental-stream-iter', + '--no-warnings'] }); + +async function main({ mode, n }) { + const { listen, connect } = require('node:quic'); + const { bytes } = require('stream/iter'); + + const key = createPrivateKey(fixtures.readKey('agent1-key.pem')); + const cert = fixtures.readKey('agent1-cert.pem'); + const body = new TextEncoder().encode('x'.repeat(256)); + const decoder = new TextDecoder(); + + const request = { + ':method': 'GET', + ':path': '/', + ':scheme': 'https', + ':authority': 'localhost', + }; + + const endpoint = await listen((session) => { + session.opened.catch(() => {}); + session.closed.catch(() => {}); + session.onstream = (stream) => { stream.closed.catch(() => {}); }; + }, { + sni: { '*': { keys: [key], certs: [cert] } }, + onheaders() { + this.sendHeaders({ ':status': '200' }); + this.writer.writeSync(body); + this.writer.endSync(); + }, + endpoint: { + maxConnectionsPerHost: 0xFFFF, + maxConnectionsTotal: 0xFFFF, + sessionCreationRate: 1_000_000, + sessionCreationBurst: 1_000_000, + }, + }); + + const address = endpoint.address; + let received = 0; + const onheaders = () => { received++; }; + + // A full handshake, one request, one response. When resume is supplied the + // request goes out in the first flight, before the handshake completes. + async function exchange(resume) { + const session = await connect(address, { + servername: 'localhost', + verifyPeer: 'manual', + alpn: 'h3', + ...resume, + }); + const stream = await session.createBidirectionalStream({ + headers: request, + onheaders, + }); + if (resume === undefined) await session.opened; + const response = decoder.decode(await bytes(stream)); + if (response.length !== body.length) { + throw new Error(`short response: ${response.length}`); + } + session.close(); + await session.closed.catch(() => {}); + return session; + } + + // Collect a ticket for the 0-RTT mode from a connection that is not timed. + let resume; + if (mode === '0rtt') { + const { promise, resolve } = Promise.withResolvers(); + let ticket; + let token; + const session = await connect(address, { + servername: 'localhost', + verifyPeer: 'manual', + alpn: 'h3', + onsessionticket(value) { + ticket ??= value; + if (token !== undefined) resolve(); + }, + onnewtoken(value) { + token ??= value; + if (ticket !== undefined) resolve(); + }, + }); + await session.opened; + await promise; + session.close(); + await session.closed.catch(() => {}); + resume = { sessionTicket: ticket, token }; + } + + // The timed 0-RTT exchanges deliberately never await session.opened, since + // waiting for the handshake is exactly what 0-RTT avoids. That leaves no + // opportunity to notice early data being refused, so check separately - + // otherwise a ticket the server stopped accepting would quietly turn this + // into a measurement of the 1-RTT path. + async function checkEarlyDataAccepted() { + const session = await connect(address, { + servername: 'localhost', + verifyPeer: 'manual', + alpn: 'h3', + ...resume, + }); + const stream = await session.createBidirectionalStream({ + headers: request, + onheaders, + }); + const info = await session.opened; + await bytes(stream); + session.close(); + await session.closed.catch(() => {}); + if (!info.earlyDataAccepted) { + throw new Error('0-RTT was not accepted, benchmark would be invalid'); + } + } + + for (let i = 0; i < 20; i++) await exchange(resume); + if (mode === '0rtt') await checkEarlyDataAccepted(); + + received = 0; + bench.start(); + for (let i = 0; i < n; i++) await exchange(resume); + bench.end(n); + + if (received !== n) throw new Error(`missing responses: ${received}/${n}`); + // The ticket is reused for every iteration, so confirm it was still being + // accepted at the end of the run and not just at the start. + if (mode === '0rtt') await checkEarlyDataAccepted(); + await endpoint.close(); +} diff --git a/benchmark/quic/handshake.js b/benchmark/quic/handshake.js new file mode 100644 index 000000000000..9f0404008e03 --- /dev/null +++ b/benchmark/quic/handshake.js @@ -0,0 +1,74 @@ +'use strict'; + +// Measures the cost of establishing QUIC sessions: how many complete +// handshakes per second a single endpoint can serve, for raw QUIC and for +// HTTP/3. Nothing is sent on the session beyond what the protocol itself +// requires, so this isolates connection setup rather than data transfer. + +const common = require('../common.js'); +const fixtures = require('../../test/common/fixtures'); +const { createPrivateKey } = require('crypto'); + +const bench = common.createBenchmark(main, { + // 'raw' negotiates a non-HTTP ALPN and does no application work. + // 'h3' negotiates HTTP/3, so the server also builds an nghttp3 connection + // and its control/QPACK streams for every session. + protocol: ['raw', 'h3'], + concurrency: [1, 10], + n: [1000], +}, { flags: ['--experimental-quic', '--no-warnings'] }); + +async function main({ protocol, concurrency, n }) { + const { listen, connect } = require('node:quic'); + + const key = createPrivateKey(fixtures.readKey('agent1-key.pem')); + const cert = fixtures.readKey('agent1-cert.pem'); + const alpn = protocol === 'h3' ? 'h3' : 'quic-bench'; + + const endpoint = await listen((session) => { + // A benchmark peer never reads these; swallow so a torn-down session + // cannot produce an unhandled rejection. + session.opened.catch(() => {}); + session.closed.catch(() => {}); + }, { + sni: { '*': { keys: [key], certs: [cert] } }, + alpn: [alpn], + // The defaults rate-limit session creation per host, which a benchmark + // hammering a single address would otherwise trip. + endpoint: { + maxConnectionsPerHost: 0xFFFF, + maxConnectionsTotal: 0xFFFF, + sessionCreationRate: 1_000_000, + sessionCreationBurst: 1_000_000, + }, + }); + + const address = endpoint.address; + + async function handshake() { + const session = await connect(address, { + servername: 'localhost', + verifyPeer: 'manual', + alpn, + }); + await session.opened; + session.close(); + await session.closed.catch(() => {}); + } + + async function run(count) { + for (let i = 0; i < count; i += concurrency) { + const batch = Math.min(concurrency, count - i); + await Promise.all(Array.from({ length: batch }, handshake)); + } + } + + // Warm up the TLS and QUIC machinery before measuring. + await run(Math.min(100, n)); + + bench.start(); + await run(n); + bench.end(n); + + await endpoint.close(); +} diff --git a/benchmark/scatter-node-bench.js b/benchmark/scatter-node-bench.js new file mode 100644 index 000000000000..4527ecc6b8b4 --- /dev/null +++ b/benchmark/scatter-node-bench.js @@ -0,0 +1,131 @@ +'use strict'; + +const CLI = require('./_cli.js'); +const { + analyzeScatter, + validateScatterParameters, +} = require('./_node-bench-analysis.js'); +const { + csvEncode, + parseInteger, + runBenchmark, +} = require('./_node-bench.js'); + +const cli = new CLI(`usage: ./node scatter-node-bench.js [options] [--] + Run an explicit node:bench file repeatedly and output each independent + observation with its benchmark parameters as CSV, or summarize the results + directly with --analyze. + + --node ./node Node.js binary + --runs 30 number of observations + --warmup 0 warmup samples before each observation + --name-pattern pattern only run matching benchmarks + --node-arg argument pass an argument to the binary (repeatable) + --analyze print a statistical summary instead of CSV + --xaxis parameter parameter to group by with --analyze (required) + --category parameter optional second grouping parameter + --no-chart omit the analysis bar chart +`, { + arrayArgs: ['node-arg'], + boolArgs: ['analyze', 'no-chart'], +}); + +if (cli.items.length !== 1) cli.abort(cli.usage); +if (cli.optional.analyze && cli.optional.xaxis === undefined) { + cli.abort('--analyze requires --xaxis '); +} + +async function main() { + const runs = parseInteger(cli.optional.runs, 30, '--runs', 1); + const warmup = parseInteger(cli.optional.warmup, 0, '--warmup', 0); + const options = { + namePattern: cli.optional['name-pattern'], + nodeArgs: cli.optional['node-arg'], + warmup, + }; + const binary = cli.optional.node || process.execPath; + const rows = []; + const paramNames = new Set(); + const csvGroups = new Map(); + let expectedIdentities; + let logicalIdentity; + + for (let run = 0; run < runs; run++) { + const samples = await runBenchmark(binary, cli.items[0], options); + if (run === 0 && cli.optional.analyze) { + validateScatterParameters( + samples, cli.optional.xaxis, cli.optional.category); + } + const identities = new Set(); + for (const sample of samples) { + if (logicalIdentity !== undefined && + logicalIdentity !== sample.logicalIdentity) { + throw new Error( + 'scatter-node-bench.js requires one logical benchmark name per file', + ); + } + logicalIdentity = sample.logicalIdentity; + if (identities.has(sample.identity)) { + throw new Error(`Benchmark '${sample.name}' was reported more than once`); + } + identities.add(sample.identity); + const csvGroup = JSON.stringify([sample.name, sample.params]); + const groupedIdentity = csvGroups.get(csvGroup); + if (groupedIdentity !== undefined && + groupedIdentity !== sample.identity) { + throw new Error( + `Distinct benchmarks would share the CSV group '${sample.name}'`, + ); + } + csvGroups.set(csvGroup, sample.identity); + rows.push({ ...sample, observation: run }); + for (const name of Object.keys(sample.params)) paramNames.add(name); + } + if (expectedIdentities === undefined) { + expectedIdentities = identities; + } else if (identities.size !== expectedIdentities.size || + ![...identities].every((id) => expectedIdentities.has(id))) { + throw new Error('The set of reported benchmarks changed between runs'); + } + } + if (rows.length === 0) { + throw new Error('No benchmark samples were produced'); + } + + const params = [...paramNames].sort(); + if (cli.optional.analyze) { + const output = analyzeScatter( + rows, + cli.optional.xaxis, + cli.optional.category, + !cli.optional['no-chart'], + ); + process.stdout.write(output); + return; + } + + for (const name of params) { + if (name === 'filename' || name === 'rate' || name === 'time') { + throw new Error(`Benchmark parameter '${name}' is reserved in scatter CSV`); + } + } + const header = ['filename', ...params, 'rate', 'time'] + .map(csvEncode) + .join(','); + const output = [header]; + for (const row of rows) { + const values = [ + csvEncode(row.name), + ...params.map((name) => csvEncode(row.params[name] ?? '')), + row.rate, + row.duration, + ]; + output.push(values.join(',')); + } + process.stdout.write(`${output.join('\n')}\n`); +} + +main().catch((error) => { + console.error(error.stack); + process.exitCode = 1; +}); diff --git a/benchmark/scatter.js b/benchmark/scatter.js index 858169d7d68c..cb1df965b70f 100644 --- a/benchmark/scatter.js +++ b/benchmark/scatter.js @@ -1,62 +1,167 @@ 'use strict'; -const fork = require('child_process').fork; +const { spawn, fork } = require('node:child_process'); +const { createHistogram } = require('node:perf_hooks'); +const { inspect } = require('util'); const path = require('path'); const CLI = require('./_cli.js'); +const BenchmarkProgress = require('./_benchmark_progress.js'); // // Parse arguments // const cli = new CLI(`usage: ./node scatter.js [options] [--] Run the benchmark script many times and output the rate (ops/s) - together with the benchmark variables as a csv. + together with the benchmark variables as a csv, which can be processed using + for example 'scatter.R'. Use --analyze to summarize the results directly + without R. --runs 30 number of samples --set variable=value set benchmark variable (can be repeated) -`, { arrayArgs: ['set'] }); + --no-progress don't show benchmark progress indicator + --analyze print a statistical summary (mean rate and confidence + interval per group) instead of csv output + --xaxis variable variable to group by when using --analyze (required + by --analyze) + --category variable additional variable to group by when using --analyze + --no-chart don't print the bar chart when using --analyze + + Examples: + --set CPUSET=0 Runs benchmarks on CPU core 0. + --set CPUSET=0-2 Specifies that benchmarks should run on CPU cores 0 to 2. + + Note: The CPUSET format should match the specifications of the 'taskset' command +`, { + arrayArgs: ['set'], + boolArgs: ['no-progress', 'analyze', 'no-chart'], +}); if (cli.items.length !== 1) { cli.abort(cli.usage); } -// Create queue from the benchmarks list such both node versions are tested -// `runs` amount of times each. const filepath = path.resolve(cli.items[0]); -const name = filepath.slice(__dirname.length + 1); +const name = path.relative(__dirname, filepath); const runs = cli.optional.runs ? parseInt(cli.optional.runs, 10) : 30; +const analyze = !!cli.optional.analyze; +const showChart = !cli.optional['no-chart']; +const xAxis = cli.optional.xaxis; +const category = cli.optional.category; + +// Grouping is what makes the summary meaningful, so --analyze needs to know +// which variable is the independent one. There is no sensible default: the +// answer depends entirely on what is being measured. +if (analyze && !xAxis) { + cli.abort( + `--analyze requires --xaxis + + --xaxis names the benchmark variable to summarize against; --category + optionally breaks each point down by a second variable. Both must be + configuration variables of this benchmark -- the keys passed to + createBenchmark() at the top of the benchmark file. Nearly every + benchmark defines 'n'; parameter sweeps add a size or mode variable + such as 'len', 'size' or 'encoding'. + + Example: + ./node benchmark/scatter.js --analyze --xaxis n ${name} +`, + ); +} + +// When --analyze is set, collect results rather than streaming csv. +const samples = analyze ? [] : null; let printHeader = true; function csvEncodeValue(value) { - if (typeof value === 'number') { + // Benchmark configuration values are numbers, booleans or strings + // (see the config parsing in common.js). Only strings need quoting, + // but anything unexpected is stringified rather than crashing the run. + if (typeof value === 'number' || typeof value === 'boolean') { return value.toString(); } - return `"${value.replace(/"/g, '""')}"`; + return `"${String(value).replace(/"/g, '""')}"`; +} + +// Note: BenchmarkProgress reports progress per file; scatter.js only ever +// runs one file, so every queue entry shares the same filename. +const queue = []; +for (let iter = 0; iter < runs; iter++) { + queue.push({ filename: name, iter }); +} + +const kStartOfQueue = 0; + +const showProgress = !cli.optional['no-progress']; +let progress; +if (showProgress) { + progress = new BenchmarkProgress(queue, [name], { analyze }); + progress.startQueue(kStartOfQueue); } (function recursive(i) { - const child = fork(path.resolve(__dirname, filepath), cli.optional.set); + const cpuCore = cli.getCpuCoreSetting(); + let child; + if (cpuCore !== null) { + const spawnArgs = ['-c', cpuCore, process.execPath, filepath, ...cli.optional.set]; + child = spawn('taskset', spawnArgs, { + env: process.env, + stdio: ['inherit', 'inherit', 'inherit', 'ipc'], + }); + } else { + child = fork(filepath, cli.optional.set); + } child.on('message', (data) => { - if (data.type !== 'report') { + if (data.type === 'config') { + if (showProgress) { + progress.startSubqueue(data, i); + } return; } - // print csv header - if (printHeader) { - const confHeader = Object.keys(data.conf) - .map(csvEncodeValue) - .join(', '); - console.log(`"filename", ${confHeader}, "rate", "time"`); - printHeader = false; + if (data.type !== 'report') { + return; } - // print data row - const confData = Object.keys(data.conf) - .map((key) => csvEncodeValue(data.conf[key])) - .join(', '); + if (analyze) { + // Validate the grouping variables against the first result rather than + // at the end. A typo in --xaxis is otherwise not reported until the + // whole run has finished, which can be many minutes of wasted work. + if (samples.length === 0) { + const confKeys = Object.keys(data.conf); + for (const key of [xAxis, category]) { + if (key !== undefined && !confKeys.includes(key)) { + child.kill(); + cli.abort( + `The variable "${key}" is not a configuration of ${name}.\n` + + `Available variables: ${confKeys.join(', ')}`, + ); + } + } + } + samples.push(data); + } else { + // print csv header + if (printHeader) { + const confHeader = Object.keys(data.conf) + .map(csvEncodeValue) + .join(','); + console.log(`"filename",${confHeader},"rate","time"`); + printHeader = false; + } + + // print data row + const confData = Object.keys(data.conf) + .map((key) => csvEncodeValue(data.conf[key])) + .join(','); - console.log(`"${name}", ${confData}, ${data.rate}, ${data.time}`); + console.log(`"${name}",${confData},${data.rate},${data.time}`); + } + + if (showProgress) { + progress.completeConfig(data); + } }); child.once('close', (code) => { @@ -64,10 +169,768 @@ function csvEncodeValue(value) { process.exit(code); return; } + if (showProgress) { + progress.completeRun(queue[i]); + } // If there are more benchmarks execute the next if (i + 1 < runs) { recursive(i + 1); + } else if (analyze) { + printAnalysis(samples, xAxis, category); } }); -})(0); +})(kStartOfQueue); + +// +// Statistics +// +// scatter.R obtains the t quantile from R's qt(); without R it has to be +// computed here. The Student's t tail probability is an incomplete beta +// function, which is evaluated directly, and the quantile is recovered by +// bisecting it. Bisection rather than an inverse-beta routine because the +// cost is irrelevant at this scale and the error bound is explicit. +// + +// Lanczos approximation, g=7, n=9. +function logGamma(x) { + const g = [ + 676.5203681218851, -1259.1392167224028, 771.32342877765313, + -176.61502916214059, 12.507343278686905, -0.13857109526572012, + 9.9843695780195716e-6, 1.5056327351493116e-7, + ]; + if (x < 0.5) { + // Reflection formula. + return Math.log(Math.PI / Math.sin(Math.PI * x)) - logGamma(1 - x); + } + x -= 1; + let a = 0.99999999999980993; + const t = x + 7.5; + for (let i = 0; i < g.length; i++) { + a += g[i] / (x + i + 1); + } + return 0.5 * Math.log(2 * Math.PI) + (x + 0.5) * Math.log(t) - t + Math.log(a); +} + +// Continued fraction for the incomplete beta function (Lentz's algorithm). +function betaContinuedFraction(x, a, b) { + const tiny = 1e-30; + const qab = a + b; + const qap = a + 1; + const qam = a - 1; + let c = 1; + let d = 1 - qab * x / qap; + if (Math.abs(d) < tiny) d = tiny; + d = 1 / d; + let h = d; + for (let m = 1; m <= 300; m++) { + const m2 = 2 * m; + let aa = m * (b - m) * x / ((qam + m2) * (a + m2)); + d = 1 + aa * d; + if (Math.abs(d) < tiny) d = tiny; + c = 1 + aa / c; + if (Math.abs(c) < tiny) c = tiny; + d = 1 / d; + h *= d * c; + aa = -(a + m) * (qab + m) * x / ((a + m2) * (qap + m2)); + d = 1 + aa * d; + if (Math.abs(d) < tiny) d = tiny; + c = 1 + aa / c; + if (Math.abs(c) < tiny) c = tiny; + d = 1 / d; + const del = d * c; + h *= del; + if (Math.abs(del - 1) < 1e-14) break; + } + return h; +} + +// Regularized incomplete beta function I_x(a, b). +function incompleteBeta(x, a, b) { + if (x <= 0) return 0; + if (x >= 1) return 1; + const lbeta = logGamma(a + b) - logGamma(a) - logGamma(b); + // Use the continued fraction on whichever side converges quickly. + if (x < (a + 1) / (a + b + 2)) { + return Math.exp(lbeta + a * Math.log(x) + b * Math.log(1 - x)) * + betaContinuedFraction(x, a, b) / a; + } + return 1 - Math.exp(lbeta + b * Math.log(1 - x) + a * Math.log(x)) * + betaContinuedFraction(1 - x, b, a) / b; +} + +// Two-tailed probability P(|T| > t) for Student's t with v degrees of freedom. +function tTailProbability(t, v) { + return incompleteBeta(v / (v + t * t), v / 2, 0.5); +} + +// Quantile of Student's t: the value q with P(T <= q) = p, for p > 0.5. +// Equivalent to R's qt(p, v). Accurate to ~1e-6 over the range used here. +function tQuantile(p, v) { + const alpha = 2 * (1 - p); + let lo = 0; + let hi = 1e3; + for (let i = 0; i < 200; i++) { + const mid = (lo + hi) / 2; + if (tTailProbability(mid, v) > alpha) { + lo = mid; + } else { + hi = mid; + } + } + return (lo + hi) / 2; +} + +function printAnalysis(samples, xAxis, category) { + if (samples.length === 0) { + console.error('No benchmark results were reported.'); + process.exitCode = 1; + return; + } + + // The grouping variables were already validated against the first result. + const confKeys = Object.keys(samples[0].conf); + + // Every variable that is neither a grouping variable nor constant across + // the run is averaged over. Report them: an aggregated variable can hide a + // real effect, and the reader has no other way to know it happened. + const aggregated = confKeys.filter((key) => { + if (key === xAxis || key === category) return false; + const first = samples[0].conf[key]; + return samples.some((s) => s.conf[key] !== first); + }); + + // Group by the grouping variables. The full sample is retained, not just + // the rate, so the aggregated variables can be accounted for below. + const groups = new Map(); + for (const sample of samples) { + const xValue = sample.conf[xAxis]; + const catValue = category === undefined ? undefined : sample.conf[category]; + const key = `${String(xValue)}\u0000${String(catValue)}`; + let group = groups.get(key); + if (group === undefined) { + group = { xValue, catValue, rates: [], members: [] }; + groups.set(key, group); + } + group.rates.push(sample.rate); + group.members.push(sample); + } + + // Naming an aggregated variable is not enough: if it drives most of the + // spread within a group, every interval below is reporting that variable + // rather than the benchmark's noise, and no number of --runs will shrink + // it. Quantify the share so the reader can tell those cases apart. + const contamination = new Map(); + for (const variable of aggregated) { + contamination.set(variable, varianceShare([...groups.values()], variable)); + } + + for (const variable of aggregated) { + const share = contamination.get(variable); + // Rounding 99.7% up to "100%" would claim the residual noise is zero. + const percent = share === 1 ? + '100' : + (share >= 0.995 ? '>99' : (share * 100).toFixed(0)); + const suffix = Number.isNaN(share) ? + '' : + ` (explains ${percent}% of within-group variance)`; + console.log(`aggregating variable: ${variable}${suffix}`); + } + + // Aggregation that dominates the spread is the single most common reason + // for uselessly wide intervals, and the usual reaction -- raising --runs -- + // cannot help, because the spread is a real effect of a variable that has + // been averaged over rather than sampling noise. + const dominant = aggregated.filter((v) => contamination.get(v) > 0.5); + if (dominant.length > 0) { + console.log(''); + const one = dominant.length === 1; + printWrapped( + `Note: ${dominant.join(', ')} ${one ? 'explains' : 'explain'} most of ` + + `the spread within each group, so the intervals below describe ` + + `${one ? 'that variable' : 'those variables'} rather than the ` + + `benchmark's own noise, and more --runs will not narrow them. Pin ` + + `${one ? 'it' : 'them'} with --set ${dominant[0]}=, or pass as ` + + `--category, for intervals that can be acted on.`, + ); + } + + if (aggregated.length > 0) { + console.log(''); + } + + const compare = (a, b) => { + if (typeof a === 'number' && typeof b === 'number') return a - b; + return String(a).localeCompare(String(b)); + }; + + const scale = histogramScale(samples.map((s) => s.rate)); + + const rows = [...groups.values()] + .sort((a, b) => compare(a.xValue, b.xValue) || + compare(a.catValue, b.catValue)) + .map((group) => { + const rates = group.rates; + const n = rates.length; + const mean = rates.reduce((a, b) => a + b, 0) / n; + + // Confidence interval of the mean, matching scatter.R: the sample + // standard error scaled by the t quantile at 97.5%. Computed from the + // raw samples rather than the histogram, which stores bucketed values. + // Undefined for a single sample, where there is no spread to estimate. + let ci = NaN; + if (n > 1) { + const variance = + rates.reduce((sum, r) => sum + (r - mean) ** 2, 0) / (n - 1); + ci = Math.sqrt(variance / n) * tQuantile(0.975, n - 1); + } + + // The histogram supplies the statistics that have no closed form here: + // an exact-binomial interval on the median, and the shape measures used + // to decide whether the mean is worth trusting. + const histogram = createHistogram({ figures: 5 }); + for (const rate of rates) { + histogram.record(Math.max(1, Math.round(rate * scale))); + } + + const medianCI = histogram.percentileCI(50); + const median = medianCI.value / scale; + const skewness = n > 1 ? histogram.skewness : NaN; + + // A summary is suspect when the two estimates of the centre disagree by + // more than the uncertainty claimed for one of them, or when the sample + // is badly asymmetric. Either way the mean is being moved by the tail + // rather than describing the bulk of the runs. + const skewed = n > 1 && + (Math.abs(skewness) > 1 || Math.abs(median - mean) > ci); + + return { + ...group, + n, + mean, + ci, + histogram, + median, + medianLower: medianCI.lower / scale, + medianUpper: medianCI.upper / scale, + skewness, + skewed, + }; + }); + + // Values are rendered through short labels so that long or non-printable + // configuration values cannot break the layout. + const legend = assignLabels(rows, 'xValue', 'xLabel'); + if (category !== undefined) { + legend.push(...assignLabels(rows, 'catValue', 'catLabel')); + } + + printTable(rows, xAxis, category); + + if (showChart) { + printChart(rows, xAxis, category); + } + + printComparisons(rows, xAxis, category); + printLegend(legend); + + const singleSample = rows.filter((r) => r.n < 2).length; + if (singleSample > 0) { + console.log(''); + printWrapped( + `Note: ${singleSample} group${singleSample === 1 ? ' has' : 's have'} ` + + `only one sample, so no confidence interval could be estimated. ` + + `Use --runs 2 or higher.`, + ); + } + + if (rows.some((r) => r.skewed)) { + console.log(''); + printWrapped( + `(!) marks groups where the median falls outside the mean's confidence ` + + `interval, or the sample is strongly skewed (|skewness| > 1). For those ` + + `rows the mean is being pulled by a few slow or fast runs, so the ` + + `median and its interval describe the typical run better. This is ` + + `usually GC or JIT tiering; more --runs will not necessarily make it ` + + `go away.`, + ); + } +} + +// HdrHistogram records positive integers with a fixed number of significant +// figures, so precision is relative and large rates need no scaling at all. +// Small rates do: without scaling, anything below 1 op/s rounds to the same +// bucket and the group collapses to a single value. Scale up until the +// smallest rate carries enough digits for rounding to be irrelevant. +function histogramScale(rates) { + let min = Infinity; + let max = 0; + for (const rate of rates) { + if (rate > 0 && rate < min) min = rate; + if (rate > max) max = rate; + } + if (!Number.isFinite(min) || max === 0) return 1; + + let scale = 1; + while (min * scale < 1e6 && max * scale < 1e15) { + scale *= 10; + } + return scale; +} + +// Share of the within-group variance attributable to one aggregated +// variable, pooled over groups. This is a one-way eta squared: the spread +// between that variable's levels divided by the total spread inside the +// group. Computed per variable and independently, so when two aggregated +// variables are correlated their shares overlap and do not sum to one. +function varianceShare(groups, variable) { + let between = 0; + let total = 0; + + for (const group of groups) { + const members = group.members; + if (members.length < 2) continue; + + const groupMean = + members.reduce((sum, s) => sum + s.rate, 0) / members.length; + + // Partition the group by the level of this variable. + const levels = new Map(); + for (const sample of members) { + const key = String(sample.conf[variable]); + let level = levels.get(key); + if (level === undefined) { + level = { sum: 0, count: 0 }; + levels.set(key, level); + } + level.sum += sample.rate; + level.count++; + } + + // A variable with a single level inside this group explains nothing + // here, but the group still contributes to the total spread. + for (const level of levels.values()) { + const levelMean = level.sum / level.count; + between += level.count * (levelMean - groupMean) ** 2; + } + for (const sample of members) { + total += (sample.rate - groupMean) ** 2; + } + } + + if (total === 0) return NaN; + return Math.min(1, between / total); +} + +// The smallest p-value the Mann-Whitney implementation can return for these +// sample sizes, found by giving it perfectly separated groups. Below a +// certain size that floor sits above 0.05, meaning no effect of any +// magnitude can be reported as significant; a non-significant result then +// says nothing at all. Derived from the implementation rather than the exact +// combinatorial bound because it uses a normal approximation. +const mannWhitneyFloors = new Map(); +function mannWhitneyFloor(nA, nB) { + const key = `${nA},${nB}`; + let floor = mannWhitneyFloors.get(key); + if (floor === undefined) { + // Values must stay distinct after the histogram's 5-significant-figure + // rounding, or they collapse into ties and the tie correction reports a + // floor lower than the test can actually reach. The 10000 range is exact + // at that precision, and the two runs cannot overlap. + const low = createHistogram({ figures: 5 }); + const high = createHistogram({ figures: 5 }); + for (let i = 0; i < nA; i++) low.record(10000 + i); + for (let i = 0; i < nB; i++) high.record(10000 + nA + i); + floor = high.mannWhitneyTest(low).pValue; + mannWhitneyFloors.set(key, floor); + } + return floor; +} + +// Cliff's delta magnitude thresholds (Romano et al.), the conventional +// reading of the statistic. +function effectSizeLabel(delta) { + const d = Math.abs(delta); + if (d < 0.147) return 'negligible'; + if (d < 0.33) return 'small'; + if (d < 0.474) return 'medium'; + return 'large'; +} + +// The question scatter.js exists to answer is whether a parameter changes the +// rate, which the per-group table only hints at through overlapping intervals. +// Compare consecutive x-axis values directly, holding the category fixed. +// Mann-Whitney rather than a t-test because a parameter sweep routinely +// changes the shape and spread of the distribution, not just its centre. +function printComparisons(rows, xAxis, category) { + const usable = rows.filter((row) => row.n > 1); + if (usable.length < 2) return; + + // Partition by category so each series is a sweep over the x-axis alone. + const series = new Map(); + for (const row of usable) { + const key = String(row.catValue); + if (!series.has(key)) series.set(key, []); + series.get(key).push(row); + } + + const lines = []; + let floor = 0; + for (const group of series.values()) { + if (group.length < 2) continue; + + const entries = []; + for (let i = 1; i < group.length; i++) { + const previous = group[i - 1]; + const current = group[i]; + const { pValue } = current.histogram.mannWhitneyTest(previous.histogram); + const delta = current.histogram.cliffsD(previous.histogram); + const change = ((current.mean - previous.mean) / previous.mean) * 100; + + floor = Math.max(floor, mannWhitneyFloor(previous.n, current.n)); + + // How the rate scales with the parameter over this step, which is the + // complexity question these sweeps are usually run to answer. Reported + // per step rather than as one fit across the whole sweep: a single + // exponent spanning a curve that changes regime describes neither. + let ratio = ''; + let exponent = ''; + if (typeof previous.xValue === 'number' && + typeof current.xValue === 'number' && + previous.xValue > 0 && current.xValue > 0 && + previous.xValue !== current.xValue && + previous.mean > 0 && current.mean > 0) { + const xRatio = current.xValue / previous.xValue; + const value = Math.log(current.mean / previous.mean) / + Math.log(xRatio); + ratio = `${xRatio.toFixed(1)}x`; + exponent = `${value >= 0 ? '+' : ''}${value.toFixed(2)}`; + } + + entries.push({ + transition: `${previous.xLabel} -> ${current.xLabel}`, + change: `${change >= 0 ? '+' : ''}${change.toFixed(2)}%`, + ratio, + exponent, + pValue: pValue < 1e-4 ? pValue.toExponential(1) : pValue.toFixed(4), + delta: `${delta >= 0 ? '+' : ''}${delta.toFixed(3)}`, + label: effectSizeLabel(delta), + }); + } + + if (entries.length > 0) { + lines.push({ + heading: category === undefined ? + null : + `${category}=${group[0].catLabel}`, + entries, + }); + } + } + + if (lines.length === 0) return; + + const all = lines.flatMap((l) => l.entries); + const widths = { + transition: Math.max(...all.map((e) => displayWidth(e.transition))), + change: Math.max(...all.map((e) => displayWidth(e.change))), + ratio: Math.max(...all.map((e) => displayWidth(e.ratio))), + exponent: Math.max(...all.map((e) => displayWidth(e.exponent))), + pValue: Math.max(...all.map((e) => displayWidth(e.pValue))), + delta: Math.max(...all.map((e) => displayWidth(e.delta))), + }; + const rpad = (s, n) => padTo(s, n, true); + const pad = (s, n) => padTo(s, n, false); + + console.log(''); + console.log(`Change between consecutive ${xAxis} values ` + + `(Mann-Whitney U, Cliff's delta):`); + + for (const { heading, entries } of lines) { + console.log(''); + if (heading !== null) { + console.log(` ${heading}`); + } + for (const entry of entries) { + console.log( + ` ${pad(entry.transition, widths.transition)}` + + ` ${rpad(entry.change, widths.change)}` + + (widths.exponent > 0 ? + ` ${rpad(entry.ratio, widths.ratio)}` + + ` exponent=${rpad(entry.exponent, widths.exponent)}` : + '') + + ` p=${rpad(entry.pValue, widths.pValue)}` + + ` delta=${rpad(entry.delta, widths.delta)} (${entry.label})`, + ); + } + } + + // A p-value has to be read against what the test could have produced. Below + // a certain sample size the floor sits above the threshold, and "not + // significant" then carries no information whatsoever. + if (floor >= 0.05) { + console.log(''); + printWrapped( + `Warning: at this sample size the smallest p-value this test can ` + + `produce is ${floor.toFixed(4)}, so no comparison above can reach ` + + `significance however large the real effect is. Treat every p-value ` + + `here as uninformative and raise --runs.`, + ); + } else if (floor >= 0.005) { + console.log(''); + printWrapped( + `Note: at this sample size the smallest p-value this test can produce ` + + `is ${floor.toFixed(4)}. A non-significant result above is therefore ` + + `weak evidence of no change rather than evidence of none; raise ` + + `--runs to strengthen it.`, + ); + } +} + +function formatRate(rate) { + return rate.toLocaleString('en-US', { + minimumFractionDigits: 1, + maximumFractionDigits: 1, + }); +} + +// Widest a single variable value may be before it is abbreviated. Benchmark +// values are usually short (`16`, `'ascii'`), but some are long enough to +// destroy the layout on their own, so there has to be a ceiling. +const kMaxValueWidth = 24; + +// Widest a composed chart label may be, since it can hold two values. +const kMaxChartLabelWidth = 44; + +// Widths are measured in code points, not UTF-16 code units: several +// benchmarks use emoji and CJK in their configurations, and counting those +// as two would misalign every column to their right. +function displayWidth(text) { + return [...text].length; +} + +function padTo(text, width, alignRight) { + const padding = ' '.repeat(Math.max(0, width - displayWidth(text))); + return alignRight ? padding + text : text + padding; +} + +// Drop out the middle rather than the tail: benchmark values that share a +// long prefix are common, and a head-only truncation would render them +// identical. Slicing by code point rather than by index so that an astral +// character cannot be cut in half into a lone surrogate. +function truncateMiddle(text, maxWidth) { + const chars = [...text]; + if (chars.length <= maxWidth) return text; + const keep = maxWidth - 3; + const head = Math.ceil(keep / 2); + const tail = Math.floor(keep / 2); + return `${chars.slice(0, head).join('')}...` + + `${chars.slice(chars.length - tail).join('')}`; +} + +// Configuration values are not guaranteed to be printable: strings may carry +// newlines or tabs (see benchmark/mime/mimetype-instantiation.js), which +// would otherwise split a table row across several lines. inspect() escapes +// them and quotes strings, matching how compare.js renders configurations. +function displayValue(value) { + const text = typeof value === 'string' ? inspect(value) : String(value); + return { text: truncateMiddle(text, kMaxValueWidth), full: text }; +} + +// Assigns a short, unique, printable label to every distinct value of one +// grouping variable, and collects the abbreviated ones for a legend so the +// full value is still recoverable from the output. +function assignLabels(rows, valueField, labelField) { + const assigned = new Map(); + const used = new Map(); + const legend = []; + + for (const row of rows) { + const key = String(row[valueField]); + let label = assigned.get(key); + + if (label === undefined) { + const { text, full } = displayValue(row[valueField]); + // Two different values can abbreviate to the same text; keep them + // distinguishable so the table cannot show one group twice. + const collisions = used.get(text) ?? 0; + used.set(text, collisions + 1); + label = collisions === 0 ? text : `${text}~${collisions + 1}`; + assigned.set(key, label); + if (text !== full) legend.push({ label, full }); + } + + row[labelField] = label; + } + + return legend; +} + +// Notes interpolate variable names and sample sizes, so their length is not +// known when they are written. Wrapping here rather than hand-placing +// newlines, which overflow as soon as an interpolated value is longer than +// the author guessed. +function printWrapped(text, width = 76) { + let line = ''; + for (const word of text.split(/\s+/)) { + if (line === '') { + line = word; + } else if (displayWidth(line) + 1 + displayWidth(word) <= width) { + line += ` ${word}`; + } else { + console.log(line); + line = word; + } + } + if (line !== '') console.log(line); +} + +function printLegend(legend) { + if (legend.length === 0) return; + console.log(''); + console.log('Abbreviated values:'); + for (const { label, full } of legend) { + console.log(` ${label}`); + console.log(` = ${full}`); + } +} + +function printTable(rows, xAxis, category) { + const header = [xAxis]; + if (category !== undefined) header.push(category); + header.push('samples', 'rate', 'confidence.interval', + 'median', 'median.interval', ''); + + // Numbers line up on the right, text reads better on the left. The grouping + // columns can be either, so they follow the type of the underlying value. + const alignRight = [typeof rows[0].xValue === 'number']; + if (category !== undefined) { + alignRight.push(typeof rows[0].catValue === 'number'); + } + alignRight.push(true, true, true, true, true, false); + + const body = rows.map((row) => { + const cells = [row.xLabel]; + if (category !== undefined) cells.push(row.catLabel); + + // The median interval is asymmetric, so it is shown as a relative range + // rather than a single half-width. + const medianInterval = row.n > 1 ? + `[${(((row.medianLower - row.median) / row.median) * 100).toFixed(2)}%, ` + + `+${(((row.medianUpper - row.median) / row.median) * 100).toFixed(2)}%]` : + 'NA'; + + cells.push( + String(row.n), + formatRate(row.mean), + // Absolute for parity with scatter.R, relative because that is what + // tells you whether the rate beside it is worth reading. Kept in one + // column so every column has a header of its own. + Number.isNaN(row.ci) ? + 'NA' : + `${formatRate(row.ci)} (±${((row.ci / row.mean) * 100).toFixed(2)}%)`, + formatRate(row.median), + medianInterval, + row.skewed ? '(!)' : '', + ); + return cells; + }); + + const widths = header.map((_, col) => Math.max( + displayWidth(header[col]), + ...body.map((cells) => displayWidth(cells[col])), + )); + + const line = (cells) => cells + .map((cell, col) => padTo(cell, widths[col], alignRight[col])) + .join(' ') + .trimEnd(); + + console.log(line(header)); + for (const cells of body) { + console.log(line(cells)); + } +} + +function printChart(rows, xAxis, category) { + if (rows.length === 0) return; + + const barWidth = 40; + // Bars are drawn from zero so that the visual length is proportional to the + // rate. A truncated axis would exaggerate small differences. + let maxRate = 0; + for (const row of rows) { + const extent = row.mean + (Number.isNaN(row.ci) ? 0 : row.ci); + if (extent > maxRate) maxRate = extent; + } + if (maxRate === 0) return; + + const labels = rows.map((row) => { + const parts = [`${xAxis}=${row.xLabel}`]; + if (category !== undefined) parts.push(`${category}=${row.catLabel}`); + return truncateMiddle(parts.join(' '), kMaxChartLabelWidth); + }); + const labelWidth = Math.max(...labels.map(displayWidth)); + const rateWidth = Math.max( + ...rows.map((r) => displayWidth(formatRate(r.mean)))); + + const pad = (s, n) => padTo(s, n, false); + const rpad = (s, n) => padTo(s, n, true); + + const axisRight = formatRate(maxRate); + const indent = ' '.repeat(labelWidth + 2); + + console.log(''); + console.log('Rate in operations/second; longer is faster. \u2502 marks the ' + + 'mean and the'); + console.log('shaded band (\u2591) is its 95% confidence interval, so bars ' + + 'whose bands'); + console.log('overlap are not clearly different.'); + console.log(''); + console.log( + `${indent}0` + + `${' '.repeat(Math.max(1, barWidth - 1 - displayWidth(axisRight)))}` + + `${axisRight}`, + ); + console.log(`${indent}+${'-'.repeat(Math.max(0, barWidth - 2))}+`); + + let previousX; + for (let i = 0; i < rows.length; i++) { + const row = rows[i]; + + // A blank line between x-axis values, so the categories being compared at + // each point stay visually grouped. + if (previousX !== undefined && row.xValue !== previousX) { + console.log(''); + } + previousX = row.xValue; + + const barEnd = (row.mean / maxRate) * barWidth; + const ci = Number.isNaN(row.ci) ? 0 : row.ci; + const ciLeft = ((row.mean - ci) / maxRate) * barWidth; + const ciRight = ((row.mean + ci) / maxRate) * barWidth; + + // Without an explicit marker the mean is invisible, because the shaded + // interval is drawn over the solid bar and straddles it. + const meanCell = Math.min(barWidth - 1, Math.floor(barEnd)); + + let bar = ''; + for (let x = 0; x < barWidth; x++) { + const pos = x + 0.5; // Center of this character cell. + if (x === meanCell) { + bar += '\u2502'; // The mean itself. + } else if (pos >= ciLeft && pos <= ciRight) { + bar += '\u2591'; // Light shade marks the confidence interval. + } else if (pos <= barEnd) { + bar += '\u2588'; + } else { + bar += ' '; + } + } + + console.log( + `${pad(labels[i], labelWidth)} ${bar} ` + + `${rpad(formatRate(row.mean), rateWidth)}`, + ); + } +} diff --git a/benchmark/vfs/module-graph.js b/benchmark/vfs/module-graph.js new file mode 100644 index 000000000000..aee5e8616198 --- /dev/null +++ b/benchmark/vfs/module-graph.js @@ -0,0 +1,62 @@ +'use strict'; +const path = require('path'); +const { pathToFileURL } = require('url'); +const common = require('../common.js'); + +const bench = common.createBenchmark(main, { + type: ['cjs', 'esm'], + files: [1e2, 1e3], + n: [10], +}, { flags: ['--experimental-vfs', '--no-warnings'] }); + +// Builds a module graph of `files` packages, each with its own package.json, +// an index requiring a package-local file and a shared root module, and an +// entry point that pulls in every package. +function buildGraph(layer, files, type) { + const entryRequires = []; + if (type === 'esm') { + layer.writeFileSync('/package.json', '{"type":"module"}'); + } + layer.writeFileSync('/shared.js', + type === 'cjs' ? 'module.exports = 0;' : 'export default 0;'); + for (let i = 0; i < files; i++) { + layer.mkdirSync(`/${i}`, { recursive: true }); + if (type === 'cjs') { + layer.writeFileSync(`/${i}/package.json`, '{"main":"index.js"}'); + layer.writeFileSync(`/${i}/lib.js`, 'module.exports = 1;'); + layer.writeFileSync( + `/${i}/index.js`, + 'require("./lib.js"); require("../shared.js"); module.exports = __filename;'); + entryRequires.push(`require('./${i}/');`); + } else { + layer.writeFileSync(`/${i}/package.json`, '{"type":"module"}'); + layer.writeFileSync(`/${i}/lib.js`, 'export default 1;'); + layer.writeFileSync( + `/${i}/index.js`, + 'import "./lib.js"; import "../shared.js"; export default import.meta.url;'); + entryRequires.push(`import './${i}/index.js';`); + } + } + layer.writeFileSync('/entry.js', entryRequires.join('\n')); +} + +async function main({ n, type, files }) { + const vfs = require('node:vfs'); + const layer = vfs.create(); + buildGraph(layer, files, type); + + bench.start(); + for (let i = 0; i < n; i++) { + const mountPoint = layer.mount(); + const entry = path.join(mountPoint, 'entry.js'); + if (type === 'cjs') { + require(entry); + } else { + await import(pathToFileURL(entry).href); + } + // Unmounting purges the module caches for the mount prefix, so every + // iteration is a cold load of the full graph. + layer.unmount(); + } + bench.end(n * files); +} diff --git a/benchmark/webstreams/adapters.js b/benchmark/webstreams/adapters.js new file mode 100644 index 000000000000..ae97e4928f88 --- /dev/null +++ b/benchmark/webstreams/adapters.js @@ -0,0 +1,106 @@ +'use strict'; +const common = require('../common.js'); +const { + Readable, + Writable, +} = require('node:stream'); +const { + ReadableStream, + WritableStream, +} = require('node:stream/web'); + +const bench = common.createBenchmark(main, { + n: [1e5], + kind: [ + 'readable-to-web', + 'readable-from-web', + 'writable-to-web', + 'writable-from-web', + ], +}); + +async function readableToWeb(n) { + const chunk = Buffer.alloc(1024); + let i = 0; + const streamReadable = new Readable({ + read() { + if (i++ < n) + this.push(chunk); + else + this.push(null); + }, + }); + const reader = Readable.toWeb(streamReadable).getReader(); + bench.start(); + while (!(await reader.read()).done); + bench.end(n); +} + +function readableFromWeb(n) { + const chunk = Buffer.alloc(1024); + let i = 0; + const readableStream = new ReadableStream({ + pull(controller) { + if (i++ < n) + controller.enqueue(chunk); + else + controller.close(); + }, + }); + const streamReadable = Readable.fromWeb(readableStream); + bench.start(); + streamReadable.on('data', () => {}); + streamReadable.on('end', () => bench.end(n)); +} + +async function writableToWeb(n) { + const chunk = Buffer.alloc(1024); + const streamWritable = new Writable({ + write(chunk, encoding, callback) { + callback(); + }, + }); + const writer = Writable.toWeb(streamWritable).getWriter(); + bench.start(); + for (let i = 0; i < n; i++) + await writer.write(chunk); + await writer.close(); + bench.end(n); +} + +function writableFromWeb(n) { + const chunk = Buffer.alloc(1024); + const writableStream = new WritableStream({ + write() {}, + }); + const streamWritable = Writable.fromWeb(writableStream); + bench.start(); + let i = 0; + function writeLoop() { + while (i++ < n) { + if (!streamWritable.write(chunk)) { + streamWritable.once('drain', writeLoop); + return; + } + } + streamWritable.end(() => bench.end(n)); + } + writeLoop(); +} + +function main({ n, kind }) { + switch (kind) { + case 'readable-to-web': + readableToWeb(n); + break; + case 'readable-from-web': + readableFromWeb(n); + break; + case 'writable-to-web': + writableToWeb(n); + break; + case 'writable-from-web': + writableFromWeb(n); + break; + } +} diff --git a/common.gypi b/common.gypi index a83523286a91..e6a17d3505a5 100644 --- a/common.gypi +++ b/common.gypi @@ -17,6 +17,7 @@ 'emulator%': [], 'node_shared%': 'false', + 'node_enable_v8debughelper%': 'false', 'node_enable_experimentals%': 'false', 'force_dynamic_crt%': 0, 'node_use_v8_platform%': 'true', @@ -42,7 +43,7 @@ # Reset this number to 0 on major V8 upgrades. # Increment by one for each non-official patch applied to deps/v8. - 'v8_embedder_string': '-node.28', + 'v8_embedder_string': '-node.32', ##### V8 defaults for Node.js ##### @@ -611,6 +612,10 @@ 'cflags': [ '-m64', '-march=z14' ], 'ldflags': [ '-m64', '-march=z14' ], }], + [ 'host_arch=="riscv64" and OS=="linux"', { + 'cflags': [ '-march=rv64gc' ], + 'ldflags': [ '-march=rv64gc' ], + }], ], }], ['_toolset=="target"', { @@ -636,6 +641,10 @@ 'cflags': [ '-m64', '-march=z14' ], 'ldflags': [ '-m64', '-march=z14' ], }], + [ 'target_arch=="riscv64" and OS=="linux"', { + 'cflags': [ '-march=rv64gc' ], + 'ldflags': [ '-march=rv64gc' ], + }], ], }], ], @@ -646,7 +655,9 @@ 'cflags!': [ '-pthread' ], 'ldflags!': [ '-pthread' ], }], - [ 'node_shared=="true"', { + # The V8 static libraries get linked into libv8_debug_helper, so they + # have to be position independent too. + [ 'node_shared=="true" or node_enable_v8debughelper=="true"', { 'cflags': [ '-fPIC' ], 'ldflags': [ '-fPIC' ], }], diff --git a/configure.py b/configure.py index b663ba85f58e..84a688917efe 100755 --- a/configure.py +++ b/configure.py @@ -282,6 +282,28 @@ help='Use the specified path to system CA (PEM format) in addition to ' 'the OpenSSL supplied CA store or compiled-in Mozilla CA copy.') +shared_optgroup.add_argument('--shared-abseil', + action='store_true', + dest='shared_abseil', + default=None, + help='link to a shared Abseil DLL instead of static linking') + +shared_optgroup.add_argument('--shared-abseil-includes', + action='store', + dest='shared_abseil_includes', + help='directory containing Abseil header files') + +shared_optgroup.add_argument('--shared-abseil-libname', + action='store', + dest='shared_abseil_libname', + default=None, + help='alternative lib name to link to [default: %(default)s]') + +shared_optgroup.add_argument('--shared-abseil-libpath', + action='store', + dest='shared_abseil_libpath', + help='a directory to search for the shared Abseil DLL') + shared_optgroup.add_argument('--shared-gtest', action='store_true', dest='shared_gtest', @@ -326,11 +348,27 @@ dest='shared_hdr_histogram_libpath', help='a directory to search for the shared HdrHistogram DLL') -parser.add_argument('--experimental-http-parser', +shared_optgroup.add_argument('--shared-highway', action='store_true', - dest='experimental_http_parser', + dest='shared_highway', default=None, - help='(no-op)') + help='link to a shared Highway (hwy) DLL instead of static linking') + +shared_optgroup.add_argument('--shared-highway-includes', + action='store', + dest='shared_highway_includes', + help='directory containing Highway header files') + +shared_optgroup.add_argument('--shared-highway-libname', + action='store', + dest='shared_highway_libname', + default='hwy', + help='alternative lib name to link to [default: %(default)s]') + +shared_optgroup.add_argument('--shared-highway-libpath', + action='store', + dest='shared_highway_libpath', + help='a directory to search for the shared Highway DLL') shared_optgroup.add_argument('--shared-http-parser', action='store_true', @@ -508,6 +546,29 @@ dest='shared_openssl_libpath', help='a directory to search for the shared OpenSSL DLLs') +shared_optgroup.add_argument('--shared-perfetto', + action='store_true', + dest='shared_perfetto', + default=None, + help='link to a shared perfetto SDK instead of the one in deps/perfetto ' + '(requires --with-perfetto)') + +shared_optgroup.add_argument('--shared-perfetto-includes', + action='store', + dest='shared_perfetto_includes', + help='directory containing perfetto header files') + +shared_optgroup.add_argument('--shared-perfetto-libname', + action='store', + dest='shared_perfetto_libname', + default='perfetto', + help='alternative lib name to link to [default: %(default)s]') + +shared_optgroup.add_argument('--shared-perfetto-libpath', + action='store', + dest='shared_perfetto_libpath', + help='a directory to search for the shared perfetto DLL') + shared_optgroup.add_argument('--shared-uvwasi', action='store_true', dest='shared_uvwasi', @@ -812,6 +873,13 @@ default=None, help=argparse.SUPPRESS) # Undocumented. +parser.add_argument('--enable-v8debughelper', + action='store_true', + dest='enable_v8debughelper', + default=None, + help='Build V8\'s debug helper as a shared library, loadable by a debugger ' + 'extension.') + parser.add_argument('--enable-trace-maps', action='store_true', dest='trace_maps', @@ -834,7 +902,7 @@ action='store_true', dest='pointer_compression_shared_cage', default=None, - help='[Experimental] Use V8 pointer compression with shared cage (requires --experimental-enable-pointer-compression)') + help='[Experimental] Use V8 pointer compression with a shared cage and enable the V8 sandbox (requires --experimental-enable-pointer-compression)') parser.add_argument('--v8-options', action='store', @@ -884,13 +952,13 @@ action='store_true', dest='node_use_large_pages', default=None, - help='This option has no effect. --use-largepages is now a runtime option.') + help='This option is no longer supported and a no-op.') parser.add_argument('--use-largepages-script-lld', action='store_true', dest='node_use_large_pages_script_lld', default=None, - help='This option has no effect. --use-largepages is now a runtime option.') + help='This option is no longer supported and a no-op.') parser.add_argument('--use-section-ordering-file', action='store', @@ -1022,33 +1090,12 @@ default=None, help='enable Control Flow Guard (CFG)') -# Dummy option for backwards compatibility -parser.add_argument('--without-report', - action='store_true', - dest='unused_without_report', - default=None, - help=argparse.SUPPRESS) - -parser.add_argument('--with-snapshot', - action='store_true', - dest='unused_with_snapshot', - default=None, - help=argparse.SUPPRESS) - -parser.add_argument('--without-snapshot', - action='store_true', - dest='unused_without_snapshot', - default=None, - help=argparse.SUPPRESS) - parser.add_argument('--without-siphash', action='store_true', dest='without_siphash', default=None, help=argparse.SUPPRESS) -# End dummy list. - parser.add_argument('--without-ssl', action='store_true', dest='without_ssl', @@ -1079,6 +1126,12 @@ default=None, help='build with experimental QUIC support') +parser.add_argument('--experimental-dtls', + action='store_true', + dest='experimental_dtls', + default=None, + help='build with experimental DTLS support') + parser.add_argument('--ninja', action='store_true', dest='use_ninja', @@ -1900,8 +1953,6 @@ def configure_node(o): else target_arch != host_arch) if cross_compiling: os.environ['GYP_CROSSCOMPILE'] = "1" - if options.unused_without_snapshot: - warn('building --without-snapshot is no longer possible') o['variables']['want_separate_host_toolset'] = int(cross_compiling) @@ -2041,10 +2092,8 @@ def configure_node(o): if options.node_use_large_pages or options.node_use_large_pages_script_lld: warn('''The `--use-largepages` and `--use-largepages-script-lld` options - have no effect during build time. Support for mapping to large pages is - now a runtime option of Node.js. Run `node --use-largepages` or add - `--use-largepages` to the `NODE_OPTIONS` environment variable once - Node.js is built to enable mapping to large pages.''') + have no effect. Mapping the Node.js static code to large pages is + no longer supported.''') if options.no_ifaddrs: o['defines'] += ['SUNOS_NO_IFADDRS'] @@ -2195,16 +2244,10 @@ def configure_v8(o, configs): flavor not in ('aix', 'os400', 'zos') and o['variables']['target_arch'] in maglev_enabled_architectures) o['variables']['v8_enable_pointer_compression'] = 1 if options.enable_pointer_compression else 0 - # Using the sandbox requires always allocating array buffer backing stores in the sandbox. - # We currently have many backing stores tied to pointers from C++ land that are not - # even necessarily dynamic (e.g. in static storage) for fast communication between JS and C++. - # Until we manage to get rid of all those, v8_enable_sandbox cannot be used. - # Note that enabling pointer compression without enabling sandbox is unsupported by V8, - # so this can be broken at any time. - o['variables']['v8_enable_sandbox'] = 0 - # We set v8_enable_pointer_compression_shared_cage to 0 always, even when - # pointer compression is enabled so that we don't accidentally enable shared - # cage mode when pointer compression is on. + # Like V8's own default, the sandbox goes with the shared pointer compression + # cage. Multi-cage builds give every IsolateGroup its own sandbox, which the + # array buffer allocator does not know about yet. + o['variables']['v8_enable_sandbox'] = 1 if options.pointer_compression_shared_cage else 0 o['variables']['v8_enable_pointer_compression_shared_cage'] = 1 if options.pointer_compression_shared_cage else 0 o['variables']['v8_enable_external_code_space'] = 1 if options.enable_pointer_compression else 0 o['variables']['v8_enable_31bit_smis_on_64bit_arch'] = 1 if options.enable_pointer_compression else 0 @@ -2229,6 +2272,7 @@ def configure_v8(o, configs): o['variables']['force_dynamic_crt'] = 1 if options.shared else 0 o['variables']['node_enable_d8'] = b(options.enable_d8) o['variables']['node_enable_v8windbg'] = b(options.enable_v8windbg) + o['variables']['node_enable_v8debughelper'] = b(options.enable_v8debughelper) if options.enable_d8: o['variables']['test_isolation_mode'] = 'noop' # Needed by d8.gyp. if options.without_bundled_v8: @@ -2236,6 +2280,8 @@ def configure_v8(o, configs): raise Exception('--enable-d8 is incompatible with --without-bundled-v8.') if options.enable_v8windbg: raise Exception('--enable-v8windbg is incompatible with --without-bundled-v8.') + if options.enable_v8debughelper: + raise Exception('--enable-v8debughelper is incompatible with --without-bundled-v8.') (pkg_libs, pkg_cflags, pkg_libpath, _) = pkg_config("v8") if pkg_libs and pkg_libpath: output['libraries'] += [pkg_libpath] + pkg_libs.split() @@ -2343,6 +2389,15 @@ def configure_lief(o): configure_library('lief', o, pkgname='LIEF') +def configure_perfetto(o): + if not options.with_perfetto: + if options.shared_perfetto: + error('--shared-perfetto requires --with-perfetto') + o['variables']['node_shared_perfetto'] = b(False) + return + + configure_library('perfetto', o) + def configure_sqlite(o): o['variables']['node_use_sqlite'] = b(not options.without_sqlite) if options.without_sqlite: @@ -2398,6 +2453,10 @@ def configure_quic(o): o['variables']['node_use_quic'] = b(options.experimental_quic and not options.without_ssl) +def configure_dtls(o): + o['variables']['node_use_dtls'] = b(options.experimental_dtls and + not options.without_ssl) + def configure_static(o): if options.fully_static or options.partly_static: if flavor == 'mac': @@ -2835,6 +2894,71 @@ def make_bin_override(): configure_library('zlib', output) configure_library('http_parser', output, pkgname='libllhttp') configure_library('libuv', output) +configure_library('abseil', output, pkgname=[ + 'absl_absl_check', + 'absl_absl_log', + 'absl_absl_vlog_is_on', + 'absl_algorithm_container', + 'absl_algorithm', + 'absl_any_invocable', + 'absl_base', + 'absl_bind_front', + 'absl_bits', + 'absl_btree', + 'absl_charset', + 'absl_cleanup', + 'absl_config', + 'absl_cord', + 'absl_core_headers', + 'absl_die_if_null', + 'absl_dynamic_annotations', + 'absl_failure_signal_handler', + 'absl_fast_type_id', + 'absl_fixed_array', + 'absl_flat_hash_map', + 'absl_flat_hash_set', + 'absl_function_ref', + 'absl_has_ostream_operator', + 'absl_hash_container_defaults', + 'absl_hash', + 'absl_inlined_vector', + 'absl_int128', + 'absl_layout', + 'absl_leak_check', + 'absl_linked_hash_map', + 'absl_linked_hash_set', + 'absl_log_entry', + 'absl_log_globals', + 'absl_log_initialize', + 'absl_log_severity', + 'absl_log_sink_registry', + 'absl_log_sink', + 'absl_memory', + 'absl_no_destructor', + 'absl_node_hash_map', + 'absl_node_hash_set', + 'absl_nullability', + 'absl_optional', + 'absl_overload', + 'absl_prefetch', + 'absl_random_bit_gen_ref', + 'absl_random_distributions', + 'absl_random_random', + 'absl_raw_logging_internal', + 'absl_span', + 'absl_stacktrace', + 'absl_status', + 'absl_statusor', + 'absl_str_format', + 'absl_string_view', + 'absl_strings', + 'absl_symbolize', + 'absl_synchronization', + 'absl_time', + 'absl_type_traits', + 'absl_utility', + 'absl_variant', +]) configure_library('ada', output) configure_library('simdjson', output) configure_library('simdutf', output) @@ -2842,12 +2966,14 @@ def make_bin_override(): configure_library('cares', output, pkgname='libcares') configure_library('gtest', output) configure_library('hdr_histogram', output) +configure_library('highway', output, pkgname='libhwy') configure_library('merve', output) configure_library('nbytes', output) configure_library('nghttp2', output, pkgname='libnghttp2') configure_library('nghttp3', output, pkgname='libnghttp3') configure_library('ngtcp2', output, pkgname='libngtcp2') configure_lief(output); +configure_perfetto(output); configure_sqlite(output); configure_ffi(output); configure_library('temporal_capi', output) @@ -2856,6 +2982,7 @@ def make_bin_override(): configure_v8(output, configurations) configure_openssl(output) configure_quic(output) +configure_dtls(output) configure_intl(output) configure_static(output) configure_inspector(output) diff --git a/deps/brotli/unofficial.gni b/deps/brotli/unofficial.gni index 91001fa43ea4..0c6a7bd8c450 100644 --- a/deps/brotli/unofficial.gni +++ b/deps/brotli/unofficial.gni @@ -4,36 +4,49 @@ # The actual configurations are put inside a template in unofficial.gni to # prevent accidental edits from contributors. -template("brotli_gn_build") { - config("brotli_config") { - include_dirs = [ "c/include" ] - } +import("../../node.gni") - gypi_values = exec_script("../../tools/gypi_to_gn.py", - [ rebase_path("brotli.gyp") ], - "scope", - [ "brotli.gyp" ]) - - source_set(target_name) { - forward_variables_from(invoker, "*") - public_configs = [ ":brotli_config" ] - sources = gypi_values.brotli_sources - if (is_linux) { - defines = [ "OS_LINUX" ] - } else if (is_mac) { - defines = [ "OS_MACOSX" ] - } else if (target_os == "freebsd") { - defines = [ "OS_FREEBSD" ] +template("brotli_gn_build") { + if (node_shared_brotli) { + import("//build/config/linux/pkg_config.gni") + pkg_config("brotli_config") { + packages = [ "libbrotlidec", "libbrotlienc" ] } - if (is_linux) { - libs = [ "m" ] + group(target_name) { + forward_variables_from(invoker, "*") + public_configs = [ ":brotli_config" ] } - if (is_clang || !is_win) { - cflags_c = [ - "-Wno-implicit-fallthrough", - "-Wno-unreachable-code", - "-Wno-unreachable-code-return", - ] + } else { + config("brotli_config") { + include_dirs = [ "c/include" ] + } + + gypi_values = exec_script("../../tools/gypi_to_gn.py", + [ rebase_path("brotli.gyp") ], + "scope", + [ "brotli.gyp" ]) + + source_set(target_name) { + forward_variables_from(invoker, "*") + public_configs = [ ":brotli_config" ] + sources = gypi_values.brotli_sources + if (is_linux) { + defines = [ "OS_LINUX" ] + } else if (is_mac) { + defines = [ "OS_MACOSX" ] + } else if (target_os == "freebsd") { + defines = [ "OS_FREEBSD" ] + } + if (is_linux) { + libs = [ "m" ] + } + if (is_clang || !is_win) { + cflags_c = [ + "-Wno-implicit-fallthrough", + "-Wno-unreachable-code", + "-Wno-unreachable-code-return", + ] + } } } } diff --git a/deps/cares/unofficial.gni b/deps/cares/unofficial.gni index e02d7f425194..364df1f312e2 100644 --- a/deps/cares/unofficial.gni +++ b/deps/cares/unofficial.gni @@ -4,78 +4,91 @@ # The actual configurations are put inside a template in unofficial.gni to # prevent accidental edits from contributors. -template("cares_gn_build") { - config("cares_config") { - include_dirs = [ "include" ] - if (!is_component_build) { - defines = [ "CARES_STATICLIB" ] - } - } - - gypi_values = exec_script("../../tools/gypi_to_gn.py", - [ rebase_path("cares.gyp") ], - "scope", - [ "cares.gyp" ]) +import("../../node.gni") - component(target_name) { - forward_variables_from(invoker, "*") - public_configs = [ ":cares_config" ] - if (is_component_build) { - defines = [ "CARES_BUILDING_LIBRARY" ] - } else { - defines = [] +template("cares_gn_build") { + if (node_shared_cares) { + import("//build/config/linux/pkg_config.gni") + pkg_config("cares_config") { + packages = [ "libcares" ] } - if (is_win) { - defines += [ "CARES_PULL_WS2TCPIP_H=1" ] + group(target_name) { + forward_variables_from(invoker, "*") + public_configs = [ ":cares_config" ] } - if (is_posix) { - defines += [ - "_DARWIN_USE_64_BIT_INODE=1", - "_LARGEFILE_SOURCE", - "_FILE_OFFSET_BITS=64", - "_GNU_SOURCE", - "HAVE_CONFIG_H", - ] + } else { + config("cares_config") { + include_dirs = [ "include" ] + if (!is_component_build) { + defines = [ "CARES_STATICLIB" ] + } } - include_dirs = [ - "src/lib", - "src/lib/include", - ] - if (is_win) { - include_dirs += [ "config/win32" ] - } else if (is_linux) { - include_dirs += [ "config/linux" ] - } else if (is_mac) { - include_dirs += [ "config/darwin" ] - } + gypi_values = exec_script("../../tools/gypi_to_gn.py", + [ rebase_path("cares.gyp") ], + "scope", + [ "cares.gyp" ]) - if (is_win) { - libs = [ - "ws2_32.lib", - "iphlpapi.lib", - ] - } + component(target_name) { + forward_variables_from(invoker, "*") + public_configs = [ ":cares_config" ] + if (is_component_build) { + defines = [ "CARES_BUILDING_LIBRARY" ] + } else { + defines = [] + } + if (is_win) { + defines += [ "CARES_PULL_WS2TCPIP_H=1" ] + } + if (is_posix) { + defines += [ + "_DARWIN_USE_64_BIT_INODE=1", + "_LARGEFILE_SOURCE", + "_FILE_OFFSET_BITS=64", + "_GNU_SOURCE", + "HAVE_CONFIG_H", + ] + } - sources = gypi_values.cares_sources_common - if (is_linux) { - sources += [ "config/linux/ares_config.h" ] - } - if (is_mac) { - sources += gypi_values.cares_sources_mac - } + include_dirs = [ + "src/lib", + "src/lib/include", + ] + if (is_win) { + include_dirs += [ "config/win32" ] + } else if (is_linux) { + include_dirs += [ "config/linux" ] + } else if (is_mac) { + include_dirs += [ "config/darwin" ] + } - if (is_clang) { if (is_win) { - cflags_c = [ - "-Wno-macro-redefined", - ] - } else { - cflags_c = [ - "-Wno-implicit-fallthrough", - "-Wno-unreachable-code", + libs = [ + "ws2_32.lib", + "iphlpapi.lib", ] } + + sources = gypi_values.cares_sources_common + if (is_linux) { + sources += [ "config/linux/ares_config.h" ] + } + if (is_mac) { + sources += gypi_values.cares_sources_mac + } + + if (is_clang) { + if (is_win) { + cflags_c = [ + "-Wno-macro-redefined", + ] + } else { + cflags_c = [ + "-Wno-implicit-fallthrough", + "-Wno-unreachable-code", + ] + } + } } } } diff --git a/deps/corepack/CHANGELOG.md b/deps/corepack/CHANGELOG.md index be8dfa5c8cb8..c90032328ab3 100644 --- a/deps/corepack/CHANGELOG.md +++ b/deps/corepack/CHANGELOG.md @@ -1,5 +1,22 @@ # Changelog +## [0.36.0](https://github.com/nodejs/corepack/compare/v0.35.0...v0.36.0) (2026-08-28) + + +### Features + +* add `COREPACK_ON_UNVERIFIED_DOWNLOAD` env variable ([#856](https://github.com/nodejs/corepack/issues/856)) ([0125d89](https://github.com/nodejs/corepack/commit/0125d89ac904672bb42bc48bb6612d137beeccda)) +* fall back to package-root metadata when dist.signatures is missing on the version endpoint ([#870](https://github.com/nodejs/corepack/issues/870)) ([b26c9d5](https://github.com/nodejs/corepack/commit/b26c9d52fdbc5db326e631de3f6557f7e1b7e55d)) +* only load closest env file, for every commands ([#891](https://github.com/nodejs/corepack/issues/891)) ([b856c51](https://github.com/nodejs/corepack/commit/b856c516c3d0a92ded6b3f9cbbaa0d3f3eb094f1)) +* update package manager versions ([#852](https://github.com/nodejs/corepack/issues/852)) ([7e613b8](https://github.com/nodejs/corepack/commit/7e613b84b079411cb9eab1f90b254597fb9ef70c)) +* use range from `devEngines` when no `packageManager` is set ([#892](https://github.com/nodejs/corepack/issues/892)) ([dec830b](https://github.com/nodejs/corepack/commit/dec830b035f540d1b4ebc516e81fbf43c5e0ffcf)) + + +### Bug Fixes + +* **npmRegistryUtils:** env vars names in integrity check fail error message ([#854](https://github.com/nodejs/corepack/issues/854)) ([8ca01c3](https://github.com/nodejs/corepack/commit/8ca01c3fbeed6c8b5d1bb94df1aacb3fe6cff846)) +* strip trailing slashes from COREPACK_NPM_REGISTRY ([#871](https://github.com/nodejs/corepack/issues/871)) ([b81e92c](https://github.com/nodejs/corepack/commit/b81e92c2338ed6c4c38cfe1239002a261e47e6d5)) + ## [0.35.0](https://github.com/nodejs/corepack/compare/v0.34.7...v0.35.0) (2026-05-15) diff --git a/deps/corepack/README.md b/deps/corepack/README.md index dd32b4ad09f1..e2adeb94958c 100644 --- a/deps/corepack/README.md +++ b/deps/corepack/README.md @@ -127,9 +127,9 @@ Depending on the value of `devEngines.packageManager.onFail`: of mismatch. If the top-level `packageManager` field is missing, Corepack will use the -package manager defined in `devEngines.packageManager` – in which case you must -provide a specific version in `devEngines.packageManager.version`, ideally with -a hash, as explained in the previous section: +package manager defined in `devEngines.packageManager`. You should provide a +specific version in `devEngines.packageManager.version`, ideally with a hash, as +explained in the previous section: ```json { @@ -142,6 +142,16 @@ a hash, as explained in the previous section: } ``` +When `devEngines.packageManager.version` is a range rather than a specific +version, Corepack resolves it the same way as when a range is given on the +command line: the latest version matching the range is looked up on the npm +registry, which means the resolution requires network access (or a cache +containing a matching version, see [Offline Workflow](#offline-workflow)), and +may change over time. Set `COREPACK_ENABLE_AUTO_PIN=1` to have Corepack add the +resolved version to the `packageManager` field. When +`devEngines.packageManager.version` is missing, Corepack falls back to its +[Known Good Release](#known-good-releases) for that package manager. + ## Known Good Releases When running Corepack within projects that don't list a supported package @@ -349,6 +359,19 @@ same major line. Should you need to upgrade to a new major, use an explicit environment variables are required and as plain text. If you want to send an empty password, explicitly set `COREPACK_NPM_PASSWORD` to an empty string. +- `COREPACK_ON_UNVERIFIED_DOWNLOAD` can be set to: + - `warn` (case insensitive): attempting to download an unsigned version without + providing a hash will emit a warning to stderr. + - `error` (case insensitive): attempting to download an unsigned version without + providing a hash will fail with an error, and nothing gets downloaded. + - `strict-warn` (case insensitive): same as `warn`, and additionally emits a + warning when downloading a version that is not pinned by a hash, even when + its signature can be verified. + - `strict-error` (case insensitive): same as `error`, and additionally fails + when downloading a version that is not pinned by a hash, even when its + signature can be verified. + - `ignore` (or any other unsupported value): disables that security feature. + - `HTTP_PROXY`, `HTTPS_PROXY`, and `NO_PROXY` are supported through [`NODE_USE_ENV_PROXY=1`](https://nodejs.org/api/cli.html#node_use_env_proxy1). diff --git a/deps/corepack/dist/lib/corepack.cjs b/deps/corepack/dist/lib/corepack.cjs index 478389c3e2d0..ff66960d4aee 100644 --- a/deps/corepack/dist/lib/corepack.cjs +++ b/deps/corepack/dist/lib/corepack.cjs @@ -5,11 +5,20 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; -var __esm = (fn2, res) => function __init() { - return fn2 && (res = (0, fn2[__getOwnPropNames(fn2)[0]])(fn2 = 0)), res; +var __esm = (fn2, res, err) => function __init() { + if (err) throw err[0]; + try { + return fn2 && (res = (0, fn2[__getOwnPropNames(fn2)[0]])(fn2 = 0)), res; + } catch (e) { + throw err = [e], e; + } }; var __commonJS = (cb, mod) => function __require() { - return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; + try { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; + } catch (e) { + throw mod = 0, e; + } }; var __export = (target, all) => { for (var name2 in all) @@ -3240,32 +3249,44 @@ var require_semver = __commonJS({ var { safeRe: re, t } = require_re(); var parseOptions = require_parse_options(); var { compareIdentifiers } = require_identifiers(); + var isPrereleaseIdentifier = (prerelease, identifier) => { + const identifiers = identifier.split("."); + if (identifiers.length > prerelease.length) { + return false; + } + for (let i = 0; i < identifiers.length; i++) { + if (compareIdentifiers(prerelease[i], identifiers[i]) !== 0) { + return false; + } + } + return true; + }; var SemVer3 = class _SemVer { - constructor(version2, options) { + constructor(version, options) { options = parseOptions(options); - if (version2 instanceof _SemVer) { - if (version2.loose === !!options.loose && version2.includePrerelease === !!options.includePrerelease) { - return version2; + if (version instanceof _SemVer) { + if (version.loose === !!options.loose && version.includePrerelease === !!options.includePrerelease) { + return version; } else { - version2 = version2.version; + version = version.version; } - } else if (typeof version2 !== "string") { - throw new TypeError(`Invalid version. Must be a string. Got type "${typeof version2}".`); + } else if (typeof version !== "string") { + throw new TypeError(`Invalid version. Must be a string. Got type "${typeof version}".`); } - if (version2.length > MAX_LENGTH) { + if (version.length > MAX_LENGTH) { throw new TypeError( `version is longer than ${MAX_LENGTH} characters` ); } - debug("SemVer", version2, options); + debug("SemVer", version, options); this.options = options; this.loose = !!options.loose; this.includePrerelease = !!options.includePrerelease; - const m = version2.trim().match(options.loose ? re[t.LOOSE] : re[t.FULL]); + const m = version.trim().match(options.loose ? re[t.LOOSE] : re[t.FULL]); if (!m) { - throw new TypeError(`Invalid Version: ${version2}`); + throw new TypeError(`Invalid Version: ${version}`); } - this.raw = version2; + this.raw = version; this.major = +m[1]; this.minor = +m[2]; this.patch = +m[3]; @@ -3486,8 +3507,9 @@ var require_semver = __commonJS({ if (identifierBase === false) { prerelease = [identifier]; } - if (compareIdentifiers(this.prerelease[0], identifier) === 0) { - if (isNaN(this.prerelease[1])) { + if (isPrereleaseIdentifier(this.prerelease, identifier)) { + const prereleaseBase = this.prerelease[identifier.split(".").length]; + if (isNaN(prereleaseBase)) { this.prerelease = prerelease; } } else { @@ -3535,12 +3557,12 @@ var require_parse = __commonJS({ "node_modules/semver/functions/parse.js"(exports2, module2) { "use strict"; var SemVer3 = require_semver(); - var parse4 = (version2, options, throwErrors = false) => { - if (version2 instanceof SemVer3) { - return version2; + var parse4 = (version, options, throwErrors = false) => { + if (version instanceof SemVer3) { + return version; } try { - return new SemVer3(version2, options); + return new SemVer3(version, options); } catch (er) { if (!throwErrors) { return null; @@ -3557,8 +3579,8 @@ var require_valid = __commonJS({ "node_modules/semver/functions/valid.js"(exports2, module2) { "use strict"; var parse4 = require_parse(); - var valid = (version2, options) => { - const v = parse4(version2, options); + var valid = (version, options) => { + const v = parse4(version, options); return v ? v.version : null; }; module2.exports = valid; @@ -3762,19 +3784,19 @@ var require_comparator = __commonJS({ toString() { return this.value; } - test(version2) { - debug("Comparator.test", version2, this.options.loose); - if (this.semver === ANY || version2 === ANY) { + test(version) { + debug("Comparator.test", version, this.options.loose); + if (this.semver === ANY || version === ANY) { return true; } - if (typeof version2 === "string") { + if (typeof version === "string") { try { - version2 = new SemVer3(version2, this.options); + version = new SemVer3(version, this.options); } catch (er) { return false; } } - return cmp(version2, this.operator, this.semver, this.options); + return cmp(version, this.operator, this.semver, this.options); } intersects(comp, options) { if (!(comp instanceof _Comparator)) { @@ -3896,6 +3918,7 @@ var require_range = __commonJS({ return this.range; } parseRange(range) { + range = range.replace(BUILDSTRIPRE, ""); const memoOpts = (this.options.includePrerelease && FLAG_INCLUDE_PRERELEASE) | (this.options.loose && FLAG_LOOSE); const memoKey = memoOpts + ":" + range; const cached = cache2.get(memoKey); @@ -3950,19 +3973,19 @@ var require_range = __commonJS({ }); } // if ANY of the sets match ALL of its comparators, then pass - test(version2) { - if (!version2) { + test(version) { + if (!version) { return false; } - if (typeof version2 === "string") { + if (typeof version === "string") { try { - version2 = new SemVer3(version2, this.options); + version = new SemVer3(version, this.options); } catch (er) { return false; } } for (let i = 0; i < this.set.length; i++) { - if (testSet(this.set[i], version2, this.options)) { + if (testSet(this.set[i], version, this.options)) { return true; } } @@ -3978,12 +4001,14 @@ var require_range = __commonJS({ var SemVer3 = require_semver(); var { safeRe: re, + src, t, comparatorTrimReplace, tildeTrimReplace, caretTrimReplace } = require_re(); var { FLAG_INCLUDE_PRERELEASE, FLAG_LOOSE } = require_constants2(); + var BUILDSTRIPRE = new RegExp(src[t.BUILD], "g"); var isNullSet = (c) => c.value === "<0.0.0-0"; var isAny = (c) => c.value === ""; var isSatisfiable = (comparators, options) => { @@ -4012,20 +4037,22 @@ var require_range = __commonJS({ return comp; }; var isX = (id) => !id || id.toLowerCase() === "x" || id === "*"; + var invalidXRangeOrder = (M, m, p) => isX(M) && !isX(m) || isX(m) && p && !isX(p); var replaceTildes = (comp, options) => { return comp.trim().split(/\s+/).map((c) => replaceTilde(c, options)).join(" "); }; var replaceTilde = (comp, options) => { const r = options.loose ? re[t.TILDELOOSE] : re[t.TILDE]; + const z = options.includePrerelease ? "-0" : ""; return comp.replace(r, (_, M, m, p, pr) => { debug("tilde", comp, _, M, m, p, pr); let ret; if (isX(M)) { ret = ""; } else if (isX(m)) { - ret = `>=${M}.0.0 <${+M + 1}.0.0-0`; + ret = `>=${M}.0.0${z} <${+M + 1}.0.0-0`; } else if (isX(p)) { - ret = `>=${M}.${m}.0 <${M}.${+m + 1}.0-0`; + ret = `>=${M}.${m}.0${z} <${M}.${+m + 1}.0-0`; } else if (pr) { debug("replaceTilde pr", pr); ret = `>=${M}.${m}.${p}-${pr} <${M}.${+m + 1}.0-0`; @@ -4071,9 +4098,9 @@ var require_range = __commonJS({ debug("no pr"); if (M === "0") { if (m === "0") { - ret = `>=${M}.${m}.${p}${z} <${M}.${m}.${+p + 1}-0`; + ret = `>=${M}.${m}.${p} <${M}.${m}.${+p + 1}-0`; } else { - ret = `>=${M}.${m}.${p}${z} <${M}.${+m + 1}.0-0`; + ret = `>=${M}.${m}.${p} <${M}.${+m + 1}.0-0`; } } else { ret = `>=${M}.${m}.${p} <${+M + 1}.0.0-0`; @@ -4092,6 +4119,9 @@ var require_range = __commonJS({ const r = options.loose ? re[t.XRANGELOOSE] : re[t.XRANGE]; return comp.replace(r, (ret, gtlt, M, m, p, pr) => { debug("xRange", comp, ret, gtlt, M, m, p, pr); + if (invalidXRangeOrder(M, m, p)) { + return comp; + } const xM = isX(M); const xm = xM || isX(m); const xp = xm || isX(p); @@ -4177,13 +4207,13 @@ var require_range = __commonJS({ } return `${from} ${to}`.trim(); }; - var testSet = (set, version2, options) => { + var testSet = (set, version, options) => { for (let i = 0; i < set.length; i++) { - if (!set[i].test(version2)) { + if (!set[i].test(version)) { return false; } } - if (version2.prerelease.length && !options.includePrerelease) { + if (version.prerelease.length && !options.includePrerelease) { for (let i = 0; i < set.length; i++) { debug(set[i].semver); if (set[i].semver === Comparator.ANY) { @@ -4191,7 +4221,7 @@ var require_range = __commonJS({ } if (set[i].semver.prerelease.length > 0) { const allowed = set[i].semver; - if (allowed.major === version2.major && allowed.minor === version2.minor && allowed.patch === version2.patch) { + if (allowed.major === version.major && allowed.minor === version.minor && allowed.patch === version.patch) { return true; } } @@ -4707,7 +4737,10 @@ function envForceColor() { if (env.FORCE_COLOR.length === 0) { return 1; } - const level = Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3); + if (!new RegExp("^\\d+$", "v").test(env.FORCE_COLOR)) { + return; + } + const level = Math.min(Number(env.FORCE_COLOR), 3); if (![0, 1, 2, 3].includes(level)) { return; } @@ -4741,6 +4774,9 @@ function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) { return 2; } } + if (forceColor !== void 0 && new RegExp("^\\d+$", "v").test(env.FORCE_COLOR)) { + return forceColor; + } if ("TF_BUILD" in env && "AGENT_NAME" in env) { return 1; } @@ -4759,16 +4795,16 @@ function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) { return 1; } if ("CI" in env) { - if (["GITHUB_ACTIONS", "GITEA_ACTIONS", "CIRCLECI"].some((key) => key in env)) { + if (["GITHUB_ACTIONS", "GITEA_ACTIONS", "CIRCLECI"].some((key) => Object.hasOwn(env, key))) { return 3; } - if (["TRAVIS", "APPVEYOR", "GITLAB_CI", "BUILDKITE", "DRONE"].some((sign) => sign in env) || env.CI_NAME === "codeship") { + if (["TRAVIS", "APPVEYOR", "GITLAB_CI", "BUILDKITE", "DRONE"].some((sign) => Object.hasOwn(env, sign)) || env.CI_NAME === "codeship") { return 1; } return min; } if ("TEAMCITY_VERSION" in env) { - return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0; + return new RegExp("^(?:9\\.0*[1-9]\\d*\\.|\\d{2,}\\.)", "v").test(env.TEAMCITY_VERSION) ? 1 : 0; } if (env.COLORTERM === "truecolor") { return 3; @@ -4783,20 +4819,20 @@ function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) { return 3; } if ("TERM_PROGRAM" in env) { - const version2 = Number.parseInt((env.TERM_PROGRAM_VERSION || "").split(".")[0], 10); + const version = Number((env.TERM_PROGRAM_VERSION || "").split(".", 1)[0]); switch (env.TERM_PROGRAM) { case "iTerm.app": { - return version2 >= 3 ? 3 : 2; + return version >= 3 ? 3 : 2; } case "Apple_Terminal": { return 2; } } } - if (/-256(color)?$/i.test(env.TERM)) { + if (new RegExp("-256(?:color)?$", "iv").test(env.TERM)) { return 2; } - if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) { + if (new RegExp("^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux", "iv").test(env.TERM)) { return 1; } if ("COLORTERM" in env) { @@ -6879,10 +6915,22 @@ var init_large_numbers = __esm({ }); // node_modules/tar/dist/esm/types.js -var isCode, name, code; +var isCode, normalFsTypes, name, code; var init_types = __esm({ "node_modules/tar/dist/esm/types.js"() { isCode = (c) => name.has(c); + normalFsTypes = /* @__PURE__ */ new Set([ + "0", + "", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "D" + ]); name = /* @__PURE__ */ new Map([ ["0", "File"], // same as File @@ -6927,12 +6975,13 @@ var init_types = __esm({ }); // node_modules/tar/dist/esm/header.js -var import_node_path, Header, splitPrefix, decString, decDate, numToDate, decNumber, nanUndef, decSmallNumber, MAXNUM, encNumber, encSmallNumber, octalString, padOctal, encDate, NULLS, encString; +var import_node_path, notNegative, Header, splitPrefix, decString, decDate, numToDate, decNumber, nanUndef, decSmallNumber, MAXNUM, encNumber, encSmallNumber, octalString, padOctal, encDate, NULLS, encString; var init_header = __esm({ "node_modules/tar/dist/esm/header.js"() { import_node_path = require("node:path"); init_large_numbers(); init_types(); + notNegative = (n) => n === void 0 || n < 0 ? void 0 : n; Header = class { cksumValid = false; needPax = false; @@ -6969,18 +7018,21 @@ var init_header = __esm({ if (!buf || !(buf.length >= off + 512)) { throw new Error("need 512 bytes for header"); } - this.path = ex?.path ?? decString(buf, off, 100); - this.mode = ex?.mode ?? gex?.mode ?? decNumber(buf, off + 100, 8); - this.uid = ex?.uid ?? gex?.uid ?? decNumber(buf, off + 108, 8); - this.gid = ex?.gid ?? gex?.gid ?? decNumber(buf, off + 116, 8); - this.size = ex?.size ?? gex?.size ?? decNumber(buf, off + 124, 12); - this.mtime = ex?.mtime ?? gex?.mtime ?? decDate(buf, off + 136, 12); - this.cksum = decNumber(buf, off + 148, 12); - if (gex) - this.#slurp(gex, true); - if (ex) - this.#slurp(ex); const t = decString(buf, off + 156, 1); + const isNormalFS = normalFsTypes.has(t); + const exForFields = isNormalFS ? ex : void 0; + const gexForFields = isNormalFS ? gex : void 0; + this.path = exForFields?.path ?? decString(buf, off, 100); + this.mode = exForFields?.mode ?? gexForFields?.mode ?? decNumber(buf, off + 100, 8); + this.uid = exForFields?.uid ?? gexForFields?.uid ?? decNumber(buf, off + 108, 8); + this.gid = exForFields?.gid ?? gexForFields?.gid ?? decNumber(buf, off + 116, 8); + this.size = notNegative(exForFields?.size ?? gexForFields?.size ?? decNumber(buf, off + 124, 12)); + this.mtime = exForFields?.mtime ?? gexForFields?.mtime ?? decDate(buf, off + 136, 12); + this.cksum = decNumber(buf, off + 148, 12); + if (gexForFields) + this.#slurp(gexForFields, true); + if (exForFields) + this.#slurp(exForFields); if (isCode(t)) { this.#type = t || "0"; } @@ -6992,10 +7044,10 @@ var init_header = __esm({ } this.linkpath = decString(buf, off + 157, 100); if (buf.subarray(off + 257, off + 265).toString() === "ustar\x0000") { - this.uname = ex?.uname ?? gex?.uname ?? decString(buf, off + 265, 32); - this.gname = ex?.gname ?? gex?.gname ?? decString(buf, off + 297, 32); - this.devmaj = ex?.devmaj ?? gex?.devmaj ?? decNumber(buf, off + 329, 8) ?? 0; - this.devmin = ex?.devmin ?? gex?.devmin ?? decNumber(buf, off + 337, 8) ?? 0; + this.uname = exForFields?.uname ?? gexForFields?.uname ?? decString(buf, off + 265, 32); + this.gname = exForFields?.gname ?? gexForFields?.gname ?? decString(buf, off + 297, 32); + this.devmaj = exForFields?.devmaj ?? gexForFields?.devmaj ?? decNumber(buf, off + 329, 8) ?? 0; + this.devmin = exForFields?.devmin ?? gexForFields?.devmin ?? decNumber(buf, off + 337, 8) ?? 0; if (buf[off + 475] !== 0) { const prefix = decString(buf, off + 345, 155); this.path = prefix + "/" + this.path; @@ -7022,7 +7074,7 @@ var init_header = __esm({ } #slurp(ex, gex = false) { Object.assign(this, Object.fromEntries(Object.entries(ex).filter(([k, v]) => { - return !(v === null || v === void 0 || k === "path" && gex || k === "linkpath" && gex || k === "global"); + return !(v === null || v === void 0 || k === "size" && Number(v) < 0 || k === "path" && gex || k === "linkpath" && gex || k === "global"); }))); } encode(buf, off = 0) { @@ -7253,8 +7305,36 @@ var init_pax = __esm({ return set; } const k = r.replace(/^SCHILY\.(dev|ino|nlink)/, "$1"); - const v = kv.join("="); - set[k] = /^([A-Z]+\.)?([mac]|birth|creation)time$/.test(k) ? new Date(Number(v) * 1e3) : /^[0-9]+$/.test(v) ? +v : v; + const v = kv.join("=").replace(/\0.*/, ""); + switch (k) { + case "path": + case "linkpath": + case "type": + case "charset": + case "comment": + case "gname": + case "uname": + set[k] = v; + break; + case "ctime": + case "atime": + case "mtime": + set[k] = new Date(Number(v) * 1e3); + break; + case "size": + const s = +v; + if (s >= 0) + set[k] = s; + break; + case "gid": + case "uid": + case "dev": + case "ino": + case "nlink": + case "mode": + set[k] = +v; + break; + } return set; }; } @@ -7265,7 +7345,7 @@ var platform, normalizeWindowsPath; var init_normalize_windows_path = __esm({ "node_modules/tar/dist/esm/normalize-windows-path.js"() { platform = process.env.TESTING_TAR_FAKE_PLATFORM || process.platform; - normalizeWindowsPath = platform !== "win32" ? (p) => p : (p) => p && p.replaceAll(/\\/g, "/"); + normalizeWindowsPath = platform !== "win32" ? (p) => String(p) : (p) => String(p).replaceAll(/\\/g, "/"); } }); @@ -7422,7 +7502,7 @@ var init_warn_method = __esm({ }); // node_modules/tar/dist/esm/parse.js -var import_events3, maxMetaEntrySize, gzipHeader, zstdHeader, ZIP_HEADER_LEN, STATE, WRITEENTRY, READENTRY, NEXTENTRY, PROCESSENTRY, EX, GEX, META, EMITMETA, BUFFER2, QUEUE, ENDED, EMITTEDEND, EMIT, UNZIP, CONSUMECHUNK, CONSUMECHUNKSUB, CONSUMEBODY, CONSUMEMETA, CONSUMEHEADER, CONSUMING, BUFFERCONCAT, MAYBEEND, WRITING, ABORTED2, DONE, SAW_VALID_ENTRY, SAW_NULL_BLOCK, SAW_EOF, CLOSESTREAM, noop2, Parser; +var import_events3, maxMetaEntrySize, gzipHeader, zstdHeader, ZIP_HEADER_LEN, STATE, WRITEENTRY, READENTRY, NEXTENTRY, PROCESSENTRY, EX, GEX, META, EMITMETA, BUFFER2, QUEUE, ENDED, EMITTEDEND, EMIT, UNZIP, CONSUMECHUNK, CONSUMECHUNKSUB, CONSUMEBODY, CONSUMEMETA, CONSUMEHEADER, CONSUMING, BUFFERCONCAT, MAYBEEND, WRITING, ABORTED2, DONE, SAW_VALID_ENTRY, SAW_NULL_BLOCK, SAW_EOF, CLOSESTREAM, MAX_DECOMPRESSION_RATIO, COMPRESSEDBYTESREAD, DECOMPRESSEDBYTESREAD, CHECKDECOMPRESSIONRATIO, noop2, Parser; var init_parse = __esm({ "node_modules/tar/dist/esm/parse.js"() { import_events3 = require("events"); @@ -7465,6 +7545,10 @@ var init_parse = __esm({ SAW_NULL_BLOCK = /* @__PURE__ */ Symbol("sawNullBlock"); SAW_EOF = /* @__PURE__ */ Symbol("sawEOF"); CLOSESTREAM = /* @__PURE__ */ Symbol("closeStream"); + MAX_DECOMPRESSION_RATIO = 1e3; + COMPRESSEDBYTESREAD = /* @__PURE__ */ Symbol("compressedBytesRead"); + DECOMPRESSEDBYTESREAD = /* @__PURE__ */ Symbol("decompressedBytesRead"); + CHECKDECOMPRESSIONRATIO = /* @__PURE__ */ Symbol("checkDecompressionRatio"); noop2 = () => true; Parser = class extends import_events3.EventEmitter { file; @@ -7473,6 +7557,7 @@ var init_parse = __esm({ filter; brotli; zstd; + maxDecompressionRatio; writable = true; readable = false; [QUEUE] = []; @@ -7492,6 +7577,8 @@ var init_parse = __esm({ [WRITING] = false; [CONSUMING] = false; [EMITTEDEND] = false; + [COMPRESSEDBYTESREAD] = 0; + [DECOMPRESSEDBYTESREAD] = 0; constructor(opt = {}) { super(); this.file = opt.file || ""; @@ -7510,6 +7597,7 @@ var init_parse = __esm({ }); } this.strict = !!opt.strict; + this.maxDecompressionRatio = typeof opt.maxDecompressionRatio === "number" ? opt.maxDecompressionRatio : MAX_DECOMPRESSION_RATIO; this.maxMetaEntrySize = opt.maxMetaEntrySize || maxMetaEntrySize; this.filter = typeof opt.filter === "function" ? opt.filter : noop2; const isTBR = opt.file && (opt.file.endsWith(".tar.br") || opt.file.endsWith(".tbr")); @@ -7710,10 +7798,29 @@ var init_parse = __esm({ } } abort(error) { + if (this[ABORTED2]) { + return; + } + if (this[UNZIP]) { + const u = this[UNZIP]; + u.write = () => true; + u.end = () => u; + u.emit = () => false; + u.destroy?.(); + } this[ABORTED2] = true; this.emit("abort", error); this.warn("TAR_ABORT", error, { recoverable: false }); } + [CHECKDECOMPRESSIONRATIO](chunk) { + this[DECOMPRESSEDBYTESREAD] += chunk.length; + const ratio = this[DECOMPRESSEDBYTESREAD] / this[COMPRESSEDBYTESREAD]; + if (ratio > this.maxDecompressionRatio) { + this.abort(new Error(`max decompression ratio exceeded: ${ratio.toFixed(2)} > ${this.maxDecompressionRatio}`)); + return false; + } + return true; + } write(chunk, encoding, cb) { if (typeof encoding === "function") { cb = encoding; @@ -7779,13 +7886,22 @@ var init_parse = __esm({ const ended = this[ENDED]; this[ENDED] = false; this[UNZIP] = this[UNZIP] === void 0 ? new Unzip({}) : isZstd ? new ZstdDecompress({}) : new BrotliDecompress({}); - this[UNZIP].on("data", (chunk2) => this[CONSUMECHUNK](chunk2)); - this[UNZIP].on("error", (er) => this.abort(er)); + this[UNZIP].on("data", (chunk2) => { + if (this[CHECKDECOMPRESSIONRATIO](chunk2)) { + this[CONSUMECHUNK](chunk2); + } + }); + this[UNZIP].on("error", (er) => { + if (!this[ABORTED2]) { + this.abort(er); + } + }); this[UNZIP].on("end", () => { this[ENDED] = true; this[CONSUMECHUNK](); }); this[WRITING] = true; + this[COMPRESSEDBYTESREAD] += chunk.length; const ret2 = !!this[UNZIP][ended ? "end" : "write"](chunk); this[WRITING] = false; cb?.(); @@ -7794,6 +7910,7 @@ var init_parse = __esm({ } this[WRITING] = true; if (this[UNZIP]) { + this[COMPRESSEDBYTESREAD] += chunk.length; this[UNZIP].write(chunk); } else { this[CONSUMECHUNK](chunk); @@ -7815,7 +7932,7 @@ var init_parse = __esm({ if (this[ENDED] && !this[EMITTEDEND] && !this[ABORTED2] && !this[CONSUMING]) { this[EMITTEDEND] = true; const entry = this[WRITEENTRY]; - if (entry && entry.blockRemain) { + if (entry?.blockRemain) { const have = this[BUFFER2] ? this[BUFFER2].length : 0; this.warn("TAR_BAD_ARCHIVE", `Truncated input (needed ${entry.blockRemain} more bytes, only ${have} available)`, { entry }); if (this[BUFFER2]) { @@ -7895,8 +8012,10 @@ var init_parse = __esm({ this.once("finish", cb); if (!this[ABORTED2]) { if (this[UNZIP]) { - if (chunk) + if (chunk) { + this[COMPRESSEDBYTESREAD] += chunk.length; this[UNZIP].write(chunk); + } this[UNZIP].end(); } else { this[ENDED] = true; @@ -7954,14 +8073,19 @@ var init_list = __esm({ filesFilter = (opt, files) => { const map = new Map(files.map((f) => [stripTrailingSlashes(f), true])); const filter = opt.filter; - const mapHas = (file, r = "") => { + const MAX2 = 100; + const mapHas = (file, r = "", depth = 0) => { + if (depth >= MAX2) { + map.set(file, false); + return false; + } const root = r || (0, import_path2.parse)(file).root || "."; let ret; if (file === root) ret = false; else { const m = map.get(file); - ret = m !== void 0 ? m : mapHas((0, import_path2.dirname)(file), root); + ret = m !== void 0 ? m : mapHas((0, import_path2.dirname)(file), root, depth + 1); } map.set(file, ret); return ret; @@ -8660,7 +8784,7 @@ var init_unpack = __esm({ this.gid = void 0; this.setOwner = false; } - this.preserveOwner = opt.preserveOwner === void 0 && typeof opt.uid !== "number" ? !!(process.getuid && process.getuid() === 0) : !!opt.preserveOwner; + this.preserveOwner = opt.preserveOwner === void 0 && typeof opt.uid !== "number" ? !!(process.getuid?.() === 0) : !!opt.preserveOwner; this.processUid = (this.preserveOwner || this.setOwner) && process.getuid ? process.getuid() : void 0; this.processGid = (this.preserveOwner || this.setOwner) && process.getgid ? process.getgid() : void 0; this.maxDepth = typeof opt.maxDepth === "number" ? opt.maxDepth : DEFAULT_MAX_DEPTH; @@ -8819,7 +8943,7 @@ var init_unpack = __esm({ } } [MKDIR](dir, mode, cb) { - mkdir(normalizeWindowsPath(dir), { + void mkdir(normalizeWindowsPath(dir), { uid: this.uid, gid: this.gid, processUid: this.processUid, @@ -9574,8 +9698,8 @@ var require_v8_compile_cache = __commonJS({ } const dirname2 = typeof process.getuid === "function" ? "v8-compile-cache-" + process.getuid() : "v8-compile-cache"; const arch = process.arch; - const version2 = typeof process.versions.v8 === "string" ? process.versions.v8 : typeof process.versions.chakracore === "string" ? "chakracore-" + process.versions.chakracore : "node-" + process.version; - const cacheDir = path16.join(os3.tmpdir(), dirname2, arch, version2); + const version = typeof process.versions.v8 === "string" ? process.versions.v8 : typeof process.versions.chakracore === "string" ? "chakracore-" + process.versions.chakracore : "node-" + process.version; + const cacheDir = path16.join(os3.tmpdir(), dirname2, arch, version); return cacheDir; } function getMainName() { @@ -9613,13 +9737,13 @@ var require_satisfies = __commonJS({ "node_modules/semver/functions/satisfies.js"(exports2, module2) { "use strict"; var Range3 = require_range(); - var satisfies = (version2, range, options) => { + var satisfies = (version, range, options) => { try { range = new Range3(range, options); } catch (er) { return false; } - return range.test(version2); + return range.test(version); }; module2.exports = satisfies; } @@ -12003,7 +12127,6 @@ var init_pack = __esm({ init_esm(); init_esm3(); init_esm5(); - init_read_entry(); init_warn_method(); import_path10 = __toESM(require("path"), 1); init_normalize_windows_path(); @@ -12026,7 +12149,7 @@ var init_pack = __esm({ ONSTAT = /* @__PURE__ */ Symbol("onStat"); ENDED3 = /* @__PURE__ */ Symbol("ended"); QUEUE2 = /* @__PURE__ */ Symbol("queue"); - PENDINGLINKS = /* @__PURE__ */ Symbol("queue"); + PENDINGLINKS = /* @__PURE__ */ Symbol("pendingLinks"); CURRENT = /* @__PURE__ */ Symbol("current"); PROCESS2 = /* @__PURE__ */ Symbol("process"); PROCESSING = /* @__PURE__ */ Symbol("processing"); @@ -12175,10 +12298,10 @@ var init_pack = __esm({ if (this[ENDED3]) { throw new Error("write after end"); } - if (path16 instanceof ReadEntry) { - this[ADDTARENTRY](path16); - } else { + if (typeof path16 === "string") { this[ADDFSENTRY](path16); + } else { + this[ADDTARENTRY](path16); } return this.flowing; } @@ -12563,7 +12686,99 @@ module.exports = __toCommonJS(lib_exports2); var import_clipanion17 = __toESM(require_advanced()); // package.json -var version = "0.35.0"; +var package_default = { + name: "corepack", + version: "0.36.0", + homepage: "https://github.com/nodejs/corepack#readme", + bugs: { + url: "https://github.com/nodejs/corepack/issues" + }, + repository: { + type: "git", + url: "https://github.com/nodejs/corepack.git" + }, + engines: { + node: "^22.22.2 || ^24.15.0 || >=26.0.0" + }, + exports: { + "./package.json": "./package.json" + }, + license: "MIT", + packageManager: "yarn@4.18.0+sha224.5707fce90df5d8720fae4e85a07ab55e90aa20fded8914893e2ba225", + devDependencies: { + "@types/debug": "^4.1.5", + "@types/node": "^22.0.0", + "@types/proxy-from-env": "^1", + "@types/semver": "^7.1.0", + "@types/which": "^3.0.0", + "@yarnpkg/eslint-config": "^3.1.1", + "@yarnpkg/fslib": "^3.0.0-rc.48", + "@zkochan/cmd-shim": "^6.0.0", + clipanion: "patch:clipanion@npm%3A3.2.1#~/.yarn/patches/clipanion-npm-3.2.1-fc9187f56c.patch", + debug: "^4.1.1", + esbuild: "^0.28.0", + eslint: "^10.8.1", + semver: "^7.6.3", + "supports-color": "^11.0.0", + tar: "^7.5.11", + typescript: "^5.7.3", + "v8-compile-cache": "^2.3.0", + vitest: "^4.0.5", + which: "^7.0.0" + }, + dependenciesMeta: { + esbuild: { + built: true + } + }, + scripts: { + build: "run clean && run build:bundle && node ./mkshims.ts", + "build:bundle": "esbuild ./sources/_lib.ts --bundle --platform=node --target=node22.22.2 --external:corepack --outfile='./dist/lib/corepack.cjs' --resolve-extensions='.ts,.mjs,.js'", + clean: "run rimraf dist shims", + corepack: "node ./sources/_cli.ts", + lint: "eslint", + prepack: "yarn build", + postpack: "run clean", + rimraf: "node -e 'for(let i=2;i { - SupportedPackageManagers3["Npm"] = `npm`; - SupportedPackageManagers3["Pnpm"] = `pnpm`; - SupportedPackageManagers3["Yarn"] = `yarn`; - return SupportedPackageManagers3; -})(SupportedPackageManagers || {}); +var supportedPackageManagersList = [`npm`, `pnpm`, `yarn`]; var SupportedPackageManagerSet = new Set( - Object.values(SupportedPackageManagers) + supportedPackageManagersList ); var SupportedPackageManagerSetWithoutNpm = new Set( - Object.values(SupportedPackageManagers) + supportedPackageManagersList.filter((pm) => pm !== `npm`) ); -SupportedPackageManagerSetWithoutNpm.delete("npm" /* Npm */); function isSupportedPackageManager(value) { return SupportedPackageManagerSet.has(value); } @@ -13454,6 +13684,9 @@ function parseSpec(raw2, source, { enforceExactVersion = true } = {}) { range }; } +function devEnginesToDescriptor({ name: name2, version }) { + return { name: name2, range: version ?? `*` }; +} function warnOrThrow(errorMessage, onFail) { switch (onFail) { case `ignore`: @@ -13471,44 +13704,45 @@ function parsePackageJSON(packageJSONContent) { const { packageManager } = packageJSONContent.devEngines; if (typeof packageManager !== `object`) { console.warn(`! Corepack only supports objects as valid value for devEngines.packageManager. The current value (${JSON.stringify(packageManager)}) will be ignored.`); - return pm; + return { packageManagerField: pm }; } if (Array.isArray(packageManager)) { console.warn(`! Corepack does not currently support array values for devEngines.packageManager`); - return pm; + return { packageManagerField: pm }; } - const { name: name2, version: version2, onFail } = packageManager; + const { name: name2, version, onFail } = packageManager; if (typeof name2 !== `string` || name2.includes(`@`)) { warnOrThrow(`The value of devEngines.packageManager.name ${JSON.stringify(name2)} is not a supported string value`, onFail); - return pm; + return { packageManagerField: pm }; } - if (version2 != null && (typeof version2 !== `string` || !(0, import_valid2.default)(version2))) { - warnOrThrow(`The value of devEngines.packageManager.version ${JSON.stringify(version2)} is not a valid semver range`, onFail); - return pm; + if (version != null && (typeof version !== `string` || !(0, import_valid2.default)(version))) { + warnOrThrow(`The value of devEngines.packageManager.version ${JSON.stringify(version)} is not a valid semver range`, onFail); + return { packageManagerField: pm }; } - log(`devEngines.packageManager defines that ${name2}@${version2} is the local package manager`); + log(`devEngines.packageManager defines that ${name2}${version ? `@${version}` : ``} should be the local package manager`); if (pm) { - if (!pm.startsWith?.(`${name2}@`)) + if (!pm.startsWith?.(`${name2}@`)) { warnOrThrow(`"packageManager" field is set to ${JSON.stringify(pm)} which does not match the "devEngines.packageManager" field set to ${JSON.stringify(name2)}`, onFail); - else if (version2 != null && !(0, import_satisfies.default)(pm.slice(packageManager.name.length + 1), version2)) - warnOrThrow(`"packageManager" field is set to ${JSON.stringify(pm)} which does not match the value defined in "devEngines.packageManager" for ${JSON.stringify(name2)} of ${JSON.stringify(version2)}`, onFail); - return pm; + } else if (version != null && !(0, import_satisfies.default)(pm.slice(name2.length + 1), version)) { + warnOrThrow(`"packageManager" field is set to ${JSON.stringify(pm)} which does not match the value defined in "devEngines.packageManager" for ${JSON.stringify(name2)} of ${JSON.stringify(version)}`, onFail); + } } - return `${name2}@${version2 ?? `*`}`; + return { packageManagerField: pm, devEnginesPackageManager: { name: name2, version, onFail } }; } - return pm; + return { packageManagerField: pm }; } async function setLocalPackageManager(cwd, info) { - const lookup = await loadSpec(cwd); - const range = `range` in lookup && lookup.range; - if (range) { - if (info.locator.name !== range.name || !(0, import_satisfies.default)(info.locator.reference, range.range)) { - warnOrThrow(`The requested version of ${info.locator.name}@${info.locator.reference} does not match the devEngines specification (${range.name}@${range.range})`, range.onFail); + const lookup = await loadSpecAndEnv(cwd); + const projectFound = lookup.type !== `NoProject`; + const devEnginesValue = projectFound ? lookup.devEnginesValue : void 0; + if (devEnginesValue) { + if (info.locator.name !== devEnginesValue.name || devEnginesValue.version != null && !(0, import_satisfies.default)(info.locator.reference, devEnginesValue.version)) { + warnOrThrow(`The requested version of ${info.locator.name}@${info.locator.reference} does not match the devEngines specification (${devEnginesValue.name}@${devEnginesValue.version ?? `*`})`, devEnginesValue.onFail); } } - const content = lookup.type !== `NoProject` ? await import_fs5.default.promises.readFile(lookup.target, `utf8`) : ``; + const content = projectFound ? await import_fs5.default.promises.readFile(lookup.target, `utf8`) : ``; const { data, indent } = readPackageJson(content); - const previousPackageManager = data.packageManager ?? (range ? `${range.name}@${range.range}` : `unknown`); + const previousPackageManager = data.packageManager ?? (devEnginesValue ? `${devEnginesValue.name}@${devEnginesValue.version ?? `*`}` : `unknown`); data.packageManager = `${info.locator.name}@${info.locator.reference}`; const newContent = normalizeLineEndings(content, `${JSON.stringify(data, null, indent)} `); @@ -13517,15 +13751,43 @@ async function setLocalPackageManager(cwd, info) { previousPackageManager }; } -async function loadSpec(initialCwd) { +async function loadEnvFileIfExists(cwd) { + const envFilePath = import_path4.default.resolve(cwd, process.env.COREPACK_ENV_FILE ?? `.corepack.env`); + if (process.env.COREPACK_ENV_FILE == `0`) { + log(`Skipping env file as configured with COREPACK_ENV_FILE`); + return void 0; + } + log(`Checking ${envFilePath}`); + try { + const localEnv = { + ...Object.fromEntries(Object.entries((0, import_util.parseEnv)(await import_fs5.default.promises.readFile(envFilePath, `utf8`))).filter((e) => e[0].startsWith(`COREPACK_`))), + ...process.env + }; + log(`Successfully loaded env file found at ${envFilePath}`); + return { env: localEnv, path: envFilePath }; + } catch (err) { + if (err?.code !== `ENOENT`) + throw err; + log(`No env file found at ${envFilePath}`); + } + return void 0; +} +async function loadSpecAndEnv(initialCwd, { envOnly } = { envOnly: false }) { let nextCwd = initialCwd; let currCwd = ``; let selection = null; + let localEnv = void 0; while (nextCwd !== currCwd && (!selection || !selection.data.packageManager)) { currCwd = nextCwd; nextCwd = import_path4.default.dirname(currCwd); if (nodeModulesRegExp.test(currCwd)) continue; + if (process.env.COREPACK_ENV_FILE !== `0` && !localEnv) + localEnv = await loadEnvFileIfExists(currCwd); + if (envOnly) { + if (localEnv) break; + continue; + } const manifestPath = import_path4.default.join(currCwd, `package.json`); log(`Checking ${manifestPath}`); let content; @@ -13541,54 +13803,42 @@ async function loadSpec(initialCwd) { } catch { } if (typeof data !== `object` || data === null) - throw new import_clipanion4.UsageError(`Invalid package.json in ${import_path4.default.relative(initialCwd, manifestPath)}`); - let localEnv; - const envFilePath2 = import_path4.default.resolve(currCwd, process.env.COREPACK_ENV_FILE ?? `.corepack.env`); - if (process.env.COREPACK_ENV_FILE == `0`) { - log(`Skipping env file as configured with COREPACK_ENV_FILE`); - localEnv = process.env; - } else if (typeof import_util.parseEnv !== `function`) { - log(`Skipping env file as it is not supported by the current version of Node.js`); - localEnv = process.env; - } else { - log(`Checking ${envFilePath2}`); - try { - localEnv = { - ...Object.fromEntries(Object.entries((0, import_util.parseEnv)(await import_fs5.default.promises.readFile(envFilePath2, `utf8`))).filter((e) => e[0].startsWith(`COREPACK_`))), - ...process.env - }; - log(`Successfully loaded env file found at ${envFilePath2}`); - } catch (err) { - if (err?.code !== `ENOENT`) - throw err; - log(`No env file found at ${envFilePath2}`); - localEnv = process.env; - } - } - selection = { data, manifestPath, localEnv, envFilePath: envFilePath2 }; + throw new import_clipanion4.UsageError(`Invalid package.json in ${import_path4.default.relative(currCwd, manifestPath)}`); + selection = { data, manifestPath }; } + if (localEnv) + process.env = localEnv.env; if (selection === null) - return { type: `NoProject`, target: import_path4.default.join(initialCwd, `package.json`) }; - let envFilePath; - if (selection.localEnv !== process.env) { - envFilePath = selection.envFilePath; - process.env = selection.localEnv; - } - const rawPmSpec = parsePackageJSON(selection.data); - if (typeof rawPmSpec === `undefined`) - return { type: `NoSpec`, target: selection.manifestPath }; - log(`${selection.manifestPath} defines ${rawPmSpec} as local package manager`); + return { type: `NoProject`, target: import_path4.default.join(initialCwd, `package.json`), envFilePath: localEnv?.path }; + const { packageManagerField, devEnginesPackageManager } = parsePackageJSON(selection.data); + if (devEnginesPackageManager != null && !packageManagerField) { + const { name: name2, version } = devEnginesPackageManager; + if (!version || !(0, import_valid.default)(version)) { + log(`${selection.manifestPath} defines ${name2} as local package manager using devEngines.packageManager, without an exact version`); + return { type: `NoSpec`, target: selection.manifestPath, envFilePath: localEnv?.path, devEnginesValue: devEnginesPackageManager }; + } + log(`${selection.manifestPath} defines ${name2}@${version} as local package manager using devEngines.packageManager`); + return { + type: `Found`, + target: selection.manifestPath, + field: `devEngines.packageManager`, + envFilePath: localEnv?.path, + devEnginesValue: devEnginesPackageManager, + // Lazy-loading it so we do not throw errors on commands that do not need valid spec. + getSpec: ({ enforceExactVersion = true } = {}) => parseSpec(`${name2}@${version}`, import_path4.default.relative(initialCwd, selection.manifestPath), { enforceExactVersion }) + }; + } + if (packageManagerField === void 0) + return { type: `NoSpec`, target: selection.manifestPath, envFilePath: localEnv?.path }; + log(`${selection.manifestPath} defines ${packageManagerField} as local package manager using the packageManager field`); return { type: `Found`, target: selection.manifestPath, - envFilePath, - range: selection.data.devEngines?.packageManager?.version && { - name: selection.data.devEngines.packageManager.name, - range: selection.data.devEngines.packageManager.version, - onFail: selection.data.devEngines.packageManager.onFail - }, + field: `packageManager`, + envFilePath: localEnv?.path, + devEnginesValue: devEnginesPackageManager, // Lazy-loading it so we do not throw errors on commands that do not need valid spec. - getSpec: ({ enforceExactVersion = true } = {}) => parseSpec(rawPmSpec, import_path4.default.relative(initialCwd, selection.manifestPath), { enforceExactVersion }) + getSpec: ({ enforceExactVersion = true } = {}) => parseSpec(packageManagerField, import_path4.default.relative(initialCwd, selection.manifestPath), { enforceExactVersion }) }; } @@ -13652,10 +13902,10 @@ async function activatePackageManager(lastKnownGood, locator) { await createLastKnownGoodFile(lastKnownGood); } var Engine = class { + config; constructor(config = config_default) { this.config = config; } - config; getPackageManagerFor(binaryName) { for (const packageManager of SupportedPackageManagerSet) { for (const rangeDefinition of Object.values(this.config.definitions[packageManager].ranges)) { @@ -13782,7 +14032,7 @@ var Engine = class { if (import_process3.default.env.COREPACK_ENABLE_STRICT === `0`) transparent = true; while (true) { - const result = await loadSpec(initialCwd); + const result = await loadSpecAndEnv(initialCwd); switch (result.type) { case `NoProject`: { if (typeof locator.reference === `function`) @@ -13791,7 +14041,13 @@ var Engine = class { return fallbackDescriptor; } case `NoSpec`: { - if (typeof locator.reference === `function`) + const { devEnginesValue } = result; + const nameMatches = devEnginesValue != null && devEnginesValue.name === fallbackDescriptor.name; + if (devEnginesValue != null && !nameMatches && !transparent) + warnOrThrow(`This project is configured to use ${devEnginesValue.name} because ${result.target} has a "devEngines.packageManager" field`, devEnginesValue.onFail); + if (nameMatches && devEnginesValue.version) + fallbackDescriptor.range = devEnginesValue.version; + else if (typeof locator.reference === `function`) fallbackDescriptor.range = await locator.reference(); if (import_process3.default.env.COREPACK_ENABLE_AUTO_PIN === `1`) { const resolved = await this.resolveDescriptor(fallbackDescriptor, { allowTags: true }); @@ -13815,7 +14071,7 @@ var Engine = class { log(`Falling back to ${fallbackDescriptor.name}@${fallbackDescriptor.range} in a ${spec.name}@${spec.range} project`); return fallbackDescriptor; } else { - throw new import_clipanion5.UsageError(`This project is configured to use ${spec.name} because ${result.target} has a "packageManager" field`); + throw new import_clipanion5.UsageError(`This project is configured to use ${spec.name} because ${result.target} has a "${result.field}" field`); } } else { log(`Using ${spec.name}@${spec.range} as defined in project manifest ${result.target}`); @@ -13892,7 +14148,7 @@ var Engine = class { const packageManagerSpec = definition.ranges[range]; const registry = getRegistryFromPackageManagerSpec(packageManagerSpec); const versions2 = await fetchAvailableVersions2(registry); - return versions2.filter((version2) => satisfiesWithPrereleases(version2, finalDescriptor.range)); + return versions2.filter((version) => satisfiesWithPrereleases(version, finalDescriptor.range)); })); const highestVersion = [...new Set(versions.flat())].sort(import_rcompare.default); if (highestVersion.length === 0) @@ -14084,16 +14340,23 @@ var BaseCommand = class extends import_clipanion9.Command { async resolvePatternsToDescriptors({ patterns }) { const resolvedSpecs = patterns.map((pattern) => parseSpec(pattern, `CLI arguments`, { enforceExactVersion: false })); if (resolvedSpecs.length === 0) { - const lookup = await loadSpec(this.context.cwd); + const lookup = await loadSpecAndEnv(this.context.cwd); switch (lookup.type) { case `NoProject`: throw new import_clipanion9.UsageError(`Couldn't find a project in the local directory - please specify the package manager to pack, or run this command from a valid project`); - case `NoSpec`: - throw new import_clipanion9.UsageError(`The local project doesn't feature a 'packageManager' field nor a 'devEngines.packageManager' field - please specify the package manager to pack, or update the manifest to reference it`); + case `NoSpec`: { + const { devEnginesValue } = lookup; + if (devEnginesValue?.version) + return [devEnginesToDescriptor(devEnginesValue)]; + throw new import_clipanion9.UsageError(`The local project doesn't feature a 'packageManager' field ${devEnginesValue ? `` : `nor a 'devEngines.packageManager' field `}- please specify the package manager to pack, or update the manifest to reference it`); + } default: { - return [lookup.range ?? lookup.getSpec()]; + const { devEnginesValue } = lookup; + return [devEnginesValue?.version ? devEnginesToDescriptor(devEnginesValue) : lookup.getSpec()]; } } + } else { + await loadSpecAndEnv(this.context.cwd, { envOnly: true }); } return resolvedSpecs; } @@ -14457,16 +14720,24 @@ var PrepareCommand = class extends import_clipanion16.Command { const specs = this.specs; const installLocations = []; if (specs.length === 0) { - const lookup = await loadSpec(this.context.cwd); + const lookup = await loadSpecAndEnv(this.context.cwd); switch (lookup.type) { case `NoProject`: throw new import_clipanion16.UsageError(`Couldn't find a project in the local directory - please specify the package manager to pack, or run this command from a valid project`); - case `NoSpec`: - throw new import_clipanion16.UsageError(`The local project doesn't feature a 'packageManager' field - please specify the package manager to pack, or update the manifest to reference it`); + case `NoSpec`: { + const { devEnginesValue } = lookup; + if (devEnginesValue?.version) { + specs.push(devEnginesToDescriptor(devEnginesValue)); + break; + } + throw new import_clipanion16.UsageError(`The local project doesn't feature a 'packageManager' field ${devEnginesValue ? `` : `nor a 'devEngines.packageManager' field `}- please specify the package manager to pack, or update the manifest to reference it`); + } default: { specs.push(lookup.getSpec()); } } + } else { + await loadSpecAndEnv(this.context.cwd, { envOnly: true }); } for (const request of specs) { const spec = typeof request === `string` ? parseSpec(request, `CLI arguments`, { enforceExactVersion: false }) : request; @@ -14512,6 +14783,7 @@ var PrepareCommand = class extends import_clipanion16.Command { }; // sources/main.ts +var { version: corepackVersion } = package_default; function getPackageManagerRequestFromCli(parameter, engine) { if (!parameter) return null; @@ -14538,7 +14810,7 @@ async function runMain(argv) { const cli = new import_clipanion17.Cli({ binaryLabel: `Corepack`, binaryName: `corepack`, - binaryVersion: version + binaryVersion: corepackVersion }); cli.register(import_clipanion17.Builtins.HelpCommand); cli.register(import_clipanion17.Builtins.VersionCommand); diff --git a/deps/corepack/package.json b/deps/corepack/package.json index 279475fb9cec..170b48449fc7 100644 --- a/deps/corepack/package.json +++ b/deps/corepack/package.json @@ -1,6 +1,6 @@ { "name": "corepack", - "version": "0.35.0", + "version": "0.36.0", "homepage": "https://github.com/nodejs/corepack#readme", "bugs": { "url": "https://github.com/nodejs/corepack/issues" @@ -16,24 +16,23 @@ "./package.json": "./package.json" }, "license": "MIT", - "packageManager": "yarn@4.14.1+sha224.88b7a7244bbd9040380c417f7eb556d85c67640b651f113cb4c72113", + "packageManager": "yarn@4.18.0+sha224.5707fce90df5d8720fae4e85a07ab55e90aa20fded8914893e2ba225", "devDependencies": { "@types/debug": "^4.1.5", "@types/node": "^22.0.0", "@types/proxy-from-env": "^1", "@types/semver": "^7.1.0", "@types/which": "^3.0.0", - "@yarnpkg/eslint-config": "^3.0.0", + "@yarnpkg/eslint-config": "^3.1.1", "@yarnpkg/fslib": "^3.0.0-rc.48", "@zkochan/cmd-shim": "^6.0.0", "clipanion": "patch:clipanion@npm%3A3.2.1#~/.yarn/patches/clipanion-npm-3.2.1-fc9187f56c.patch", "debug": "^4.1.1", "esbuild": "^0.28.0", - "eslint": "^9.22.0", + "eslint": "^10.8.1", "semver": "^7.6.3", - "supports-color": "^10.0.0", + "supports-color": "^11.0.0", "tar": "^7.5.11", - "tsx": "^4.16.2", "typescript": "^5.7.3", "v8-compile-cache": "^2.3.0", "vitest": "^4.0.5", @@ -45,11 +44,11 @@ } }, "scripts": { - "build": "run clean && run build:bundle && tsx ./mkshims.ts", + "build": "run clean && run build:bundle && node ./mkshims.ts", "build:bundle": "esbuild ./sources/_lib.ts --bundle --platform=node --target=node22.22.2 --external:corepack --outfile='./dist/lib/corepack.cjs' --resolve-extensions='.ts,.mjs,.js'", "clean": "run rimraf dist shims", - "corepack": "tsx ./sources/_cli.ts", - "lint": "eslint .", + "corepack": "node ./sources/_cli.ts", + "lint": "eslint", "prepack": "yarn build", "postpack": "run clean", "rimraf": "node -e 'for(let i=2;i \ - gtest_##prefix##test_suite_name##_EvalGenerator_() { \ + gtest_##prefix##test_suite_name##_EvalGenerator_() { \ return GTEST_EXPAND_(GTEST_GET_FIRST_(__VA_ARGS__, DUMMY_PARAM_)); \ } \ static ::std::string gtest_##prefix##test_suite_name##_EvalGenerateName_( \ @@ -562,7 +562,7 @@ auto ConvertGenerator(Gen&& gen, Func&& f) { __VA_ARGS__, \ ::testing::internal::DefaultParamName, \ DUMMY_PARAM_))); \ - auto t = std::make_tuple(__VA_ARGS__); \ + const auto t = std::make_tuple(__VA_ARGS__); \ static_assert(std::tuple_size::value <= 2, \ "Too Many Args!"); \ } \ diff --git a/deps/googletest/include/gtest/gtest-printers.h b/deps/googletest/include/gtest/gtest-printers.h index 69c9fec3ca95..f647ee691263 100644 --- a/deps/googletest/include/gtest/gtest-printers.h +++ b/deps/googletest/include/gtest/gtest-printers.h @@ -522,17 +522,14 @@ inline void PrintTo(bool x, ::std::ostream* os) { GTEST_API_ void PrintTo(wchar_t wc, ::std::ostream* os); GTEST_API_ void PrintTo(char32_t c, ::std::ostream* os); -inline void PrintTo(char16_t c, ::std::ostream* os) { - // TODO(b/418738869): Incorrect for values not representing valid codepoints. - // Also see https://github.com/google/googletest/issues/4762. - PrintTo(static_cast(c), os); -} + +// Overloads for the UTF-8 and UTF-16 code unit types. A code unit that +// encodes a code point all by itself is printed with the U+XXXX notation; +// one that does not (any non-ASCII char8_t, and the UTF-16 surrogates) is +// printed as a code unit instead, the way wchar_t is. +GTEST_API_ void PrintTo(char16_t c, ::std::ostream* os); #ifdef __cpp_lib_char8_t -inline void PrintTo(char8_t c, ::std::ostream* os) { - // TODO(b/418738869): Incorrect for values not representing valid codepoints. - // Also see https://github.com/google/googletest/issues/4762. - PrintTo(static_cast(c), os); -} +GTEST_API_ void PrintTo(char8_t c, ::std::ostream* os); #endif // gcc/clang __{u,}int128_t @@ -674,12 +671,12 @@ inline void PrintTo(char32_t* s, ::std::ostream* os) { PrintTo(ImplicitCast_(s), os); } -// MSVC can be configured to define wchar_t as a typedef of unsigned -// short. It defines _NATIVE_WCHAR_T_DEFINED when wchar_t is a native -// type. When wchar_t is a typedef, defining an overload for const -// wchar_t* would cause unsigned short* be printed as a wide string, -// possibly causing invalid memory accesses. -#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) +// Only add an overload for printing wchar_t* if: +// 1. Wide string support is enabled. +// 2. wchar_t is a distinct native type. (If it's a typedef, the overload could +// cause a pointer to the underlying type to be mistakenly treated as a +// string.) +#if GTEST_HAS_STD_WSTRING && GTEST_HAS_NATIVE_WCHAR // Overloads for wide C strings GTEST_API_ void PrintTo(const wchar_t* s, ::std::ostream* os); inline void PrintTo(wchar_t* s, ::std::ostream* os) { diff --git a/deps/googletest/include/gtest/gtest.h b/deps/googletest/include/gtest/gtest.h index 089b10e9f7a9..9fe7fb44239e 100644 --- a/deps/googletest/include/gtest/gtest.h +++ b/deps/googletest/include/gtest/gtest.h @@ -71,7 +71,7 @@ #include "gtest/gtest-typed-test.h" // IWYU pragma: export #include "gtest/gtest_pred_impl.h" // IWYU pragma: export #include "gtest/gtest_prod.h" // IWYU pragma: export -#include "gtest/internal/gtest-internal.h" +#include "gtest/internal/gtest-internal.h" // IWYU pragma: export #include "gtest/internal/gtest-string.h" GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ @@ -1514,6 +1514,8 @@ GTEST_API_ AssertionResult CmpHelperSTRCASENE(const char* s1_expression, const char* s2_expression, const char* s1, const char* s2); +#if GTEST_HAS_STD_WSTRING + // Helper function for *_STREQ on wide strings. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. @@ -1528,6 +1530,8 @@ GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression, const char* s2_expression, const wchar_t* s1, const wchar_t* s2); +#endif // GTEST_HAS_STD_WSTRING + } // namespace internal // IsSubstring() and IsNotSubstring() are intended to be used as the @@ -1542,18 +1546,10 @@ GTEST_API_ AssertionResult IsSubstring(const char* needle_expr, const char* haystack_expr, const char* needle, const char* haystack); -GTEST_API_ AssertionResult IsSubstring(const char* needle_expr, - const char* haystack_expr, - const wchar_t* needle, - const wchar_t* haystack); GTEST_API_ AssertionResult IsNotSubstring(const char* needle_expr, const char* haystack_expr, const char* needle, const char* haystack); -GTEST_API_ AssertionResult IsNotSubstring(const char* needle_expr, - const char* haystack_expr, - const wchar_t* needle, - const wchar_t* haystack); GTEST_API_ AssertionResult IsSubstring(const char* needle_expr, const char* haystack_expr, const ::std::string& needle, @@ -1564,6 +1560,14 @@ GTEST_API_ AssertionResult IsNotSubstring(const char* needle_expr, const ::std::string& haystack); #if GTEST_HAS_STD_WSTRING +GTEST_API_ AssertionResult IsSubstring(const char* needle_expr, + const char* haystack_expr, + const wchar_t* needle, + const wchar_t* haystack); +GTEST_API_ AssertionResult IsNotSubstring(const char* needle_expr, + const char* haystack_expr, + const wchar_t* needle, + const wchar_t* haystack); GTEST_API_ AssertionResult IsSubstring(const char* needle_expr, const char* haystack_expr, const ::std::wstring& needle, diff --git a/deps/googletest/include/gtest/internal/gtest-internal.h b/deps/googletest/include/gtest/internal/gtest-internal.h index 55e9966720bf..f845ffed298e 100644 --- a/deps/googletest/include/gtest/internal/gtest-internal.h +++ b/deps/googletest/include/gtest/internal/gtest-internal.h @@ -39,7 +39,7 @@ #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ -#include "gtest/internal/gtest-port.h" +#include "gtest/internal/gtest-port.h" // IWYU pragma: export #ifdef GTEST_OS_LINUX #include @@ -1516,8 +1516,9 @@ class [[nodiscard]] NeverThrown { parent_class>::GetSetUpCaseOrSuite(__FILE__, __LINE__), \ ::testing::internal::SuiteApiResolver< \ parent_class>::GetTearDownCaseOrSuite(__FILE__, __LINE__), \ - new ::testing::internal::TestFactoryImpl); \ + ::std::make_unique<::testing::internal::TestFactoryImpl< \ + GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)>>() \ + .release()); \ void GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::TestBody() #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ diff --git a/deps/googletest/include/gtest/internal/gtest-port.h b/deps/googletest/include/gtest/internal/gtest-port.h index 051228553449..94a56ce3dd9b 100644 --- a/deps/googletest/include/gtest/internal/gtest-port.h +++ b/deps/googletest/include/gtest/internal/gtest-port.h @@ -500,6 +500,17 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; #endif // defined(_MSC_VER) || defined(__BORLANDC__) #endif // GTEST_HAS_EXCEPTIONS +// MSVC either defines wchar_t as a typedef of unsigned short, or as a native +// type (in which case, it defines _NATIVE_WCHAR_T_DEFINED). When wchar_t is a +// typedef, defining an overload for const wchar_t* would cause unsigned short* +// be printed as a wide string, possibly causing invalid memory accesses, so we +// omit wchar_t overloads in that case. +#if defined(_MSC_VER) && !defined(_NATIVE_WCHAR_T_DEFINED) +#define GTEST_HAS_NATIVE_WCHAR 0 +#else +#define GTEST_HAS_NATIVE_WCHAR 1 +#endif + // 1. Calculate default GTEST_HAS_STD_WSTRING values based on STL capabilities. #if defined(_MSVC_STL_VERSION) // Microsoft's STL implementation always supports ::std::wstring. @@ -2185,7 +2196,13 @@ GTEST_DISABLE_DEPRECATED_PUSH_() !defined(GTEST_OS_WINDOWS_RT) && !defined(GTEST_OS_WINDOWS_GAMES) && \ !defined(GTEST_OS_ESP8266) && !defined(GTEST_OS_XTENSA) && \ !defined(GTEST_OS_QURT) -inline int ChDir(const char* dir) { return chdir(dir); } +inline int ChDir(const char* dir) { +#ifdef GTEST_OS_WINDOWS + return _chdir(dir); +#else + return chdir(dir); +#endif +} #endif inline FILE* FOpen(const char* path, const char* mode) { #if defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_MINGW) @@ -2202,17 +2219,37 @@ inline FILE* FOpen(const char* path, const char* mode) { inline FILE* FReopen(const char* path, const char* mode, FILE* stream) { return freopen(path, mode, stream); } -inline FILE* FDOpen(int fd, const char* mode) { return fdopen(fd, mode); } +inline FILE* FDOpen(int fd, const char* mode) { +#ifdef GTEST_OS_WINDOWS + return _fdopen(fd, mode); +#else + return fdopen(fd, mode); +#endif +} #endif // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_QURT inline int FClose(FILE* fp) { return fclose(fp); } #if !defined(GTEST_OS_WINDOWS_MOBILE) && !defined(GTEST_OS_QURT) inline int Read(int fd, void* buf, unsigned int count) { +#ifdef GTEST_OS_WINDOWS + return static_cast(_read(fd, buf, count)); +#else return static_cast(read(fd, buf, count)); +#endif } inline int Write(int fd, const void* buf, unsigned int count) { +#ifdef GTEST_OS_WINDOWS + return static_cast(_write(fd, buf, count)); +#else return static_cast(write(fd, buf, count)); +#endif +} +inline int Close(int fd) { +#ifdef GTEST_OS_WINDOWS + return _close(fd); +#else + return close(fd); +#endif } -inline int Close(int fd) { return close(fd); } #endif // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_QURT #endif // GTEST_HAS_FILE_SYSTEM diff --git a/deps/googletest/src/gtest-port.cc b/deps/googletest/src/gtest-port.cc index 433586f3b711..5aa800305c7a 100644 --- a/deps/googletest/src/gtest-port.cc +++ b/deps/googletest/src/gtest-port.cc @@ -1085,7 +1085,14 @@ bool EndsWithPathSeparator(const std::string& path) { class CapturedStream { public: // The ctor redirects the stream to a temporary file. - explicit CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) { + explicit CapturedStream(int fd) + : fd_(fd), +#ifdef GTEST_OS_WINDOWS + uncaptured_fd_(_dup(fd)) +#else + uncaptured_fd_(dup(fd)) +#endif + { #ifdef GTEST_OS_WINDOWS char temp_dir_path[MAX_PATH + 1] = {'\0'}; // NOLINT char temp_file_path[MAX_PATH + 1] = {'\0'}; // NOLINT @@ -1097,7 +1104,7 @@ class CapturedStream { GTEST_CHECK_(success != 0) << "Failed to create temporary file in " << temp_dir_path << " with error " << ::GetLastError(); - const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE); + const int captured_fd = _creat(temp_file_path, _S_IREAD | _S_IWRITE); GTEST_CHECK_(captured_fd != -1) << "Failed to open temporary file " << temp_file_path << " with error " << ::GetLastError(); @@ -1167,8 +1174,12 @@ class CapturedStream { filename_ = std::move(name_template); #endif // GTEST_OS_WINDOWS fflush(nullptr); +#ifdef GTEST_OS_WINDOWS + _dup2(captured_fd, fd_); +#else dup2(captured_fd, fd_); - close(captured_fd); +#endif + posix::Close(captured_fd); } ~CapturedStream() { remove(filename_.c_str()); } @@ -1177,8 +1188,12 @@ class CapturedStream { if (uncaptured_fd_ != -1) { // Restores the original stream. fflush(nullptr); +#ifdef GTEST_OS_WINDOWS + _dup2(uncaptured_fd_, fd_); +#else dup2(uncaptured_fd_, fd_); - close(uncaptured_fd_); +#endif + posix::Close(uncaptured_fd_); uncaptured_fd_ = -1; } diff --git a/deps/googletest/src/gtest-printers.cc b/deps/googletest/src/gtest-printers.cc index 975ebb829876..17ac19f691c5 100644 --- a/deps/googletest/src/gtest-printers.cc +++ b/deps/googletest/src/gtest-printers.cc @@ -286,6 +286,28 @@ void PrintTo(char32_t c, ::std::ostream* os) { << static_cast(c); } +// char8_t and char16_t hold code units, not code points, so the U+XXXX +// notation only applies to the values that encode a code point on their own. +// The rest -- non-ASCII char8_t, which are always part of a multi-unit UTF-8 +// sequence, and the UTF-16 surrogates -- are printed as code units. +void PrintTo(char16_t c, ::std::ostream* os) { + if (c >= 0xD800 && c <= 0xDFFF) { + PrintCharAndCodeTo(c, os); + } else { + PrintTo(static_cast(c), os); + } +} + +#ifdef __cpp_lib_char8_t +void PrintTo(char8_t c, ::std::ostream* os) { + if (c >= 0x80) { + PrintCharAndCodeTo(c, os); + } else { + PrintTo(static_cast(c), os); + } +} +#endif + // gcc/clang __{u,}int128_t #if defined(__SIZEOF_INT128__) void PrintTo(__uint128_t v, ::std::ostream* os) { @@ -468,16 +490,9 @@ void PrintTo(const char16_t* s, ostream* os) { PrintCStringTo(s, os); } void PrintTo(const char32_t* s, ostream* os) { PrintCStringTo(s, os); } -// MSVC compiler can be configured to define whar_t as a typedef -// of unsigned short. Defining an overload for const wchar_t* in that case -// would cause pointers to unsigned shorts be printed as wide strings, -// possibly accessing more memory than intended and causing invalid -// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when -// wchar_t is implemented as a native type. -#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) -// Prints the given wide C string to the ostream. +#if GTEST_HAS_STD_WSTRING && GTEST_HAS_NATIVE_WCHAR void PrintTo(const wchar_t* s, ostream* os) { PrintCStringTo(s, os); } -#endif // wchar_t is native +#endif namespace { diff --git a/deps/googletest/src/gtest.cc b/deps/googletest/src/gtest.cc index 3c855468268f..30a2bb7de0bc 100644 --- a/deps/googletest/src/gtest.cc +++ b/deps/googletest/src/gtest.cc @@ -1876,11 +1876,13 @@ bool IsSubstringPred(const char* needle, const char* haystack) { return strstr(haystack, needle) != nullptr; } +#if GTEST_HAS_STD_WSTRING bool IsSubstringPred(const wchar_t* needle, const wchar_t* haystack) { if (needle == nullptr || haystack == nullptr) return needle == haystack; return wcsstr(haystack, needle) != nullptr; } +#endif // GTEST_HAS_STD_WSTRING // StringType here can be either ::std::string or ::std::wstring. template @@ -1922,23 +1924,12 @@ AssertionResult IsSubstring(const char* needle_expr, const char* haystack_expr, return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); } -AssertionResult IsSubstring(const char* needle_expr, const char* haystack_expr, - const wchar_t* needle, const wchar_t* haystack) { - return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); -} - AssertionResult IsNotSubstring(const char* needle_expr, const char* haystack_expr, const char* needle, const char* haystack) { return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); } -AssertionResult IsNotSubstring(const char* needle_expr, - const char* haystack_expr, const wchar_t* needle, - const wchar_t* haystack) { - return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); -} - AssertionResult IsSubstring(const char* needle_expr, const char* haystack_expr, const ::std::string& needle, const ::std::string& haystack) { @@ -1953,6 +1944,17 @@ AssertionResult IsNotSubstring(const char* needle_expr, } #if GTEST_HAS_STD_WSTRING +AssertionResult IsSubstring(const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring(const char* needle_expr, + const char* haystack_expr, const wchar_t* needle, + const wchar_t* haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} + AssertionResult IsSubstring(const char* needle_expr, const char* haystack_expr, const ::std::wstring& needle, const ::std::wstring& haystack) { @@ -2182,6 +2184,7 @@ bool String::WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs) { return wcscmp(lhs, rhs) == 0; } +#if GTEST_HAS_STD_WSTRING // Helper function for *_STREQ on wide strings. AssertionResult CmpHelperSTREQ(const char* lhs_expression, const char* rhs_expression, const wchar_t* lhs, @@ -2206,6 +2209,7 @@ AssertionResult CmpHelperSTRNE(const char* s1_expression, << "Expected: (" << s1_expression << ") != (" << s2_expression << "), actual: " << PrintToString(s1) << " vs " << PrintToString(s2); } +#endif // GTEST_HAS_STD_WSTRING // Compares two C strings, ignoring case. Returns true if and only if they have // the same content. diff --git a/deps/histogram/unofficial.gni b/deps/histogram/unofficial.gni index 1173ab298ae7..fd8c3a276bcb 100644 --- a/deps/histogram/unofficial.gni +++ b/deps/histogram/unofficial.gni @@ -4,29 +4,42 @@ # The actual configurations are put inside a template in unofficial.gni to # prevent accidental edits from contributors. +import("../../node.gni") + template("histogram_gn_build") { - config("histogram_config") { - include_dirs = [ "include" ] - } + if (node_shared_hdr_histogram) { + import("//build/config/linux/pkg_config.gni") + pkg_config("histogram_config") { + packages = [ "hdr_histogram" ] + } + group(target_name) { + forward_variables_from(invoker, "*") + public_configs = [ ":histogram_config" ] + } + } else { + config("histogram_config") { + include_dirs = [ "include" ] + } - gypi_values = exec_script("../../tools/gypi_to_gn.py", - [ rebase_path("histogram.gyp") ], - "scope", - [ "histogram.gyp" ]) + gypi_values = exec_script("../../tools/gypi_to_gn.py", + [ rebase_path("histogram.gyp") ], + "scope", + [ "histogram.gyp" ]) - source_set(target_name) { - forward_variables_from(invoker, "*") - public_configs = [ ":histogram_config" ] - sources = gypi_values.histogram_sources - if (is_clang || !is_win) { - cflags_c = [ - "-Wno-atomic-alignment", - "-Wno-incompatible-pointer-types", - "-Wno-unused-function", - ] - } - if (is_linux) { - libs = [ "atomic" ] + source_set(target_name) { + forward_variables_from(invoker, "*") + public_configs = [ ":histogram_config" ] + sources = gypi_values.histogram_sources + if (is_clang || !is_win) { + cflags_c = [ + "-Wno-atomic-alignment", + "-Wno-incompatible-pointer-types", + "-Wno-unused-function", + ] + } + if (is_linux) { + libs = [ "atomic" ] + } } } } diff --git a/deps/llhttp/unofficial.gni b/deps/llhttp/unofficial.gni index fdce32e59764..28257dcb33ae 100644 --- a/deps/llhttp/unofficial.gni +++ b/deps/llhttp/unofficial.gni @@ -4,26 +4,39 @@ # The actual configurations are put inside a template in unofficial.gni to # prevent accidental edits from contributors. +import("../../node.gni") + template("llhttp_gn_build") { - config("llhttp_config") { - include_dirs = [ "include" ] - } + if (node_shared_http_parser) { + import("//build/config/linux/pkg_config.gni") + pkg_config("llhttp_config") { + packages = [ "libllhttp" ] + } + group(target_name) { + forward_variables_from(invoker, "*") + public_configs = [ ":llhttp_config" ] + } + } else { + config("llhttp_config") { + include_dirs = [ "include" ] + } - gypi_values = exec_script("../../tools/gypi_to_gn.py", - [ rebase_path("llhttp.gyp") ], - "scope", - [ "llhttp.gyp" ]) + gypi_values = exec_script("../../tools/gypi_to_gn.py", + [ rebase_path("llhttp.gyp") ], + "scope", + [ "llhttp.gyp" ]) - source_set(target_name) { - forward_variables_from(invoker, "*") - public_configs = [ ":llhttp_config" ] - include_dirs = [ "include" ] - sources = gypi_values.llhttp_sources - if (is_clang || !is_win) { - cflags_c = [ - "-Wno-implicit-fallthrough", - "-Wno-unreachable-code", - ] + source_set(target_name) { + forward_variables_from(invoker, "*") + public_configs = [ ":llhttp_config" ] + include_dirs = [ "include" ] + sources = gypi_values.llhttp_sources + if (is_clang || !is_win) { + cflags_c = [ + "-Wno-implicit-fallthrough", + "-Wno-unreachable-code", + ] + } } } } diff --git a/deps/ncrypto/ncrypto.cc b/deps/ncrypto/ncrypto.cc index fb7446578f57..20f22e614525 100644 --- a/deps/ncrypto/ncrypto.cc +++ b/deps/ncrypto/ncrypto.cc @@ -14,9 +14,11 @@ #endif #include #include +#include #include #include #include +#include #if OPENSSL_VERSION_MAJOR >= 3 #include #include @@ -129,6 +131,31 @@ struct OpenSSLBufferDeleter { }; using OpenSSLBufferPointer = std::unique_ptr; + +struct RsaOtherPrimeParamNames { + const char* factor; + const char* exponent; + const char* coefficient; +}; + +#define RSA_OTHER_PRIME_PARAM_NAMES(prime, coefficient) \ + { \ + OSSL_PKEY_PARAM_RSA_FACTOR #prime, OSSL_PKEY_PARAM_RSA_EXPONENT #prime, \ + OSSL_PKEY_PARAM_RSA_COEFFICIENT #coefficient \ + } + +constexpr std::array kRsaOtherPrimeParamNames = {{ + RSA_OTHER_PRIME_PARAM_NAMES(3, 2), + RSA_OTHER_PRIME_PARAM_NAMES(4, 3), + RSA_OTHER_PRIME_PARAM_NAMES(5, 4), + RSA_OTHER_PRIME_PARAM_NAMES(6, 5), + RSA_OTHER_PRIME_PARAM_NAMES(7, 6), + RSA_OTHER_PRIME_PARAM_NAMES(8, 7), + RSA_OTHER_PRIME_PARAM_NAMES(9, 8), + RSA_OTHER_PRIME_PARAM_NAMES(10, 9), +}}; + +#undef RSA_OTHER_PRIME_PARAM_NAMES #endif static constexpr int kX509NameFlagsRFC2253WithinUtf8JSON = @@ -507,23 +534,43 @@ DataPointer DataPointer::resize(size_t len) { } // ============================================================================ -bool isFipsEnabled() { - ClearErrorOnReturn clear_error_on_return; +namespace { +// This generation only coordinates cache invalidation. It does not make +// OpenSSL default property changes safe to race with crypto operations. +std::atomic fips_state_generation{0}; + +bool isFipsEnabledRaw() { #if OPENSSL_VERSION_MAJOR >= 3 return EVP_default_properties_is_fips_enabled(nullptr) == 1; #else return FIPS_mode() == 1; #endif } +} // namespace + +bool isFipsEnabled() { + ClearErrorOnReturn clear_error_on_return; + return isFipsEnabledRaw(); +} bool setFipsEnabled(bool enable, CryptoErrorList* errors) { - if (isFipsEnabled() == enable) return true; + const bool was_enabled = isFipsEnabled(); + if (was_enabled == enable) return true; ClearErrorOnReturn clearErrorOnReturn(errors); #if OPENSSL_VERSION_MAJOR >= 3 - return EVP_default_properties_enable_fips(nullptr, enable ? 1 : 0) == 1; + const bool success = + EVP_default_properties_enable_fips(nullptr, enable ? 1 : 0) == 1; #else - return FIPS_mode_set(enable ? 1 : 0) == 1; + const bool success = FIPS_mode_set(enable ? 1 : 0) == 1; #endif + if (success && isFipsEnabledRaw() != was_enabled) { + fips_state_generation.fetch_add(1, std::memory_order_release); + } + return success; +} + +uint64_t getFipsStateGeneration() { + return fips_state_generation.load(std::memory_order_acquire); } bool testFipsEnabled() { @@ -3060,6 +3107,19 @@ EVPKeyPointer EVPKeyPointer::NewRSA(const Rsa& rsa) { bld.get(), OSSL_PKEY_PARAM_RSA_COEFFICIENT1, private_key.qi) != 1) { return {}; } + + const auto other_prime_infos = rsa.getOtherPrimeInfos(); + if (other_prime_infos.size() > kRsaOtherPrimeParamNames.size()) return {}; + for (size_t i = 0; i < other_prime_infos.size(); i++) { + const auto& info = other_prime_infos[i]; + const auto& names = kRsaOtherPrimeParamNames[i]; + if (info.r == nullptr || info.d == nullptr || info.t == nullptr || + OSSL_PARAM_BLD_push_BN(bld.get(), names.factor, info.r) != 1 || + OSSL_PARAM_BLD_push_BN(bld.get(), names.exponent, info.d) != 1 || + OSSL_PARAM_BLD_push_BN(bld.get(), names.coefficient, info.t) != 1) { + return {}; + } + } selection = EVP_PKEY_KEYPAIR; } @@ -4406,13 +4466,211 @@ bool SSLCtxPointer::setCipherSuites(const char* ciphers) { // ============================================================================ -#if OPENSSL_WITH_AES_SIV || OPENSSL_WITH_AES_GCM_SIV +namespace { +constexpr char AsciiToLower(char c) { + return c >= 'A' && c <= 'Z' ? c + ('a' - 'A') : c; +} + +#if NCRYPTO_USE_OPENSSL3_PROVIDER +constexpr auto kUnsupportedCipherFlags = + EVP_CIPH_FLAG_CIPHER_WITH_MAC | EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK; + +bool HasUnsupportedCipherFlags(const EVP_CIPHER* cipher) { + return (EVP_CIPHER_get_flags(cipher) & kUnsupportedCipherFlags) != 0; +} + +bool IsSupportedLegacyCipher(const EVP_CIPHER* cipher) { + return cipher != nullptr && cipher != EVP_enc_null() && + !HasUnsupportedCipherFlags(cipher); +} + +bool IsSupportedFetchedCipher(const EVP_CIPHER* cipher) { + if (cipher == nullptr || EVP_CIPHER_is_a(cipher, "NULL") || + HasUnsupportedCipherFlags(cipher)) { + return false; + } + +#ifdef OSSL_CIPHER_PARAM_ENCRYPT_THEN_MAC + int encrypt_then_mac = 0; + OSSL_PARAM params[] = { + OSSL_PARAM_construct_int(OSSL_CIPHER_PARAM_ENCRYPT_THEN_MAC, + &encrypt_then_mac), + OSSL_PARAM_construct_end(), + }; + if (EVP_CIPHER_get_params(const_cast(cipher), params) == 1 && + encrypt_then_mac != 0) { + return false; + } +#endif + + return true; +} + +void PushAlgorithmAlias(const char* name, void* arg) { + if (name == nullptr) return; + static_cast*>(arg)->emplace_back(name); +} +#endif +} // namespace + +#if NCRYPTO_USE_OPENSSL3_PROVIDER Cipher::Cipher(DeleteFnPtr cipher) : cipher_(cipher.get()), fetched_cipher_(std::move(cipher)) {} #endif +size_t CaseInsensitiveNameHash::operator()( + std::string_view name) const noexcept { + size_t hash = 5381; + for (char c : name) hash = ((hash << 5) + hash) ^ AsciiToLower(c); + return hash; +} + +bool CaseInsensitiveNameEqual::operator()(std::string_view lhs, + std::string_view rhs) const noexcept { + if (lhs.size() != rhs.size()) return false; + for (size_t n = 0; n < lhs.size(); n++) { + if (AsciiToLower(lhs[n]) != AsciiToLower(rhs[n])) return false; + } + return true; +} + +DigestCache::Result DigestCache::lookup(const char* name, + uint64_t generation) const { +#if NCRYPTO_USE_OPENSSL3_PROVIDER + if (generation_ != generation) return {}; + const auto it = aliases_.find(name); + if (it == aliases_.end()) return {}; + return lookup(it->second, generation); +#else + static_cast(name); + static_cast(generation); + return {}; +#endif +} + +DigestCache::Result DigestCache::insert(const char* name, + const EVP_MD* digest, + uint64_t generation) { +#if NCRYPTO_USE_OPENSSL3_PROVIDER + if (generation_ != generation || name == nullptr || digest == nullptr) { + return {}; + } + + const char* canonical_name = EVP_MD_get0_name(digest); + const OSSL_PROVIDER* provider = EVP_MD_get0_provider(digest); + if (canonical_name == nullptr || provider == nullptr) return {}; + + for (size_t index = 0; index < digests_.size(); index++) { + const EVP_MD* cached = digests_[index].get(); + if (cached == nullptr) continue; + const char* cached_name = EVP_MD_get0_name(cached); + if (EVP_MD_get0_provider(cached) == provider && cached_name != nullptr && + CaseInsensitiveNameEqual()(cached_name, canonical_name)) { + const int32_t id = static_cast(first_id_ + index); + aliases_.insert_or_assign(name, id); + return {cached, id}; + } + } + + if (next_id_ == UINT32_MAX || + EVP_MD_up_ref(const_cast(digest)) != 1) { + return {}; + } + + digests_.emplace_back(const_cast(digest)); + const int32_t id = static_cast(next_id_++); + const size_t index = digests_.size() - 1; + + std::vector aliases; + EVP_MD_names_do_all(digests_[index].get(), PushAlgorithmAlias, &aliases); + for (const std::string& alias : aliases) aliases_.emplace(alias, id); + aliases_.insert_or_assign(name, id); + + return {digests_[index].get(), id}; +#else + static_cast(name); + static_cast(digest); + static_cast(generation); + return {}; +#endif +} + +void DigestCache::reset(uint64_t generation) { +#if NCRYPTO_USE_OPENSSL3_PROVIDER + if (generation_ == generation) return; + aliases_.clear(); + digests_.clear(); + first_id_ = next_id_; +#endif + generation_ = generation; +} + +const DigestCache::AliasMap& DigestCache::aliases() const { +#if NCRYPTO_USE_OPENSSL3_PROVIDER + return aliases_; +#else + static const AliasMap empty; + return empty; +#endif +} + +const EVP_CIPHER* CipherCache::lookup(const char* name, uint64_t generation) { +#if NCRYPTO_USE_OPENSSL3_PROVIDER + if (generation_ != generation) { + aliases_.clear(); + ciphers_.clear(); + generation_ = generation; + } + + const auto it = aliases_.find(name); + if (it == aliases_.end()) return nullptr; + if (it->second >= ciphers_.size()) return nullptr; + return ciphers_[it->second].get(); +#else + static_cast(name); + static_cast(generation); + return nullptr; +#endif +} + +#if NCRYPTO_USE_OPENSSL3_PROVIDER +const EVP_CIPHER* CipherCache::insert( + const char* name, + DeleteFnPtr&& cipher, + uint64_t generation) { + if (generation_ != generation || cipher == nullptr) return nullptr; + + const char* canonical_name = EVP_CIPHER_get0_name(cipher.get()); + const OSSL_PROVIDER* provider = EVP_CIPHER_get0_provider(cipher.get()); + if (canonical_name != nullptr && provider != nullptr) { + for (size_t id = 0; id < ciphers_.size(); id++) { + const EVP_CIPHER* cached = ciphers_[id].get(); + const char* cached_name = EVP_CIPHER_get0_name(cached); + if (EVP_CIPHER_get0_provider(cached) == provider && + cached_name != nullptr && + CaseInsensitiveNameEqual()(cached_name, canonical_name)) { + aliases_.insert_or_assign(name, id); + return cached; + } + } + } + + ciphers_.emplace_back(std::move(cipher)); + const size_t id = ciphers_.size() - 1; + + std::vector aliases; + EVP_CIPHER_names_do_all(ciphers_[id].get(), PushAlgorithmAlias, &aliases); + for (const std::string& alias : aliases) { + aliases_.emplace(alias, id); + } + aliases_.insert_or_assign(name, id); + + return ciphers_[id].get(); +} +#endif + Cipher::Cipher(const Cipher& other) : cipher_(other.cipher_) { -#if OPENSSL_WITH_AES_SIV || OPENSSL_WITH_AES_GCM_SIV +#if NCRYPTO_USE_OPENSSL3_PROVIDER if (other.fetched_cipher_ != nullptr) { if (EVP_CIPHER_up_ref(other.fetched_cipher_.get()) == 1) { fetched_cipher_.reset(other.fetched_cipher_.get()); @@ -4425,7 +4683,7 @@ Cipher::Cipher(const Cipher& other) : cipher_(other.cipher_) { Cipher& Cipher::operator=(const Cipher& other) { if (this == &other) return *this; -#if OPENSSL_WITH_AES_SIV || OPENSSL_WITH_AES_GCM_SIV +#if NCRYPTO_USE_OPENSSL3_PROVIDER if (other.fetched_cipher_ != nullptr) { if (EVP_CIPHER_up_ref(other.fetched_cipher_.get()) == 1) { fetched_cipher_.reset(other.fetched_cipher_.get()); @@ -4442,40 +4700,59 @@ Cipher& Cipher::operator=(const Cipher& other) { return *this; } -const Cipher Cipher::FromName(const char* name) { +const Cipher Cipher::FromName(const char* name, CipherCache* cache) { const EVP_CIPHER* cipher = EVP_get_cipherbyname(name); - if (cipher != nullptr) return Cipher(cipher); + if (cipher != nullptr) { +#if NCRYPTO_USE_OPENSSL3_PROVIDER + if (!IsSupportedLegacyCipher(cipher)) return Cipher(); +#endif + return Cipher(cipher); + } + +#if NCRYPTO_USE_OPENSSL3_PROVIDER + // A resolution that overlaps a FIPS transition may use either property + // state. The cache retains the generation observed here, so the first + // resolution begun after the transition clears any stale entries. + const uint64_t generation = getFipsStateGeneration(); + if (cache != nullptr) { + if (const EVP_CIPHER* cached = cache->lookup(name, generation)) { + return Cipher(cached); + } + } -#if OPENSSL_WITH_AES_SIV || OPENSSL_WITH_AES_GCM_SIV MarkPopErrorOnReturn mark_pop_error_on_return; DeleteFnPtr fetched( EVP_CIPHER_fetch(nullptr, name, nullptr)); - if (fetched == nullptr) return Cipher(); + if (!IsSupportedFetchedCipher(fetched.get())) return Cipher(); - const int mode = EVP_CIPHER_mode(fetched.get()); - const bool is_siv_mode = -#if OPENSSL_WITH_AES_SIV - mode == EVP_CIPH_SIV_MODE || -#endif -#if OPENSSL_WITH_AES_GCM_SIV - mode == EVP_CIPH_GCM_SIV_MODE || -#endif - false; - if (is_siv_mode) return Cipher(std::move(fetched)); + if (cache != nullptr && generation == getFipsStateGeneration()) { + if (const EVP_CIPHER* cached = + cache->insert(name, std::move(fetched), generation)) { + return Cipher(cached); + } + } - return Cipher(); + return Cipher(std::move(fetched)); #else + static_cast(cache); return Cipher(); #endif } -const Cipher Cipher::FromNid(int nid) { +const Cipher Cipher::FromNid(int nid, CipherCache* cache) { const EVP_CIPHER* cipher = EVP_get_cipherbynid(nid); - if (cipher != nullptr) return Cipher(cipher); + if (cipher != nullptr) { +#if NCRYPTO_USE_OPENSSL3_PROVIDER + if (!IsSupportedLegacyCipher(cipher)) return Cipher(); +#endif + return Cipher(cipher); + } -#if OPENSSL_WITH_AES_SIV || OPENSSL_WITH_AES_GCM_SIV +#if NCRYPTO_USE_OPENSSL3_PROVIDER const char* name = OBJ_nid2sn(nid); - if (name != nullptr) return FromName(name); + if (name != nullptr) return FromName(name, cache); +#else + static_cast(cache); #endif return Cipher(); @@ -4485,27 +4762,79 @@ const Cipher Cipher::FromCtx(const CipherCtxPointer& ctx) { return Cipher(GetCipherCtxCipher(ctx.get())); } -const Cipher Cipher::EMPTY = Cipher(); -const Cipher Cipher::AES_128_CBC = Cipher::FromNid(NID_aes_128_cbc); -const Cipher Cipher::AES_192_CBC = Cipher::FromNid(NID_aes_192_cbc); -const Cipher Cipher::AES_256_CBC = Cipher::FromNid(NID_aes_256_cbc); -const Cipher Cipher::AES_128_CTR = Cipher::FromNid(NID_aes_128_ctr); -const Cipher Cipher::AES_192_CTR = Cipher::FromNid(NID_aes_192_ctr); -const Cipher Cipher::AES_256_CTR = Cipher::FromNid(NID_aes_256_ctr); -const Cipher Cipher::AES_128_GCM = Cipher::FromNid(NID_aes_128_gcm); -const Cipher Cipher::AES_192_GCM = Cipher::FromNid(NID_aes_192_gcm); -const Cipher Cipher::AES_256_GCM = Cipher::FromNid(NID_aes_256_gcm); -const Cipher Cipher::AES_128_KW = Cipher::FromNid(NID_id_aes128_wrap); -const Cipher Cipher::AES_192_KW = Cipher::FromNid(NID_id_aes192_wrap); -const Cipher Cipher::AES_256_KW = Cipher::FromNid(NID_id_aes256_wrap); +namespace { +template +const Cipher& GetPredefinedCipher() { + static const Cipher cipher = Cipher::FromNid(nid); + return cipher; +} +} // namespace + +const Cipher& Cipher::AES_128_CBC() { + return GetPredefinedCipher(); +} + +const Cipher& Cipher::AES_192_CBC() { + return GetPredefinedCipher(); +} + +const Cipher& Cipher::AES_256_CBC() { + return GetPredefinedCipher(); +} + +const Cipher& Cipher::AES_128_CTR() { + return GetPredefinedCipher(); +} + +const Cipher& Cipher::AES_192_CTR() { + return GetPredefinedCipher(); +} + +const Cipher& Cipher::AES_256_CTR() { + return GetPredefinedCipher(); +} + +const Cipher& Cipher::AES_128_GCM() { + return GetPredefinedCipher(); +} + +const Cipher& Cipher::AES_192_GCM() { + return GetPredefinedCipher(); +} + +const Cipher& Cipher::AES_256_GCM() { + return GetPredefinedCipher(); +} + +const Cipher& Cipher::AES_128_KW() { + return GetPredefinedCipher(); +} + +const Cipher& Cipher::AES_192_KW() { + return GetPredefinedCipher(); +} + +const Cipher& Cipher::AES_256_KW() { + return GetPredefinedCipher(); +} #ifndef OPENSSL_IS_BORINGSSL -const Cipher Cipher::AES_128_OCB = Cipher::FromNid(NID_aes_128_ocb); -const Cipher Cipher::AES_192_OCB = Cipher::FromNid(NID_aes_192_ocb); -const Cipher Cipher::AES_256_OCB = Cipher::FromNid(NID_aes_256_ocb); +const Cipher& Cipher::AES_128_OCB() { + return GetPredefinedCipher(); +} + +const Cipher& Cipher::AES_192_OCB() { + return GetPredefinedCipher(); +} + +const Cipher& Cipher::AES_256_OCB() { + return GetPredefinedCipher(); +} #endif -const Cipher Cipher::CHACHA20_POLY1305 = Cipher::FromNid(NID_chacha20_poly1305); +const Cipher& Cipher::CHACHA20_POLY1305() { + return GetPredefinedCipher(); +} bool Cipher::isGcmMode() const { if (!cipher_) return false; @@ -4527,6 +4856,15 @@ bool Cipher::isCcmMode() const { return getMode() == EVP_CIPH_CCM_MODE; } +bool Cipher::isCtsMode() const { + if (!cipher_) return false; +#if NCRYPTO_USE_OPENSSL3_PROVIDER + return (EVP_CIPHER_get_flags(cipher_) & EVP_CIPH_FLAG_CTS) != 0; +#else + return false; +#endif +} + bool Cipher::isOcbMode() const { if (!cipher_) return false; return getMode() == EVP_CIPH_OCB_MODE; @@ -4631,7 +4969,7 @@ const char* Cipher::getName() const { const char* name = OBJ_nid2sn(nid); if (name != nullptr) return name; } -#if OPENSSL_WITH_AES_SIV || OPENSSL_WITH_AES_GCM_SIV +#if NCRYPTO_USE_OPENSSL3_PROVIDER return EVP_CIPHER_get0_name(cipher_); #else return {}; @@ -4728,11 +5066,57 @@ bool CipherCtxPointer::setAeadTagLength(size_t length) { ctx_.get(), EVP_CTRL_AEAD_SET_TAG, length, nullptr); } +#if NCRYPTO_USE_OPENSSL3_PROVIDER +namespace { +// OSSL_CIPHER_PARAM_XTS_STANDARD is not defined by OpenSSL 3.0. Use its +// parameter name directly so custom 3.0 providers can advertise it too. +constexpr char kCipherParamXtsStandard[] = "xts_standard"; + +bool SetCipherCtxStringParam(EVP_CIPHER_CTX* ctx, + const char* key, + const char* value) { + if (ctx == nullptr || value == nullptr) return false; + + const OSSL_PARAM* settable = EVP_CIPHER_CTX_settable_params(ctx); + const OSSL_PARAM* descriptor = + settable == nullptr ? nullptr : OSSL_PARAM_locate_const(settable, key); + if (descriptor == nullptr || + descriptor->data_type != OSSL_PARAM_UTF8_STRING) { + return false; + } + + OSSL_PARAM params[] = { + OSSL_PARAM_construct_utf8_string(key, const_cast(value), 0), + OSSL_PARAM_END, + }; + return EVP_CIPHER_CTX_set_params(ctx, params) == 1; +} +} // namespace +#endif + +bool CipherCtxPointer::setCtsMode(const char* mode) { +#if NCRYPTO_USE_OPENSSL3_PROVIDER + return SetCipherCtxStringParam(ctx_.get(), OSSL_CIPHER_PARAM_CTS_MODE, mode); +#else + static_cast(mode); + return false; +#endif +} + bool CipherCtxPointer::setPadding(bool padding) { if (!ctx_) return false; return EVP_CIPHER_CTX_set_padding(ctx_.get(), padding); } +bool CipherCtxPointer::setXtsStandard(const char* standard) { +#if NCRYPTO_USE_OPENSSL3_PROVIDER + return SetCipherCtxStringParam(ctx_.get(), kCipherParamXtsStandard, standard); +#else + static_cast(standard); + return false; +#endif +} + int CipherCtxPointer::getBlockSize() const { if (!ctx_) return 0; return EVP_CIPHER_CTX_block_size(ctx_.get()); @@ -4758,6 +5142,16 @@ bool CipherCtxPointer::isCcmMode() const { return getMode() == EVP_CIPH_CCM_MODE; } +bool CipherCtxPointer::isCtsMode() const { + if (!ctx_) return false; + return Cipher::FromCtx(*this).isCtsMode(); +} + +bool CipherCtxPointer::isXtsMode() const { + if (!ctx_) return false; + return getMode() == EVP_CIPH_XTS_MODE; +} + bool CipherCtxPointer::isWrapMode() const { if (!ctx_) return false; return getMode() == EVP_CIPH_WRAP_MODE; @@ -5779,6 +6173,11 @@ DataPointer CipherImpl(const EVPKeyPointer& key, } } // namespace +Rsa::OtherPrimeInfoPointer::OtherPrimeInfoPointer(BignumPointer&& r, + BignumPointer&& d, + BignumPointer&& t) + : r(r.release()), d(d.release()), t(t.release()) {} + #if NCRYPTO_USE_OPENSSL3_PROVIDER namespace { int DigestAlgorithmIdentifierToNid(const unsigned char* data, size_t size) { @@ -6007,6 +6406,19 @@ Rsa::Rsa(const EVP_PKEY* pkey) : Rsa() { return; } + for (const auto& names : kRsaOtherPrimeParamNames) { + OtherPrimeInfoPointer info; + if (!GetOptionalPKeyBnParam(pkey, names.factor, &info.r) || + !GetOptionalPKeyBnParam(pkey, names.exponent, &info.d) || + !GetOptionalPKeyBnParam(pkey, names.coefficient, &info.t)) { + return; + } + + if (!info.r && !info.d && !info.t) break; + if (!info.r || !info.d || !info.t) return; + other_prime_infos_.push_back(std::move(info)); + } + if (type == EVP_PKEY_RSA_PSS) { MarkPopErrorOnReturn pop_errors; PssParams params; @@ -6045,6 +6457,35 @@ const Rsa::PrivateKey Rsa::getPrivateKey() const { #endif } +const Rsa::OtherPrimeInfos Rsa::getOtherPrimeInfos() const { + OtherPrimeInfos infos; +#if NCRYPTO_USE_OPENSSL3_PROVIDER + infos.reserve(other_prime_infos_.size()); + for (const auto& info : other_prime_infos_) { + infos.push_back({info.r.get(), info.d.get(), info.t.get()}); + } +#elif NCRYPTO_USE_LEGACY_OPENSSL + if (rsa_ == nullptr) return infos; + const int count = RSA_get_multi_prime_extra_count(rsa_); + if (count <= 0) return infos; + + std::vector factors(count); + std::vector exponents(count); + std::vector coefficients(count); + if (RSA_get0_multi_prime_factors(rsa_, factors.data()) != 1 || + RSA_get0_multi_prime_crt_params( + rsa_, exponents.data(), coefficients.data()) != 1) { + return {}; + } + + infos.reserve(count); + for (int i = 0; i < count; i++) { + infos.push_back({factors[i], exponents[i], coefficients[i]}); + } +#endif + return infos; +} + const std::optional Rsa::getPssParams() const { #if NCRYPTO_USE_OPENSSL3_PROVIDER return pss_params_; @@ -6146,15 +6587,20 @@ bool Rsa::setPrivateKey(BignumPointer&& d, BignumPointer&& p, BignumPointer&& dp, BignumPointer&& dq, - BignumPointer&& qi) { + BignumPointer&& qi, + OtherPrimeInfoPointers&& other_prime_infos) { #if NCRYPTO_USE_OPENSSL3_PROVIDER if (!d || !q || !p || !dp || !dq || !qi) return false; + for (const auto& info : other_prime_infos) { + if (!info.r || !info.d || !info.t) return false; + } d_.reset(d.release()); q_.reset(q.release()); p_.reset(p.release()); dp_.reset(dp.release()); dq_.reset(dq.release()); qi_.reset(qi.release()); + other_prime_infos_ = std::move(other_prime_infos); rsa_ = n_ != nullptr && e_ != nullptr; return rsa_; #else @@ -6176,6 +6622,37 @@ bool Rsa::setPrivateKey(BignumPointer&& d, dp.release(); dq.release(); qi.release(); + +#if NCRYPTO_USE_LEGACY_OPENSSL + if (!other_prime_infos.empty()) { + std::vector factors; + std::vector exponents; + std::vector coefficients; + factors.reserve(other_prime_infos.size()); + exponents.reserve(other_prime_infos.size()); + coefficients.reserve(other_prime_infos.size()); + for (const auto& info : other_prime_infos) { + if (!info.r || !info.d || !info.t) return false; + factors.push_back(info.r.get()); + exponents.push_back(info.d.get()); + coefficients.push_back(info.t.get()); + } + if (RSA_set0_multi_prime_params(const_cast(rsa_), + factors.data(), + exponents.data(), + coefficients.data(), + static_cast(factors.size())) != 1) { + return false; + } + for (auto& info : other_prime_infos) { + info.r.release(); + info.d.release(); + info.t.release(); + } + } +#else + if (!other_prime_infos.empty()) return false; +#endif return true; #endif } @@ -6229,23 +6706,7 @@ struct CipherCallbackContext { void operator()(const char* name) { cb(name); } }; -#if OPENSSL_WITH_AES_SIV -constexpr const char* kProviderOnlyAesSivCiphers[] = { - "aes-128-siv", - "aes-192-siv", - "aes-256-siv", -}; -#endif - -#if OPENSSL_WITH_AES_GCM_SIV -constexpr const char* kProviderOnlyAesGcmSivCiphers[] = { - "aes-128-gcm-siv", - "aes-192-gcm-siv", - "aes-256-gcm-siv", -}; -#endif - -#if OPENSSL_VERSION_MAJOR >= 3 +#if NCRYPTO_USE_OPENSSL3_PROVIDER template fetched( + fetch_type(nullptr, real_name, nullptr)); + if (!IsSupportedFetchedCipher(fetched.get())) return; - free_type(fetched); auto& cb = *(static_cast(arg)); cb(from); } + +void array_push_back_provider_name(const char* name, void* arg) { + if (name == nullptr) return; + + const std::string_view name_view(name); + const bool is_dotted_decimal = + name_view.find('.') != std::string_view::npos && + std::all_of(name_view.begin(), name_view.end(), [](unsigned char c) { + return (c >= '0' && c <= '9') || c == '.'; + }); + if (is_dotted_decimal) return; + + std::string normalized_name(name_view); + std::transform(normalized_name.begin(), + normalized_name.end(), + normalized_name.begin(), + [](unsigned char c) { + if (c >= 'A' && c <= 'Z') { + return static_cast(c + ('a' - 'A')); + } + return static_cast(c); + }); + auto& cb = *(static_cast(arg)); + cb(normalized_name.c_str()); +} + +void array_push_back_provider(EVP_CIPHER* cipher, void* arg) { + const char* name = EVP_CIPHER_get0_name(cipher); + if (name == nullptr) return; + + DeleteFnPtr fetched( + EVP_CIPHER_fetch(nullptr, name, nullptr)); + if (!IsSupportedFetchedCipher(fetched.get())) return; + + EVP_CIPHER_names_do_all(fetched.get(), array_push_back_provider_name, arg); +} #else template void array_push_back(const TypeName* evp_ref, @@ -6301,7 +6798,7 @@ void Cipher::ForEach(Cipher::CipherNameCallback callback) { } #else EVP_CIPHER_do_all_sorted( -#if OPENSSL_VERSION_MAJOR >= 3 +#if NCRYPTO_USE_OPENSSL3_PROVIDER array_push_back, #endif &context); -#if OPENSSL_WITH_AES_SIV || OPENSSL_WITH_AES_GCM_SIV - auto maybe_push_provider_only_cipher = [&](const char* name) { - EVP_CIPHER* cipher = EVP_CIPHER_fetch(nullptr, name, nullptr); - if (cipher == nullptr) return; - EVP_CIPHER_free(cipher); - context.cb(name); - }; -#endif -#if OPENSSL_WITH_AES_SIV - for (const char* name : kProviderOnlyAesSivCiphers) { - maybe_push_provider_only_cipher(name); - } -#endif -#if OPENSSL_WITH_AES_GCM_SIV - for (const char* name : kProviderOnlyAesGcmSivCiphers) { - maybe_push_provider_only_cipher(name); - } +#if NCRYPTO_USE_OPENSSL3_PROVIDER + EVP_CIPHER_do_all_provided(nullptr, array_push_back_provider, &context); #endif #endif } @@ -6479,11 +6961,19 @@ EVP_MD_CTX* EVPMDCtxPointer::release() { return ctx_.release(); } -bool EVPMDCtxPointer::digestInit(const Digest& digest) { +bool EVPMDCtxPointer::digestInit(const EVP_MD* digest) { if (!ctx_) return false; return EVP_DigestInit_ex(ctx_.get(), digest, nullptr) > 0; } +#if !defined(OPENSSL_IS_BORINGSSL) && OPENSSL_VERSION_PREREQ(4, 0) +bool EVPMDCtxPointer::digestInit(const EVP_MD* digest, + const OSSL_PARAM* params) { + if (!ctx_) return false; + return EVP_DigestInit_ex2(ctx_.get(), digest, params) > 0; +} +#endif + bool EVPMDCtxPointer::digestUpdate(const Buffer& in) { if (!ctx_) return false; return EVP_DigestUpdate(ctx_.get(), in.data, in.len) > 0; @@ -6832,6 +7322,79 @@ EVPMacPointer EVPMacPointer::Fetch(const char* algorithm) { return EVPMacPointer(EVP_MAC_fetch(nullptr, algorithm, nullptr)); } +MacKind MacCache::GetKind(EVP_MAC* mac) { + if (EVP_MAC_is_a(mac, OSSL_MAC_NAME_HMAC)) return MacKind::kHmac; + if (EVP_MAC_is_a(mac, OSSL_MAC_NAME_CMAC)) return MacKind::kCmac; + if (EVP_MAC_is_a(mac, OSSL_MAC_NAME_GMAC)) return MacKind::kGmac; + return MacKind::kOther; +} + +MacCache::Result MacCache::lookup(const char* name, uint64_t generation) const { + if (generation_ != generation || name == nullptr) return {}; + const auto it = aliases_.find(name); + if (it == aliases_.end()) return {}; + return lookup(it->second, generation); +} + +MacCache::Result MacCache::insert(const char* name, + EVPMacPointer&& mac, + uint64_t generation) { + if (generation_ != generation || generation != getFipsStateGeneration() || + name == nullptr || mac == nullptr) { + return {}; + } + + const char* canonical_name = EVP_MAC_get0_name(mac.get()); + const OSSL_PROVIDER* provider = EVP_MAC_get0_provider(mac.get()); + if (canonical_name == nullptr || provider == nullptr) return {}; + + for (size_t index = 0; index < macs_.size(); index++) { + EVP_MAC* cached = macs_[index].mac.get(); + if (cached == nullptr) continue; + const char* cached_name = EVP_MAC_get0_name(cached); + if (EVP_MAC_get0_provider(cached) == provider && cached_name != nullptr && + CaseInsensitiveNameEqual()(cached_name, canonical_name)) { + if (generation != getFipsStateGeneration()) return {}; + const int32_t id = static_cast(first_id_ + index); + aliases_.insert_or_assign(name, id); + return {cached, id, macs_[index].kind}; + } + } + + if (next_id_ == UINT32_MAX) return {}; + + std::vector aliases; + { + MarkPopErrorOnReturn mark_pop_error_on_return; + if (EVP_MAC_names_do_all(mac.get(), PushAlgorithmAlias, &aliases) != 1) { + return {}; + } + } + if (generation != getFipsStateGeneration()) return {}; + + const MacKind kind = GetKind(mac.get()); + macs_.push_back({std::move(mac), kind}); + const int32_t id = static_cast(next_id_++); + const size_t index = macs_.size() - 1; + + for (const std::string& alias : aliases) aliases_.emplace(alias, id); + aliases_.insert_or_assign(name, id); + + return {macs_[index].mac.get(), id, kind}; +} + +void MacCache::reset(uint64_t generation) { + if (generation_ == generation) return; + aliases_.clear(); + macs_.clear(); + first_id_ = next_id_; + generation_ = generation; +} + +const MacCache::AliasMap& MacCache::aliases() const { + return aliases_; +} + EVPMacCtxPointer::EVPMacCtxPointer(EVP_MAC_CTX* ctx) : ctx_(ctx) {} EVPMacCtxPointer::EVPMacCtxPointer(EVPMacCtxPointer&& other) noexcept @@ -6859,22 +7422,42 @@ EVP_MAC_CTX* EVPMacCtxPointer::release() { bool EVPMacCtxPointer::init(const Buffer& key, const OSSL_PARAM* params) { if (!ctx_) return false; - return EVP_MAC_init(ctx_.get(), - static_cast(key.data), - key.len, - params) == 1; + + static constexpr unsigned char kEmptyKey = 0; + const unsigned char* key_data = static_cast(key.data); + if (key_data == nullptr) { + if (key.len != 0) return false; + key_data = &kEmptyKey; + } + + return EVP_MAC_init(ctx_.get(), key_data, key.len, params) == 1; } bool EVPMacCtxPointer::update(const Buffer& data) { if (!ctx_) return false; + if (data.len == 0) return true; + if (data.data == nullptr) return false; return EVP_MAC_update(ctx_.get(), static_cast(data.data), data.len) == 1; } +size_t EVPMacCtxPointer::getSize() const { + return ctx_ ? EVP_MAC_CTX_get_mac_size(ctx_.get()) : 0; +} + +const OSSL_PARAM* EVPMacCtxPointer::getSettableParams() const { + return ctx_ ? EVP_MAC_CTX_settable_params(ctx_.get()) : nullptr; +} + DataPointer EVPMacCtxPointer::final(size_t length) { if (!ctx_) return {}; - auto buf = DataPointer::Alloc(length); + + // DataPointer uses a null allocation to represent failure. Retain a + // one-byte allocation for a successful zero-length result while passing the + // requested zero capacity to OpenSSL. A non-null output pointer is required + // to actually finalize; nullptr only queries the output length. + auto buf = DataPointer::Alloc(length == 0 ? 1 : length); if (!buf) return {}; size_t result_len = length; @@ -6884,8 +7467,9 @@ DataPointer EVPMacCtxPointer::final(size_t length) { length) != 1) { return {}; } + if (result_len > length) return {}; - return buf; + return buf.resize(result_len); } EVPMacCtxPointer EVPMacCtxPointer::New(EVP_MAC* mac) { @@ -7009,7 +7593,10 @@ DataPointer xofHashDigest(const Buffer& buf, if (ctx.digestInit(md) != 1) { return {}; } - if (ctx.digestUpdate(reinterpret_cast&>(buf)) != 1) { + if (ctx.digestUpdate(Buffer{ + .data = buf.data, + .len = buf.len, + }) != 1) { return {}; } return ctx.digestFinal(output_length); @@ -7145,14 +7732,86 @@ size_t Digest::size() const { return EVP_MD_size(md_); } +#if NCRYPTO_USE_OPENSSL3_PROVIDER +Digest::Digest(DeleteFnPtr md) + : md_(md.get()), fetched_md_(std::move(md)) {} +#endif + +Digest::Digest(const Digest& other) : md_(other.md_) { +#if NCRYPTO_USE_OPENSSL3_PROVIDER + if (other.fetched_md_ != nullptr) { + if (EVP_MD_up_ref(other.fetched_md_.get()) == 1) { + fetched_md_.reset(other.fetched_md_.get()); + } else { + md_ = nullptr; + } + } +#endif +} + +Digest& Digest::operator=(const Digest& other) { + if (this == &other) return *this; +#if NCRYPTO_USE_OPENSSL3_PROVIDER + if (other.fetched_md_ != nullptr) { + if (EVP_MD_up_ref(other.fetched_md_.get()) == 1) { + fetched_md_.reset(other.fetched_md_.get()); + } else { + fetched_md_.reset(); + md_ = nullptr; + return *this; + } + } else { + fetched_md_.reset(); + } +#endif + md_ = other.md_; + return *this; +} + const Digest Digest::MD5 = Digest(EVP_md5()); const Digest Digest::SHA1 = Digest(EVP_sha1()); const Digest Digest::SHA256 = Digest(EVP_sha256()); const Digest Digest::SHA384 = Digest(EVP_sha384()); const Digest Digest::SHA512 = Digest(EVP_sha512()); +#if NCRYPTO_USE_OPENSSL3_PROVIDER +namespace { +bool IsSupportedDigest(const EVP_MD* md) { + if (md == nullptr || EVP_MD_is_a(md, "NULL")) return false; + + // OpenSSL currently crashes when ML-DSA-MU finalizes an empty input. Keep it + // unavailable until the provider implementation is fixed. + // https://github.com/openssl/openssl/issues/32445 + if (EVP_MD_is_a(md, "ML-DSA-MU")) return false; + + return true; +} +} // namespace +#endif + const Digest Digest::FromName(const char* name) { - return ncrypto::getDigestByName(name); + const EVP_MD* md = ncrypto::getDigestByName(name); + if (md != nullptr) { +#if NCRYPTO_USE_OPENSSL3_PROVIDER + if (md == EVP_md_null()) return Digest(); +#endif + return Digest(md); + } + + return Fetch(name); +} + +const Digest Digest::Fetch(const char* name) { +#if NCRYPTO_USE_OPENSSL3_PROVIDER + MarkPopErrorOnReturn mark_pop_error_on_return; + DeleteFnPtr fetched( + EVP_MD_fetch(nullptr, name, nullptr)); + if (IsSupportedDigest(fetched.get())) { + return Digest(std::move(fetched)); + } +#endif + + return Digest(); } // ============================================================================ diff --git a/deps/ncrypto/ncrypto.h b/deps/ncrypto/ncrypto.h index 58e32cc18fc7..6b1edceed061 100644 --- a/deps/ncrypto/ncrypto.h +++ b/deps/ncrypto/ncrypto.h @@ -13,12 +13,15 @@ #include #include #include +#include #include #include #include #include #include #include +#include +#include #if defined(NCRYPTO_ENGINE_COMPAT) && NCRYPTO_ENGINE_COMPAT && \ !defined(OPENSSL_NO_ENGINE) #include @@ -363,6 +366,7 @@ class DataPointer; class DHPointer; class ECKeyPointer; class EVPKeyPointer; +class MacCache; class EVPMacCtxPointer; class EVPMacPointer; class EVPMDCtxPointer; @@ -397,9 +401,12 @@ class Digest final { static constexpr size_t MAX_SIZE = EVP_MAX_MD_SIZE; Digest() = default; Digest(const EVP_MD* md) : md_(md) {} - Digest(const Digest&) = default; - Digest& operator=(const Digest&) = default; + Digest(const Digest& other); + Digest& operator=(const Digest& other); inline Digest& operator=(const EVP_MD* md) { +#if NCRYPTO_USE_OPENSSL3_PROVIDER + fetched_md_.reset(); +#endif md_ = md; return *this; } @@ -418,9 +425,72 @@ class Digest final { static const Digest SHA512; static const Digest FromName(const char* name); + static const Digest Fetch(const char* name); private: const EVP_MD* md_ = nullptr; +#if NCRYPTO_USE_OPENSSL3_PROVIDER + explicit Digest(DeleteFnPtr md); + DeleteFnPtr fetched_md_; +#endif +}; + +struct CaseInsensitiveNameHash { + using is_transparent = void; + size_t operator()(std::string_view name) const noexcept; +}; + +struct CaseInsensitiveNameEqual { + using is_transparent = void; + bool operator()(std::string_view lhs, std::string_view rhs) const noexcept; +}; + +class DigestCache final { + public: + struct Result { + const EVP_MD* digest = nullptr; + int32_t id = -1; + }; + + using AliasMap = std::unordered_map; + + DigestCache() = default; + NCRYPTO_DISALLOW_COPY_AND_MOVE(DigestCache) + + Result lookup(const char* name, uint64_t generation) const; + inline Result lookup(int32_t id, uint64_t generation) const { +#if NCRYPTO_USE_OPENSSL3_PROVIDER + if (generation_ != generation || id == -1) return {}; + const uint32_t unsigned_id = static_cast(id); + if (unsigned_id < first_id_) return {}; + const size_t index = unsigned_id - first_id_; + if (index >= digests_.size()) return {}; + return {digests_[index].get(), id}; +#else + static_cast(id); + static_cast(generation); + return {}; +#endif + } + Result insert(const char* name, const EVP_MD* digest, uint64_t generation); + void reset(uint64_t generation); + const AliasMap& aliases() const; + + private: + uint64_t generation_ = 0; +#if NCRYPTO_USE_OPENSSL3_PROVIDER + using EVPMDPointer = DeleteFnPtr; + + // IDs are not reused across generations because JavaScript caches them + // independently in each Realm. + uint32_t first_id_ = 0; + uint32_t next_id_ = 0; + std::vector digests_; + AliasMap aliases_; +#endif }; // Computes a fixed-length digest. @@ -431,6 +501,32 @@ DataPointer xofHashDigest(const Buffer& data, const EVP_MD* md, size_t length); +class CipherCache final { + public: + CipherCache() = default; + NCRYPTO_DISALLOW_COPY_AND_MOVE(CipherCache) + + const EVP_CIPHER* lookup(const char* name, uint64_t generation); +#if NCRYPTO_USE_OPENSSL3_PROVIDER + const EVP_CIPHER* insert(const char* name, + DeleteFnPtr&& cipher, + uint64_t generation); +#endif + + private: +#if NCRYPTO_USE_OPENSSL3_PROVIDER + using EVPCipherPointer = DeleteFnPtr; + + uint64_t generation_ = 0; + std::vector ciphers_; + std::unordered_map + aliases_; +#endif +}; + class Cipher final { public: static constexpr size_t MAX_KEY_LENGTH = EVP_MAX_KEY_LENGTH; @@ -452,7 +548,7 @@ class Cipher final { Cipher(const Cipher& other); Cipher& operator=(const Cipher& other); inline Cipher& operator=(const EVP_CIPHER* cipher) { -#if OPENSSL_WITH_AES_SIV || OPENSSL_WITH_AES_GCM_SIV +#if NCRYPTO_USE_OPENSSL3_PROVIDER fetched_cipher_.reset(); #endif cipher_ = cipher; @@ -476,6 +572,7 @@ class Cipher final { bool isWrapMode() const; bool isCtrMode() const; bool isCcmMode() const; + bool isCtsMode() const; bool isOcbMode() const; bool isSivMode() const; bool isGcmSivMode() const; @@ -489,8 +586,8 @@ class Cipher final { unsigned char* key, unsigned char* iv) const; - static const Cipher FromName(const char* name); - static const Cipher FromNid(int nid); + static const Cipher FromName(const char* name, CipherCache* cache = nullptr); + static const Cipher FromNid(int nid, CipherCache* cache = nullptr); static const Cipher FromCtx(const CipherCtxPointer& ctx); using CipherNameCallback = std::function; @@ -499,28 +596,24 @@ class Cipher final { // is able to do so. static void ForEach(CipherNameCallback callback); - // Utilities to get various ciphers by type. If the underlying - // implementation does not support the requested cipher, then - // the result will be an empty Cipher object whose bool operator - // will return false. - - static const Cipher EMPTY; - static const Cipher AES_128_CBC; - static const Cipher AES_192_CBC; - static const Cipher AES_256_CBC; - static const Cipher AES_128_CTR; - static const Cipher AES_192_CTR; - static const Cipher AES_256_CTR; - static const Cipher AES_128_GCM; - static const Cipher AES_192_GCM; - static const Cipher AES_256_GCM; - static const Cipher AES_128_KW; - static const Cipher AES_192_KW; - static const Cipher AES_256_KW; - static const Cipher AES_128_OCB; - static const Cipher AES_192_OCB; - static const Cipher AES_256_OCB; - static const Cipher CHACHA20_POLY1305; + // Lazily resolves common ciphers. If the underlying implementation does not + // support the requested cipher, the returned Cipher will be empty. + static const Cipher& AES_128_CBC(); + static const Cipher& AES_192_CBC(); + static const Cipher& AES_256_CBC(); + static const Cipher& AES_128_CTR(); + static const Cipher& AES_192_CTR(); + static const Cipher& AES_256_CTR(); + static const Cipher& AES_128_GCM(); + static const Cipher& AES_192_GCM(); + static const Cipher& AES_256_GCM(); + static const Cipher& AES_128_KW(); + static const Cipher& AES_192_KW(); + static const Cipher& AES_256_KW(); + static const Cipher& AES_128_OCB(); + static const Cipher& AES_192_OCB(); + static const Cipher& AES_256_OCB(); + static const Cipher& CHACHA20_POLY1305(); struct CipherParams { int padding; @@ -550,7 +643,7 @@ class Cipher final { private: const EVP_CIPHER* cipher_ = nullptr; -#if OPENSSL_WITH_AES_SIV || OPENSSL_WITH_AES_GCM_SIV +#if NCRYPTO_USE_OPENSSL3_PROVIDER explicit Cipher(DeleteFnPtr cipher); DeleteFnPtr fetched_cipher_; #endif @@ -631,6 +724,23 @@ class Rsa final { const BIGNUM* dq; const BIGNUM* qi; }; + struct OtherPrimeInfo { + const BIGNUM* r; + const BIGNUM* d; + const BIGNUM* t; + }; + struct OtherPrimeInfoPointer { + OtherPrimeInfoPointer() = default; + OtherPrimeInfoPointer(BignumPointer&& r, + BignumPointer&& d, + BignumPointer&& t); + + DeleteFnPtr r; + DeleteFnPtr d; + DeleteFnPtr t; + }; + using OtherPrimeInfos = std::vector; + using OtherPrimeInfoPointers = std::vector; struct PssParams { std::string_view digest = "sha1"; std::optional mgf1_digest = "sha1"; @@ -639,6 +749,7 @@ class Rsa final { const PublicKey getPublicKey() const; const PrivateKey getPrivateKey() const; + const OtherPrimeInfos getOtherPrimeInfos() const; const std::optional getPssParams() const; bool setPublicKey(BignumPointer&& n, BignumPointer&& e); @@ -647,7 +758,8 @@ class Rsa final { BignumPointer&& p, BignumPointer&& dp, BignumPointer&& dq, - BignumPointer&& qi); + BignumPointer&& qi, + OtherPrimeInfoPointers&& other_prime_infos = {}); using CipherParams = Cipher::CipherParams; @@ -672,6 +784,7 @@ class Rsa final { DeleteFnPtr dp_; DeleteFnPtr dq_; DeleteFnPtr qi_; + OtherPrimeInfoPointers other_prime_infos_; std::optional pss_params_; #else OSSL3_CONST RSA* rsa_; @@ -940,7 +1053,9 @@ class CipherCtxPointer final { bool setIvLength(size_t length); bool setAeadTag(const Buffer& tag); bool setAeadTagLength(size_t length); + bool setCtsMode(const char* mode); bool setPadding(bool padding); + bool setXtsStandard(const char* standard); bool init(const Cipher& cipher, bool encrypt, const unsigned char* key = nullptr, @@ -953,6 +1068,8 @@ class CipherCtxPointer final { bool isGcmMode() const; bool isOcbMode() const; bool isCcmMode() const; + bool isCtsMode() const; + bool isXtsMode() const; bool isWrapMode() const; bool isSivMode() const; bool isGcmSivMode() const; @@ -1690,7 +1807,16 @@ class EVPMDCtxPointer final { void reset(EVP_MD_CTX* ctx = nullptr); EVP_MD_CTX* release(); - bool digestInit(const Digest& digest); + bool digestInit(const EVP_MD* digest); + inline bool digestInit(const Digest& digest) { + return digestInit(digest.get()); + } +#if !defined(OPENSSL_IS_BORINGSSL) && OPENSSL_VERSION_PREREQ(4, 0) + bool digestInit(const EVP_MD* digest, const OSSL_PARAM* params); + inline bool digestInit(const Digest& digest, const OSSL_PARAM* params) { + return digestInit(digest.get(), params); + } +#endif bool digestUpdate(const Buffer& in); DataPointer digestFinal(size_t length); bool digestFinalInto(Buffer* buf); @@ -1782,6 +1908,61 @@ class EVPMacPointer final { DeleteFnPtr mac_; }; +enum class MacKind : uint8_t { + kOther, + kHmac, + kCmac, + kGmac, +}; + +class MacCache final { + public: + struct Result { + // Borrowed from the cache and valid until the cache is reset. Creating an + // EVP_MAC_CTX takes an independent reference to the method. + EVP_MAC* mac = nullptr; + int32_t id = -1; + MacKind kind = MacKind::kOther; + }; + + using AliasMap = std::unordered_map; + + MacCache() = default; + NCRYPTO_DISALLOW_COPY_AND_MOVE(MacCache) + + Result lookup(const char* name, uint64_t generation) const; + inline Result lookup(int32_t id, uint64_t generation) const { + if (generation_ != generation || id == -1) return {}; + const uint32_t unsigned_id = static_cast(id); + if (unsigned_id < first_id_) return {}; + const size_t index = unsigned_id - first_id_; + if (index >= macs_.size()) return {}; + return {macs_[index].mac.get(), id, macs_[index].kind}; + } + Result insert(const char* name, EVPMacPointer&& mac, uint64_t generation); + void reset(uint64_t generation); + const AliasMap& aliases() const; + static MacKind GetKind(EVP_MAC* mac); + + private: + struct Entry { + EVPMacPointer mac; + MacKind kind; + }; + + uint64_t generation_ = 0; + + // IDs are not reused across generations because JavaScript may cache them + // independently in each Realm. + uint32_t first_id_ = 0; + uint32_t next_id_ = 0; + std::vector macs_; + AliasMap aliases_; +}; + class EVPMacCtxPointer final { public: EVPMacCtxPointer() = default; @@ -1800,6 +1981,8 @@ class EVPMacCtxPointer final { bool init(const Buffer& key, const OSSL_PARAM* params = nullptr); bool update(const Buffer& data); + size_t getSize() const; + const OSSL_PARAM* getSettableParams() const; DataPointer final(size_t length); static EVPMacCtxPointer New(EVP_MAC* mac); @@ -1836,6 +2019,14 @@ class HMACCtxPointer final { }; #endif // OPENSSL_WITH_EVP_MAC +#if !OPENSSL_WITH_EVP_MAC +class MacCache final { + public: + MacCache() = default; + NCRYPTO_DISALLOW_COPY_AND_MOVE(MacCache) +}; +#endif + #ifndef OPENSSL_NO_ENGINE class EnginePointer final { public: @@ -1880,6 +2071,8 @@ bool isFipsEnabled(); bool setFipsEnabled(bool enabled, CryptoErrorList* errors); +uint64_t getFipsStateGeneration(); + bool testFipsEnabled(); // ============================================================================ diff --git a/deps/nghttp2/unofficial.gni b/deps/nghttp2/unofficial.gni index 4558fbbf5e5f..d37754f59124 100644 --- a/deps/nghttp2/unofficial.gni +++ b/deps/nghttp2/unofficial.gni @@ -4,40 +4,53 @@ # The actual configurations are put inside a template in unofficial.gni to # prevent accidental edits from contributors. +import("../../node.gni") + template("nghttp2_gn_build") { - config("nghttp2_config") { - include_dirs = [ "lib/includes" ] - if (!is_component_build) { - defines = [ "NGHTTP2_STATICLIB" ] + if (node_shared_nghttp2) { + import("//build/config/linux/pkg_config.gni") + pkg_config("nghttp2_config") { + packages = [ "libnghttp2" ] + } + group(target_name) { + forward_variables_from(invoker, "*") + public_configs = [ ":nghttp2_config" ] + } + } else { + config("nghttp2_config") { + include_dirs = [ "lib/includes" ] + if (!is_component_build) { + defines = [ "NGHTTP2_STATICLIB" ] + } } - } - gypi_values = exec_script("../../tools/gypi_to_gn.py", - [ rebase_path("nghttp2.gyp") ], - "scope", - [ "nghttp2.gyp" ]) + gypi_values = exec_script("../../tools/gypi_to_gn.py", + [ rebase_path("nghttp2.gyp") ], + "scope", + [ "nghttp2.gyp" ]) - component(target_name) { - forward_variables_from(invoker, "*") + component(target_name) { + forward_variables_from(invoker, "*") - public_configs = [ ":nghttp2_config" ] - defines = [ - "_U_", - "HAVE_CONFIG_H" - ] - if (is_component_build) { - defines += [ "BUILDING_NGHTTP2" ] - } + public_configs = [ ":nghttp2_config" ] + defines = [ + "_U_", + "HAVE_CONFIG_H" + ] + if (is_component_build) { + defines += [ "BUILDING_NGHTTP2" ] + } - sources = gypi_values.nghttp2_sources + sources = gypi_values.nghttp2_sources - if (is_clang || !is_win) { - cflags_c = [ - "-Wno-implicit-fallthrough", - # Ref https://github.com/nghttp2/nghttp2/pull/2258 - # This can be removed when the above PR is ingested. - "-Wno-extra-semi", - ] + if (is_clang || !is_win) { + cflags_c = [ + "-Wno-implicit-fallthrough", + # Ref https://github.com/nghttp2/nghttp2/pull/2258 + # This can be removed when the above PR is ingested. + "-Wno-extra-semi", + ] + } } } } diff --git a/deps/npm/docs/content/commands/npm-ls.md b/deps/npm/docs/content/commands/npm-ls.md index 24746c173b7c..b38603c203fc 100644 --- a/deps/npm/docs/content/commands/npm-ls.md +++ b/deps/npm/docs/content/commands/npm-ls.md @@ -23,7 +23,7 @@ Note that nested packages will *also* show the paths to the specified packages. For example, running `npm ls promzard` in npm's source tree will show: ```bash -npm@11.19.0 /path/to/npm +npm@11.19.1 /path/to/npm └─┬ init-package-json@0.0.4 └── promzard@0.1.5 ``` diff --git a/deps/npm/docs/content/commands/npm.md b/deps/npm/docs/content/commands/npm.md index 769bb262064e..75157bd7b598 100644 --- a/deps/npm/docs/content/commands/npm.md +++ b/deps/npm/docs/content/commands/npm.md @@ -14,7 +14,7 @@ Note: This command is unaware of workspaces. ### Version -11.19.0 +11.19.1 ### Description diff --git a/deps/npm/docs/output/commands/npm-access.html b/deps/npm/docs/output/commands/npm-access.html index 2a044ef5ed59..ac6df64b960b 100644 --- a/deps/npm/docs/output/commands/npm-access.html +++ b/deps/npm/docs/output/commands/npm-access.html @@ -186,9 +186,9 @@
-

+

npm-access - @11.19.0 + @11.19.1

Set access level on published packages
diff --git a/deps/npm/docs/output/commands/npm-adduser.html b/deps/npm/docs/output/commands/npm-adduser.html index c59e21d94298..29aec6314e96 100644 --- a/deps/npm/docs/output/commands/npm-adduser.html +++ b/deps/npm/docs/output/commands/npm-adduser.html @@ -186,9 +186,9 @@
-

+

npm-adduser - @11.19.0 + @11.19.1

Add a registry user account
diff --git a/deps/npm/docs/output/commands/npm-approve-scripts.html b/deps/npm/docs/output/commands/npm-approve-scripts.html index 55c9db2b2a2b..3d61cc8ea23a 100644 --- a/deps/npm/docs/output/commands/npm-approve-scripts.html +++ b/deps/npm/docs/output/commands/npm-approve-scripts.html @@ -186,9 +186,9 @@
-

+

npm-approve-scripts - @11.19.0 + @11.19.1

Approve install scripts for specific dependencies
diff --git a/deps/npm/docs/output/commands/npm-audit.html b/deps/npm/docs/output/commands/npm-audit.html index 438891b03cbc..9117faa9bed5 100644 --- a/deps/npm/docs/output/commands/npm-audit.html +++ b/deps/npm/docs/output/commands/npm-audit.html @@ -186,9 +186,9 @@
-

+

npm-audit - @11.19.0 + @11.19.1

Run a security audit
diff --git a/deps/npm/docs/output/commands/npm-bugs.html b/deps/npm/docs/output/commands/npm-bugs.html index eb7a91c9457f..63f4c29210a2 100644 --- a/deps/npm/docs/output/commands/npm-bugs.html +++ b/deps/npm/docs/output/commands/npm-bugs.html @@ -186,9 +186,9 @@
-

+

npm-bugs - @11.19.0 + @11.19.1

Report bugs for a package in a web browser
diff --git a/deps/npm/docs/output/commands/npm-cache.html b/deps/npm/docs/output/commands/npm-cache.html index 374878c8d04e..3377b00cc56c 100644 --- a/deps/npm/docs/output/commands/npm-cache.html +++ b/deps/npm/docs/output/commands/npm-cache.html @@ -186,9 +186,9 @@
-

+

npm-cache - @11.19.0 + @11.19.1

Manipulates packages cache
diff --git a/deps/npm/docs/output/commands/npm-ci.html b/deps/npm/docs/output/commands/npm-ci.html index 0a91d5159b12..edde5bbdef66 100644 --- a/deps/npm/docs/output/commands/npm-ci.html +++ b/deps/npm/docs/output/commands/npm-ci.html @@ -186,9 +186,9 @@
-

+

npm-ci - @11.19.0 + @11.19.1

Clean install a project
diff --git a/deps/npm/docs/output/commands/npm-completion.html b/deps/npm/docs/output/commands/npm-completion.html index dc927a82868a..b5a6f445d451 100644 --- a/deps/npm/docs/output/commands/npm-completion.html +++ b/deps/npm/docs/output/commands/npm-completion.html @@ -186,9 +186,9 @@
-

+

npm-completion - @11.19.0 + @11.19.1

Tab Completion for npm
diff --git a/deps/npm/docs/output/commands/npm-config.html b/deps/npm/docs/output/commands/npm-config.html index 5b4e3e1204bc..c9ea9080cf78 100644 --- a/deps/npm/docs/output/commands/npm-config.html +++ b/deps/npm/docs/output/commands/npm-config.html @@ -186,9 +186,9 @@
-

+

npm-config - @11.19.0 + @11.19.1

Manage the npm configuration files
diff --git a/deps/npm/docs/output/commands/npm-dedupe.html b/deps/npm/docs/output/commands/npm-dedupe.html index 0f08ae285737..abe4a229e77c 100644 --- a/deps/npm/docs/output/commands/npm-dedupe.html +++ b/deps/npm/docs/output/commands/npm-dedupe.html @@ -186,9 +186,9 @@
-

+

npm-dedupe - @11.19.0 + @11.19.1

Reduce duplication in the package tree
diff --git a/deps/npm/docs/output/commands/npm-deny-scripts.html b/deps/npm/docs/output/commands/npm-deny-scripts.html index 8b82b3684feb..3a56f32dc977 100644 --- a/deps/npm/docs/output/commands/npm-deny-scripts.html +++ b/deps/npm/docs/output/commands/npm-deny-scripts.html @@ -186,9 +186,9 @@
-

+

npm-deny-scripts - @11.19.0 + @11.19.1

Deny install scripts for specific dependencies
diff --git a/deps/npm/docs/output/commands/npm-deprecate.html b/deps/npm/docs/output/commands/npm-deprecate.html index 489345c280bc..90f45466cad9 100644 --- a/deps/npm/docs/output/commands/npm-deprecate.html +++ b/deps/npm/docs/output/commands/npm-deprecate.html @@ -186,9 +186,9 @@
-

+

npm-deprecate - @11.19.0 + @11.19.1

Deprecate a version of a package
diff --git a/deps/npm/docs/output/commands/npm-diff.html b/deps/npm/docs/output/commands/npm-diff.html index 3bb3d244a198..fba245e3b33a 100644 --- a/deps/npm/docs/output/commands/npm-diff.html +++ b/deps/npm/docs/output/commands/npm-diff.html @@ -186,9 +186,9 @@
-

+

npm-diff - @11.19.0 + @11.19.1

The registry diff command
diff --git a/deps/npm/docs/output/commands/npm-dist-tag.html b/deps/npm/docs/output/commands/npm-dist-tag.html index 9f3aafdf4314..2d42ee8e3e84 100644 --- a/deps/npm/docs/output/commands/npm-dist-tag.html +++ b/deps/npm/docs/output/commands/npm-dist-tag.html @@ -186,9 +186,9 @@
-

+

npm-dist-tag - @11.19.0 + @11.19.1

Modify package distribution tags
diff --git a/deps/npm/docs/output/commands/npm-docs.html b/deps/npm/docs/output/commands/npm-docs.html index fbdd0ad2b626..98295c7943e0 100644 --- a/deps/npm/docs/output/commands/npm-docs.html +++ b/deps/npm/docs/output/commands/npm-docs.html @@ -186,9 +186,9 @@
-

+

npm-docs - @11.19.0 + @11.19.1

Open documentation for a package in a web browser
diff --git a/deps/npm/docs/output/commands/npm-doctor.html b/deps/npm/docs/output/commands/npm-doctor.html index b7dc5d2caf84..096f12bf3b80 100644 --- a/deps/npm/docs/output/commands/npm-doctor.html +++ b/deps/npm/docs/output/commands/npm-doctor.html @@ -186,9 +186,9 @@
-

+

npm-doctor - @11.19.0 + @11.19.1

Check the health of your npm environment
diff --git a/deps/npm/docs/output/commands/npm-edit.html b/deps/npm/docs/output/commands/npm-edit.html index 3aed53c2677a..7a555a8f39a4 100644 --- a/deps/npm/docs/output/commands/npm-edit.html +++ b/deps/npm/docs/output/commands/npm-edit.html @@ -186,9 +186,9 @@
-

+

npm-edit - @11.19.0 + @11.19.1

Edit an installed package
diff --git a/deps/npm/docs/output/commands/npm-exec.html b/deps/npm/docs/output/commands/npm-exec.html index a5ea0d54c343..94e8e68c05f1 100644 --- a/deps/npm/docs/output/commands/npm-exec.html +++ b/deps/npm/docs/output/commands/npm-exec.html @@ -186,9 +186,9 @@
-

+

npm-exec - @11.19.0 + @11.19.1

Run a command from a local or remote npm package
diff --git a/deps/npm/docs/output/commands/npm-explain.html b/deps/npm/docs/output/commands/npm-explain.html index bce1694bcf08..ccf68b227121 100644 --- a/deps/npm/docs/output/commands/npm-explain.html +++ b/deps/npm/docs/output/commands/npm-explain.html @@ -186,9 +186,9 @@
-

+

npm-explain - @11.19.0 + @11.19.1

Explain installed packages
diff --git a/deps/npm/docs/output/commands/npm-explore.html b/deps/npm/docs/output/commands/npm-explore.html index 872892c9f1d5..7b4d6a2ed2c4 100644 --- a/deps/npm/docs/output/commands/npm-explore.html +++ b/deps/npm/docs/output/commands/npm-explore.html @@ -186,9 +186,9 @@
-

+

npm-explore - @11.19.0 + @11.19.1

Browse an installed package
diff --git a/deps/npm/docs/output/commands/npm-find-dupes.html b/deps/npm/docs/output/commands/npm-find-dupes.html index b71cbeb015db..19b5ae4ffcfa 100644 --- a/deps/npm/docs/output/commands/npm-find-dupes.html +++ b/deps/npm/docs/output/commands/npm-find-dupes.html @@ -186,9 +186,9 @@
-

+

npm-find-dupes - @11.19.0 + @11.19.1

Find duplication in the package tree
diff --git a/deps/npm/docs/output/commands/npm-fund.html b/deps/npm/docs/output/commands/npm-fund.html index 9f04fd7ea66b..c657d182afd3 100644 --- a/deps/npm/docs/output/commands/npm-fund.html +++ b/deps/npm/docs/output/commands/npm-fund.html @@ -186,9 +186,9 @@
-

+

npm-fund - @11.19.0 + @11.19.1

Retrieve funding information
diff --git a/deps/npm/docs/output/commands/npm-get.html b/deps/npm/docs/output/commands/npm-get.html index 94a56fd4a81b..59eaf5e577cb 100644 --- a/deps/npm/docs/output/commands/npm-get.html +++ b/deps/npm/docs/output/commands/npm-get.html @@ -186,9 +186,9 @@
-

+

npm-get - @11.19.0 + @11.19.1

Get a value from the npm configuration
diff --git a/deps/npm/docs/output/commands/npm-help-search.html b/deps/npm/docs/output/commands/npm-help-search.html index d3666992d1e9..d4abfb29c360 100644 --- a/deps/npm/docs/output/commands/npm-help-search.html +++ b/deps/npm/docs/output/commands/npm-help-search.html @@ -186,9 +186,9 @@
-

+

npm-help-search - @11.19.0 + @11.19.1

Search npm help documentation
diff --git a/deps/npm/docs/output/commands/npm-help.html b/deps/npm/docs/output/commands/npm-help.html index e7fa1b32e601..d4fe535e8bd0 100644 --- a/deps/npm/docs/output/commands/npm-help.html +++ b/deps/npm/docs/output/commands/npm-help.html @@ -186,9 +186,9 @@
-

+

npm-help - @11.19.0 + @11.19.1

Get help on npm
diff --git a/deps/npm/docs/output/commands/npm-init.html b/deps/npm/docs/output/commands/npm-init.html index 265ee78ad2cf..af686f90a7ac 100644 --- a/deps/npm/docs/output/commands/npm-init.html +++ b/deps/npm/docs/output/commands/npm-init.html @@ -186,9 +186,9 @@
-

+

npm-init - @11.19.0 + @11.19.1

Create a package.json file
diff --git a/deps/npm/docs/output/commands/npm-install-ci-test.html b/deps/npm/docs/output/commands/npm-install-ci-test.html index 94d4e4a663b8..bdf779e2eef8 100644 --- a/deps/npm/docs/output/commands/npm-install-ci-test.html +++ b/deps/npm/docs/output/commands/npm-install-ci-test.html @@ -186,9 +186,9 @@
-

+

npm-install-ci-test - @11.19.0 + @11.19.1

Install a project with a clean slate and run tests
diff --git a/deps/npm/docs/output/commands/npm-install-scripts.html b/deps/npm/docs/output/commands/npm-install-scripts.html index d78f5efc1653..8174e90a5094 100644 --- a/deps/npm/docs/output/commands/npm-install-scripts.html +++ b/deps/npm/docs/output/commands/npm-install-scripts.html @@ -186,9 +186,9 @@
-

+

npm-install-scripts - @11.19.0 + @11.19.1

Manage install-script approvals for dependencies
diff --git a/deps/npm/docs/output/commands/npm-install-test.html b/deps/npm/docs/output/commands/npm-install-test.html index c55b06547a9d..e75fb52d3239 100644 --- a/deps/npm/docs/output/commands/npm-install-test.html +++ b/deps/npm/docs/output/commands/npm-install-test.html @@ -186,9 +186,9 @@
-

+

npm-install-test - @11.19.0 + @11.19.1

Install package(s) and run tests
diff --git a/deps/npm/docs/output/commands/npm-install.html b/deps/npm/docs/output/commands/npm-install.html index 80af90cc3db9..ed78f6576bb7 100644 --- a/deps/npm/docs/output/commands/npm-install.html +++ b/deps/npm/docs/output/commands/npm-install.html @@ -186,9 +186,9 @@
-

+

npm-install - @11.19.0 + @11.19.1

Install a package
diff --git a/deps/npm/docs/output/commands/npm-link.html b/deps/npm/docs/output/commands/npm-link.html index 3a5795b866f5..aa01ff7a259a 100644 --- a/deps/npm/docs/output/commands/npm-link.html +++ b/deps/npm/docs/output/commands/npm-link.html @@ -186,9 +186,9 @@
-

+

npm-link - @11.19.0 + @11.19.1

Symlink a package folder
diff --git a/deps/npm/docs/output/commands/npm-ll.html b/deps/npm/docs/output/commands/npm-ll.html index 601f99e91029..f8df2515bfa4 100644 --- a/deps/npm/docs/output/commands/npm-ll.html +++ b/deps/npm/docs/output/commands/npm-ll.html @@ -186,9 +186,9 @@
-

+

npm-ll - @11.19.0 + @11.19.1

List installed packages
diff --git a/deps/npm/docs/output/commands/npm-login.html b/deps/npm/docs/output/commands/npm-login.html index 33d44e488838..1c6d938ec6c1 100644 --- a/deps/npm/docs/output/commands/npm-login.html +++ b/deps/npm/docs/output/commands/npm-login.html @@ -186,9 +186,9 @@
-

+

npm-login - @11.19.0 + @11.19.1

Login to a registry user account
diff --git a/deps/npm/docs/output/commands/npm-logout.html b/deps/npm/docs/output/commands/npm-logout.html index 0be803c18ae7..cf319a086f89 100644 --- a/deps/npm/docs/output/commands/npm-logout.html +++ b/deps/npm/docs/output/commands/npm-logout.html @@ -186,9 +186,9 @@
-

+

npm-logout - @11.19.0 + @11.19.1

Log out of the registry
diff --git a/deps/npm/docs/output/commands/npm-ls.html b/deps/npm/docs/output/commands/npm-ls.html index bda454a04c77..b733762be373 100644 --- a/deps/npm/docs/output/commands/npm-ls.html +++ b/deps/npm/docs/output/commands/npm-ls.html @@ -186,9 +186,9 @@
-

+

npm-ls - @11.19.0 + @11.19.1

List installed packages
@@ -209,7 +209,7 @@

Description

Positional arguments are name@version-range identifiers, which will limit the results to only the paths to the packages named. Note that nested packages will also show the paths to the specified packages. For example, running npm ls promzard in npm's source tree will show:

-
npm@11.19.0 /path/to/npm
+
npm@11.19.1 /path/to/npm
 └─┬ init-package-json@0.0.4
   └── promzard@0.1.5
 
diff --git a/deps/npm/docs/output/commands/npm-org.html b/deps/npm/docs/output/commands/npm-org.html index 32df155d69ce..6a2c22951a60 100644 --- a/deps/npm/docs/output/commands/npm-org.html +++ b/deps/npm/docs/output/commands/npm-org.html @@ -186,9 +186,9 @@
-

+

npm-org - @11.19.0 + @11.19.1

Manage orgs
diff --git a/deps/npm/docs/output/commands/npm-outdated.html b/deps/npm/docs/output/commands/npm-outdated.html index 5355d7dd09aa..b85880371cdf 100644 --- a/deps/npm/docs/output/commands/npm-outdated.html +++ b/deps/npm/docs/output/commands/npm-outdated.html @@ -186,9 +186,9 @@
-

+

npm-outdated - @11.19.0 + @11.19.1

Check for outdated packages
diff --git a/deps/npm/docs/output/commands/npm-owner.html b/deps/npm/docs/output/commands/npm-owner.html index 7dc17627f50a..6b8afff7ba36 100644 --- a/deps/npm/docs/output/commands/npm-owner.html +++ b/deps/npm/docs/output/commands/npm-owner.html @@ -186,9 +186,9 @@
-

+

npm-owner - @11.19.0 + @11.19.1

Manage package owners
diff --git a/deps/npm/docs/output/commands/npm-pack.html b/deps/npm/docs/output/commands/npm-pack.html index 3f92c3ff7579..d7f148d92ed7 100644 --- a/deps/npm/docs/output/commands/npm-pack.html +++ b/deps/npm/docs/output/commands/npm-pack.html @@ -186,9 +186,9 @@
-

+

npm-pack - @11.19.0 + @11.19.1

Create a tarball from a package
diff --git a/deps/npm/docs/output/commands/npm-ping.html b/deps/npm/docs/output/commands/npm-ping.html index 84d634064212..3c49a0713166 100644 --- a/deps/npm/docs/output/commands/npm-ping.html +++ b/deps/npm/docs/output/commands/npm-ping.html @@ -186,9 +186,9 @@
-

+

npm-ping - @11.19.0 + @11.19.1

Ping npm registry
diff --git a/deps/npm/docs/output/commands/npm-pkg.html b/deps/npm/docs/output/commands/npm-pkg.html index cf995cca7679..d80ac21f9af3 100644 --- a/deps/npm/docs/output/commands/npm-pkg.html +++ b/deps/npm/docs/output/commands/npm-pkg.html @@ -186,9 +186,9 @@
-

+

npm-pkg - @11.19.0 + @11.19.1

Manages your package.json
diff --git a/deps/npm/docs/output/commands/npm-prefix.html b/deps/npm/docs/output/commands/npm-prefix.html index 0336ac659020..1592a1d3048d 100644 --- a/deps/npm/docs/output/commands/npm-prefix.html +++ b/deps/npm/docs/output/commands/npm-prefix.html @@ -186,9 +186,9 @@
-

+

npm-prefix - @11.19.0 + @11.19.1

Display prefix
diff --git a/deps/npm/docs/output/commands/npm-profile.html b/deps/npm/docs/output/commands/npm-profile.html index 8c0d0a337c8c..24f5db6d7f37 100644 --- a/deps/npm/docs/output/commands/npm-profile.html +++ b/deps/npm/docs/output/commands/npm-profile.html @@ -186,9 +186,9 @@
-

+

npm-profile - @11.19.0 + @11.19.1

Change settings on your registry profile
diff --git a/deps/npm/docs/output/commands/npm-prune.html b/deps/npm/docs/output/commands/npm-prune.html index d340e0fd84a6..736620c0a24a 100644 --- a/deps/npm/docs/output/commands/npm-prune.html +++ b/deps/npm/docs/output/commands/npm-prune.html @@ -186,9 +186,9 @@
-

+

npm-prune - @11.19.0 + @11.19.1

Remove extraneous packages
diff --git a/deps/npm/docs/output/commands/npm-publish.html b/deps/npm/docs/output/commands/npm-publish.html index d1ee0efa5d16..a20d56b8d10e 100644 --- a/deps/npm/docs/output/commands/npm-publish.html +++ b/deps/npm/docs/output/commands/npm-publish.html @@ -186,9 +186,9 @@
-

+

npm-publish - @11.19.0 + @11.19.1

Publish a package
diff --git a/deps/npm/docs/output/commands/npm-query.html b/deps/npm/docs/output/commands/npm-query.html index a8347390a34a..a74342cf2782 100644 --- a/deps/npm/docs/output/commands/npm-query.html +++ b/deps/npm/docs/output/commands/npm-query.html @@ -186,9 +186,9 @@
-

+

npm-query - @11.19.0 + @11.19.1

Dependency selector query
diff --git a/deps/npm/docs/output/commands/npm-rebuild.html b/deps/npm/docs/output/commands/npm-rebuild.html index 8c2277d8a914..39403a70941d 100644 --- a/deps/npm/docs/output/commands/npm-rebuild.html +++ b/deps/npm/docs/output/commands/npm-rebuild.html @@ -186,9 +186,9 @@
-

+

npm-rebuild - @11.19.0 + @11.19.1

Rebuild a package
diff --git a/deps/npm/docs/output/commands/npm-repo.html b/deps/npm/docs/output/commands/npm-repo.html index b60cd8bc1ddd..5337679c8248 100644 --- a/deps/npm/docs/output/commands/npm-repo.html +++ b/deps/npm/docs/output/commands/npm-repo.html @@ -186,9 +186,9 @@
-

+

npm-repo - @11.19.0 + @11.19.1

Open package repository page in the browser
diff --git a/deps/npm/docs/output/commands/npm-restart.html b/deps/npm/docs/output/commands/npm-restart.html index 960530ad2975..0786bdc34a54 100644 --- a/deps/npm/docs/output/commands/npm-restart.html +++ b/deps/npm/docs/output/commands/npm-restart.html @@ -186,9 +186,9 @@
-

+

npm-restart - @11.19.0 + @11.19.1

Restart a package
diff --git a/deps/npm/docs/output/commands/npm-root.html b/deps/npm/docs/output/commands/npm-root.html index b5ad8c5c1389..165223c6fdb6 100644 --- a/deps/npm/docs/output/commands/npm-root.html +++ b/deps/npm/docs/output/commands/npm-root.html @@ -186,9 +186,9 @@
-

+

npm-root - @11.19.0 + @11.19.1

Display npm root
diff --git a/deps/npm/docs/output/commands/npm-run.html b/deps/npm/docs/output/commands/npm-run.html index 985df67fddef..15ca998eb8a8 100644 --- a/deps/npm/docs/output/commands/npm-run.html +++ b/deps/npm/docs/output/commands/npm-run.html @@ -186,9 +186,9 @@
-

+

npm-run - @11.19.0 + @11.19.1

Run arbitrary package scripts
diff --git a/deps/npm/docs/output/commands/npm-sbom.html b/deps/npm/docs/output/commands/npm-sbom.html index db72c21adc4f..fe84c36327a6 100644 --- a/deps/npm/docs/output/commands/npm-sbom.html +++ b/deps/npm/docs/output/commands/npm-sbom.html @@ -186,9 +186,9 @@
-

+

npm-sbom - @11.19.0 + @11.19.1

Generate a Software Bill of Materials (SBOM)
diff --git a/deps/npm/docs/output/commands/npm-search.html b/deps/npm/docs/output/commands/npm-search.html index f4764833e25a..98006e7d2253 100644 --- a/deps/npm/docs/output/commands/npm-search.html +++ b/deps/npm/docs/output/commands/npm-search.html @@ -186,9 +186,9 @@
-

+

npm-search - @11.19.0 + @11.19.1

Search for packages
diff --git a/deps/npm/docs/output/commands/npm-set.html b/deps/npm/docs/output/commands/npm-set.html index d0fe94ba7e98..6202cdf7b3cd 100644 --- a/deps/npm/docs/output/commands/npm-set.html +++ b/deps/npm/docs/output/commands/npm-set.html @@ -186,9 +186,9 @@
-

+

npm-set - @11.19.0 + @11.19.1

Set a value in the npm configuration
diff --git a/deps/npm/docs/output/commands/npm-shrinkwrap.html b/deps/npm/docs/output/commands/npm-shrinkwrap.html index 85fb2b99986f..abb9c216e6da 100644 --- a/deps/npm/docs/output/commands/npm-shrinkwrap.html +++ b/deps/npm/docs/output/commands/npm-shrinkwrap.html @@ -186,9 +186,9 @@
-

+

npm-shrinkwrap - @11.19.0 + @11.19.1

Lock down dependency versions for publication
diff --git a/deps/npm/docs/output/commands/npm-stage.html b/deps/npm/docs/output/commands/npm-stage.html index 225d4970fad3..74c4f7acddf0 100644 --- a/deps/npm/docs/output/commands/npm-stage.html +++ b/deps/npm/docs/output/commands/npm-stage.html @@ -186,9 +186,9 @@
-

+

npm-stage - @11.19.0 + @11.19.1

Stage packages for publishing
diff --git a/deps/npm/docs/output/commands/npm-star.html b/deps/npm/docs/output/commands/npm-star.html index 5521c413462c..4ba2f61b1797 100644 --- a/deps/npm/docs/output/commands/npm-star.html +++ b/deps/npm/docs/output/commands/npm-star.html @@ -186,9 +186,9 @@
-

+

npm-star - @11.19.0 + @11.19.1

Mark your favorite packages
diff --git a/deps/npm/docs/output/commands/npm-stars.html b/deps/npm/docs/output/commands/npm-stars.html index 9f497020875d..a1c7c0a4fd9d 100644 --- a/deps/npm/docs/output/commands/npm-stars.html +++ b/deps/npm/docs/output/commands/npm-stars.html @@ -186,9 +186,9 @@
-

+

npm-stars - @11.19.0 + @11.19.1

View packages marked as favorites
diff --git a/deps/npm/docs/output/commands/npm-start.html b/deps/npm/docs/output/commands/npm-start.html index 4a6ec9e7e2c8..063ac6b3d809 100644 --- a/deps/npm/docs/output/commands/npm-start.html +++ b/deps/npm/docs/output/commands/npm-start.html @@ -186,9 +186,9 @@
-

+

npm-start - @11.19.0 + @11.19.1

Start a package
diff --git a/deps/npm/docs/output/commands/npm-stop.html b/deps/npm/docs/output/commands/npm-stop.html index 243f702c961e..b4e84d2488de 100644 --- a/deps/npm/docs/output/commands/npm-stop.html +++ b/deps/npm/docs/output/commands/npm-stop.html @@ -186,9 +186,9 @@
-

+

npm-stop - @11.19.0 + @11.19.1

Stop a package
diff --git a/deps/npm/docs/output/commands/npm-team.html b/deps/npm/docs/output/commands/npm-team.html index 0baf06db4b1a..c9a7504b91fa 100644 --- a/deps/npm/docs/output/commands/npm-team.html +++ b/deps/npm/docs/output/commands/npm-team.html @@ -186,9 +186,9 @@
-

+

npm-team - @11.19.0 + @11.19.1

Manage organization teams and team memberships
diff --git a/deps/npm/docs/output/commands/npm-test.html b/deps/npm/docs/output/commands/npm-test.html index 2d46aafd0b14..bbb30678ba8c 100644 --- a/deps/npm/docs/output/commands/npm-test.html +++ b/deps/npm/docs/output/commands/npm-test.html @@ -186,9 +186,9 @@
-

+

npm-test - @11.19.0 + @11.19.1

Test a package
diff --git a/deps/npm/docs/output/commands/npm-token.html b/deps/npm/docs/output/commands/npm-token.html index 58a528ce2180..680c2aa534f8 100644 --- a/deps/npm/docs/output/commands/npm-token.html +++ b/deps/npm/docs/output/commands/npm-token.html @@ -186,9 +186,9 @@
-

+

npm-token - @11.19.0 + @11.19.1

Manage your authentication tokens
diff --git a/deps/npm/docs/output/commands/npm-trust.html b/deps/npm/docs/output/commands/npm-trust.html index 429e22957b18..6d531484035c 100644 --- a/deps/npm/docs/output/commands/npm-trust.html +++ b/deps/npm/docs/output/commands/npm-trust.html @@ -186,9 +186,9 @@
-

+

npm-trust - @11.19.0 + @11.19.1

Manage trusted publishing relationships between packages and CI/CD providers
diff --git a/deps/npm/docs/output/commands/npm-undeprecate.html b/deps/npm/docs/output/commands/npm-undeprecate.html index 67b6d048c079..d5239ca0cac0 100644 --- a/deps/npm/docs/output/commands/npm-undeprecate.html +++ b/deps/npm/docs/output/commands/npm-undeprecate.html @@ -186,9 +186,9 @@
-

+

npm-undeprecate - @11.19.0 + @11.19.1

Undeprecate a version of a package
diff --git a/deps/npm/docs/output/commands/npm-uninstall.html b/deps/npm/docs/output/commands/npm-uninstall.html index 8197d3646c62..26991d034bd4 100644 --- a/deps/npm/docs/output/commands/npm-uninstall.html +++ b/deps/npm/docs/output/commands/npm-uninstall.html @@ -186,9 +186,9 @@
-

+

npm-uninstall - @11.19.0 + @11.19.1

Remove a package
diff --git a/deps/npm/docs/output/commands/npm-unpublish.html b/deps/npm/docs/output/commands/npm-unpublish.html index 21b698cad72e..4fda332a9615 100644 --- a/deps/npm/docs/output/commands/npm-unpublish.html +++ b/deps/npm/docs/output/commands/npm-unpublish.html @@ -186,9 +186,9 @@
-

+

npm-unpublish - @11.19.0 + @11.19.1

Remove a package from the registry
diff --git a/deps/npm/docs/output/commands/npm-unstar.html b/deps/npm/docs/output/commands/npm-unstar.html index 2564643c7435..25db54715ddb 100644 --- a/deps/npm/docs/output/commands/npm-unstar.html +++ b/deps/npm/docs/output/commands/npm-unstar.html @@ -186,9 +186,9 @@
-

+

npm-unstar - @11.19.0 + @11.19.1

Remove an item from your favorite packages
diff --git a/deps/npm/docs/output/commands/npm-update.html b/deps/npm/docs/output/commands/npm-update.html index c89bc400aa3c..fff2f70073cd 100644 --- a/deps/npm/docs/output/commands/npm-update.html +++ b/deps/npm/docs/output/commands/npm-update.html @@ -186,9 +186,9 @@
-

+

npm-update - @11.19.0 + @11.19.1

Update packages
diff --git a/deps/npm/docs/output/commands/npm-version.html b/deps/npm/docs/output/commands/npm-version.html index 2cb36d263256..310abe5db903 100644 --- a/deps/npm/docs/output/commands/npm-version.html +++ b/deps/npm/docs/output/commands/npm-version.html @@ -186,9 +186,9 @@
-

+

npm-version - @11.19.0 + @11.19.1

Bump a package version
diff --git a/deps/npm/docs/output/commands/npm-view.html b/deps/npm/docs/output/commands/npm-view.html index 2356b4e79166..18f28fe17077 100644 --- a/deps/npm/docs/output/commands/npm-view.html +++ b/deps/npm/docs/output/commands/npm-view.html @@ -186,9 +186,9 @@
-

+

npm-view - @11.19.0 + @11.19.1

View registry info
diff --git a/deps/npm/docs/output/commands/npm-whoami.html b/deps/npm/docs/output/commands/npm-whoami.html index bd768a237695..91a7d6e2288d 100644 --- a/deps/npm/docs/output/commands/npm-whoami.html +++ b/deps/npm/docs/output/commands/npm-whoami.html @@ -186,9 +186,9 @@
-

+

npm-whoami - @11.19.0 + @11.19.1

Display npm username
diff --git a/deps/npm/docs/output/commands/npm.html b/deps/npm/docs/output/commands/npm.html index cc749dc6e59a..99674e1362df 100644 --- a/deps/npm/docs/output/commands/npm.html +++ b/deps/npm/docs/output/commands/npm.html @@ -186,9 +186,9 @@
-

+

npm - @11.19.0 + @11.19.1

javascript package manager
@@ -203,7 +203,7 @@

Table of contents

Note: This command is unaware of workspaces.

Version

-

11.19.0

+

11.19.1

Description

npm is the package manager for the Node JavaScript platform. It puts modules in place so that node can find them, and manages dependency conflicts intelligently.

diff --git a/deps/npm/docs/output/commands/npx.html b/deps/npm/docs/output/commands/npx.html index 8abb0349d715..d3cb1e00cc5b 100644 --- a/deps/npm/docs/output/commands/npx.html +++ b/deps/npm/docs/output/commands/npx.html @@ -186,9 +186,9 @@
-

+

npx - @11.19.0 + @11.19.1

Run a command from a local or remote npm package
diff --git a/deps/npm/docs/output/configuring-npm/folders.html b/deps/npm/docs/output/configuring-npm/folders.html index 7b04e59dbed2..3e86bf9a9ee5 100644 --- a/deps/npm/docs/output/configuring-npm/folders.html +++ b/deps/npm/docs/output/configuring-npm/folders.html @@ -186,9 +186,9 @@
-

+

Folders - @11.19.0 + @11.19.1

Folder structures used by npm
diff --git a/deps/npm/docs/output/configuring-npm/install.html b/deps/npm/docs/output/configuring-npm/install.html index d607ef84697b..610fc057a134 100644 --- a/deps/npm/docs/output/configuring-npm/install.html +++ b/deps/npm/docs/output/configuring-npm/install.html @@ -186,9 +186,9 @@
-

+

Install - @11.19.0 + @11.19.1

Download and install node and npm
diff --git a/deps/npm/docs/output/configuring-npm/npm-global.html b/deps/npm/docs/output/configuring-npm/npm-global.html index 7b04e59dbed2..3e86bf9a9ee5 100644 --- a/deps/npm/docs/output/configuring-npm/npm-global.html +++ b/deps/npm/docs/output/configuring-npm/npm-global.html @@ -186,9 +186,9 @@
-

+

Folders - @11.19.0 + @11.19.1

Folder structures used by npm
diff --git a/deps/npm/docs/output/configuring-npm/npm-json.html b/deps/npm/docs/output/configuring-npm/npm-json.html index 0cdb967a8c34..97a03a6d6175 100644 --- a/deps/npm/docs/output/configuring-npm/npm-json.html +++ b/deps/npm/docs/output/configuring-npm/npm-json.html @@ -186,9 +186,9 @@
-

+

package.json - @11.19.0 + @11.19.1

Specifics of npm's package.json handling
diff --git a/deps/npm/docs/output/configuring-npm/npm-shrinkwrap-json.html b/deps/npm/docs/output/configuring-npm/npm-shrinkwrap-json.html index f26ba837f409..134524b16af6 100644 --- a/deps/npm/docs/output/configuring-npm/npm-shrinkwrap-json.html +++ b/deps/npm/docs/output/configuring-npm/npm-shrinkwrap-json.html @@ -186,9 +186,9 @@
-

+

npm-shrinkwrap.json - @11.19.0 + @11.19.1

A publishable lockfile
diff --git a/deps/npm/docs/output/configuring-npm/npmrc.html b/deps/npm/docs/output/configuring-npm/npmrc.html index 6e88197b3fbf..a5eb291b57ca 100644 --- a/deps/npm/docs/output/configuring-npm/npmrc.html +++ b/deps/npm/docs/output/configuring-npm/npmrc.html @@ -186,9 +186,9 @@
-

+

.npmrc - @11.19.0 + @11.19.1

The npm config files
diff --git a/deps/npm/docs/output/configuring-npm/package-json.html b/deps/npm/docs/output/configuring-npm/package-json.html index 0cdb967a8c34..97a03a6d6175 100644 --- a/deps/npm/docs/output/configuring-npm/package-json.html +++ b/deps/npm/docs/output/configuring-npm/package-json.html @@ -186,9 +186,9 @@
-

+

package.json - @11.19.0 + @11.19.1

Specifics of npm's package.json handling
diff --git a/deps/npm/docs/output/configuring-npm/package-lock-json.html b/deps/npm/docs/output/configuring-npm/package-lock-json.html index 68476b2f14e4..9a4f1631b337 100644 --- a/deps/npm/docs/output/configuring-npm/package-lock-json.html +++ b/deps/npm/docs/output/configuring-npm/package-lock-json.html @@ -186,9 +186,9 @@
-

+

package-lock.json - @11.19.0 + @11.19.1

A manifestation of the manifest
diff --git a/deps/npm/docs/output/using-npm/config.html b/deps/npm/docs/output/using-npm/config.html index 9d288a3a2e86..ac5829fba75d 100644 --- a/deps/npm/docs/output/using-npm/config.html +++ b/deps/npm/docs/output/using-npm/config.html @@ -186,9 +186,9 @@
-

+

Config - @11.19.0 + @11.19.1

About npm configuration
diff --git a/deps/npm/docs/output/using-npm/dependency-selectors.html b/deps/npm/docs/output/using-npm/dependency-selectors.html index 80acfdd6ea80..c56b5e6c4027 100644 --- a/deps/npm/docs/output/using-npm/dependency-selectors.html +++ b/deps/npm/docs/output/using-npm/dependency-selectors.html @@ -186,9 +186,9 @@
-

+

Dependency Selectors - @11.19.0 + @11.19.1

Dependency Selector Syntax & Querying
diff --git a/deps/npm/docs/output/using-npm/developers.html b/deps/npm/docs/output/using-npm/developers.html index 5457f4a7943b..984f28bfe7b2 100644 --- a/deps/npm/docs/output/using-npm/developers.html +++ b/deps/npm/docs/output/using-npm/developers.html @@ -186,9 +186,9 @@
-

+

Developers - @11.19.0 + @11.19.1

Developer guide
diff --git a/deps/npm/docs/output/using-npm/logging.html b/deps/npm/docs/output/using-npm/logging.html index 62b819e82646..f6f6dd742f12 100644 --- a/deps/npm/docs/output/using-npm/logging.html +++ b/deps/npm/docs/output/using-npm/logging.html @@ -186,9 +186,9 @@
-

+

Logging - @11.19.0 + @11.19.1

Why, What & How we Log
diff --git a/deps/npm/docs/output/using-npm/orgs.html b/deps/npm/docs/output/using-npm/orgs.html index 39559c361b78..f579fcbbac1f 100644 --- a/deps/npm/docs/output/using-npm/orgs.html +++ b/deps/npm/docs/output/using-npm/orgs.html @@ -186,9 +186,9 @@
-

+

Organizations - @11.19.0 + @11.19.1

Working with teams & organizations
diff --git a/deps/npm/docs/output/using-npm/package-spec.html b/deps/npm/docs/output/using-npm/package-spec.html index 82b8d1d9ad2e..620f470d109b 100644 --- a/deps/npm/docs/output/using-npm/package-spec.html +++ b/deps/npm/docs/output/using-npm/package-spec.html @@ -186,9 +186,9 @@
-

+

Package spec - @11.19.0 + @11.19.1

Package name specifier
diff --git a/deps/npm/docs/output/using-npm/registry.html b/deps/npm/docs/output/using-npm/registry.html index b3d34df82033..e61715c22e4b 100644 --- a/deps/npm/docs/output/using-npm/registry.html +++ b/deps/npm/docs/output/using-npm/registry.html @@ -186,9 +186,9 @@
-

+

Registry - @11.19.0 + @11.19.1

The JavaScript Package Registry
diff --git a/deps/npm/docs/output/using-npm/removal.html b/deps/npm/docs/output/using-npm/removal.html index b85ee02590cc..07ee6c06bc40 100644 --- a/deps/npm/docs/output/using-npm/removal.html +++ b/deps/npm/docs/output/using-npm/removal.html @@ -186,9 +186,9 @@
-

+

Removal - @11.19.0 + @11.19.1

Cleaning the slate
diff --git a/deps/npm/docs/output/using-npm/scope.html b/deps/npm/docs/output/using-npm/scope.html index f2e733bc9ebf..a08571ebfda3 100644 --- a/deps/npm/docs/output/using-npm/scope.html +++ b/deps/npm/docs/output/using-npm/scope.html @@ -186,9 +186,9 @@
-

+

Scope - @11.19.0 + @11.19.1

Scoped packages
diff --git a/deps/npm/docs/output/using-npm/scripts.html b/deps/npm/docs/output/using-npm/scripts.html index c2a9641f62d2..4e852304a114 100644 --- a/deps/npm/docs/output/using-npm/scripts.html +++ b/deps/npm/docs/output/using-npm/scripts.html @@ -186,9 +186,9 @@
-

+

Scripts - @11.19.0 + @11.19.1

How npm handles the "scripts" field
diff --git a/deps/npm/docs/output/using-npm/workspaces.html b/deps/npm/docs/output/using-npm/workspaces.html index 3a9986755339..ec3d3abed055 100644 --- a/deps/npm/docs/output/using-npm/workspaces.html +++ b/deps/npm/docs/output/using-npm/workspaces.html @@ -186,9 +186,9 @@
-

+

Workspaces - @11.19.0 + @11.19.1

Working with workspaces
diff --git a/deps/npm/lib/commands/pack.js b/deps/npm/lib/commands/pack.js index be4a1b240bea..9c4b59657f4a 100644 --- a/deps/npm/lib/commands/pack.js +++ b/deps/npm/lib/commands/pack.js @@ -45,6 +45,7 @@ class Pack extends BaseCommand { ) ? { ...this.npm.flatOptions, before: null } : this.npm.flatOptions const manifest = await pacote.manifest(spec, { ...options, + ...(spec.type === 'directory' && { allowDirectory: 'all' }), Arborist, preferOnline: true, _isRoot: true, diff --git a/deps/npm/man/man1/npm-access.1 b/deps/npm/man/man1/npm-access.1 index 3b7d77d8962f..435819623db2 100644 --- a/deps/npm/man/man1/npm-access.1 +++ b/deps/npm/man/man1/npm-access.1 @@ -1,4 +1,4 @@ -.TH "NPM-ACCESS" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-ACCESS" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-access\fR - Set access level on published packages .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-adduser.1 b/deps/npm/man/man1/npm-adduser.1 index 53ed267a0aa4..5cc628784241 100644 --- a/deps/npm/man/man1/npm-adduser.1 +++ b/deps/npm/man/man1/npm-adduser.1 @@ -1,4 +1,4 @@ -.TH "NPM-ADDUSER" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-ADDUSER" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-adduser\fR - Add a registry user account .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-approve-scripts.1 b/deps/npm/man/man1/npm-approve-scripts.1 index 943459b20562..f874e752ab97 100644 --- a/deps/npm/man/man1/npm-approve-scripts.1 +++ b/deps/npm/man/man1/npm-approve-scripts.1 @@ -1,4 +1,4 @@ -.TH "NPM-APPROVE-SCRIPTS" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-APPROVE-SCRIPTS" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-approve-scripts\fR - Approve install scripts for specific dependencies .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-audit.1 b/deps/npm/man/man1/npm-audit.1 index 77fbcbe595ef..8c9815292aee 100644 --- a/deps/npm/man/man1/npm-audit.1 +++ b/deps/npm/man/man1/npm-audit.1 @@ -1,4 +1,4 @@ -.TH "NPM-AUDIT" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-AUDIT" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-audit\fR - Run a security audit .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-bugs.1 b/deps/npm/man/man1/npm-bugs.1 index 05a37e504c7e..0113cf310fdb 100644 --- a/deps/npm/man/man1/npm-bugs.1 +++ b/deps/npm/man/man1/npm-bugs.1 @@ -1,4 +1,4 @@ -.TH "NPM-BUGS" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-BUGS" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-bugs\fR - Report bugs for a package in a web browser .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-cache.1 b/deps/npm/man/man1/npm-cache.1 index fd725dd57fe2..71eaeccf613d 100644 --- a/deps/npm/man/man1/npm-cache.1 +++ b/deps/npm/man/man1/npm-cache.1 @@ -1,4 +1,4 @@ -.TH "NPM-CACHE" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-CACHE" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-cache\fR - Manipulates packages cache .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-ci.1 b/deps/npm/man/man1/npm-ci.1 index bbae51d8e983..2e544d6dfa80 100644 --- a/deps/npm/man/man1/npm-ci.1 +++ b/deps/npm/man/man1/npm-ci.1 @@ -1,4 +1,4 @@ -.TH "NPM-CI" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-CI" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-ci\fR - Clean install a project .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-completion.1 b/deps/npm/man/man1/npm-completion.1 index d01c54ab63af..d5cefe61d0c7 100644 --- a/deps/npm/man/man1/npm-completion.1 +++ b/deps/npm/man/man1/npm-completion.1 @@ -1,4 +1,4 @@ -.TH "NPM-COMPLETION" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-COMPLETION" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-completion\fR - Tab Completion for npm .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-config.1 b/deps/npm/man/man1/npm-config.1 index 34b79e9d1c57..b0ef989fe726 100644 --- a/deps/npm/man/man1/npm-config.1 +++ b/deps/npm/man/man1/npm-config.1 @@ -1,4 +1,4 @@ -.TH "NPM-CONFIG" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-CONFIG" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-config\fR - Manage the npm configuration files .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-dedupe.1 b/deps/npm/man/man1/npm-dedupe.1 index 0b11deb4d467..1fa8e34027fb 100644 --- a/deps/npm/man/man1/npm-dedupe.1 +++ b/deps/npm/man/man1/npm-dedupe.1 @@ -1,4 +1,4 @@ -.TH "NPM-DEDUPE" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-DEDUPE" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-dedupe\fR - Reduce duplication in the package tree .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-deny-scripts.1 b/deps/npm/man/man1/npm-deny-scripts.1 index d8a41f57479e..70fb96d6fcd2 100644 --- a/deps/npm/man/man1/npm-deny-scripts.1 +++ b/deps/npm/man/man1/npm-deny-scripts.1 @@ -1,4 +1,4 @@ -.TH "NPM-DENY-SCRIPTS" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-DENY-SCRIPTS" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-deny-scripts\fR - Deny install scripts for specific dependencies .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-deprecate.1 b/deps/npm/man/man1/npm-deprecate.1 index c45dd75584ec..e07bd5829ef7 100644 --- a/deps/npm/man/man1/npm-deprecate.1 +++ b/deps/npm/man/man1/npm-deprecate.1 @@ -1,4 +1,4 @@ -.TH "NPM-DEPRECATE" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-DEPRECATE" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-deprecate\fR - Deprecate a version of a package .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-diff.1 b/deps/npm/man/man1/npm-diff.1 index 45efb60c236c..42c3903bd468 100644 --- a/deps/npm/man/man1/npm-diff.1 +++ b/deps/npm/man/man1/npm-diff.1 @@ -1,4 +1,4 @@ -.TH "NPM-DIFF" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-DIFF" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-diff\fR - The registry diff command .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-dist-tag.1 b/deps/npm/man/man1/npm-dist-tag.1 index 989a2c64d307..8ebc625273cc 100644 --- a/deps/npm/man/man1/npm-dist-tag.1 +++ b/deps/npm/man/man1/npm-dist-tag.1 @@ -1,4 +1,4 @@ -.TH "NPM-DIST-TAG" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-DIST-TAG" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-dist-tag\fR - Modify package distribution tags .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-docs.1 b/deps/npm/man/man1/npm-docs.1 index ee614b710885..26fa80d54d5d 100644 --- a/deps/npm/man/man1/npm-docs.1 +++ b/deps/npm/man/man1/npm-docs.1 @@ -1,4 +1,4 @@ -.TH "NPM-DOCS" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-DOCS" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-docs\fR - Open documentation for a package in a web browser .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-doctor.1 b/deps/npm/man/man1/npm-doctor.1 index 5344645b17ed..f5b750fd6a3b 100644 --- a/deps/npm/man/man1/npm-doctor.1 +++ b/deps/npm/man/man1/npm-doctor.1 @@ -1,4 +1,4 @@ -.TH "NPM-DOCTOR" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-DOCTOR" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-doctor\fR - Check the health of your npm environment .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-edit.1 b/deps/npm/man/man1/npm-edit.1 index bca15e054f60..5055e6feaa5d 100644 --- a/deps/npm/man/man1/npm-edit.1 +++ b/deps/npm/man/man1/npm-edit.1 @@ -1,4 +1,4 @@ -.TH "NPM-EDIT" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-EDIT" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-edit\fR - Edit an installed package .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-exec.1 b/deps/npm/man/man1/npm-exec.1 index 4b580f484bc1..5ae0a77e2880 100644 --- a/deps/npm/man/man1/npm-exec.1 +++ b/deps/npm/man/man1/npm-exec.1 @@ -1,4 +1,4 @@ -.TH "NPM-EXEC" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-EXEC" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-exec\fR - Run a command from a local or remote npm package .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-explain.1 b/deps/npm/man/man1/npm-explain.1 index 20374a8fbb37..7869082b6c6f 100644 --- a/deps/npm/man/man1/npm-explain.1 +++ b/deps/npm/man/man1/npm-explain.1 @@ -1,4 +1,4 @@ -.TH "NPM-EXPLAIN" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-EXPLAIN" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-explain\fR - Explain installed packages .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-explore.1 b/deps/npm/man/man1/npm-explore.1 index bee110155bd5..df1fd2dc6517 100644 --- a/deps/npm/man/man1/npm-explore.1 +++ b/deps/npm/man/man1/npm-explore.1 @@ -1,4 +1,4 @@ -.TH "NPM-EXPLORE" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-EXPLORE" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-explore\fR - Browse an installed package .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-find-dupes.1 b/deps/npm/man/man1/npm-find-dupes.1 index a1cfc3abd0d2..f1f3970dd1d7 100644 --- a/deps/npm/man/man1/npm-find-dupes.1 +++ b/deps/npm/man/man1/npm-find-dupes.1 @@ -1,4 +1,4 @@ -.TH "NPM-FIND-DUPES" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-FIND-DUPES" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-find-dupes\fR - Find duplication in the package tree .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-fund.1 b/deps/npm/man/man1/npm-fund.1 index ec516b28396d..88bfe299c31f 100644 --- a/deps/npm/man/man1/npm-fund.1 +++ b/deps/npm/man/man1/npm-fund.1 @@ -1,4 +1,4 @@ -.TH "NPM-FUND" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-FUND" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-fund\fR - Retrieve funding information .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-get.1 b/deps/npm/man/man1/npm-get.1 index d4763eb28c8c..7982d28e324a 100644 --- a/deps/npm/man/man1/npm-get.1 +++ b/deps/npm/man/man1/npm-get.1 @@ -1,4 +1,4 @@ -.TH "NPM-GET" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-GET" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-get\fR - Get a value from the npm configuration .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-help-search.1 b/deps/npm/man/man1/npm-help-search.1 index 63213fa4188a..e7c7d97ebcea 100644 --- a/deps/npm/man/man1/npm-help-search.1 +++ b/deps/npm/man/man1/npm-help-search.1 @@ -1,4 +1,4 @@ -.TH "NPM-HELP-SEARCH" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-HELP-SEARCH" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-help-search\fR - Search npm help documentation .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-help.1 b/deps/npm/man/man1/npm-help.1 index 59f2f1df9436..7725a82d09c1 100644 --- a/deps/npm/man/man1/npm-help.1 +++ b/deps/npm/man/man1/npm-help.1 @@ -1,4 +1,4 @@ -.TH "NPM-HELP" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-HELP" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-help\fR - Get help on npm .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-init.1 b/deps/npm/man/man1/npm-init.1 index cf4c37761d14..bd984db7d203 100644 --- a/deps/npm/man/man1/npm-init.1 +++ b/deps/npm/man/man1/npm-init.1 @@ -1,4 +1,4 @@ -.TH "NPM-INIT" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-INIT" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-init\fR - Create a package.json file .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-install-ci-test.1 b/deps/npm/man/man1/npm-install-ci-test.1 index e30140015a1c..b477b4a8b0eb 100644 --- a/deps/npm/man/man1/npm-install-ci-test.1 +++ b/deps/npm/man/man1/npm-install-ci-test.1 @@ -1,4 +1,4 @@ -.TH "NPM-INSTALL-CI-TEST" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-INSTALL-CI-TEST" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-install-ci-test\fR - Install a project with a clean slate and run tests .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-install-scripts.1 b/deps/npm/man/man1/npm-install-scripts.1 index 907b48c50ff5..b634903e3ecc 100644 --- a/deps/npm/man/man1/npm-install-scripts.1 +++ b/deps/npm/man/man1/npm-install-scripts.1 @@ -1,4 +1,4 @@ -.TH "NPM-INSTALL-SCRIPTS" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-INSTALL-SCRIPTS" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-install-scripts\fR - Manage install-script approvals for dependencies .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-install-test.1 b/deps/npm/man/man1/npm-install-test.1 index 88e0ed187377..d6774940ea2f 100644 --- a/deps/npm/man/man1/npm-install-test.1 +++ b/deps/npm/man/man1/npm-install-test.1 @@ -1,4 +1,4 @@ -.TH "NPM-INSTALL-TEST" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-INSTALL-TEST" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-install-test\fR - Install package(s) and run tests .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-install.1 b/deps/npm/man/man1/npm-install.1 index b1ccd245238d..c6ca10ab642c 100644 --- a/deps/npm/man/man1/npm-install.1 +++ b/deps/npm/man/man1/npm-install.1 @@ -1,4 +1,4 @@ -.TH "NPM-INSTALL" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-INSTALL" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-install\fR - Install a package .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-link.1 b/deps/npm/man/man1/npm-link.1 index d124bcf66a33..ea482b872b86 100644 --- a/deps/npm/man/man1/npm-link.1 +++ b/deps/npm/man/man1/npm-link.1 @@ -1,4 +1,4 @@ -.TH "NPM-LINK" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-LINK" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-link\fR - Symlink a package folder .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-ll.1 b/deps/npm/man/man1/npm-ll.1 index 982d8ee3a6c7..136777491e0f 100644 --- a/deps/npm/man/man1/npm-ll.1 +++ b/deps/npm/man/man1/npm-ll.1 @@ -1,4 +1,4 @@ -.TH "NPM-LL" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-LL" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-ll\fR - List installed packages .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-login.1 b/deps/npm/man/man1/npm-login.1 index 392c5b25d84d..ecc47d745dee 100644 --- a/deps/npm/man/man1/npm-login.1 +++ b/deps/npm/man/man1/npm-login.1 @@ -1,4 +1,4 @@ -.TH "NPM-LOGIN" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-LOGIN" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-login\fR - Login to a registry user account .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-logout.1 b/deps/npm/man/man1/npm-logout.1 index 7ca6be27366c..22d86e96586e 100644 --- a/deps/npm/man/man1/npm-logout.1 +++ b/deps/npm/man/man1/npm-logout.1 @@ -1,4 +1,4 @@ -.TH "NPM-LOGOUT" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-LOGOUT" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-logout\fR - Log out of the registry .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-ls.1 b/deps/npm/man/man1/npm-ls.1 index 6fe6245988fe..52224d908c20 100644 --- a/deps/npm/man/man1/npm-ls.1 +++ b/deps/npm/man/man1/npm-ls.1 @@ -1,4 +1,4 @@ -.TH "NPM-LS" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-LS" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-ls\fR - List installed packages .SS "Synopsis" @@ -20,7 +20,7 @@ Positional arguments are \fBname@version-range\fR identifiers, which will limit .P .RS 2 .nf -npm@11.19.0 /path/to/npm +npm@11.19.1 /path/to/npm └─┬ init-package-json@0.0.4 └── promzard@0.1.5 .fi diff --git a/deps/npm/man/man1/npm-org.1 b/deps/npm/man/man1/npm-org.1 index 50e94a589d49..4b7592722da4 100644 --- a/deps/npm/man/man1/npm-org.1 +++ b/deps/npm/man/man1/npm-org.1 @@ -1,4 +1,4 @@ -.TH "NPM-ORG" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-ORG" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-org\fR - Manage orgs .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-outdated.1 b/deps/npm/man/man1/npm-outdated.1 index a2ecbcc50b5c..f83acac0d642 100644 --- a/deps/npm/man/man1/npm-outdated.1 +++ b/deps/npm/man/man1/npm-outdated.1 @@ -1,4 +1,4 @@ -.TH "NPM-OUTDATED" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-OUTDATED" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-outdated\fR - Check for outdated packages .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-owner.1 b/deps/npm/man/man1/npm-owner.1 index 3815d60d8b2b..68a98e734ef5 100644 --- a/deps/npm/man/man1/npm-owner.1 +++ b/deps/npm/man/man1/npm-owner.1 @@ -1,4 +1,4 @@ -.TH "NPM-OWNER" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-OWNER" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-owner\fR - Manage package owners .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-pack.1 b/deps/npm/man/man1/npm-pack.1 index f5f159779bdc..58b82df26634 100644 --- a/deps/npm/man/man1/npm-pack.1 +++ b/deps/npm/man/man1/npm-pack.1 @@ -1,4 +1,4 @@ -.TH "NPM-PACK" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-PACK" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-pack\fR - Create a tarball from a package .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-ping.1 b/deps/npm/man/man1/npm-ping.1 index e44d02e67e88..4df93fbd993a 100644 --- a/deps/npm/man/man1/npm-ping.1 +++ b/deps/npm/man/man1/npm-ping.1 @@ -1,4 +1,4 @@ -.TH "NPM-PING" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-PING" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-ping\fR - Ping npm registry .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-pkg.1 b/deps/npm/man/man1/npm-pkg.1 index ad4adfa8c654..ad11f73873aa 100644 --- a/deps/npm/man/man1/npm-pkg.1 +++ b/deps/npm/man/man1/npm-pkg.1 @@ -1,4 +1,4 @@ -.TH "NPM-PKG" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-PKG" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-pkg\fR - Manages your package.json .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-prefix.1 b/deps/npm/man/man1/npm-prefix.1 index a810bc8c0140..6c990176088b 100644 --- a/deps/npm/man/man1/npm-prefix.1 +++ b/deps/npm/man/man1/npm-prefix.1 @@ -1,4 +1,4 @@ -.TH "NPM-PREFIX" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-PREFIX" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-prefix\fR - Display prefix .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-profile.1 b/deps/npm/man/man1/npm-profile.1 index 0593fa483958..0d5d54620f73 100644 --- a/deps/npm/man/man1/npm-profile.1 +++ b/deps/npm/man/man1/npm-profile.1 @@ -1,4 +1,4 @@ -.TH "NPM-PROFILE" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-PROFILE" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-profile\fR - Change settings on your registry profile .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-prune.1 b/deps/npm/man/man1/npm-prune.1 index c62e7d6bd395..8f67ca9384f8 100644 --- a/deps/npm/man/man1/npm-prune.1 +++ b/deps/npm/man/man1/npm-prune.1 @@ -1,4 +1,4 @@ -.TH "NPM-PRUNE" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-PRUNE" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-prune\fR - Remove extraneous packages .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-publish.1 b/deps/npm/man/man1/npm-publish.1 index 62676301d5ab..4e738ab0bbd7 100644 --- a/deps/npm/man/man1/npm-publish.1 +++ b/deps/npm/man/man1/npm-publish.1 @@ -1,4 +1,4 @@ -.TH "NPM-PUBLISH" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-PUBLISH" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-publish\fR - Publish a package .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-query.1 b/deps/npm/man/man1/npm-query.1 index 3ca4eb1b659f..334fc20660e4 100644 --- a/deps/npm/man/man1/npm-query.1 +++ b/deps/npm/man/man1/npm-query.1 @@ -1,4 +1,4 @@ -.TH "NPM-QUERY" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-QUERY" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-query\fR - Dependency selector query .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-rebuild.1 b/deps/npm/man/man1/npm-rebuild.1 index b0710049573e..6a09726529b4 100644 --- a/deps/npm/man/man1/npm-rebuild.1 +++ b/deps/npm/man/man1/npm-rebuild.1 @@ -1,4 +1,4 @@ -.TH "NPM-REBUILD" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-REBUILD" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-rebuild\fR - Rebuild a package .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-repo.1 b/deps/npm/man/man1/npm-repo.1 index 46fdc0cb111e..5ff08e9eeb4d 100644 --- a/deps/npm/man/man1/npm-repo.1 +++ b/deps/npm/man/man1/npm-repo.1 @@ -1,4 +1,4 @@ -.TH "NPM-REPO" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-REPO" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-repo\fR - Open package repository page in the browser .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-restart.1 b/deps/npm/man/man1/npm-restart.1 index b552a5e2a86a..d4f5f0d3df1f 100644 --- a/deps/npm/man/man1/npm-restart.1 +++ b/deps/npm/man/man1/npm-restart.1 @@ -1,4 +1,4 @@ -.TH "NPM-RESTART" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-RESTART" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-restart\fR - Restart a package .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-root.1 b/deps/npm/man/man1/npm-root.1 index 9d701e336bff..ecd0c64ef6bb 100644 --- a/deps/npm/man/man1/npm-root.1 +++ b/deps/npm/man/man1/npm-root.1 @@ -1,4 +1,4 @@ -.TH "NPM-ROOT" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-ROOT" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-root\fR - Display npm root .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-run.1 b/deps/npm/man/man1/npm-run.1 index 185111dbafbb..8aadcceff7c1 100644 --- a/deps/npm/man/man1/npm-run.1 +++ b/deps/npm/man/man1/npm-run.1 @@ -1,4 +1,4 @@ -.TH "NPM-RUN" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-RUN" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-run\fR - Run arbitrary package scripts .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-sbom.1 b/deps/npm/man/man1/npm-sbom.1 index a8a74f9e02c6..f694d642f9ad 100644 --- a/deps/npm/man/man1/npm-sbom.1 +++ b/deps/npm/man/man1/npm-sbom.1 @@ -1,4 +1,4 @@ -.TH "NPM-SBOM" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-SBOM" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-sbom\fR - Generate a Software Bill of Materials (SBOM) .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-search.1 b/deps/npm/man/man1/npm-search.1 index 2a0fbbc58709..969d0e784902 100644 --- a/deps/npm/man/man1/npm-search.1 +++ b/deps/npm/man/man1/npm-search.1 @@ -1,4 +1,4 @@ -.TH "NPM-SEARCH" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-SEARCH" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-search\fR - Search for packages .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-set.1 b/deps/npm/man/man1/npm-set.1 index 4333006b47ff..4deaf8e01aca 100644 --- a/deps/npm/man/man1/npm-set.1 +++ b/deps/npm/man/man1/npm-set.1 @@ -1,4 +1,4 @@ -.TH "NPM-SET" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-SET" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-set\fR - Set a value in the npm configuration .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-shrinkwrap.1 b/deps/npm/man/man1/npm-shrinkwrap.1 index 0fc20a6ccaeb..35caa20c3dc0 100644 --- a/deps/npm/man/man1/npm-shrinkwrap.1 +++ b/deps/npm/man/man1/npm-shrinkwrap.1 @@ -1,4 +1,4 @@ -.TH "NPM-SHRINKWRAP" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-SHRINKWRAP" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-shrinkwrap\fR - Lock down dependency versions for publication .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-stage.1 b/deps/npm/man/man1/npm-stage.1 index 9a677ba6b03e..8c2016052130 100644 --- a/deps/npm/man/man1/npm-stage.1 +++ b/deps/npm/man/man1/npm-stage.1 @@ -1,4 +1,4 @@ -.TH "NPM-STAGE" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-STAGE" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-stage\fR - Stage packages for publishing .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-star.1 b/deps/npm/man/man1/npm-star.1 index dbabe90b0bd6..a2191c120e35 100644 --- a/deps/npm/man/man1/npm-star.1 +++ b/deps/npm/man/man1/npm-star.1 @@ -1,4 +1,4 @@ -.TH "NPM-STAR" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-STAR" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-star\fR - Mark your favorite packages .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-stars.1 b/deps/npm/man/man1/npm-stars.1 index 2999dd8abbf0..aca98ed914a5 100644 --- a/deps/npm/man/man1/npm-stars.1 +++ b/deps/npm/man/man1/npm-stars.1 @@ -1,4 +1,4 @@ -.TH "NPM-STARS" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-STARS" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-stars\fR - View packages marked as favorites .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-start.1 b/deps/npm/man/man1/npm-start.1 index c8966bd38a68..d2f3b4d87cc8 100644 --- a/deps/npm/man/man1/npm-start.1 +++ b/deps/npm/man/man1/npm-start.1 @@ -1,4 +1,4 @@ -.TH "NPM-START" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-START" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-start\fR - Start a package .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-stop.1 b/deps/npm/man/man1/npm-stop.1 index c900d58437f5..7896dd6acd17 100644 --- a/deps/npm/man/man1/npm-stop.1 +++ b/deps/npm/man/man1/npm-stop.1 @@ -1,4 +1,4 @@ -.TH "NPM-STOP" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-STOP" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-stop\fR - Stop a package .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-team.1 b/deps/npm/man/man1/npm-team.1 index 4de50f8c6b06..21ccc530ad81 100644 --- a/deps/npm/man/man1/npm-team.1 +++ b/deps/npm/man/man1/npm-team.1 @@ -1,4 +1,4 @@ -.TH "NPM-TEAM" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-TEAM" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-team\fR - Manage organization teams and team memberships .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-test.1 b/deps/npm/man/man1/npm-test.1 index 311ba399498b..8cae879d8291 100644 --- a/deps/npm/man/man1/npm-test.1 +++ b/deps/npm/man/man1/npm-test.1 @@ -1,4 +1,4 @@ -.TH "NPM-TEST" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-TEST" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-test\fR - Test a package .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-token.1 b/deps/npm/man/man1/npm-token.1 index 4b1cbae98b24..fc82daf8d0cf 100644 --- a/deps/npm/man/man1/npm-token.1 +++ b/deps/npm/man/man1/npm-token.1 @@ -1,4 +1,4 @@ -.TH "NPM-TOKEN" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-TOKEN" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-token\fR - Manage your authentication tokens .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-trust.1 b/deps/npm/man/man1/npm-trust.1 index f8de6022c0f0..fce69eb33b75 100644 --- a/deps/npm/man/man1/npm-trust.1 +++ b/deps/npm/man/man1/npm-trust.1 @@ -1,4 +1,4 @@ -.TH "NPM-TRUST" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-TRUST" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-trust\fR - Manage trusted publishing relationships between packages and CI/CD providers .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-undeprecate.1 b/deps/npm/man/man1/npm-undeprecate.1 index 1a26688b4530..11f91ee9b913 100644 --- a/deps/npm/man/man1/npm-undeprecate.1 +++ b/deps/npm/man/man1/npm-undeprecate.1 @@ -1,4 +1,4 @@ -.TH "NPM-UNDEPRECATE" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-UNDEPRECATE" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-undeprecate\fR - Undeprecate a version of a package .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-uninstall.1 b/deps/npm/man/man1/npm-uninstall.1 index 39791e588e7e..b9ff997229dc 100644 --- a/deps/npm/man/man1/npm-uninstall.1 +++ b/deps/npm/man/man1/npm-uninstall.1 @@ -1,4 +1,4 @@ -.TH "NPM-UNINSTALL" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-UNINSTALL" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-uninstall\fR - Remove a package .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-unpublish.1 b/deps/npm/man/man1/npm-unpublish.1 index f839376efe0f..5bbb86e8c8f3 100644 --- a/deps/npm/man/man1/npm-unpublish.1 +++ b/deps/npm/man/man1/npm-unpublish.1 @@ -1,4 +1,4 @@ -.TH "NPM-UNPUBLISH" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-UNPUBLISH" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-unpublish\fR - Remove a package from the registry .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-unstar.1 b/deps/npm/man/man1/npm-unstar.1 index 555868c3fb68..0d0e2f2c9e6a 100644 --- a/deps/npm/man/man1/npm-unstar.1 +++ b/deps/npm/man/man1/npm-unstar.1 @@ -1,4 +1,4 @@ -.TH "NPM-UNSTAR" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-UNSTAR" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-unstar\fR - Remove an item from your favorite packages .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-update.1 b/deps/npm/man/man1/npm-update.1 index 55b4191e801b..4f5e015b20d7 100644 --- a/deps/npm/man/man1/npm-update.1 +++ b/deps/npm/man/man1/npm-update.1 @@ -1,4 +1,4 @@ -.TH "NPM-UPDATE" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-UPDATE" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-update\fR - Update packages .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-version.1 b/deps/npm/man/man1/npm-version.1 index fd261b5cd42a..c15a0d19acfa 100644 --- a/deps/npm/man/man1/npm-version.1 +++ b/deps/npm/man/man1/npm-version.1 @@ -1,4 +1,4 @@ -.TH "NPM-VERSION" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-VERSION" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-version\fR - Bump a package version .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-view.1 b/deps/npm/man/man1/npm-view.1 index a150ce2d979d..b9210c424cd2 100644 --- a/deps/npm/man/man1/npm-view.1 +++ b/deps/npm/man/man1/npm-view.1 @@ -1,4 +1,4 @@ -.TH "NPM-VIEW" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-VIEW" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-view\fR - View registry info .SS "Synopsis" diff --git a/deps/npm/man/man1/npm-whoami.1 b/deps/npm/man/man1/npm-whoami.1 index 920d19146bd3..5d44c35a7f48 100644 --- a/deps/npm/man/man1/npm-whoami.1 +++ b/deps/npm/man/man1/npm-whoami.1 @@ -1,4 +1,4 @@ -.TH "NPM-WHOAMI" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM-WHOAMI" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-whoami\fR - Display npm username .SS "Synopsis" diff --git a/deps/npm/man/man1/npm.1 b/deps/npm/man/man1/npm.1 index 9791f5f274f5..25a9e19288c9 100644 --- a/deps/npm/man/man1/npm.1 +++ b/deps/npm/man/man1/npm.1 @@ -1,4 +1,4 @@ -.TH "NPM" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPM" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm\fR - javascript package manager .SS "Synopsis" @@ -12,7 +12,7 @@ npm Note: This command is unaware of workspaces. .SS "Version" .P -11.19.0 +11.19.1 .SS "Description" .P npm is the package manager for the Node JavaScript platform. It puts modules in place so that node can find them, and manages dependency conflicts intelligently. diff --git a/deps/npm/man/man1/npx.1 b/deps/npm/man/man1/npx.1 index 3c4afb8aec51..39fcb358f7ce 100644 --- a/deps/npm/man/man1/npx.1 +++ b/deps/npm/man/man1/npx.1 @@ -1,4 +1,4 @@ -.TH "NPX" "1" "July 2026" "NPM@11.19.0" "" +.TH "NPX" "1" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpx\fR - Run a command from a local or remote npm package .SS "Synopsis" diff --git a/deps/npm/man/man5/folders.5 b/deps/npm/man/man5/folders.5 index 0717f575c47f..7ec714295100 100644 --- a/deps/npm/man/man5/folders.5 +++ b/deps/npm/man/man5/folders.5 @@ -1,4 +1,4 @@ -.TH "FOLDERS" "5" "July 2026" "NPM@11.19.0" "" +.TH "FOLDERS" "5" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBFolders\fR - Folder structures used by npm .SS "Description" diff --git a/deps/npm/man/man5/install.5 b/deps/npm/man/man5/install.5 index 200dcc3dfd3a..b54f427c5da9 100644 --- a/deps/npm/man/man5/install.5 +++ b/deps/npm/man/man5/install.5 @@ -1,4 +1,4 @@ -.TH "INSTALL" "5" "July 2026" "NPM@11.19.0" "" +.TH "INSTALL" "5" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBInstall\fR - Download and install node and npm .SS "Description" diff --git a/deps/npm/man/man5/npm-global.5 b/deps/npm/man/man5/npm-global.5 index 0717f575c47f..7ec714295100 100644 --- a/deps/npm/man/man5/npm-global.5 +++ b/deps/npm/man/man5/npm-global.5 @@ -1,4 +1,4 @@ -.TH "FOLDERS" "5" "July 2026" "NPM@11.19.0" "" +.TH "FOLDERS" "5" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBFolders\fR - Folder structures used by npm .SS "Description" diff --git a/deps/npm/man/man5/npm-json.5 b/deps/npm/man/man5/npm-json.5 index 4d4a9084ac7a..4a79f2788851 100644 --- a/deps/npm/man/man5/npm-json.5 +++ b/deps/npm/man/man5/npm-json.5 @@ -1,4 +1,4 @@ -.TH "PACKAGE.JSON" "5" "July 2026" "NPM@11.19.0" "" +.TH "PACKAGE.JSON" "5" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBpackage.json\fR - Specifics of npm's package.json handling .SS "Description" diff --git a/deps/npm/man/man5/npm-shrinkwrap-json.5 b/deps/npm/man/man5/npm-shrinkwrap-json.5 index 9f3d7597d161..1af7bf467c03 100644 --- a/deps/npm/man/man5/npm-shrinkwrap-json.5 +++ b/deps/npm/man/man5/npm-shrinkwrap-json.5 @@ -1,4 +1,4 @@ -.TH "NPM-SHRINKWRAP.JSON" "5" "July 2026" "NPM@11.19.0" "" +.TH "NPM-SHRINKWRAP.JSON" "5" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBnpm-shrinkwrap.json\fR - A publishable lockfile .SS "Description" diff --git a/deps/npm/man/man5/npmrc.5 b/deps/npm/man/man5/npmrc.5 index 83578c624089..9d2361126088 100644 --- a/deps/npm/man/man5/npmrc.5 +++ b/deps/npm/man/man5/npmrc.5 @@ -1,4 +1,4 @@ -.TH ".NPMRC" "5" "July 2026" "NPM@11.19.0" "" +.TH ".NPMRC" "5" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fB.npmrc\fR - The npm config files .SS "Description" diff --git a/deps/npm/man/man5/package-json.5 b/deps/npm/man/man5/package-json.5 index 4d4a9084ac7a..4a79f2788851 100644 --- a/deps/npm/man/man5/package-json.5 +++ b/deps/npm/man/man5/package-json.5 @@ -1,4 +1,4 @@ -.TH "PACKAGE.JSON" "5" "July 2026" "NPM@11.19.0" "" +.TH "PACKAGE.JSON" "5" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBpackage.json\fR - Specifics of npm's package.json handling .SS "Description" diff --git a/deps/npm/man/man5/package-lock-json.5 b/deps/npm/man/man5/package-lock-json.5 index 7bc632269f50..ace3d4d69594 100644 --- a/deps/npm/man/man5/package-lock-json.5 +++ b/deps/npm/man/man5/package-lock-json.5 @@ -1,4 +1,4 @@ -.TH "PACKAGE-LOCK.JSON" "5" "July 2026" "NPM@11.19.0" "" +.TH "PACKAGE-LOCK.JSON" "5" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBpackage-lock.json\fR - A manifestation of the manifest .SS "Description" diff --git a/deps/npm/man/man7/config.7 b/deps/npm/man/man7/config.7 index b68980abc38f..684663e33757 100644 --- a/deps/npm/man/man7/config.7 +++ b/deps/npm/man/man7/config.7 @@ -1,4 +1,4 @@ -.TH "CONFIG" "7" "July 2026" "NPM@11.19.0" "" +.TH "CONFIG" "7" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBConfig\fR - About npm configuration .SS "Description" diff --git a/deps/npm/man/man7/dependency-selectors.7 b/deps/npm/man/man7/dependency-selectors.7 index 4d242ab6e6c4..ec08ce0750b3 100644 --- a/deps/npm/man/man7/dependency-selectors.7 +++ b/deps/npm/man/man7/dependency-selectors.7 @@ -1,4 +1,4 @@ -.TH "SELECTORS" "7" "July 2026" "NPM@11.19.0" "" +.TH "SELECTORS" "7" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBSelectors\fR - Dependency Selector Syntax & Querying .SS "Description" diff --git a/deps/npm/man/man7/developers.7 b/deps/npm/man/man7/developers.7 index 201aedc081dd..aebb1f99a74a 100644 --- a/deps/npm/man/man7/developers.7 +++ b/deps/npm/man/man7/developers.7 @@ -1,4 +1,4 @@ -.TH "DEVELOPERS" "7" "July 2026" "NPM@11.19.0" "" +.TH "DEVELOPERS" "7" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBDevelopers\fR - Developer guide .SS "Description" diff --git a/deps/npm/man/man7/logging.7 b/deps/npm/man/man7/logging.7 index be1e6ea6fffa..7fab6e089256 100644 --- a/deps/npm/man/man7/logging.7 +++ b/deps/npm/man/man7/logging.7 @@ -1,4 +1,4 @@ -.TH "LOGGING" "7" "July 2026" "NPM@11.19.0" "" +.TH "LOGGING" "7" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBLogging\fR - Why, What & How we Log .SS "Description" diff --git a/deps/npm/man/man7/orgs.7 b/deps/npm/man/man7/orgs.7 index 43732ecdb5cb..975eded22dfc 100644 --- a/deps/npm/man/man7/orgs.7 +++ b/deps/npm/man/man7/orgs.7 @@ -1,4 +1,4 @@ -.TH "ORGANIZATIONS" "7" "July 2026" "NPM@11.19.0" "" +.TH "ORGANIZATIONS" "7" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBOrganizations\fR - Working with teams & organizations .SS "Description" diff --git a/deps/npm/man/man7/package-spec.7 b/deps/npm/man/man7/package-spec.7 index d76da151b48e..a68e9b8f7e74 100644 --- a/deps/npm/man/man7/package-spec.7 +++ b/deps/npm/man/man7/package-spec.7 @@ -1,4 +1,4 @@ -.TH "SPEC" "7" "July 2026" "NPM@11.19.0" "" +.TH "SPEC" "7" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBspec\fR - Package name specifier .SS "Description" diff --git a/deps/npm/man/man7/registry.7 b/deps/npm/man/man7/registry.7 index 16e295f6ac11..a91c60c14565 100644 --- a/deps/npm/man/man7/registry.7 +++ b/deps/npm/man/man7/registry.7 @@ -1,4 +1,4 @@ -.TH "REGISTRY" "7" "July 2026" "NPM@11.19.0" "" +.TH "REGISTRY" "7" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBRegistry\fR - The JavaScript Package Registry .SS "Description" diff --git a/deps/npm/man/man7/removal.7 b/deps/npm/man/man7/removal.7 index 1e0a0ddd0cf3..bb4d7a8d4365 100644 --- a/deps/npm/man/man7/removal.7 +++ b/deps/npm/man/man7/removal.7 @@ -1,4 +1,4 @@ -.TH "REMOVAL" "7" "July 2026" "NPM@11.19.0" "" +.TH "REMOVAL" "7" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBRemoval\fR - Cleaning the slate .SS "Synopsis" diff --git a/deps/npm/man/man7/scope.7 b/deps/npm/man/man7/scope.7 index 6bb685d20984..f2744feb1343 100644 --- a/deps/npm/man/man7/scope.7 +++ b/deps/npm/man/man7/scope.7 @@ -1,4 +1,4 @@ -.TH "SCOPE" "7" "July 2026" "NPM@11.19.0" "" +.TH "SCOPE" "7" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBScope\fR - Scoped packages .SS "Description" diff --git a/deps/npm/man/man7/scripts.7 b/deps/npm/man/man7/scripts.7 index 797e70b65138..4af3522042ba 100644 --- a/deps/npm/man/man7/scripts.7 +++ b/deps/npm/man/man7/scripts.7 @@ -1,4 +1,4 @@ -.TH "SCRIPTS" "7" "July 2026" "NPM@11.19.0" "" +.TH "SCRIPTS" "7" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBScripts\fR - How npm handles the "scripts" field .SS "Description" diff --git a/deps/npm/man/man7/workspaces.7 b/deps/npm/man/man7/workspaces.7 index fb9807cdfe4c..b31d897d2f3d 100644 --- a/deps/npm/man/man7/workspaces.7 +++ b/deps/npm/man/man7/workspaces.7 @@ -1,4 +1,4 @@ -.TH "WORKSPACES" "7" "July 2026" "NPM@11.19.0" "" +.TH "WORKSPACES" "7" "August 2026" "NPM@11.19.1" "" .SH "NAME" \fBWorkspaces\fR - Working with workspaces .SS "Description" diff --git a/deps/npm/node_modules/brace-expansion/dist/commonjs/index.js b/deps/npm/node_modules/brace-expansion/dist/commonjs/index.js index e4e5bd87666d..869a6bee2380 100644 --- a/deps/npm/node_modules/brace-expansion/dist/commonjs/index.js +++ b/deps/npm/node_modules/brace-expansion/dist/commonjs/index.js @@ -1,6 +1,6 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.EXPANSION_MAX = void 0; +exports.EXPANSION_MAX_LENGTH = exports.EXPANSION_MAX = void 0; exports.expand = expand; const balanced_match_1 = require("balanced-match"); const escSlash = '\0SLASH' + Math.random() + '\0'; @@ -19,6 +19,17 @@ const closePattern = /\\}/g; const commaPattern = /\\,/g; const periodPattern = /\\\./g; exports.EXPANSION_MAX = 100_000; +// `EXPANSION_MAX` caps the *number* of expansions, but not their length. An +// input like `'{a,b}'.repeat(1500)` stays under that count - its output is +// truncated to 100k results - while making every result ~1500 characters +// long. The result set, and the intermediate arrays built while combining +// brace sets, then grow large enough to exhaust memory and crash the process +// (CVE-2026-14257). `EXPANSION_MAX_LENGTH` bounds the total number of +// characters the accumulator may hold at any point, so memory stays flat no +// matter how many brace groups are chained. The limit sits well above any +// realistic expansion (100k results hitting `EXPANSION_MAX` measure ~1M +// characters) so legitimate input is unaffected. +exports.EXPANSION_MAX_LENGTH = 4_000_000; function numeric(str) { return !isNaN(str) ? parseInt(str, 10) : str.charCodeAt(0); } @@ -68,7 +79,7 @@ function expand(str, options = {}) { if (!str) { return []; } - const { max = exports.EXPANSION_MAX } = options; + const { max = exports.EXPANSION_MAX, maxLength = exports.EXPANSION_MAX_LENGTH } = options; // I don't know why Bash 4.3 does this, but it does. // Anything starting with {} will have the first two bytes preserved // but *only* at the top level, so {},a}b will not expand to anything, @@ -78,7 +89,7 @@ function expand(str, options = {}) { if (str.slice(0, 2) === '{}') { str = '\\{\\}' + str.slice(2); } - return expand_(escapeBraces(str), max, true).map(unescapeBraces); + return expand_(escapeBraces(str), max, maxLength, true).map(unescapeBraces); } function embrace(str) { return '{' + str + '}'; @@ -92,25 +103,116 @@ function lte(i, y) { function gte(i, y) { return i >= y; } -function expand_(str, max, isTop) { - /** @type {string[]} */ - const expansions = []; - // The `{a},b}` rewrite below restarts expansion on a rewritten string with - // the same `max` and `isTop = true`. Loop instead of recursing so a long run - // of non-expanding `{}` groups can't exhaust the call stack. +// Build `{ acc[a] + pre + values[v] }` for every combination, capping the +// number of results at `max` and the total number of characters at `maxLength`. +// This is the one place output grows, so bounding it here keeps the single +// accumulator - and therefore memory - flat regardless of how many brace groups +// are combined (CVE-2026-14257). +function combine(acc, pre, values, max, maxLength, dropEmpties) { + const out = []; + let length = 0; + for (let a = 0; a < acc.length; a++) { + for (let v = 0; v < values.length; v++) { + if (out.length >= max) + return out; + const expansion = acc[a] + pre + values[v]; + // Bash drops empty results at the top level. Skip them before they count + // against `max`, so `max` bounds the number of *kept* results. + if (dropEmpties && !expansion) + continue; + if (length + expansion.length > maxLength) + return out; + out.push(expansion); + length += expansion.length; + } + } + return out; +} +// The expansion values of a single numeric (`1..5`) or alphabetic (`a..e..2`) +// sequence body. +function expandSequence(body, isAlphaSequence, max, maxLength) { + const n = body.split(/\.\./); + const N = []; + // A sequence body always splits into two or three parts, but the compiler + // can't know that. + /* c8 ignore start */ + if (n[0] === undefined || n[1] === undefined) { + return N; + } + /* c8 ignore stop */ + const x = numeric(n[0]); + const y = numeric(n[1]); + const width = Math.max(n[0].length, n[1].length); + let incr = n.length === 3 && n[2] !== undefined ? + Math.max(Math.abs(numeric(n[2])), 1) + : 1; + let test = lte; + const reverse = y < x; + if (reverse) { + incr *= -1; + test = gte; + } + const pad = n.some(isPadded); + let length = 0; + for (let i = x; test(i, y) && N.length < max; i += incr) { + let c; + if (isAlphaSequence) { + c = String.fromCharCode(i); + if (c === '\\') { + c = ''; + } + } + else { + c = String(i); + if (pad) { + const need = width - c.length; + if (need > 0) { + const z = new Array(need + 1).join('0'); + if (i < 0) { + c = '-' + z + c.slice(1); + } + else { + c = z + c; + } + } + } + } + if (length + c.length > maxLength) + break; + N.push(c); + length += c.length; + } + return N; +} +function expand_(str, max, maxLength, isTop) { + // Consume the string's top-level brace groups left to right, threading a + // running set of combined prefixes (`acc`). Expanding the tail iteratively - + // rather than recursing on `m.post` once per group - keeps the native stack + // depth constant, so deeply chained input (`'{a,b}'.repeat(3000)`) can no + // longer overflow the stack, and leaves a single accumulator whose size + // `maxLength` bounds directly (CVE-2026-14257). + let acc = ['']; + // Bash drops empty results, but only when the *first* top-level group is a + // comma set - a sequence like `{a..\}` may legitimately yield ''. The drop + // is on the final strings, so it is applied to whichever `combine` produces + // them (the one with no brace set left in the tail). + let dropEmpties = false; + let firstGroup = true; for (;;) { const m = (0, balanced_match_1.balanced)('{', '}', str); - if (!m) - return [str]; + // No brace set left: the rest of the string is literal. + if (!m) { + return combine(acc, str, [''], max, maxLength, dropEmpties); + } // no need to expand pre, since it is guaranteed to be free of brace-sets const pre = m.pre; - if (/\$$/.test(m.pre)) { - const post = m.post.length ? expand_(m.post, max, false) : ['']; - for (let k = 0; k < post.length && k < max; k++) { - const expansion = pre + '{' + m.body + '}' + post[k]; - expansions.push(expansion); - } - return expansions; + if (/\$$/.test(pre)) { + acc = combine(acc, pre + '{' + m.body + '}', [''], max, maxLength, dropEmpties && !m.post.length); + firstGroup = false; + if (!m.post.length) + break; + str = m.post; + continue; } const isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); const isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); @@ -123,89 +225,65 @@ function expand_(str, max, isTop) { isTop = true; continue; } - return [str]; + // Nothing here expands, so the whole remaining string is literal. + return combine(acc, pre + '{' + m.body + '}' + m.post, [''], max, maxLength, dropEmpties); + } + if (firstGroup) { + dropEmpties = isTop && !isSequence; + firstGroup = false; } - // Only expand post once we know this brace set actually expands. Computing - // it before the early returns above expanded post a second time on every - // non-expanding `{}`, which is what made inputs like `a{},{},{}...` blow up - // exponentially. - const post = m.post.length ? expand_(m.post, max, false) : ['']; - let n; + let values; if (isSequence) { - n = m.body.split(/\.\./); + values = expandSequence(m.body, isAlphaSequence, max, maxLength); } else { - n = parseCommaParts(m.body); + let n = parseCommaParts(m.body); if (n.length === 1 && n[0] !== undefined) { // x{{a,b}}y ==> x{a}y x{b}y - n = expand_(n[0], max, false).map(embrace); + n = expand_(n[0], max, maxLength, false).map(embrace); //XXX is this necessary? Can't seem to hit it in tests. /* c8 ignore start */ if (n.length === 1) { - return post.map(p => m.pre + n[0] + p); + acc = combine(acc, pre + n[0], [''], max, maxLength, dropEmpties && !m.post.length); + if (!m.post.length) + break; + str = m.post; + continue; } /* c8 ignore stop */ } - } - // at this point, n is the parts, and we know it's not a comma set - // with a single entry. - let N; - if (isSequence && n[0] !== undefined && n[1] !== undefined) { - const x = numeric(n[0]); - const y = numeric(n[1]); - const width = Math.max(n[0].length, n[1].length); - let incr = n.length === 3 && n[2] !== undefined ? - Math.max(Math.abs(numeric(n[2])), 1) - : 1; - let test = lte; - const reverse = y < x; - if (reverse) { - incr *= -1; - test = gte; - } - const pad = n.some(isPadded); - N = []; - for (let i = x; test(i, y) && N.length < max; i += incr) { - let c; - if (isAlphaSequence) { - c = String.fromCharCode(i); - if (c === '\\') { - c = ''; - } + // Values that `combine` is going to drop as empty produce no result, so + // they must not count against `max` - otherwise `{a,,b}` with `max: 2` + // would stop at `['a', '']` and yield one result instead of two. Skipping + // them outright keeps `values` bounded while leaving `max` a bound on + // *kept* results. + let dropsEmpties = dropEmpties && !m.post.length && !pre; + for (let d = 0; dropsEmpties && d < acc.length; d++) { + if (acc[d]) { + dropsEmpties = false; } - else { - c = String(i); - if (pad) { - const need = width - c.length; - if (need > 0) { - const z = new Array(need + 1).join('0'); - if (i < 0) { - c = '-' + z + c.slice(1); - } - else { - c = z + c; - } - } - } - } - N.push(c); } - } - else { - N = []; - for (let j = 0; j < n.length; j++) { - N.push.apply(N, expand_(n[j], max, false)); - } - } - for (let j = 0; j < N.length; j++) { - for (let k = 0; k < post.length && expansions.length < max; k++) { - const expansion = pre + N[j] + post[k]; - if (!isTop || isSequence || expansion) { - expansions.push(expansion); + values = []; + let valuesLength = 0; + outer: for (let j = 0; j < n.length; j++) { + const expanded = expand_(n[j], max, maxLength, false); + for (let k = 0; k < expanded.length; k++) { + const v = expanded[k]; + if (dropsEmpties && !v) + continue; + if (values.length >= max || valuesLength + v.length > maxLength) { + break outer; + } + values.push(v); + valuesLength += v.length; } } } - return expansions; + acc = combine(acc, pre, values, max, maxLength, dropEmpties && !m.post.length); + if (!m.post.length) + break; + str = m.post; } + return acc; } //# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/deps/npm/node_modules/brace-expansion/dist/esm/index.js b/deps/npm/node_modules/brace-expansion/dist/esm/index.js index b2d2aa91bb1c..fd68f5702920 100644 --- a/deps/npm/node_modules/brace-expansion/dist/esm/index.js +++ b/deps/npm/node_modules/brace-expansion/dist/esm/index.js @@ -15,6 +15,17 @@ const closePattern = /\\}/g; const commaPattern = /\\,/g; const periodPattern = /\\\./g; export const EXPANSION_MAX = 100_000; +// `EXPANSION_MAX` caps the *number* of expansions, but not their length. An +// input like `'{a,b}'.repeat(1500)` stays under that count - its output is +// truncated to 100k results - while making every result ~1500 characters +// long. The result set, and the intermediate arrays built while combining +// brace sets, then grow large enough to exhaust memory and crash the process +// (CVE-2026-14257). `EXPANSION_MAX_LENGTH` bounds the total number of +// characters the accumulator may hold at any point, so memory stays flat no +// matter how many brace groups are chained. The limit sits well above any +// realistic expansion (100k results hitting `EXPANSION_MAX` measure ~1M +// characters) so legitimate input is unaffected. +export const EXPANSION_MAX_LENGTH = 4_000_000; function numeric(str) { return !isNaN(str) ? parseInt(str, 10) : str.charCodeAt(0); } @@ -64,7 +75,7 @@ export function expand(str, options = {}) { if (!str) { return []; } - const { max = EXPANSION_MAX } = options; + const { max = EXPANSION_MAX, maxLength = EXPANSION_MAX_LENGTH } = options; // I don't know why Bash 4.3 does this, but it does. // Anything starting with {} will have the first two bytes preserved // but *only* at the top level, so {},a}b will not expand to anything, @@ -74,7 +85,7 @@ export function expand(str, options = {}) { if (str.slice(0, 2) === '{}') { str = '\\{\\}' + str.slice(2); } - return expand_(escapeBraces(str), max, true).map(unescapeBraces); + return expand_(escapeBraces(str), max, maxLength, true).map(unescapeBraces); } function embrace(str) { return '{' + str + '}'; @@ -88,25 +99,116 @@ function lte(i, y) { function gte(i, y) { return i >= y; } -function expand_(str, max, isTop) { - /** @type {string[]} */ - const expansions = []; - // The `{a},b}` rewrite below restarts expansion on a rewritten string with - // the same `max` and `isTop = true`. Loop instead of recursing so a long run - // of non-expanding `{}` groups can't exhaust the call stack. +// Build `{ acc[a] + pre + values[v] }` for every combination, capping the +// number of results at `max` and the total number of characters at `maxLength`. +// This is the one place output grows, so bounding it here keeps the single +// accumulator - and therefore memory - flat regardless of how many brace groups +// are combined (CVE-2026-14257). +function combine(acc, pre, values, max, maxLength, dropEmpties) { + const out = []; + let length = 0; + for (let a = 0; a < acc.length; a++) { + for (let v = 0; v < values.length; v++) { + if (out.length >= max) + return out; + const expansion = acc[a] + pre + values[v]; + // Bash drops empty results at the top level. Skip them before they count + // against `max`, so `max` bounds the number of *kept* results. + if (dropEmpties && !expansion) + continue; + if (length + expansion.length > maxLength) + return out; + out.push(expansion); + length += expansion.length; + } + } + return out; +} +// The expansion values of a single numeric (`1..5`) or alphabetic (`a..e..2`) +// sequence body. +function expandSequence(body, isAlphaSequence, max, maxLength) { + const n = body.split(/\.\./); + const N = []; + // A sequence body always splits into two or three parts, but the compiler + // can't know that. + /* c8 ignore start */ + if (n[0] === undefined || n[1] === undefined) { + return N; + } + /* c8 ignore stop */ + const x = numeric(n[0]); + const y = numeric(n[1]); + const width = Math.max(n[0].length, n[1].length); + let incr = n.length === 3 && n[2] !== undefined ? + Math.max(Math.abs(numeric(n[2])), 1) + : 1; + let test = lte; + const reverse = y < x; + if (reverse) { + incr *= -1; + test = gte; + } + const pad = n.some(isPadded); + let length = 0; + for (let i = x; test(i, y) && N.length < max; i += incr) { + let c; + if (isAlphaSequence) { + c = String.fromCharCode(i); + if (c === '\\') { + c = ''; + } + } + else { + c = String(i); + if (pad) { + const need = width - c.length; + if (need > 0) { + const z = new Array(need + 1).join('0'); + if (i < 0) { + c = '-' + z + c.slice(1); + } + else { + c = z + c; + } + } + } + } + if (length + c.length > maxLength) + break; + N.push(c); + length += c.length; + } + return N; +} +function expand_(str, max, maxLength, isTop) { + // Consume the string's top-level brace groups left to right, threading a + // running set of combined prefixes (`acc`). Expanding the tail iteratively - + // rather than recursing on `m.post` once per group - keeps the native stack + // depth constant, so deeply chained input (`'{a,b}'.repeat(3000)`) can no + // longer overflow the stack, and leaves a single accumulator whose size + // `maxLength` bounds directly (CVE-2026-14257). + let acc = ['']; + // Bash drops empty results, but only when the *first* top-level group is a + // comma set - a sequence like `{a..\}` may legitimately yield ''. The drop + // is on the final strings, so it is applied to whichever `combine` produces + // them (the one with no brace set left in the tail). + let dropEmpties = false; + let firstGroup = true; for (;;) { const m = balanced('{', '}', str); - if (!m) - return [str]; + // No brace set left: the rest of the string is literal. + if (!m) { + return combine(acc, str, [''], max, maxLength, dropEmpties); + } // no need to expand pre, since it is guaranteed to be free of brace-sets const pre = m.pre; - if (/\$$/.test(m.pre)) { - const post = m.post.length ? expand_(m.post, max, false) : ['']; - for (let k = 0; k < post.length && k < max; k++) { - const expansion = pre + '{' + m.body + '}' + post[k]; - expansions.push(expansion); - } - return expansions; + if (/\$$/.test(pre)) { + acc = combine(acc, pre + '{' + m.body + '}', [''], max, maxLength, dropEmpties && !m.post.length); + firstGroup = false; + if (!m.post.length) + break; + str = m.post; + continue; } const isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); const isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); @@ -119,89 +221,65 @@ function expand_(str, max, isTop) { isTop = true; continue; } - return [str]; + // Nothing here expands, so the whole remaining string is literal. + return combine(acc, pre + '{' + m.body + '}' + m.post, [''], max, maxLength, dropEmpties); + } + if (firstGroup) { + dropEmpties = isTop && !isSequence; + firstGroup = false; } - // Only expand post once we know this brace set actually expands. Computing - // it before the early returns above expanded post a second time on every - // non-expanding `{}`, which is what made inputs like `a{},{},{}...` blow up - // exponentially. - const post = m.post.length ? expand_(m.post, max, false) : ['']; - let n; + let values; if (isSequence) { - n = m.body.split(/\.\./); + values = expandSequence(m.body, isAlphaSequence, max, maxLength); } else { - n = parseCommaParts(m.body); + let n = parseCommaParts(m.body); if (n.length === 1 && n[0] !== undefined) { // x{{a,b}}y ==> x{a}y x{b}y - n = expand_(n[0], max, false).map(embrace); + n = expand_(n[0], max, maxLength, false).map(embrace); //XXX is this necessary? Can't seem to hit it in tests. /* c8 ignore start */ if (n.length === 1) { - return post.map(p => m.pre + n[0] + p); + acc = combine(acc, pre + n[0], [''], max, maxLength, dropEmpties && !m.post.length); + if (!m.post.length) + break; + str = m.post; + continue; } /* c8 ignore stop */ } - } - // at this point, n is the parts, and we know it's not a comma set - // with a single entry. - let N; - if (isSequence && n[0] !== undefined && n[1] !== undefined) { - const x = numeric(n[0]); - const y = numeric(n[1]); - const width = Math.max(n[0].length, n[1].length); - let incr = n.length === 3 && n[2] !== undefined ? - Math.max(Math.abs(numeric(n[2])), 1) - : 1; - let test = lte; - const reverse = y < x; - if (reverse) { - incr *= -1; - test = gte; - } - const pad = n.some(isPadded); - N = []; - for (let i = x; test(i, y) && N.length < max; i += incr) { - let c; - if (isAlphaSequence) { - c = String.fromCharCode(i); - if (c === '\\') { - c = ''; - } + // Values that `combine` is going to drop as empty produce no result, so + // they must not count against `max` - otherwise `{a,,b}` with `max: 2` + // would stop at `['a', '']` and yield one result instead of two. Skipping + // them outright keeps `values` bounded while leaving `max` a bound on + // *kept* results. + let dropsEmpties = dropEmpties && !m.post.length && !pre; + for (let d = 0; dropsEmpties && d < acc.length; d++) { + if (acc[d]) { + dropsEmpties = false; } - else { - c = String(i); - if (pad) { - const need = width - c.length; - if (need > 0) { - const z = new Array(need + 1).join('0'); - if (i < 0) { - c = '-' + z + c.slice(1); - } - else { - c = z + c; - } - } - } - } - N.push(c); } - } - else { - N = []; - for (let j = 0; j < n.length; j++) { - N.push.apply(N, expand_(n[j], max, false)); - } - } - for (let j = 0; j < N.length; j++) { - for (let k = 0; k < post.length && expansions.length < max; k++) { - const expansion = pre + N[j] + post[k]; - if (!isTop || isSequence || expansion) { - expansions.push(expansion); + values = []; + let valuesLength = 0; + outer: for (let j = 0; j < n.length; j++) { + const expanded = expand_(n[j], max, maxLength, false); + for (let k = 0; k < expanded.length; k++) { + const v = expanded[k]; + if (dropsEmpties && !v) + continue; + if (values.length >= max || valuesLength + v.length > maxLength) { + break outer; + } + values.push(v); + valuesLength += v.length; } } } - return expansions; + acc = combine(acc, pre, values, max, maxLength, dropEmpties && !m.post.length); + if (!m.post.length) + break; + str = m.post; } + return acc; } //# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/deps/npm/node_modules/brace-expansion/package.json b/deps/npm/node_modules/brace-expansion/package.json index a5142f2787b6..4376400796c9 100644 --- a/deps/npm/node_modules/brace-expansion/package.json +++ b/deps/npm/node_modules/brace-expansion/package.json @@ -1,7 +1,7 @@ { "name": "brace-expansion", "description": "Brace expansion as known from sh/bash", - "version": "5.0.7", + "version": "5.0.9", "files": [ "dist" ], @@ -46,7 +46,7 @@ }, "license": "MIT", "engines": { - "node": "18 || 20 || >=22" + "node": "20 || >=22" }, "tshy": { "exports": { diff --git a/deps/npm/node_modules/ip-address/dist/common.js b/deps/npm/node_modules/ip-address/dist/common.js index 6b76e051b44e..0c15d21e3a39 100644 --- a/deps/npm/node_modules/ip-address/dist/common.js +++ b/deps/npm/node_modules/ip-address/dist/common.js @@ -1,23 +1,47 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.isInSubnet = isInSubnet; +exports.isHostInSubnet = isHostInSubnet; exports.isCorrect = isCorrect; exports.prefixLengthFromMask = prefixLengthFromMask; +exports.assertByteArray = assertByteArray; exports.numberToPaddedHex = numberToPaddedHex; exports.stringToPaddedHex = stringToPaddedHex; exports.testBit = testBit; const address_error_1 = require("./address-error"); +/** + * Returns whether this address's *network* is contained within `address`, + * i.e. whether every address this one can represent also falls inside + * `address`. A network wider than `address` is not contained in it, so + * `10.0.0.0/8` is not in `10.0.0.0/16`. + * + * To ask whether the address itself falls inside a range, ignoring any CIDR + * suffix it was written with, use {@link isHostInSubnet} instead. That is the + * question the special-use classifiers ask. + */ function isInSubnet(address) { if (this.subnetMask < address.subnetMask) { return false; } - if (this.mask(address.subnetMask) === address.mask()) { - return true; - } - return false; + return isHostInSubnet.call(this, address); +} +/** + * Returns whether this address's host bits fall inside `address`, ignoring + * this address's own subnet mask. + * + * This is the primitive the special-use classifiers (`isLoopback`, + * `isPrivate`, `isLinkLocal`, `getType`, …) are built on: they answer a + * question about the address, so the answer must not change with the CIDR + * suffix the caller happened to write. Use this rather than + * {@link isInSubnet} when classifying a single address — notably when the + * address came from untrusted input and the result backs a trust-boundary + * decision such as an SSRF allow/deny filter. + */ +function isHostInSubnet(address) { + return this.mask(address.subnetMask) === address.mask(); } function isCorrect(defaultBits) { - return function () { + return function isCorrectForm() { if (this.addressMinusSuffix !== this.correctForm()) { return false; } @@ -46,6 +70,21 @@ function prefixLengthFromMask(value, totalBits) { } return firstZero; } +/** + * Throws `AddressError` unless `bytes` holds exactly `byteCount` integers, + * each from `minimum` to 255. Pass a `minimum` of `-128` where signed bytes + * are accepted and folded to unsigned, and `0` where they are not. + */ +function assertByteArray(bytes, byteCount, family, minimum) { + if (bytes.length !== byteCount) { + throw new address_error_1.AddressError(`${family} addresses require exactly ${byteCount} bytes`); + } + for (let i = 0; i < bytes.length; i++) { + if (!Number.isInteger(bytes[i]) || bytes[i] < minimum || bytes[i] > 255) { + throw new address_error_1.AddressError(`All bytes must be integers between ${minimum} and 255`); + } + } +} function numberToPaddedHex(number) { return number.toString(16).padStart(2, '0'); } diff --git a/deps/npm/node_modules/ip-address/dist/ipv4.js b/deps/npm/node_modules/ip-address/dist/ipv4.js index 2c0fd182086d..1360e1836a0d 100644 --- a/deps/npm/node_modules/ip-address/dist/ipv4.js +++ b/deps/npm/node_modules/ip-address/dist/ipv4.js @@ -35,6 +35,7 @@ const isCorrect4 = common.isCorrect(constants.BITS); */ class Address4 { constructor(address) { + this.addressMinusSuffix = ''; this.groups = constants.GROUPS; this.parsedAddress = []; this.parsedSubnet = ''; @@ -51,6 +52,15 @@ class Address4 { * @returns {boolean} */ this.isInSubnet = common.isInSubnet; + /** + * Returns true if this address's host bits fall inside the given subnet, + * ignoring this address's own subnet mask. Prefer this over `isInSubnet` + * when classifying a single address, so the answer doesn't change with the + * CIDR suffix the caller happened to write — notably when the address came + * from untrusted input and the result backs a trust-boundary decision. + * @returns {boolean} + */ + this.isHostInSubnet = common.isHostInSubnet; this.address = address; const subnet = constants.RE_SUBNET_STRING.exec(address); if (subnet) { @@ -78,7 +88,7 @@ class Address4 { new Address4(address); return true; } - catch (e) { + catch { return false; } } @@ -90,6 +100,11 @@ class Address4 { */ parse(address) { const groups = address.split('.'); + // Checked before the general match so the error names the actual problem. + // Address6 rejects the same notation on its v4-in-v6 path. + if (groups.some((group) => /^0\d/.test(group))) { + throw new address_error_1.AddressError("IPv4 addresses can't have leading zeroes."); + } if (!address.match(constants.RE_ADDRESS)) { throw new address_error_1.AddressError('Invalid IPv4 address.'); } @@ -128,7 +143,6 @@ class Address4 { static fromAddressAndWildcardMask(address, wildcardMask) { const wildcard = new Address4(wildcardMask).bigInt(); const allOnes = (BigInt(1) << BigInt(constants.BITS)) - BigInt(1); - // eslint-disable-next-line no-bitwise const mask = wildcard ^ allOnes; const bits = common.prefixLengthFromMask(mask, constants.BITS); return new Address4(`${address}/${bits}`); @@ -328,32 +342,32 @@ class Address4 { * @returns {Address4} */ static fromBigInt(bigInt) { - if (bigInt < 0n || bigInt > 0xffffffffn) { + if (bigInt < BigInt(0) || bigInt > BigInt(0xffffffff)) { throw new address_error_1.AddressError('IPv4 BigInt must be in the range 0 to 2**32 - 1'); } return Address4.fromHex(bigInt.toString(16).padStart(8, '0')); } /** - * Convert a byte array to an Address4 object. + * Convert a byte array to an Address4 object. Throws `AddressError` unless + * given exactly 4 integers from 0 to 255. Signed bytes are rejected, so + * this differs from `Address6.fromByteArray`, which folds them; the two + * contracts converge on this stricter form in the next major version. * * To convert from a Node.js `Buffer`, spread it: `Address4.fromByteArray([...buf])`. * @param {Array} bytes - an array of 4 bytes (0-255) * @returns {Address4} */ static fromByteArray(bytes) { - if (bytes.length !== 4) { - throw new address_error_1.AddressError('IPv4 addresses require exactly 4 bytes'); - } - // Validate that all bytes are within valid range (0-255) - for (let i = 0; i < bytes.length; i++) { - if (!Number.isInteger(bytes[i]) || bytes[i] < 0 || bytes[i] > 255) { - throw new address_error_1.AddressError('All bytes must be integers between 0 and 255'); - } - } + common.assertByteArray(bytes, 4, 'IPv4', 0); return this.fromUnsignedByteArray(bytes); } /** - * Convert an unsigned byte array to an Address4 object + * Convert an unsigned byte array to an Address4 object. Throws + * `AddressError` unless given exactly 4 bytes, and rejects values outside + * 0 to 255 when parsing the resulting address. + * + * To convert from a Node.js `Buffer`, spread it: + * `Address4.fromUnsignedByteArray([...buf])`. * @param {Array} bytes - an array of 4 unsigned bytes (0-255) * @returns {Address4} */ @@ -383,7 +397,8 @@ class Address4 { return this.binaryZeroPad().slice(start, end); } /** - * Return the reversed ip6.arpa form of the address + * Return the reversed in-addr.arpa form of the address, e.g. + * `42.2.0.192.in-addr.arpa.` for `192.0.2.42`. * @param {Object} options * @param {boolean} options.omitSuffix - omit the "in-addr.arpa" suffix * @returns {String} @@ -403,49 +418,49 @@ class Address4 { * @returns {boolean} */ isMulticast() { - return this.isInSubnet(MULTICAST_V4); + return this.isHostInSubnet(MULTICAST_V4); } /** * Returns true if the address is in one of the [RFC 1918](https://datatracker.ietf.org/doc/html/rfc1918) private address ranges (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`). * @returns {boolean} */ isPrivate() { - return PRIVATE_V4.some((subnet) => this.isInSubnet(subnet)); + return PRIVATE_V4.some((subnet) => this.isHostInSubnet(subnet)); } /** * Returns true if the address is in the loopback range `127.0.0.0/8` ([RFC 1122](https://datatracker.ietf.org/doc/html/rfc1122)). * @returns {boolean} */ isLoopback() { - return this.isInSubnet(LOOPBACK_V4); + return this.isHostInSubnet(LOOPBACK_V4); } /** * Returns true if the address is in the link-local range `169.254.0.0/16` ([RFC 3927](https://datatracker.ietf.org/doc/html/rfc3927)). * @returns {boolean} */ isLinkLocal() { - return this.isInSubnet(LINK_LOCAL_V4); + return this.isHostInSubnet(LINK_LOCAL_V4); } /** * Returns true if the address is the unspecified address `0.0.0.0`. * @returns {boolean} */ isUnspecified() { - return this.isInSubnet(UNSPECIFIED_V4); + return this.isHostInSubnet(UNSPECIFIED_V4); } /** * Returns true if the address is the limited broadcast address `255.255.255.255` ([RFC 919](https://datatracker.ietf.org/doc/html/rfc919)). * @returns {boolean} */ isBroadcast() { - return this.isInSubnet(BROADCAST_V4); + return this.isHostInSubnet(BROADCAST_V4); } /** * Returns true if the address is in the carrier-grade NAT range `100.64.0.0/10` ([RFC 6598](https://datatracker.ietf.org/doc/html/rfc6598)). * @returns {boolean} */ isCGNAT() { - return this.isInSubnet(CGNAT_V4); + return this.isHostInSubnet(CGNAT_V4); } /** * Returns a zero-padded base-2 string representation of the address @@ -458,12 +473,17 @@ class Address4 { return this._binaryZeroPad; } /** - * Groups an IPv4 address for inclusion at the end of an IPv6 address + * Groups an IPv4 address for inclusion at the end of an IPv6 address. + * + * Returns an HTML fragment: each half of the address is wrapped in a + * `` carrying the group classes an address-inspector UI hovers on. + * The address content is HTML-escaped; anything you concatenate around it + * is your responsibility. * @returns {String} */ groupForV6() { const segments = this.parsedAddress; - return this.address.replace(constants.RE_ADDRESS, `${segments + return this.correctForm().replace(constants.RE_ADDRESS, `${segments .slice(0, 2) .join('.')}.${segments .slice(2, 4) diff --git a/deps/npm/node_modules/ip-address/dist/ipv6.js b/deps/npm/node_modules/ip-address/dist/ipv6.js index a78020ee7886..d5f4fdb9c87a 100644 --- a/deps/npm/node_modules/ip-address/dist/ipv6.js +++ b/deps/npm/node_modules/ip-address/dist/ipv6.js @@ -73,7 +73,6 @@ function paddedHex(octet) { return parseInt(octet, 16).toString(16).padStart(4, '0'); } function unsignByte(b) { - // eslint-disable-next-line no-bitwise return b & 0xff; } /** @@ -97,6 +96,15 @@ class Address6 { * @returns {boolean} */ this.isInSubnet = common.isInSubnet; + /** + * Returns true if this address's host bits fall inside the given subnet, + * ignoring this address's own subnet mask. Prefer this over `isInSubnet` + * when classifying a single address, so the answer doesn't change with the + * CIDR suffix the caller happened to write — notably when the address came + * from untrusted input and the result backs a trust-boundary decision. + * @returns {boolean} + */ + this.isHostInSubnet = common.isHostInSubnet; /** * Returns true if the address is correct, false otherwise * @returns {boolean} @@ -121,7 +129,10 @@ class Address6 { } address = address.replace(constants6.RE_SUBNET_STRING, ''); } - else if (/\//.test(address)) { + // RE_SUBNET_STRING anchors on the end of the address, so it strips only + // the trailing suffix. A second one left behind (`::/0/1`) is malformed + // and must be rejected rather than parsed as an address group. + if (/\//.test(address)) { throw new address_error_1.AddressError('Invalid subnet mask.'); } const zone = constants6.RE_ZONE_STRING.exec(address); @@ -145,7 +156,7 @@ class Address6 { new Address6(address); return true; } - catch (e) { + catch { return false; } } @@ -160,7 +171,7 @@ class Address6 { * address.correctForm(); // '::e8:d4a5:1000' */ static fromBigInt(bigInt) { - if (bigInt < 0n || bigInt > (1n << BigInt(constants6.BITS)) - 1n) { + if (bigInt < BigInt(0) || bigInt > (BigInt(1) << BigInt(constants6.BITS)) - BigInt(1)) { throw new address_error_1.AddressError('IPv6 BigInt must be in the range 0 to 2**128 - 1'); } const hex = bigInt.toString(16).padStart(32, '0'); @@ -181,46 +192,36 @@ class Address6 { * addressAndPort.port; // 8080 */ static fromURL(url) { + var _a; let host; let port = null; let result; + let error; + // Remove the protocol prefix, if any + const stripped = url.replace(/^[a-z][a-z0-9+.-]*:\/\//i, ''); // If we have brackets parse them and find a port - if (url.indexOf('[') !== -1 && url.indexOf(']:') !== -1) { - result = constants6.RE_URL_WITH_PORT.exec(url); + if (stripped.indexOf('[') !== -1 && stripped.indexOf(']:') !== -1) { + error = 'failed to parse address with port'; + result = constants6.RE_URL_WITH_PORT.exec(stripped); if (result === null) { - return { - error: 'failed to parse address with port', - address: null, - port: null, - }; + return { error, address: null, port: null }; } host = result[1]; port = result[2]; - // If there's a URL extract the address } - else if (url.indexOf('/') !== -1) { - // Remove the protocol prefix - url = url.replace(/^[a-z0-9]+:\/\//, ''); - // Parse the address - result = constants6.RE_URL.exec(url); + else { + error = 'failed to parse address from URL'; + result = constants6.RE_URL.exec(stripped); if (result === null) { - return { - error: 'failed to parse address from URL', - address: null, - port: null, - }; + return { error, address: null, port: null }; } - host = result[1]; - // Otherwise just assign the URL to the host and let the library parse it - } - else { - host = url; + host = (_a = result[1]) !== null && _a !== void 0 ? _a : result[2]; } // If there's a port convert it to an integer if (port) { port = parseInt(port, 10); - // squelch out of range ports - if (port < 0 || port > 65536) { + // squelch out of range ports (valid ports are 0-65535) + if (port < 0 || port > 65535) { port = null; } } @@ -228,10 +229,17 @@ class Address6 { // Standardize `undefined` to `null` port = null; } - return { - address: new Address6(host), - port, - }; + // The URL character class is a superset of valid IPv6, so a host the + // regex accepted (an IPv4 literal, bare punctuation, too many groups) + // can still be rejected by the parser + let address; + try { + address = new Address6(host); + } + catch { + return { error, address: null, port: null }; + } + return { address, port }; } /** * Construct an `Address6` from an address and a hex subnet mask given as @@ -258,7 +266,6 @@ class Address6 { static fromAddressAndWildcardMask(address, wildcardMask) { const wildcard = new Address6(wildcardMask).bigInt(); const allOnes = (BigInt(1) << BigInt(constants6.BITS)) - BigInt(1); - // eslint-disable-next-line no-bitwise const mask = wildcard ^ allOnes; const bits = common.prefixLengthFromMask(mask, constants6.BITS); return new Address6(`${address}/${bits}`); @@ -493,7 +500,7 @@ class Address6 { getType() { for (let i = 0; i < TYPE_SUBNETS.length; i++) { const entry = TYPE_SUBNETS[i]; - if (this.isInSubnet(entry[0])) { + if (this.isHostInSubnet(entry[0])) { return entry[1]; } } @@ -635,20 +642,27 @@ class Address6 { } const groups = address.split(':'); const lastGroup = groups.slice(-1)[0]; + // RE_ADDRESS rejects octets with a leading zero, so a dotted-quad tail is + // matched permissively first: that way this notation still gets its own + // message with the offending octet highlighted, rather than falling + // through as an unrecognized group. + const v4Octets = lastGroup.split('.'); + if (v4Octets.length === constants4.GROUPS && + v4Octets.every((octet) => /^\d{1,3}$/.test(octet))) { + if (v4Octets.some((octet) => /^0\d/.test(octet))) { + // The prefix groups haven't been through the bad-character check + // yet, so escape them before including in the error HTML. + const highlighted = v4Octets.map(spanLeadingZeroes4).join('.'); + const prefix = groups.slice(0, -1).map(helpers.escapeHtml).join(':'); + const separator = groups.length > 1 ? ':' : ''; + throw new address_error_1.AddressError("IPv4 addresses can't have leading zeroes.", `${prefix}${separator}${highlighted}`); + } + } const address4 = lastGroup.match(constants4.RE_ADDRESS); if (address4) { this.parsedAddress4 = address4[0]; - this.address4 = new ipv4_1.Address4(this.parsedAddress4); - for (let i = 0; i < this.address4.groups; i++) { - if (/^0[0-9]+/.test(this.address4.parsedAddress[i])) { - // The prefix groups haven't been through the bad-character check - // yet, so escape them before including in the error HTML. - const highlighted = this.address4.parsedAddress.map(spanLeadingZeroes4).join('.'); - const prefix = groups.slice(0, -1).map(helpers.escapeHtml).join(':'); - const separator = groups.length > 1 ? ':' : ''; - throw new address_error_1.AddressError("IPv4 addresses can't have leading zeroes.", `${prefix}${separator}${highlighted}`); - } - } + const v4Suffix = this.subnetMask >= 96 ? `/${this.subnetMask - 96}` : ''; + this.address4 = new ipv4_1.Address4(`${this.parsedAddress4}${v4Suffix}`); this.v4 = true; groups[groups.length - 1] = this.address4.toGroup6(); address = groups.join(':'); @@ -734,7 +748,11 @@ class Address6 { return BigInt(`0x${this.parsedAddress.map(paddedHex).join('')}`); } /** - * Return the last two groups of this address as an IPv4 address string + * Return the last two groups of this address as an IPv4 address string. + * If this address carries a CIDR prefix that covers the trailing 32 bits + * (i.e. `subnetMask >= 96`), the resulting `Address4` inherits the + * corresponding v4 prefix (`subnetMask - 96`); otherwise it defaults to + * `/32`. * @returns {Address4} * @example * var address = new Address6('2001:4860:4001::1825:bf11'); @@ -742,7 +760,18 @@ class Address6 { */ to4() { const binary = this.binaryZeroPad().split(''); - return ipv4_1.Address4.fromHex(BigInt(`0b${binary.slice(96, 128).join('')}`).toString(16).padStart(8, '0')); + const hex = BigInt(`0b${binary.slice(96, 128).join('')}`) + .toString(16) + .padStart(8, '0'); + if (this.subnetMask >= 96) { + const v4Mask = this.subnetMask - 96; + const groups = []; + for (let i = 0; i < 8; i += 2) { + groups.push(parseInt(hex.slice(i, i + 2), 16)); + } + return new ipv4_1.Address4(`${groups.join('.')}/${v4Mask}`); + } + return ipv4_1.Address4.fromHex(hex); } /** * Return the v4-in-v6 form of the address @@ -756,7 +785,7 @@ class Address6 { if (!/:$/.test(correct)) { infix = ':'; } - return correct + infix + address4.address; + return correct + infix + address4.correctForm(); } /** * Decodes the Teredo tunneling fields embedded in this address. Returns the @@ -788,11 +817,9 @@ class Address6 { */ const prefix = this.getBitsBase16(0, 32); const bitsForUdpPort = this.getBits(80, 96); - // eslint-disable-next-line no-bitwise const udpPort = (bitsForUdpPort ^ BigInt('0xffff')).toString(); const server4 = ipv4_1.Address4.fromHex(this.getBitsBase16(32, 64)); const bitsForClient4 = this.getBits(96, 128); - // eslint-disable-next-line no-bitwise const client4 = ipv4_1.Address4.fromHex((bitsForClient4 ^ BigInt('0xffffffff')).toString(16).padStart(8, '0')); const flagsBase2 = this.getBitsBase2(64, 80); const coneNat = (0, common_1.testBit)(flagsBase2, 15); @@ -874,12 +901,14 @@ class Address6 { } else { const beforeU = 64 - pl; - bits = - prefixBits.slice(0, pl) + - v4Bits.slice(0, beforeU) + - '00000000' + - v4Bits.slice(beforeU) + - '0'.repeat(128 - 72 - (32 - beforeU)); + bits = [ + prefixBits.slice(0, pl), + v4Bits.slice(0, beforeU), + // Bits 64 to 71 are the reserved u octet and are always zero. + '00000000', + v4Bits.slice(beforeU), + '0'.repeat(128 - 72 - (32 - beforeU)), + ].join(''); } const hex = BigInt(`0b${bits}`).toString(16).padStart(32, '0'); const groups = []; @@ -902,7 +931,7 @@ class Address6 { if (pl !== 32 && pl !== 40 && pl !== 48 && pl !== 56 && pl !== 64 && pl !== 96) { throw new address_error_1.AddressError('NAT64 prefix length must be 32, 40, 48, 56, 64, or 96'); } - if (!this.isInSubnet(prefix6)) { + if (!this.isHostInSubnet(prefix6)) { return null; } const bits = this.binaryZeroPad(); @@ -927,9 +956,9 @@ class Address6 { * @returns {Array} */ toByteArray() { - const valueWithoutPadding = this.bigInt().toString(16); - const leadingPad = '0'.repeat(valueWithoutPadding.length % 2); - const value = `${leadingPad}${valueWithoutPadding}`; + const value = this.bigInt() + .toString(16) + .padStart(constants6.BITS / 4, '0'); const bytes = []; for (let i = 0, length = value.length; i < length; i += 2) { bytes.push(parseInt(value.substring(i, i + 2), 16)); @@ -943,24 +972,39 @@ class Address6 { * @returns {Array} */ toUnsignedByteArray() { + // toByteArray() emits 0 to 255, so unsigning it is an identity mapping and + // the two methods return equal arrays. 11.0.0 keeps one of them and makes + // this a deprecated alias; test/common-test.ts fails at that version. return this.toByteArray().map(unsignByte); } /** * Convert a byte array to an Address6 object. * + * Accepts unsigned bytes (0 to 255) or signed bytes (-128 to 127, as an + * `Int8Array` or a Java `byte[]` holds them), folding signed values to their + * unsigned equivalent. Throws `AddressError` unless given exactly 16 + * integers from -128 to 255. + * * To convert from a Node.js `Buffer`, spread it: `Address6.fromByteArray([...buf])`. * @returns {Address6} */ static fromByteArray(bytes) { + // Address4.fromByteArray takes unsigned bytes only. 11.0.0 aligns this + // method with it, at which point the -128 floor here, unsignByte, and the + // mapping below all go; test/common-test.ts fails at that version. + common.assertByteArray(bytes, 16, 'IPv6', -128); return this.fromUnsignedByteArray(bytes.map(unsignByte)); } /** * Convert an unsigned byte array to an Address6 object. * + * Throws `AddressError` unless given exactly 16 integers from 0 to 255. + * * To convert from a Node.js `Buffer`, spread it: `Address6.fromUnsignedByteArray([...buf])`. * @returns {Address6} */ static fromUnsignedByteArray(bytes) { + common.assertByteArray(bytes, 16, 'IPv6', 0); const BYTE_MAX = BigInt('256'); let result = BigInt('0'); let multiplier = BigInt('1'); @@ -982,7 +1026,11 @@ class Address6 { * @returns {boolean} */ isLinkLocal() { - // Zeroes are required, i.e. we can't check isInSubnet with 'fe80::/10' + const embedded = this.embeddedIPv4(); + if (embedded) { + return embedded.isLinkLocal(); + } + // Zeroes are required, i.e. we can't check isHostInSubnet with 'fe80::/10' if (this.getBitsBase2(0, 64) === '1111111010000000000000000000000000000000000000000000000000000000') { return true; @@ -994,6 +1042,10 @@ class Address6 { * @returns {boolean} */ isMulticast() { + const embedded = this.embeddedIPv4(); + if (embedded) { + return embedded.isMulticast(); + } const type = this.getType(); return type === 'Multicast' || type.startsWith('Multicast '); } @@ -1016,27 +1068,54 @@ class Address6 { * @returns {boolean} */ isMapped4() { - return this.isInSubnet(IPV4_MAPPED_SUBNET); + return this.isHostInSubnet(IPV4_MAPPED_SUBNET); + } + /** + * If this address embeds a routable IPv4 address — i.e. it is IPv4-mapped + * (`::ffff:0:0/96`) or sits in the NAT64 well-known prefix (`64:ff9b::/96`, + * [RFC 6052](https://datatracker.ietf.org/doc/html/rfc6052)) — return that + * embedded address as an {@link Address4}; otherwise return null. + * + * The special-property checks (`isLoopback`, `isLinkLocal`, `isMulticast`, + * `isUnspecified`, `isPrivate`, `isCGNAT`, `isBroadcast`) call this first and + * delegate to the embedded {@link Address4} when present, so a literal such as + * `::ffff:127.0.0.1` is classified by what it actually reaches (loopback) + * rather than by its IPv6 wrapper (which `getType()` reports as IPv4-mapped). + * This matters wherever the checks back a trust-boundary decision (e.g. an + * SSRF allow/deny filter): without normalization, `::ffff:10.0.0.1`, + * `::ffff:169.254.169.254`, `64:ff9b::7f00:1`, etc. would all read as + * non-internal. + * @returns {Address4 | null} + */ + embeddedIPv4() { + if (this.isMapped4() || this.isHostInSubnet(NAT64_WELL_KNOWN_SUBNET)) { + return this.to4(); + } + return null; } /** * Returns true if the address is a Teredo address, false otherwise * @returns {boolean} */ isTeredo() { - return this.isInSubnet(TEREDO_SUBNET); + return this.isHostInSubnet(TEREDO_SUBNET); } /** * Returns true if the address is a 6to4 address, false otherwise * @returns {boolean} */ is6to4() { - return this.isInSubnet(SIX_TO_FOUR_SUBNET); + return this.isHostInSubnet(SIX_TO_FOUR_SUBNET); } /** * Returns true if the address is a loopback address, false otherwise * @returns {boolean} */ isLoopback() { + const embedded = this.embeddedIPv4(); + if (embedded) { + return embedded.isLoopback(); + } return this.getType() === 'Loopback'; } /** @@ -1044,13 +1123,64 @@ class Address6 { * @returns {boolean} */ isULA() { - return this.isInSubnet(ULA_SUBNET); + return this.isHostInSubnet(ULA_SUBNET); + } + /** + * Returns true if the address is private, i.e. a Unique Local Address in + * `fc00::/7` ([RFC 4193](https://datatracker.ietf.org/doc/html/rfc4193)) or an + * IPv4-mapped / NAT64 address whose embedded IPv4 address is in one of the + * [RFC 1918](https://datatracker.ietf.org/doc/html/rfc1918) private ranges + * (e.g. `::ffff:10.0.0.1`). This is the IPv6 counterpart to + * {@link Address4.isPrivate}; use it instead of {@link isULA} when you need to + * catch mapped RFC 1918 addresses as well as native ULAs. + * @returns {boolean} + */ + isPrivate() { + const embedded = this.embeddedIPv4(); + if (embedded) { + return embedded.isPrivate(); + } + return this.isULA(); + } + /** + * Returns true if the address is an IPv4-mapped / NAT64 address whose embedded + * IPv4 address is in the carrier-grade NAT range `100.64.0.0/10` + * ([RFC 6598](https://datatracker.ietf.org/doc/html/rfc6598)), false + * otherwise. There is no native IPv6 CGNAT range, so this only ever returns + * true for an embedded IPv4 address (e.g. `::ffff:100.64.0.1`). + * @returns {boolean} + */ + isCGNAT() { + const embedded = this.embeddedIPv4(); + if (embedded) { + return embedded.isCGNAT(); + } + return false; + } + /** + * Returns true if the address is an IPv4-mapped / NAT64 address whose embedded + * IPv4 address is the limited broadcast address `255.255.255.255` + * ([RFC 919](https://datatracker.ietf.org/doc/html/rfc919)), false otherwise. + * There is no IPv6 broadcast, so this only ever returns true for an embedded + * IPv4 address (e.g. `::ffff:255.255.255.255`). + * @returns {boolean} + */ + isBroadcast() { + const embedded = this.embeddedIPv4(); + if (embedded) { + return embedded.isBroadcast(); + } + return false; } /** * Returns true if the address is the unspecified address `::`. * @returns {boolean} */ isUnspecified() { + const embedded = this.embeddedIPv4(); + if (embedded) { + return embedded.isUnspecified(); + } return this.getType() === 'Unspecified'; } /** @@ -1058,7 +1188,7 @@ class Address6 { * @returns {boolean} */ isDocumentation() { - return this.isInSubnet(DOCUMENTATION_SUBNET); + return this.isHostInSubnet(DOCUMENTATION_SUBNET); } // #endregion // #region HTML @@ -1111,7 +1241,12 @@ class Address6 { return `${safeForm}`; } /** - * Groups an address + * Groups an address. + * + * Returns an HTML fragment: each group is wrapped in a `` carrying + * the group classes an address-inspector UI hovers on. The address content + * is HTML-escaped; anything you concatenate around it is your + * responsibility. * @returns {String} */ group() { @@ -1214,4 +1349,5 @@ const SIX_TO_FOUR_SUBNET = new Address6('2002::/16'); const ULA_SUBNET = new Address6('fc00::/7'); const DOCUMENTATION_SUBNET = new Address6('2001:db8::/32'); const IPV4_MAPPED_SUBNET = new Address6('::ffff:0:0/96'); +const NAT64_WELL_KNOWN_SUBNET = new Address6('64:ff9b::/96'); //# sourceMappingURL=ipv6.js.map \ No newline at end of file diff --git a/deps/npm/node_modules/ip-address/dist/v4/constants.js b/deps/npm/node_modules/ip-address/dist/v4/constants.js index 6fa2518f9649..158288b7de65 100644 --- a/deps/npm/node_modules/ip-address/dist/v4/constants.js +++ b/deps/npm/node_modules/ip-address/dist/v4/constants.js @@ -3,6 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.RE_SUBNET_STRING = exports.RE_ADDRESS = exports.GROUPS = exports.BITS = void 0; exports.BITS = 32; exports.GROUPS = 4; -exports.RE_ADDRESS = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/g; +// Each octet is 0-255 written without a leading zero. A leading zero is +// octal to the WHATWG URL parser, inet_aton, and getaddrinfo, but decimal to +// parseInt(part, 10), so accepting the notation would make this library +// disagree with the network stack about which host a string names. +exports.RE_ADDRESS = /^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])$/g; exports.RE_SUBNET_STRING = /\/\d{1,2}$/; //# sourceMappingURL=constants.js.map \ No newline at end of file diff --git a/deps/npm/node_modules/ip-address/dist/v6/constants.js b/deps/npm/node_modules/ip-address/dist/v6/constants.js index 1a8cd1dd616e..4616cad66b6a 100644 --- a/deps/npm/node_modules/ip-address/dist/v6/constants.js +++ b/deps/npm/node_modules/ip-address/dist/v6/constants.js @@ -44,6 +44,7 @@ exports.TYPES = { 'ff05::1:3/128': 'Multicast (All DHCP servers in this site)', '::/128': 'Unspecified', '::1/128': 'Loopback', + '::ffff:0:0/96': 'IPv4-mapped', 'ff00::/8': 'Multicast', 'fe80::/10': 'Link-local unicast', 'fc00::/7': 'Unique local', @@ -76,6 +77,6 @@ exports.RE_SUBNET_STRING = /\/\d{1,3}(?=%|$)/; * @static */ exports.RE_ZONE_STRING = /%.*$/; -exports.RE_URL = /^\[{0,1}([0-9a-f:]+)\]{0,1}/; -exports.RE_URL_WITH_PORT = /\[([0-9a-f:]+)\]:([0-9]{1,5})/; +exports.RE_URL = /^(?:\[([0-9a-f:.]+)\]|([0-9a-f:.]+))(?:[/?#].*)?$/i; +exports.RE_URL_WITH_PORT = /^\[([0-9a-f:.]+)\]:([0-9]{1,5})(?:[/?#].*)?$/i; //# sourceMappingURL=constants.js.map \ No newline at end of file diff --git a/deps/npm/node_modules/ip-address/package.json b/deps/npm/node_modules/ip-address/package.json index 47d109ec6f34..6ea2d24bd62b 100644 --- a/deps/npm/node_modules/ip-address/package.json +++ b/deps/npm/node_modules/ip-address/package.json @@ -16,7 +16,7 @@ "bigint", "browser" ], - "version": "10.2.0", + "version": "10.5.0", "author": "Beau Gunderson (https://beaugunderson.com/)", "license": "MIT", "main": "dist/ip-address.js", @@ -25,6 +25,9 @@ "docs": "tsx scripts/build-readme.ts", "build": "rm -rf dist; mkdir dist; tsc", "prepack": "npm run docs && npm run build", + "prepare": "git config core.hooksPath hooks || true", + "lint": "prettier --check . && eslint . --ext .ts,.js --max-warnings 0", + "lint:fix": "prettier --write . && eslint . --ext .ts,.js --max-warnings 0 --fix", "test-ci": "c8 --experimental-monocart mocha", "test": "mocha", "watch": "mocha --watch" @@ -54,7 +57,7 @@ ], "repository": { "type": "git", - "url": "git://github.com/beaugunderson/ip-address.git" + "url": "https://github.com/beaugunderson/ip-address.git" }, "overrides": { "diff": "^8.0.3", @@ -70,11 +73,10 @@ "chai": "^6.2.2", "eslint": "^8.57.1", "eslint_d": "^14.0.4", - "eslint-config-airbnb": "^19.0.4", + "eslint-config-airbnb-base": "^15.0.0", "eslint-config-prettier": "^10.1.8", "eslint-plugin-filenames": "^1.3.2", "eslint-plugin-import": "^2.32.0", - "eslint-plugin-jsx-a11y": "^6.10.2", "eslint-plugin-prettier": "^5.5.5", "eslint-plugin-sort-imports-es6-autofix": "^0.6.0", "mocha": "^11.7.5", diff --git a/deps/npm/node_modules/libnpmpack/lib/index.js b/deps/npm/node_modules/libnpmpack/lib/index.js index 6c8ee3fd6334..ce6707938bb3 100644 --- a/deps/npm/node_modules/libnpmpack/lib/index.js +++ b/deps/npm/node_modules/libnpmpack/lib/index.js @@ -12,6 +12,11 @@ async function pack (spec = 'file:.', opts = {}) { // gets spec spec = npa(spec) + // An explicit directory is the package being packed, not a dependency fetch. + if (spec.type === 'directory') { + opts = { ...opts, allowDirectory: 'all' } + } + const manifest = await pacote.manifest(spec, { ...opts, Arborist, _isRoot: true }) const stdio = opts.foregroundScripts ? 'inherit' : 'pipe' diff --git a/deps/npm/node_modules/libnpmpack/package.json b/deps/npm/node_modules/libnpmpack/package.json index 5741c8522c19..54c31fccd635 100644 --- a/deps/npm/node_modules/libnpmpack/package.json +++ b/deps/npm/node_modules/libnpmpack/package.json @@ -1,6 +1,6 @@ { "name": "libnpmpack", - "version": "9.1.12", + "version": "9.1.13", "description": "Programmatic API for the bits behind npm pack", "author": "GitHub Inc.", "main": "lib/index.js", diff --git a/deps/npm/node_modules/tar/dist/commonjs/index.min.js b/deps/npm/node_modules/tar/dist/commonjs/index.min.js index 1a229a01e5a5..c1fe035f48f3 100644 --- a/deps/npm/node_modules/tar/dist/commonjs/index.min.js +++ b/deps/npm/node_modules/tar/dist/commonjs/index.min.js @@ -1,4 +1,4 @@ -"use strict";var d=(s,e)=>()=>(e||s((e={exports:{}}).exports,e),e.exports);var We=d(F=>{"use strict";var Do=F&&F.__importDefault||function(s){return s&&s.__esModule?s:{default:s}};Object.defineProperty(F,"__esModule",{value:!0});F.Minipass=F.isWritable=F.isReadable=F.isStream=void 0;var kr=typeof process=="object"&&process?process:{stdout:null,stderr:null},ss=require("node:events"),qr=Do(require("node:stream")),Po=require("node:string_decoder"),No=s=>!!s&&typeof s=="object"&&(s instanceof Zt||s instanceof qr.default||(0,F.isReadable)(s)||(0,F.isWritable)(s));F.isStream=No;var Mo=s=>!!s&&typeof s=="object"&&s instanceof ss.EventEmitter&&typeof s.pipe=="function"&&s.pipe!==qr.default.Writable.prototype.pipe;F.isReadable=Mo;var Lo=s=>!!s&&typeof s=="object"&&s instanceof ss.EventEmitter&&typeof s.write=="function"&&typeof s.end=="function";F.isWritable=Lo;var ce=Symbol("EOF"),ue=Symbol("maybeEmitEnd"),we=Symbol("emittedEnd"),jt=Symbol("emittingEnd"),dt=Symbol("emittedError"),Ut=Symbol("closed"),xr=Symbol("read"),qt=Symbol("flush"),jr=Symbol("flushChunk"),K=Symbol("encoding"),Ue=Symbol("decoder"),R=Symbol("flowing"),mt=Symbol("paused"),qe=Symbol("resume"),O=Symbol("buffer"),I=Symbol("pipes"),v=Symbol("bufferLength"),Xi=Symbol("bufferPush"),Wt=Symbol("bufferShift"),N=Symbol("objectMode"),y=Symbol("destroyed"),Qi=Symbol("error"),Ji=Symbol("emitData"),Ur=Symbol("emitEnd"),es=Symbol("emitEnd2"),J=Symbol("async"),ts=Symbol("abort"),Ht=Symbol("aborted"),pt=Symbol("signal"),Ne=Symbol("dataListeners"),x=Symbol("discarded"),_t=s=>Promise.resolve().then(s),Ao=s=>s(),Io=s=>s==="end"||s==="finish"||s==="prefinish",Fo=s=>s instanceof ArrayBuffer||!!s&&typeof s=="object"&&s.constructor&&s.constructor.name==="ArrayBuffer"&&s.byteLength>=0,Co=s=>!Buffer.isBuffer(s)&&ArrayBuffer.isView(s),Gt=class{src;dest;opts;ondrain;constructor(e,t,i){this.src=e,this.dest=t,this.opts=i,this.ondrain=()=>e[qe](),this.dest.on("drain",this.ondrain)}unpipe(){this.dest.removeListener("drain",this.ondrain)}proxyErrors(e){}end(){this.unpipe(),this.opts.end&&this.dest.end()}},is=class extends Gt{unpipe(){this.src.removeListener("error",this.proxyErrors),super.unpipe()}constructor(e,t,i){super(e,t,i),this.proxyErrors=r=>this.dest.emit("error",r),e.on("error",this.proxyErrors)}},Bo=s=>!!s.objectMode,zo=s=>!s.objectMode&&!!s.encoding&&s.encoding!=="buffer",Zt=class extends ss.EventEmitter{[R]=!1;[mt]=!1;[I]=[];[O]=[];[N];[K];[J];[Ue];[ce]=!1;[we]=!1;[jt]=!1;[Ut]=!1;[dt]=null;[v]=0;[y]=!1;[pt];[Ht]=!1;[Ne]=0;[x]=!1;writable=!0;readable=!0;constructor(...e){let t=e[0]||{};if(super(),t.objectMode&&typeof t.encoding=="string")throw new TypeError("Encoding and objectMode may not be used together");Bo(t)?(this[N]=!0,this[K]=null):zo(t)?(this[K]=t.encoding,this[N]=!1):(this[N]=!1,this[K]=null),this[J]=!!t.async,this[Ue]=this[K]?new Po.StringDecoder(this[K]):null,t&&t.debugExposeBuffer===!0&&Object.defineProperty(this,"buffer",{get:()=>this[O]}),t&&t.debugExposePipes===!0&&Object.defineProperty(this,"pipes",{get:()=>this[I]});let{signal:i}=t;i&&(this[pt]=i,i.aborted?this[ts]():i.addEventListener("abort",()=>this[ts]()))}get bufferLength(){return this[v]}get encoding(){return this[K]}set encoding(e){throw new Error("Encoding must be set at instantiation time")}setEncoding(e){throw new Error("Encoding must be set at instantiation time")}get objectMode(){return this[N]}set objectMode(e){throw new Error("objectMode must be set at instantiation time")}get async(){return this[J]}set async(e){this[J]=this[J]||!!e}[ts](){this[Ht]=!0,this.emit("abort",this[pt]?.reason),this.destroy(this[pt]?.reason)}get aborted(){return this[Ht]}set aborted(e){}write(e,t,i){if(this[Ht])return!1;if(this[ce])throw new Error("write after end");if(this[y])return this.emit("error",Object.assign(new Error("Cannot call write after a stream was destroyed"),{code:"ERR_STREAM_DESTROYED"})),!0;typeof t=="function"&&(i=t,t="utf8"),t||(t="utf8");let r=this[J]?_t:Ao;if(!this[N]&&!Buffer.isBuffer(e)){if(Co(e))e=Buffer.from(e.buffer,e.byteOffset,e.byteLength);else if(Fo(e))e=Buffer.from(e);else if(typeof e!="string")throw new Error("Non-contiguous data written to non-objectMode stream")}return this[N]?(this[R]&&this[v]!==0&&this[qt](!0),this[R]?this.emit("data",e):this[Xi](e),this[v]!==0&&this.emit("readable"),i&&r(i),this[R]):e.length?(typeof e=="string"&&!(t===this[K]&&!this[Ue]?.lastNeed)&&(e=Buffer.from(e,t)),Buffer.isBuffer(e)&&this[K]&&(e=this[Ue].write(e)),this[R]&&this[v]!==0&&this[qt](!0),this[R]?this.emit("data",e):this[Xi](e),this[v]!==0&&this.emit("readable"),i&&r(i),this[R]):(this[v]!==0&&this.emit("readable"),i&&r(i),this[R])}read(e){if(this[y])return null;if(this[x]=!1,this[v]===0||e===0||e&&e>this[v])return this[ue](),null;this[N]&&(e=null),this[O].length>1&&!this[N]&&(this[O]=[this[K]?this[O].join(""):Buffer.concat(this[O],this[v])]);let t=this[xr](e||null,this[O][0]);return this[ue](),t}[xr](e,t){if(this[N])this[Wt]();else{let i=t;e===i.length||e===null?this[Wt]():typeof i=="string"?(this[O][0]=i.slice(e),t=i.slice(0,e),this[v]-=e):(this[O][0]=i.subarray(e),t=i.subarray(0,e),this[v]-=e)}return this.emit("data",t),!this[O].length&&!this[ce]&&this.emit("drain"),t}end(e,t,i){return typeof e=="function"&&(i=e,e=void 0),typeof t=="function"&&(i=t,t="utf8"),e!==void 0&&this.write(e,t),i&&this.once("end",i),this[ce]=!0,this.writable=!1,(this[R]||!this[mt])&&this[ue](),this}[qe](){this[y]||(!this[Ne]&&!this[I].length&&(this[x]=!0),this[mt]=!1,this[R]=!0,this.emit("resume"),this[O].length?this[qt]():this[ce]?this[ue]():this.emit("drain"))}resume(){return this[qe]()}pause(){this[R]=!1,this[mt]=!0,this[x]=!1}get destroyed(){return this[y]}get flowing(){return this[R]}get paused(){return this[mt]}[Xi](e){this[N]?this[v]+=1:this[v]+=e.length,this[O].push(e)}[Wt](){return this[N]?this[v]-=1:this[v]-=this[O][0].length,this[O].shift()}[qt](e=!1){do;while(this[jr](this[Wt]())&&this[O].length);!e&&!this[O].length&&!this[ce]&&this.emit("drain")}[jr](e){return this.emit("data",e),this[R]}pipe(e,t){if(this[y])return e;this[x]=!1;let i=this[we];return t=t||{},e===kr.stdout||e===kr.stderr?t.end=!1:t.end=t.end!==!1,t.proxyErrors=!!t.proxyErrors,i?t.end&&e.end():(this[I].push(t.proxyErrors?new is(this,e,t):new Gt(this,e,t)),this[J]?_t(()=>this[qe]()):this[qe]()),e}unpipe(e){let t=this[I].find(i=>i.dest===e);t&&(this[I].length===1?(this[R]&&this[Ne]===0&&(this[R]=!1),this[I]=[]):this[I].splice(this[I].indexOf(t),1),t.unpipe())}addListener(e,t){return this.on(e,t)}on(e,t){let i=super.on(e,t);if(e==="data")this[x]=!1,this[Ne]++,!this[I].length&&!this[R]&&this[qe]();else if(e==="readable"&&this[v]!==0)super.emit("readable");else if(Io(e)&&this[we])super.emit(e),this.removeAllListeners(e);else if(e==="error"&&this[dt]){let r=t;this[J]?_t(()=>r.call(this,this[dt])):r.call(this,this[dt])}return i}removeListener(e,t){return this.off(e,t)}off(e,t){let i=super.off(e,t);return e==="data"&&(this[Ne]=this.listeners("data").length,this[Ne]===0&&!this[x]&&!this[I].length&&(this[R]=!1)),i}removeAllListeners(e){let t=super.removeAllListeners(e);return(e==="data"||e===void 0)&&(this[Ne]=0,!this[x]&&!this[I].length&&(this[R]=!1)),t}get emittedEnd(){return this[we]}[ue](){!this[jt]&&!this[we]&&!this[y]&&this[O].length===0&&this[ce]&&(this[jt]=!0,this.emit("end"),this.emit("prefinish"),this.emit("finish"),this[Ut]&&this.emit("close"),this[jt]=!1)}emit(e,...t){let i=t[0];if(e!=="error"&&e!=="close"&&e!==y&&this[y])return!1;if(e==="data")return!this[N]&&!i?!1:this[J]?(_t(()=>this[Ji](i)),!0):this[Ji](i);if(e==="end")return this[Ur]();if(e==="close"){if(this[Ut]=!0,!this[we]&&!this[y])return!1;let n=super.emit("close");return this.removeAllListeners("close"),n}else if(e==="error"){this[dt]=i,super.emit(Qi,i);let n=!this[pt]||this.listeners("error").length?super.emit("error",i):!1;return this[ue](),n}else if(e==="resume"){let n=super.emit("resume");return this[ue](),n}else if(e==="finish"||e==="prefinish"){let n=super.emit(e);return this.removeAllListeners(e),n}let r=super.emit(e,...t);return this[ue](),r}[Ji](e){for(let i of this[I])i.dest.write(e)===!1&&this.pause();let t=this[x]?!1:super.emit("data",e);return this[ue](),t}[Ur](){return this[we]?!1:(this[we]=!0,this.readable=!1,this[J]?(_t(()=>this[es]()),!0):this[es]())}[es](){if(this[Ue]){let t=this[Ue].end();if(t){for(let i of this[I])i.dest.write(t);this[x]||super.emit("data",t)}}for(let t of this[I])t.end();let e=super.emit("end");return this.removeAllListeners("end"),e}async collect(){let e=Object.assign([],{dataLength:0});this[N]||(e.dataLength=0);let t=this.promise();return this.on("data",i=>{e.push(i),this[N]||(e.dataLength+=i.length)}),await t,e}async concat(){if(this[N])throw new Error("cannot concat in objectMode");let e=await this.collect();return this[K]?e.join(""):Buffer.concat(e,e.dataLength)}async promise(){return new Promise((e,t)=>{this.on(y,()=>t(new Error("stream destroyed"))),this.on("error",i=>t(i)),this.on("end",()=>e())})}[Symbol.asyncIterator](){this[x]=!1;let e=!1,t=async()=>(this.pause(),e=!0,{value:void 0,done:!0});return{next:()=>{if(e)return t();let r=this.read();if(r!==null)return Promise.resolve({done:!1,value:r});if(this[ce])return t();let n,o,a=u=>{this.off("data",h),this.off("end",l),this.off(y,c),t(),o(u)},h=u=>{this.off("error",a),this.off("end",l),this.off(y,c),this.pause(),n({value:u,done:!!this[ce]})},l=()=>{this.off("error",a),this.off("data",h),this.off(y,c),t(),n({done:!0,value:void 0})},c=()=>a(new Error("stream destroyed"));return new Promise((u,E)=>{o=E,n=u,this.once(y,c),this.once("error",a),this.once("end",l),this.once("data",h)})},throw:t,return:t,[Symbol.asyncIterator](){return this},[Symbol.asyncDispose]:async()=>{}}}[Symbol.iterator](){this[x]=!1;let e=!1,t=()=>(this.pause(),this.off(Qi,t),this.off(y,t),this.off("end",t),e=!0,{done:!0,value:void 0}),i=()=>{if(e)return t();let r=this.read();return r===null?t():{done:!1,value:r}};return this.once("end",t),this.once(Qi,t),this.once(y,t),{next:i,throw:t,return:t,[Symbol.iterator](){return this},[Symbol.dispose]:()=>{}}}destroy(e){if(this[y])return e?this.emit("error",e):this.emit(y),this;this[y]=!0,this[x]=!0,this[O].length=0,this[v]=0;let t=this;return typeof t.close=="function"&&!this[Ut]&&t.close(),e?this.emit("error",e):this.emit(y),this}static get isStream(){return F.isStream}};F.Minipass=Zt});var Ke=d(W=>{"use strict";var Wr=W&&W.__importDefault||function(s){return s&&s.__esModule?s:{default:s}};Object.defineProperty(W,"__esModule",{value:!0});W.WriteStreamSync=W.WriteStream=W.ReadStreamSync=W.ReadStream=void 0;var ko=Wr(require("events")),z=Wr(require("fs")),xo=We(),jo=z.default.writev,Ee=Symbol("_autoClose"),$=Symbol("_close"),wt=Symbol("_ended"),p=Symbol("_fd"),rs=Symbol("_finished"),de=Symbol("_flags"),ns=Symbol("_flush"),ls=Symbol("_handleChunk"),cs=Symbol("_makeBuf"),Et=Symbol("_mode"),Yt=Symbol("_needDrain"),Ze=Symbol("_onerror"),Ye=Symbol("_onopen"),os=Symbol("_onread"),He=Symbol("_onwrite"),be=Symbol("_open"),V=Symbol("_path"),ye=Symbol("_pos"),ee=Symbol("_queue"),Ge=Symbol("_read"),as=Symbol("_readSize"),fe=Symbol("_reading"),yt=Symbol("_remain"),hs=Symbol("_size"),Kt=Symbol("_write"),Me=Symbol("_writing"),Vt=Symbol("_defaultFlag"),Le=Symbol("_errored"),$t=class extends xo.Minipass{[Le]=!1;[p];[V];[as];[fe]=!1;[hs];[yt];[Ee];constructor(e,t){if(t=t||{},super(t),this.readable=!0,this.writable=!1,typeof e!="string")throw new TypeError("path must be a string");this[Le]=!1,this[p]=typeof t.fd=="number"?t.fd:void 0,this[V]=e,this[as]=t.readSize||16*1024*1024,this[fe]=!1,this[hs]=typeof t.size=="number"?t.size:1/0,this[yt]=this[hs],this[Ee]=typeof t.autoClose=="boolean"?t.autoClose:!0,typeof this[p]=="number"?this[Ge]():this[be]()}get fd(){return this[p]}get path(){return this[V]}write(){throw new TypeError("this is a readable stream")}end(){throw new TypeError("this is a readable stream")}[be](){z.default.open(this[V],"r",(e,t)=>this[Ye](e,t))}[Ye](e,t){e?this[Ze](e):(this[p]=t,this.emit("open",t),this[Ge]())}[cs](){return Buffer.allocUnsafe(Math.min(this[as],this[yt]))}[Ge](){if(!this[fe]){this[fe]=!0;let e=this[cs]();if(e.length===0)return process.nextTick(()=>this[os](null,0,e));z.default.read(this[p],e,0,e.length,null,(t,i,r)=>this[os](t,i,r))}}[os](e,t,i){this[fe]=!1,e?this[Ze](e):this[ls](t,i)&&this[Ge]()}[$](){if(this[Ee]&&typeof this[p]=="number"){let e=this[p];this[p]=void 0,z.default.close(e,t=>t?this.emit("error",t):this.emit("close"))}}[Ze](e){this[fe]=!0,this[$](),this.emit("error",e)}[ls](e,t){let i=!1;return this[yt]-=e,e>0&&(i=super.write(ethis[Ye](e,t))}[Ye](e,t){this[Vt]&&this[de]==="r+"&&e&&e.code==="ENOENT"?(this[de]="w",this[be]()):e?this[Ze](e):(this[p]=t,this.emit("open",t),this[Me]||this[ns]())}end(e,t){return e&&this.write(e,t),this[wt]=!0,!this[Me]&&!this[ee].length&&typeof this[p]=="number"&&this[He](null,0),this}write(e,t){return typeof e=="string"&&(e=Buffer.from(e,t)),this[wt]?(this.emit("error",new Error("write() after end()")),!1):this[p]===void 0||this[Me]||this[ee].length?(this[ee].push(e),this[Yt]=!0,!1):(this[Me]=!0,this[Kt](e),!0)}[Kt](e){z.default.write(this[p],e,0,e.length,this[ye],(t,i)=>this[He](t,i))}[He](e,t){e?this[Ze](e):(this[ye]!==void 0&&typeof t=="number"&&(this[ye]+=t),this[ee].length?this[ns]():(this[Me]=!1,this[wt]&&!this[rs]?(this[rs]=!0,this[$](),this.emit("finish")):this[Yt]&&(this[Yt]=!1,this.emit("drain"))))}[ns](){if(this[ee].length===0)this[wt]&&this[He](null,0);else if(this[ee].length===1)this[Kt](this[ee].pop());else{let e=this[ee];this[ee]=[],jo(this[p],e,this[ye],(t,i)=>this[He](t,i))}}[$](){if(this[Ee]&&typeof this[p]=="number"){let e=this[p];this[p]=void 0,z.default.close(e,t=>t?this.emit("error",t):this.emit("close"))}}};W.WriteStream=Xt;var fs=class extends Xt{[be](){let e;if(this[Vt]&&this[de]==="r+")try{e=z.default.openSync(this[V],this[de],this[Et])}catch(t){if(t?.code==="ENOENT")return this[de]="w",this[be]();throw t}else e=z.default.openSync(this[V],this[de],this[Et]);this[Ye](null,e)}[$](){if(this[Ee]&&typeof this[p]=="number"){let e=this[p];this[p]=void 0,z.default.closeSync(e),this.emit("close")}}[Kt](e){let t=!0;try{this[He](null,z.default.writeSync(this[p],e,0,e.length,this[ye])),t=!1}finally{if(t)try{this[$]()}catch{}}}};W.WriteStreamSync=fs});var Qt=d(b=>{"use strict";Object.defineProperty(b,"__esModule",{value:!0});b.dealias=b.isNoFile=b.isFile=b.isAsync=b.isSync=b.isAsyncNoFile=b.isSyncNoFile=b.isAsyncFile=b.isSyncFile=void 0;var Uo=new Map([["C","cwd"],["f","file"],["z","gzip"],["P","preservePaths"],["U","unlink"],["strip-components","strip"],["stripComponents","strip"],["keep-newer","newer"],["keepNewer","newer"],["keep-newer-files","newer"],["keepNewerFiles","newer"],["k","keep"],["keep-existing","keep"],["keepExisting","keep"],["m","noMtime"],["no-mtime","noMtime"],["p","preserveOwner"],["L","follow"],["h","follow"],["onentry","onReadEntry"]]),qo=s=>!!s.sync&&!!s.file;b.isSyncFile=qo;var Wo=s=>!s.sync&&!!s.file;b.isAsyncFile=Wo;var Ho=s=>!!s.sync&&!s.file;b.isSyncNoFile=Ho;var Go=s=>!s.sync&&!s.file;b.isAsyncNoFile=Go;var Zo=s=>!!s.sync;b.isSync=Zo;var Yo=s=>!s.sync;b.isAsync=Yo;var Ko=s=>!!s.file;b.isFile=Ko;var Vo=s=>!s.file;b.isNoFile=Vo;var $o=s=>{let e=Uo.get(s);return e||s},Xo=(s={})=>{if(!s)return{};let e={};for(let[t,i]of Object.entries(s)){let r=$o(t);e[r]=i}return e.chmod===void 0&&e.noChmod===!1&&(e.chmod=!0),delete e.noChmod,e};b.dealias=Xo});var Ve=d(Jt=>{"use strict";Object.defineProperty(Jt,"__esModule",{value:!0});Jt.makeCommand=void 0;var bt=Qt(),Qo=(s,e,t,i,r)=>Object.assign((n=[],o,a)=>{Array.isArray(n)&&(o=n,n={}),typeof o=="function"&&(a=o,o=void 0),o=o?Array.from(o):[];let h=(0,bt.dealias)(n);if(r?.(h,o),(0,bt.isSyncFile)(h)){if(typeof a=="function")throw new TypeError("callback not supported for sync tar functions");return s(h,o)}else if((0,bt.isAsyncFile)(h)){let l=e(h,o);return a?l.then(()=>a(),a):l}else if((0,bt.isSyncNoFile)(h)){if(typeof a=="function")throw new TypeError("callback not supported for sync tar functions");return t(h,o)}else if((0,bt.isAsyncNoFile)(h)){if(typeof a=="function")throw new TypeError("callback only supported with file option");return i(h,o)}throw new Error("impossible options??")},{syncFile:s,asyncFile:e,syncNoFile:t,asyncNoFile:i,validate:r});Jt.makeCommand=Qo});var ds=d($e=>{"use strict";var Jo=$e&&$e.__importDefault||function(s){return s&&s.__esModule?s:{default:s}};Object.defineProperty($e,"__esModule",{value:!0});$e.constants=void 0;var ea=Jo(require("zlib")),ta=ea.default.constants||{ZLIB_VERNUM:4736};$e.constants=Object.freeze(Object.assign(Object.create(null),{Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_MEM_ERROR:-4,Z_BUF_ERROR:-5,Z_VERSION_ERROR:-6,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,DEFLATE:1,INFLATE:2,GZIP:3,GUNZIP:4,DEFLATERAW:5,INFLATERAW:6,UNZIP:7,BROTLI_DECODE:8,BROTLI_ENCODE:9,Z_MIN_WINDOWBITS:8,Z_MAX_WINDOWBITS:15,Z_DEFAULT_WINDOWBITS:15,Z_MIN_CHUNK:64,Z_MAX_CHUNK:1/0,Z_DEFAULT_CHUNK:16384,Z_MIN_MEMLEVEL:1,Z_MAX_MEMLEVEL:9,Z_DEFAULT_MEMLEVEL:8,Z_MIN_LEVEL:-1,Z_MAX_LEVEL:9,Z_DEFAULT_LEVEL:-1,BROTLI_OPERATION_PROCESS:0,BROTLI_OPERATION_FLUSH:1,BROTLI_OPERATION_FINISH:2,BROTLI_OPERATION_EMIT_METADATA:3,BROTLI_MODE_GENERIC:0,BROTLI_MODE_TEXT:1,BROTLI_MODE_FONT:2,BROTLI_DEFAULT_MODE:0,BROTLI_MIN_QUALITY:0,BROTLI_MAX_QUALITY:11,BROTLI_DEFAULT_QUALITY:11,BROTLI_MIN_WINDOW_BITS:10,BROTLI_MAX_WINDOW_BITS:24,BROTLI_LARGE_MAX_WINDOW_BITS:30,BROTLI_DEFAULT_WINDOW:22,BROTLI_MIN_INPUT_BLOCK_BITS:16,BROTLI_MAX_INPUT_BLOCK_BITS:24,BROTLI_PARAM_MODE:0,BROTLI_PARAM_QUALITY:1,BROTLI_PARAM_LGWIN:2,BROTLI_PARAM_LGBLOCK:3,BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING:4,BROTLI_PARAM_SIZE_HINT:5,BROTLI_PARAM_LARGE_WINDOW:6,BROTLI_PARAM_NPOSTFIX:7,BROTLI_PARAM_NDIRECT:8,BROTLI_DECODER_RESULT_ERROR:0,BROTLI_DECODER_RESULT_SUCCESS:1,BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT:2,BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT:3,BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION:0,BROTLI_DECODER_PARAM_LARGE_WINDOW:1,BROTLI_DECODER_NO_ERROR:0,BROTLI_DECODER_SUCCESS:1,BROTLI_DECODER_NEEDS_MORE_INPUT:2,BROTLI_DECODER_NEEDS_MORE_OUTPUT:3,BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_NIBBLE:-1,BROTLI_DECODER_ERROR_FORMAT_RESERVED:-2,BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_META_NIBBLE:-3,BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET:-4,BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME:-5,BROTLI_DECODER_ERROR_FORMAT_CL_SPACE:-6,BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE:-7,BROTLI_DECODER_ERROR_FORMAT_CONTEXT_MAP_REPEAT:-8,BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_1:-9,BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_2:-10,BROTLI_DECODER_ERROR_FORMAT_TRANSFORM:-11,BROTLI_DECODER_ERROR_FORMAT_DICTIONARY:-12,BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS:-13,BROTLI_DECODER_ERROR_FORMAT_PADDING_1:-14,BROTLI_DECODER_ERROR_FORMAT_PADDING_2:-15,BROTLI_DECODER_ERROR_FORMAT_DISTANCE:-16,BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET:-19,BROTLI_DECODER_ERROR_INVALID_ARGUMENTS:-20,BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MODES:-21,BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS:-22,BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MAP:-25,BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_1:-26,BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_2:-27,BROTLI_DECODER_ERROR_ALLOC_BLOCK_TYPE_TREES:-30,BROTLI_DECODER_ERROR_UNREACHABLE:-31},ta))});var Ps=d(f=>{"use strict";var ia=f&&f.__createBinding||(Object.create?(function(s,e,t,i){i===void 0&&(i=t);var r=Object.getOwnPropertyDescriptor(e,t);(!r||("get"in r?!e.__esModule:r.writable||r.configurable))&&(r={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(s,i,r)}):(function(s,e,t,i){i===void 0&&(i=t),s[i]=e[t]})),sa=f&&f.__setModuleDefault||(Object.create?(function(s,e){Object.defineProperty(s,"default",{enumerable:!0,value:e})}):function(s,e){s.default=e}),ra=f&&f.__importStar||(function(){var s=function(e){return s=Object.getOwnPropertyNames||function(t){var i=[];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(i[i.length]=r);return i},s(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var i=s(e),r=0;rs,ms=Gr?.writable===!0||Gr?.set!==void 0?s=>{Ae.Buffer.concat=s?la:ha}:s=>{},Ie=Symbol("_superWrite"),Fe=class extends Error{code;errno;constructor(e,t){super("zlib: "+e.message,{cause:e}),this.code=e.code,this.errno=e.errno,this.code||(this.code="ZLIB_ERROR"),this.message="zlib: "+e.message,Error.captureStackTrace(this,t??this.constructor)}get name(){return"ZlibError"}};f.ZlibError=Fe;var ps=Symbol("flushFlag"),St=class extends oa.Minipass{#e=!1;#i=!1;#s;#n;#r;#t;#o;get sawError(){return this.#e}get handle(){return this.#t}get flushFlag(){return this.#s}constructor(e,t){if(!e||typeof e!="object")throw new TypeError("invalid options for ZlibBase constructor");if(super(e),this.#s=e.flush??0,this.#n=e.finishFlush??0,this.#r=e.fullFlushFlag??0,typeof Hr[t]!="function")throw new TypeError("Compression method not supported: "+t);try{this.#t=new Hr[t](e)}catch(i){throw new Fe(i,this.constructor)}this.#o=i=>{this.#e||(this.#e=!0,this.close(),this.emit("error",i))},this.#t?.on("error",i=>this.#o(new Fe(i))),this.once("end",()=>this.close)}close(){this.#t&&(this.#t.close(),this.#t=void 0,this.emit("close"))}reset(){if(!this.#e)return(0,_s.default)(this.#t,"zlib binding closed"),this.#t.reset?.()}flush(e){this.ended||(typeof e!="number"&&(e=this.#r),this.write(Object.assign(Ae.Buffer.alloc(0),{[ps]:e})))}end(e,t,i){return typeof e=="function"&&(i=e,t=void 0,e=void 0),typeof t=="function"&&(i=t,t=void 0),e&&(t?this.write(e,t):this.write(e)),this.flush(this.#n),this.#i=!0,super.end(i)}get ended(){return this.#i}[Ie](e){return super.write(e)}write(e,t,i){if(typeof t=="function"&&(i=t,t="utf8"),typeof e=="string"&&(e=Ae.Buffer.from(e,t)),this.#e)return;(0,_s.default)(this.#t,"zlib binding closed");let r=this.#t._handle,n=r.close;r.close=()=>{};let o=this.#t.close;this.#t.close=()=>{},ms(!0);let a;try{let l=typeof e[ps]=="number"?e[ps]:this.#s;a=this.#t._processChunk(e,l),ms(!1)}catch(l){ms(!1),this.#o(new Fe(l,this.write))}finally{this.#t&&(this.#t._handle=r,r.close=n,this.#t.close=o,this.#t.removeAllListeners("error"))}this.#t&&this.#t.on("error",l=>this.#o(new Fe(l,this.write)));let h;if(a)if(Array.isArray(a)&&a.length>0){let l=a[0];h=this[Ie](Ae.Buffer.from(l));for(let c=1;c{typeof r=="function"&&(n=r,r=this.flushFlag),this.flush(r),n?.()};try{this.handle.params(e,t)}finally{this.handle.flush=i}this.handle&&(this.#e=e,this.#i=t)}}}};f.Zlib=ie;var ws=class extends ie{constructor(e){super(e,"Deflate")}};f.Deflate=ws;var ys=class extends ie{constructor(e){super(e,"Inflate")}};f.Inflate=ys;var Es=class extends ie{#e;constructor(e){super(e,"Gzip"),this.#e=e&&!!e.portable}[Ie](e){return this.#e?(this.#e=!1,e[9]=255,super[Ie](e)):super[Ie](e)}};f.Gzip=Es;var bs=class extends ie{constructor(e){super(e,"Gunzip")}};f.Gunzip=bs;var Ss=class extends ie{constructor(e){super(e,"DeflateRaw")}};f.DeflateRaw=Ss;var gs=class extends ie{constructor(e){super(e,"InflateRaw")}};f.InflateRaw=gs;var Rs=class extends ie{constructor(e){super(e,"Unzip")}};f.Unzip=Rs;var ei=class extends St{constructor(e,t){e=e||{},e.flush=e.flush||te.constants.BROTLI_OPERATION_PROCESS,e.finishFlush=e.finishFlush||te.constants.BROTLI_OPERATION_FINISH,e.fullFlushFlag=te.constants.BROTLI_OPERATION_FLUSH,super(e,t)}},Os=class extends ei{constructor(e){super(e,"BrotliCompress")}};f.BrotliCompress=Os;var vs=class extends ei{constructor(e){super(e,"BrotliDecompress")}};f.BrotliDecompress=vs;var ti=class extends St{constructor(e,t){e=e||{},e.flush=e.flush||te.constants.ZSTD_e_continue,e.finishFlush=e.finishFlush||te.constants.ZSTD_e_end,e.fullFlushFlag=te.constants.ZSTD_e_flush,super(e,t)}},Ts=class extends ti{constructor(e){super(e,"ZstdCompress")}};f.ZstdCompress=Ts;var Ds=class extends ti{constructor(e){super(e,"ZstdDecompress")}};f.ZstdDecompress=Ds});var Kr=d(Xe=>{"use strict";Object.defineProperty(Xe,"__esModule",{value:!0});Xe.parse=Xe.encode=void 0;var ca=(s,e)=>{if(Number.isSafeInteger(s))s<0?fa(s,e):ua(s,e);else throw Error("cannot encode number outside of javascript safe integer range");return e};Xe.encode=ca;var ua=(s,e)=>{e[0]=128;for(var t=e.length;t>1;t--)e[t-1]=s&255,s=Math.floor(s/256)},fa=(s,e)=>{e[0]=255;var t=!1;s=s*-1;for(var i=e.length;i>1;i--){var r=s&255;s=Math.floor(s/256),t?e[i-1]=Zr(r):r===0?e[i-1]=0:(t=!0,e[i-1]=Yr(r))}},da=s=>{let e=s[0],t=e===128?pa(s.subarray(1,s.length)):e===255?ma(s):null;if(t===null)throw Error("invalid base256 encoding");if(!Number.isSafeInteger(t))throw Error("parsed number outside of javascript safe integer range");return t};Xe.parse=da;var ma=s=>{for(var e=s.length,t=0,i=!1,r=e-1;r>-1;r--){var n=Number(s[r]),o;i?o=Zr(n):n===0?o=n:(i=!0,o=Yr(n)),o!==0&&(t-=o*Math.pow(256,e-r-1))}return t},pa=s=>{for(var e=s.length,t=0,i=e-1;i>-1;i--){var r=Number(s[i]);r!==0&&(t+=r*Math.pow(256,e-i-1))}return t},Zr=s=>(255^s)&255,Yr=s=>(255^s)+1&255});var Ns=d(C=>{"use strict";Object.defineProperty(C,"__esModule",{value:!0});C.code=C.name=C.normalFsTypes=C.isName=C.isCode=void 0;var _a=s=>C.name.has(s);C.isCode=_a;var wa=s=>C.code.has(s);C.isName=wa;C.normalFsTypes=new Set(["0","","1","2","3","4","5","6","7","D"]);C.name=new Map([["0","File"],["","OldFile"],["1","Link"],["2","SymbolicLink"],["3","CharacterDevice"],["4","BlockDevice"],["5","Directory"],["6","FIFO"],["7","ContiguousFile"],["g","GlobalExtendedHeader"],["x","ExtendedHeader"],["A","SolarisACL"],["D","GNUDumpDir"],["I","Inode"],["K","NextFileHasLongLinkpath"],["L","NextFileHasLongPath"],["M","ContinuationFile"],["N","OldGnuLongPath"],["S","SparseFile"],["V","TapeVolumeHeader"],["X","OldExtendedHeader"]]);C.code=new Map(Array.from(C.name).map(s=>[s[1],s[0]]))});var et=d(se=>{"use strict";var ya=se&&se.__createBinding||(Object.create?(function(s,e,t,i){i===void 0&&(i=t);var r=Object.getOwnPropertyDescriptor(e,t);(!r||("get"in r?!e.__esModule:r.writable||r.configurable))&&(r={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(s,i,r)}):(function(s,e,t,i){i===void 0&&(i=t),s[i]=e[t]})),Ea=se&&se.__setModuleDefault||(Object.create?(function(s,e){Object.defineProperty(s,"default",{enumerable:!0,value:e})}):function(s,e){s.default=e}),Vr=se&&se.__importStar||(function(){var s=function(e){return s=Object.getOwnPropertyNames||function(t){var i=[];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(i[i.length]=r);return i},s(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var i=s(e),r=0;rs===void 0||s<0?void 0:s,As=class{cksumValid=!1;needPax=!1;nullBlock=!1;block;path;mode;uid;gid;size;cksum;#e="Unsupported";linkpath;uname;gname;devmaj=0;devmin=0;atime;ctime;mtime;charset;comment;constructor(e,t=0,i,r){Buffer.isBuffer(e)?this.decode(e,t||0,i,r):e&&this.#i(e)}decode(e,t,i,r){if(t||(t=0),!e||!(e.length>=t+512))throw new Error("need 512 bytes for header");let n=Ce(e,t+156,1),o=Je.normalFsTypes.has(n),a=o?i:void 0,h=o?r:void 0;if(this.path=a?.path??Ce(e,t,100),this.mode=a?.mode??h?.mode??Se(e,t+100,8),this.uid=a?.uid??h?.uid??Se(e,t+108,8),this.gid=a?.gid??h?.gid??Se(e,t+116,8),this.size=ba(a?.size??h?.size??Se(e,t+124,12)),this.mtime=a?.mtime??h?.mtime??Ms(e,t+136,12),this.cksum=Se(e,t+148,12),h&&this.#i(h,!0),a&&this.#i(a),Je.isCode(n)&&(this.#e=n||"0"),this.#e==="0"&&this.path.slice(-1)==="/"&&(this.#e="5"),this.#e==="5"&&(this.size=0),this.linkpath=Ce(e,t+157,100),e.subarray(t+257,t+265).toString()==="ustar\x0000")if(this.uname=a?.uname??h?.uname??Ce(e,t+265,32),this.gname=a?.gname??h?.gname??Ce(e,t+297,32),this.devmaj=a?.devmaj??h?.devmaj??Se(e,t+329,8)??0,this.devmin=a?.devmin??h?.devmin??Se(e,t+337,8)??0,e[t+475]!==0){let c=Ce(e,t+345,155);this.path=c+"/"+this.path}else{let c=Ce(e,t+345,130);c&&(this.path=c+"/"+this.path),this.atime=i?.atime??r?.atime??Ms(e,t+476,12),this.ctime=i?.ctime??r?.ctime??Ms(e,t+488,12)}let l=256;for(let c=t;c!(r==null||i==="size"&&Number(r)<0||i==="path"&&t||i==="linkpath"&&t||i==="global"))))}encode(e,t=0){if(e||(e=this.block=Buffer.alloc(512)),this.#e==="Unsupported"&&(this.#e="0"),!(e.length>=t+512))throw new Error("need 512 bytes for header");let i=this.ctime||this.atime?130:155,r=Sa(this.path||"",i),n=r[0],o=r[1];this.needPax=!!r[2],this.needPax=Be(e,t,100,n)||this.needPax,this.needPax=ge(e,t+100,8,this.mode)||this.needPax,this.needPax=ge(e,t+108,8,this.uid)||this.needPax,this.needPax=ge(e,t+116,8,this.gid)||this.needPax,this.needPax=ge(e,t+124,12,this.size)||this.needPax,this.needPax=Ls(e,t+136,12,this.mtime)||this.needPax,e[t+156]=Number(this.#e.codePointAt(0)),this.needPax=Be(e,t+157,100,this.linkpath)||this.needPax,e.write("ustar\x0000",t+257,8),this.needPax=Be(e,t+265,32,this.uname)||this.needPax,this.needPax=Be(e,t+297,32,this.gname)||this.needPax,this.needPax=ge(e,t+329,8,this.devmaj)||this.needPax,this.needPax=ge(e,t+337,8,this.devmin)||this.needPax,this.needPax=Be(e,t+345,i,o)||this.needPax,e[t+475]!==0?this.needPax=Be(e,t+345,155,o)||this.needPax:(this.needPax=Be(e,t+345,130,o)||this.needPax,this.needPax=Ls(e,t+476,12,this.atime)||this.needPax,this.needPax=Ls(e,t+488,12,this.ctime)||this.needPax);let a=256;for(let h=t;h{let i=s,r="",n,o=Qe.posix.parse(s).root||".";if(Buffer.byteLength(i)<100)n=[i,r,!1];else{r=Qe.posix.dirname(i),i=Qe.posix.basename(i);do Buffer.byteLength(i)<=100&&Buffer.byteLength(r)<=e?n=[i,r,!1]:Buffer.byteLength(i)>100&&Buffer.byteLength(r)<=e?n=[i.slice(0,99),r,!0]:(i=Qe.posix.join(Qe.posix.basename(r),i),r=Qe.posix.dirname(r));while(r!==o&&n===void 0);n||(n=[s.slice(0,99),"",!0])}return n},Ce=(s,e,t)=>s.subarray(e,e+t).toString("utf8").replace(/\0.*/,""),Ms=(s,e,t)=>ga(Se(s,e,t)),ga=s=>s===void 0?void 0:new Date(s*1e3),Se=(s,e,t)=>Number(s[e])&128?$r.parse(s.subarray(e,e+t)):Oa(s,e,t),Ra=s=>isNaN(s)?void 0:s,Oa=(s,e,t)=>Ra(parseInt(s.subarray(e,e+t).toString("utf8").replace(/\0.*$/,"").trim(),8)),va={12:8589934591,8:2097151},ge=(s,e,t,i)=>i===void 0?!1:i>va[t]||i<0?($r.encode(i,s.subarray(e,e+t)),!0):(Ta(s,e,t,i),!1),Ta=(s,e,t,i)=>s.write(Da(i,t),e,t,"ascii"),Da=(s,e)=>Pa(Math.floor(s).toString(8),e),Pa=(s,e)=>(s.length===e-1?s:new Array(e-s.length-1).join("0")+s+" ")+"\0",Ls=(s,e,t,i)=>i===void 0?!1:ge(s,e,t,i.getTime()/1e3),Na=new Array(156).join("\0"),Be=(s,e,t,i)=>i===void 0?!1:(s.write(i+Na,e,t,"utf8"),i.length!==Buffer.byteLength(i)||i.length>t)});var si=d(ii=>{"use strict";Object.defineProperty(ii,"__esModule",{value:!0});ii.Pax=void 0;var Ma=require("node:path"),La=et(),Is=class s{atime;mtime;ctime;charset;comment;gid;uid;gname;uname;linkpath;dev;ino;nlink;path;size;mode;global;constructor(e,t=!1){this.atime=e.atime,this.charset=e.charset,this.comment=e.comment,this.ctime=e.ctime,this.dev=e.dev,this.gid=e.gid,this.global=t,this.gname=e.gname,this.ino=e.ino,this.linkpath=e.linkpath,this.mtime=e.mtime,this.nlink=e.nlink,this.path=e.path,this.size=e.size,this.uid=e.uid,this.uname=e.uname}encode(){let e=this.encodeBody();if(e==="")return Buffer.allocUnsafe(0);let t=Buffer.byteLength(e),i=512*Math.ceil(1+t/512),r=Buffer.allocUnsafe(i);for(let n=0;n<512;n++)r[n]=0;new La.Header({path:("PaxHeader/"+(0,Ma.basename)(this.path??"")).slice(0,99),mode:this.mode||420,uid:this.uid,gid:this.gid,size:t,mtime:this.mtime,type:this.global?"GlobalExtendedHeader":"ExtendedHeader",linkpath:"",uname:this.uname||"",gname:this.gname||"",devmaj:0,devmin:0,atime:this.atime,ctime:this.ctime}).encode(r),r.write(e,512,t,"utf8");for(let n=t+512;n()=>(e||s((e={exports:{}}).exports,e),e.exports);var We=d(F=>{"use strict";var Do=F&&F.__importDefault||function(s){return s&&s.__esModule?s:{default:s}};Object.defineProperty(F,"__esModule",{value:!0});F.Minipass=F.isWritable=F.isReadable=F.isStream=void 0;var kr=typeof process=="object"&&process?process:{stdout:null,stderr:null},ss=require("node:events"),qr=Do(require("node:stream")),Po=require("node:string_decoder"),No=s=>!!s&&typeof s=="object"&&(s instanceof Zt||s instanceof qr.default||(0,F.isReadable)(s)||(0,F.isWritable)(s));F.isStream=No;var Mo=s=>!!s&&typeof s=="object"&&s instanceof ss.EventEmitter&&typeof s.pipe=="function"&&s.pipe!==qr.default.Writable.prototype.pipe;F.isReadable=Mo;var Lo=s=>!!s&&typeof s=="object"&&s instanceof ss.EventEmitter&&typeof s.write=="function"&&typeof s.end=="function";F.isWritable=Lo;var ce=Symbol("EOF"),ue=Symbol("maybeEmitEnd"),we=Symbol("emittedEnd"),jt=Symbol("emittingEnd"),dt=Symbol("emittedError"),Ut=Symbol("closed"),xr=Symbol("read"),qt=Symbol("flush"),jr=Symbol("flushChunk"),K=Symbol("encoding"),Ue=Symbol("decoder"),R=Symbol("flowing"),mt=Symbol("paused"),qe=Symbol("resume"),O=Symbol("buffer"),I=Symbol("pipes"),v=Symbol("bufferLength"),Xi=Symbol("bufferPush"),Wt=Symbol("bufferShift"),N=Symbol("objectMode"),E=Symbol("destroyed"),Qi=Symbol("error"),Ji=Symbol("emitData"),Ur=Symbol("emitEnd"),es=Symbol("emitEnd2"),J=Symbol("async"),ts=Symbol("abort"),Ht=Symbol("aborted"),pt=Symbol("signal"),Ne=Symbol("dataListeners"),x=Symbol("discarded"),_t=s=>Promise.resolve().then(s),Ao=s=>s(),Io=s=>s==="end"||s==="finish"||s==="prefinish",Fo=s=>s instanceof ArrayBuffer||!!s&&typeof s=="object"&&s.constructor&&s.constructor.name==="ArrayBuffer"&&s.byteLength>=0,Co=s=>!Buffer.isBuffer(s)&&ArrayBuffer.isView(s),Gt=class{src;dest;opts;ondrain;constructor(e,t,i){this.src=e,this.dest=t,this.opts=i,this.ondrain=()=>e[qe](),this.dest.on("drain",this.ondrain)}unpipe(){this.dest.removeListener("drain",this.ondrain)}proxyErrors(e){}end(){this.unpipe(),this.opts.end&&this.dest.end()}},is=class extends Gt{unpipe(){this.src.removeListener("error",this.proxyErrors),super.unpipe()}constructor(e,t,i){super(e,t,i),this.proxyErrors=r=>this.dest.emit("error",r),e.on("error",this.proxyErrors)}},Bo=s=>!!s.objectMode,zo=s=>!s.objectMode&&!!s.encoding&&s.encoding!=="buffer",Zt=class extends ss.EventEmitter{[R]=!1;[mt]=!1;[I]=[];[O]=[];[N];[K];[J];[Ue];[ce]=!1;[we]=!1;[jt]=!1;[Ut]=!1;[dt]=null;[v]=0;[E]=!1;[pt];[Ht]=!1;[Ne]=0;[x]=!1;writable=!0;readable=!0;constructor(...e){let t=e[0]||{};if(super(),t.objectMode&&typeof t.encoding=="string")throw new TypeError("Encoding and objectMode may not be used together");Bo(t)?(this[N]=!0,this[K]=null):zo(t)?(this[K]=t.encoding,this[N]=!1):(this[N]=!1,this[K]=null),this[J]=!!t.async,this[Ue]=this[K]?new Po.StringDecoder(this[K]):null,t&&t.debugExposeBuffer===!0&&Object.defineProperty(this,"buffer",{get:()=>this[O]}),t&&t.debugExposePipes===!0&&Object.defineProperty(this,"pipes",{get:()=>this[I]});let{signal:i}=t;i&&(this[pt]=i,i.aborted?this[ts]():i.addEventListener("abort",()=>this[ts]()))}get bufferLength(){return this[v]}get encoding(){return this[K]}set encoding(e){throw new Error("Encoding must be set at instantiation time")}setEncoding(e){throw new Error("Encoding must be set at instantiation time")}get objectMode(){return this[N]}set objectMode(e){throw new Error("objectMode must be set at instantiation time")}get async(){return this[J]}set async(e){this[J]=this[J]||!!e}[ts](){this[Ht]=!0,this.emit("abort",this[pt]?.reason),this.destroy(this[pt]?.reason)}get aborted(){return this[Ht]}set aborted(e){}write(e,t,i){if(this[Ht])return!1;if(this[ce])throw new Error("write after end");if(this[E])return this.emit("error",Object.assign(new Error("Cannot call write after a stream was destroyed"),{code:"ERR_STREAM_DESTROYED"})),!0;typeof t=="function"&&(i=t,t="utf8"),t||(t="utf8");let r=this[J]?_t:Ao;if(!this[N]&&!Buffer.isBuffer(e)){if(Co(e))e=Buffer.from(e.buffer,e.byteOffset,e.byteLength);else if(Fo(e))e=Buffer.from(e);else if(typeof e!="string")throw new Error("Non-contiguous data written to non-objectMode stream")}return this[N]?(this[R]&&this[v]!==0&&this[qt](!0),this[R]?this.emit("data",e):this[Xi](e),this[v]!==0&&this.emit("readable"),i&&r(i),this[R]):e.length?(typeof e=="string"&&!(t===this[K]&&!this[Ue]?.lastNeed)&&(e=Buffer.from(e,t)),Buffer.isBuffer(e)&&this[K]&&(e=this[Ue].write(e)),this[R]&&this[v]!==0&&this[qt](!0),this[R]?this.emit("data",e):this[Xi](e),this[v]!==0&&this.emit("readable"),i&&r(i),this[R]):(this[v]!==0&&this.emit("readable"),i&&r(i),this[R])}read(e){if(this[E])return null;if(this[x]=!1,this[v]===0||e===0||e&&e>this[v])return this[ue](),null;this[N]&&(e=null),this[O].length>1&&!this[N]&&(this[O]=[this[K]?this[O].join(""):Buffer.concat(this[O],this[v])]);let t=this[xr](e||null,this[O][0]);return this[ue](),t}[xr](e,t){if(this[N])this[Wt]();else{let i=t;e===i.length||e===null?this[Wt]():typeof i=="string"?(this[O][0]=i.slice(e),t=i.slice(0,e),this[v]-=e):(this[O][0]=i.subarray(e),t=i.subarray(0,e),this[v]-=e)}return this.emit("data",t),!this[O].length&&!this[ce]&&this.emit("drain"),t}end(e,t,i){return typeof e=="function"&&(i=e,e=void 0),typeof t=="function"&&(i=t,t="utf8"),e!==void 0&&this.write(e,t),i&&this.once("end",i),this[ce]=!0,this.writable=!1,(this[R]||!this[mt])&&this[ue](),this}[qe](){this[E]||(!this[Ne]&&!this[I].length&&(this[x]=!0),this[mt]=!1,this[R]=!0,this.emit("resume"),this[O].length?this[qt]():this[ce]?this[ue]():this.emit("drain"))}resume(){return this[qe]()}pause(){this[R]=!1,this[mt]=!0,this[x]=!1}get destroyed(){return this[E]}get flowing(){return this[R]}get paused(){return this[mt]}[Xi](e){this[N]?this[v]+=1:this[v]+=e.length,this[O].push(e)}[Wt](){return this[N]?this[v]-=1:this[v]-=this[O][0].length,this[O].shift()}[qt](e=!1){do;while(this[jr](this[Wt]())&&this[O].length);!e&&!this[O].length&&!this[ce]&&this.emit("drain")}[jr](e){return this.emit("data",e),this[R]}pipe(e,t){if(this[E])return e;this[x]=!1;let i=this[we];return t=t||{},e===kr.stdout||e===kr.stderr?t.end=!1:t.end=t.end!==!1,t.proxyErrors=!!t.proxyErrors,i?t.end&&e.end():(this[I].push(t.proxyErrors?new is(this,e,t):new Gt(this,e,t)),this[J]?_t(()=>this[qe]()):this[qe]()),e}unpipe(e){let t=this[I].find(i=>i.dest===e);t&&(this[I].length===1?(this[R]&&this[Ne]===0&&(this[R]=!1),this[I]=[]):this[I].splice(this[I].indexOf(t),1),t.unpipe())}addListener(e,t){return this.on(e,t)}on(e,t){let i=super.on(e,t);if(e==="data")this[x]=!1,this[Ne]++,!this[I].length&&!this[R]&&this[qe]();else if(e==="readable"&&this[v]!==0)super.emit("readable");else if(Io(e)&&this[we])super.emit(e),this.removeAllListeners(e);else if(e==="error"&&this[dt]){let r=t;this[J]?_t(()=>r.call(this,this[dt])):r.call(this,this[dt])}return i}removeListener(e,t){return this.off(e,t)}off(e,t){let i=super.off(e,t);return e==="data"&&(this[Ne]=this.listeners("data").length,this[Ne]===0&&!this[x]&&!this[I].length&&(this[R]=!1)),i}removeAllListeners(e){let t=super.removeAllListeners(e);return(e==="data"||e===void 0)&&(this[Ne]=0,!this[x]&&!this[I].length&&(this[R]=!1)),t}get emittedEnd(){return this[we]}[ue](){!this[jt]&&!this[we]&&!this[E]&&this[O].length===0&&this[ce]&&(this[jt]=!0,this.emit("end"),this.emit("prefinish"),this.emit("finish"),this[Ut]&&this.emit("close"),this[jt]=!1)}emit(e,...t){let i=t[0];if(e!=="error"&&e!=="close"&&e!==E&&this[E])return!1;if(e==="data")return!this[N]&&!i?!1:this[J]?(_t(()=>this[Ji](i)),!0):this[Ji](i);if(e==="end")return this[Ur]();if(e==="close"){if(this[Ut]=!0,!this[we]&&!this[E])return!1;let n=super.emit("close");return this.removeAllListeners("close"),n}else if(e==="error"){this[dt]=i,super.emit(Qi,i);let n=!this[pt]||this.listeners("error").length?super.emit("error",i):!1;return this[ue](),n}else if(e==="resume"){let n=super.emit("resume");return this[ue](),n}else if(e==="finish"||e==="prefinish"){let n=super.emit(e);return this.removeAllListeners(e),n}let r=super.emit(e,...t);return this[ue](),r}[Ji](e){for(let i of this[I])i.dest.write(e)===!1&&this.pause();let t=this[x]?!1:super.emit("data",e);return this[ue](),t}[Ur](){return this[we]?!1:(this[we]=!0,this.readable=!1,this[J]?(_t(()=>this[es]()),!0):this[es]())}[es](){if(this[Ue]){let t=this[Ue].end();if(t){for(let i of this[I])i.dest.write(t);this[x]||super.emit("data",t)}}for(let t of this[I])t.end();let e=super.emit("end");return this.removeAllListeners("end"),e}async collect(){let e=Object.assign([],{dataLength:0});this[N]||(e.dataLength=0);let t=this.promise();return this.on("data",i=>{e.push(i),this[N]||(e.dataLength+=i.length)}),await t,e}async concat(){if(this[N])throw new Error("cannot concat in objectMode");let e=await this.collect();return this[K]?e.join(""):Buffer.concat(e,e.dataLength)}async promise(){return new Promise((e,t)=>{this.on(E,()=>t(new Error("stream destroyed"))),this.on("error",i=>t(i)),this.on("end",()=>e())})}[Symbol.asyncIterator](){this[x]=!1;let e=!1,t=async()=>(this.pause(),e=!0,{value:void 0,done:!0});return{next:()=>{if(e)return t();let r=this.read();if(r!==null)return Promise.resolve({done:!1,value:r});if(this[ce])return t();let n,o,a=u=>{this.off("data",h),this.off("end",l),this.off(E,c),t(),o(u)},h=u=>{this.off("error",a),this.off("end",l),this.off(E,c),this.pause(),n({value:u,done:!!this[ce]})},l=()=>{this.off("error",a),this.off("data",h),this.off(E,c),t(),n({done:!0,value:void 0})},c=()=>a(new Error("stream destroyed"));return new Promise((u,b)=>{o=b,n=u,this.once(E,c),this.once("error",a),this.once("end",l),this.once("data",h)})},throw:t,return:t,[Symbol.asyncIterator](){return this},[Symbol.asyncDispose]:async()=>{}}}[Symbol.iterator](){this[x]=!1;let e=!1,t=()=>(this.pause(),this.off(Qi,t),this.off(E,t),this.off("end",t),e=!0,{done:!0,value:void 0}),i=()=>{if(e)return t();let r=this.read();return r===null?t():{done:!1,value:r}};return this.once("end",t),this.once(Qi,t),this.once(E,t),{next:i,throw:t,return:t,[Symbol.iterator](){return this},[Symbol.dispose]:()=>{}}}destroy(e){if(this[E])return e?this.emit("error",e):this.emit(E),this;this[E]=!0,this[x]=!0,this[O].length=0,this[v]=0;let t=this;return typeof t.close=="function"&&!this[Ut]&&t.close(),e?this.emit("error",e):this.emit(E),this}static get isStream(){return F.isStream}};F.Minipass=Zt});var Ke=d(W=>{"use strict";var Wr=W&&W.__importDefault||function(s){return s&&s.__esModule?s:{default:s}};Object.defineProperty(W,"__esModule",{value:!0});W.WriteStreamSync=W.WriteStream=W.ReadStreamSync=W.ReadStream=void 0;var ko=Wr(require("events")),z=Wr(require("fs")),xo=We(),jo=z.default.writev,Ee=Symbol("_autoClose"),$=Symbol("_close"),wt=Symbol("_ended"),p=Symbol("_fd"),rs=Symbol("_finished"),de=Symbol("_flags"),ns=Symbol("_flush"),ls=Symbol("_handleChunk"),cs=Symbol("_makeBuf"),Et=Symbol("_mode"),Yt=Symbol("_needDrain"),Ze=Symbol("_onerror"),Ye=Symbol("_onopen"),os=Symbol("_onread"),He=Symbol("_onwrite"),be=Symbol("_open"),V=Symbol("_path"),ye=Symbol("_pos"),ee=Symbol("_queue"),Ge=Symbol("_read"),as=Symbol("_readSize"),fe=Symbol("_reading"),yt=Symbol("_remain"),hs=Symbol("_size"),Kt=Symbol("_write"),Me=Symbol("_writing"),Vt=Symbol("_defaultFlag"),Le=Symbol("_errored"),$t=class extends xo.Minipass{[Le]=!1;[p];[V];[as];[fe]=!1;[hs];[yt];[Ee];constructor(e,t){if(t=t||{},super(t),this.readable=!0,this.writable=!1,typeof e!="string")throw new TypeError("path must be a string");this[Le]=!1,this[p]=typeof t.fd=="number"?t.fd:void 0,this[V]=e,this[as]=t.readSize||16*1024*1024,this[fe]=!1,this[hs]=typeof t.size=="number"?t.size:1/0,this[yt]=this[hs],this[Ee]=typeof t.autoClose=="boolean"?t.autoClose:!0,typeof this[p]=="number"?this[Ge]():this[be]()}get fd(){return this[p]}get path(){return this[V]}write(){throw new TypeError("this is a readable stream")}end(){throw new TypeError("this is a readable stream")}[be](){z.default.open(this[V],"r",(e,t)=>this[Ye](e,t))}[Ye](e,t){e?this[Ze](e):(this[p]=t,this.emit("open",t),this[Ge]())}[cs](){return Buffer.allocUnsafe(Math.min(this[as],this[yt]))}[Ge](){if(!this[fe]){this[fe]=!0;let e=this[cs]();if(e.length===0)return process.nextTick(()=>this[os](null,0,e));z.default.read(this[p],e,0,e.length,null,(t,i,r)=>this[os](t,i,r))}}[os](e,t,i){this[fe]=!1,e?this[Ze](e):this[ls](t,i)&&this[Ge]()}[$](){if(this[Ee]&&typeof this[p]=="number"){let e=this[p];this[p]=void 0,z.default.close(e,t=>t?this.emit("error",t):this.emit("close"))}}[Ze](e){this[fe]=!0,this[$](),this.emit("error",e)}[ls](e,t){let i=!1;return this[yt]-=e,e>0&&(i=super.write(ethis[Ye](e,t))}[Ye](e,t){this[Vt]&&this[de]==="r+"&&e&&e.code==="ENOENT"?(this[de]="w",this[be]()):e?this[Ze](e):(this[p]=t,this.emit("open",t),this[Me]||this[ns]())}end(e,t){return e&&this.write(e,t),this[wt]=!0,!this[Me]&&!this[ee].length&&typeof this[p]=="number"&&this[He](null,0),this}write(e,t){return typeof e=="string"&&(e=Buffer.from(e,t)),this[wt]?(this.emit("error",new Error("write() after end()")),!1):this[p]===void 0||this[Me]||this[ee].length?(this[ee].push(e),this[Yt]=!0,!1):(this[Me]=!0,this[Kt](e),!0)}[Kt](e){z.default.write(this[p],e,0,e.length,this[ye],(t,i)=>this[He](t,i))}[He](e,t){e?this[Ze](e):(this[ye]!==void 0&&typeof t=="number"&&(this[ye]+=t),this[ee].length?this[ns]():(this[Me]=!1,this[wt]&&!this[rs]?(this[rs]=!0,this[$](),this.emit("finish")):this[Yt]&&(this[Yt]=!1,this.emit("drain"))))}[ns](){if(this[ee].length===0)this[wt]&&this[He](null,0);else if(this[ee].length===1)this[Kt](this[ee].pop());else{let e=this[ee];this[ee]=[],jo(this[p],e,this[ye],(t,i)=>this[He](t,i))}}[$](){if(this[Ee]&&typeof this[p]=="number"){let e=this[p];this[p]=void 0,z.default.close(e,t=>t?this.emit("error",t):this.emit("close"))}}};W.WriteStream=Xt;var fs=class extends Xt{[be](){let e;if(this[Vt]&&this[de]==="r+")try{e=z.default.openSync(this[V],this[de],this[Et])}catch(t){if(t?.code==="ENOENT")return this[de]="w",this[be]();throw t}else e=z.default.openSync(this[V],this[de],this[Et]);this[Ye](null,e)}[$](){if(this[Ee]&&typeof this[p]=="number"){let e=this[p];this[p]=void 0,z.default.closeSync(e),this.emit("close")}}[Kt](e){let t=!0;try{this[He](null,z.default.writeSync(this[p],e,0,e.length,this[ye])),t=!1}finally{if(t)try{this[$]()}catch{}}}};W.WriteStreamSync=fs});var Qt=d(S=>{"use strict";Object.defineProperty(S,"__esModule",{value:!0});S.dealias=S.isNoFile=S.isFile=S.isAsync=S.isSync=S.isAsyncNoFile=S.isSyncNoFile=S.isAsyncFile=S.isSyncFile=void 0;var Uo=new Map([["C","cwd"],["f","file"],["z","gzip"],["P","preservePaths"],["U","unlink"],["strip-components","strip"],["stripComponents","strip"],["keep-newer","newer"],["keepNewer","newer"],["keep-newer-files","newer"],["keepNewerFiles","newer"],["k","keep"],["keep-existing","keep"],["keepExisting","keep"],["m","noMtime"],["no-mtime","noMtime"],["p","preserveOwner"],["L","follow"],["h","follow"],["onentry","onReadEntry"]]),qo=s=>!!s.sync&&!!s.file;S.isSyncFile=qo;var Wo=s=>!s.sync&&!!s.file;S.isAsyncFile=Wo;var Ho=s=>!!s.sync&&!s.file;S.isSyncNoFile=Ho;var Go=s=>!s.sync&&!s.file;S.isAsyncNoFile=Go;var Zo=s=>!!s.sync;S.isSync=Zo;var Yo=s=>!s.sync;S.isAsync=Yo;var Ko=s=>!!s.file;S.isFile=Ko;var Vo=s=>!s.file;S.isNoFile=Vo;var $o=s=>{let e=Uo.get(s);return e||s},Xo=(s={})=>{if(!s)return{};let e={};for(let[t,i]of Object.entries(s)){let r=$o(t);e[r]=i}return e.chmod===void 0&&e.noChmod===!1&&(e.chmod=!0),delete e.noChmod,e};S.dealias=Xo});var Ve=d(Jt=>{"use strict";Object.defineProperty(Jt,"__esModule",{value:!0});Jt.makeCommand=void 0;var bt=Qt(),Qo=(s,e,t,i,r)=>Object.assign((n=[],o,a)=>{Array.isArray(n)&&(o=n,n={}),typeof o=="function"&&(a=o,o=void 0),o=o?Array.from(o):[];let h=(0,bt.dealias)(n);if(r?.(h,o),(0,bt.isSyncFile)(h)){if(typeof a=="function")throw new TypeError("callback not supported for sync tar functions");return s(h,o)}else if((0,bt.isAsyncFile)(h)){let l=e(h,o);return a?l.then(()=>a(),a):l}else if((0,bt.isSyncNoFile)(h)){if(typeof a=="function")throw new TypeError("callback not supported for sync tar functions");return t(h,o)}else if((0,bt.isAsyncNoFile)(h)){if(typeof a=="function")throw new TypeError("callback only supported with file option");return i(h,o)}throw new Error("impossible options??")},{syncFile:s,asyncFile:e,syncNoFile:t,asyncNoFile:i,validate:r});Jt.makeCommand=Qo});var ds=d($e=>{"use strict";var Jo=$e&&$e.__importDefault||function(s){return s&&s.__esModule?s:{default:s}};Object.defineProperty($e,"__esModule",{value:!0});$e.constants=void 0;var ea=Jo(require("zlib")),ta=ea.default.constants||{ZLIB_VERNUM:4736};$e.constants=Object.freeze(Object.assign(Object.create(null),{Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_MEM_ERROR:-4,Z_BUF_ERROR:-5,Z_VERSION_ERROR:-6,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,DEFLATE:1,INFLATE:2,GZIP:3,GUNZIP:4,DEFLATERAW:5,INFLATERAW:6,UNZIP:7,BROTLI_DECODE:8,BROTLI_ENCODE:9,Z_MIN_WINDOWBITS:8,Z_MAX_WINDOWBITS:15,Z_DEFAULT_WINDOWBITS:15,Z_MIN_CHUNK:64,Z_MAX_CHUNK:1/0,Z_DEFAULT_CHUNK:16384,Z_MIN_MEMLEVEL:1,Z_MAX_MEMLEVEL:9,Z_DEFAULT_MEMLEVEL:8,Z_MIN_LEVEL:-1,Z_MAX_LEVEL:9,Z_DEFAULT_LEVEL:-1,BROTLI_OPERATION_PROCESS:0,BROTLI_OPERATION_FLUSH:1,BROTLI_OPERATION_FINISH:2,BROTLI_OPERATION_EMIT_METADATA:3,BROTLI_MODE_GENERIC:0,BROTLI_MODE_TEXT:1,BROTLI_MODE_FONT:2,BROTLI_DEFAULT_MODE:0,BROTLI_MIN_QUALITY:0,BROTLI_MAX_QUALITY:11,BROTLI_DEFAULT_QUALITY:11,BROTLI_MIN_WINDOW_BITS:10,BROTLI_MAX_WINDOW_BITS:24,BROTLI_LARGE_MAX_WINDOW_BITS:30,BROTLI_DEFAULT_WINDOW:22,BROTLI_MIN_INPUT_BLOCK_BITS:16,BROTLI_MAX_INPUT_BLOCK_BITS:24,BROTLI_PARAM_MODE:0,BROTLI_PARAM_QUALITY:1,BROTLI_PARAM_LGWIN:2,BROTLI_PARAM_LGBLOCK:3,BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING:4,BROTLI_PARAM_SIZE_HINT:5,BROTLI_PARAM_LARGE_WINDOW:6,BROTLI_PARAM_NPOSTFIX:7,BROTLI_PARAM_NDIRECT:8,BROTLI_DECODER_RESULT_ERROR:0,BROTLI_DECODER_RESULT_SUCCESS:1,BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT:2,BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT:3,BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION:0,BROTLI_DECODER_PARAM_LARGE_WINDOW:1,BROTLI_DECODER_NO_ERROR:0,BROTLI_DECODER_SUCCESS:1,BROTLI_DECODER_NEEDS_MORE_INPUT:2,BROTLI_DECODER_NEEDS_MORE_OUTPUT:3,BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_NIBBLE:-1,BROTLI_DECODER_ERROR_FORMAT_RESERVED:-2,BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_META_NIBBLE:-3,BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET:-4,BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME:-5,BROTLI_DECODER_ERROR_FORMAT_CL_SPACE:-6,BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE:-7,BROTLI_DECODER_ERROR_FORMAT_CONTEXT_MAP_REPEAT:-8,BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_1:-9,BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_2:-10,BROTLI_DECODER_ERROR_FORMAT_TRANSFORM:-11,BROTLI_DECODER_ERROR_FORMAT_DICTIONARY:-12,BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS:-13,BROTLI_DECODER_ERROR_FORMAT_PADDING_1:-14,BROTLI_DECODER_ERROR_FORMAT_PADDING_2:-15,BROTLI_DECODER_ERROR_FORMAT_DISTANCE:-16,BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET:-19,BROTLI_DECODER_ERROR_INVALID_ARGUMENTS:-20,BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MODES:-21,BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS:-22,BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MAP:-25,BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_1:-26,BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_2:-27,BROTLI_DECODER_ERROR_ALLOC_BLOCK_TYPE_TREES:-30,BROTLI_DECODER_ERROR_UNREACHABLE:-31},ta))});var Ps=d(f=>{"use strict";var ia=f&&f.__createBinding||(Object.create?(function(s,e,t,i){i===void 0&&(i=t);var r=Object.getOwnPropertyDescriptor(e,t);(!r||("get"in r?!e.__esModule:r.writable||r.configurable))&&(r={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(s,i,r)}):(function(s,e,t,i){i===void 0&&(i=t),s[i]=e[t]})),sa=f&&f.__setModuleDefault||(Object.create?(function(s,e){Object.defineProperty(s,"default",{enumerable:!0,value:e})}):function(s,e){s.default=e}),ra=f&&f.__importStar||(function(){var s=function(e){return s=Object.getOwnPropertyNames||function(t){var i=[];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(i[i.length]=r);return i},s(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var i=s(e),r=0;rs,ms=Gr?.writable===!0||Gr?.set!==void 0?s=>{Ae.Buffer.concat=s?la:ha}:s=>{},Ie=Symbol("_superWrite"),Fe=class extends Error{code;errno;constructor(e,t){super("zlib: "+e.message,{cause:e}),this.code=e.code,this.errno=e.errno,this.code||(this.code="ZLIB_ERROR"),this.message="zlib: "+e.message,Error.captureStackTrace(this,t??this.constructor)}get name(){return"ZlibError"}};f.ZlibError=Fe;var ps=Symbol("flushFlag"),St=class extends oa.Minipass{#e=!1;#i=!1;#s;#n;#r;#t;#o;get sawError(){return this.#e}get handle(){return this.#t}get flushFlag(){return this.#s}constructor(e,t){if(!e||typeof e!="object")throw new TypeError("invalid options for ZlibBase constructor");if(super(e),this.#s=e.flush??0,this.#n=e.finishFlush??0,this.#r=e.fullFlushFlag??0,typeof Hr[t]!="function")throw new TypeError("Compression method not supported: "+t);try{this.#t=new Hr[t](e)}catch(i){throw new Fe(i,this.constructor)}this.#o=i=>{this.#e||(this.#e=!0,this.close(),this.emit("error",i))},this.#t?.on("error",i=>this.#o(new Fe(i))),this.once("end",()=>this.close)}close(){this.#t&&(this.#t.close(),this.#t=void 0,this.emit("close"))}reset(){if(!this.#e)return(0,_s.default)(this.#t,"zlib binding closed"),this.#t.reset?.()}flush(e){this.ended||(typeof e!="number"&&(e=this.#r),this.write(Object.assign(Ae.Buffer.alloc(0),{[ps]:e})))}end(e,t,i){return typeof e=="function"&&(i=e,t=void 0,e=void 0),typeof t=="function"&&(i=t,t=void 0),e&&(t?this.write(e,t):this.write(e)),this.flush(this.#n),this.#i=!0,super.end(i)}get ended(){return this.#i}[Ie](e){return super.write(e)}write(e,t,i){if(typeof t=="function"&&(i=t,t="utf8"),typeof e=="string"&&(e=Ae.Buffer.from(e,t)),this.#e)return;(0,_s.default)(this.#t,"zlib binding closed");let r=this.#t._handle,n=r.close;r.close=()=>{};let o=this.#t.close;this.#t.close=()=>{},ms(!0);let a;try{let l=typeof e[ps]=="number"?e[ps]:this.#s;a=this.#t._processChunk(e,l),ms(!1)}catch(l){ms(!1),this.#o(new Fe(l,this.write))}finally{this.#t&&(this.#t._handle=r,r.close=n,this.#t.close=o,this.#t.removeAllListeners("error"))}this.#t&&this.#t.on("error",l=>this.#o(new Fe(l,this.write)));let h;if(a)if(Array.isArray(a)&&a.length>0){let l=a[0];h=this[Ie](Ae.Buffer.from(l));for(let c=1;c{typeof r=="function"&&(n=r,r=this.flushFlag),this.flush(r),n?.()};try{this.handle.params(e,t)}finally{this.handle.flush=i}this.handle&&(this.#e=e,this.#i=t)}}}};f.Zlib=ie;var ws=class extends ie{constructor(e){super(e,"Deflate")}};f.Deflate=ws;var ys=class extends ie{constructor(e){super(e,"Inflate")}};f.Inflate=ys;var Es=class extends ie{#e;constructor(e){super(e,"Gzip"),this.#e=e&&!!e.portable}[Ie](e){return this.#e?(this.#e=!1,e[9]=255,super[Ie](e)):super[Ie](e)}};f.Gzip=Es;var bs=class extends ie{constructor(e){super(e,"Gunzip")}};f.Gunzip=bs;var Ss=class extends ie{constructor(e){super(e,"DeflateRaw")}};f.DeflateRaw=Ss;var gs=class extends ie{constructor(e){super(e,"InflateRaw")}};f.InflateRaw=gs;var Rs=class extends ie{constructor(e){super(e,"Unzip")}};f.Unzip=Rs;var ei=class extends St{constructor(e,t){e=e||{},e.flush=e.flush||te.constants.BROTLI_OPERATION_PROCESS,e.finishFlush=e.finishFlush||te.constants.BROTLI_OPERATION_FINISH,e.fullFlushFlag=te.constants.BROTLI_OPERATION_FLUSH,super(e,t)}},Os=class extends ei{constructor(e){super(e,"BrotliCompress")}};f.BrotliCompress=Os;var vs=class extends ei{constructor(e){super(e,"BrotliDecompress")}};f.BrotliDecompress=vs;var ti=class extends St{constructor(e,t){e=e||{},e.flush=e.flush||te.constants.ZSTD_e_continue,e.finishFlush=e.finishFlush||te.constants.ZSTD_e_end,e.fullFlushFlag=te.constants.ZSTD_e_flush,super(e,t)}},Ts=class extends ti{constructor(e){super(e,"ZstdCompress")}};f.ZstdCompress=Ts;var Ds=class extends ti{constructor(e){super(e,"ZstdDecompress")}};f.ZstdDecompress=Ds});var Kr=d(Xe=>{"use strict";Object.defineProperty(Xe,"__esModule",{value:!0});Xe.parse=Xe.encode=void 0;var ca=(s,e)=>{if(Number.isSafeInteger(s))s<0?fa(s,e):ua(s,e);else throw Error("cannot encode number outside of javascript safe integer range");return e};Xe.encode=ca;var ua=(s,e)=>{e[0]=128;for(var t=e.length;t>1;t--)e[t-1]=s&255,s=Math.floor(s/256)},fa=(s,e)=>{e[0]=255;var t=!1;s=s*-1;for(var i=e.length;i>1;i--){var r=s&255;s=Math.floor(s/256),t?e[i-1]=Zr(r):r===0?e[i-1]=0:(t=!0,e[i-1]=Yr(r))}},da=s=>{let e=s[0],t=e===128?pa(s.subarray(1,s.length)):e===255?ma(s):null;if(t===null)throw Error("invalid base256 encoding");if(!Number.isSafeInteger(t))throw Error("parsed number outside of javascript safe integer range");return t};Xe.parse=da;var ma=s=>{for(var e=s.length,t=0,i=!1,r=e-1;r>-1;r--){var n=Number(s[r]),o;i?o=Zr(n):n===0?o=n:(i=!0,o=Yr(n)),o!==0&&(t-=o*Math.pow(256,e-r-1))}return t},pa=s=>{for(var e=s.length,t=0,i=e-1;i>-1;i--){var r=Number(s[i]);r!==0&&(t+=r*Math.pow(256,e-i-1))}return t},Zr=s=>(255^s)&255,Yr=s=>(255^s)+1&255});var Ns=d(C=>{"use strict";Object.defineProperty(C,"__esModule",{value:!0});C.code=C.name=C.normalFsTypes=C.isName=C.isCode=void 0;var _a=s=>C.name.has(s);C.isCode=_a;var wa=s=>C.code.has(s);C.isName=wa;C.normalFsTypes=new Set(["0","","1","2","3","4","5","6","7","D"]);C.name=new Map([["0","File"],["","OldFile"],["1","Link"],["2","SymbolicLink"],["3","CharacterDevice"],["4","BlockDevice"],["5","Directory"],["6","FIFO"],["7","ContiguousFile"],["g","GlobalExtendedHeader"],["x","ExtendedHeader"],["A","SolarisACL"],["D","GNUDumpDir"],["I","Inode"],["K","NextFileHasLongLinkpath"],["L","NextFileHasLongPath"],["M","ContinuationFile"],["N","OldGnuLongPath"],["S","SparseFile"],["V","TapeVolumeHeader"],["X","OldExtendedHeader"]]);C.code=new Map(Array.from(C.name).map(s=>[s[1],s[0]]))});var et=d(se=>{"use strict";var ya=se&&se.__createBinding||(Object.create?(function(s,e,t,i){i===void 0&&(i=t);var r=Object.getOwnPropertyDescriptor(e,t);(!r||("get"in r?!e.__esModule:r.writable||r.configurable))&&(r={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(s,i,r)}):(function(s,e,t,i){i===void 0&&(i=t),s[i]=e[t]})),Ea=se&&se.__setModuleDefault||(Object.create?(function(s,e){Object.defineProperty(s,"default",{enumerable:!0,value:e})}):function(s,e){s.default=e}),Vr=se&&se.__importStar||(function(){var s=function(e){return s=Object.getOwnPropertyNames||function(t){var i=[];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(i[i.length]=r);return i},s(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var i=s(e),r=0;rs===void 0||s<0?void 0:s,As=class{cksumValid=!1;needPax=!1;nullBlock=!1;block;path;mode;uid;gid;size;cksum;#e="Unsupported";linkpath;uname;gname;devmaj=0;devmin=0;atime;ctime;mtime;charset;comment;constructor(e,t=0,i,r){Buffer.isBuffer(e)?this.decode(e,t||0,i,r):e&&this.#i(e)}decode(e,t,i,r){if(t||(t=0),!e||!(e.length>=t+512))throw new Error("need 512 bytes for header");let n=Ce(e,t+156,1),o=Je.normalFsTypes.has(n),a=o?i:void 0,h=o?r:void 0;if(this.path=a?.path??Ce(e,t,100),this.mode=a?.mode??h?.mode??Se(e,t+100,8),this.uid=a?.uid??h?.uid??Se(e,t+108,8),this.gid=a?.gid??h?.gid??Se(e,t+116,8),this.size=ba(a?.size??h?.size??Se(e,t+124,12)),this.mtime=a?.mtime??h?.mtime??Ms(e,t+136,12),this.cksum=Se(e,t+148,12),h&&this.#i(h,!0),a&&this.#i(a),Je.isCode(n)&&(this.#e=n||"0"),this.#e==="0"&&this.path.slice(-1)==="/"&&(this.#e="5"),this.#e==="5"&&(this.size=0),this.linkpath=Ce(e,t+157,100),e.subarray(t+257,t+265).toString()==="ustar\x0000")if(this.uname=a?.uname??h?.uname??Ce(e,t+265,32),this.gname=a?.gname??h?.gname??Ce(e,t+297,32),this.devmaj=a?.devmaj??h?.devmaj??Se(e,t+329,8)??0,this.devmin=a?.devmin??h?.devmin??Se(e,t+337,8)??0,e[t+475]!==0){let c=Ce(e,t+345,155);this.path=c+"/"+this.path}else{let c=Ce(e,t+345,130);c&&(this.path=c+"/"+this.path),this.atime=i?.atime??r?.atime??Ms(e,t+476,12),this.ctime=i?.ctime??r?.ctime??Ms(e,t+488,12)}let l=256;for(let c=t;c!(r==null||i==="size"&&Number(r)<0||i==="path"&&t||i==="linkpath"&&t||i==="global"))))}encode(e,t=0){if(e||(e=this.block=Buffer.alloc(512)),this.#e==="Unsupported"&&(this.#e="0"),!(e.length>=t+512))throw new Error("need 512 bytes for header");let i=this.ctime||this.atime?130:155,r=Sa(this.path||"",i),n=r[0],o=r[1];this.needPax=!!r[2],this.needPax=Be(e,t,100,n)||this.needPax,this.needPax=ge(e,t+100,8,this.mode)||this.needPax,this.needPax=ge(e,t+108,8,this.uid)||this.needPax,this.needPax=ge(e,t+116,8,this.gid)||this.needPax,this.needPax=ge(e,t+124,12,this.size)||this.needPax,this.needPax=Ls(e,t+136,12,this.mtime)||this.needPax,e[t+156]=Number(this.#e.codePointAt(0)),this.needPax=Be(e,t+157,100,this.linkpath)||this.needPax,e.write("ustar\x0000",t+257,8),this.needPax=Be(e,t+265,32,this.uname)||this.needPax,this.needPax=Be(e,t+297,32,this.gname)||this.needPax,this.needPax=ge(e,t+329,8,this.devmaj)||this.needPax,this.needPax=ge(e,t+337,8,this.devmin)||this.needPax,this.needPax=Be(e,t+345,i,o)||this.needPax,e[t+475]!==0?this.needPax=Be(e,t+345,155,o)||this.needPax:(this.needPax=Be(e,t+345,130,o)||this.needPax,this.needPax=Ls(e,t+476,12,this.atime)||this.needPax,this.needPax=Ls(e,t+488,12,this.ctime)||this.needPax);let a=256;for(let h=t;h{let i=s,r="",n,o=Qe.posix.parse(s).root||".";if(Buffer.byteLength(i)<100)n=[i,r,!1];else{r=Qe.posix.dirname(i),i=Qe.posix.basename(i);do Buffer.byteLength(i)<=100&&Buffer.byteLength(r)<=e?n=[i,r,!1]:Buffer.byteLength(i)>100&&Buffer.byteLength(r)<=e?n=[i.slice(0,99),r,!0]:(i=Qe.posix.join(Qe.posix.basename(r),i),r=Qe.posix.dirname(r));while(r!==o&&n===void 0);n||(n=[s.slice(0,99),"",!0])}return n},Ce=(s,e,t)=>s.subarray(e,e+t).toString("utf8").replace(/\0.*/,""),Ms=(s,e,t)=>ga(Se(s,e,t)),ga=s=>s===void 0?void 0:new Date(s*1e3),Se=(s,e,t)=>Number(s[e])&128?$r.parse(s.subarray(e,e+t)):Oa(s,e,t),Ra=s=>isNaN(s)?void 0:s,Oa=(s,e,t)=>Ra(parseInt(s.subarray(e,e+t).toString("utf8").replace(/\0.*$/,"").trim(),8)),va={12:8589934591,8:2097151},ge=(s,e,t,i)=>i===void 0?!1:i>va[t]||i<0?($r.encode(i,s.subarray(e,e+t)),!0):(Ta(s,e,t,i),!1),Ta=(s,e,t,i)=>s.write(Da(i,t),e,t,"ascii"),Da=(s,e)=>Pa(Math.floor(s).toString(8),e),Pa=(s,e)=>(s.length===e-1?s:new Array(e-s.length-1).join("0")+s+" ")+"\0",Ls=(s,e,t,i)=>i===void 0?!1:ge(s,e,t,i.getTime()/1e3),Na=new Array(156).join("\0"),Be=(s,e,t,i)=>i===void 0?!1:(s.write(i+Na,e,t,"utf8"),i.length!==Buffer.byteLength(i)||i.length>t)});var si=d(ii=>{"use strict";Object.defineProperty(ii,"__esModule",{value:!0});ii.Pax=void 0;var Ma=require("node:path"),La=et(),Is=class s{atime;mtime;ctime;charset;comment;gid;uid;gname;uname;linkpath;dev;ino;nlink;path;size;mode;global;constructor(e,t=!1){this.atime=e.atime,this.charset=e.charset,this.comment=e.comment,this.ctime=e.ctime,this.dev=e.dev,this.gid=e.gid,this.global=t,this.gname=e.gname,this.ino=e.ino,this.linkpath=e.linkpath,this.mtime=e.mtime,this.nlink=e.nlink,this.path=e.path,this.size=e.size,this.uid=e.uid,this.uname=e.uname}encode(){let e=this.encodeBody();if(e==="")return Buffer.allocUnsafe(0);let t=Buffer.byteLength(e),i=512*Math.ceil(1+t/512),r=Buffer.allocUnsafe(i);for(let n=0;n<512;n++)r[n]=0;new La.Header({path:("PaxHeader/"+(0,Ma.basename)(this.path??"")).slice(0,99),mode:this.mode||420,uid:this.uid,gid:this.gid,size:t,mtime:this.mtime,type:this.global?"GlobalExtendedHeader":"ExtendedHeader",linkpath:"",uname:this.uname||"",gname:this.gname||"",devmaj:0,devmin:0,atime:this.atime,ctime:this.ctime}).encode(r),r.write(e,512,t,"utf8");for(let n=t+512;n=Math.pow(10,o)&&(o+=1),o+n+r}static parse(e,t,i=!1){return new s(Aa(Ia(e),t),i)}};ii.Pax=Is;var Aa=(s,e)=>e?Object.assign({},e,s):s,Ia=s=>s.replace(/\n$/,"").split(` -`).reduce(Fa,Object.create(null)),Fa=(s,e)=>{let t=parseInt(e,10);if(t!==Buffer.byteLength(e)+1)return s;e=e.slice((t+" ").length);let i=e.split("="),r=i.shift();if(!r)return s;let n=r.replace(/^SCHILY\.(dev|ino|nlink)/,"$1"),o=i.join("=").replace(/\0.*/,"");switch(n){case"path":case"linkpath":case"type":case"charset":case"comment":case"gname":case"uname":s[n]=o;break;case"ctime":case"atime":case"mtime":s[n]=new Date(Number(o)*1e3);break;case"size":let a=+o;a>=0&&(s[n]=a);break;case"gid":case"uid":case"dev":case"ino":case"nlink":case"mode":s[n]=+o;break}return s}});var tt=d(ri=>{"use strict";Object.defineProperty(ri,"__esModule",{value:!0});ri.normalizeWindowsPath=void 0;var Ca=process.env.TESTING_TAR_FAKE_PLATFORM||process.platform;ri.normalizeWindowsPath=Ca!=="win32"?s=>String(s):s=>String(s).replaceAll(/\\/g,"/")});var Cs=d(oi=>{"use strict";Object.defineProperty(oi,"__esModule",{value:!0});oi.ReadEntry=void 0;var Ba=We(),ni=tt(),Fs=class extends Ba.Minipass{extended;globalExtended;header;startBlockSize;blockRemain;remain;type;meta=!1;ignore=!1;path;mode;uid;gid;uname;gname;size=0;mtime;atime;ctime;linkpath;dev;ino;nlink;invalid=!1;absolute;unsupported=!1;constructor(e,t,i){switch(super({}),this.pause(),this.extended=t,this.globalExtended=i,this.header=e,this.remain=e.size??0,this.startBlockSize=512*Math.ceil(this.remain/512),this.blockRemain=this.startBlockSize,this.type=e.type,this.type){case"File":case"OldFile":case"Link":case"SymbolicLink":case"CharacterDevice":case"BlockDevice":case"Directory":case"FIFO":case"ContiguousFile":case"GNUDumpDir":break;case"NextFileHasLongLinkpath":case"NextFileHasLongPath":case"OldGnuLongPath":case"GlobalExtendedHeader":case"ExtendedHeader":case"OldExtendedHeader":this.meta=!0;break;default:this.ignore=!0}if(!e.path)throw new Error("no path provided for tar.ReadEntry");this.path=(0,ni.normalizeWindowsPath)(e.path),this.mode=e.mode,this.mode&&(this.mode=this.mode&4095),this.uid=e.uid,this.gid=e.gid,this.uname=e.uname,this.gname=e.gname,this.size=this.remain,this.mtime=e.mtime,this.atime=e.atime,this.ctime=e.ctime,this.linkpath=e.linkpath?(0,ni.normalizeWindowsPath)(e.linkpath):void 0,this.uname=e.uname,this.gname=e.gname,t&&this.#e(t),i&&this.#e(i,!0)}write(e){let t=e.length;if(t>this.blockRemain)throw new Error("writing more to entry than is appropriate");let i=this.remain,r=this.blockRemain;return this.remain=Math.max(0,i-t),this.blockRemain=Math.max(0,r-t),this.ignore?!0:i>=t?super.write(e):super.write(e.subarray(0,i))}#e(e,t=!1){e.path&&(e.path=(0,ni.normalizeWindowsPath)(e.path)),e.linkpath&&(e.linkpath=(0,ni.normalizeWindowsPath)(e.linkpath)),Object.assign(this,Object.fromEntries(Object.entries(e).filter(([i,r])=>!(r==null||i==="path"&&t))))}};oi.ReadEntry=Fs});var hi=d(ai=>{"use strict";Object.defineProperty(ai,"__esModule",{value:!0});ai.warnMethod=void 0;var za=(s,e,t,i={})=>{s.file&&(i.file=s.file),s.cwd&&(i.cwd=s.cwd),i.code=t instanceof Error&&t.code||e,i.tarCode=e,!s.strict&&i.recoverable!==!1?(t instanceof Error&&(i=Object.assign(t,i),t=t.message),s.emit("warn",e,t,i)):t instanceof Error?s.emit("error",Object.assign(t,i)):s.emit("error",Object.assign(new Error(`${e}: ${t}`),i))};ai.warnMethod=za});var _i=d(pi=>{"use strict";Object.defineProperty(pi,"__esModule",{value:!0});pi.Parser=void 0;var ka=require("events"),Bs=Ps(),Xr=et(),Qr=si(),xa=Cs(),ja=hi(),Ua=1024*1024,qs=Buffer.from([31,139]),Ws=Buffer.from([40,181,47,253]),qa=Math.max(qs.length,Ws.length),H=Symbol("state"),ze=Symbol("writeEntry"),me=Symbol("readEntry"),zs=Symbol("nextEntry"),Jr=Symbol("processEntry"),re=Symbol("extendedHeader"),gt=Symbol("globalExtendedHeader"),Re=Symbol("meta"),en=Symbol("emitMeta"),_=Symbol("buffer"),pe=Symbol("queue"),Oe=Symbol("ended"),ks=Symbol("emittedEnd"),ke=Symbol("emit"),S=Symbol("unzip"),li=Symbol("consumeChunk"),ci=Symbol("consumeChunkSub"),xs=Symbol("consumeBody"),tn=Symbol("consumeMeta"),sn=Symbol("consumeHeader"),Rt=Symbol("consuming"),js=Symbol("bufferConcat"),ui=Symbol("maybeEnd"),it=Symbol("writing"),ne=Symbol("aborted"),fi=Symbol("onDone"),xe=Symbol("sawValidEntry"),di=Symbol("sawNullBlock"),mi=Symbol("sawEOF"),rn=Symbol("closeStream"),Wa=1e3,Ot=Symbol("compressedBytesRead"),Us=Symbol("decompressedBytesRead"),nn=Symbol("checkDecompressionRatio"),Ha=()=>!0,Hs=class extends ka.EventEmitter{file;strict;maxMetaEntrySize;filter;brotli;zstd;maxDecompressionRatio;writable=!0;readable=!1;[pe]=[];[_];[me];[ze];[H]="begin";[Re]="";[re];[gt];[Oe]=!1;[S];[ne]=!1;[xe];[di]=!1;[mi]=!1;[it]=!1;[Rt]=!1;[ks]=!1;[Ot]=0;[Us]=0;constructor(e={}){super(),this.file=e.file||"",this.on(fi,()=>{(this[H]==="begin"||this[xe]===!1)&&this.warn("TAR_BAD_ARCHIVE","Unrecognized archive format")}),e.ondone?this.on(fi,e.ondone):this.on(fi,()=>{this.emit("prefinish"),this.emit("finish"),this.emit("end")}),this.strict=!!e.strict,this.maxDecompressionRatio=typeof e.maxDecompressionRatio=="number"?e.maxDecompressionRatio:Wa,this.maxMetaEntrySize=e.maxMetaEntrySize||Ua,this.filter=typeof e.filter=="function"?e.filter:Ha;let t=e.file&&(e.file.endsWith(".tar.br")||e.file.endsWith(".tbr"));this.brotli=!(e.gzip||e.zstd)&&e.brotli!==void 0?e.brotli:t?void 0:!1;let i=e.file&&(e.file.endsWith(".tar.zst")||e.file.endsWith(".tzst"));this.zstd=!(e.gzip||e.brotli)&&e.zstd!==void 0?e.zstd:i?!0:void 0,this.on("end",()=>this[rn]()),typeof e.onwarn=="function"&&this.on("warn",e.onwarn),typeof e.onReadEntry=="function"&&this.on("entry",e.onReadEntry)}warn(e,t,i={}){(0,ja.warnMethod)(this,e,t,i)}[sn](e,t){this[xe]===void 0&&(this[xe]=!1);let i;try{i=new Xr.Header(e,t,this[re],this[gt])}catch(r){return this.warn("TAR_ENTRY_INVALID",r)}if(i.nullBlock)this[di]?(this[mi]=!0,this[H]==="begin"&&(this[H]="header"),this[ke]("eof")):(this[di]=!0,this[ke]("nullBlock"));else if(this[di]=!1,!i.cksumValid)this.warn("TAR_ENTRY_INVALID","checksum failure",{header:i});else if(!i.path)this.warn("TAR_ENTRY_INVALID","path is required",{header:i});else{let r=i.type;if(/^(Symbolic)?Link$/.test(r)&&!i.linkpath)this.warn("TAR_ENTRY_INVALID","linkpath required",{header:i});else if(!/^(Symbolic)?Link$/.test(r)&&!/^(Global)?ExtendedHeader$/.test(r)&&i.linkpath)this.warn("TAR_ENTRY_INVALID","linkpath forbidden",{header:i});else{let n=this[ze]=new xa.ReadEntry(i,this[re],this[gt]);if(!this[xe])if(n.remain){let o=()=>{n.invalid||(this[xe]=!0)};n.on("end",o)}else this[xe]=!0;n.meta?n.size>this.maxMetaEntrySize?(n.ignore=!0,this[ke]("ignoredEntry",n),this[H]="ignore",n.resume()):n.size>0&&(this[Re]="",n.on("data",o=>this[Re]+=o),this[H]="meta"):(this[re]=void 0,n.ignore=n.ignore||!this.filter(n.path,n),n.ignore?(this[ke]("ignoredEntry",n),this[H]=n.remain?"ignore":"header",n.resume()):(n.remain?this[H]="body":(this[H]="header",n.end()),this[me]?this[pe].push(n):(this[pe].push(n),this[zs]())))}}}[rn](){queueMicrotask(()=>this.emit("close"))}[Jr](e){let t=!0;if(!e)this[me]=void 0,t=!1;else if(Array.isArray(e)){let[i,...r]=e;this.emit(i,...r)}else this[me]=e,this.emit("entry",e),e.emittedEnd||(e.on("end",()=>this[zs]()),t=!1);return t}[zs](){do;while(this[Jr](this[pe].shift()));if(this[pe].length===0){let e=this[me];!e||e.flowing||e.size===e.remain?this[it]||this.emit("drain"):e.once("drain",()=>this.emit("drain"))}}[xs](e,t){let i=this[ze];if(!i)throw new Error("attempt to consume body without entry??");let r=i.blockRemain??0,n=r>=e.length&&t===0?e:e.subarray(t,t+r);return i.write(n),i.blockRemain||(this[H]="header",this[ze]=void 0,i.end()),n.length}[tn](e,t){let i=this[ze],r=this[xs](e,t);return!this[ze]&&i&&this[en](i),r}[ke](e,t,i){this[pe].length===0&&!this[me]?this.emit(e,t,i):this[pe].push([e,t,i])}[en](e){switch(this[ke]("meta",this[Re]),e.type){case"ExtendedHeader":case"OldExtendedHeader":this[re]=Qr.Pax.parse(this[Re],this[re],!1);break;case"GlobalExtendedHeader":this[gt]=Qr.Pax.parse(this[Re],this[gt],!0);break;case"NextFileHasLongPath":case"OldGnuLongPath":{let t=this[re]??Object.create(null);this[re]=t,t.path=this[Re].replace(/\0.*/,"");break}case"NextFileHasLongLinkpath":{let t=this[re]||Object.create(null);this[re]=t,t.linkpath=this[Re].replace(/\0.*/,"");break}default:throw new Error("unknown meta: "+e.type)}}abort(e){this[ne]||(this[ne]=!0,this.emit("abort",e),this.warn("TAR_ABORT",e,{recoverable:!1}))}[nn](e){this[Us]+=e.length;let t=this[Us]/this[Ot];return t>this.maxDecompressionRatio?(this.abort(new Error(`max decompression ratio exceeded: ${t.toFixed(2)} > ${this.maxDecompressionRatio}`)),!1):!0}write(e,t,i){if(typeof t=="function"&&(i=t,t=void 0),typeof e=="string"&&(e=Buffer.from(e,typeof t=="string"?t:"utf8")),this[ne])return i?.(),!1;if((this[S]===void 0||this.brotli===void 0&&this[S]===!1)&&e){if(this[_]&&(e=Buffer.concat([this[_],e]),this[_]=void 0),e.length{this[nn](c)&&this[li](c)}),this[S].on("error",c=>{this[ne]||this.abort(c)}),this[S].on("end",()=>{this[Oe]=!0,this[li]()}),this[it]=!0,this[Ot]+=e.length;let l=!!this[S][h?"end":"write"](e);return this[it]=!1,i?.(),l}}this[it]=!0,this[S]?(this[Ot]+=e.length,this[S].write(e)):this[li](e),this[it]=!1;let n=this[pe].length>0?!1:this[me]?this[me].flowing:!0;return!n&&this[pe].length===0&&this[me]?.once("drain",()=>this.emit("drain")),i?.(),n}[js](e){e&&!this[ne]&&(this[_]=this[_]?Buffer.concat([this[_],e]):e)}[ui](){if(this[Oe]&&!this[ks]&&!this[ne]&&!this[Rt]){this[ks]=!0;let e=this[ze];if(e?.blockRemain){let t=this[_]?this[_].length:0;this.warn("TAR_BAD_ARCHIVE",`Truncated input (needed ${e.blockRemain} more bytes, only ${t} available)`,{entry:e}),this[_]&&e.write(this[_]),e.end()}this[ke](fi)}}[li](e){if(this[Rt]&&e)this[js](e);else if(!e&&!this[_])this[ui]();else if(e){if(this[Rt]=!0,this[_]){this[js](e);let t=this[_];this[_]=void 0,this[ci](t)}else this[ci](e);for(;this[_]&&this[_]?.length>=512&&!this[ne]&&!this[mi];){let t=this[_];this[_]=void 0,this[ci](t)}this[Rt]=!1}(!this[_]||this[Oe])&&this[ui]()}[ci](e){let t=0,i=e.length;for(;t+512<=i&&!this[ne]&&!this[mi];)switch(this[H]){case"begin":case"header":this[sn](e,t),t+=512;break;case"ignore":case"body":t+=this[xs](e,t);break;case"meta":t+=this[tn](e,t);break;default:throw new Error("invalid state: "+this[H])}t{"use strict";Object.defineProperty(wi,"__esModule",{value:!0});wi.stripTrailingSlashes=void 0;var Ga=s=>{let e=s.length-1,t=-1;for(;e>-1&&s.charAt(e)==="/";)t=e,e--;return t===-1?s:s.slice(0,t)};wi.stripTrailingSlashes=Ga});var rt=d(B=>{"use strict";var Za=B&&B.__createBinding||(Object.create?(function(s,e,t,i){i===void 0&&(i=t);var r=Object.getOwnPropertyDescriptor(e,t);(!r||("get"in r?!e.__esModule:r.writable||r.configurable))&&(r={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(s,i,r)}):(function(s,e,t,i){i===void 0&&(i=t),s[i]=e[t]})),Ya=B&&B.__setModuleDefault||(Object.create?(function(s,e){Object.defineProperty(s,"default",{enumerable:!0,value:e})}):function(s,e){s.default=e}),Ka=B&&B.__importStar||(function(){var s=function(e){return s=Object.getOwnPropertyNames||function(t){var i=[];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(i[i.length]=r);return i},s(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var i=s(e),r=0;r{let e=s.onReadEntry;s.onReadEntry=e?t=>{e(t),t.resume()}:t=>t.resume()},Ja=(s,e)=>{let t=new Map(e.map(n=>[(0,Gs.stripTrailingSlashes)(n),!0])),i=s.filter,r=(n,o="")=>{let a=o||(0,on.parse)(n).root||".",h;if(n===a)h=!1;else{let l=t.get(n);h=l!==void 0?l:r((0,on.dirname)(n),a)}return t.set(n,h),h};s.filter=i?(n,o)=>i(n,o)&&r((0,Gs.stripTrailingSlashes)(n)):n=>r((0,Gs.stripTrailingSlashes)(n))};B.filesFilter=Ja;var eh=s=>{let e=new Ei.Parser(s),t=s.file,i;try{i=st.default.openSync(t,"r");let r=st.default.fstatSync(i),n=s.maxReadSize||16*1024*1024;if(r.size{let t=new Ei.Parser(s),i=s.maxReadSize||16*1024*1024,r=s.file;return new Promise((o,a)=>{t.on("error",a),t.on("end",o),st.default.stat(r,(h,l)=>{if(h)a(h);else{let c=new $a.ReadStream(r,{readSize:i,size:l.size});c.on("error",a),c.pipe(t)}})})};B.list=(0,Xa.makeCommand)(eh,th,s=>new Ei.Parser(s),s=>new Ei.Parser(s),(s,e)=>{e?.length&&(0,B.filesFilter)(s,e),s.noResume||Qa(s)})});var an=d(bi=>{"use strict";Object.defineProperty(bi,"__esModule",{value:!0});bi.modeFix=void 0;var ih=(s,e,t)=>(s&=4095,t&&(s=(s|384)&-19),e&&(s&256&&(s|=64),s&32&&(s|=8),s&4&&(s|=1)),s);bi.modeFix=ih});var Zs=d(Si=>{"use strict";Object.defineProperty(Si,"__esModule",{value:!0});Si.stripAbsolutePath=void 0;var sh=require("node:path"),{isAbsolute:rh,parse:hn}=sh.win32,nh=s=>{let e="",t=hn(s);for(;rh(s)||t.root;){let i=s.charAt(0)==="/"&&s.slice(0,4)!=="//?/"?"/":t.root;s=s.slice(i.length),e+=i,t=hn(s)}return[e,s]};Si.stripAbsolutePath=nh});var Ks=d(nt=>{"use strict";Object.defineProperty(nt,"__esModule",{value:!0});nt.decode=nt.encode=void 0;var gi=["|","<",">","?",":"],Ys=gi.map(s=>String.fromCodePoint(61440+Number(s.codePointAt(0)))),oh=new Map(gi.map((s,e)=>[s,Ys[e]])),ah=new Map(Ys.map((s,e)=>[s,gi[e]])),hh=s=>gi.reduce((e,t)=>e.split(t).join(oh.get(t)),s);nt.encode=hh;var lh=s=>Ys.reduce((e,t)=>e.split(t).join(ah.get(t)),s);nt.decode=lh});var nr=d(M=>{"use strict";var ch=M&&M.__createBinding||(Object.create?(function(s,e,t,i){i===void 0&&(i=t);var r=Object.getOwnPropertyDescriptor(e,t);(!r||("get"in r?!e.__esModule:r.writable||r.configurable))&&(r={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(s,i,r)}):(function(s,e,t,i){i===void 0&&(i=t),s[i]=e[t]})),uh=M&&M.__setModuleDefault||(Object.create?(function(s,e){Object.defineProperty(s,"default",{enumerable:!0,value:e})}):function(s,e){s.default=e}),fh=M&&M.__importStar||(function(){var s=function(e){return s=Object.getOwnPropertyNames||function(t){var i=[];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(i[i.length]=r);return i},s(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var i=s(e),r=0;re?(s=(0,oe.normalizeWindowsPath)(s).replace(/^\.(\/|$)/,""),(0,dh.stripTrailingSlashes)(e)+"/"+s):(0,oe.normalizeWindowsPath)(s),ph=16*1024*1024,cn=Symbol("process"),un=Symbol("file"),fn=Symbol("directory"),$s=Symbol("symlink"),dn=Symbol("hardlink"),vt=Symbol("header"),Ri=Symbol("read"),Xs=Symbol("lstat"),Oi=Symbol("onlstat"),Qs=Symbol("onread"),Js=Symbol("onreadlink"),er=Symbol("openfile"),tr=Symbol("onopenfile"),ve=Symbol("close"),vi=Symbol("mode"),ir=Symbol("awaitDrain"),Vs=Symbol("ondrain"),he=Symbol("prefix"),Ti=class extends pn.Minipass{path;portable;myuid=process.getuid&&process.getuid()||0;myuser=process.env.USER||"";maxReadSize;linkCache;statCache;preservePaths;cwd;strict;mtime;noPax;noMtime;prefix;fd;blockLen=0;blockRemain=0;buf;pos=0;remain=0;length=0;offset=0;win32;absolute;header;type;linkpath;stat;onWriteEntry;#e=!1;constructor(e,t={}){let i=(0,yn.dealias)(t);super(),this.path=(0,oe.normalizeWindowsPath)(e),this.portable=!!i.portable,this.maxReadSize=i.maxReadSize||ph,this.linkCache=i.linkCache||new Map,this.statCache=i.statCache||new Map,this.preservePaths=!!i.preservePaths,this.cwd=(0,oe.normalizeWindowsPath)(i.cwd||process.cwd()),this.strict=!!i.strict,this.noPax=!!i.noPax,this.noMtime=!!i.noMtime,this.mtime=i.mtime,this.prefix=i.prefix?(0,oe.normalizeWindowsPath)(i.prefix):void 0,this.onWriteEntry=i.onWriteEntry,typeof i.onwarn=="function"&&this.on("warn",i.onwarn);let r=!1;if(!this.preservePaths){let[o,a]=(0,bn.stripAbsolutePath)(this.path);o&&typeof a=="string"&&(this.path=a,r=o)}this.win32=!!i.win32||process.platform==="win32",this.win32&&(this.path=mh.decode(this.path.replaceAll(/\\/g,"/")),e=e.replaceAll(/\\/g,"/")),this.absolute=(0,oe.normalizeWindowsPath)(i.absolute||ln.default.resolve(this.cwd,e)),this.path===""&&(this.path="./"),r&&this.warn("TAR_ENTRY_INFO",`stripping ${r} from absolute path`,{entry:this,path:r+this.path});let n=this.statCache.get(this.absolute);n?this[Oi](n):this[Xs]()}warn(e,t,i={}){return(0,Sn.warnMethod)(this,e,t,i)}emit(e,...t){return e==="error"&&(this.#e=!0),super.emit(e,...t)}[Xs](){ae.default.lstat(this.absolute,(e,t)=>{if(e)return this.emit("error",e);this[Oi](t)})}[Oi](e){this.statCache.set(this.absolute,e),this.stat=e,e.isFile()||(e.size=0),this.type=_h(e),this.emit("stat",e),this[cn]()}[cn](){switch(this.type){case"File":return this[un]();case"Directory":return this[fn]();case"SymbolicLink":return this[$s]();default:return this.end()}}[vi](e){return(0,wn.modeFix)(e,this.type==="Directory",this.portable)}[he](e){return gn(e,this.prefix)}[vt](){if(!this.stat)throw new Error("cannot write header before stat");this.type==="Directory"&&this.portable&&(this.noMtime=!0),this.onWriteEntry?.(this),this.header=new _n.Header({path:this[he](this.path),linkpath:this.type==="Link"&&this.linkpath!==void 0?this[he](this.linkpath):this.linkpath,mode:this[vi](this.stat.mode),uid:this.portable?void 0:this.stat.uid,gid:this.portable?void 0:this.stat.gid,size:this.stat.size,mtime:this.noMtime?void 0:this.mtime||this.stat.mtime,type:this.type==="Unsupported"?void 0:this.type,uname:this.portable?void 0:this.stat.uid===this.myuid?this.myuser:"",atime:this.portable?void 0:this.stat.atime,ctime:this.portable?void 0:this.stat.ctime}),this.header.encode()&&!this.noPax&&super.write(new En.Pax({atime:this.portable?void 0:this.header.atime,ctime:this.portable?void 0:this.header.ctime,gid:this.portable?void 0:this.header.gid,mtime:this.noMtime?void 0:this.mtime||this.header.mtime,path:this[he](this.path),linkpath:this.type==="Link"&&this.linkpath!==void 0?this[he](this.linkpath):this.linkpath,size:this.header.size,uid:this.portable?void 0:this.header.uid,uname:this.portable?void 0:this.header.uname,dev:this.portable?void 0:this.stat.dev,ino:this.portable?void 0:this.stat.ino,nlink:this.portable?void 0:this.stat.nlink}).encode());let e=this.header?.block;if(!e)throw new Error("failed to encode header");super.write(e)}[fn](){if(!this.stat)throw new Error("cannot create directory entry without stat");this.path.slice(-1)!=="/"&&(this.path+="/"),this.stat.size=0,this[vt](),this.end()}[$s](){ae.default.readlink(this.absolute,(e,t)=>{if(e)return this.emit("error",e);this[Js](t)})}[Js](e){this.linkpath=(0,oe.normalizeWindowsPath)(e),this[vt](),this.end()}[dn](e){if(!this.stat)throw new Error("cannot create link entry without stat");this.type="Link",this.linkpath=(0,oe.normalizeWindowsPath)(ln.default.relative(this.cwd,e)),this.stat.size=0,this[vt](),this.end()}[un](){if(!this.stat)throw new Error("cannot create file entry without stat");if(this.stat.nlink>1){let e=`${this.stat.dev}:${this.stat.ino}`,t=this.linkCache.get(e);if(t?.indexOf(this.cwd)===0)return this[dn](t);this.linkCache.set(e,this.absolute)}if(this[vt](),this.stat.size===0)return this.end();this[er]()}[er](){ae.default.open(this.absolute,"r",(e,t)=>{if(e)return this.emit("error",e);this[tr](t)})}[tr](e){if(this.fd=e,this.#e)return this[ve]();if(!this.stat)throw new Error("should stat before calling onopenfile");this.blockLen=512*Math.ceil(this.stat.size/512),this.blockRemain=this.blockLen;let t=Math.min(this.blockLen,this.maxReadSize);this.buf=Buffer.allocUnsafe(t),this.offset=0,this.pos=0,this.remain=this.stat.size,this.length=this.buf.length,this[Ri]()}[Ri](){let{fd:e,buf:t,offset:i,length:r,pos:n}=this;if(e===void 0||t===void 0)throw new Error("cannot read file without first opening");ae.default.read(e,t,i,r,n,(o,a)=>{if(o)return this[ve](()=>this.emit("error",o));this[Qs](a)})}[ve](e=()=>{}){this.fd!==void 0&&ae.default.close(this.fd,e)}[Qs](e){if(e<=0&&this.remain>0){let r=Object.assign(new Error("encountered unexpected EOF"),{path:this.absolute,syscall:"read",code:"EOF"});return this[ve](()=>this.emit("error",r))}if(e>this.remain){let r=Object.assign(new Error("did not encounter expected EOF"),{path:this.absolute,syscall:"read",code:"EOF"});return this[ve](()=>this.emit("error",r))}if(!this.buf)throw new Error("should have created buffer prior to reading");if(e===this.remain)for(let r=e;rthis[Vs]())}[ir](e){this.once("drain",e)}write(e,t,i){if(typeof t=="function"&&(i=t,t=void 0),typeof e=="string"&&(e=Buffer.from(e,typeof t=="string"?t:"utf8")),this.blockRemaine?this.emit("error",e):this.end());if(!this.buf)throw new Error("buffer lost somehow in ONDRAIN");this.offset>=this.length&&(this.buf=Buffer.allocUnsafe(Math.min(this.blockRemain,this.buf.length)),this.offset=0),this.length=this.buf.length-this.offset,this[Ri]()}};M.WriteEntry=Ti;var sr=class extends Ti{sync=!0;[Xs](){this[Oi](ae.default.lstatSync(this.absolute))}[$s](){this[Js](ae.default.readlinkSync(this.absolute))}[er](){this[tr](ae.default.openSync(this.absolute,"r"))}[Ri](){let e=!0;try{let{fd:t,buf:i,offset:r,length:n,pos:o}=this;if(t===void 0||i===void 0)throw new Error("fd and buf must be set in READ method");let a=ae.default.readSync(t,i,r,n,o);this[Qs](a),e=!1}finally{if(e)try{this[ve](()=>{})}catch{}}}[ir](e){e()}[ve](e=()=>{}){this.fd!==void 0&&ae.default.closeSync(this.fd),e()}};M.WriteEntrySync=sr;var rr=class extends pn.Minipass{blockLen=0;blockRemain=0;buf=0;pos=0;remain=0;length=0;preservePaths;portable;strict;noPax;noMtime;readEntry;type;prefix;path;mode;uid;gid;uname;gname;header;mtime;atime;ctime;linkpath;size;onWriteEntry;warn(e,t,i={}){return(0,Sn.warnMethod)(this,e,t,i)}constructor(e,t={}){let i=(0,yn.dealias)(t);super(),this.preservePaths=!!i.preservePaths,this.portable=!!i.portable,this.strict=!!i.strict,this.noPax=!!i.noPax,this.noMtime=!!i.noMtime,this.onWriteEntry=i.onWriteEntry,this.readEntry=e;let{type:r}=e;if(r==="Unsupported")throw new Error("writing entry that should be ignored");this.type=r,this.type==="Directory"&&this.portable&&(this.noMtime=!0),this.prefix=i.prefix,this.path=(0,oe.normalizeWindowsPath)(e.path),this.mode=e.mode!==void 0?this[vi](e.mode):void 0,this.uid=this.portable?void 0:e.uid,this.gid=this.portable?void 0:e.gid,this.uname=this.portable?void 0:e.uname,this.gname=this.portable?void 0:e.gname,this.size=e.size,this.mtime=this.noMtime?void 0:i.mtime||e.mtime,this.atime=this.portable?void 0:e.atime,this.ctime=this.portable?void 0:e.ctime,this.linkpath=e.linkpath!==void 0?(0,oe.normalizeWindowsPath)(e.linkpath):void 0,typeof i.onwarn=="function"&&this.on("warn",i.onwarn);let n=!1;if(!this.preservePaths){let[a,h]=(0,bn.stripAbsolutePath)(this.path);a&&typeof h=="string"&&(this.path=h,n=a)}this.remain=e.size,this.blockRemain=e.startBlockSize,this.onWriteEntry?.(this),this.header=new _n.Header({path:this[he](this.path),linkpath:this.type==="Link"&&this.linkpath!==void 0?this[he](this.linkpath):this.linkpath,mode:this.mode,uid:this.portable?void 0:this.uid,gid:this.portable?void 0:this.gid,size:this.size,mtime:this.noMtime?void 0:this.mtime,type:this.type,uname:this.portable?void 0:this.uname,atime:this.portable?void 0:this.atime,ctime:this.portable?void 0:this.ctime}),n&&this.warn("TAR_ENTRY_INFO",`stripping ${n} from absolute path`,{entry:this,path:n+this.path}),this.header.encode()&&!this.noPax&&super.write(new En.Pax({atime:this.portable?void 0:this.atime,ctime:this.portable?void 0:this.ctime,gid:this.portable?void 0:this.gid,mtime:this.noMtime?void 0:this.mtime,path:this[he](this.path),linkpath:this.type==="Link"&&this.linkpath!==void 0?this[he](this.linkpath):this.linkpath,size:this.size,uid:this.portable?void 0:this.uid,uname:this.portable?void 0:this.uname,dev:this.portable?void 0:this.readEntry.dev,ino:this.portable?void 0:this.readEntry.ino,nlink:this.portable?void 0:this.readEntry.nlink}).encode());let o=this.header?.block;if(!o)throw new Error("failed to encode header");super.write(o),e.pipe(this)}[he](e){return gn(e,this.prefix)}[vi](e){return(0,wn.modeFix)(e,this.type==="Directory",this.portable)}write(e,t,i){typeof t=="function"&&(i=t,t=void 0),typeof e=="string"&&(e=Buffer.from(e,typeof t=="string"?t:"utf8"));let r=e.length;if(r>this.blockRemain)throw new Error("writing more to entry than is appropriate");return this.blockRemain-=r,super.write(e,i)}end(e,t,i){return this.blockRemain&&super.write(Buffer.alloc(this.blockRemain)),typeof e=="function"&&(i=e,t=void 0,e=void 0),typeof t=="function"&&(i=t,t=void 0),typeof e=="string"&&(e=Buffer.from(e,t??"utf8")),i&&this.once("finish",i),e?super.end(e,i):super.end(i),this}};M.WriteEntryTar=rr;var _h=s=>s.isFile()?"File":s.isDirectory()?"Directory":s.isSymbolicLink()?"SymbolicLink":"Unsupported"});var Rn=d(at=>{"use strict";Object.defineProperty(at,"__esModule",{value:!0});at.Node=at.Yallist=void 0;var or=class s{tail;head;length=0;static create(e=[]){return new s(e)}constructor(e=[]){for(let t of e)this.push(t)}*[Symbol.iterator](){for(let e=this.head;e;e=e.next)yield e.value}removeNode(e){if(e.list!==this)throw new Error("removing node which does not belong to this list");let t=e.next,i=e.prev;return t&&(t.prev=i),i&&(i.next=t),e===this.head&&(this.head=t),e===this.tail&&(this.tail=i),this.length--,e.next=void 0,e.prev=void 0,e.list=void 0,t}unshiftNode(e){if(e===this.head)return;e.list&&e.list.removeNode(e);let t=this.head;e.list=this,e.next=t,t&&(t.prev=e),this.head=e,this.tail||(this.tail=e),this.length++}pushNode(e){if(e===this.tail)return;e.list&&e.list.removeNode(e);let t=this.tail;e.list=this,e.prev=t,t&&(t.next=e),this.tail=e,this.head||(this.head=e),this.length++}push(...e){for(let t=0,i=e.length;t1)i=t;else if(this.head)r=this.head.next,i=this.head.value;else throw new TypeError("Reduce of empty list with no initial value");for(var n=0;r;n++)i=e(i,r.value,n),r=r.next;return i}reduceReverse(e,t){let i,r=this.tail;if(arguments.length>1)i=t;else if(this.tail)r=this.tail.prev,i=this.tail.value;else throw new TypeError("Reduce of empty list with no initial value");for(let n=this.length-1;r;n--)i=e(i,r.value,n),r=r.prev;return i}toArray(){let e=new Array(this.length);for(let t=0,i=this.head;i;t++)e[t]=i.value,i=i.next;return e}toArrayReverse(){let e=new Array(this.length);for(let t=0,i=this.tail;i;t++)e[t]=i.value,i=i.prev;return e}slice(e=0,t=this.length){t<0&&(t+=this.length),e<0&&(e+=this.length);let i=new s;if(tthis.length&&(t=this.length);let r=this.head,n=0;for(n=0;r&&nthis.length&&(t=this.length);let r=this.length,n=this.tail;for(;n&&r>t;r--)n=n.prev;for(;n&&r>e;r--,n=n.prev)i.push(n.value);return i}splice(e,t=0,...i){e>this.length&&(e=this.length-1),e<0&&(e=this.length+e);let r=this.head;for(let o=0;r&&o{"use strict";var bh=L&&L.__createBinding||(Object.create?(function(s,e,t,i){i===void 0&&(i=t);var r=Object.getOwnPropertyDescriptor(e,t);(!r||("get"in r?!e.__esModule:r.writable||r.configurable))&&(r={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(s,i,r)}):(function(s,e,t,i){i===void 0&&(i=t),s[i]=e[t]})),Sh=L&&L.__setModuleDefault||(Object.create?(function(s,e){Object.defineProperty(s,"default",{enumerable:!0,value:e})}):function(s,e){s.default=e}),gh=L&&L.__importStar||(function(){var s=function(e){return s=Object.getOwnPropertyNames||function(t){var i=[];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(i[i.length]=r);return i},s(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var i=s(e),r=0;r1)throw new TypeError("gzip, brotli, zstd are mutually exclusive");if(e.gzip&&(typeof e.gzip!="object"&&(e.gzip={}),this.portable&&(e.gzip.portable=!0),this.zip=new ar.Gzip(e.gzip)),e.brotli&&(typeof e.brotli!="object"&&(e.brotli={}),this.zip=new ar.BrotliCompress(e.brotli)),e.zstd&&(typeof e.zstd!="object"&&(e.zstd={}),this.zip=new ar.ZstdCompress(e.zstd)),!this.zip)throw new Error("impossible");let t=this.zip;t.on("data",i=>super.write(i)),t.on("end",()=>super.end()),t.on("drain",()=>this[cr]()),this.on("resume",()=>t.resume())}else this.on("drain",this[cr]);this.noDirRecurse=!!e.noDirRecurse,this.follow=!!e.follow,this.noMtime=!!e.noMtime,e.mtime&&(this.mtime=e.mtime),this.filter=typeof e.filter=="function"?e.filter:()=>!0,this[X]=new Oh.Yallist,this[Q]=0,this.jobs=Number(e.jobs)||4,this[Pt]=!1,this[Tt]=!1}[Nn](e){return super.write(e)}add(e){return this.write(e),this}end(e,t,i){return typeof e=="function"&&(i=e,e=void 0),typeof t=="function"&&(i=t,t=void 0),e&&this.add(e),this[Tt]=!0,this[je](),i&&i(),this}write(e){if(this[Tt])throw new Error("write after end");return typeof e=="string"?this[Ni](e):this[vn](e),this.flowing}[vn](e){let t=(0,ur.normalizeWindowsPath)(Dn.default.resolve(this.cwd,e.path));if(!this.filter(e.path,e))e.resume();else{let i=new Nt(e.path,t);i.entry=new fr.WriteEntryTar(e,this[lr](i)),i.entry.on("end",()=>this[hr](i)),this[Q]+=1,this[X].push(i)}this[je]()}[Ni](e){let t=(0,ur.normalizeWindowsPath)(Dn.default.resolve(this.cwd,e));this[X].push(new Nt(e,t)),this[je]()}[dr](e){e.pending=!0,this[Q]+=1;let t=this.follow?"stat":"lstat";Ii.default[t](e.absolute,(i,r)=>{e.pending=!1,this[Q]-=1,i?this.emit("error",i):this[Pi](e,r)})}[Pi](e,t){if(this.statCache.set(e.absolute,t),e.stat=t,!this.filter(e.path,t))e.ignore=!0;else if(t.isFile()&&t.nlink>1&&!this.linkCache.get(`${t.dev}:${t.ino}`)&&!this.sync)if(e===this[Te])this[Di](e);else{let i=`${t.dev}:${t.ino}`,r=this[Dt].get(i);r?r.push(e):this[Dt].set(i,[e]),e.pendingLink=!0,e.pending=!0}this[je]()}[mr](e){e.pending=!0,this[Q]+=1,Ii.default.readdir(e.absolute,(t,i)=>{if(e.pending=!1,this[Q]-=1,t)return this.emit("error",t);this[Mi](e,i)})}[Mi](e,t){this.readdirCache.set(e.absolute,t),e.readdir=t,this[je]()}[je](){if(!this[Pt]){this[Pt]=!0;for(let e=this[X].head;e&&this[Q]1){let i=`${t.dev}:${t.ino}`,r=this[Dt].get(i);if(r){this[Dt].delete(i);for(let n of r)n.pending=!1,this[Di](n)}}this[je]()}[Di](e){if(e.pending&&e.pendingLink&&e===this[Te]&&(e.pending=!1,e.pendingLink=!1),!e.pending){if(e.entry){e===this[Te]&&!e.piped&&this[Li](e);return}if(!e.stat){let t=this.statCache.get(e.absolute);t?this[Pi](e,t):this[dr](e)}if(e.stat&&!e.ignore){if(!this.noDirRecurse&&e.stat.isDirectory()&&!e.readdir){let t=this.readdirCache.get(e.absolute);if(t?this[Mi](e,t):this[mr](e),!e.readdir)return}if(e.entry=this[Tn](e),!e.entry){e.ignore=!0;return}e===this[Te]&&!e.piped&&this[Li](e)}}}[lr](e){return{onwarn:(t,i,r)=>this.warn(t,i,r),noPax:this.noPax,cwd:this.cwd,absolute:e.absolute,preservePaths:this.preservePaths,maxReadSize:this.maxReadSize,strict:this.strict,portable:this.portable,linkCache:this.linkCache,statCache:this.statCache,noMtime:this.noMtime,mtime:this.mtime,prefix:this.prefix,onWriteEntry:this.onWriteEntry}}[Tn](e){this[Q]+=1;try{return new this[Ai](e.path,this[lr](e)).on("end",()=>this[hr](e)).on("error",i=>this.emit("error",i))}catch(t){this.emit("error",t)}}[cr](){this[Te]&&this[Te].entry&&this[Te].entry.resume()}[Li](e){e.piped=!0,e.readdir&&e.readdir.forEach(r=>{let n=e.path,o=n==="./"?"":n.replace(/\/*$/,"/");this[Ni](o+r)});let t=e.entry,i=this.zip;if(!t)throw new Error("cannot pipe without source");i?t.on("data",r=>{i.write(r)||t.pause()}):t.on("data",r=>{super.write(r)||t.pause()})}pause(){return this.zip&&this.zip.pause(),super.pause()}warn(e,t,i={}){(0,vh.warnMethod)(this,e,t,i)}};L.Pack=Fi;var pr=class extends Fi{sync=!0;constructor(e){super(e),this[Ai]=fr.WriteEntrySync}pause(){}resume(){}[dr](e){let t=this.follow?"statSync":"lstatSync";this[Pi](e,Ii.default[t](e.absolute))}[mr](e){this[Mi](e,Ii.default.readdirSync(e.absolute))}[Li](e){let t=e.entry,i=this.zip;if(e.readdir&&e.readdir.forEach(r=>{let n=e.path,o=n==="./"?"":n.replace(/\/*$/,"/");this[Ni](o+r)}),!t)throw new Error("Cannot pipe without source");i?t.on("data",r=>{i.write(r)}):t.on("data",r=>{super[Nn](r)})}};L.PackSync=pr});var _r=d(ht=>{"use strict";var Th=ht&&ht.__importDefault||function(s){return s&&s.__esModule?s:{default:s}};Object.defineProperty(ht,"__esModule",{value:!0});ht.create=void 0;var Mn=Ke(),Ln=Th(require("node:path")),An=rt(),Dh=Ve(),Bi=Ci(),Ph=(s,e)=>{let t=new Bi.PackSync(s),i=new Mn.WriteStreamSync(s.file,{mode:s.mode||438});t.pipe(i),In(t,e)},Nh=(s,e)=>{let t=new Bi.Pack(s),i=new Mn.WriteStream(s.file,{mode:s.mode||438});t.pipe(i);let r=new Promise((n,o)=>{i.on("error",o),i.on("close",n),t.on("error",o)});return Fn(t,e).catch(n=>t.emit("error",n)),r},In=(s,e)=>{e.forEach(t=>{t.charAt(0)==="@"?(0,An.list)({file:Ln.default.resolve(s.cwd,t.slice(1)),sync:!0,noResume:!0,onReadEntry:i=>s.add(i)}):s.add(t)}),s.end()},Fn=async(s,e)=>{for(let t of e)t.charAt(0)==="@"?await(0,An.list)({file:Ln.default.resolve(String(s.cwd),t.slice(1)),noResume:!0,onReadEntry:i=>{s.add(i)}}):s.add(t);s.end()},Mh=(s,e)=>{let t=new Bi.PackSync(s);return In(t,e),t},Lh=(s,e)=>{let t=new Bi.Pack(s);return Fn(t,e).catch(i=>t.emit("error",i)),t};ht.create=(0,Dh.makeCommand)(Ph,Nh,Mh,Lh,(s,e)=>{if(!e?.length)throw new TypeError("no paths specified to add to archive")})});var Wn=d(lt=>{"use strict";var Ah=lt&<.__importDefault||function(s){return s&&s.__esModule?s:{default:s}};Object.defineProperty(lt,"__esModule",{value:!0});lt.getWriteFlag=void 0;var zn=Ah(require("fs")),Ih=process.env.__FAKE_PLATFORM__||process.platform,kn=Ih==="win32",{O_CREAT:xn,O_NOFOLLOW:Cn,O_TRUNC:jn,O_WRONLY:Un}=zn.default.constants,qn=Number(process.env.__FAKE_FS_O_FILENAME__)||zn.default.constants.UV_FS_O_FILEMAP||0,Fh=kn&&!!qn,Ch=512*1024,Bh=qn|jn|xn|Un,Bn=!kn&&typeof Cn=="number"?Cn|jn|xn|Un:null;lt.getWriteFlag=Bn!==null?()=>Bn:Fh?s=>s"w"});var Gn=d(le=>{"use strict";var Hn=le&&le.__importDefault||function(s){return s&&s.__esModule?s:{default:s}};Object.defineProperty(le,"__esModule",{value:!0});le.chownrSync=le.chownr=void 0;var ki=Hn(require("node:fs")),Mt=Hn(require("node:path")),wr=(s,e,t)=>{try{return ki.default.lchownSync(s,e,t)}catch(i){if(i?.code!=="ENOENT")throw i}},zi=(s,e,t,i)=>{ki.default.lchown(s,e,t,r=>{i(r&&r?.code!=="ENOENT"?r:null)})},zh=(s,e,t,i,r)=>{if(e.isDirectory())(0,le.chownr)(Mt.default.resolve(s,e.name),t,i,n=>{if(n)return r(n);let o=Mt.default.resolve(s,e.name);zi(o,t,i,r)});else{let n=Mt.default.resolve(s,e.name);zi(n,t,i,r)}},kh=(s,e,t,i)=>{ki.default.readdir(s,{withFileTypes:!0},(r,n)=>{if(r){if(r.code==="ENOENT")return i();if(r.code!=="ENOTDIR"&&r.code!=="ENOTSUP")return i(r)}if(r||!n.length)return zi(s,e,t,i);let o=n.length,a=null,h=l=>{if(!a){if(l)return i(a=l);if(--o===0)return zi(s,e,t,i)}};for(let l of n)zh(s,l,e,t,h)})};le.chownr=kh;var xh=(s,e,t,i)=>{e.isDirectory()&&(0,le.chownrSync)(Mt.default.resolve(s,e.name),t,i),wr(Mt.default.resolve(s,e.name),t,i)},jh=(s,e,t)=>{let i;try{i=ki.default.readdirSync(s,{withFileTypes:!0})}catch(r){let n=r;if(n?.code==="ENOENT")return;if(n?.code==="ENOTDIR"||n?.code==="ENOTSUP")return wr(s,e,t);throw n}for(let r of i)xh(s,r,e,t);return wr(s,e,t)};le.chownrSync=jh});var Zn=d(xi=>{"use strict";Object.defineProperty(xi,"__esModule",{value:!0});xi.CwdError=void 0;var yr=class extends Error{path;code;syscall="chdir";constructor(e,t){super(`${t}: Cannot cd into '${e}'`),this.path=e,this.code=t}get name(){return"CwdError"}};xi.CwdError=yr});var br=d(ji=>{"use strict";Object.defineProperty(ji,"__esModule",{value:!0});ji.SymlinkError=void 0;var Er=class extends Error{path;symlink;syscall="symlink";code="TAR_SYMLINK_ERROR";constructor(e,t){super("TAR_SYMLINK_ERROR: Cannot extract through symbolic link"),this.symlink=e,this.path=t}get name(){return"SymlinkError"}};ji.SymlinkError=Er});var Xn=d(De=>{"use strict";var gr=De&&De.__importDefault||function(s){return s&&s.__esModule?s:{default:s}};Object.defineProperty(De,"__esModule",{value:!0});De.mkdirSync=De.mkdir=void 0;var Yn=Gn(),j=gr(require("node:fs")),Uh=gr(require("node:fs/promises")),Ui=gr(require("node:path")),Kn=Zn(),_e=tt(),Vn=br(),qh=(s,e)=>{j.default.stat(s,(t,i)=>{(t||!i.isDirectory())&&(t=new Kn.CwdError(s,t?.code||"ENOTDIR")),e(t)})},Wh=(s,e,t)=>{s=(0,_e.normalizeWindowsPath)(s);let i=e.umask??18,r=e.mode|448,n=(r&i)!==0,o=e.uid,a=e.gid,h=typeof o=="number"&&typeof a=="number"&&(o!==e.processUid||a!==e.processGid),l=e.preserve,c=e.unlink,u=(0,_e.normalizeWindowsPath)(e.cwd),E=(w,P)=>{w?t(w):P&&h?(0,Yn.chownr)(P,o,a,xt=>E(xt)):n?j.default.chmod(s,r,t):t()};if(s===u)return qh(s,E);if(l)return Uh.default.mkdir(s,{mode:r,recursive:!0}).then(w=>E(null,w??void 0),E);let A=(0,_e.normalizeWindowsPath)(Ui.default.relative(u,s)).split("/");Sr(u,A,r,c,u,void 0,E)};De.mkdir=Wh;var Sr=(s,e,t,i,r,n,o)=>{if(e.length===0)return o(null,n);let a=e.shift(),h=(0,_e.normalizeWindowsPath)(Ui.default.resolve(s+"/"+a));j.default.mkdir(h,t,$n(h,e,t,i,r,n,o))},$n=(s,e,t,i,r,n,o)=>a=>{a?j.default.lstat(s,(h,l)=>{if(h)h.path=h.path&&(0,_e.normalizeWindowsPath)(h.path),o(h);else if(l.isDirectory())Sr(s,e,t,i,r,n,o);else if(i)j.default.unlink(s,c=>{if(c)return o(c);j.default.mkdir(s,t,$n(s,e,t,i,r,n,o))});else{if(l.isSymbolicLink())return o(new Vn.SymlinkError(s,s+"/"+e.join("/")));o(a)}}):(n=n||s,Sr(s,e,t,i,r,n,o))},Hh=s=>{let e=!1,t;try{e=j.default.statSync(s).isDirectory()}catch(i){t=i?.code}finally{if(!e)throw new Kn.CwdError(s,t??"ENOTDIR")}},Gh=(s,e)=>{s=(0,_e.normalizeWindowsPath)(s);let t=e.umask??18,i=e.mode|448,r=(i&t)!==0,n=e.uid,o=e.gid,a=typeof n=="number"&&typeof o=="number"&&(n!==e.processUid||o!==e.processGid),h=e.preserve,l=e.unlink,c=(0,_e.normalizeWindowsPath)(e.cwd),u=w=>{w&&a&&(0,Yn.chownrSync)(w,n,o),r&&j.default.chmodSync(s,i)};if(s===c)return Hh(c),u();if(h)return u(j.default.mkdirSync(s,{mode:i,recursive:!0})??void 0);let D=(0,_e.normalizeWindowsPath)(Ui.default.relative(c,s)).split("/"),A;for(let w=D.shift(),P=c;w&&(P+="/"+w);w=D.shift()){P=(0,_e.normalizeWindowsPath)(Ui.default.resolve(P));try{j.default.mkdirSync(P,i),A=A||P}catch{let xt=j.default.lstatSync(P);if(xt.isDirectory())continue;if(l){j.default.unlinkSync(P),j.default.mkdirSync(P,i),A=A||P;continue}else if(xt.isSymbolicLink())return new Vn.SymlinkError(P,P+"/"+D.join("/"))}}return u(A)};De.mkdirSync=Gh});var Jn=d(qi=>{"use strict";Object.defineProperty(qi,"__esModule",{value:!0});qi.normalizeUnicode=void 0;var Rr=Object.create(null),Qn=1e4,ct=new Set,Zh=s=>{ct.has(s)?ct.delete(s):Rr[s]=s.normalize("NFD").toLocaleLowerCase("en").toLocaleUpperCase("en"),ct.add(s);let e=Rr[s],t=ct.size-Qn;if(t>Qn/10){for(let i of ct)if(ct.delete(i),delete Rr[i],--t<=0)break}return e};qi.normalizeUnicode=Zh});var to=d(Wi=>{"use strict";Object.defineProperty(Wi,"__esModule",{value:!0});Wi.PathReservations=void 0;var eo=require("node:path"),Yh=Jn(),Kh=yi(),Vh=process.env.TESTING_TAR_FAKE_PLATFORM||process.platform,$h=Vh==="win32",Xh=s=>s.split("/").slice(0,-1).reduce((t,i)=>{let r=t.at(-1);return r!==void 0&&(i=(0,eo.join)(r,i)),t.push(i||"/"),t},[]),Or=class{#e=new Map;#i=new Map;#s=new Set;reserve(e,t){e=$h?["win32 parallelization disabled"]:e.map(r=>(0,Kh.stripTrailingSlashes)((0,eo.join)((0,Yh.normalizeUnicode)(r))));let i=new Set(e.map(r=>Xh(r)).reduce((r,n)=>r.concat(n)));this.#i.set(t,{dirs:i,paths:e});for(let r of e){let n=this.#e.get(r);n?n.push(t):this.#e.set(r,[t])}for(let r of i){let n=this.#e.get(r);if(!n)this.#e.set(r,[new Set([t])]);else{let o=n.at(-1);o instanceof Set?o.add(t):n.push(new Set([t]))}}return this.#r(t)}#n(e){let t=this.#i.get(e);if(!t)throw new Error("function does not have any path reservations");return{paths:t.paths.map(i=>this.#e.get(i)),dirs:[...t.dirs].map(i=>this.#e.get(i))}}check(e){let{paths:t,dirs:i}=this.#n(e);return t.every(r=>r&&r[0]===e)&&i.every(r=>r&&r[0]instanceof Set&&r[0].has(e))}#r(e){return this.#s.has(e)||!this.check(e)?!1:(this.#s.add(e),e(()=>this.#t(e)),!0)}#t(e){if(!this.#s.has(e))return!1;let t=this.#i.get(e);if(!t)throw new Error("invalid reservation");let{paths:i,dirs:r}=t,n=new Set;for(let o of i){let a=this.#e.get(o);if(!a||a?.[0]!==e)continue;let h=a[1];if(!h){this.#e.delete(o);continue}if(a.shift(),typeof h=="function")n.add(h);else for(let l of h)n.add(l)}for(let o of r){let a=this.#e.get(o),h=a?.[0];if(!(!a||!(h instanceof Set)))if(h.size===1&&a.length===1){this.#e.delete(o);continue}else if(h.size===1){a.shift();let l=a[0];typeof l=="function"&&n.add(l)}else h.delete(e)}return this.#s.delete(e),n.forEach(o=>this.#r(o)),!0}};Wi.PathReservations=Or});var io=d(Hi=>{"use strict";Object.defineProperty(Hi,"__esModule",{value:!0});Hi.umask=void 0;var Qh=()=>process.umask();Hi.umask=Qh});var Cr=d(k=>{"use strict";var Jh=k&&k.__createBinding||(Object.create?(function(s,e,t,i){i===void 0&&(i=t);var r=Object.getOwnPropertyDescriptor(e,t);(!r||("get"in r?!e.__esModule:r.writable||r.configurable))&&(r={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(s,i,r)}):(function(s,e,t,i){i===void 0&&(i=t),s[i]=e[t]})),el=k&&k.__setModuleDefault||(Object.create?(function(s,e){Object.defineProperty(s,"default",{enumerable:!0,value:e})}):function(s,e){s.default=e}),fo=k&&k.__importStar||(function(){var s=function(e){return s=Object.getOwnPropertyNames||function(t){var i=[];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(i[i.length]=r);return i},s(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var i=s(e),r=0;r{if(!zt)return m.default.unlink(s,e);let t=s+".DELETE."+(0,mo.randomBytes)(16).toString("hex");m.default.rename(s,t,i=>{if(i)return e(i);m.default.unlink(t,e)})},cl=s=>{if(!zt)return m.default.unlinkSync(s);let e=s+".DELETE."+(0,mo.randomBytes)(16).toString("hex");m.default.renameSync(s,e),m.default.unlinkSync(e)},uo=(s,e,t)=>s!==void 0&&s===s>>>0?s:e!==void 0&&e===e>>>0?e:t,Yi=class extends sl.Parser{[Tr]=!1;[Bt]=!1;[Gi]=0;reservations=new nl.PathReservations;transform;writable=!0;readable=!1;uid;gid;setOwner;preserveOwner;processGid;processUid;maxDepth;forceChown;win32;newer;keep;noMtime;preservePaths;unlink;cwd;strip;processUmask;umask;dmode;fmode;chmod;constructor(e={}){if(e.ondone=()=>{this[Tr]=!0,this[Dr]()},super(e),this.transform=e.transform,this.chmod=!!e.chmod,typeof e.uid=="number"||typeof e.gid=="number"){if(typeof e.uid!="number"||typeof e.gid!="number")throw new TypeError("cannot set owner without number uid and gid");if(e.preserveOwner)throw new TypeError("cannot preserve owner in archive and also set owner explicitly");this.uid=e.uid,this.gid=e.gid,this.setOwner=!0}else this.uid=void 0,this.gid=void 0,this.setOwner=!1;this.preserveOwner=e.preserveOwner===void 0&&typeof e.uid!="number"?process.getuid?.()===0:!!e.preserveOwner,this.processUid=(this.preserveOwner||this.setOwner)&&process.getuid?process.getuid():void 0,this.processGid=(this.preserveOwner||this.setOwner)&&process.getgid?process.getgid():void 0,this.maxDepth=typeof e.maxDepth=="number"?e.maxDepth:hl,this.forceChown=e.forceChown===!0,this.win32=!!e.win32||zt,this.newer=!!e.newer,this.keep=!!e.keep,this.noMtime=!!e.noMtime,this.preservePaths=!!e.preservePaths,this.unlink=!!e.unlink,this.cwd=(0,U.normalizeWindowsPath)(g.default.resolve(e.cwd||process.cwd())),this.strip=Number(e.strip)||0,this.processUmask=this.chmod?typeof e.processUmask=="number"?e.processUmask:(0,ol.umask)():0,this.umask=typeof e.umask=="number"?e.umask:this.processUmask,this.dmode=e.dmode||511&~this.umask,this.fmode=e.fmode||438&~this.umask,this.on("entry",t=>this[ro](t))}warn(e,t,i={}){return(e==="TAR_BAD_ARCHIVE"||e==="TAR_ABORT")&&(i.recoverable=!1),super.warn(e,t,i)}[Dr](){this[Tr]&&this[Gi]===0&&(this.emit("prefinish"),this.emit("finish"),this.emit("end"))}[vr](e,t){let i=e[t],{type:r}=e;if(!i||this.preservePaths)return!0;let[n,o]=(0,rl.stripAbsolutePath)(i),a=o.replaceAll(/\\/g,"/").split("/");if(a.includes("..")||zt&&/^[a-z]:\.\.$/i.test(a[0]??"")){if(t==="path"||r==="Link")return this.warn("TAR_ENTRY_ERROR",`${t} contains '..'`,{entry:e,[t]:i}),!1;let h=g.default.posix.dirname(e.path),l=g.default.posix.normalize(g.default.posix.join(h,a.join("/")));if(l.startsWith("../")||l==="..")return this.warn("TAR_ENTRY_ERROR",`${t} escapes extraction directory`,{entry:e,[t]:i}),!1}return n&&(e[t]=String(o),this.warn("TAR_ENTRY_INFO",`stripping ${n} from absolute ${t}`,{entry:e,[t]:i})),!0}[lo](e){let t=(0,U.normalizeWindowsPath)(e.path),i=t.split("/");if(this.strip){if(i.length=this.strip)e.linkpath=r.slice(this.strip).join("/");else return!1}i.splice(0,this.strip),e.path=i.join("/")}if(isFinite(this.maxDepth)&&i.length>this.maxDepth)return this.warn("TAR_ENTRY_ERROR","path excessively deep",{entry:e,path:t,depth:i.length,maxDepth:this.maxDepth}),!1;if(!this[vr](e,"path")||!this[vr](e,"linkpath"))return!1;if(e.absolute=g.default.isAbsolute(e.path)?(0,U.normalizeWindowsPath)(g.default.resolve(e.path)):(0,U.normalizeWindowsPath)(g.default.resolve(this.cwd,e.path)),!this.preservePaths&&typeof e.absolute=="string"&&e.absolute.indexOf(this.cwd+"/")!==0&&e.absolute!==this.cwd)return this.warn("TAR_ENTRY_ERROR","path escaped extraction target",{entry:e,path:(0,U.normalizeWindowsPath)(e.path),resolvedPath:e.absolute,cwd:this.cwd}),!1;if(e.absolute===this.cwd&&e.type!=="Directory"&&e.type!=="GNUDumpDir")return!1;if(this.win32){let{root:r}=g.default.win32.parse(String(e.absolute));e.absolute=r+so.encode(String(e.absolute).slice(r.length));let{root:n}=g.default.win32.parse(e.path);e.path=n+so.encode(e.path.slice(n.length))}return!0}[ro](e){if(!this[lo](e))return e.resume();switch(il.default.equal(typeof e.absolute,"string"),e.type){case"Directory":case"GNUDumpDir":e.mode&&(e.mode=e.mode|448);case"File":case"OldFile":case"ContiguousFile":case"Link":case"SymbolicLink":return this[Pr](e);default:return this[ho](e)}}[T](e,t){e.name==="CwdError"?this.emit("error",e):(this.warn("TAR_ENTRY_ERROR",e,{entry:t}),this[ut](),t.resume())}[Pe](e,t,i){(0,_o.mkdir)((0,U.normalizeWindowsPath)(e),{uid:this.uid,gid:this.gid,processUid:this.processUid,processGid:this.processGid,umask:this.processUmask,preserve:this.preservePaths,unlink:this.unlink,cwd:this.cwd,mode:t},i)}[It](e){return this.forceChown||this.preserveOwner&&(typeof e.uid=="number"&&e.uid!==this.processUid||typeof e.gid=="number"&&e.gid!==this.processGid)||typeof this.uid=="number"&&this.uid!==this.processUid||typeof this.gid=="number"&&this.gid!==this.processGid}[Ft](e){return uo(this.uid,e.uid,this.processUid)}[Ct](e){return uo(this.gid,e.gid,this.processGid)}[Mr](e,t){let i=typeof e.mode=="number"?e.mode&4095:this.fmode,r=new tl.WriteStream(String(e.absolute),{flags:(0,po.getWriteFlag)(e.size),mode:i,autoClose:!1});r.on("error",h=>{r.fd&&m.default.close(r.fd,()=>{}),r.write=()=>!0,this[T](h,e),t()});let n=1,o=h=>{if(h){r.fd&&m.default.close(r.fd,()=>{}),this[T](h,e),t();return}--n===0&&r.fd!==void 0&&m.default.close(r.fd,l=>{l?this[T](l,e):this[ut](),t()})};r.on("finish",()=>{let h=String(e.absolute),l=r.fd;if(typeof l=="number"&&e.mtime&&!this.noMtime){n++;let c=e.atime||new Date,u=e.mtime;m.default.futimes(l,c,u,E=>E?m.default.utimes(h,c,u,D=>o(D&&E)):o())}if(typeof l=="number"&&this[It](e)){n++;let c=this[Ft](e),u=this[Ct](e);typeof c=="number"&&typeof u=="number"&&m.default.fchown(l,c,u,E=>E?m.default.chown(h,c,u,D=>o(D&&E)):o())}o()});let a=this.transform&&this.transform(e)||e;a!==e&&(a.on("error",h=>{this[T](h,e),t()}),e.pipe(a)),a.pipe(r)}[Lr](e,t){let i=typeof e.mode=="number"?e.mode&4095:this.dmode;this[Pe](String(e.absolute),i,r=>{if(r){this[T](r,e),t();return}let n=1,o=()=>{--n===0&&(t(),this[ut](),e.resume())};e.mtime&&!this.noMtime&&(n++,m.default.utimes(String(e.absolute),e.atime||new Date,e.mtime,o)),this[It](e)&&(n++,m.default.chown(String(e.absolute),Number(this[Ft](e)),Number(this[Ct](e)),o)),o()})}[ho](e){e.unsupported=!0,this.warn("TAR_ENTRY_UNSUPPORTED",`unsupported entry type: ${e.type}`,{entry:e}),e.resume()}[oo](e,t){let i=(0,U.normalizeWindowsPath)(g.default.relative(this.cwd,g.default.resolve(g.default.dirname(String(e.absolute)),String(e.linkpath)))).split("/");this[At](e,this.cwd,i,()=>this[Zi](e,String(e.linkpath),"symlink",t),r=>{this[T](r,e),t()})}[ao](e,t){let i=(0,U.normalizeWindowsPath)(g.default.resolve(this.cwd,String(e.linkpath))),r=(0,U.normalizeWindowsPath)(String(e.linkpath)).split("/");this[At](e,this.cwd,r,()=>this[Zi](e,i,"link",t),n=>{this[T](n,e),t()})}[At](e,t,i,r,n){let o=i.shift();if(this.preservePaths||o===void 0)return r();let a=g.default.resolve(t,o);m.default.lstat(a,(h,l)=>{if(h)return r();if(l?.isSymbolicLink())return n(new wo.SymlinkError(a,g.default.resolve(a,i.join("/"))));this[At](e,a,i,r,n)})}[co](){this[Gi]++}[ut](){this[Gi]--,this[Dr]()}[Ar](e){this[ut](),e.resume()}[Nr](e,t){return e.type==="File"&&!this.unlink&&t.isFile()&&t.nlink<=1&&!zt}[Pr](e){this[co]();let t=[e.path];e.linkpath&&t.push(e.linkpath),this.reservations.reserve(t,i=>this[no](e,i))}[no](e,t){let i=a=>{t(a)},r=()=>{this[Pe](this.cwd,this.dmode,a=>{if(a){this[T](a,e),i();return}this[Bt]=!0,n()})},n=()=>{if(e.absolute!==this.cwd){let a=(0,U.normalizeWindowsPath)(g.default.dirname(String(e.absolute)));if(a!==this.cwd)return this[Pe](a,this.dmode,h=>{if(h){this[T](h,e),i();return}o()})}o()},o=()=>{m.default.lstat(String(e.absolute),(a,h)=>{if(h&&(this.keep||this.newer&&h.mtime>(e.mtime??h.mtime))){this[Ar](e),i();return}if(a||this[Nr](e,h))return this[G](null,e,i);if(h.isDirectory()){if(e.type==="Directory"){let l=this.chmod&&e.mode&&(h.mode&4095)!==e.mode,c=u=>this[G](u??null,e,i);return l?m.default.chmod(String(e.absolute),Number(e.mode),c):c()}if(e.absolute!==this.cwd)return m.default.rmdir(String(e.absolute),l=>this[G](l??null,e,i))}if(e.absolute===this.cwd)return this[G](null,e,i);ll(String(e.absolute),l=>this[G](l??null,e,i))})};this[Bt]?n():r()}[G](e,t,i){if(e){this[T](e,t),i();return}switch(t.type){case"File":case"OldFile":case"ContiguousFile":return this[Mr](t,i);case"Link":return this[ao](t,i);case"SymbolicLink":return this[oo](t,i);case"Directory":case"GNUDumpDir":return this[Lr](t,i)}}[Zi](e,t,i,r){m.default[i](t,String(e.absolute),n=>{n?this[T](n,e):(this[ut](),e.resume()),r()})}};k.Unpack=Yi;var Lt=s=>{try{return[null,s()]}catch(e){return[e,null]}},Ir=class extends Yi{sync=!0;[G](e,t){return super[G](e,t,()=>{})}[Pr](e){if(!this[Bt]){let n=this[Pe](this.cwd,this.dmode);if(n)return this[T](n,e);this[Bt]=!0}if(e.absolute!==this.cwd){let n=(0,U.normalizeWindowsPath)(g.default.dirname(String(e.absolute)));if(n!==this.cwd){let o=this[Pe](n,this.dmode);if(o)return this[T](o,e)}}let[t,i]=Lt(()=>m.default.lstatSync(String(e.absolute)));if(i&&(this.keep||this.newer&&i.mtime>(e.mtime??i.mtime)))return this[Ar](e);if(t||this[Nr](e,i))return this[G](null,e);if(i.isDirectory()){if(e.type==="Directory"){let o=this.chmod&&e.mode&&(i.mode&4095)!==e.mode,[a]=o?Lt(()=>{m.default.chmodSync(String(e.absolute),Number(e.mode))}):[];return this[G](a,e)}let[n]=Lt(()=>m.default.rmdirSync(String(e.absolute)));this[G](n,e)}let[r]=e.absolute===this.cwd?[]:Lt(()=>cl(String(e.absolute)));this[G](r,e)}[Mr](e,t){let i=typeof e.mode=="number"?e.mode&4095:this.fmode,r=a=>{let h;try{m.default.closeSync(n)}catch(l){h=l}(a||h)&&this[T](a||h,e),t()},n;try{n=m.default.openSync(String(e.absolute),(0,po.getWriteFlag)(e.size),i)}catch(a){return r(a)}let o=this.transform&&this.transform(e)||e;o!==e&&(o.on("error",a=>this[T](a,e)),e.pipe(o)),o.on("data",a=>{try{m.default.writeSync(n,a,0,a.length)}catch(h){r(h)}}),o.on("end",()=>{let a=null;if(e.mtime&&!this.noMtime){let h=e.atime||new Date,l=e.mtime;try{m.default.futimesSync(n,h,l)}catch(c){try{m.default.utimesSync(String(e.absolute),h,l)}catch{a=c}}}if(this[It](e)){let h=this[Ft](e),l=this[Ct](e);try{m.default.fchownSync(n,Number(h),Number(l))}catch(c){try{m.default.chownSync(String(e.absolute),Number(h),Number(l))}catch{a=a||c}}}r(a)})}[Lr](e,t){let i=typeof e.mode=="number"?e.mode&4095:this.dmode,r=this[Pe](String(e.absolute),i);if(r){this[T](r,e),t();return}if(e.mtime&&!this.noMtime)try{m.default.utimesSync(String(e.absolute),e.atime||new Date,e.mtime)}catch{}if(this[It](e))try{m.default.chownSync(String(e.absolute),Number(this[Ft](e)),Number(this[Ct](e)))}catch{}t(),e.resume()}[Pe](e,t){try{return(0,_o.mkdirSync)((0,U.normalizeWindowsPath)(e),{uid:this.uid,gid:this.gid,processUid:this.processUid,processGid:this.processGid,umask:this.processUmask,preserve:this.preservePaths,unlink:this.unlink,cwd:this.cwd,mode:t})}catch(i){return i}}[At](e,t,i,r,n){if(this.preservePaths||i.length===0)return r();let o=t;for(let a of i){o=g.default.resolve(o,a);let[h,l]=Lt(()=>m.default.lstatSync(o));if(h)return r();if(l.isSymbolicLink())return n(new wo.SymlinkError(o,g.default.resolve(t,i.join("/"))))}r()}[Zi](e,t,i,r){let n=`${i}Sync`;try{m.default[n](t,String(e.absolute)),r(),e.resume()}catch(o){return this[T](o,e)}}};k.UnpackSync=Ir});var Br=d(Z=>{"use strict";var ul=Z&&Z.__createBinding||(Object.create?(function(s,e,t,i){i===void 0&&(i=t);var r=Object.getOwnPropertyDescriptor(e,t);(!r||("get"in r?!e.__esModule:r.writable||r.configurable))&&(r={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(s,i,r)}):(function(s,e,t,i){i===void 0&&(i=t),s[i]=e[t]})),fl=Z&&Z.__setModuleDefault||(Object.create?(function(s,e){Object.defineProperty(s,"default",{enumerable:!0,value:e})}):function(s,e){s.default=e}),dl=Z&&Z.__importStar||(function(){var s=function(e){return s=Object.getOwnPropertyNames||function(t){var i=[];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(i[i.length]=r);return i},s(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var i=s(e),r=0;r{let e=new Ki.UnpackSync(s),t=s.file,i=Eo.default.statSync(t),r=s.maxReadSize||16*1024*1024;new yo.ReadStreamSync(t,{readSize:r,size:i.size}).pipe(e)},yl=(s,e)=>{let t=new Ki.Unpack(s),i=s.maxReadSize||16*1024*1024,r=s.file;return new Promise((o,a)=>{t.on("error",a),t.on("close",o),Eo.default.stat(r,(h,l)=>{if(h)a(h);else{let c=new yo.ReadStream(r,{readSize:i,size:l.size});c.on("error",a),c.pipe(t)}})})};Z.extract=(0,_l.makeCommand)(wl,yl,s=>new Ki.UnpackSync(s),s=>new Ki.Unpack(s),(s,e)=>{e?.length&&(0,pl.filesFilter)(s,e)})});var Vi=d(ft=>{"use strict";var bo=ft&&ft.__importDefault||function(s){return s&&s.__esModule?s:{default:s}};Object.defineProperty(ft,"__esModule",{value:!0});ft.replace=void 0;var So=Ke(),q=bo(require("node:fs")),go=bo(require("node:path")),Ro=et(),Oo=rt(),El=Ve(),bl=Qt(),vo=Ci(),Sl=(s,e)=>{let t=new vo.PackSync(s),i=!0,r,n;try{try{r=q.default.openSync(s.file,"r+")}catch(h){if(h?.code==="ENOENT")r=q.default.openSync(s.file,"w+");else throw h}let o=q.default.fstatSync(r),a=Buffer.alloc(512);e:for(n=0;no.size)break;n+=l,s.mtimeCache&&h.mtime&&s.mtimeCache.set(String(h.path),h.mtime)}i=!1,gl(s,t,n,r,e)}finally{if(i)try{q.default.closeSync(r)}catch{}}},gl=(s,e,t,i,r)=>{let n=new So.WriteStreamSync(s.file,{fd:i,start:t});e.pipe(n),Ol(e,r)},Rl=(s,e)=>{e=Array.from(e);let t=new vo.Pack(s),i=(n,o,a)=>{let h=(D,A)=>{D?q.default.close(n,w=>a(D)):a(null,A)},l=0;if(o===0)return h(null,0);let c=0,u=Buffer.alloc(512),E=(D,A)=>{if(D||A===void 0)return h(D);if(c+=A,c<512&&A)return q.default.read(n,u,c,u.length-c,l+c,E);if(l===0&&u[0]===31&&u[1]===139)return h(new Error("cannot append to compressed archives"));if(c<512)return h(null,l);let w=new Ro.Header(u);if(!w.cksumValid)return h(null,l);let P=512*Math.ceil((w.size??0)/512);if(l+P+512>o||(l+=P+512,l>=o))return h(null,l);s.mtimeCache&&w.mtime&&s.mtimeCache.set(String(w.path),w.mtime),c=0,q.default.read(n,u,0,512,l,E)};q.default.read(n,u,0,512,l,E)};return new Promise((n,o)=>{t.on("error",o);let a="r+",h=(l,c)=>{if(l&&l.code==="ENOENT"&&a==="r+")return a="w+",q.default.open(s.file,a,h);if(l||!c)return o(l);q.default.fstat(c,(u,E)=>{if(u)return q.default.close(c,()=>o(u));i(c,E.size,(D,A)=>{if(D)return o(D);let w=new So.WriteStream(s.file,{fd:c,start:A});t.pipe(w),w.on("error",o),w.on("close",n),vl(t,e)})})};q.default.open(s.file,a,h)})},Ol=(s,e)=>{e.forEach(t=>{t.charAt(0)==="@"?(0,Oo.list)({file:go.default.resolve(s.cwd,t.slice(1)),sync:!0,noResume:!0,onReadEntry:i=>s.add(i)}):s.add(t)}),s.end()},vl=async(s,e)=>{for(let t of e)t.charAt(0)==="@"?await(0,Oo.list)({file:go.default.resolve(String(s.cwd),t.slice(1)),noResume:!0,onReadEntry:i=>s.add(i)}):s.add(t);s.end()};ft.replace=(0,El.makeCommand)(Sl,Rl,()=>{throw new TypeError("file is required")},()=>{throw new TypeError("file is required")},(s,e)=>{if(!(0,bl.isFile)(s))throw new TypeError("file is required");if(s.gzip||s.brotli||s.zstd||s.file.endsWith(".br")||s.file.endsWith(".tbr"))throw new TypeError("cannot append to compressed archives");if(!e?.length)throw new TypeError("no paths specified to add/replace")})});var zr=d($i=>{"use strict";Object.defineProperty($i,"__esModule",{value:!0});$i.update=void 0;var Tl=Ve(),kt=Vi();$i.update=(0,Tl.makeCommand)(kt.replace.syncFile,kt.replace.asyncFile,kt.replace.syncNoFile,kt.replace.asyncNoFile,(s,e=[])=>{kt.replace.validate?.(s,e),Dl(s)});var Dl=s=>{let e=s.filter;s.mtimeCache||(s.mtimeCache=new Map),s.filter=e?(t,i)=>e(t,i)&&!((s.mtimeCache?.get(t)??i.mtime??0)>(i.mtime??0)):(t,i)=>!((s.mtimeCache?.get(t)??i.mtime??0)>(i.mtime??0))}});var To=exports&&exports.__createBinding||(Object.create?(function(s,e,t,i){i===void 0&&(i=t);var r=Object.getOwnPropertyDescriptor(e,t);(!r||("get"in r?!e.__esModule:r.writable||r.configurable))&&(r={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(s,i,r)}):(function(s,e,t,i){i===void 0&&(i=t),s[i]=e[t]})),Pl=exports&&exports.__setModuleDefault||(Object.create?(function(s,e){Object.defineProperty(s,"default",{enumerable:!0,value:e})}):function(s,e){s.default=e}),Y=exports&&exports.__exportStar||function(s,e){for(var t in s)t!=="default"&&!Object.prototype.hasOwnProperty.call(e,t)&&To(e,s,t)},Nl=exports&&exports.__importStar||(function(){var s=function(e){return s=Object.getOwnPropertyNames||function(t){var i=[];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(i[i.length]=r);return i},s(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var i=s(e),r=0;r{let t=parseInt(e,10);if(t!==Buffer.byteLength(e)+1)return s;e=e.slice((t+" ").length);let i=e.split("="),r=i.shift();if(!r)return s;let n=r.replace(/^SCHILY\.(dev|ino|nlink)/,"$1"),o=i.join("=").replace(/\0.*/,"");switch(n){case"path":case"linkpath":case"type":case"charset":case"comment":case"gname":case"uname":s[n]=o;break;case"ctime":case"atime":case"mtime":s[n]=new Date(Number(o)*1e3);break;case"size":let a=+o;a>=0&&(s[n]=a);break;case"gid":case"uid":case"dev":case"ino":case"nlink":case"mode":s[n]=+o;break}return s}});var tt=d(ri=>{"use strict";Object.defineProperty(ri,"__esModule",{value:!0});ri.normalizeWindowsPath=void 0;var Ca=process.env.TESTING_TAR_FAKE_PLATFORM||process.platform;ri.normalizeWindowsPath=Ca!=="win32"?s=>String(s):s=>String(s).replaceAll(/\\/g,"/")});var Cs=d(oi=>{"use strict";Object.defineProperty(oi,"__esModule",{value:!0});oi.ReadEntry=void 0;var Ba=We(),ni=tt(),Fs=class extends Ba.Minipass{extended;globalExtended;header;startBlockSize;blockRemain;remain;type;meta=!1;ignore=!1;path;mode;uid;gid;uname;gname;size=0;mtime;atime;ctime;linkpath;dev;ino;nlink;invalid=!1;absolute;unsupported=!1;constructor(e,t,i){switch(super({}),this.pause(),this.extended=t,this.globalExtended=i,this.header=e,this.remain=e.size??0,this.startBlockSize=512*Math.ceil(this.remain/512),this.blockRemain=this.startBlockSize,this.type=e.type,this.type){case"File":case"OldFile":case"Link":case"SymbolicLink":case"CharacterDevice":case"BlockDevice":case"Directory":case"FIFO":case"ContiguousFile":case"GNUDumpDir":break;case"NextFileHasLongLinkpath":case"NextFileHasLongPath":case"OldGnuLongPath":case"GlobalExtendedHeader":case"ExtendedHeader":case"OldExtendedHeader":this.meta=!0;break;default:this.ignore=!0}if(!e.path)throw new Error("no path provided for tar.ReadEntry");this.path=(0,ni.normalizeWindowsPath)(e.path),this.mode=e.mode,this.mode&&(this.mode=this.mode&4095),this.uid=e.uid,this.gid=e.gid,this.uname=e.uname,this.gname=e.gname,this.size=this.remain,this.mtime=e.mtime,this.atime=e.atime,this.ctime=e.ctime,this.linkpath=e.linkpath?(0,ni.normalizeWindowsPath)(e.linkpath):void 0,this.uname=e.uname,this.gname=e.gname,t&&this.#e(t),i&&this.#e(i,!0)}write(e){let t=e.length;if(t>this.blockRemain)throw new Error("writing more to entry than is appropriate");let i=this.remain,r=this.blockRemain;return this.remain=Math.max(0,i-t),this.blockRemain=Math.max(0,r-t),this.ignore?!0:i>=t?super.write(e):super.write(e.subarray(0,i))}#e(e,t=!1){e.path&&(e.path=(0,ni.normalizeWindowsPath)(e.path)),e.linkpath&&(e.linkpath=(0,ni.normalizeWindowsPath)(e.linkpath)),Object.assign(this,Object.fromEntries(Object.entries(e).filter(([i,r])=>!(r==null||i==="path"&&t))))}};oi.ReadEntry=Fs});var hi=d(ai=>{"use strict";Object.defineProperty(ai,"__esModule",{value:!0});ai.warnMethod=void 0;var za=(s,e,t,i={})=>{s.file&&(i.file=s.file),s.cwd&&(i.cwd=s.cwd),i.code=t instanceof Error&&t.code||e,i.tarCode=e,!s.strict&&i.recoverable!==!1?(t instanceof Error&&(i=Object.assign(t,i),t=t.message),s.emit("warn",e,t,i)):t instanceof Error?s.emit("error",Object.assign(t,i)):s.emit("error",Object.assign(new Error(`${e}: ${t}`),i))};ai.warnMethod=za});var _i=d(pi=>{"use strict";Object.defineProperty(pi,"__esModule",{value:!0});pi.Parser=void 0;var ka=require("events"),Bs=Ps(),Xr=et(),Qr=si(),xa=Cs(),ja=hi(),Ua=1024*1024,qs=Buffer.from([31,139]),Ws=Buffer.from([40,181,47,253]),qa=Math.max(qs.length,Ws.length),H=Symbol("state"),ze=Symbol("writeEntry"),me=Symbol("readEntry"),zs=Symbol("nextEntry"),Jr=Symbol("processEntry"),re=Symbol("extendedHeader"),gt=Symbol("globalExtendedHeader"),Re=Symbol("meta"),en=Symbol("emitMeta"),_=Symbol("buffer"),pe=Symbol("queue"),Oe=Symbol("ended"),ks=Symbol("emittedEnd"),ke=Symbol("emit"),y=Symbol("unzip"),li=Symbol("consumeChunk"),ci=Symbol("consumeChunkSub"),xs=Symbol("consumeBody"),tn=Symbol("consumeMeta"),sn=Symbol("consumeHeader"),Rt=Symbol("consuming"),js=Symbol("bufferConcat"),ui=Symbol("maybeEnd"),it=Symbol("writing"),ne=Symbol("aborted"),fi=Symbol("onDone"),xe=Symbol("sawValidEntry"),di=Symbol("sawNullBlock"),mi=Symbol("sawEOF"),rn=Symbol("closeStream"),Wa=1e3,Ot=Symbol("compressedBytesRead"),Us=Symbol("decompressedBytesRead"),nn=Symbol("checkDecompressionRatio"),Ha=()=>!0,Hs=class extends ka.EventEmitter{file;strict;maxMetaEntrySize;filter;brotli;zstd;maxDecompressionRatio;writable=!0;readable=!1;[pe]=[];[_];[me];[ze];[H]="begin";[Re]="";[re];[gt];[Oe]=!1;[y];[ne]=!1;[xe];[di]=!1;[mi]=!1;[it]=!1;[Rt]=!1;[ks]=!1;[Ot]=0;[Us]=0;constructor(e={}){super(),this.file=e.file||"",this.on(fi,()=>{(this[H]==="begin"||this[xe]===!1)&&this.warn("TAR_BAD_ARCHIVE","Unrecognized archive format")}),e.ondone?this.on(fi,e.ondone):this.on(fi,()=>{this.emit("prefinish"),this.emit("finish"),this.emit("end")}),this.strict=!!e.strict,this.maxDecompressionRatio=typeof e.maxDecompressionRatio=="number"?e.maxDecompressionRatio:Wa,this.maxMetaEntrySize=e.maxMetaEntrySize||Ua,this.filter=typeof e.filter=="function"?e.filter:Ha;let t=e.file&&(e.file.endsWith(".tar.br")||e.file.endsWith(".tbr"));this.brotli=!(e.gzip||e.zstd)&&e.brotli!==void 0?e.brotli:t?void 0:!1;let i=e.file&&(e.file.endsWith(".tar.zst")||e.file.endsWith(".tzst"));this.zstd=!(e.gzip||e.brotli)&&e.zstd!==void 0?e.zstd:i?!0:void 0,this.on("end",()=>this[rn]()),typeof e.onwarn=="function"&&this.on("warn",e.onwarn),typeof e.onReadEntry=="function"&&this.on("entry",e.onReadEntry)}warn(e,t,i={}){(0,ja.warnMethod)(this,e,t,i)}[sn](e,t){this[xe]===void 0&&(this[xe]=!1);let i;try{i=new Xr.Header(e,t,this[re],this[gt])}catch(r){return this.warn("TAR_ENTRY_INVALID",r)}if(i.nullBlock)this[di]?(this[mi]=!0,this[H]==="begin"&&(this[H]="header"),this[ke]("eof")):(this[di]=!0,this[ke]("nullBlock"));else if(this[di]=!1,!i.cksumValid)this.warn("TAR_ENTRY_INVALID","checksum failure",{header:i});else if(!i.path)this.warn("TAR_ENTRY_INVALID","path is required",{header:i});else{let r=i.type;if(/^(Symbolic)?Link$/.test(r)&&!i.linkpath)this.warn("TAR_ENTRY_INVALID","linkpath required",{header:i});else if(!/^(Symbolic)?Link$/.test(r)&&!/^(Global)?ExtendedHeader$/.test(r)&&i.linkpath)this.warn("TAR_ENTRY_INVALID","linkpath forbidden",{header:i});else{let n=this[ze]=new xa.ReadEntry(i,this[re],this[gt]);if(!this[xe])if(n.remain){let o=()=>{n.invalid||(this[xe]=!0)};n.on("end",o)}else this[xe]=!0;n.meta?n.size>this.maxMetaEntrySize?(n.ignore=!0,this[ke]("ignoredEntry",n),this[H]="ignore",n.resume()):n.size>0&&(this[Re]="",n.on("data",o=>this[Re]+=o),this[H]="meta"):(this[re]=void 0,n.ignore=n.ignore||!this.filter(n.path,n),n.ignore?(this[ke]("ignoredEntry",n),this[H]=n.remain?"ignore":"header",n.resume()):(n.remain?this[H]="body":(this[H]="header",n.end()),this[me]?this[pe].push(n):(this[pe].push(n),this[zs]())))}}}[rn](){queueMicrotask(()=>this.emit("close"))}[Jr](e){let t=!0;if(!e)this[me]=void 0,t=!1;else if(Array.isArray(e)){let[i,...r]=e;this.emit(i,...r)}else this[me]=e,this.emit("entry",e),e.emittedEnd||(e.on("end",()=>this[zs]()),t=!1);return t}[zs](){do;while(this[Jr](this[pe].shift()));if(this[pe].length===0){let e=this[me];!e||e.flowing||e.size===e.remain?this[it]||this.emit("drain"):e.once("drain",()=>this.emit("drain"))}}[xs](e,t){let i=this[ze];if(!i)throw new Error("attempt to consume body without entry??");let r=i.blockRemain??0,n=r>=e.length&&t===0?e:e.subarray(t,t+r);return i.write(n),i.blockRemain||(this[H]="header",this[ze]=void 0,i.end()),n.length}[tn](e,t){let i=this[ze],r=this[xs](e,t);return!this[ze]&&i&&this[en](i),r}[ke](e,t,i){this[pe].length===0&&!this[me]?this.emit(e,t,i):this[pe].push([e,t,i])}[en](e){switch(this[ke]("meta",this[Re]),e.type){case"ExtendedHeader":case"OldExtendedHeader":this[re]=Qr.Pax.parse(this[Re],this[re],!1);break;case"GlobalExtendedHeader":this[gt]=Qr.Pax.parse(this[Re],this[gt],!0);break;case"NextFileHasLongPath":case"OldGnuLongPath":{let t=this[re]??Object.create(null);this[re]=t,t.path=this[Re].replace(/\0.*/,"");break}case"NextFileHasLongLinkpath":{let t=this[re]||Object.create(null);this[re]=t,t.linkpath=this[Re].replace(/\0.*/,"");break}default:throw new Error("unknown meta: "+e.type)}}abort(e){if(!this[ne]){if(this[y]){let t=this[y];t.write=()=>!0,t.end=()=>t,t.emit=()=>!1,t.destroy?.()}this[ne]=!0,this.emit("abort",e),this.warn("TAR_ABORT",e,{recoverable:!1})}}[nn](e){this[Us]+=e.length;let t=this[Us]/this[Ot];return t>this.maxDecompressionRatio?(this.abort(new Error(`max decompression ratio exceeded: ${t.toFixed(2)} > ${this.maxDecompressionRatio}`)),!1):!0}write(e,t,i){if(typeof t=="function"&&(i=t,t=void 0),typeof e=="string"&&(e=Buffer.from(e,typeof t=="string"?t:"utf8")),this[ne])return i?.(),!1;if((this[y]===void 0||this.brotli===void 0&&this[y]===!1)&&e){if(this[_]&&(e=Buffer.concat([this[_],e]),this[_]=void 0),e.length{this[nn](c)&&this[li](c)}),this[y].on("error",c=>{this[ne]||this.abort(c)}),this[y].on("end",()=>{this[Oe]=!0,this[li]()}),this[it]=!0,this[Ot]+=e.length;let l=!!this[y][h?"end":"write"](e);return this[it]=!1,i?.(),l}}this[it]=!0,this[y]?(this[Ot]+=e.length,this[y].write(e)):this[li](e),this[it]=!1;let n=this[pe].length>0?!1:this[me]?this[me].flowing:!0;return!n&&this[pe].length===0&&this[me]?.once("drain",()=>this.emit("drain")),i?.(),n}[js](e){e&&!this[ne]&&(this[_]=this[_]?Buffer.concat([this[_],e]):e)}[ui](){if(this[Oe]&&!this[ks]&&!this[ne]&&!this[Rt]){this[ks]=!0;let e=this[ze];if(e?.blockRemain){let t=this[_]?this[_].length:0;this.warn("TAR_BAD_ARCHIVE",`Truncated input (needed ${e.blockRemain} more bytes, only ${t} available)`,{entry:e}),this[_]&&e.write(this[_]),e.end()}this[ke](fi)}}[li](e){if(this[Rt]&&e)this[js](e);else if(!e&&!this[_])this[ui]();else if(e){if(this[Rt]=!0,this[_]){this[js](e);let t=this[_];this[_]=void 0,this[ci](t)}else this[ci](e);for(;this[_]&&this[_]?.length>=512&&!this[ne]&&!this[mi];){let t=this[_];this[_]=void 0,this[ci](t)}this[Rt]=!1}(!this[_]||this[Oe])&&this[ui]()}[ci](e){let t=0,i=e.length;for(;t+512<=i&&!this[ne]&&!this[mi];)switch(this[H]){case"begin":case"header":this[sn](e,t),t+=512;break;case"ignore":case"body":t+=this[xs](e,t);break;case"meta":t+=this[tn](e,t);break;default:throw new Error("invalid state: "+this[H])}t{"use strict";Object.defineProperty(wi,"__esModule",{value:!0});wi.stripTrailingSlashes=void 0;var Ga=s=>{let e=s.length-1,t=-1;for(;e>-1&&s.charAt(e)==="/";)t=e,e--;return t===-1?s:s.slice(0,t)};wi.stripTrailingSlashes=Ga});var rt=d(B=>{"use strict";var Za=B&&B.__createBinding||(Object.create?(function(s,e,t,i){i===void 0&&(i=t);var r=Object.getOwnPropertyDescriptor(e,t);(!r||("get"in r?!e.__esModule:r.writable||r.configurable))&&(r={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(s,i,r)}):(function(s,e,t,i){i===void 0&&(i=t),s[i]=e[t]})),Ya=B&&B.__setModuleDefault||(Object.create?(function(s,e){Object.defineProperty(s,"default",{enumerable:!0,value:e})}):function(s,e){s.default=e}),Ka=B&&B.__importStar||(function(){var s=function(e){return s=Object.getOwnPropertyNames||function(t){var i=[];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(i[i.length]=r);return i},s(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var i=s(e),r=0;r{let e=s.onReadEntry;s.onReadEntry=e?t=>{e(t),t.resume()}:t=>t.resume()},Ja=(s,e)=>{let t=new Map(e.map(o=>[(0,Gs.stripTrailingSlashes)(o),!0])),i=s.filter,r=100,n=(o,a="",h=0)=>{if(h>=r)return t.set(o,!1),!1;let l=a||(0,on.parse)(o).root||".",c;if(o===l)c=!1;else{let u=t.get(o);c=u!==void 0?u:n((0,on.dirname)(o),l,h+1)}return t.set(o,c),c};s.filter=i?(o,a)=>i(o,a)&&n((0,Gs.stripTrailingSlashes)(o)):o=>n((0,Gs.stripTrailingSlashes)(o))};B.filesFilter=Ja;var eh=s=>{let e=new Ei.Parser(s),t=s.file,i;try{i=st.default.openSync(t,"r");let r=st.default.fstatSync(i),n=s.maxReadSize||16*1024*1024;if(r.size{let t=new Ei.Parser(s),i=s.maxReadSize||16*1024*1024,r=s.file;return new Promise((o,a)=>{t.on("error",a),t.on("end",o),st.default.stat(r,(h,l)=>{if(h)a(h);else{let c=new $a.ReadStream(r,{readSize:i,size:l.size});c.on("error",a),c.pipe(t)}})})};B.list=(0,Xa.makeCommand)(eh,th,s=>new Ei.Parser(s),s=>new Ei.Parser(s),(s,e)=>{e?.length&&(0,B.filesFilter)(s,e),s.noResume||Qa(s)})});var an=d(bi=>{"use strict";Object.defineProperty(bi,"__esModule",{value:!0});bi.modeFix=void 0;var ih=(s,e,t)=>(s&=4095,t&&(s=(s|384)&-19),e&&(s&256&&(s|=64),s&32&&(s|=8),s&4&&(s|=1)),s);bi.modeFix=ih});var Zs=d(Si=>{"use strict";Object.defineProperty(Si,"__esModule",{value:!0});Si.stripAbsolutePath=void 0;var sh=require("node:path"),{isAbsolute:rh,parse:hn}=sh.win32,nh=s=>{let e="",t=hn(s);for(;rh(s)||t.root;){let i=s.charAt(0)==="/"&&s.slice(0,4)!=="//?/"?"/":t.root;s=s.slice(i.length),e+=i,t=hn(s)}return[e,s]};Si.stripAbsolutePath=nh});var Ks=d(nt=>{"use strict";Object.defineProperty(nt,"__esModule",{value:!0});nt.decode=nt.encode=void 0;var gi=["|","<",">","?",":"],Ys=gi.map(s=>String.fromCodePoint(61440+Number(s.codePointAt(0)))),oh=new Map(gi.map((s,e)=>[s,Ys[e]])),ah=new Map(Ys.map((s,e)=>[s,gi[e]])),hh=s=>gi.reduce((e,t)=>e.split(t).join(oh.get(t)),s);nt.encode=hh;var lh=s=>Ys.reduce((e,t)=>e.split(t).join(ah.get(t)),s);nt.decode=lh});var nr=d(M=>{"use strict";var ch=M&&M.__createBinding||(Object.create?(function(s,e,t,i){i===void 0&&(i=t);var r=Object.getOwnPropertyDescriptor(e,t);(!r||("get"in r?!e.__esModule:r.writable||r.configurable))&&(r={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(s,i,r)}):(function(s,e,t,i){i===void 0&&(i=t),s[i]=e[t]})),uh=M&&M.__setModuleDefault||(Object.create?(function(s,e){Object.defineProperty(s,"default",{enumerable:!0,value:e})}):function(s,e){s.default=e}),fh=M&&M.__importStar||(function(){var s=function(e){return s=Object.getOwnPropertyNames||function(t){var i=[];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(i[i.length]=r);return i},s(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var i=s(e),r=0;re?(s=(0,oe.normalizeWindowsPath)(s).replace(/^\.(\/|$)/,""),(0,dh.stripTrailingSlashes)(e)+"/"+s):(0,oe.normalizeWindowsPath)(s),ph=16*1024*1024,cn=Symbol("process"),un=Symbol("file"),fn=Symbol("directory"),$s=Symbol("symlink"),dn=Symbol("hardlink"),vt=Symbol("header"),Ri=Symbol("read"),Xs=Symbol("lstat"),Oi=Symbol("onlstat"),Qs=Symbol("onread"),Js=Symbol("onreadlink"),er=Symbol("openfile"),tr=Symbol("onopenfile"),ve=Symbol("close"),vi=Symbol("mode"),ir=Symbol("awaitDrain"),Vs=Symbol("ondrain"),he=Symbol("prefix"),Ti=class extends pn.Minipass{path;portable;myuid=process.getuid&&process.getuid()||0;myuser=process.env.USER||"";maxReadSize;linkCache;statCache;preservePaths;cwd;strict;mtime;noPax;noMtime;prefix;fd;blockLen=0;blockRemain=0;buf;pos=0;remain=0;length=0;offset=0;win32;absolute;header;type;linkpath;stat;onWriteEntry;#e=!1;constructor(e,t={}){let i=(0,yn.dealias)(t);super(),this.path=(0,oe.normalizeWindowsPath)(e),this.portable=!!i.portable,this.maxReadSize=i.maxReadSize||ph,this.linkCache=i.linkCache||new Map,this.statCache=i.statCache||new Map,this.preservePaths=!!i.preservePaths,this.cwd=(0,oe.normalizeWindowsPath)(i.cwd||process.cwd()),this.strict=!!i.strict,this.noPax=!!i.noPax,this.noMtime=!!i.noMtime,this.mtime=i.mtime,this.prefix=i.prefix?(0,oe.normalizeWindowsPath)(i.prefix):void 0,this.onWriteEntry=i.onWriteEntry,typeof i.onwarn=="function"&&this.on("warn",i.onwarn);let r=!1;if(!this.preservePaths){let[o,a]=(0,bn.stripAbsolutePath)(this.path);o&&typeof a=="string"&&(this.path=a,r=o)}this.win32=!!i.win32||process.platform==="win32",this.win32&&(this.path=mh.decode(this.path.replaceAll(/\\/g,"/")),e=e.replaceAll(/\\/g,"/")),this.absolute=(0,oe.normalizeWindowsPath)(i.absolute||ln.default.resolve(this.cwd,e)),this.path===""&&(this.path="./"),r&&this.warn("TAR_ENTRY_INFO",`stripping ${r} from absolute path`,{entry:this,path:r+this.path});let n=this.statCache.get(this.absolute);n?this[Oi](n):this[Xs]()}warn(e,t,i={}){return(0,Sn.warnMethod)(this,e,t,i)}emit(e,...t){return e==="error"&&(this.#e=!0),super.emit(e,...t)}[Xs](){ae.default.lstat(this.absolute,(e,t)=>{if(e)return this.emit("error",e);this[Oi](t)})}[Oi](e){this.statCache.set(this.absolute,e),this.stat=e,e.isFile()||(e.size=0),this.type=_h(e),this.emit("stat",e),this[cn]()}[cn](){switch(this.type){case"File":return this[un]();case"Directory":return this[fn]();case"SymbolicLink":return this[$s]();default:return this.end()}}[vi](e){return(0,wn.modeFix)(e,this.type==="Directory",this.portable)}[he](e){return gn(e,this.prefix)}[vt](){if(!this.stat)throw new Error("cannot write header before stat");this.type==="Directory"&&this.portable&&(this.noMtime=!0),this.onWriteEntry?.(this),this.header=new _n.Header({path:this[he](this.path),linkpath:this.type==="Link"&&this.linkpath!==void 0?this[he](this.linkpath):this.linkpath,mode:this[vi](this.stat.mode),uid:this.portable?void 0:this.stat.uid,gid:this.portable?void 0:this.stat.gid,size:this.stat.size,mtime:this.noMtime?void 0:this.mtime||this.stat.mtime,type:this.type==="Unsupported"?void 0:this.type,uname:this.portable?void 0:this.stat.uid===this.myuid?this.myuser:"",atime:this.portable?void 0:this.stat.atime,ctime:this.portable?void 0:this.stat.ctime}),this.header.encode()&&!this.noPax&&super.write(new En.Pax({atime:this.portable?void 0:this.header.atime,ctime:this.portable?void 0:this.header.ctime,gid:this.portable?void 0:this.header.gid,mtime:this.noMtime?void 0:this.mtime||this.header.mtime,path:this[he](this.path),linkpath:this.type==="Link"&&this.linkpath!==void 0?this[he](this.linkpath):this.linkpath,size:this.header.size,uid:this.portable?void 0:this.header.uid,uname:this.portable?void 0:this.header.uname,dev:this.portable?void 0:this.stat.dev,ino:this.portable?void 0:this.stat.ino,nlink:this.portable?void 0:this.stat.nlink}).encode());let e=this.header?.block;if(!e)throw new Error("failed to encode header");super.write(e)}[fn](){if(!this.stat)throw new Error("cannot create directory entry without stat");this.path.slice(-1)!=="/"&&(this.path+="/"),this.stat.size=0,this[vt](),this.end()}[$s](){ae.default.readlink(this.absolute,(e,t)=>{if(e)return this.emit("error",e);this[Js](t)})}[Js](e){this.linkpath=(0,oe.normalizeWindowsPath)(e),this[vt](),this.end()}[dn](e){if(!this.stat)throw new Error("cannot create link entry without stat");this.type="Link",this.linkpath=(0,oe.normalizeWindowsPath)(ln.default.relative(this.cwd,e)),this.stat.size=0,this[vt](),this.end()}[un](){if(!this.stat)throw new Error("cannot create file entry without stat");if(this.stat.nlink>1){let e=`${this.stat.dev}:${this.stat.ino}`,t=this.linkCache.get(e);if(t?.indexOf(this.cwd)===0)return this[dn](t);this.linkCache.set(e,this.absolute)}if(this[vt](),this.stat.size===0)return this.end();this[er]()}[er](){ae.default.open(this.absolute,"r",(e,t)=>{if(e)return this.emit("error",e);this[tr](t)})}[tr](e){if(this.fd=e,this.#e)return this[ve]();if(!this.stat)throw new Error("should stat before calling onopenfile");this.blockLen=512*Math.ceil(this.stat.size/512),this.blockRemain=this.blockLen;let t=Math.min(this.blockLen,this.maxReadSize);this.buf=Buffer.allocUnsafe(t),this.offset=0,this.pos=0,this.remain=this.stat.size,this.length=this.buf.length,this[Ri]()}[Ri](){let{fd:e,buf:t,offset:i,length:r,pos:n}=this;if(e===void 0||t===void 0)throw new Error("cannot read file without first opening");ae.default.read(e,t,i,r,n,(o,a)=>{if(o)return this[ve](()=>this.emit("error",o));this[Qs](a)})}[ve](e=()=>{}){this.fd!==void 0&&ae.default.close(this.fd,e)}[Qs](e){if(e<=0&&this.remain>0){let r=Object.assign(new Error("encountered unexpected EOF"),{path:this.absolute,syscall:"read",code:"EOF"});return this[ve](()=>this.emit("error",r))}if(e>this.remain){let r=Object.assign(new Error("did not encounter expected EOF"),{path:this.absolute,syscall:"read",code:"EOF"});return this[ve](()=>this.emit("error",r))}if(!this.buf)throw new Error("should have created buffer prior to reading");if(e===this.remain)for(let r=e;rthis[Vs]())}[ir](e){this.once("drain",e)}write(e,t,i){if(typeof t=="function"&&(i=t,t=void 0),typeof e=="string"&&(e=Buffer.from(e,typeof t=="string"?t:"utf8")),this.blockRemaine?this.emit("error",e):this.end());if(!this.buf)throw new Error("buffer lost somehow in ONDRAIN");this.offset>=this.length&&(this.buf=Buffer.allocUnsafe(Math.min(this.blockRemain,this.buf.length)),this.offset=0),this.length=this.buf.length-this.offset,this[Ri]()}};M.WriteEntry=Ti;var sr=class extends Ti{sync=!0;[Xs](){this[Oi](ae.default.lstatSync(this.absolute))}[$s](){this[Js](ae.default.readlinkSync(this.absolute))}[er](){this[tr](ae.default.openSync(this.absolute,"r"))}[Ri](){let e=!0;try{let{fd:t,buf:i,offset:r,length:n,pos:o}=this;if(t===void 0||i===void 0)throw new Error("fd and buf must be set in READ method");let a=ae.default.readSync(t,i,r,n,o);this[Qs](a),e=!1}finally{if(e)try{this[ve](()=>{})}catch{}}}[ir](e){e()}[ve](e=()=>{}){this.fd!==void 0&&ae.default.closeSync(this.fd),e()}};M.WriteEntrySync=sr;var rr=class extends pn.Minipass{blockLen=0;blockRemain=0;buf=0;pos=0;remain=0;length=0;preservePaths;portable;strict;noPax;noMtime;readEntry;type;prefix;path;mode;uid;gid;uname;gname;header;mtime;atime;ctime;linkpath;size;onWriteEntry;warn(e,t,i={}){return(0,Sn.warnMethod)(this,e,t,i)}constructor(e,t={}){let i=(0,yn.dealias)(t);super(),this.preservePaths=!!i.preservePaths,this.portable=!!i.portable,this.strict=!!i.strict,this.noPax=!!i.noPax,this.noMtime=!!i.noMtime,this.onWriteEntry=i.onWriteEntry,this.readEntry=e;let{type:r}=e;if(r==="Unsupported")throw new Error("writing entry that should be ignored");this.type=r,this.type==="Directory"&&this.portable&&(this.noMtime=!0),this.prefix=i.prefix,this.path=(0,oe.normalizeWindowsPath)(e.path),this.mode=e.mode!==void 0?this[vi](e.mode):void 0,this.uid=this.portable?void 0:e.uid,this.gid=this.portable?void 0:e.gid,this.uname=this.portable?void 0:e.uname,this.gname=this.portable?void 0:e.gname,this.size=e.size,this.mtime=this.noMtime?void 0:i.mtime||e.mtime,this.atime=this.portable?void 0:e.atime,this.ctime=this.portable?void 0:e.ctime,this.linkpath=e.linkpath!==void 0?(0,oe.normalizeWindowsPath)(e.linkpath):void 0,typeof i.onwarn=="function"&&this.on("warn",i.onwarn);let n=!1;if(!this.preservePaths){let[a,h]=(0,bn.stripAbsolutePath)(this.path);a&&typeof h=="string"&&(this.path=h,n=a)}this.remain=e.size,this.blockRemain=e.startBlockSize,this.onWriteEntry?.(this),this.header=new _n.Header({path:this[he](this.path),linkpath:this.type==="Link"&&this.linkpath!==void 0?this[he](this.linkpath):this.linkpath,mode:this.mode,uid:this.portable?void 0:this.uid,gid:this.portable?void 0:this.gid,size:this.size,mtime:this.noMtime?void 0:this.mtime,type:this.type,uname:this.portable?void 0:this.uname,atime:this.portable?void 0:this.atime,ctime:this.portable?void 0:this.ctime}),n&&this.warn("TAR_ENTRY_INFO",`stripping ${n} from absolute path`,{entry:this,path:n+this.path}),this.header.encode()&&!this.noPax&&super.write(new En.Pax({atime:this.portable?void 0:this.atime,ctime:this.portable?void 0:this.ctime,gid:this.portable?void 0:this.gid,mtime:this.noMtime?void 0:this.mtime,path:this[he](this.path),linkpath:this.type==="Link"&&this.linkpath!==void 0?this[he](this.linkpath):this.linkpath,size:this.size,uid:this.portable?void 0:this.uid,uname:this.portable?void 0:this.uname,dev:this.portable?void 0:this.readEntry.dev,ino:this.portable?void 0:this.readEntry.ino,nlink:this.portable?void 0:this.readEntry.nlink}).encode());let o=this.header?.block;if(!o)throw new Error("failed to encode header");super.write(o),e.pipe(this)}[he](e){return gn(e,this.prefix)}[vi](e){return(0,wn.modeFix)(e,this.type==="Directory",this.portable)}write(e,t,i){typeof t=="function"&&(i=t,t=void 0),typeof e=="string"&&(e=Buffer.from(e,typeof t=="string"?t:"utf8"));let r=e.length;if(r>this.blockRemain)throw new Error("writing more to entry than is appropriate");return this.blockRemain-=r,super.write(e,i)}end(e,t,i){return this.blockRemain&&super.write(Buffer.alloc(this.blockRemain)),typeof e=="function"&&(i=e,t=void 0,e=void 0),typeof t=="function"&&(i=t,t=void 0),typeof e=="string"&&(e=Buffer.from(e,t??"utf8")),i&&this.once("finish",i),e?super.end(e,i):super.end(i),this}};M.WriteEntryTar=rr;var _h=s=>s.isFile()?"File":s.isDirectory()?"Directory":s.isSymbolicLink()?"SymbolicLink":"Unsupported"});var Rn=d(at=>{"use strict";Object.defineProperty(at,"__esModule",{value:!0});at.Node=at.Yallist=void 0;var or=class s{tail;head;length=0;static create(e=[]){return new s(e)}constructor(e=[]){for(let t of e)this.push(t)}*[Symbol.iterator](){for(let e=this.head;e;e=e.next)yield e.value}removeNode(e){if(e.list!==this)throw new Error("removing node which does not belong to this list");let t=e.next,i=e.prev;return t&&(t.prev=i),i&&(i.next=t),e===this.head&&(this.head=t),e===this.tail&&(this.tail=i),this.length--,e.next=void 0,e.prev=void 0,e.list=void 0,t}unshiftNode(e){if(e===this.head)return;e.list&&e.list.removeNode(e);let t=this.head;e.list=this,e.next=t,t&&(t.prev=e),this.head=e,this.tail||(this.tail=e),this.length++}pushNode(e){if(e===this.tail)return;e.list&&e.list.removeNode(e);let t=this.tail;e.list=this,e.prev=t,t&&(t.next=e),this.tail=e,this.head||(this.head=e),this.length++}push(...e){for(let t=0,i=e.length;t1)i=t;else if(this.head)r=this.head.next,i=this.head.value;else throw new TypeError("Reduce of empty list with no initial value");for(var n=0;r;n++)i=e(i,r.value,n),r=r.next;return i}reduceReverse(e,t){let i,r=this.tail;if(arguments.length>1)i=t;else if(this.tail)r=this.tail.prev,i=this.tail.value;else throw new TypeError("Reduce of empty list with no initial value");for(let n=this.length-1;r;n--)i=e(i,r.value,n),r=r.prev;return i}toArray(){let e=new Array(this.length);for(let t=0,i=this.head;i;t++)e[t]=i.value,i=i.next;return e}toArrayReverse(){let e=new Array(this.length);for(let t=0,i=this.tail;i;t++)e[t]=i.value,i=i.prev;return e}slice(e=0,t=this.length){t<0&&(t+=this.length),e<0&&(e+=this.length);let i=new s;if(tthis.length&&(t=this.length);let r=this.head,n=0;for(n=0;r&&nthis.length&&(t=this.length);let r=this.length,n=this.tail;for(;n&&r>t;r--)n=n.prev;for(;n&&r>e;r--,n=n.prev)i.push(n.value);return i}splice(e,t=0,...i){e>this.length&&(e=this.length-1),e<0&&(e=this.length+e);let r=this.head;for(let o=0;r&&o{"use strict";var bh=L&&L.__createBinding||(Object.create?(function(s,e,t,i){i===void 0&&(i=t);var r=Object.getOwnPropertyDescriptor(e,t);(!r||("get"in r?!e.__esModule:r.writable||r.configurable))&&(r={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(s,i,r)}):(function(s,e,t,i){i===void 0&&(i=t),s[i]=e[t]})),Sh=L&&L.__setModuleDefault||(Object.create?(function(s,e){Object.defineProperty(s,"default",{enumerable:!0,value:e})}):function(s,e){s.default=e}),gh=L&&L.__importStar||(function(){var s=function(e){return s=Object.getOwnPropertyNames||function(t){var i=[];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(i[i.length]=r);return i},s(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var i=s(e),r=0;r1)throw new TypeError("gzip, brotli, zstd are mutually exclusive");if(e.gzip&&(typeof e.gzip!="object"&&(e.gzip={}),this.portable&&(e.gzip.portable=!0),this.zip=new ar.Gzip(e.gzip)),e.brotli&&(typeof e.brotli!="object"&&(e.brotli={}),this.zip=new ar.BrotliCompress(e.brotli)),e.zstd&&(typeof e.zstd!="object"&&(e.zstd={}),this.zip=new ar.ZstdCompress(e.zstd)),!this.zip)throw new Error("impossible");let t=this.zip;t.on("data",i=>super.write(i)),t.on("end",()=>super.end()),t.on("drain",()=>this[cr]()),this.on("resume",()=>t.resume())}else this.on("drain",this[cr]);this.noDirRecurse=!!e.noDirRecurse,this.follow=!!e.follow,this.noMtime=!!e.noMtime,e.mtime&&(this.mtime=e.mtime),this.filter=typeof e.filter=="function"?e.filter:()=>!0,this[X]=new Oh.Yallist,this[Q]=0,this.jobs=Number(e.jobs)||4,this[Pt]=!1,this[Tt]=!1}[Nn](e){return super.write(e)}add(e){return this.write(e),this}end(e,t,i){return typeof e=="function"&&(i=e,e=void 0),typeof t=="function"&&(i=t,t=void 0),e&&this.add(e),this[Tt]=!0,this[je](),i&&i(),this}write(e){if(this[Tt])throw new Error("write after end");return typeof e=="string"?this[Ni](e):this[vn](e),this.flowing}[vn](e){let t=(0,ur.normalizeWindowsPath)(Dn.default.resolve(this.cwd,e.path));if(!this.filter(e.path,e))e.resume();else{let i=new Nt(e.path,t);i.entry=new fr.WriteEntryTar(e,this[lr](i)),i.entry.on("end",()=>this[hr](i)),this[Q]+=1,this[X].push(i)}this[je]()}[Ni](e){let t=(0,ur.normalizeWindowsPath)(Dn.default.resolve(this.cwd,e));this[X].push(new Nt(e,t)),this[je]()}[dr](e){e.pending=!0,this[Q]+=1;let t=this.follow?"stat":"lstat";Ii.default[t](e.absolute,(i,r)=>{e.pending=!1,this[Q]-=1,i?this.emit("error",i):this[Pi](e,r)})}[Pi](e,t){if(this.statCache.set(e.absolute,t),e.stat=t,!this.filter(e.path,t))e.ignore=!0;else if(t.isFile()&&t.nlink>1&&!this.linkCache.get(`${t.dev}:${t.ino}`)&&!this.sync)if(e===this[Te])this[Di](e);else{let i=`${t.dev}:${t.ino}`,r=this[Dt].get(i);r?r.push(e):this[Dt].set(i,[e]),e.pendingLink=!0,e.pending=!0}this[je]()}[mr](e){e.pending=!0,this[Q]+=1,Ii.default.readdir(e.absolute,(t,i)=>{if(e.pending=!1,this[Q]-=1,t)return this.emit("error",t);this[Mi](e,i)})}[Mi](e,t){this.readdirCache.set(e.absolute,t),e.readdir=t,this[je]()}[je](){if(!this[Pt]){this[Pt]=!0;for(let e=this[X].head;e&&this[Q]1){let i=`${t.dev}:${t.ino}`,r=this[Dt].get(i);if(r){this[Dt].delete(i);for(let n of r)n.pending=!1,this[Di](n)}}this[je]()}[Di](e){if(e.pending&&e.pendingLink&&e===this[Te]&&(e.pending=!1,e.pendingLink=!1),!e.pending){if(e.entry){e===this[Te]&&!e.piped&&this[Li](e);return}if(!e.stat){let t=this.statCache.get(e.absolute);t?this[Pi](e,t):this[dr](e)}if(e.stat&&!e.ignore){if(!this.noDirRecurse&&e.stat.isDirectory()&&!e.readdir){let t=this.readdirCache.get(e.absolute);if(t?this[Mi](e,t):this[mr](e),!e.readdir)return}if(e.entry=this[Tn](e),!e.entry){e.ignore=!0;return}e===this[Te]&&!e.piped&&this[Li](e)}}}[lr](e){return{onwarn:(t,i,r)=>this.warn(t,i,r),noPax:this.noPax,cwd:this.cwd,absolute:e.absolute,preservePaths:this.preservePaths,maxReadSize:this.maxReadSize,strict:this.strict,portable:this.portable,linkCache:this.linkCache,statCache:this.statCache,noMtime:this.noMtime,mtime:this.mtime,prefix:this.prefix,onWriteEntry:this.onWriteEntry}}[Tn](e){this[Q]+=1;try{return new this[Ai](e.path,this[lr](e)).on("end",()=>this[hr](e)).on("error",i=>this.emit("error",i))}catch(t){this.emit("error",t)}}[cr](){this[Te]&&this[Te].entry&&this[Te].entry.resume()}[Li](e){e.piped=!0,e.readdir&&e.readdir.forEach(r=>{let n=e.path,o=n==="./"?"":n.replace(/\/*$/,"/");this[Ni](o+r)});let t=e.entry,i=this.zip;if(!t)throw new Error("cannot pipe without source");i?t.on("data",r=>{i.write(r)||t.pause()}):t.on("data",r=>{super.write(r)||t.pause()})}pause(){return this.zip&&this.zip.pause(),super.pause()}warn(e,t,i={}){(0,vh.warnMethod)(this,e,t,i)}};L.Pack=Fi;var pr=class extends Fi{sync=!0;constructor(e){super(e),this[Ai]=fr.WriteEntrySync}pause(){}resume(){}[dr](e){let t=this.follow?"statSync":"lstatSync";this[Pi](e,Ii.default[t](e.absolute))}[mr](e){this[Mi](e,Ii.default.readdirSync(e.absolute))}[Li](e){let t=e.entry,i=this.zip;if(e.readdir&&e.readdir.forEach(r=>{let n=e.path,o=n==="./"?"":n.replace(/\/*$/,"/");this[Ni](o+r)}),!t)throw new Error("Cannot pipe without source");i?t.on("data",r=>{i.write(r)}):t.on("data",r=>{super[Nn](r)})}};L.PackSync=pr});var _r=d(ht=>{"use strict";var Th=ht&&ht.__importDefault||function(s){return s&&s.__esModule?s:{default:s}};Object.defineProperty(ht,"__esModule",{value:!0});ht.create=void 0;var Mn=Ke(),Ln=Th(require("node:path")),An=rt(),Dh=Ve(),Bi=Ci(),Ph=(s,e)=>{let t=new Bi.PackSync(s),i=new Mn.WriteStreamSync(s.file,{mode:s.mode||438});t.pipe(i),In(t,e)},Nh=(s,e)=>{let t=new Bi.Pack(s),i=new Mn.WriteStream(s.file,{mode:s.mode||438});t.pipe(i);let r=new Promise((n,o)=>{i.on("error",o),i.on("close",n),t.on("error",o)});return Fn(t,e).catch(n=>t.emit("error",n)),r},In=(s,e)=>{e.forEach(t=>{t.charAt(0)==="@"?(0,An.list)({file:Ln.default.resolve(s.cwd,t.slice(1)),sync:!0,noResume:!0,onReadEntry:i=>s.add(i)}):s.add(t)}),s.end()},Fn=async(s,e)=>{for(let t of e)t.charAt(0)==="@"?await(0,An.list)({file:Ln.default.resolve(String(s.cwd),t.slice(1)),noResume:!0,onReadEntry:i=>{s.add(i)}}):s.add(t);s.end()},Mh=(s,e)=>{let t=new Bi.PackSync(s);return In(t,e),t},Lh=(s,e)=>{let t=new Bi.Pack(s);return Fn(t,e).catch(i=>t.emit("error",i)),t};ht.create=(0,Dh.makeCommand)(Ph,Nh,Mh,Lh,(s,e)=>{if(!e?.length)throw new TypeError("no paths specified to add to archive")})});var Wn=d(lt=>{"use strict";var Ah=lt&<.__importDefault||function(s){return s&&s.__esModule?s:{default:s}};Object.defineProperty(lt,"__esModule",{value:!0});lt.getWriteFlag=void 0;var zn=Ah(require("fs")),Ih=process.env.__FAKE_PLATFORM__||process.platform,kn=Ih==="win32",{O_CREAT:xn,O_NOFOLLOW:Cn,O_TRUNC:jn,O_WRONLY:Un}=zn.default.constants,qn=Number(process.env.__FAKE_FS_O_FILENAME__)||zn.default.constants.UV_FS_O_FILEMAP||0,Fh=kn&&!!qn,Ch=512*1024,Bh=qn|jn|xn|Un,Bn=!kn&&typeof Cn=="number"?Cn|jn|xn|Un:null;lt.getWriteFlag=Bn!==null?()=>Bn:Fh?s=>s"w"});var Gn=d(le=>{"use strict";var Hn=le&&le.__importDefault||function(s){return s&&s.__esModule?s:{default:s}};Object.defineProperty(le,"__esModule",{value:!0});le.chownrSync=le.chownr=void 0;var ki=Hn(require("node:fs")),Mt=Hn(require("node:path")),wr=(s,e,t)=>{try{return ki.default.lchownSync(s,e,t)}catch(i){if(i?.code!=="ENOENT")throw i}},zi=(s,e,t,i)=>{ki.default.lchown(s,e,t,r=>{i(r&&r?.code!=="ENOENT"?r:null)})},zh=(s,e,t,i,r)=>{if(e.isDirectory())(0,le.chownr)(Mt.default.resolve(s,e.name),t,i,n=>{if(n)return r(n);let o=Mt.default.resolve(s,e.name);zi(o,t,i,r)});else{let n=Mt.default.resolve(s,e.name);zi(n,t,i,r)}},kh=(s,e,t,i)=>{ki.default.readdir(s,{withFileTypes:!0},(r,n)=>{if(r){if(r.code==="ENOENT")return i();if(r.code!=="ENOTDIR"&&r.code!=="ENOTSUP")return i(r)}if(r||!n.length)return zi(s,e,t,i);let o=n.length,a=null,h=l=>{if(!a){if(l)return i(a=l);if(--o===0)return zi(s,e,t,i)}};for(let l of n)zh(s,l,e,t,h)})};le.chownr=kh;var xh=(s,e,t,i)=>{e.isDirectory()&&(0,le.chownrSync)(Mt.default.resolve(s,e.name),t,i),wr(Mt.default.resolve(s,e.name),t,i)},jh=(s,e,t)=>{let i;try{i=ki.default.readdirSync(s,{withFileTypes:!0})}catch(r){let n=r;if(n?.code==="ENOENT")return;if(n?.code==="ENOTDIR"||n?.code==="ENOTSUP")return wr(s,e,t);throw n}for(let r of i)xh(s,r,e,t);return wr(s,e,t)};le.chownrSync=jh});var Zn=d(xi=>{"use strict";Object.defineProperty(xi,"__esModule",{value:!0});xi.CwdError=void 0;var yr=class extends Error{path;code;syscall="chdir";constructor(e,t){super(`${t}: Cannot cd into '${e}'`),this.path=e,this.code=t}get name(){return"CwdError"}};xi.CwdError=yr});var br=d(ji=>{"use strict";Object.defineProperty(ji,"__esModule",{value:!0});ji.SymlinkError=void 0;var Er=class extends Error{path;symlink;syscall="symlink";code="TAR_SYMLINK_ERROR";constructor(e,t){super("TAR_SYMLINK_ERROR: Cannot extract through symbolic link"),this.symlink=e,this.path=t}get name(){return"SymlinkError"}};ji.SymlinkError=Er});var Xn=d(De=>{"use strict";var gr=De&&De.__importDefault||function(s){return s&&s.__esModule?s:{default:s}};Object.defineProperty(De,"__esModule",{value:!0});De.mkdirSync=De.mkdir=void 0;var Yn=Gn(),j=gr(require("node:fs")),Uh=gr(require("node:fs/promises")),Ui=gr(require("node:path")),Kn=Zn(),_e=tt(),Vn=br(),qh=(s,e)=>{j.default.stat(s,(t,i)=>{(t||!i.isDirectory())&&(t=new Kn.CwdError(s,t?.code||"ENOTDIR")),e(t)})},Wh=(s,e,t)=>{s=(0,_e.normalizeWindowsPath)(s);let i=e.umask??18,r=e.mode|448,n=(r&i)!==0,o=e.uid,a=e.gid,h=typeof o=="number"&&typeof a=="number"&&(o!==e.processUid||a!==e.processGid),l=e.preserve,c=e.unlink,u=(0,_e.normalizeWindowsPath)(e.cwd),b=(w,P)=>{w?t(w):P&&h?(0,Yn.chownr)(P,o,a,xt=>b(xt)):n?j.default.chmod(s,r,t):t()};if(s===u)return qh(s,b);if(l)return Uh.default.mkdir(s,{mode:r,recursive:!0}).then(w=>b(null,w??void 0),b);let A=(0,_e.normalizeWindowsPath)(Ui.default.relative(u,s)).split("/");Sr(u,A,r,c,u,void 0,b)};De.mkdir=Wh;var Sr=(s,e,t,i,r,n,o)=>{if(e.length===0)return o(null,n);let a=e.shift(),h=(0,_e.normalizeWindowsPath)(Ui.default.resolve(s+"/"+a));j.default.mkdir(h,t,$n(h,e,t,i,r,n,o))},$n=(s,e,t,i,r,n,o)=>a=>{a?j.default.lstat(s,(h,l)=>{if(h)h.path=h.path&&(0,_e.normalizeWindowsPath)(h.path),o(h);else if(l.isDirectory())Sr(s,e,t,i,r,n,o);else if(i)j.default.unlink(s,c=>{if(c)return o(c);j.default.mkdir(s,t,$n(s,e,t,i,r,n,o))});else{if(l.isSymbolicLink())return o(new Vn.SymlinkError(s,s+"/"+e.join("/")));o(a)}}):(n=n||s,Sr(s,e,t,i,r,n,o))},Hh=s=>{let e=!1,t;try{e=j.default.statSync(s).isDirectory()}catch(i){t=i?.code}finally{if(!e)throw new Kn.CwdError(s,t??"ENOTDIR")}},Gh=(s,e)=>{s=(0,_e.normalizeWindowsPath)(s);let t=e.umask??18,i=e.mode|448,r=(i&t)!==0,n=e.uid,o=e.gid,a=typeof n=="number"&&typeof o=="number"&&(n!==e.processUid||o!==e.processGid),h=e.preserve,l=e.unlink,c=(0,_e.normalizeWindowsPath)(e.cwd),u=w=>{w&&a&&(0,Yn.chownrSync)(w,n,o),r&&j.default.chmodSync(s,i)};if(s===c)return Hh(c),u();if(h)return u(j.default.mkdirSync(s,{mode:i,recursive:!0})??void 0);let D=(0,_e.normalizeWindowsPath)(Ui.default.relative(c,s)).split("/"),A;for(let w=D.shift(),P=c;w&&(P+="/"+w);w=D.shift()){P=(0,_e.normalizeWindowsPath)(Ui.default.resolve(P));try{j.default.mkdirSync(P,i),A=A||P}catch{let xt=j.default.lstatSync(P);if(xt.isDirectory())continue;if(l){j.default.unlinkSync(P),j.default.mkdirSync(P,i),A=A||P;continue}else if(xt.isSymbolicLink())return new Vn.SymlinkError(P,P+"/"+D.join("/"))}}return u(A)};De.mkdirSync=Gh});var Jn=d(qi=>{"use strict";Object.defineProperty(qi,"__esModule",{value:!0});qi.normalizeUnicode=void 0;var Rr=Object.create(null),Qn=1e4,ct=new Set,Zh=s=>{ct.has(s)?ct.delete(s):Rr[s]=s.normalize("NFD").toLocaleLowerCase("en").toLocaleUpperCase("en"),ct.add(s);let e=Rr[s],t=ct.size-Qn;if(t>Qn/10){for(let i of ct)if(ct.delete(i),delete Rr[i],--t<=0)break}return e};qi.normalizeUnicode=Zh});var to=d(Wi=>{"use strict";Object.defineProperty(Wi,"__esModule",{value:!0});Wi.PathReservations=void 0;var eo=require("node:path"),Yh=Jn(),Kh=yi(),Vh=process.env.TESTING_TAR_FAKE_PLATFORM||process.platform,$h=Vh==="win32",Xh=s=>s.split("/").slice(0,-1).reduce((t,i)=>{let r=t.at(-1);return r!==void 0&&(i=(0,eo.join)(r,i)),t.push(i||"/"),t},[]),Or=class{#e=new Map;#i=new Map;#s=new Set;reserve(e,t){e=$h?["win32 parallelization disabled"]:e.map(r=>(0,Kh.stripTrailingSlashes)((0,eo.join)((0,Yh.normalizeUnicode)(r))));let i=new Set(e.map(r=>Xh(r)).reduce((r,n)=>r.concat(n)));this.#i.set(t,{dirs:i,paths:e});for(let r of e){let n=this.#e.get(r);n?n.push(t):this.#e.set(r,[t])}for(let r of i){let n=this.#e.get(r);if(!n)this.#e.set(r,[new Set([t])]);else{let o=n.at(-1);o instanceof Set?o.add(t):n.push(new Set([t]))}}return this.#r(t)}#n(e){let t=this.#i.get(e);if(!t)throw new Error("function does not have any path reservations");return{paths:t.paths.map(i=>this.#e.get(i)),dirs:[...t.dirs].map(i=>this.#e.get(i))}}check(e){let{paths:t,dirs:i}=this.#n(e);return t.every(r=>r&&r[0]===e)&&i.every(r=>r&&r[0]instanceof Set&&r[0].has(e))}#r(e){return this.#s.has(e)||!this.check(e)?!1:(this.#s.add(e),e(()=>this.#t(e)),!0)}#t(e){if(!this.#s.has(e))return!1;let t=this.#i.get(e);if(!t)throw new Error("invalid reservation");let{paths:i,dirs:r}=t,n=new Set;for(let o of i){let a=this.#e.get(o);if(!a||a?.[0]!==e)continue;let h=a[1];if(!h){this.#e.delete(o);continue}if(a.shift(),typeof h=="function")n.add(h);else for(let l of h)n.add(l)}for(let o of r){let a=this.#e.get(o),h=a?.[0];if(!(!a||!(h instanceof Set)))if(h.size===1&&a.length===1){this.#e.delete(o);continue}else if(h.size===1){a.shift();let l=a[0];typeof l=="function"&&n.add(l)}else h.delete(e)}return this.#s.delete(e),n.forEach(o=>this.#r(o)),!0}};Wi.PathReservations=Or});var io=d(Hi=>{"use strict";Object.defineProperty(Hi,"__esModule",{value:!0});Hi.umask=void 0;var Qh=()=>process.umask();Hi.umask=Qh});var Cr=d(k=>{"use strict";var Jh=k&&k.__createBinding||(Object.create?(function(s,e,t,i){i===void 0&&(i=t);var r=Object.getOwnPropertyDescriptor(e,t);(!r||("get"in r?!e.__esModule:r.writable||r.configurable))&&(r={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(s,i,r)}):(function(s,e,t,i){i===void 0&&(i=t),s[i]=e[t]})),el=k&&k.__setModuleDefault||(Object.create?(function(s,e){Object.defineProperty(s,"default",{enumerable:!0,value:e})}):function(s,e){s.default=e}),fo=k&&k.__importStar||(function(){var s=function(e){return s=Object.getOwnPropertyNames||function(t){var i=[];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(i[i.length]=r);return i},s(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var i=s(e),r=0;r{if(!zt)return m.default.unlink(s,e);let t=s+".DELETE."+(0,mo.randomBytes)(16).toString("hex");m.default.rename(s,t,i=>{if(i)return e(i);m.default.unlink(t,e)})},cl=s=>{if(!zt)return m.default.unlinkSync(s);let e=s+".DELETE."+(0,mo.randomBytes)(16).toString("hex");m.default.renameSync(s,e),m.default.unlinkSync(e)},uo=(s,e,t)=>s!==void 0&&s===s>>>0?s:e!==void 0&&e===e>>>0?e:t,Yi=class extends sl.Parser{[Tr]=!1;[Bt]=!1;[Gi]=0;reservations=new nl.PathReservations;transform;writable=!0;readable=!1;uid;gid;setOwner;preserveOwner;processGid;processUid;maxDepth;forceChown;win32;newer;keep;noMtime;preservePaths;unlink;cwd;strip;processUmask;umask;dmode;fmode;chmod;constructor(e={}){if(e.ondone=()=>{this[Tr]=!0,this[Dr]()},super(e),this.transform=e.transform,this.chmod=!!e.chmod,typeof e.uid=="number"||typeof e.gid=="number"){if(typeof e.uid!="number"||typeof e.gid!="number")throw new TypeError("cannot set owner without number uid and gid");if(e.preserveOwner)throw new TypeError("cannot preserve owner in archive and also set owner explicitly");this.uid=e.uid,this.gid=e.gid,this.setOwner=!0}else this.uid=void 0,this.gid=void 0,this.setOwner=!1;this.preserveOwner=e.preserveOwner===void 0&&typeof e.uid!="number"?process.getuid?.()===0:!!e.preserveOwner,this.processUid=(this.preserveOwner||this.setOwner)&&process.getuid?process.getuid():void 0,this.processGid=(this.preserveOwner||this.setOwner)&&process.getgid?process.getgid():void 0,this.maxDepth=typeof e.maxDepth=="number"?e.maxDepth:hl,this.forceChown=e.forceChown===!0,this.win32=!!e.win32||zt,this.newer=!!e.newer,this.keep=!!e.keep,this.noMtime=!!e.noMtime,this.preservePaths=!!e.preservePaths,this.unlink=!!e.unlink,this.cwd=(0,U.normalizeWindowsPath)(g.default.resolve(e.cwd||process.cwd())),this.strip=Number(e.strip)||0,this.processUmask=this.chmod?typeof e.processUmask=="number"?e.processUmask:(0,ol.umask)():0,this.umask=typeof e.umask=="number"?e.umask:this.processUmask,this.dmode=e.dmode||511&~this.umask,this.fmode=e.fmode||438&~this.umask,this.on("entry",t=>this[ro](t))}warn(e,t,i={}){return(e==="TAR_BAD_ARCHIVE"||e==="TAR_ABORT")&&(i.recoverable=!1),super.warn(e,t,i)}[Dr](){this[Tr]&&this[Gi]===0&&(this.emit("prefinish"),this.emit("finish"),this.emit("end"))}[vr](e,t){let i=e[t],{type:r}=e;if(!i||this.preservePaths)return!0;let[n,o]=(0,rl.stripAbsolutePath)(i),a=o.replaceAll(/\\/g,"/").split("/");if(a.includes("..")||zt&&/^[a-z]:\.\.$/i.test(a[0]??"")){if(t==="path"||r==="Link")return this.warn("TAR_ENTRY_ERROR",`${t} contains '..'`,{entry:e,[t]:i}),!1;let h=g.default.posix.dirname(e.path),l=g.default.posix.normalize(g.default.posix.join(h,a.join("/")));if(l.startsWith("../")||l==="..")return this.warn("TAR_ENTRY_ERROR",`${t} escapes extraction directory`,{entry:e,[t]:i}),!1}return n&&(e[t]=String(o),this.warn("TAR_ENTRY_INFO",`stripping ${n} from absolute ${t}`,{entry:e,[t]:i})),!0}[lo](e){let t=(0,U.normalizeWindowsPath)(e.path),i=t.split("/");if(this.strip){if(i.length=this.strip)e.linkpath=r.slice(this.strip).join("/");else return!1}i.splice(0,this.strip),e.path=i.join("/")}if(isFinite(this.maxDepth)&&i.length>this.maxDepth)return this.warn("TAR_ENTRY_ERROR","path excessively deep",{entry:e,path:t,depth:i.length,maxDepth:this.maxDepth}),!1;if(!this[vr](e,"path")||!this[vr](e,"linkpath"))return!1;if(e.absolute=g.default.isAbsolute(e.path)?(0,U.normalizeWindowsPath)(g.default.resolve(e.path)):(0,U.normalizeWindowsPath)(g.default.resolve(this.cwd,e.path)),!this.preservePaths&&typeof e.absolute=="string"&&e.absolute.indexOf(this.cwd+"/")!==0&&e.absolute!==this.cwd)return this.warn("TAR_ENTRY_ERROR","path escaped extraction target",{entry:e,path:(0,U.normalizeWindowsPath)(e.path),resolvedPath:e.absolute,cwd:this.cwd}),!1;if(e.absolute===this.cwd&&e.type!=="Directory"&&e.type!=="GNUDumpDir")return!1;if(this.win32){let{root:r}=g.default.win32.parse(String(e.absolute));e.absolute=r+so.encode(String(e.absolute).slice(r.length));let{root:n}=g.default.win32.parse(e.path);e.path=n+so.encode(e.path.slice(n.length))}return!0}[ro](e){if(!this[lo](e))return e.resume();switch(il.default.equal(typeof e.absolute,"string"),e.type){case"Directory":case"GNUDumpDir":e.mode&&(e.mode=e.mode|448);case"File":case"OldFile":case"ContiguousFile":case"Link":case"SymbolicLink":return this[Pr](e);default:return this[ho](e)}}[T](e,t){e.name==="CwdError"?this.emit("error",e):(this.warn("TAR_ENTRY_ERROR",e,{entry:t}),this[ut](),t.resume())}[Pe](e,t,i){(0,_o.mkdir)((0,U.normalizeWindowsPath)(e),{uid:this.uid,gid:this.gid,processUid:this.processUid,processGid:this.processGid,umask:this.processUmask,preserve:this.preservePaths,unlink:this.unlink,cwd:this.cwd,mode:t},i)}[It](e){return this.forceChown||this.preserveOwner&&(typeof e.uid=="number"&&e.uid!==this.processUid||typeof e.gid=="number"&&e.gid!==this.processGid)||typeof this.uid=="number"&&this.uid!==this.processUid||typeof this.gid=="number"&&this.gid!==this.processGid}[Ft](e){return uo(this.uid,e.uid,this.processUid)}[Ct](e){return uo(this.gid,e.gid,this.processGid)}[Mr](e,t){let i=typeof e.mode=="number"?e.mode&4095:this.fmode,r=new tl.WriteStream(String(e.absolute),{flags:(0,po.getWriteFlag)(e.size),mode:i,autoClose:!1});r.on("error",h=>{r.fd&&m.default.close(r.fd,()=>{}),r.write=()=>!0,this[T](h,e),t()});let n=1,o=h=>{if(h){r.fd&&m.default.close(r.fd,()=>{}),this[T](h,e),t();return}--n===0&&r.fd!==void 0&&m.default.close(r.fd,l=>{l?this[T](l,e):this[ut](),t()})};r.on("finish",()=>{let h=String(e.absolute),l=r.fd;if(typeof l=="number"&&e.mtime&&!this.noMtime){n++;let c=e.atime||new Date,u=e.mtime;m.default.futimes(l,c,u,b=>b?m.default.utimes(h,c,u,D=>o(D&&b)):o())}if(typeof l=="number"&&this[It](e)){n++;let c=this[Ft](e),u=this[Ct](e);typeof c=="number"&&typeof u=="number"&&m.default.fchown(l,c,u,b=>b?m.default.chown(h,c,u,D=>o(D&&b)):o())}o()});let a=this.transform&&this.transform(e)||e;a!==e&&(a.on("error",h=>{this[T](h,e),t()}),e.pipe(a)),a.pipe(r)}[Lr](e,t){let i=typeof e.mode=="number"?e.mode&4095:this.dmode;this[Pe](String(e.absolute),i,r=>{if(r){this[T](r,e),t();return}let n=1,o=()=>{--n===0&&(t(),this[ut](),e.resume())};e.mtime&&!this.noMtime&&(n++,m.default.utimes(String(e.absolute),e.atime||new Date,e.mtime,o)),this[It](e)&&(n++,m.default.chown(String(e.absolute),Number(this[Ft](e)),Number(this[Ct](e)),o)),o()})}[ho](e){e.unsupported=!0,this.warn("TAR_ENTRY_UNSUPPORTED",`unsupported entry type: ${e.type}`,{entry:e}),e.resume()}[oo](e,t){let i=(0,U.normalizeWindowsPath)(g.default.relative(this.cwd,g.default.resolve(g.default.dirname(String(e.absolute)),String(e.linkpath)))).split("/");this[At](e,this.cwd,i,()=>this[Zi](e,String(e.linkpath),"symlink",t),r=>{this[T](r,e),t()})}[ao](e,t){let i=(0,U.normalizeWindowsPath)(g.default.resolve(this.cwd,String(e.linkpath))),r=(0,U.normalizeWindowsPath)(String(e.linkpath)).split("/");this[At](e,this.cwd,r,()=>this[Zi](e,i,"link",t),n=>{this[T](n,e),t()})}[At](e,t,i,r,n){let o=i.shift();if(this.preservePaths||o===void 0)return r();let a=g.default.resolve(t,o);m.default.lstat(a,(h,l)=>{if(h)return r();if(l?.isSymbolicLink())return n(new wo.SymlinkError(a,g.default.resolve(a,i.join("/"))));this[At](e,a,i,r,n)})}[co](){this[Gi]++}[ut](){this[Gi]--,this[Dr]()}[Ar](e){this[ut](),e.resume()}[Nr](e,t){return e.type==="File"&&!this.unlink&&t.isFile()&&t.nlink<=1&&!zt}[Pr](e){this[co]();let t=[e.path];e.linkpath&&t.push(e.linkpath),this.reservations.reserve(t,i=>this[no](e,i))}[no](e,t){let i=a=>{t(a)},r=()=>{this[Pe](this.cwd,this.dmode,a=>{if(a){this[T](a,e),i();return}this[Bt]=!0,n()})},n=()=>{if(e.absolute!==this.cwd){let a=(0,U.normalizeWindowsPath)(g.default.dirname(String(e.absolute)));if(a!==this.cwd)return this[Pe](a,this.dmode,h=>{if(h){this[T](h,e),i();return}o()})}o()},o=()=>{m.default.lstat(String(e.absolute),(a,h)=>{if(h&&(this.keep||this.newer&&h.mtime>(e.mtime??h.mtime))){this[Ar](e),i();return}if(a||this[Nr](e,h))return this[G](null,e,i);if(h.isDirectory()){if(e.type==="Directory"){let l=this.chmod&&e.mode&&(h.mode&4095)!==e.mode,c=u=>this[G](u??null,e,i);return l?m.default.chmod(String(e.absolute),Number(e.mode),c):c()}if(e.absolute!==this.cwd)return m.default.rmdir(String(e.absolute),l=>this[G](l??null,e,i))}if(e.absolute===this.cwd)return this[G](null,e,i);ll(String(e.absolute),l=>this[G](l??null,e,i))})};this[Bt]?n():r()}[G](e,t,i){if(e){this[T](e,t),i();return}switch(t.type){case"File":case"OldFile":case"ContiguousFile":return this[Mr](t,i);case"Link":return this[ao](t,i);case"SymbolicLink":return this[oo](t,i);case"Directory":case"GNUDumpDir":return this[Lr](t,i)}}[Zi](e,t,i,r){m.default[i](t,String(e.absolute),n=>{n?this[T](n,e):(this[ut](),e.resume()),r()})}};k.Unpack=Yi;var Lt=s=>{try{return[null,s()]}catch(e){return[e,null]}},Ir=class extends Yi{sync=!0;[G](e,t){return super[G](e,t,()=>{})}[Pr](e){if(!this[Bt]){let n=this[Pe](this.cwd,this.dmode);if(n)return this[T](n,e);this[Bt]=!0}if(e.absolute!==this.cwd){let n=(0,U.normalizeWindowsPath)(g.default.dirname(String(e.absolute)));if(n!==this.cwd){let o=this[Pe](n,this.dmode);if(o)return this[T](o,e)}}let[t,i]=Lt(()=>m.default.lstatSync(String(e.absolute)));if(i&&(this.keep||this.newer&&i.mtime>(e.mtime??i.mtime)))return this[Ar](e);if(t||this[Nr](e,i))return this[G](null,e);if(i.isDirectory()){if(e.type==="Directory"){let o=this.chmod&&e.mode&&(i.mode&4095)!==e.mode,[a]=o?Lt(()=>{m.default.chmodSync(String(e.absolute),Number(e.mode))}):[];return this[G](a,e)}let[n]=Lt(()=>m.default.rmdirSync(String(e.absolute)));this[G](n,e)}let[r]=e.absolute===this.cwd?[]:Lt(()=>cl(String(e.absolute)));this[G](r,e)}[Mr](e,t){let i=typeof e.mode=="number"?e.mode&4095:this.fmode,r=a=>{let h;try{m.default.closeSync(n)}catch(l){h=l}(a||h)&&this[T](a||h,e),t()},n;try{n=m.default.openSync(String(e.absolute),(0,po.getWriteFlag)(e.size),i)}catch(a){return r(a)}let o=this.transform&&this.transform(e)||e;o!==e&&(o.on("error",a=>this[T](a,e)),e.pipe(o)),o.on("data",a=>{try{m.default.writeSync(n,a,0,a.length)}catch(h){r(h)}}),o.on("end",()=>{let a=null;if(e.mtime&&!this.noMtime){let h=e.atime||new Date,l=e.mtime;try{m.default.futimesSync(n,h,l)}catch(c){try{m.default.utimesSync(String(e.absolute),h,l)}catch{a=c}}}if(this[It](e)){let h=this[Ft](e),l=this[Ct](e);try{m.default.fchownSync(n,Number(h),Number(l))}catch(c){try{m.default.chownSync(String(e.absolute),Number(h),Number(l))}catch{a=a||c}}}r(a)})}[Lr](e,t){let i=typeof e.mode=="number"?e.mode&4095:this.dmode,r=this[Pe](String(e.absolute),i);if(r){this[T](r,e),t();return}if(e.mtime&&!this.noMtime)try{m.default.utimesSync(String(e.absolute),e.atime||new Date,e.mtime)}catch{}if(this[It](e))try{m.default.chownSync(String(e.absolute),Number(this[Ft](e)),Number(this[Ct](e)))}catch{}t(),e.resume()}[Pe](e,t){try{return(0,_o.mkdirSync)((0,U.normalizeWindowsPath)(e),{uid:this.uid,gid:this.gid,processUid:this.processUid,processGid:this.processGid,umask:this.processUmask,preserve:this.preservePaths,unlink:this.unlink,cwd:this.cwd,mode:t})}catch(i){return i}}[At](e,t,i,r,n){if(this.preservePaths||i.length===0)return r();let o=t;for(let a of i){o=g.default.resolve(o,a);let[h,l]=Lt(()=>m.default.lstatSync(o));if(h)return r();if(l.isSymbolicLink())return n(new wo.SymlinkError(o,g.default.resolve(t,i.join("/"))))}r()}[Zi](e,t,i,r){let n=`${i}Sync`;try{m.default[n](t,String(e.absolute)),r(),e.resume()}catch(o){return this[T](o,e)}}};k.UnpackSync=Ir});var Br=d(Z=>{"use strict";var ul=Z&&Z.__createBinding||(Object.create?(function(s,e,t,i){i===void 0&&(i=t);var r=Object.getOwnPropertyDescriptor(e,t);(!r||("get"in r?!e.__esModule:r.writable||r.configurable))&&(r={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(s,i,r)}):(function(s,e,t,i){i===void 0&&(i=t),s[i]=e[t]})),fl=Z&&Z.__setModuleDefault||(Object.create?(function(s,e){Object.defineProperty(s,"default",{enumerable:!0,value:e})}):function(s,e){s.default=e}),dl=Z&&Z.__importStar||(function(){var s=function(e){return s=Object.getOwnPropertyNames||function(t){var i=[];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(i[i.length]=r);return i},s(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var i=s(e),r=0;r{let e=new Ki.UnpackSync(s),t=s.file,i=Eo.default.statSync(t),r=s.maxReadSize||16*1024*1024;new yo.ReadStreamSync(t,{readSize:r,size:i.size}).pipe(e)},yl=(s,e)=>{let t=new Ki.Unpack(s),i=s.maxReadSize||16*1024*1024,r=s.file;return new Promise((o,a)=>{t.on("error",a),t.on("close",o),Eo.default.stat(r,(h,l)=>{if(h)a(h);else{let c=new yo.ReadStream(r,{readSize:i,size:l.size});c.on("error",a),c.pipe(t)}})})};Z.extract=(0,_l.makeCommand)(wl,yl,s=>new Ki.UnpackSync(s),s=>new Ki.Unpack(s),(s,e)=>{e?.length&&(0,pl.filesFilter)(s,e)})});var Vi=d(ft=>{"use strict";var bo=ft&&ft.__importDefault||function(s){return s&&s.__esModule?s:{default:s}};Object.defineProperty(ft,"__esModule",{value:!0});ft.replace=void 0;var So=Ke(),q=bo(require("node:fs")),go=bo(require("node:path")),Ro=et(),Oo=rt(),El=Ve(),bl=Qt(),vo=Ci(),Sl=(s,e)=>{let t=new vo.PackSync(s),i=!0,r,n;try{try{r=q.default.openSync(s.file,"r+")}catch(h){if(h?.code==="ENOENT")r=q.default.openSync(s.file,"w+");else throw h}let o=q.default.fstatSync(r),a=Buffer.alloc(512);e:for(n=0;no.size)break;n+=l,s.mtimeCache&&h.mtime&&s.mtimeCache.set(String(h.path),h.mtime)}i=!1,gl(s,t,n,r,e)}finally{if(i)try{q.default.closeSync(r)}catch{}}},gl=(s,e,t,i,r)=>{let n=new So.WriteStreamSync(s.file,{fd:i,start:t});e.pipe(n),Ol(e,r)},Rl=(s,e)=>{e=Array.from(e);let t=new vo.Pack(s),i=(n,o,a)=>{let h=(D,A)=>{D?q.default.close(n,w=>a(D)):a(null,A)},l=0;if(o===0)return h(null,0);let c=0,u=Buffer.alloc(512),b=(D,A)=>{if(D||A===void 0)return h(D);if(c+=A,c<512&&A)return q.default.read(n,u,c,u.length-c,l+c,b);if(l===0&&u[0]===31&&u[1]===139)return h(new Error("cannot append to compressed archives"));if(c<512)return h(null,l);let w=new Ro.Header(u);if(!w.cksumValid)return h(null,l);let P=512*Math.ceil((w.size??0)/512);if(l+P+512>o||(l+=P+512,l>=o))return h(null,l);s.mtimeCache&&w.mtime&&s.mtimeCache.set(String(w.path),w.mtime),c=0,q.default.read(n,u,0,512,l,b)};q.default.read(n,u,0,512,l,b)};return new Promise((n,o)=>{t.on("error",o);let a="r+",h=(l,c)=>{if(l&&l.code==="ENOENT"&&a==="r+")return a="w+",q.default.open(s.file,a,h);if(l||!c)return o(l);q.default.fstat(c,(u,b)=>{if(u)return q.default.close(c,()=>o(u));i(c,b.size,(D,A)=>{if(D)return o(D);let w=new So.WriteStream(s.file,{fd:c,start:A});t.pipe(w),w.on("error",o),w.on("close",n),vl(t,e)})})};q.default.open(s.file,a,h)})},Ol=(s,e)=>{e.forEach(t=>{t.charAt(0)==="@"?(0,Oo.list)({file:go.default.resolve(s.cwd,t.slice(1)),sync:!0,noResume:!0,onReadEntry:i=>s.add(i)}):s.add(t)}),s.end()},vl=async(s,e)=>{for(let t of e)t.charAt(0)==="@"?await(0,Oo.list)({file:go.default.resolve(String(s.cwd),t.slice(1)),noResume:!0,onReadEntry:i=>s.add(i)}):s.add(t);s.end()};ft.replace=(0,El.makeCommand)(Sl,Rl,()=>{throw new TypeError("file is required")},()=>{throw new TypeError("file is required")},(s,e)=>{if(!(0,bl.isFile)(s))throw new TypeError("file is required");if(s.gzip||s.brotli||s.zstd||s.file.endsWith(".br")||s.file.endsWith(".tbr"))throw new TypeError("cannot append to compressed archives");if(!e?.length)throw new TypeError("no paths specified to add/replace")})});var zr=d($i=>{"use strict";Object.defineProperty($i,"__esModule",{value:!0});$i.update=void 0;var Tl=Ve(),kt=Vi();$i.update=(0,Tl.makeCommand)(kt.replace.syncFile,kt.replace.asyncFile,kt.replace.syncNoFile,kt.replace.asyncNoFile,(s,e=[])=>{kt.replace.validate?.(s,e),Dl(s)});var Dl=s=>{let e=s.filter;s.mtimeCache||(s.mtimeCache=new Map),s.filter=e?(t,i)=>e(t,i)&&!((s.mtimeCache?.get(t)??i.mtime??0)>(i.mtime??0)):(t,i)=>!((s.mtimeCache?.get(t)??i.mtime??0)>(i.mtime??0))}});var To=exports&&exports.__createBinding||(Object.create?(function(s,e,t,i){i===void 0&&(i=t);var r=Object.getOwnPropertyDescriptor(e,t);(!r||("get"in r?!e.__esModule:r.writable||r.configurable))&&(r={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(s,i,r)}):(function(s,e,t,i){i===void 0&&(i=t),s[i]=e[t]})),Pl=exports&&exports.__setModuleDefault||(Object.create?(function(s,e){Object.defineProperty(s,"default",{enumerable:!0,value:e})}):function(s,e){s.default=e}),Y=exports&&exports.__exportStar||function(s,e){for(var t in s)t!=="default"&&!Object.prototype.hasOwnProperty.call(e,t)&&To(e,s,t)},Nl=exports&&exports.__importStar||(function(){var s=function(e){return s=Object.getOwnPropertyNames||function(t){var i=[];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(i[i.length]=r);return i},s(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var i=s(e),r=0;r { const filesFilter = (opt, files) => { const map = new Map(files.map(f => [(0, strip_trailing_slashes_js_1.stripTrailingSlashes)(f), true])); const filter = opt.filter; - const mapHas = (file, r = '') => { + // limit recursion to 100 levels + const MAX = 100; + const mapHas = (file, r = '', depth = 0) => { + /* c8 ignore start - excessive caution */ + if (depth >= MAX) { + map.set(file, false); + return false; + } + /* c8 ignore stop */ const root = r || (0, path_1.parse)(file).root || '.'; let ret; if (file === root) ret = false; else { const m = map.get(file); - ret = m !== undefined ? m : mapHas((0, path_1.dirname)(file), root); + ret = m !== undefined ? m : mapHas((0, path_1.dirname)(file), root, depth + 1); } map.set(file, ret); return ret; diff --git a/deps/npm/node_modules/tar/dist/commonjs/parse.js b/deps/npm/node_modules/tar/dist/commonjs/parse.js index 2968e861ee68..6ab1e333458c 100644 --- a/deps/npm/node_modules/tar/dist/commonjs/parse.js +++ b/deps/npm/node_modules/tar/dist/commonjs/parse.js @@ -376,6 +376,16 @@ class Parser extends events_1.EventEmitter { if (this[ABORTED]) { return; } + if (this[UNZIP]) { + // fully nerf the decompressor and close its underlying binding + const u = this[UNZIP]; + /* c8 ignore start */ + u.write = () => true; + u.end = () => u; + u.emit = () => false; + /* c8 ignore stop */ + u.destroy?.(); + } this[ABORTED] = true; this.emit('abort', error); // always throws, even in non-strict mode diff --git a/deps/npm/node_modules/tar/dist/esm/index.min.js b/deps/npm/node_modules/tar/dist/esm/index.min.js index bf4036b4115e..9d9044ce85e3 100644 --- a/deps/npm/node_modules/tar/dist/esm/index.min.js +++ b/deps/npm/node_modules/tar/dist/esm/index.min.js @@ -1,4 +1,4 @@ -var zr=Object.defineProperty;var Ur=(s,t)=>{for(var e in t)zr(s,e,{get:t[e],enumerable:!0})};import Qr from"events";import I from"fs";import{EventEmitter as Di}from"node:events";import Cs from"node:stream";import{StringDecoder as Hr}from"node:string_decoder";var Ds=typeof process=="object"&&process?process:{stdout:null,stderr:null},Wr=s=>!!s&&typeof s=="object"&&(s instanceof A||s instanceof Cs||Gr(s)||Zr(s)),Gr=s=>!!s&&typeof s=="object"&&s instanceof Di&&typeof s.pipe=="function"&&s.pipe!==Cs.Writable.prototype.pipe,Zr=s=>!!s&&typeof s=="object"&&s instanceof Di&&typeof s.write=="function"&&typeof s.end=="function",Q=Symbol("EOF"),J=Symbol("maybeEmitEnd"),nt=Symbol("emittedEnd"),De=Symbol("emittingEnd"),qt=Symbol("emittedError"),Ne=Symbol("closed"),Ns=Symbol("read"),Ae=Symbol("flush"),As=Symbol("flushChunk"),z=Symbol("encoding"),Mt=Symbol("decoder"),g=Symbol("flowing"),Qt=Symbol("paused"),Bt=Symbol("resume"),b=Symbol("buffer"),N=Symbol("pipes"),_=Symbol("bufferLength"),bi=Symbol("bufferPush"),Ie=Symbol("bufferShift"),L=Symbol("objectMode"),w=Symbol("destroyed"),_i=Symbol("error"),Oi=Symbol("emitData"),Is=Symbol("emitEnd"),Ti=Symbol("emitEnd2"),Z=Symbol("async"),xi=Symbol("abort"),Ce=Symbol("aborted"),Jt=Symbol("signal"),Rt=Symbol("dataListeners"),C=Symbol("discarded"),jt=s=>Promise.resolve().then(s),Yr=s=>s(),Kr=s=>s==="end"||s==="finish"||s==="prefinish",Vr=s=>s instanceof ArrayBuffer||!!s&&typeof s=="object"&&s.constructor&&s.constructor.name==="ArrayBuffer"&&s.byteLength>=0,$r=s=>!Buffer.isBuffer(s)&&ArrayBuffer.isView(s),Fe=class{src;dest;opts;ondrain;constructor(t,e,i){this.src=t,this.dest=e,this.opts=i,this.ondrain=()=>t[Bt](),this.dest.on("drain",this.ondrain)}unpipe(){this.dest.removeListener("drain",this.ondrain)}proxyErrors(t){}end(){this.unpipe(),this.opts.end&&this.dest.end()}},Li=class extends Fe{unpipe(){this.src.removeListener("error",this.proxyErrors),super.unpipe()}constructor(t,e,i){super(t,e,i),this.proxyErrors=r=>this.dest.emit("error",r),t.on("error",this.proxyErrors)}},Xr=s=>!!s.objectMode,qr=s=>!s.objectMode&&!!s.encoding&&s.encoding!=="buffer",A=class extends Di{[g]=!1;[Qt]=!1;[N]=[];[b]=[];[L];[z];[Z];[Mt];[Q]=!1;[nt]=!1;[De]=!1;[Ne]=!1;[qt]=null;[_]=0;[w]=!1;[Jt];[Ce]=!1;[Rt]=0;[C]=!1;writable=!0;readable=!0;constructor(...t){let e=t[0]||{};if(super(),e.objectMode&&typeof e.encoding=="string")throw new TypeError("Encoding and objectMode may not be used together");Xr(e)?(this[L]=!0,this[z]=null):qr(e)?(this[z]=e.encoding,this[L]=!1):(this[L]=!1,this[z]=null),this[Z]=!!e.async,this[Mt]=this[z]?new Hr(this[z]):null,e&&e.debugExposeBuffer===!0&&Object.defineProperty(this,"buffer",{get:()=>this[b]}),e&&e.debugExposePipes===!0&&Object.defineProperty(this,"pipes",{get:()=>this[N]});let{signal:i}=e;i&&(this[Jt]=i,i.aborted?this[xi]():i.addEventListener("abort",()=>this[xi]()))}get bufferLength(){return this[_]}get encoding(){return this[z]}set encoding(t){throw new Error("Encoding must be set at instantiation time")}setEncoding(t){throw new Error("Encoding must be set at instantiation time")}get objectMode(){return this[L]}set objectMode(t){throw new Error("objectMode must be set at instantiation time")}get async(){return this[Z]}set async(t){this[Z]=this[Z]||!!t}[xi](){this[Ce]=!0,this.emit("abort",this[Jt]?.reason),this.destroy(this[Jt]?.reason)}get aborted(){return this[Ce]}set aborted(t){}write(t,e,i){if(this[Ce])return!1;if(this[Q])throw new Error("write after end");if(this[w])return this.emit("error",Object.assign(new Error("Cannot call write after a stream was destroyed"),{code:"ERR_STREAM_DESTROYED"})),!0;typeof e=="function"&&(i=e,e="utf8"),e||(e="utf8");let r=this[Z]?jt:Yr;if(!this[L]&&!Buffer.isBuffer(t)){if($r(t))t=Buffer.from(t.buffer,t.byteOffset,t.byteLength);else if(Vr(t))t=Buffer.from(t);else if(typeof t!="string")throw new Error("Non-contiguous data written to non-objectMode stream")}return this[L]?(this[g]&&this[_]!==0&&this[Ae](!0),this[g]?this.emit("data",t):this[bi](t),this[_]!==0&&this.emit("readable"),i&&r(i),this[g]):t.length?(typeof t=="string"&&!(e===this[z]&&!this[Mt]?.lastNeed)&&(t=Buffer.from(t,e)),Buffer.isBuffer(t)&&this[z]&&(t=this[Mt].write(t)),this[g]&&this[_]!==0&&this[Ae](!0),this[g]?this.emit("data",t):this[bi](t),this[_]!==0&&this.emit("readable"),i&&r(i),this[g]):(this[_]!==0&&this.emit("readable"),i&&r(i),this[g])}read(t){if(this[w])return null;if(this[C]=!1,this[_]===0||t===0||t&&t>this[_])return this[J](),null;this[L]&&(t=null),this[b].length>1&&!this[L]&&(this[b]=[this[z]?this[b].join(""):Buffer.concat(this[b],this[_])]);let e=this[Ns](t||null,this[b][0]);return this[J](),e}[Ns](t,e){if(this[L])this[Ie]();else{let i=e;t===i.length||t===null?this[Ie]():typeof i=="string"?(this[b][0]=i.slice(t),e=i.slice(0,t),this[_]-=t):(this[b][0]=i.subarray(t),e=i.subarray(0,t),this[_]-=t)}return this.emit("data",e),!this[b].length&&!this[Q]&&this.emit("drain"),e}end(t,e,i){return typeof t=="function"&&(i=t,t=void 0),typeof e=="function"&&(i=e,e="utf8"),t!==void 0&&this.write(t,e),i&&this.once("end",i),this[Q]=!0,this.writable=!1,(this[g]||!this[Qt])&&this[J](),this}[Bt](){this[w]||(!this[Rt]&&!this[N].length&&(this[C]=!0),this[Qt]=!1,this[g]=!0,this.emit("resume"),this[b].length?this[Ae]():this[Q]?this[J]():this.emit("drain"))}resume(){return this[Bt]()}pause(){this[g]=!1,this[Qt]=!0,this[C]=!1}get destroyed(){return this[w]}get flowing(){return this[g]}get paused(){return this[Qt]}[bi](t){this[L]?this[_]+=1:this[_]+=t.length,this[b].push(t)}[Ie](){return this[L]?this[_]-=1:this[_]-=this[b][0].length,this[b].shift()}[Ae](t=!1){do;while(this[As](this[Ie]())&&this[b].length);!t&&!this[b].length&&!this[Q]&&this.emit("drain")}[As](t){return this.emit("data",t),this[g]}pipe(t,e){if(this[w])return t;this[C]=!1;let i=this[nt];return e=e||{},t===Ds.stdout||t===Ds.stderr?e.end=!1:e.end=e.end!==!1,e.proxyErrors=!!e.proxyErrors,i?e.end&&t.end():(this[N].push(e.proxyErrors?new Li(this,t,e):new Fe(this,t,e)),this[Z]?jt(()=>this[Bt]()):this[Bt]()),t}unpipe(t){let e=this[N].find(i=>i.dest===t);e&&(this[N].length===1?(this[g]&&this[Rt]===0&&(this[g]=!1),this[N]=[]):this[N].splice(this[N].indexOf(e),1),e.unpipe())}addListener(t,e){return this.on(t,e)}on(t,e){let i=super.on(t,e);if(t==="data")this[C]=!1,this[Rt]++,!this[N].length&&!this[g]&&this[Bt]();else if(t==="readable"&&this[_]!==0)super.emit("readable");else if(Kr(t)&&this[nt])super.emit(t),this.removeAllListeners(t);else if(t==="error"&&this[qt]){let r=e;this[Z]?jt(()=>r.call(this,this[qt])):r.call(this,this[qt])}return i}removeListener(t,e){return this.off(t,e)}off(t,e){let i=super.off(t,e);return t==="data"&&(this[Rt]=this.listeners("data").length,this[Rt]===0&&!this[C]&&!this[N].length&&(this[g]=!1)),i}removeAllListeners(t){let e=super.removeAllListeners(t);return(t==="data"||t===void 0)&&(this[Rt]=0,!this[C]&&!this[N].length&&(this[g]=!1)),e}get emittedEnd(){return this[nt]}[J](){!this[De]&&!this[nt]&&!this[w]&&this[b].length===0&&this[Q]&&(this[De]=!0,this.emit("end"),this.emit("prefinish"),this.emit("finish"),this[Ne]&&this.emit("close"),this[De]=!1)}emit(t,...e){let i=e[0];if(t!=="error"&&t!=="close"&&t!==w&&this[w])return!1;if(t==="data")return!this[L]&&!i?!1:this[Z]?(jt(()=>this[Oi](i)),!0):this[Oi](i);if(t==="end")return this[Is]();if(t==="close"){if(this[Ne]=!0,!this[nt]&&!this[w])return!1;let n=super.emit("close");return this.removeAllListeners("close"),n}else if(t==="error"){this[qt]=i,super.emit(_i,i);let n=!this[Jt]||this.listeners("error").length?super.emit("error",i):!1;return this[J](),n}else if(t==="resume"){let n=super.emit("resume");return this[J](),n}else if(t==="finish"||t==="prefinish"){let n=super.emit(t);return this.removeAllListeners(t),n}let r=super.emit(t,...e);return this[J](),r}[Oi](t){for(let i of this[N])i.dest.write(t)===!1&&this.pause();let e=this[C]?!1:super.emit("data",t);return this[J](),e}[Is](){return this[nt]?!1:(this[nt]=!0,this.readable=!1,this[Z]?(jt(()=>this[Ti]()),!0):this[Ti]())}[Ti](){if(this[Mt]){let e=this[Mt].end();if(e){for(let i of this[N])i.dest.write(e);this[C]||super.emit("data",e)}}for(let e of this[N])e.end();let t=super.emit("end");return this.removeAllListeners("end"),t}async collect(){let t=Object.assign([],{dataLength:0});this[L]||(t.dataLength=0);let e=this.promise();return this.on("data",i=>{t.push(i),this[L]||(t.dataLength+=i.length)}),await e,t}async concat(){if(this[L])throw new Error("cannot concat in objectMode");let t=await this.collect();return this[z]?t.join(""):Buffer.concat(t,t.dataLength)}async promise(){return new Promise((t,e)=>{this.on(w,()=>e(new Error("stream destroyed"))),this.on("error",i=>e(i)),this.on("end",()=>t())})}[Symbol.asyncIterator](){this[C]=!1;let t=!1,e=async()=>(this.pause(),t=!0,{value:void 0,done:!0});return{next:()=>{if(t)return e();let r=this.read();if(r!==null)return Promise.resolve({done:!1,value:r});if(this[Q])return e();let n,o,h=d=>{this.off("data",a),this.off("end",l),this.off(w,c),e(),o(d)},a=d=>{this.off("error",h),this.off("end",l),this.off(w,c),this.pause(),n({value:d,done:!!this[Q]})},l=()=>{this.off("error",h),this.off("data",a),this.off(w,c),e(),n({done:!0,value:void 0})},c=()=>h(new Error("stream destroyed"));return new Promise((d,S)=>{o=S,n=d,this.once(w,c),this.once("error",h),this.once("end",l),this.once("data",a)})},throw:e,return:e,[Symbol.asyncIterator](){return this},[Symbol.asyncDispose]:async()=>{}}}[Symbol.iterator](){this[C]=!1;let t=!1,e=()=>(this.pause(),this.off(_i,e),this.off(w,e),this.off("end",e),t=!0,{done:!0,value:void 0}),i=()=>{if(t)return e();let r=this.read();return r===null?e():{done:!1,value:r}};return this.once("end",e),this.once(_i,e),this.once(w,e),{next:i,throw:e,return:e,[Symbol.iterator](){return this},[Symbol.dispose]:()=>{}}}destroy(t){if(this[w])return t?this.emit("error",t):this.emit(w),this;this[w]=!0,this[C]=!0,this[b].length=0,this[_]=0;let e=this;return typeof e.close=="function"&&!this[Ne]&&e.close(),t?this.emit("error",t):this.emit(w),this}static get isStream(){return Wr}};var Jr=I.writev,ht=Symbol("_autoClose"),H=Symbol("_close"),te=Symbol("_ended"),u=Symbol("_fd"),Ni=Symbol("_finished"),tt=Symbol("_flags"),Ai=Symbol("_flush"),ki=Symbol("_handleChunk"),vi=Symbol("_makeBuf"),ie=Symbol("_mode"),ke=Symbol("_needDrain"),Ut=Symbol("_onerror"),Ht=Symbol("_onopen"),Ii=Symbol("_onread"),Pt=Symbol("_onwrite"),at=Symbol("_open"),U=Symbol("_path"),ot=Symbol("_pos"),Y=Symbol("_queue"),zt=Symbol("_read"),Ci=Symbol("_readSize"),j=Symbol("_reading"),ee=Symbol("_remain"),Fi=Symbol("_size"),ve=Symbol("_write"),gt=Symbol("_writing"),Me=Symbol("_defaultFlag"),bt=Symbol("_errored"),_t=class extends A{[bt]=!1;[u];[U];[Ci];[j]=!1;[Fi];[ee];[ht];constructor(t,e){if(e=e||{},super(e),this.readable=!0,this.writable=!1,typeof t!="string")throw new TypeError("path must be a string");this[bt]=!1,this[u]=typeof e.fd=="number"?e.fd:void 0,this[U]=t,this[Ci]=e.readSize||16*1024*1024,this[j]=!1,this[Fi]=typeof e.size=="number"?e.size:1/0,this[ee]=this[Fi],this[ht]=typeof e.autoClose=="boolean"?e.autoClose:!0,typeof this[u]=="number"?this[zt]():this[at]()}get fd(){return this[u]}get path(){return this[U]}write(){throw new TypeError("this is a readable stream")}end(){throw new TypeError("this is a readable stream")}[at](){I.open(this[U],"r",(t,e)=>this[Ht](t,e))}[Ht](t,e){t?this[Ut](t):(this[u]=e,this.emit("open",e),this[zt]())}[vi](){return Buffer.allocUnsafe(Math.min(this[Ci],this[ee]))}[zt](){if(!this[j]){this[j]=!0;let t=this[vi]();if(t.length===0)return process.nextTick(()=>this[Ii](null,0,t));I.read(this[u],t,0,t.length,null,(e,i,r)=>this[Ii](e,i,r))}}[Ii](t,e,i){this[j]=!1,t?this[Ut](t):this[ki](e,i)&&this[zt]()}[H](){if(this[ht]&&typeof this[u]=="number"){let t=this[u];this[u]=void 0,I.close(t,e=>e?this.emit("error",e):this.emit("close"))}}[Ut](t){this[j]=!0,this[H](),this.emit("error",t)}[ki](t,e){let i=!1;return this[ee]-=t,t>0&&(i=super.write(tthis[Ht](t,e))}[Ht](t,e){this[Me]&&this[tt]==="r+"&&t&&t.code==="ENOENT"?(this[tt]="w",this[at]()):t?this[Ut](t):(this[u]=e,this.emit("open",e),this[gt]||this[Ai]())}end(t,e){return t&&this.write(t,e),this[te]=!0,!this[gt]&&!this[Y].length&&typeof this[u]=="number"&&this[Pt](null,0),this}write(t,e){return typeof t=="string"&&(t=Buffer.from(t,e)),this[te]?(this.emit("error",new Error("write() after end()")),!1):this[u]===void 0||this[gt]||this[Y].length?(this[Y].push(t),this[ke]=!0,!1):(this[gt]=!0,this[ve](t),!0)}[ve](t){I.write(this[u],t,0,t.length,this[ot],(e,i)=>this[Pt](e,i))}[Pt](t,e){t?this[Ut](t):(this[ot]!==void 0&&typeof e=="number"&&(this[ot]+=e),this[Y].length?this[Ai]():(this[gt]=!1,this[te]&&!this[Ni]?(this[Ni]=!0,this[H](),this.emit("finish")):this[ke]&&(this[ke]=!1,this.emit("drain"))))}[Ai](){if(this[Y].length===0)this[te]&&this[Pt](null,0);else if(this[Y].length===1)this[ve](this[Y].pop());else{let t=this[Y];this[Y]=[],Jr(this[u],t,this[ot],(e,i)=>this[Pt](e,i))}}[H](){if(this[ht]&&typeof this[u]=="number"){let t=this[u];this[u]=void 0,I.close(t,e=>e?this.emit("error",e):this.emit("close"))}}},Wt=class extends et{[at](){let t;if(this[Me]&&this[tt]==="r+")try{t=I.openSync(this[U],this[tt],this[ie])}catch(e){if(e?.code==="ENOENT")return this[tt]="w",this[at]();throw e}else t=I.openSync(this[U],this[tt],this[ie]);this[Ht](null,t)}[H](){if(this[ht]&&typeof this[u]=="number"){let t=this[u];this[u]=void 0,I.closeSync(t),this.emit("close")}}[ve](t){let e=!0;try{this[Pt](null,I.writeSync(this[u],t,0,t.length,this[ot])),e=!1}finally{if(e)try{this[H]()}catch{}}}};import cr from"node:path";import Kt from"node:fs";import{dirname as Fn,parse as kn}from"path";var jr=new Map([["C","cwd"],["f","file"],["z","gzip"],["P","preservePaths"],["U","unlink"],["strip-components","strip"],["stripComponents","strip"],["keep-newer","newer"],["keepNewer","newer"],["keep-newer-files","newer"],["keepNewerFiles","newer"],["k","keep"],["keep-existing","keep"],["keepExisting","keep"],["m","noMtime"],["no-mtime","noMtime"],["p","preserveOwner"],["L","follow"],["h","follow"],["onentry","onReadEntry"]]),Fs=s=>!!s.sync&&!!s.file,ks=s=>!s.sync&&!!s.file,vs=s=>!!s.sync&&!s.file,Ms=s=>!s.sync&&!s.file;var Bs=s=>!!s.file;var tn=s=>{let t=jr.get(s);return t||s},se=(s={})=>{if(!s)return{};let t={};for(let[e,i]of Object.entries(s)){let r=tn(e);t[r]=i}return t.chmod===void 0&&t.noChmod===!1&&(t.chmod=!0),delete t.noChmod,t};var K=(s,t,e,i,r)=>Object.assign((n=[],o,h)=>{Array.isArray(n)&&(o=n,n={}),typeof o=="function"&&(h=o,o=void 0),o=o?Array.from(o):[];let a=se(n);if(r?.(a,o),Fs(a)){if(typeof h=="function")throw new TypeError("callback not supported for sync tar functions");return s(a,o)}else if(ks(a)){let l=t(a,o);return h?l.then(()=>h(),h):l}else if(vs(a)){if(typeof h=="function")throw new TypeError("callback not supported for sync tar functions");return e(a,o)}else if(Ms(a)){if(typeof h=="function")throw new TypeError("callback only supported with file option");return i(a,o)}throw new Error("impossible options??")},{syncFile:s,asyncFile:t,syncNoFile:e,asyncNoFile:i,validate:r});import{EventEmitter as Dn}from"events";import zi from"assert";import{Buffer as Ot}from"buffer";import*as Ps from"zlib";import en from"zlib";var sn=en.constants||{ZLIB_VERNUM:4736},M=Object.freeze(Object.assign(Object.create(null),{Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_MEM_ERROR:-4,Z_BUF_ERROR:-5,Z_VERSION_ERROR:-6,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,DEFLATE:1,INFLATE:2,GZIP:3,GUNZIP:4,DEFLATERAW:5,INFLATERAW:6,UNZIP:7,BROTLI_DECODE:8,BROTLI_ENCODE:9,Z_MIN_WINDOWBITS:8,Z_MAX_WINDOWBITS:15,Z_DEFAULT_WINDOWBITS:15,Z_MIN_CHUNK:64,Z_MAX_CHUNK:1/0,Z_DEFAULT_CHUNK:16384,Z_MIN_MEMLEVEL:1,Z_MAX_MEMLEVEL:9,Z_DEFAULT_MEMLEVEL:8,Z_MIN_LEVEL:-1,Z_MAX_LEVEL:9,Z_DEFAULT_LEVEL:-1,BROTLI_OPERATION_PROCESS:0,BROTLI_OPERATION_FLUSH:1,BROTLI_OPERATION_FINISH:2,BROTLI_OPERATION_EMIT_METADATA:3,BROTLI_MODE_GENERIC:0,BROTLI_MODE_TEXT:1,BROTLI_MODE_FONT:2,BROTLI_DEFAULT_MODE:0,BROTLI_MIN_QUALITY:0,BROTLI_MAX_QUALITY:11,BROTLI_DEFAULT_QUALITY:11,BROTLI_MIN_WINDOW_BITS:10,BROTLI_MAX_WINDOW_BITS:24,BROTLI_LARGE_MAX_WINDOW_BITS:30,BROTLI_DEFAULT_WINDOW:22,BROTLI_MIN_INPUT_BLOCK_BITS:16,BROTLI_MAX_INPUT_BLOCK_BITS:24,BROTLI_PARAM_MODE:0,BROTLI_PARAM_QUALITY:1,BROTLI_PARAM_LGWIN:2,BROTLI_PARAM_LGBLOCK:3,BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING:4,BROTLI_PARAM_SIZE_HINT:5,BROTLI_PARAM_LARGE_WINDOW:6,BROTLI_PARAM_NPOSTFIX:7,BROTLI_PARAM_NDIRECT:8,BROTLI_DECODER_RESULT_ERROR:0,BROTLI_DECODER_RESULT_SUCCESS:1,BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT:2,BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT:3,BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION:0,BROTLI_DECODER_PARAM_LARGE_WINDOW:1,BROTLI_DECODER_NO_ERROR:0,BROTLI_DECODER_SUCCESS:1,BROTLI_DECODER_NEEDS_MORE_INPUT:2,BROTLI_DECODER_NEEDS_MORE_OUTPUT:3,BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_NIBBLE:-1,BROTLI_DECODER_ERROR_FORMAT_RESERVED:-2,BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_META_NIBBLE:-3,BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET:-4,BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME:-5,BROTLI_DECODER_ERROR_FORMAT_CL_SPACE:-6,BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE:-7,BROTLI_DECODER_ERROR_FORMAT_CONTEXT_MAP_REPEAT:-8,BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_1:-9,BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_2:-10,BROTLI_DECODER_ERROR_FORMAT_TRANSFORM:-11,BROTLI_DECODER_ERROR_FORMAT_DICTIONARY:-12,BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS:-13,BROTLI_DECODER_ERROR_FORMAT_PADDING_1:-14,BROTLI_DECODER_ERROR_FORMAT_PADDING_2:-15,BROTLI_DECODER_ERROR_FORMAT_DISTANCE:-16,BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET:-19,BROTLI_DECODER_ERROR_INVALID_ARGUMENTS:-20,BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MODES:-21,BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS:-22,BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MAP:-25,BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_1:-26,BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_2:-27,BROTLI_DECODER_ERROR_ALLOC_BLOCK_TYPE_TREES:-30,BROTLI_DECODER_ERROR_UNREACHABLE:-31},sn));var rn=Ot.concat,zs=Object.getOwnPropertyDescriptor(Ot,"concat"),nn=s=>s,Bi=zs?.writable===!0||zs?.set!==void 0?s=>{Ot.concat=s?nn:rn}:s=>{},Tt=Symbol("_superWrite"),Gt=class extends Error{code;errno;constructor(t,e){super("zlib: "+t.message,{cause:t}),this.code=t.code,this.errno=t.errno,this.code||(this.code="ZLIB_ERROR"),this.message="zlib: "+t.message,Error.captureStackTrace(this,e??this.constructor)}get name(){return"ZlibError"}},Pi=Symbol("flushFlag"),re=class extends A{#t=!1;#i=!1;#s;#n;#r;#e;#o;get sawError(){return this.#t}get handle(){return this.#e}get flushFlag(){return this.#s}constructor(t,e){if(!t||typeof t!="object")throw new TypeError("invalid options for ZlibBase constructor");if(super(t),this.#s=t.flush??0,this.#n=t.finishFlush??0,this.#r=t.fullFlushFlag??0,typeof Ps[e]!="function")throw new TypeError("Compression method not supported: "+e);try{this.#e=new Ps[e](t)}catch(i){throw new Gt(i,this.constructor)}this.#o=i=>{this.#t||(this.#t=!0,this.close(),this.emit("error",i))},this.#e?.on("error",i=>this.#o(new Gt(i))),this.once("end",()=>this.close)}close(){this.#e&&(this.#e.close(),this.#e=void 0,this.emit("close"))}reset(){if(!this.#t)return zi(this.#e,"zlib binding closed"),this.#e.reset?.()}flush(t){this.ended||(typeof t!="number"&&(t=this.#r),this.write(Object.assign(Ot.alloc(0),{[Pi]:t})))}end(t,e,i){return typeof t=="function"&&(i=t,e=void 0,t=void 0),typeof e=="function"&&(i=e,e=void 0),t&&(e?this.write(t,e):this.write(t)),this.flush(this.#n),this.#i=!0,super.end(i)}get ended(){return this.#i}[Tt](t){return super.write(t)}write(t,e,i){if(typeof e=="function"&&(i=e,e="utf8"),typeof t=="string"&&(t=Ot.from(t,e)),this.#t)return;zi(this.#e,"zlib binding closed");let r=this.#e._handle,n=r.close;r.close=()=>{};let o=this.#e.close;this.#e.close=()=>{},Bi(!0);let h;try{let l=typeof t[Pi]=="number"?t[Pi]:this.#s;h=this.#e._processChunk(t,l),Bi(!1)}catch(l){Bi(!1),this.#o(new Gt(l,this.write))}finally{this.#e&&(this.#e._handle=r,r.close=n,this.#e.close=o,this.#e.removeAllListeners("error"))}this.#e&&this.#e.on("error",l=>this.#o(new Gt(l,this.write)));let a;if(h)if(Array.isArray(h)&&h.length>0){let l=h[0];a=this[Tt](Ot.from(l));for(let c=1;c{typeof r=="function"&&(n=r,r=this.flushFlag),this.flush(r),n?.()};try{this.handle.params(t,e)}finally{this.handle.flush=i}this.handle&&(this.#t=t,this.#i=e)}}}};var ze=class extends Pe{#t;constructor(t){super(t,"Gzip"),this.#t=t&&!!t.portable}[Tt](t){return this.#t?(this.#t=!1,t[9]=255,super[Tt](t)):super[Tt](t)}};var Ue=class extends Pe{constructor(t){super(t,"Unzip")}},He=class extends re{constructor(t,e){t=t||{},t.flush=t.flush||M.BROTLI_OPERATION_PROCESS,t.finishFlush=t.finishFlush||M.BROTLI_OPERATION_FINISH,t.fullFlushFlag=M.BROTLI_OPERATION_FLUSH,super(t,e)}},We=class extends He{constructor(t){super(t,"BrotliCompress")}},Ge=class extends He{constructor(t){super(t,"BrotliDecompress")}},Ze=class extends re{constructor(t,e){t=t||{},t.flush=t.flush||M.ZSTD_e_continue,t.finishFlush=t.finishFlush||M.ZSTD_e_end,t.fullFlushFlag=M.ZSTD_e_flush,super(t,e)}},Ye=class extends Ze{constructor(t){super(t,"ZstdCompress")}},Ke=class extends Ze{constructor(t){super(t,"ZstdDecompress")}};import{posix as Zt}from"node:path";var Us=(s,t)=>{if(Number.isSafeInteger(s))s<0?an(s,t):hn(s,t);else throw Error("cannot encode number outside of javascript safe integer range");return t},hn=(s,t)=>{t[0]=128;for(var e=t.length;e>1;e--)t[e-1]=s&255,s=Math.floor(s/256)},an=(s,t)=>{t[0]=255;var e=!1;s=s*-1;for(var i=t.length;i>1;i--){var r=s&255;s=Math.floor(s/256),e?t[i-1]=Ws(r):r===0?t[i-1]=0:(e=!0,t[i-1]=Gs(r))}},Hs=s=>{let t=s[0],e=t===128?cn(s.subarray(1,s.length)):t===255?ln(s):null;if(e===null)throw Error("invalid base256 encoding");if(!Number.isSafeInteger(e))throw Error("parsed number outside of javascript safe integer range");return e},ln=s=>{for(var t=s.length,e=0,i=!1,r=t-1;r>-1;r--){var n=Number(s[r]),o;i?o=Ws(n):n===0?o=n:(i=!0,o=Gs(n)),o!==0&&(e-=o*Math.pow(256,t-r-1))}return e},cn=s=>{for(var t=s.length,e=0,i=t-1;i>-1;i--){var r=Number(s[i]);r!==0&&(e+=r*Math.pow(256,t-i-1))}return e},Ws=s=>(255^s)&255,Gs=s=>(255^s)+1&255;var Hi={};Ur(Hi,{code:()=>Ve,isCode:()=>ne,isName:()=>dn,name:()=>oe,normalFsTypes:()=>Ui});var ne=s=>oe.has(s),dn=s=>Ve.has(s),Ui=new Set(["0","","1","2","3","4","5","6","7","D"]),oe=new Map([["0","File"],["","OldFile"],["1","Link"],["2","SymbolicLink"],["3","CharacterDevice"],["4","BlockDevice"],["5","Directory"],["6","FIFO"],["7","ContiguousFile"],["g","GlobalExtendedHeader"],["x","ExtendedHeader"],["A","SolarisACL"],["D","GNUDumpDir"],["I","Inode"],["K","NextFileHasLongLinkpath"],["L","NextFileHasLongPath"],["M","ContinuationFile"],["N","OldGnuLongPath"],["S","SparseFile"],["V","TapeVolumeHeader"],["X","OldExtendedHeader"]]),Ve=new Map(Array.from(oe).map(s=>[s[1],s[0]]));var mn=s=>s===void 0||s<0?void 0:s,F=class{cksumValid=!1;needPax=!1;nullBlock=!1;block;path;mode;uid;gid;size;cksum;#t="Unsupported";linkpath;uname;gname;devmaj=0;devmin=0;atime;ctime;mtime;charset;comment;constructor(t,e=0,i,r){Buffer.isBuffer(t)?this.decode(t,e||0,i,r):t&&this.#i(t)}decode(t,e,i,r){if(e||(e=0),!t||!(t.length>=e+512))throw new Error("need 512 bytes for header");let n=xt(t,e+156,1),o=Ui.has(n),h=o?i:void 0,a=o?r:void 0;if(this.path=h?.path??xt(t,e,100),this.mode=h?.mode??a?.mode??lt(t,e+100,8),this.uid=h?.uid??a?.uid??lt(t,e+108,8),this.gid=h?.gid??a?.gid??lt(t,e+116,8),this.size=mn(h?.size??a?.size??lt(t,e+124,12)),this.mtime=h?.mtime??a?.mtime??Wi(t,e+136,12),this.cksum=lt(t,e+148,12),a&&this.#i(a,!0),h&&this.#i(h),ne(n)&&(this.#t=n||"0"),this.#t==="0"&&this.path.slice(-1)==="/"&&(this.#t="5"),this.#t==="5"&&(this.size=0),this.linkpath=xt(t,e+157,100),t.subarray(e+257,e+265).toString()==="ustar\x0000")if(this.uname=h?.uname??a?.uname??xt(t,e+265,32),this.gname=h?.gname??a?.gname??xt(t,e+297,32),this.devmaj=h?.devmaj??a?.devmaj??lt(t,e+329,8)??0,this.devmin=h?.devmin??a?.devmin??lt(t,e+337,8)??0,t[e+475]!==0){let c=xt(t,e+345,155);this.path=c+"/"+this.path}else{let c=xt(t,e+345,130);c&&(this.path=c+"/"+this.path),this.atime=i?.atime??r?.atime??Wi(t,e+476,12),this.ctime=i?.ctime??r?.ctime??Wi(t,e+488,12)}let l=256;for(let c=e;c!(r==null||i==="size"&&Number(r)<0||i==="path"&&e||i==="linkpath"&&e||i==="global"))))}encode(t,e=0){if(t||(t=this.block=Buffer.alloc(512)),this.#t==="Unsupported"&&(this.#t="0"),!(t.length>=e+512))throw new Error("need 512 bytes for header");let i=this.ctime||this.atime?130:155,r=un(this.path||"",i),n=r[0],o=r[1];this.needPax=!!r[2],this.needPax=Lt(t,e,100,n)||this.needPax,this.needPax=ct(t,e+100,8,this.mode)||this.needPax,this.needPax=ct(t,e+108,8,this.uid)||this.needPax,this.needPax=ct(t,e+116,8,this.gid)||this.needPax,this.needPax=ct(t,e+124,12,this.size)||this.needPax,this.needPax=Gi(t,e+136,12,this.mtime)||this.needPax,t[e+156]=Number(this.#t.codePointAt(0)),this.needPax=Lt(t,e+157,100,this.linkpath)||this.needPax,t.write("ustar\x0000",e+257,8),this.needPax=Lt(t,e+265,32,this.uname)||this.needPax,this.needPax=Lt(t,e+297,32,this.gname)||this.needPax,this.needPax=ct(t,e+329,8,this.devmaj)||this.needPax,this.needPax=ct(t,e+337,8,this.devmin)||this.needPax,this.needPax=Lt(t,e+345,i,o)||this.needPax,t[e+475]!==0?this.needPax=Lt(t,e+345,155,o)||this.needPax:(this.needPax=Lt(t,e+345,130,o)||this.needPax,this.needPax=Gi(t,e+476,12,this.atime)||this.needPax,this.needPax=Gi(t,e+488,12,this.ctime)||this.needPax);let h=256;for(let a=e;a{let i=s,r="",n,o=Zt.parse(s).root||".";if(Buffer.byteLength(i)<100)n=[i,r,!1];else{r=Zt.dirname(i),i=Zt.basename(i);do Buffer.byteLength(i)<=100&&Buffer.byteLength(r)<=t?n=[i,r,!1]:Buffer.byteLength(i)>100&&Buffer.byteLength(r)<=t?n=[i.slice(0,99),r,!0]:(i=Zt.join(Zt.basename(r),i),r=Zt.dirname(r));while(r!==o&&n===void 0);n||(n=[s.slice(0,99),"",!0])}return n},xt=(s,t,e)=>s.subarray(t,t+e).toString("utf8").replace(/\0.*/,""),Wi=(s,t,e)=>pn(lt(s,t,e)),pn=s=>s===void 0?void 0:new Date(s*1e3),lt=(s,t,e)=>Number(s[t])&128?Hs(s.subarray(t,t+e)):wn(s,t,e),En=s=>isNaN(s)?void 0:s,wn=(s,t,e)=>En(parseInt(s.subarray(t,t+e).toString("utf8").replace(/\0.*$/,"").trim(),8)),Sn={12:8589934591,8:2097151},ct=(s,t,e,i)=>i===void 0?!1:i>Sn[e]||i<0?(Us(i,s.subarray(t,t+e)),!0):(yn(s,t,e,i),!1),yn=(s,t,e,i)=>s.write(Rn(i,e),t,e,"ascii"),Rn=(s,t)=>gn(Math.floor(s).toString(8),t),gn=(s,t)=>(s.length===t-1?s:new Array(t-s.length-1).join("0")+s+" ")+"\0",Gi=(s,t,e,i)=>i===void 0?!1:ct(s,t,e,i.getTime()/1e3),bn=new Array(156).join("\0"),Lt=(s,t,e,i)=>i===void 0?!1:(s.write(i+bn,t,e,"utf8"),i.length!==Buffer.byteLength(i)||i.length>e);import{basename as _n}from"node:path";var ft=class s{atime;mtime;ctime;charset;comment;gid;uid;gname;uname;linkpath;dev;ino;nlink;path;size;mode;global;constructor(t,e=!1){this.atime=t.atime,this.charset=t.charset,this.comment=t.comment,this.ctime=t.ctime,this.dev=t.dev,this.gid=t.gid,this.global=e,this.gname=t.gname,this.ino=t.ino,this.linkpath=t.linkpath,this.mtime=t.mtime,this.nlink=t.nlink,this.path=t.path,this.size=t.size,this.uid=t.uid,this.uname=t.uname}encode(){let t=this.encodeBody();if(t==="")return Buffer.allocUnsafe(0);let e=Buffer.byteLength(t),i=512*Math.ceil(1+e/512),r=Buffer.allocUnsafe(i);for(let n=0;n<512;n++)r[n]=0;new F({path:("PaxHeader/"+_n(this.path??"")).slice(0,99),mode:this.mode||420,uid:this.uid,gid:this.gid,size:e,mtime:this.mtime,type:this.global?"GlobalExtendedHeader":"ExtendedHeader",linkpath:"",uname:this.uname||"",gname:this.gname||"",devmaj:0,devmin:0,atime:this.atime,ctime:this.ctime}).encode(r),r.write(t,512,e,"utf8");for(let n=e+512;n{for(var e in t)zr(s,e,{get:t[e],enumerable:!0})};import Qr from"events";import I from"fs";import{EventEmitter as Di}from"node:events";import Cs from"node:stream";import{StringDecoder as Hr}from"node:string_decoder";var Ds=typeof process=="object"&&process?process:{stdout:null,stderr:null},Wr=s=>!!s&&typeof s=="object"&&(s instanceof A||s instanceof Cs||Gr(s)||Zr(s)),Gr=s=>!!s&&typeof s=="object"&&s instanceof Di&&typeof s.pipe=="function"&&s.pipe!==Cs.Writable.prototype.pipe,Zr=s=>!!s&&typeof s=="object"&&s instanceof Di&&typeof s.write=="function"&&typeof s.end=="function",Q=Symbol("EOF"),J=Symbol("maybeEmitEnd"),nt=Symbol("emittedEnd"),De=Symbol("emittingEnd"),qt=Symbol("emittedError"),Ne=Symbol("closed"),Ns=Symbol("read"),Ae=Symbol("flush"),As=Symbol("flushChunk"),z=Symbol("encoding"),Mt=Symbol("decoder"),g=Symbol("flowing"),Qt=Symbol("paused"),Bt=Symbol("resume"),b=Symbol("buffer"),N=Symbol("pipes"),_=Symbol("bufferLength"),bi=Symbol("bufferPush"),Ie=Symbol("bufferShift"),L=Symbol("objectMode"),S=Symbol("destroyed"),_i=Symbol("error"),Oi=Symbol("emitData"),Is=Symbol("emitEnd"),Ti=Symbol("emitEnd2"),Z=Symbol("async"),xi=Symbol("abort"),Ce=Symbol("aborted"),Jt=Symbol("signal"),Rt=Symbol("dataListeners"),C=Symbol("discarded"),jt=s=>Promise.resolve().then(s),Yr=s=>s(),Kr=s=>s==="end"||s==="finish"||s==="prefinish",Vr=s=>s instanceof ArrayBuffer||!!s&&typeof s=="object"&&s.constructor&&s.constructor.name==="ArrayBuffer"&&s.byteLength>=0,$r=s=>!Buffer.isBuffer(s)&&ArrayBuffer.isView(s),Fe=class{src;dest;opts;ondrain;constructor(t,e,i){this.src=t,this.dest=e,this.opts=i,this.ondrain=()=>t[Bt](),this.dest.on("drain",this.ondrain)}unpipe(){this.dest.removeListener("drain",this.ondrain)}proxyErrors(t){}end(){this.unpipe(),this.opts.end&&this.dest.end()}},Li=class extends Fe{unpipe(){this.src.removeListener("error",this.proxyErrors),super.unpipe()}constructor(t,e,i){super(t,e,i),this.proxyErrors=r=>this.dest.emit("error",r),t.on("error",this.proxyErrors)}},Xr=s=>!!s.objectMode,qr=s=>!s.objectMode&&!!s.encoding&&s.encoding!=="buffer",A=class extends Di{[g]=!1;[Qt]=!1;[N]=[];[b]=[];[L];[z];[Z];[Mt];[Q]=!1;[nt]=!1;[De]=!1;[Ne]=!1;[qt]=null;[_]=0;[S]=!1;[Jt];[Ce]=!1;[Rt]=0;[C]=!1;writable=!0;readable=!0;constructor(...t){let e=t[0]||{};if(super(),e.objectMode&&typeof e.encoding=="string")throw new TypeError("Encoding and objectMode may not be used together");Xr(e)?(this[L]=!0,this[z]=null):qr(e)?(this[z]=e.encoding,this[L]=!1):(this[L]=!1,this[z]=null),this[Z]=!!e.async,this[Mt]=this[z]?new Hr(this[z]):null,e&&e.debugExposeBuffer===!0&&Object.defineProperty(this,"buffer",{get:()=>this[b]}),e&&e.debugExposePipes===!0&&Object.defineProperty(this,"pipes",{get:()=>this[N]});let{signal:i}=e;i&&(this[Jt]=i,i.aborted?this[xi]():i.addEventListener("abort",()=>this[xi]()))}get bufferLength(){return this[_]}get encoding(){return this[z]}set encoding(t){throw new Error("Encoding must be set at instantiation time")}setEncoding(t){throw new Error("Encoding must be set at instantiation time")}get objectMode(){return this[L]}set objectMode(t){throw new Error("objectMode must be set at instantiation time")}get async(){return this[Z]}set async(t){this[Z]=this[Z]||!!t}[xi](){this[Ce]=!0,this.emit("abort",this[Jt]?.reason),this.destroy(this[Jt]?.reason)}get aborted(){return this[Ce]}set aborted(t){}write(t,e,i){if(this[Ce])return!1;if(this[Q])throw new Error("write after end");if(this[S])return this.emit("error",Object.assign(new Error("Cannot call write after a stream was destroyed"),{code:"ERR_STREAM_DESTROYED"})),!0;typeof e=="function"&&(i=e,e="utf8"),e||(e="utf8");let r=this[Z]?jt:Yr;if(!this[L]&&!Buffer.isBuffer(t)){if($r(t))t=Buffer.from(t.buffer,t.byteOffset,t.byteLength);else if(Vr(t))t=Buffer.from(t);else if(typeof t!="string")throw new Error("Non-contiguous data written to non-objectMode stream")}return this[L]?(this[g]&&this[_]!==0&&this[Ae](!0),this[g]?this.emit("data",t):this[bi](t),this[_]!==0&&this.emit("readable"),i&&r(i),this[g]):t.length?(typeof t=="string"&&!(e===this[z]&&!this[Mt]?.lastNeed)&&(t=Buffer.from(t,e)),Buffer.isBuffer(t)&&this[z]&&(t=this[Mt].write(t)),this[g]&&this[_]!==0&&this[Ae](!0),this[g]?this.emit("data",t):this[bi](t),this[_]!==0&&this.emit("readable"),i&&r(i),this[g]):(this[_]!==0&&this.emit("readable"),i&&r(i),this[g])}read(t){if(this[S])return null;if(this[C]=!1,this[_]===0||t===0||t&&t>this[_])return this[J](),null;this[L]&&(t=null),this[b].length>1&&!this[L]&&(this[b]=[this[z]?this[b].join(""):Buffer.concat(this[b],this[_])]);let e=this[Ns](t||null,this[b][0]);return this[J](),e}[Ns](t,e){if(this[L])this[Ie]();else{let i=e;t===i.length||t===null?this[Ie]():typeof i=="string"?(this[b][0]=i.slice(t),e=i.slice(0,t),this[_]-=t):(this[b][0]=i.subarray(t),e=i.subarray(0,t),this[_]-=t)}return this.emit("data",e),!this[b].length&&!this[Q]&&this.emit("drain"),e}end(t,e,i){return typeof t=="function"&&(i=t,t=void 0),typeof e=="function"&&(i=e,e="utf8"),t!==void 0&&this.write(t,e),i&&this.once("end",i),this[Q]=!0,this.writable=!1,(this[g]||!this[Qt])&&this[J](),this}[Bt](){this[S]||(!this[Rt]&&!this[N].length&&(this[C]=!0),this[Qt]=!1,this[g]=!0,this.emit("resume"),this[b].length?this[Ae]():this[Q]?this[J]():this.emit("drain"))}resume(){return this[Bt]()}pause(){this[g]=!1,this[Qt]=!0,this[C]=!1}get destroyed(){return this[S]}get flowing(){return this[g]}get paused(){return this[Qt]}[bi](t){this[L]?this[_]+=1:this[_]+=t.length,this[b].push(t)}[Ie](){return this[L]?this[_]-=1:this[_]-=this[b][0].length,this[b].shift()}[Ae](t=!1){do;while(this[As](this[Ie]())&&this[b].length);!t&&!this[b].length&&!this[Q]&&this.emit("drain")}[As](t){return this.emit("data",t),this[g]}pipe(t,e){if(this[S])return t;this[C]=!1;let i=this[nt];return e=e||{},t===Ds.stdout||t===Ds.stderr?e.end=!1:e.end=e.end!==!1,e.proxyErrors=!!e.proxyErrors,i?e.end&&t.end():(this[N].push(e.proxyErrors?new Li(this,t,e):new Fe(this,t,e)),this[Z]?jt(()=>this[Bt]()):this[Bt]()),t}unpipe(t){let e=this[N].find(i=>i.dest===t);e&&(this[N].length===1?(this[g]&&this[Rt]===0&&(this[g]=!1),this[N]=[]):this[N].splice(this[N].indexOf(e),1),e.unpipe())}addListener(t,e){return this.on(t,e)}on(t,e){let i=super.on(t,e);if(t==="data")this[C]=!1,this[Rt]++,!this[N].length&&!this[g]&&this[Bt]();else if(t==="readable"&&this[_]!==0)super.emit("readable");else if(Kr(t)&&this[nt])super.emit(t),this.removeAllListeners(t);else if(t==="error"&&this[qt]){let r=e;this[Z]?jt(()=>r.call(this,this[qt])):r.call(this,this[qt])}return i}removeListener(t,e){return this.off(t,e)}off(t,e){let i=super.off(t,e);return t==="data"&&(this[Rt]=this.listeners("data").length,this[Rt]===0&&!this[C]&&!this[N].length&&(this[g]=!1)),i}removeAllListeners(t){let e=super.removeAllListeners(t);return(t==="data"||t===void 0)&&(this[Rt]=0,!this[C]&&!this[N].length&&(this[g]=!1)),e}get emittedEnd(){return this[nt]}[J](){!this[De]&&!this[nt]&&!this[S]&&this[b].length===0&&this[Q]&&(this[De]=!0,this.emit("end"),this.emit("prefinish"),this.emit("finish"),this[Ne]&&this.emit("close"),this[De]=!1)}emit(t,...e){let i=e[0];if(t!=="error"&&t!=="close"&&t!==S&&this[S])return!1;if(t==="data")return!this[L]&&!i?!1:this[Z]?(jt(()=>this[Oi](i)),!0):this[Oi](i);if(t==="end")return this[Is]();if(t==="close"){if(this[Ne]=!0,!this[nt]&&!this[S])return!1;let n=super.emit("close");return this.removeAllListeners("close"),n}else if(t==="error"){this[qt]=i,super.emit(_i,i);let n=!this[Jt]||this.listeners("error").length?super.emit("error",i):!1;return this[J](),n}else if(t==="resume"){let n=super.emit("resume");return this[J](),n}else if(t==="finish"||t==="prefinish"){let n=super.emit(t);return this.removeAllListeners(t),n}let r=super.emit(t,...e);return this[J](),r}[Oi](t){for(let i of this[N])i.dest.write(t)===!1&&this.pause();let e=this[C]?!1:super.emit("data",t);return this[J](),e}[Is](){return this[nt]?!1:(this[nt]=!0,this.readable=!1,this[Z]?(jt(()=>this[Ti]()),!0):this[Ti]())}[Ti](){if(this[Mt]){let e=this[Mt].end();if(e){for(let i of this[N])i.dest.write(e);this[C]||super.emit("data",e)}}for(let e of this[N])e.end();let t=super.emit("end");return this.removeAllListeners("end"),t}async collect(){let t=Object.assign([],{dataLength:0});this[L]||(t.dataLength=0);let e=this.promise();return this.on("data",i=>{t.push(i),this[L]||(t.dataLength+=i.length)}),await e,t}async concat(){if(this[L])throw new Error("cannot concat in objectMode");let t=await this.collect();return this[z]?t.join(""):Buffer.concat(t,t.dataLength)}async promise(){return new Promise((t,e)=>{this.on(S,()=>e(new Error("stream destroyed"))),this.on("error",i=>e(i)),this.on("end",()=>t())})}[Symbol.asyncIterator](){this[C]=!1;let t=!1,e=async()=>(this.pause(),t=!0,{value:void 0,done:!0});return{next:()=>{if(t)return e();let r=this.read();if(r!==null)return Promise.resolve({done:!1,value:r});if(this[Q])return e();let n,o,h=d=>{this.off("data",a),this.off("end",l),this.off(S,c),e(),o(d)},a=d=>{this.off("error",h),this.off("end",l),this.off(S,c),this.pause(),n({value:d,done:!!this[Q]})},l=()=>{this.off("error",h),this.off("data",a),this.off(S,c),e(),n({done:!0,value:void 0})},c=()=>h(new Error("stream destroyed"));return new Promise((d,y)=>{o=y,n=d,this.once(S,c),this.once("error",h),this.once("end",l),this.once("data",a)})},throw:e,return:e,[Symbol.asyncIterator](){return this},[Symbol.asyncDispose]:async()=>{}}}[Symbol.iterator](){this[C]=!1;let t=!1,e=()=>(this.pause(),this.off(_i,e),this.off(S,e),this.off("end",e),t=!0,{done:!0,value:void 0}),i=()=>{if(t)return e();let r=this.read();return r===null?e():{done:!1,value:r}};return this.once("end",e),this.once(_i,e),this.once(S,e),{next:i,throw:e,return:e,[Symbol.iterator](){return this},[Symbol.dispose]:()=>{}}}destroy(t){if(this[S])return t?this.emit("error",t):this.emit(S),this;this[S]=!0,this[C]=!0,this[b].length=0,this[_]=0;let e=this;return typeof e.close=="function"&&!this[Ne]&&e.close(),t?this.emit("error",t):this.emit(S),this}static get isStream(){return Wr}};var Jr=I.writev,ht=Symbol("_autoClose"),H=Symbol("_close"),te=Symbol("_ended"),m=Symbol("_fd"),Ni=Symbol("_finished"),tt=Symbol("_flags"),Ai=Symbol("_flush"),ki=Symbol("_handleChunk"),vi=Symbol("_makeBuf"),ie=Symbol("_mode"),ke=Symbol("_needDrain"),Ut=Symbol("_onerror"),Ht=Symbol("_onopen"),Ii=Symbol("_onread"),Pt=Symbol("_onwrite"),at=Symbol("_open"),U=Symbol("_path"),ot=Symbol("_pos"),Y=Symbol("_queue"),zt=Symbol("_read"),Ci=Symbol("_readSize"),j=Symbol("_reading"),ee=Symbol("_remain"),Fi=Symbol("_size"),ve=Symbol("_write"),gt=Symbol("_writing"),Me=Symbol("_defaultFlag"),bt=Symbol("_errored"),_t=class extends A{[bt]=!1;[m];[U];[Ci];[j]=!1;[Fi];[ee];[ht];constructor(t,e){if(e=e||{},super(e),this.readable=!0,this.writable=!1,typeof t!="string")throw new TypeError("path must be a string");this[bt]=!1,this[m]=typeof e.fd=="number"?e.fd:void 0,this[U]=t,this[Ci]=e.readSize||16*1024*1024,this[j]=!1,this[Fi]=typeof e.size=="number"?e.size:1/0,this[ee]=this[Fi],this[ht]=typeof e.autoClose=="boolean"?e.autoClose:!0,typeof this[m]=="number"?this[zt]():this[at]()}get fd(){return this[m]}get path(){return this[U]}write(){throw new TypeError("this is a readable stream")}end(){throw new TypeError("this is a readable stream")}[at](){I.open(this[U],"r",(t,e)=>this[Ht](t,e))}[Ht](t,e){t?this[Ut](t):(this[m]=e,this.emit("open",e),this[zt]())}[vi](){return Buffer.allocUnsafe(Math.min(this[Ci],this[ee]))}[zt](){if(!this[j]){this[j]=!0;let t=this[vi]();if(t.length===0)return process.nextTick(()=>this[Ii](null,0,t));I.read(this[m],t,0,t.length,null,(e,i,r)=>this[Ii](e,i,r))}}[Ii](t,e,i){this[j]=!1,t?this[Ut](t):this[ki](e,i)&&this[zt]()}[H](){if(this[ht]&&typeof this[m]=="number"){let t=this[m];this[m]=void 0,I.close(t,e=>e?this.emit("error",e):this.emit("close"))}}[Ut](t){this[j]=!0,this[H](),this.emit("error",t)}[ki](t,e){let i=!1;return this[ee]-=t,t>0&&(i=super.write(tthis[Ht](t,e))}[Ht](t,e){this[Me]&&this[tt]==="r+"&&t&&t.code==="ENOENT"?(this[tt]="w",this[at]()):t?this[Ut](t):(this[m]=e,this.emit("open",e),this[gt]||this[Ai]())}end(t,e){return t&&this.write(t,e),this[te]=!0,!this[gt]&&!this[Y].length&&typeof this[m]=="number"&&this[Pt](null,0),this}write(t,e){return typeof t=="string"&&(t=Buffer.from(t,e)),this[te]?(this.emit("error",new Error("write() after end()")),!1):this[m]===void 0||this[gt]||this[Y].length?(this[Y].push(t),this[ke]=!0,!1):(this[gt]=!0,this[ve](t),!0)}[ve](t){I.write(this[m],t,0,t.length,this[ot],(e,i)=>this[Pt](e,i))}[Pt](t,e){t?this[Ut](t):(this[ot]!==void 0&&typeof e=="number"&&(this[ot]+=e),this[Y].length?this[Ai]():(this[gt]=!1,this[te]&&!this[Ni]?(this[Ni]=!0,this[H](),this.emit("finish")):this[ke]&&(this[ke]=!1,this.emit("drain"))))}[Ai](){if(this[Y].length===0)this[te]&&this[Pt](null,0);else if(this[Y].length===1)this[ve](this[Y].pop());else{let t=this[Y];this[Y]=[],Jr(this[m],t,this[ot],(e,i)=>this[Pt](e,i))}}[H](){if(this[ht]&&typeof this[m]=="number"){let t=this[m];this[m]=void 0,I.close(t,e=>e?this.emit("error",e):this.emit("close"))}}},Wt=class extends et{[at](){let t;if(this[Me]&&this[tt]==="r+")try{t=I.openSync(this[U],this[tt],this[ie])}catch(e){if(e?.code==="ENOENT")return this[tt]="w",this[at]();throw e}else t=I.openSync(this[U],this[tt],this[ie]);this[Ht](null,t)}[H](){if(this[ht]&&typeof this[m]=="number"){let t=this[m];this[m]=void 0,I.closeSync(t),this.emit("close")}}[ve](t){let e=!0;try{this[Pt](null,I.writeSync(this[m],t,0,t.length,this[ot])),e=!1}finally{if(e)try{this[H]()}catch{}}}};import cr from"node:path";import Kt from"node:fs";import{dirname as Fn,parse as kn}from"path";var jr=new Map([["C","cwd"],["f","file"],["z","gzip"],["P","preservePaths"],["U","unlink"],["strip-components","strip"],["stripComponents","strip"],["keep-newer","newer"],["keepNewer","newer"],["keep-newer-files","newer"],["keepNewerFiles","newer"],["k","keep"],["keep-existing","keep"],["keepExisting","keep"],["m","noMtime"],["no-mtime","noMtime"],["p","preserveOwner"],["L","follow"],["h","follow"],["onentry","onReadEntry"]]),Fs=s=>!!s.sync&&!!s.file,ks=s=>!s.sync&&!!s.file,vs=s=>!!s.sync&&!s.file,Ms=s=>!s.sync&&!s.file;var Bs=s=>!!s.file;var tn=s=>{let t=jr.get(s);return t||s},se=(s={})=>{if(!s)return{};let t={};for(let[e,i]of Object.entries(s)){let r=tn(e);t[r]=i}return t.chmod===void 0&&t.noChmod===!1&&(t.chmod=!0),delete t.noChmod,t};var K=(s,t,e,i,r)=>Object.assign((n=[],o,h)=>{Array.isArray(n)&&(o=n,n={}),typeof o=="function"&&(h=o,o=void 0),o=o?Array.from(o):[];let a=se(n);if(r?.(a,o),Fs(a)){if(typeof h=="function")throw new TypeError("callback not supported for sync tar functions");return s(a,o)}else if(ks(a)){let l=t(a,o);return h?l.then(()=>h(),h):l}else if(vs(a)){if(typeof h=="function")throw new TypeError("callback not supported for sync tar functions");return e(a,o)}else if(Ms(a)){if(typeof h=="function")throw new TypeError("callback only supported with file option");return i(a,o)}throw new Error("impossible options??")},{syncFile:s,asyncFile:t,syncNoFile:e,asyncNoFile:i,validate:r});import{EventEmitter as Dn}from"events";import zi from"assert";import{Buffer as Ot}from"buffer";import*as Ps from"zlib";import en from"zlib";var sn=en.constants||{ZLIB_VERNUM:4736},M=Object.freeze(Object.assign(Object.create(null),{Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_MEM_ERROR:-4,Z_BUF_ERROR:-5,Z_VERSION_ERROR:-6,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,DEFLATE:1,INFLATE:2,GZIP:3,GUNZIP:4,DEFLATERAW:5,INFLATERAW:6,UNZIP:7,BROTLI_DECODE:8,BROTLI_ENCODE:9,Z_MIN_WINDOWBITS:8,Z_MAX_WINDOWBITS:15,Z_DEFAULT_WINDOWBITS:15,Z_MIN_CHUNK:64,Z_MAX_CHUNK:1/0,Z_DEFAULT_CHUNK:16384,Z_MIN_MEMLEVEL:1,Z_MAX_MEMLEVEL:9,Z_DEFAULT_MEMLEVEL:8,Z_MIN_LEVEL:-1,Z_MAX_LEVEL:9,Z_DEFAULT_LEVEL:-1,BROTLI_OPERATION_PROCESS:0,BROTLI_OPERATION_FLUSH:1,BROTLI_OPERATION_FINISH:2,BROTLI_OPERATION_EMIT_METADATA:3,BROTLI_MODE_GENERIC:0,BROTLI_MODE_TEXT:1,BROTLI_MODE_FONT:2,BROTLI_DEFAULT_MODE:0,BROTLI_MIN_QUALITY:0,BROTLI_MAX_QUALITY:11,BROTLI_DEFAULT_QUALITY:11,BROTLI_MIN_WINDOW_BITS:10,BROTLI_MAX_WINDOW_BITS:24,BROTLI_LARGE_MAX_WINDOW_BITS:30,BROTLI_DEFAULT_WINDOW:22,BROTLI_MIN_INPUT_BLOCK_BITS:16,BROTLI_MAX_INPUT_BLOCK_BITS:24,BROTLI_PARAM_MODE:0,BROTLI_PARAM_QUALITY:1,BROTLI_PARAM_LGWIN:2,BROTLI_PARAM_LGBLOCK:3,BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING:4,BROTLI_PARAM_SIZE_HINT:5,BROTLI_PARAM_LARGE_WINDOW:6,BROTLI_PARAM_NPOSTFIX:7,BROTLI_PARAM_NDIRECT:8,BROTLI_DECODER_RESULT_ERROR:0,BROTLI_DECODER_RESULT_SUCCESS:1,BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT:2,BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT:3,BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION:0,BROTLI_DECODER_PARAM_LARGE_WINDOW:1,BROTLI_DECODER_NO_ERROR:0,BROTLI_DECODER_SUCCESS:1,BROTLI_DECODER_NEEDS_MORE_INPUT:2,BROTLI_DECODER_NEEDS_MORE_OUTPUT:3,BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_NIBBLE:-1,BROTLI_DECODER_ERROR_FORMAT_RESERVED:-2,BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_META_NIBBLE:-3,BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET:-4,BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME:-5,BROTLI_DECODER_ERROR_FORMAT_CL_SPACE:-6,BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE:-7,BROTLI_DECODER_ERROR_FORMAT_CONTEXT_MAP_REPEAT:-8,BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_1:-9,BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_2:-10,BROTLI_DECODER_ERROR_FORMAT_TRANSFORM:-11,BROTLI_DECODER_ERROR_FORMAT_DICTIONARY:-12,BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS:-13,BROTLI_DECODER_ERROR_FORMAT_PADDING_1:-14,BROTLI_DECODER_ERROR_FORMAT_PADDING_2:-15,BROTLI_DECODER_ERROR_FORMAT_DISTANCE:-16,BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET:-19,BROTLI_DECODER_ERROR_INVALID_ARGUMENTS:-20,BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MODES:-21,BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS:-22,BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MAP:-25,BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_1:-26,BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_2:-27,BROTLI_DECODER_ERROR_ALLOC_BLOCK_TYPE_TREES:-30,BROTLI_DECODER_ERROR_UNREACHABLE:-31},sn));var rn=Ot.concat,zs=Object.getOwnPropertyDescriptor(Ot,"concat"),nn=s=>s,Bi=zs?.writable===!0||zs?.set!==void 0?s=>{Ot.concat=s?nn:rn}:s=>{},Tt=Symbol("_superWrite"),Gt=class extends Error{code;errno;constructor(t,e){super("zlib: "+t.message,{cause:t}),this.code=t.code,this.errno=t.errno,this.code||(this.code="ZLIB_ERROR"),this.message="zlib: "+t.message,Error.captureStackTrace(this,e??this.constructor)}get name(){return"ZlibError"}},Pi=Symbol("flushFlag"),re=class extends A{#t=!1;#i=!1;#s;#n;#r;#e;#o;get sawError(){return this.#t}get handle(){return this.#e}get flushFlag(){return this.#s}constructor(t,e){if(!t||typeof t!="object")throw new TypeError("invalid options for ZlibBase constructor");if(super(t),this.#s=t.flush??0,this.#n=t.finishFlush??0,this.#r=t.fullFlushFlag??0,typeof Ps[e]!="function")throw new TypeError("Compression method not supported: "+e);try{this.#e=new Ps[e](t)}catch(i){throw new Gt(i,this.constructor)}this.#o=i=>{this.#t||(this.#t=!0,this.close(),this.emit("error",i))},this.#e?.on("error",i=>this.#o(new Gt(i))),this.once("end",()=>this.close)}close(){this.#e&&(this.#e.close(),this.#e=void 0,this.emit("close"))}reset(){if(!this.#t)return zi(this.#e,"zlib binding closed"),this.#e.reset?.()}flush(t){this.ended||(typeof t!="number"&&(t=this.#r),this.write(Object.assign(Ot.alloc(0),{[Pi]:t})))}end(t,e,i){return typeof t=="function"&&(i=t,e=void 0,t=void 0),typeof e=="function"&&(i=e,e=void 0),t&&(e?this.write(t,e):this.write(t)),this.flush(this.#n),this.#i=!0,super.end(i)}get ended(){return this.#i}[Tt](t){return super.write(t)}write(t,e,i){if(typeof e=="function"&&(i=e,e="utf8"),typeof t=="string"&&(t=Ot.from(t,e)),this.#t)return;zi(this.#e,"zlib binding closed");let r=this.#e._handle,n=r.close;r.close=()=>{};let o=this.#e.close;this.#e.close=()=>{},Bi(!0);let h;try{let l=typeof t[Pi]=="number"?t[Pi]:this.#s;h=this.#e._processChunk(t,l),Bi(!1)}catch(l){Bi(!1),this.#o(new Gt(l,this.write))}finally{this.#e&&(this.#e._handle=r,r.close=n,this.#e.close=o,this.#e.removeAllListeners("error"))}this.#e&&this.#e.on("error",l=>this.#o(new Gt(l,this.write)));let a;if(h)if(Array.isArray(h)&&h.length>0){let l=h[0];a=this[Tt](Ot.from(l));for(let c=1;c{typeof r=="function"&&(n=r,r=this.flushFlag),this.flush(r),n?.()};try{this.handle.params(t,e)}finally{this.handle.flush=i}this.handle&&(this.#t=t,this.#i=e)}}}};var ze=class extends Pe{#t;constructor(t){super(t,"Gzip"),this.#t=t&&!!t.portable}[Tt](t){return this.#t?(this.#t=!1,t[9]=255,super[Tt](t)):super[Tt](t)}};var Ue=class extends Pe{constructor(t){super(t,"Unzip")}},He=class extends re{constructor(t,e){t=t||{},t.flush=t.flush||M.BROTLI_OPERATION_PROCESS,t.finishFlush=t.finishFlush||M.BROTLI_OPERATION_FINISH,t.fullFlushFlag=M.BROTLI_OPERATION_FLUSH,super(t,e)}},We=class extends He{constructor(t){super(t,"BrotliCompress")}},Ge=class extends He{constructor(t){super(t,"BrotliDecompress")}},Ze=class extends re{constructor(t,e){t=t||{},t.flush=t.flush||M.ZSTD_e_continue,t.finishFlush=t.finishFlush||M.ZSTD_e_end,t.fullFlushFlag=M.ZSTD_e_flush,super(t,e)}},Ye=class extends Ze{constructor(t){super(t,"ZstdCompress")}},Ke=class extends Ze{constructor(t){super(t,"ZstdDecompress")}};import{posix as Zt}from"node:path";var Us=(s,t)=>{if(Number.isSafeInteger(s))s<0?an(s,t):hn(s,t);else throw Error("cannot encode number outside of javascript safe integer range");return t},hn=(s,t)=>{t[0]=128;for(var e=t.length;e>1;e--)t[e-1]=s&255,s=Math.floor(s/256)},an=(s,t)=>{t[0]=255;var e=!1;s=s*-1;for(var i=t.length;i>1;i--){var r=s&255;s=Math.floor(s/256),e?t[i-1]=Ws(r):r===0?t[i-1]=0:(e=!0,t[i-1]=Gs(r))}},Hs=s=>{let t=s[0],e=t===128?cn(s.subarray(1,s.length)):t===255?ln(s):null;if(e===null)throw Error("invalid base256 encoding");if(!Number.isSafeInteger(e))throw Error("parsed number outside of javascript safe integer range");return e},ln=s=>{for(var t=s.length,e=0,i=!1,r=t-1;r>-1;r--){var n=Number(s[r]),o;i?o=Ws(n):n===0?o=n:(i=!0,o=Gs(n)),o!==0&&(e-=o*Math.pow(256,t-r-1))}return e},cn=s=>{for(var t=s.length,e=0,i=t-1;i>-1;i--){var r=Number(s[i]);r!==0&&(e+=r*Math.pow(256,t-i-1))}return e},Ws=s=>(255^s)&255,Gs=s=>(255^s)+1&255;var Hi={};Ur(Hi,{code:()=>Ve,isCode:()=>ne,isName:()=>dn,name:()=>oe,normalFsTypes:()=>Ui});var ne=s=>oe.has(s),dn=s=>Ve.has(s),Ui=new Set(["0","","1","2","3","4","5","6","7","D"]),oe=new Map([["0","File"],["","OldFile"],["1","Link"],["2","SymbolicLink"],["3","CharacterDevice"],["4","BlockDevice"],["5","Directory"],["6","FIFO"],["7","ContiguousFile"],["g","GlobalExtendedHeader"],["x","ExtendedHeader"],["A","SolarisACL"],["D","GNUDumpDir"],["I","Inode"],["K","NextFileHasLongLinkpath"],["L","NextFileHasLongPath"],["M","ContinuationFile"],["N","OldGnuLongPath"],["S","SparseFile"],["V","TapeVolumeHeader"],["X","OldExtendedHeader"]]),Ve=new Map(Array.from(oe).map(s=>[s[1],s[0]]));var un=s=>s===void 0||s<0?void 0:s,F=class{cksumValid=!1;needPax=!1;nullBlock=!1;block;path;mode;uid;gid;size;cksum;#t="Unsupported";linkpath;uname;gname;devmaj=0;devmin=0;atime;ctime;mtime;charset;comment;constructor(t,e=0,i,r){Buffer.isBuffer(t)?this.decode(t,e||0,i,r):t&&this.#i(t)}decode(t,e,i,r){if(e||(e=0),!t||!(t.length>=e+512))throw new Error("need 512 bytes for header");let n=xt(t,e+156,1),o=Ui.has(n),h=o?i:void 0,a=o?r:void 0;if(this.path=h?.path??xt(t,e,100),this.mode=h?.mode??a?.mode??lt(t,e+100,8),this.uid=h?.uid??a?.uid??lt(t,e+108,8),this.gid=h?.gid??a?.gid??lt(t,e+116,8),this.size=un(h?.size??a?.size??lt(t,e+124,12)),this.mtime=h?.mtime??a?.mtime??Wi(t,e+136,12),this.cksum=lt(t,e+148,12),a&&this.#i(a,!0),h&&this.#i(h),ne(n)&&(this.#t=n||"0"),this.#t==="0"&&this.path.slice(-1)==="/"&&(this.#t="5"),this.#t==="5"&&(this.size=0),this.linkpath=xt(t,e+157,100),t.subarray(e+257,e+265).toString()==="ustar\x0000")if(this.uname=h?.uname??a?.uname??xt(t,e+265,32),this.gname=h?.gname??a?.gname??xt(t,e+297,32),this.devmaj=h?.devmaj??a?.devmaj??lt(t,e+329,8)??0,this.devmin=h?.devmin??a?.devmin??lt(t,e+337,8)??0,t[e+475]!==0){let c=xt(t,e+345,155);this.path=c+"/"+this.path}else{let c=xt(t,e+345,130);c&&(this.path=c+"/"+this.path),this.atime=i?.atime??r?.atime??Wi(t,e+476,12),this.ctime=i?.ctime??r?.ctime??Wi(t,e+488,12)}let l=256;for(let c=e;c!(r==null||i==="size"&&Number(r)<0||i==="path"&&e||i==="linkpath"&&e||i==="global"))))}encode(t,e=0){if(t||(t=this.block=Buffer.alloc(512)),this.#t==="Unsupported"&&(this.#t="0"),!(t.length>=e+512))throw new Error("need 512 bytes for header");let i=this.ctime||this.atime?130:155,r=mn(this.path||"",i),n=r[0],o=r[1];this.needPax=!!r[2],this.needPax=Lt(t,e,100,n)||this.needPax,this.needPax=ct(t,e+100,8,this.mode)||this.needPax,this.needPax=ct(t,e+108,8,this.uid)||this.needPax,this.needPax=ct(t,e+116,8,this.gid)||this.needPax,this.needPax=ct(t,e+124,12,this.size)||this.needPax,this.needPax=Gi(t,e+136,12,this.mtime)||this.needPax,t[e+156]=Number(this.#t.codePointAt(0)),this.needPax=Lt(t,e+157,100,this.linkpath)||this.needPax,t.write("ustar\x0000",e+257,8),this.needPax=Lt(t,e+265,32,this.uname)||this.needPax,this.needPax=Lt(t,e+297,32,this.gname)||this.needPax,this.needPax=ct(t,e+329,8,this.devmaj)||this.needPax,this.needPax=ct(t,e+337,8,this.devmin)||this.needPax,this.needPax=Lt(t,e+345,i,o)||this.needPax,t[e+475]!==0?this.needPax=Lt(t,e+345,155,o)||this.needPax:(this.needPax=Lt(t,e+345,130,o)||this.needPax,this.needPax=Gi(t,e+476,12,this.atime)||this.needPax,this.needPax=Gi(t,e+488,12,this.ctime)||this.needPax);let h=256;for(let a=e;a{let i=s,r="",n,o=Zt.parse(s).root||".";if(Buffer.byteLength(i)<100)n=[i,r,!1];else{r=Zt.dirname(i),i=Zt.basename(i);do Buffer.byteLength(i)<=100&&Buffer.byteLength(r)<=t?n=[i,r,!1]:Buffer.byteLength(i)>100&&Buffer.byteLength(r)<=t?n=[i.slice(0,99),r,!0]:(i=Zt.join(Zt.basename(r),i),r=Zt.dirname(r));while(r!==o&&n===void 0);n||(n=[s.slice(0,99),"",!0])}return n},xt=(s,t,e)=>s.subarray(t,t+e).toString("utf8").replace(/\0.*/,""),Wi=(s,t,e)=>pn(lt(s,t,e)),pn=s=>s===void 0?void 0:new Date(s*1e3),lt=(s,t,e)=>Number(s[t])&128?Hs(s.subarray(t,t+e)):wn(s,t,e),En=s=>isNaN(s)?void 0:s,wn=(s,t,e)=>En(parseInt(s.subarray(t,t+e).toString("utf8").replace(/\0.*$/,"").trim(),8)),Sn={12:8589934591,8:2097151},ct=(s,t,e,i)=>i===void 0?!1:i>Sn[e]||i<0?(Us(i,s.subarray(t,t+e)),!0):(yn(s,t,e,i),!1),yn=(s,t,e,i)=>s.write(Rn(i,e),t,e,"ascii"),Rn=(s,t)=>gn(Math.floor(s).toString(8),t),gn=(s,t)=>(s.length===t-1?s:new Array(t-s.length-1).join("0")+s+" ")+"\0",Gi=(s,t,e,i)=>i===void 0?!1:ct(s,t,e,i.getTime()/1e3),bn=new Array(156).join("\0"),Lt=(s,t,e,i)=>i===void 0?!1:(s.write(i+bn,t,e,"utf8"),i.length!==Buffer.byteLength(i)||i.length>e);import{basename as _n}from"node:path";var ft=class s{atime;mtime;ctime;charset;comment;gid;uid;gname;uname;linkpath;dev;ino;nlink;path;size;mode;global;constructor(t,e=!1){this.atime=t.atime,this.charset=t.charset,this.comment=t.comment,this.ctime=t.ctime,this.dev=t.dev,this.gid=t.gid,this.global=e,this.gname=t.gname,this.ino=t.ino,this.linkpath=t.linkpath,this.mtime=t.mtime,this.nlink=t.nlink,this.path=t.path,this.size=t.size,this.uid=t.uid,this.uname=t.uname}encode(){let t=this.encodeBody();if(t==="")return Buffer.allocUnsafe(0);let e=Buffer.byteLength(t),i=512*Math.ceil(1+e/512),r=Buffer.allocUnsafe(i);for(let n=0;n<512;n++)r[n]=0;new F({path:("PaxHeader/"+_n(this.path??"")).slice(0,99),mode:this.mode||420,uid:this.uid,gid:this.gid,size:e,mtime:this.mtime,type:this.global?"GlobalExtendedHeader":"ExtendedHeader",linkpath:"",uname:this.uname||"",gname:this.gname||"",devmaj:0,devmin:0,atime:this.atime,ctime:this.ctime}).encode(r),r.write(t,512,e,"utf8");for(let n=e+512;n=Math.pow(10,o)&&(o+=1),o+n+r}static parse(t,e,i=!1){return new s(On(Tn(t),e),i)}},On=(s,t)=>t?Object.assign({},t,s):s,Tn=s=>s.replace(/\n$/,"").split(` -`).reduce(xn,Object.create(null)),xn=(s,t)=>{let e=parseInt(t,10);if(e!==Buffer.byteLength(t)+1)return s;t=t.slice((e+" ").length);let i=t.split("="),r=i.shift();if(!r)return s;let n=r.replace(/^SCHILY\.(dev|ino|nlink)/,"$1"),o=i.join("=").replace(/\0.*/,"");switch(n){case"path":case"linkpath":case"type":case"charset":case"comment":case"gname":case"uname":s[n]=o;break;case"ctime":case"atime":case"mtime":s[n]=new Date(Number(o)*1e3);break;case"size":let h=+o;h>=0&&(s[n]=h);break;case"gid":case"uid":case"dev":case"ino":case"nlink":case"mode":s[n]=+o;break}return s};var Ln=process.env.TESTING_TAR_FAKE_PLATFORM||process.platform,f=Ln!=="win32"?s=>String(s):s=>String(s).replaceAll(/\\/g,"/");var $e=class extends A{extended;globalExtended;header;startBlockSize;blockRemain;remain;type;meta=!1;ignore=!1;path;mode;uid;gid;uname;gname;size=0;mtime;atime;ctime;linkpath;dev;ino;nlink;invalid=!1;absolute;unsupported=!1;constructor(t,e,i){switch(super({}),this.pause(),this.extended=e,this.globalExtended=i,this.header=t,this.remain=t.size??0,this.startBlockSize=512*Math.ceil(this.remain/512),this.blockRemain=this.startBlockSize,this.type=t.type,this.type){case"File":case"OldFile":case"Link":case"SymbolicLink":case"CharacterDevice":case"BlockDevice":case"Directory":case"FIFO":case"ContiguousFile":case"GNUDumpDir":break;case"NextFileHasLongLinkpath":case"NextFileHasLongPath":case"OldGnuLongPath":case"GlobalExtendedHeader":case"ExtendedHeader":case"OldExtendedHeader":this.meta=!0;break;default:this.ignore=!0}if(!t.path)throw new Error("no path provided for tar.ReadEntry");this.path=f(t.path),this.mode=t.mode,this.mode&&(this.mode=this.mode&4095),this.uid=t.uid,this.gid=t.gid,this.uname=t.uname,this.gname=t.gname,this.size=this.remain,this.mtime=t.mtime,this.atime=t.atime,this.ctime=t.ctime,this.linkpath=t.linkpath?f(t.linkpath):void 0,this.uname=t.uname,this.gname=t.gname,e&&this.#t(e),i&&this.#t(i,!0)}write(t){let e=t.length;if(e>this.blockRemain)throw new Error("writing more to entry than is appropriate");let i=this.remain,r=this.blockRemain;return this.remain=Math.max(0,i-e),this.blockRemain=Math.max(0,r-e),this.ignore?!0:i>=e?super.write(t):super.write(t.subarray(0,i))}#t(t,e=!1){t.path&&(t.path=f(t.path)),t.linkpath&&(t.linkpath=f(t.linkpath)),Object.assign(this,Object.fromEntries(Object.entries(t).filter(([i,r])=>!(r==null||i==="path"&&e))))}};var Dt=(s,t,e,i={})=>{s.file&&(i.file=s.file),s.cwd&&(i.cwd=s.cwd),i.code=e instanceof Error&&e.code||t,i.tarCode=t,!s.strict&&i.recoverable!==!1?(e instanceof Error&&(i=Object.assign(e,i),e=e.message),s.emit("warn",t,e,i)):e instanceof Error?s.emit("error",Object.assign(e,i)):s.emit("error",Object.assign(new Error(`${t}: ${e}`),i))};var Nn=1024*1024,Xi=Buffer.from([31,139]),qi=Buffer.from([40,181,47,253]),An=Math.max(Xi.length,qi.length),B=Symbol("state"),Nt=Symbol("writeEntry"),it=Symbol("readEntry"),Zi=Symbol("nextEntry"),Zs=Symbol("processEntry"),V=Symbol("extendedHeader"),he=Symbol("globalExtendedHeader"),dt=Symbol("meta"),Ys=Symbol("emitMeta"),p=Symbol("buffer"),st=Symbol("queue"),mt=Symbol("ended"),Yi=Symbol("emittedEnd"),At=Symbol("emit"),y=Symbol("unzip"),Xe=Symbol("consumeChunk"),qe=Symbol("consumeChunkSub"),Ki=Symbol("consumeBody"),Ks=Symbol("consumeMeta"),Vs=Symbol("consumeHeader"),ae=Symbol("consuming"),Vi=Symbol("bufferConcat"),Qe=Symbol("maybeEnd"),Yt=Symbol("writing"),$=Symbol("aborted"),Je=Symbol("onDone"),It=Symbol("sawValidEntry"),je=Symbol("sawNullBlock"),ti=Symbol("sawEOF"),$s=Symbol("closeStream"),In=1e3,le=Symbol("compressedBytesRead"),$i=Symbol("decompressedBytesRead"),Xs=Symbol("checkDecompressionRatio"),Cn=()=>!0,rt=class extends Dn{file;strict;maxMetaEntrySize;filter;brotli;zstd;maxDecompressionRatio;writable=!0;readable=!1;[st]=[];[p];[it];[Nt];[B]="begin";[dt]="";[V];[he];[mt]=!1;[y];[$]=!1;[It];[je]=!1;[ti]=!1;[Yt]=!1;[ae]=!1;[Yi]=!1;[le]=0;[$i]=0;constructor(t={}){super(),this.file=t.file||"",this.on(Je,()=>{(this[B]==="begin"||this[It]===!1)&&this.warn("TAR_BAD_ARCHIVE","Unrecognized archive format")}),t.ondone?this.on(Je,t.ondone):this.on(Je,()=>{this.emit("prefinish"),this.emit("finish"),this.emit("end")}),this.strict=!!t.strict,this.maxDecompressionRatio=typeof t.maxDecompressionRatio=="number"?t.maxDecompressionRatio:In,this.maxMetaEntrySize=t.maxMetaEntrySize||Nn,this.filter=typeof t.filter=="function"?t.filter:Cn;let e=t.file&&(t.file.endsWith(".tar.br")||t.file.endsWith(".tbr"));this.brotli=!(t.gzip||t.zstd)&&t.brotli!==void 0?t.brotli:e?void 0:!1;let i=t.file&&(t.file.endsWith(".tar.zst")||t.file.endsWith(".tzst"));this.zstd=!(t.gzip||t.brotli)&&t.zstd!==void 0?t.zstd:i?!0:void 0,this.on("end",()=>this[$s]()),typeof t.onwarn=="function"&&this.on("warn",t.onwarn),typeof t.onReadEntry=="function"&&this.on("entry",t.onReadEntry)}warn(t,e,i={}){Dt(this,t,e,i)}[Vs](t,e){this[It]===void 0&&(this[It]=!1);let i;try{i=new F(t,e,this[V],this[he])}catch(r){return this.warn("TAR_ENTRY_INVALID",r)}if(i.nullBlock)this[je]?(this[ti]=!0,this[B]==="begin"&&(this[B]="header"),this[At]("eof")):(this[je]=!0,this[At]("nullBlock"));else if(this[je]=!1,!i.cksumValid)this.warn("TAR_ENTRY_INVALID","checksum failure",{header:i});else if(!i.path)this.warn("TAR_ENTRY_INVALID","path is required",{header:i});else{let r=i.type;if(/^(Symbolic)?Link$/.test(r)&&!i.linkpath)this.warn("TAR_ENTRY_INVALID","linkpath required",{header:i});else if(!/^(Symbolic)?Link$/.test(r)&&!/^(Global)?ExtendedHeader$/.test(r)&&i.linkpath)this.warn("TAR_ENTRY_INVALID","linkpath forbidden",{header:i});else{let n=this[Nt]=new $e(i,this[V],this[he]);if(!this[It])if(n.remain){let o=()=>{n.invalid||(this[It]=!0)};n.on("end",o)}else this[It]=!0;n.meta?n.size>this.maxMetaEntrySize?(n.ignore=!0,this[At]("ignoredEntry",n),this[B]="ignore",n.resume()):n.size>0&&(this[dt]="",n.on("data",o=>this[dt]+=o),this[B]="meta"):(this[V]=void 0,n.ignore=n.ignore||!this.filter(n.path,n),n.ignore?(this[At]("ignoredEntry",n),this[B]=n.remain?"ignore":"header",n.resume()):(n.remain?this[B]="body":(this[B]="header",n.end()),this[it]?this[st].push(n):(this[st].push(n),this[Zi]())))}}}[$s](){queueMicrotask(()=>this.emit("close"))}[Zs](t){let e=!0;if(!t)this[it]=void 0,e=!1;else if(Array.isArray(t)){let[i,...r]=t;this.emit(i,...r)}else this[it]=t,this.emit("entry",t),t.emittedEnd||(t.on("end",()=>this[Zi]()),e=!1);return e}[Zi](){do;while(this[Zs](this[st].shift()));if(this[st].length===0){let t=this[it];!t||t.flowing||t.size===t.remain?this[Yt]||this.emit("drain"):t.once("drain",()=>this.emit("drain"))}}[Ki](t,e){let i=this[Nt];if(!i)throw new Error("attempt to consume body without entry??");let r=i.blockRemain??0,n=r>=t.length&&e===0?t:t.subarray(e,e+r);return i.write(n),i.blockRemain||(this[B]="header",this[Nt]=void 0,i.end()),n.length}[Ks](t,e){let i=this[Nt],r=this[Ki](t,e);return!this[Nt]&&i&&this[Ys](i),r}[At](t,e,i){this[st].length===0&&!this[it]?this.emit(t,e,i):this[st].push([t,e,i])}[Ys](t){switch(this[At]("meta",this[dt]),t.type){case"ExtendedHeader":case"OldExtendedHeader":this[V]=ft.parse(this[dt],this[V],!1);break;case"GlobalExtendedHeader":this[he]=ft.parse(this[dt],this[he],!0);break;case"NextFileHasLongPath":case"OldGnuLongPath":{let e=this[V]??Object.create(null);this[V]=e,e.path=this[dt].replace(/\0.*/,"");break}case"NextFileHasLongLinkpath":{let e=this[V]||Object.create(null);this[V]=e,e.linkpath=this[dt].replace(/\0.*/,"");break}default:throw new Error("unknown meta: "+t.type)}}abort(t){this[$]||(this[$]=!0,this.emit("abort",t),this.warn("TAR_ABORT",t,{recoverable:!1}))}[Xs](t){this[$i]+=t.length;let e=this[$i]/this[le];return e>this.maxDecompressionRatio?(this.abort(new Error(`max decompression ratio exceeded: ${e.toFixed(2)} > ${this.maxDecompressionRatio}`)),!1):!0}write(t,e,i){if(typeof e=="function"&&(i=e,e=void 0),typeof t=="string"&&(t=Buffer.from(t,typeof e=="string"?e:"utf8")),this[$])return i?.(),!1;if((this[y]===void 0||this.brotli===void 0&&this[y]===!1)&&t){if(this[p]&&(t=Buffer.concat([this[p],t]),this[p]=void 0),t.length{this[Xs](c)&&this[Xe](c)}),this[y].on("error",c=>{this[$]||this.abort(c)}),this[y].on("end",()=>{this[mt]=!0,this[Xe]()}),this[Yt]=!0,this[le]+=t.length;let l=!!this[y][a?"end":"write"](t);return this[Yt]=!1,i?.(),l}}this[Yt]=!0,this[y]?(this[le]+=t.length,this[y].write(t)):this[Xe](t),this[Yt]=!1;let n=this[st].length>0?!1:this[it]?this[it].flowing:!0;return!n&&this[st].length===0&&this[it]?.once("drain",()=>this.emit("drain")),i?.(),n}[Vi](t){t&&!this[$]&&(this[p]=this[p]?Buffer.concat([this[p],t]):t)}[Qe](){if(this[mt]&&!this[Yi]&&!this[$]&&!this[ae]){this[Yi]=!0;let t=this[Nt];if(t?.blockRemain){let e=this[p]?this[p].length:0;this.warn("TAR_BAD_ARCHIVE",`Truncated input (needed ${t.blockRemain} more bytes, only ${e} available)`,{entry:t}),this[p]&&t.write(this[p]),t.end()}this[At](Je)}}[Xe](t){if(this[ae]&&t)this[Vi](t);else if(!t&&!this[p])this[Qe]();else if(t){if(this[ae]=!0,this[p]){this[Vi](t);let e=this[p];this[p]=void 0,this[qe](e)}else this[qe](t);for(;this[p]&&this[p]?.length>=512&&!this[$]&&!this[ti];){let e=this[p];this[p]=void 0,this[qe](e)}this[ae]=!1}(!this[p]||this[mt])&&this[Qe]()}[qe](t){let e=0,i=t.length;for(;e+512<=i&&!this[$]&&!this[ti];)switch(this[B]){case"begin":case"header":this[Vs](t,e),e+=512;break;case"ignore":case"body":e+=this[Ki](t,e);break;case"meta":e+=this[Ks](t,e);break;default:throw new Error("invalid state: "+this[B])}e{let t=s.length-1,e=-1;for(;t>-1&&s.charAt(t)==="/";)e=t,t--;return e===-1?s:s.slice(0,e)};var vn=s=>{let t=s.onReadEntry;s.onReadEntry=t?e=>{t(e),e.resume()}:e=>e.resume()},Qi=(s,t)=>{let e=new Map(t.map(n=>[ut(n),!0])),i=s.filter,r=(n,o="")=>{let h=o||kn(n).root||".",a;if(n===h)a=!1;else{let l=e.get(n);a=l!==void 0?l:r(Fn(n),h)}return e.set(n,a),a};s.filter=i?(n,o)=>i(n,o)&&r(ut(n)):n=>r(ut(n))},Mn=s=>{let t=new rt(s),e=s.file,i;try{i=Kt.openSync(e,"r");let r=Kt.fstatSync(i),n=s.maxReadSize||16*1024*1024;if(r.size{let e=new rt(s),i=s.maxReadSize||16*1024*1024,r=s.file;return new Promise((o,h)=>{e.on("error",h),e.on("end",o),Kt.stat(r,(a,l)=>{if(a)h(a);else{let c=new _t(r,{readSize:i,size:l.size});c.on("error",h),c.pipe(e)}})})},Ct=K(Mn,Bn,s=>new rt(s),s=>new rt(s),(s,t)=>{t?.length&&Qi(s,t),s.noResume||vn(s)});import ui from"fs";import X from"fs";import js from"path";var Ji=(s,t,e)=>(s&=4095,e&&(s=(s|384)&-19),t&&(s&256&&(s|=64),s&32&&(s|=8),s&4&&(s|=1)),s);import{win32 as Pn}from"node:path";var{isAbsolute:zn,parse:qs}=Pn,ce=s=>{let t="",e=qs(s);for(;zn(s)||e.root;){let i=s.charAt(0)==="/"&&s.slice(0,4)!=="//?/"?"/":e.root;s=s.slice(i.length),t+=i,e=qs(s)}return[t,s]};var ei=["|","<",">","?",":"],ji=ei.map(s=>String.fromCodePoint(61440+Number(s.codePointAt(0)))),Un=new Map(ei.map((s,t)=>[s,ji[t]])),Hn=new Map(ji.map((s,t)=>[s,ei[t]])),ts=s=>ei.reduce((t,e)=>t.split(e).join(Un.get(e)),s),Qs=s=>ji.reduce((t,e)=>t.split(e).join(Hn.get(e)),s);var rr=(s,t)=>t?(s=f(s).replace(/^\.(\/|$)/,""),ut(t)+"/"+s):f(s),Wn=16*1024*1024,tr=Symbol("process"),er=Symbol("file"),ir=Symbol("directory"),is=Symbol("symlink"),sr=Symbol("hardlink"),fe=Symbol("header"),ii=Symbol("read"),ss=Symbol("lstat"),si=Symbol("onlstat"),rs=Symbol("onread"),ns=Symbol("onreadlink"),os=Symbol("openfile"),hs=Symbol("onopenfile"),pt=Symbol("close"),ri=Symbol("mode"),as=Symbol("awaitDrain"),es=Symbol("ondrain"),q=Symbol("prefix"),de=class extends A{path;portable;myuid=process.getuid&&process.getuid()||0;myuser=process.env.USER||"";maxReadSize;linkCache;statCache;preservePaths;cwd;strict;mtime;noPax;noMtime;prefix;fd;blockLen=0;blockRemain=0;buf;pos=0;remain=0;length=0;offset=0;win32;absolute;header;type;linkpath;stat;onWriteEntry;#t=!1;constructor(t,e={}){let i=se(e);super(),this.path=f(t),this.portable=!!i.portable,this.maxReadSize=i.maxReadSize||Wn,this.linkCache=i.linkCache||new Map,this.statCache=i.statCache||new Map,this.preservePaths=!!i.preservePaths,this.cwd=f(i.cwd||process.cwd()),this.strict=!!i.strict,this.noPax=!!i.noPax,this.noMtime=!!i.noMtime,this.mtime=i.mtime,this.prefix=i.prefix?f(i.prefix):void 0,this.onWriteEntry=i.onWriteEntry,typeof i.onwarn=="function"&&this.on("warn",i.onwarn);let r=!1;if(!this.preservePaths){let[o,h]=ce(this.path);o&&typeof h=="string"&&(this.path=h,r=o)}this.win32=!!i.win32||process.platform==="win32",this.win32&&(this.path=Qs(this.path.replaceAll(/\\/g,"/")),t=t.replaceAll(/\\/g,"/")),this.absolute=f(i.absolute||js.resolve(this.cwd,t)),this.path===""&&(this.path="./"),r&&this.warn("TAR_ENTRY_INFO",`stripping ${r} from absolute path`,{entry:this,path:r+this.path});let n=this.statCache.get(this.absolute);n?this[si](n):this[ss]()}warn(t,e,i={}){return Dt(this,t,e,i)}emit(t,...e){return t==="error"&&(this.#t=!0),super.emit(t,...e)}[ss](){X.lstat(this.absolute,(t,e)=>{if(t)return this.emit("error",t);this[si](e)})}[si](t){this.statCache.set(this.absolute,t),this.stat=t,t.isFile()||(t.size=0),this.type=Gn(t),this.emit("stat",t),this[tr]()}[tr](){switch(this.type){case"File":return this[er]();case"Directory":return this[ir]();case"SymbolicLink":return this[is]();default:return this.end()}}[ri](t){return Ji(t,this.type==="Directory",this.portable)}[q](t){return rr(t,this.prefix)}[fe](){if(!this.stat)throw new Error("cannot write header before stat");this.type==="Directory"&&this.portable&&(this.noMtime=!0),this.onWriteEntry?.(this),this.header=new F({path:this[q](this.path),linkpath:this.type==="Link"&&this.linkpath!==void 0?this[q](this.linkpath):this.linkpath,mode:this[ri](this.stat.mode),uid:this.portable?void 0:this.stat.uid,gid:this.portable?void 0:this.stat.gid,size:this.stat.size,mtime:this.noMtime?void 0:this.mtime||this.stat.mtime,type:this.type==="Unsupported"?void 0:this.type,uname:this.portable?void 0:this.stat.uid===this.myuid?this.myuser:"",atime:this.portable?void 0:this.stat.atime,ctime:this.portable?void 0:this.stat.ctime}),this.header.encode()&&!this.noPax&&super.write(new ft({atime:this.portable?void 0:this.header.atime,ctime:this.portable?void 0:this.header.ctime,gid:this.portable?void 0:this.header.gid,mtime:this.noMtime?void 0:this.mtime||this.header.mtime,path:this[q](this.path),linkpath:this.type==="Link"&&this.linkpath!==void 0?this[q](this.linkpath):this.linkpath,size:this.header.size,uid:this.portable?void 0:this.header.uid,uname:this.portable?void 0:this.header.uname,dev:this.portable?void 0:this.stat.dev,ino:this.portable?void 0:this.stat.ino,nlink:this.portable?void 0:this.stat.nlink}).encode());let t=this.header?.block;if(!t)throw new Error("failed to encode header");super.write(t)}[ir](){if(!this.stat)throw new Error("cannot create directory entry without stat");this.path.slice(-1)!=="/"&&(this.path+="/"),this.stat.size=0,this[fe](),this.end()}[is](){X.readlink(this.absolute,(t,e)=>{if(t)return this.emit("error",t);this[ns](e)})}[ns](t){this.linkpath=f(t),this[fe](),this.end()}[sr](t){if(!this.stat)throw new Error("cannot create link entry without stat");this.type="Link",this.linkpath=f(js.relative(this.cwd,t)),this.stat.size=0,this[fe](),this.end()}[er](){if(!this.stat)throw new Error("cannot create file entry without stat");if(this.stat.nlink>1){let t=`${this.stat.dev}:${this.stat.ino}`,e=this.linkCache.get(t);if(e?.indexOf(this.cwd)===0)return this[sr](e);this.linkCache.set(t,this.absolute)}if(this[fe](),this.stat.size===0)return this.end();this[os]()}[os](){X.open(this.absolute,"r",(t,e)=>{if(t)return this.emit("error",t);this[hs](e)})}[hs](t){if(this.fd=t,this.#t)return this[pt]();if(!this.stat)throw new Error("should stat before calling onopenfile");this.blockLen=512*Math.ceil(this.stat.size/512),this.blockRemain=this.blockLen;let e=Math.min(this.blockLen,this.maxReadSize);this.buf=Buffer.allocUnsafe(e),this.offset=0,this.pos=0,this.remain=this.stat.size,this.length=this.buf.length,this[ii]()}[ii](){let{fd:t,buf:e,offset:i,length:r,pos:n}=this;if(t===void 0||e===void 0)throw new Error("cannot read file without first opening");X.read(t,e,i,r,n,(o,h)=>{if(o)return this[pt](()=>this.emit("error",o));this[rs](h)})}[pt](t=()=>{}){this.fd!==void 0&&X.close(this.fd,t)}[rs](t){if(t<=0&&this.remain>0){let r=Object.assign(new Error("encountered unexpected EOF"),{path:this.absolute,syscall:"read",code:"EOF"});return this[pt](()=>this.emit("error",r))}if(t>this.remain){let r=Object.assign(new Error("did not encounter expected EOF"),{path:this.absolute,syscall:"read",code:"EOF"});return this[pt](()=>this.emit("error",r))}if(!this.buf)throw new Error("should have created buffer prior to reading");if(t===this.remain)for(let r=t;rthis[es]())}[as](t){this.once("drain",t)}write(t,e,i){if(typeof e=="function"&&(i=e,e=void 0),typeof t=="string"&&(t=Buffer.from(t,typeof e=="string"?e:"utf8")),this.blockRemaint?this.emit("error",t):this.end());if(!this.buf)throw new Error("buffer lost somehow in ONDRAIN");this.offset>=this.length&&(this.buf=Buffer.allocUnsafe(Math.min(this.blockRemain,this.buf.length)),this.offset=0),this.length=this.buf.length-this.offset,this[ii]()}},ni=class extends de{sync=!0;[ss](){this[si](X.lstatSync(this.absolute))}[is](){this[ns](X.readlinkSync(this.absolute))}[os](){this[hs](X.openSync(this.absolute,"r"))}[ii](){let t=!0;try{let{fd:e,buf:i,offset:r,length:n,pos:o}=this;if(e===void 0||i===void 0)throw new Error("fd and buf must be set in READ method");let h=X.readSync(e,i,r,n,o);this[rs](h),t=!1}finally{if(t)try{this[pt](()=>{})}catch{}}}[as](t){t()}[pt](t=()=>{}){this.fd!==void 0&&X.closeSync(this.fd),t()}},oi=class extends A{blockLen=0;blockRemain=0;buf=0;pos=0;remain=0;length=0;preservePaths;portable;strict;noPax;noMtime;readEntry;type;prefix;path;mode;uid;gid;uname;gname;header;mtime;atime;ctime;linkpath;size;onWriteEntry;warn(t,e,i={}){return Dt(this,t,e,i)}constructor(t,e={}){let i=se(e);super(),this.preservePaths=!!i.preservePaths,this.portable=!!i.portable,this.strict=!!i.strict,this.noPax=!!i.noPax,this.noMtime=!!i.noMtime,this.onWriteEntry=i.onWriteEntry,this.readEntry=t;let{type:r}=t;if(r==="Unsupported")throw new Error("writing entry that should be ignored");this.type=r,this.type==="Directory"&&this.portable&&(this.noMtime=!0),this.prefix=i.prefix,this.path=f(t.path),this.mode=t.mode!==void 0?this[ri](t.mode):void 0,this.uid=this.portable?void 0:t.uid,this.gid=this.portable?void 0:t.gid,this.uname=this.portable?void 0:t.uname,this.gname=this.portable?void 0:t.gname,this.size=t.size,this.mtime=this.noMtime?void 0:i.mtime||t.mtime,this.atime=this.portable?void 0:t.atime,this.ctime=this.portable?void 0:t.ctime,this.linkpath=t.linkpath!==void 0?f(t.linkpath):void 0,typeof i.onwarn=="function"&&this.on("warn",i.onwarn);let n=!1;if(!this.preservePaths){let[h,a]=ce(this.path);h&&typeof a=="string"&&(this.path=a,n=h)}this.remain=t.size,this.blockRemain=t.startBlockSize,this.onWriteEntry?.(this),this.header=new F({path:this[q](this.path),linkpath:this.type==="Link"&&this.linkpath!==void 0?this[q](this.linkpath):this.linkpath,mode:this.mode,uid:this.portable?void 0:this.uid,gid:this.portable?void 0:this.gid,size:this.size,mtime:this.noMtime?void 0:this.mtime,type:this.type,uname:this.portable?void 0:this.uname,atime:this.portable?void 0:this.atime,ctime:this.portable?void 0:this.ctime}),n&&this.warn("TAR_ENTRY_INFO",`stripping ${n} from absolute path`,{entry:this,path:n+this.path}),this.header.encode()&&!this.noPax&&super.write(new ft({atime:this.portable?void 0:this.atime,ctime:this.portable?void 0:this.ctime,gid:this.portable?void 0:this.gid,mtime:this.noMtime?void 0:this.mtime,path:this[q](this.path),linkpath:this.type==="Link"&&this.linkpath!==void 0?this[q](this.linkpath):this.linkpath,size:this.size,uid:this.portable?void 0:this.uid,uname:this.portable?void 0:this.uname,dev:this.portable?void 0:this.readEntry.dev,ino:this.portable?void 0:this.readEntry.ino,nlink:this.portable?void 0:this.readEntry.nlink}).encode());let o=this.header?.block;if(!o)throw new Error("failed to encode header");super.write(o),t.pipe(this)}[q](t){return rr(t,this.prefix)}[ri](t){return Ji(t,this.type==="Directory",this.portable)}write(t,e,i){typeof e=="function"&&(i=e,e=void 0),typeof t=="string"&&(t=Buffer.from(t,typeof e=="string"?e:"utf8"));let r=t.length;if(r>this.blockRemain)throw new Error("writing more to entry than is appropriate");return this.blockRemain-=r,super.write(t,i)}end(t,e,i){return this.blockRemain&&super.write(Buffer.alloc(this.blockRemain)),typeof t=="function"&&(i=t,e=void 0,t=void 0),typeof e=="function"&&(i=e,e=void 0),typeof t=="string"&&(t=Buffer.from(t,e??"utf8")),i&&this.once("finish",i),t?super.end(t,i):super.end(i),this}},Gn=s=>s.isFile()?"File":s.isDirectory()?"Directory":s.isSymbolicLink()?"SymbolicLink":"Unsupported";var hi=class s{tail;head;length=0;static create(t=[]){return new s(t)}constructor(t=[]){for(let e of t)this.push(e)}*[Symbol.iterator](){for(let t=this.head;t;t=t.next)yield t.value}removeNode(t){if(t.list!==this)throw new Error("removing node which does not belong to this list");let e=t.next,i=t.prev;return e&&(e.prev=i),i&&(i.next=e),t===this.head&&(this.head=e),t===this.tail&&(this.tail=i),this.length--,t.next=void 0,t.prev=void 0,t.list=void 0,e}unshiftNode(t){if(t===this.head)return;t.list&&t.list.removeNode(t);let e=this.head;t.list=this,t.next=e,e&&(e.prev=t),this.head=t,this.tail||(this.tail=t),this.length++}pushNode(t){if(t===this.tail)return;t.list&&t.list.removeNode(t);let e=this.tail;t.list=this,t.prev=e,e&&(e.next=t),this.tail=t,this.head||(this.head=t),this.length++}push(...t){for(let e=0,i=t.length;e1)i=e;else if(this.head)r=this.head.next,i=this.head.value;else throw new TypeError("Reduce of empty list with no initial value");for(var n=0;r;n++)i=t(i,r.value,n),r=r.next;return i}reduceReverse(t,e){let i,r=this.tail;if(arguments.length>1)i=e;else if(this.tail)r=this.tail.prev,i=this.tail.value;else throw new TypeError("Reduce of empty list with no initial value");for(let n=this.length-1;r;n--)i=t(i,r.value,n),r=r.prev;return i}toArray(){let t=new Array(this.length);for(let e=0,i=this.head;i;e++)t[e]=i.value,i=i.next;return t}toArrayReverse(){let t=new Array(this.length);for(let e=0,i=this.tail;i;e++)t[e]=i.value,i=i.prev;return t}slice(t=0,e=this.length){e<0&&(e+=this.length),t<0&&(t+=this.length);let i=new s;if(ethis.length&&(e=this.length);let r=this.head,n=0;for(n=0;r&&nthis.length&&(e=this.length);let r=this.length,n=this.tail;for(;n&&r>e;r--)n=n.prev;for(;n&&r>t;r--,n=n.prev)i.push(n.value);return i}splice(t,e=0,...i){t>this.length&&(t=this.length-1),t<0&&(t=this.length+t);let r=this.head;for(let o=0;r&&o1)throw new TypeError("gzip, brotli, zstd are mutually exclusive");if(t.gzip&&(typeof t.gzip!="object"&&(t.gzip={}),this.portable&&(t.gzip.portable=!0),this.zip=new ze(t.gzip)),t.brotli&&(typeof t.brotli!="object"&&(t.brotli={}),this.zip=new We(t.brotli)),t.zstd&&(typeof t.zstd!="object"&&(t.zstd={}),this.zip=new Ye(t.zstd)),!this.zip)throw new Error("impossible");let e=this.zip;e.on("data",i=>super.write(i)),e.on("end",()=>super.end()),e.on("drain",()=>this[fs]()),this.on("resume",()=>e.resume())}else this.on("drain",this[fs]);this.noDirRecurse=!!t.noDirRecurse,this.follow=!!t.follow,this.noMtime=!!t.noMtime,t.mtime&&(this.mtime=t.mtime),this.filter=typeof t.filter=="function"?t.filter:()=>!0,this[W]=new hi,this[G]=0,this.jobs=Number(t.jobs)||4,this[Ee]=!1,this[ue]=!1}[lr](t){return super.write(t)}add(t){return this.write(t),this}end(t,e,i){return typeof t=="function"&&(i=t,t=void 0),typeof e=="function"&&(i=e,e=void 0),t&&this.add(t),this[ue]=!0,this[Ft](),i&&i(),this}write(t){if(this[ue])throw new Error("write after end");return typeof t=="string"?this[ci](t):this[or](t),this.flowing}[or](t){let e=f(ar.resolve(this.cwd,t.path));if(!this.filter(t.path,t))t.resume();else{let i=new pi(t.path,e);i.entry=new oi(t,this[cs](i)),i.entry.on("end",()=>this[ls](i)),this[G]+=1,this[W].push(i)}this[Ft]()}[ci](t){let e=f(ar.resolve(this.cwd,t));this[W].push(new pi(t,e)),this[Ft]()}[ds](t){t.pending=!0,this[G]+=1;let e=this.follow?"stat":"lstat";ui[e](t.absolute,(i,r)=>{t.pending=!1,this[G]-=1,i?this.emit("error",i):this[li](t,r)})}[li](t,e){if(this.statCache.set(t.absolute,e),t.stat=e,!this.filter(t.path,e))t.ignore=!0;else if(e.isFile()&&e.nlink>1&&!this.linkCache.get(`${e.dev}:${e.ino}`)&&!this.sync)if(t===this[Et])this[ai](t);else{let i=`${e.dev}:${e.ino}`,r=this[pe].get(i);r?r.push(t):this[pe].set(i,[t]),t.pendingLink=!0,t.pending=!0}this[Ft]()}[ms](t){t.pending=!0,this[G]+=1,ui.readdir(t.absolute,(e,i)=>{if(t.pending=!1,this[G]-=1,e)return this.emit("error",e);this[fi](t,i)})}[fi](t,e){this.readdirCache.set(t.absolute,e),t.readdir=e,this[Ft]()}[Ft](){if(!this[Ee]){this[Ee]=!0;for(let t=this[W].head;t&&this[G]1){let i=`${e.dev}:${e.ino}`,r=this[pe].get(i);if(r){this[pe].delete(i);for(let n of r)n.pending=!1,this[ai](n)}}this[Ft]()}[ai](t){if(t.pending&&t.pendingLink&&t===this[Et]&&(t.pending=!1,t.pendingLink=!1),!t.pending){if(t.entry){t===this[Et]&&!t.piped&&this[di](t);return}if(!t.stat){let e=this.statCache.get(t.absolute);e?this[li](t,e):this[ds](t)}if(t.stat&&!t.ignore){if(!this.noDirRecurse&&t.stat.isDirectory()&&!t.readdir){let e=this.readdirCache.get(t.absolute);if(e?this[fi](t,e):this[ms](t),!t.readdir)return}if(t.entry=this[hr](t),!t.entry){t.ignore=!0;return}t===this[Et]&&!t.piped&&this[di](t)}}}[cs](t){return{onwarn:(e,i,r)=>this.warn(e,i,r),noPax:this.noPax,cwd:this.cwd,absolute:t.absolute,preservePaths:this.preservePaths,maxReadSize:this.maxReadSize,strict:this.strict,portable:this.portable,linkCache:this.linkCache,statCache:this.statCache,noMtime:this.noMtime,mtime:this.mtime,prefix:this.prefix,onWriteEntry:this.onWriteEntry}}[hr](t){this[G]+=1;try{return new this[mi](t.path,this[cs](t)).on("end",()=>this[ls](t)).on("error",i=>this.emit("error",i))}catch(e){this.emit("error",e)}}[fs](){this[Et]&&this[Et].entry&&this[Et].entry.resume()}[di](t){t.piped=!0,t.readdir&&t.readdir.forEach(r=>{let n=t.path,o=n==="./"?"":n.replace(/\/*$/,"/");this[ci](o+r)});let e=t.entry,i=this.zip;if(!e)throw new Error("cannot pipe without source");i?e.on("data",r=>{i.write(r)||e.pause()}):e.on("data",r=>{super.write(r)||e.pause()})}pause(){return this.zip&&this.zip.pause(),super.pause()}warn(t,e,i={}){Dt(this,t,e,i)}},kt=class extends wt{sync=!0;constructor(t){super(t),this[mi]=ni}pause(){}resume(){}[ds](t){let e=this.follow?"statSync":"lstatSync";this[li](t,ui[e](t.absolute))}[ms](t){this[fi](t,ui.readdirSync(t.absolute))}[di](t){let e=t.entry,i=this.zip;if(t.readdir&&t.readdir.forEach(r=>{let n=t.path,o=n==="./"?"":n.replace(/\/*$/,"/");this[ci](o+r)}),!e)throw new Error("Cannot pipe without source");i?e.on("data",r=>{i.write(r)}):e.on("data",r=>{super[lr](r)})}};var Vn=(s,t)=>{let e=new kt(s),i=new Wt(s.file,{mode:s.mode||438});e.pipe(i),fr(e,t)},$n=(s,t)=>{let e=new wt(s),i=new et(s.file,{mode:s.mode||438});e.pipe(i);let r=new Promise((n,o)=>{i.on("error",o),i.on("close",n),e.on("error",o)});return dr(e,t).catch(n=>e.emit("error",n)),r},fr=(s,t)=>{t.forEach(e=>{e.charAt(0)==="@"?Ct({file:cr.resolve(s.cwd,e.slice(1)),sync:!0,noResume:!0,onReadEntry:i=>s.add(i)}):s.add(e)}),s.end()},dr=async(s,t)=>{for(let e of t)e.charAt(0)==="@"?await Ct({file:cr.resolve(String(s.cwd),e.slice(1)),noResume:!0,onReadEntry:i=>{s.add(i)}}):s.add(e);s.end()},Xn=(s,t)=>{let e=new kt(s);return fr(e,t),e},qn=(s,t)=>{let e=new wt(s);return dr(e,t).catch(i=>e.emit("error",i)),e},Qn=K(Vn,$n,Xn,qn,(s,t)=>{if(!t?.length)throw new TypeError("no paths specified to add to archive")});import Br from"node:fs";import co from"node:assert";import{randomBytes as Mr}from"node:crypto";import m from"node:fs";import R from"node:path";import pr from"fs";var Jn=process.env.__FAKE_PLATFORM__||process.platform,Er=Jn==="win32",{O_CREAT:wr,O_NOFOLLOW:mr,O_TRUNC:Sr,O_WRONLY:yr}=pr.constants,Rr=Number(process.env.__FAKE_FS_O_FILENAME__)||pr.constants.UV_FS_O_FILEMAP||0,jn=Er&&!!Rr,to=512*1024,eo=Rr|Sr|wr|yr,ur=!Er&&typeof mr=="number"?mr|Sr|wr|yr:null,us=ur!==null?()=>ur:jn?s=>s"w";import wi from"node:fs";import we from"node:path";var ps=(s,t,e)=>{try{return wi.lchownSync(s,t,e)}catch(i){if(i?.code!=="ENOENT")throw i}},Ei=(s,t,e,i)=>{wi.lchown(s,t,e,r=>{i(r&&r?.code!=="ENOENT"?r:null)})},io=(s,t,e,i,r)=>{if(t.isDirectory())Es(we.resolve(s,t.name),e,i,n=>{if(n)return r(n);let o=we.resolve(s,t.name);Ei(o,e,i,r)});else{let n=we.resolve(s,t.name);Ei(n,e,i,r)}},Es=(s,t,e,i)=>{wi.readdir(s,{withFileTypes:!0},(r,n)=>{if(r){if(r.code==="ENOENT")return i();if(r.code!=="ENOTDIR"&&r.code!=="ENOTSUP")return i(r)}if(r||!n.length)return Ei(s,t,e,i);let o=n.length,h=null,a=l=>{if(!h){if(l)return i(h=l);if(--o===0)return Ei(s,t,e,i)}};for(let l of n)io(s,l,t,e,a)})},so=(s,t,e,i)=>{t.isDirectory()&&ws(we.resolve(s,t.name),e,i),ps(we.resolve(s,t.name),e,i)},ws=(s,t,e)=>{let i;try{i=wi.readdirSync(s,{withFileTypes:!0})}catch(r){let n=r;if(n?.code==="ENOENT")return;if(n?.code==="ENOTDIR"||n?.code==="ENOTSUP")return ps(s,t,e);throw n}for(let r of i)so(s,r,t,e);return ps(s,t,e)};import k from"node:fs";import ro from"node:fs/promises";import Si from"node:path";var Se=class extends Error{path;code;syscall="chdir";constructor(t,e){super(`${e}: Cannot cd into '${t}'`),this.path=t,this.code=e}get name(){return"CwdError"}};var St=class extends Error{path;symlink;syscall="symlink";code="TAR_SYMLINK_ERROR";constructor(t,e){super("TAR_SYMLINK_ERROR: Cannot extract through symbolic link"),this.symlink=t,this.path=e}get name(){return"SymlinkError"}};var no=(s,t)=>{k.stat(s,(e,i)=>{(e||!i.isDirectory())&&(e=new Se(s,e?.code||"ENOTDIR")),t(e)})},gr=(s,t,e)=>{s=f(s);let i=t.umask??18,r=t.mode|448,n=(r&i)!==0,o=t.uid,h=t.gid,a=typeof o=="number"&&typeof h=="number"&&(o!==t.processUid||h!==t.processGid),l=t.preserve,c=t.unlink,d=f(t.cwd),S=(E,x)=>{E?e(E):x&&a?Es(x,o,h,Le=>S(Le)):n?k.chmod(s,r,e):e()};if(s===d)return no(s,S);if(l)return ro.mkdir(s,{mode:r,recursive:!0}).then(E=>S(null,E??void 0),S);let D=f(Si.relative(d,s)).split("/");Ss(d,D,r,c,d,void 0,S)},Ss=(s,t,e,i,r,n,o)=>{if(t.length===0)return o(null,n);let h=t.shift(),a=f(Si.resolve(s+"/"+h));k.mkdir(a,e,br(a,t,e,i,r,n,o))},br=(s,t,e,i,r,n,o)=>h=>{h?k.lstat(s,(a,l)=>{if(a)a.path=a.path&&f(a.path),o(a);else if(l.isDirectory())Ss(s,t,e,i,r,n,o);else if(i)k.unlink(s,c=>{if(c)return o(c);k.mkdir(s,e,br(s,t,e,i,r,n,o))});else{if(l.isSymbolicLink())return o(new St(s,s+"/"+t.join("/")));o(h)}}):(n=n||s,Ss(s,t,e,i,r,n,o))},oo=s=>{let t=!1,e;try{t=k.statSync(s).isDirectory()}catch(i){e=i?.code}finally{if(!t)throw new Se(s,e??"ENOTDIR")}},_r=(s,t)=>{s=f(s);let e=t.umask??18,i=t.mode|448,r=(i&e)!==0,n=t.uid,o=t.gid,h=typeof n=="number"&&typeof o=="number"&&(n!==t.processUid||o!==t.processGid),a=t.preserve,l=t.unlink,c=f(t.cwd),d=E=>{E&&h&&ws(E,n,o),r&&k.chmodSync(s,i)};if(s===c)return oo(c),d();if(a)return d(k.mkdirSync(s,{mode:i,recursive:!0})??void 0);let T=f(Si.relative(c,s)).split("/"),D;for(let E=T.shift(),x=c;E&&(x+="/"+E);E=T.shift()){x=f(Si.resolve(x));try{k.mkdirSync(x,i),D=D||x}catch{let Le=k.lstatSync(x);if(Le.isDirectory())continue;if(l){k.unlinkSync(x),k.mkdirSync(x,i),D=D||x;continue}else if(Le.isSymbolicLink())return new St(x,x+"/"+T.join("/"))}}return d(D)};import{join as xr}from"node:path";var ys=Object.create(null),Or=1e4,Vt=new Set,Tr=s=>{Vt.has(s)?Vt.delete(s):ys[s]=s.normalize("NFD").toLocaleLowerCase("en").toLocaleUpperCase("en"),Vt.add(s);let t=ys[s],e=Vt.size-Or;if(e>Or/10){for(let i of Vt)if(Vt.delete(i),delete ys[i],--e<=0)break}return t};var ho=process.env.TESTING_TAR_FAKE_PLATFORM||process.platform,ao=ho==="win32",lo=s=>s.split("/").slice(0,-1).reduce((e,i)=>{let r=e.at(-1);return r!==void 0&&(i=xr(r,i)),e.push(i||"/"),e},[]),yi=class{#t=new Map;#i=new Map;#s=new Set;reserve(t,e){t=ao?["win32 parallelization disabled"]:t.map(r=>ut(xr(Tr(r))));let i=new Set(t.map(r=>lo(r)).reduce((r,n)=>r.concat(n)));this.#i.set(e,{dirs:i,paths:t});for(let r of t){let n=this.#t.get(r);n?n.push(e):this.#t.set(r,[e])}for(let r of i){let n=this.#t.get(r);if(!n)this.#t.set(r,[new Set([e])]);else{let o=n.at(-1);o instanceof Set?o.add(e):n.push(new Set([e]))}}return this.#r(e)}#n(t){let e=this.#i.get(t);if(!e)throw new Error("function does not have any path reservations");return{paths:e.paths.map(i=>this.#t.get(i)),dirs:[...e.dirs].map(i=>this.#t.get(i))}}check(t){let{paths:e,dirs:i}=this.#n(t);return e.every(r=>r&&r[0]===t)&&i.every(r=>r&&r[0]instanceof Set&&r[0].has(t))}#r(t){return this.#s.has(t)||!this.check(t)?!1:(this.#s.add(t),t(()=>this.#e(t)),!0)}#e(t){if(!this.#s.has(t))return!1;let e=this.#i.get(t);if(!e)throw new Error("invalid reservation");let{paths:i,dirs:r}=e,n=new Set;for(let o of i){let h=this.#t.get(o);if(!h||h?.[0]!==t)continue;let a=h[1];if(!a){this.#t.delete(o);continue}if(h.shift(),typeof a=="function")n.add(a);else for(let l of a)n.add(l)}for(let o of r){let h=this.#t.get(o),a=h?.[0];if(!(!h||!(a instanceof Set)))if(a.size===1&&h.length===1){this.#t.delete(o);continue}else if(a.size===1){h.shift();let l=h[0];typeof l=="function"&&n.add(l)}else a.delete(t)}return this.#s.delete(t),n.forEach(o=>this.#r(o)),!0}};var Lr=()=>process.umask();var Dr=Symbol("onEntry"),_s=Symbol("checkFs"),Nr=Symbol("checkFs2"),Os=Symbol("isReusable"),P=Symbol("makeFs"),Ts=Symbol("file"),xs=Symbol("directory"),gi=Symbol("link"),Ar=Symbol("symlink"),Ir=Symbol("hardlink"),Re=Symbol("ensureNoSymlink"),Cr=Symbol("unsupported"),Fr=Symbol("checkPath"),Rs=Symbol("stripAbsolutePath"),yt=Symbol("mkdir"),O=Symbol("onError"),Ri=Symbol("pending"),kr=Symbol("pend"),$t=Symbol("unpend"),gs=Symbol("ended"),bs=Symbol("maybeClose"),Ls=Symbol("skip"),ge=Symbol("doChown"),be=Symbol("uid"),_e=Symbol("gid"),Oe=Symbol("checkedCwd"),fo=process.env.TESTING_TAR_FAKE_PLATFORM||process.platform,Te=fo==="win32",mo=1024,uo=(s,t)=>{if(!Te)return m.unlink(s,t);let e=s+".DELETE."+Mr(16).toString("hex");m.rename(s,e,i=>{if(i)return t(i);m.unlink(e,t)})},po=s=>{if(!Te)return m.unlinkSync(s);let t=s+".DELETE."+Mr(16).toString("hex");m.renameSync(s,t),m.unlinkSync(t)},vr=(s,t,e)=>s!==void 0&&s===s>>>0?s:t!==void 0&&t===t>>>0?t:e,Xt=class extends rt{[gs]=!1;[Oe]=!1;[Ri]=0;reservations=new yi;transform;writable=!0;readable=!1;uid;gid;setOwner;preserveOwner;processGid;processUid;maxDepth;forceChown;win32;newer;keep;noMtime;preservePaths;unlink;cwd;strip;processUmask;umask;dmode;fmode;chmod;constructor(t={}){if(t.ondone=()=>{this[gs]=!0,this[bs]()},super(t),this.transform=t.transform,this.chmod=!!t.chmod,typeof t.uid=="number"||typeof t.gid=="number"){if(typeof t.uid!="number"||typeof t.gid!="number")throw new TypeError("cannot set owner without number uid and gid");if(t.preserveOwner)throw new TypeError("cannot preserve owner in archive and also set owner explicitly");this.uid=t.uid,this.gid=t.gid,this.setOwner=!0}else this.uid=void 0,this.gid=void 0,this.setOwner=!1;this.preserveOwner=t.preserveOwner===void 0&&typeof t.uid!="number"?process.getuid?.()===0:!!t.preserveOwner,this.processUid=(this.preserveOwner||this.setOwner)&&process.getuid?process.getuid():void 0,this.processGid=(this.preserveOwner||this.setOwner)&&process.getgid?process.getgid():void 0,this.maxDepth=typeof t.maxDepth=="number"?t.maxDepth:mo,this.forceChown=t.forceChown===!0,this.win32=!!t.win32||Te,this.newer=!!t.newer,this.keep=!!t.keep,this.noMtime=!!t.noMtime,this.preservePaths=!!t.preservePaths,this.unlink=!!t.unlink,this.cwd=f(R.resolve(t.cwd||process.cwd())),this.strip=Number(t.strip)||0,this.processUmask=this.chmod?typeof t.processUmask=="number"?t.processUmask:Lr():0,this.umask=typeof t.umask=="number"?t.umask:this.processUmask,this.dmode=t.dmode||511&~this.umask,this.fmode=t.fmode||438&~this.umask,this.on("entry",e=>this[Dr](e))}warn(t,e,i={}){return(t==="TAR_BAD_ARCHIVE"||t==="TAR_ABORT")&&(i.recoverable=!1),super.warn(t,e,i)}[bs](){this[gs]&&this[Ri]===0&&(this.emit("prefinish"),this.emit("finish"),this.emit("end"))}[Rs](t,e){let i=t[e],{type:r}=t;if(!i||this.preservePaths)return!0;let[n,o]=ce(i),h=o.replaceAll(/\\/g,"/").split("/");if(h.includes("..")||Te&&/^[a-z]:\.\.$/i.test(h[0]??"")){if(e==="path"||r==="Link")return this.warn("TAR_ENTRY_ERROR",`${e} contains '..'`,{entry:t,[e]:i}),!1;let a=R.posix.dirname(t.path),l=R.posix.normalize(R.posix.join(a,h.join("/")));if(l.startsWith("../")||l==="..")return this.warn("TAR_ENTRY_ERROR",`${e} escapes extraction directory`,{entry:t,[e]:i}),!1}return n&&(t[e]=String(o),this.warn("TAR_ENTRY_INFO",`stripping ${n} from absolute ${e}`,{entry:t,[e]:i})),!0}[Fr](t){let e=f(t.path),i=e.split("/");if(this.strip){if(i.length=this.strip)t.linkpath=r.slice(this.strip).join("/");else return!1}i.splice(0,this.strip),t.path=i.join("/")}if(isFinite(this.maxDepth)&&i.length>this.maxDepth)return this.warn("TAR_ENTRY_ERROR","path excessively deep",{entry:t,path:e,depth:i.length,maxDepth:this.maxDepth}),!1;if(!this[Rs](t,"path")||!this[Rs](t,"linkpath"))return!1;if(t.absolute=R.isAbsolute(t.path)?f(R.resolve(t.path)):f(R.resolve(this.cwd,t.path)),!this.preservePaths&&typeof t.absolute=="string"&&t.absolute.indexOf(this.cwd+"/")!==0&&t.absolute!==this.cwd)return this.warn("TAR_ENTRY_ERROR","path escaped extraction target",{entry:t,path:f(t.path),resolvedPath:t.absolute,cwd:this.cwd}),!1;if(t.absolute===this.cwd&&t.type!=="Directory"&&t.type!=="GNUDumpDir")return!1;if(this.win32){let{root:r}=R.win32.parse(String(t.absolute));t.absolute=r+ts(String(t.absolute).slice(r.length));let{root:n}=R.win32.parse(t.path);t.path=n+ts(t.path.slice(n.length))}return!0}[Dr](t){if(!this[Fr](t))return t.resume();switch(co.equal(typeof t.absolute,"string"),t.type){case"Directory":case"GNUDumpDir":t.mode&&(t.mode=t.mode|448);case"File":case"OldFile":case"ContiguousFile":case"Link":case"SymbolicLink":return this[_s](t);default:return this[Cr](t)}}[O](t,e){t.name==="CwdError"?this.emit("error",t):(this.warn("TAR_ENTRY_ERROR",t,{entry:e}),this[$t](),e.resume())}[yt](t,e,i){gr(f(t),{uid:this.uid,gid:this.gid,processUid:this.processUid,processGid:this.processGid,umask:this.processUmask,preserve:this.preservePaths,unlink:this.unlink,cwd:this.cwd,mode:e},i)}[ge](t){return this.forceChown||this.preserveOwner&&(typeof t.uid=="number"&&t.uid!==this.processUid||typeof t.gid=="number"&&t.gid!==this.processGid)||typeof this.uid=="number"&&this.uid!==this.processUid||typeof this.gid=="number"&&this.gid!==this.processGid}[be](t){return vr(this.uid,t.uid,this.processUid)}[_e](t){return vr(this.gid,t.gid,this.processGid)}[Ts](t,e){let i=typeof t.mode=="number"?t.mode&4095:this.fmode,r=new et(String(t.absolute),{flags:us(t.size),mode:i,autoClose:!1});r.on("error",a=>{r.fd&&m.close(r.fd,()=>{}),r.write=()=>!0,this[O](a,t),e()});let n=1,o=a=>{if(a){r.fd&&m.close(r.fd,()=>{}),this[O](a,t),e();return}--n===0&&r.fd!==void 0&&m.close(r.fd,l=>{l?this[O](l,t):this[$t](),e()})};r.on("finish",()=>{let a=String(t.absolute),l=r.fd;if(typeof l=="number"&&t.mtime&&!this.noMtime){n++;let c=t.atime||new Date,d=t.mtime;m.futimes(l,c,d,S=>S?m.utimes(a,c,d,T=>o(T&&S)):o())}if(typeof l=="number"&&this[ge](t)){n++;let c=this[be](t),d=this[_e](t);typeof c=="number"&&typeof d=="number"&&m.fchown(l,c,d,S=>S?m.chown(a,c,d,T=>o(T&&S)):o())}o()});let h=this.transform&&this.transform(t)||t;h!==t&&(h.on("error",a=>{this[O](a,t),e()}),t.pipe(h)),h.pipe(r)}[xs](t,e){let i=typeof t.mode=="number"?t.mode&4095:this.dmode;this[yt](String(t.absolute),i,r=>{if(r){this[O](r,t),e();return}let n=1,o=()=>{--n===0&&(e(),this[$t](),t.resume())};t.mtime&&!this.noMtime&&(n++,m.utimes(String(t.absolute),t.atime||new Date,t.mtime,o)),this[ge](t)&&(n++,m.chown(String(t.absolute),Number(this[be](t)),Number(this[_e](t)),o)),o()})}[Cr](t){t.unsupported=!0,this.warn("TAR_ENTRY_UNSUPPORTED",`unsupported entry type: ${t.type}`,{entry:t}),t.resume()}[Ar](t,e){let i=f(R.relative(this.cwd,R.resolve(R.dirname(String(t.absolute)),String(t.linkpath)))).split("/");this[Re](t,this.cwd,i,()=>this[gi](t,String(t.linkpath),"symlink",e),r=>{this[O](r,t),e()})}[Ir](t,e){let i=f(R.resolve(this.cwd,String(t.linkpath))),r=f(String(t.linkpath)).split("/");this[Re](t,this.cwd,r,()=>this[gi](t,i,"link",e),n=>{this[O](n,t),e()})}[Re](t,e,i,r,n){let o=i.shift();if(this.preservePaths||o===void 0)return r();let h=R.resolve(e,o);m.lstat(h,(a,l)=>{if(a)return r();if(l?.isSymbolicLink())return n(new St(h,R.resolve(h,i.join("/"))));this[Re](t,h,i,r,n)})}[kr](){this[Ri]++}[$t](){this[Ri]--,this[bs]()}[Ls](t){this[$t](),t.resume()}[Os](t,e){return t.type==="File"&&!this.unlink&&e.isFile()&&e.nlink<=1&&!Te}[_s](t){this[kr]();let e=[t.path];t.linkpath&&e.push(t.linkpath),this.reservations.reserve(e,i=>this[Nr](t,i))}[Nr](t,e){let i=h=>{e(h)},r=()=>{this[yt](this.cwd,this.dmode,h=>{if(h){this[O](h,t),i();return}this[Oe]=!0,n()})},n=()=>{if(t.absolute!==this.cwd){let h=f(R.dirname(String(t.absolute)));if(h!==this.cwd)return this[yt](h,this.dmode,a=>{if(a){this[O](a,t),i();return}o()})}o()},o=()=>{m.lstat(String(t.absolute),(h,a)=>{if(a&&(this.keep||this.newer&&a.mtime>(t.mtime??a.mtime))){this[Ls](t),i();return}if(h||this[Os](t,a))return this[P](null,t,i);if(a.isDirectory()){if(t.type==="Directory"){let l=this.chmod&&t.mode&&(a.mode&4095)!==t.mode,c=d=>this[P](d??null,t,i);return l?m.chmod(String(t.absolute),Number(t.mode),c):c()}if(t.absolute!==this.cwd)return m.rmdir(String(t.absolute),l=>this[P](l??null,t,i))}if(t.absolute===this.cwd)return this[P](null,t,i);uo(String(t.absolute),l=>this[P](l??null,t,i))})};this[Oe]?n():r()}[P](t,e,i){if(t){this[O](t,e),i();return}switch(e.type){case"File":case"OldFile":case"ContiguousFile":return this[Ts](e,i);case"Link":return this[Ir](e,i);case"SymbolicLink":return this[Ar](e,i);case"Directory":case"GNUDumpDir":return this[xs](e,i)}}[gi](t,e,i,r){m[i](e,String(t.absolute),n=>{n?this[O](n,t):(this[$t](),t.resume()),r()})}},ye=s=>{try{return[null,s()]}catch(t){return[t,null]}},xe=class extends Xt{sync=!0;[P](t,e){return super[P](t,e,()=>{})}[_s](t){if(!this[Oe]){let n=this[yt](this.cwd,this.dmode);if(n)return this[O](n,t);this[Oe]=!0}if(t.absolute!==this.cwd){let n=f(R.dirname(String(t.absolute)));if(n!==this.cwd){let o=this[yt](n,this.dmode);if(o)return this[O](o,t)}}let[e,i]=ye(()=>m.lstatSync(String(t.absolute)));if(i&&(this.keep||this.newer&&i.mtime>(t.mtime??i.mtime)))return this[Ls](t);if(e||this[Os](t,i))return this[P](null,t);if(i.isDirectory()){if(t.type==="Directory"){let o=this.chmod&&t.mode&&(i.mode&4095)!==t.mode,[h]=o?ye(()=>{m.chmodSync(String(t.absolute),Number(t.mode))}):[];return this[P](h,t)}let[n]=ye(()=>m.rmdirSync(String(t.absolute)));this[P](n,t)}let[r]=t.absolute===this.cwd?[]:ye(()=>po(String(t.absolute)));this[P](r,t)}[Ts](t,e){let i=typeof t.mode=="number"?t.mode&4095:this.fmode,r=h=>{let a;try{m.closeSync(n)}catch(l){a=l}(h||a)&&this[O](h||a,t),e()},n;try{n=m.openSync(String(t.absolute),us(t.size),i)}catch(h){return r(h)}let o=this.transform&&this.transform(t)||t;o!==t&&(o.on("error",h=>this[O](h,t)),t.pipe(o)),o.on("data",h=>{try{m.writeSync(n,h,0,h.length)}catch(a){r(a)}}),o.on("end",()=>{let h=null;if(t.mtime&&!this.noMtime){let a=t.atime||new Date,l=t.mtime;try{m.futimesSync(n,a,l)}catch(c){try{m.utimesSync(String(t.absolute),a,l)}catch{h=c}}}if(this[ge](t)){let a=this[be](t),l=this[_e](t);try{m.fchownSync(n,Number(a),Number(l))}catch(c){try{m.chownSync(String(t.absolute),Number(a),Number(l))}catch{h=h||c}}}r(h)})}[xs](t,e){let i=typeof t.mode=="number"?t.mode&4095:this.dmode,r=this[yt](String(t.absolute),i);if(r){this[O](r,t),e();return}if(t.mtime&&!this.noMtime)try{m.utimesSync(String(t.absolute),t.atime||new Date,t.mtime)}catch{}if(this[ge](t))try{m.chownSync(String(t.absolute),Number(this[be](t)),Number(this[_e](t)))}catch{}e(),t.resume()}[yt](t,e){try{return _r(f(t),{uid:this.uid,gid:this.gid,processUid:this.processUid,processGid:this.processGid,umask:this.processUmask,preserve:this.preservePaths,unlink:this.unlink,cwd:this.cwd,mode:e})}catch(i){return i}}[Re](t,e,i,r,n){if(this.preservePaths||i.length===0)return r();let o=e;for(let h of i){o=R.resolve(o,h);let[a,l]=ye(()=>m.lstatSync(o));if(a)return r();if(l.isSymbolicLink())return n(new St(o,R.resolve(e,i.join("/"))))}r()}[gi](t,e,i,r){let n=`${i}Sync`;try{m[n](e,String(t.absolute)),r(),t.resume()}catch(o){return this[O](o,t)}}};var Eo=s=>{let t=new xe(s),e=s.file,i=Br.statSync(e),r=s.maxReadSize||16*1024*1024;new Be(e,{readSize:r,size:i.size}).pipe(t)},wo=(s,t)=>{let e=new Xt(s),i=s.maxReadSize||16*1024*1024,r=s.file;return new Promise((o,h)=>{e.on("error",h),e.on("close",o),Br.stat(r,(a,l)=>{if(a)h(a);else{let c=new _t(r,{readSize:i,size:l.size});c.on("error",h),c.pipe(e)}})})},So=K(Eo,wo,s=>new xe(s),s=>new Xt(s),(s,t)=>{t?.length&&Qi(s,t)});import v from"node:fs";import Pr from"node:path";var yo=(s,t)=>{let e=new kt(s),i=!0,r,n;try{try{r=v.openSync(s.file,"r+")}catch(a){if(a?.code==="ENOENT")r=v.openSync(s.file,"w+");else throw a}let o=v.fstatSync(r),h=Buffer.alloc(512);t:for(n=0;no.size)break;n+=l,s.mtimeCache&&a.mtime&&s.mtimeCache.set(String(a.path),a.mtime)}i=!1,Ro(s,e,n,r,t)}finally{if(i)try{v.closeSync(r)}catch{}}},Ro=(s,t,e,i,r)=>{let n=new Wt(s.file,{fd:i,start:e});t.pipe(n),bo(t,r)},go=(s,t)=>{t=Array.from(t);let e=new wt(s),i=(n,o,h)=>{let a=(T,D)=>{T?v.close(n,E=>h(T)):h(null,D)},l=0;if(o===0)return a(null,0);let c=0,d=Buffer.alloc(512),S=(T,D)=>{if(T||D===void 0)return a(T);if(c+=D,c<512&&D)return v.read(n,d,c,d.length-c,l+c,S);if(l===0&&d[0]===31&&d[1]===139)return a(new Error("cannot append to compressed archives"));if(c<512)return a(null,l);let E=new F(d);if(!E.cksumValid)return a(null,l);let x=512*Math.ceil((E.size??0)/512);if(l+x+512>o||(l+=x+512,l>=o))return a(null,l);s.mtimeCache&&E.mtime&&s.mtimeCache.set(String(E.path),E.mtime),c=0,v.read(n,d,0,512,l,S)};v.read(n,d,0,512,l,S)};return new Promise((n,o)=>{e.on("error",o);let h="r+",a=(l,c)=>{if(l&&l.code==="ENOENT"&&h==="r+")return h="w+",v.open(s.file,h,a);if(l||!c)return o(l);v.fstat(c,(d,S)=>{if(d)return v.close(c,()=>o(d));i(c,S.size,(T,D)=>{if(T)return o(T);let E=new et(s.file,{fd:c,start:D});e.pipe(E),E.on("error",o),E.on("close",n),_o(e,t)})})};v.open(s.file,h,a)})},bo=(s,t)=>{t.forEach(e=>{e.charAt(0)==="@"?Ct({file:Pr.resolve(s.cwd,e.slice(1)),sync:!0,noResume:!0,onReadEntry:i=>s.add(i)}):s.add(e)}),s.end()},_o=async(s,t)=>{for(let e of t)e.charAt(0)==="@"?await Ct({file:Pr.resolve(String(s.cwd),e.slice(1)),noResume:!0,onReadEntry:i=>s.add(i)}):s.add(e);s.end()},vt=K(yo,go,()=>{throw new TypeError("file is required")},()=>{throw new TypeError("file is required")},(s,t)=>{if(!Bs(s))throw new TypeError("file is required");if(s.gzip||s.brotli||s.zstd||s.file.endsWith(".br")||s.file.endsWith(".tbr"))throw new TypeError("cannot append to compressed archives");if(!t?.length)throw new TypeError("no paths specified to add/replace")});var Oo=K(vt.syncFile,vt.asyncFile,vt.syncNoFile,vt.asyncNoFile,(s,t=[])=>{vt.validate?.(s,t),To(s)}),To=s=>{let t=s.filter;s.mtimeCache||(s.mtimeCache=new Map),s.filter=t?(e,i)=>t(e,i)&&!((s.mtimeCache?.get(e)??i.mtime??0)>(i.mtime??0)):(e,i)=>!((s.mtimeCache?.get(e)??i.mtime??0)>(i.mtime??0))};export{F as Header,wt as Pack,pi as PackJob,kt as PackSync,rt as Parser,ft as Pax,$e as ReadEntry,Xt as Unpack,xe as UnpackSync,de as WriteEntry,ni as WriteEntrySync,oi as WriteEntryTar,Qn as c,Qn as create,So as extract,Qi as filesFilter,Ct as list,vt as r,vt as replace,Ct as t,Hi as types,Oo as u,Oo as update,So as x}; +`).reduce(xn,Object.create(null)),xn=(s,t)=>{let e=parseInt(t,10);if(e!==Buffer.byteLength(t)+1)return s;t=t.slice((e+" ").length);let i=t.split("="),r=i.shift();if(!r)return s;let n=r.replace(/^SCHILY\.(dev|ino|nlink)/,"$1"),o=i.join("=").replace(/\0.*/,"");switch(n){case"path":case"linkpath":case"type":case"charset":case"comment":case"gname":case"uname":s[n]=o;break;case"ctime":case"atime":case"mtime":s[n]=new Date(Number(o)*1e3);break;case"size":let h=+o;h>=0&&(s[n]=h);break;case"gid":case"uid":case"dev":case"ino":case"nlink":case"mode":s[n]=+o;break}return s};var Ln=process.env.TESTING_TAR_FAKE_PLATFORM||process.platform,f=Ln!=="win32"?s=>String(s):s=>String(s).replaceAll(/\\/g,"/");var $e=class extends A{extended;globalExtended;header;startBlockSize;blockRemain;remain;type;meta=!1;ignore=!1;path;mode;uid;gid;uname;gname;size=0;mtime;atime;ctime;linkpath;dev;ino;nlink;invalid=!1;absolute;unsupported=!1;constructor(t,e,i){switch(super({}),this.pause(),this.extended=e,this.globalExtended=i,this.header=t,this.remain=t.size??0,this.startBlockSize=512*Math.ceil(this.remain/512),this.blockRemain=this.startBlockSize,this.type=t.type,this.type){case"File":case"OldFile":case"Link":case"SymbolicLink":case"CharacterDevice":case"BlockDevice":case"Directory":case"FIFO":case"ContiguousFile":case"GNUDumpDir":break;case"NextFileHasLongLinkpath":case"NextFileHasLongPath":case"OldGnuLongPath":case"GlobalExtendedHeader":case"ExtendedHeader":case"OldExtendedHeader":this.meta=!0;break;default:this.ignore=!0}if(!t.path)throw new Error("no path provided for tar.ReadEntry");this.path=f(t.path),this.mode=t.mode,this.mode&&(this.mode=this.mode&4095),this.uid=t.uid,this.gid=t.gid,this.uname=t.uname,this.gname=t.gname,this.size=this.remain,this.mtime=t.mtime,this.atime=t.atime,this.ctime=t.ctime,this.linkpath=t.linkpath?f(t.linkpath):void 0,this.uname=t.uname,this.gname=t.gname,e&&this.#t(e),i&&this.#t(i,!0)}write(t){let e=t.length;if(e>this.blockRemain)throw new Error("writing more to entry than is appropriate");let i=this.remain,r=this.blockRemain;return this.remain=Math.max(0,i-e),this.blockRemain=Math.max(0,r-e),this.ignore?!0:i>=e?super.write(t):super.write(t.subarray(0,i))}#t(t,e=!1){t.path&&(t.path=f(t.path)),t.linkpath&&(t.linkpath=f(t.linkpath)),Object.assign(this,Object.fromEntries(Object.entries(t).filter(([i,r])=>!(r==null||i==="path"&&e))))}};var Dt=(s,t,e,i={})=>{s.file&&(i.file=s.file),s.cwd&&(i.cwd=s.cwd),i.code=e instanceof Error&&e.code||t,i.tarCode=t,!s.strict&&i.recoverable!==!1?(e instanceof Error&&(i=Object.assign(e,i),e=e.message),s.emit("warn",t,e,i)):e instanceof Error?s.emit("error",Object.assign(e,i)):s.emit("error",Object.assign(new Error(`${t}: ${e}`),i))};var Nn=1024*1024,Xi=Buffer.from([31,139]),qi=Buffer.from([40,181,47,253]),An=Math.max(Xi.length,qi.length),B=Symbol("state"),Nt=Symbol("writeEntry"),it=Symbol("readEntry"),Zi=Symbol("nextEntry"),Zs=Symbol("processEntry"),V=Symbol("extendedHeader"),he=Symbol("globalExtendedHeader"),dt=Symbol("meta"),Ys=Symbol("emitMeta"),p=Symbol("buffer"),st=Symbol("queue"),ut=Symbol("ended"),Yi=Symbol("emittedEnd"),At=Symbol("emit"),w=Symbol("unzip"),Xe=Symbol("consumeChunk"),qe=Symbol("consumeChunkSub"),Ki=Symbol("consumeBody"),Ks=Symbol("consumeMeta"),Vs=Symbol("consumeHeader"),ae=Symbol("consuming"),Vi=Symbol("bufferConcat"),Qe=Symbol("maybeEnd"),Yt=Symbol("writing"),$=Symbol("aborted"),Je=Symbol("onDone"),It=Symbol("sawValidEntry"),je=Symbol("sawNullBlock"),ti=Symbol("sawEOF"),$s=Symbol("closeStream"),In=1e3,le=Symbol("compressedBytesRead"),$i=Symbol("decompressedBytesRead"),Xs=Symbol("checkDecompressionRatio"),Cn=()=>!0,rt=class extends Dn{file;strict;maxMetaEntrySize;filter;brotli;zstd;maxDecompressionRatio;writable=!0;readable=!1;[st]=[];[p];[it];[Nt];[B]="begin";[dt]="";[V];[he];[ut]=!1;[w];[$]=!1;[It];[je]=!1;[ti]=!1;[Yt]=!1;[ae]=!1;[Yi]=!1;[le]=0;[$i]=0;constructor(t={}){super(),this.file=t.file||"",this.on(Je,()=>{(this[B]==="begin"||this[It]===!1)&&this.warn("TAR_BAD_ARCHIVE","Unrecognized archive format")}),t.ondone?this.on(Je,t.ondone):this.on(Je,()=>{this.emit("prefinish"),this.emit("finish"),this.emit("end")}),this.strict=!!t.strict,this.maxDecompressionRatio=typeof t.maxDecompressionRatio=="number"?t.maxDecompressionRatio:In,this.maxMetaEntrySize=t.maxMetaEntrySize||Nn,this.filter=typeof t.filter=="function"?t.filter:Cn;let e=t.file&&(t.file.endsWith(".tar.br")||t.file.endsWith(".tbr"));this.brotli=!(t.gzip||t.zstd)&&t.brotli!==void 0?t.brotli:e?void 0:!1;let i=t.file&&(t.file.endsWith(".tar.zst")||t.file.endsWith(".tzst"));this.zstd=!(t.gzip||t.brotli)&&t.zstd!==void 0?t.zstd:i?!0:void 0,this.on("end",()=>this[$s]()),typeof t.onwarn=="function"&&this.on("warn",t.onwarn),typeof t.onReadEntry=="function"&&this.on("entry",t.onReadEntry)}warn(t,e,i={}){Dt(this,t,e,i)}[Vs](t,e){this[It]===void 0&&(this[It]=!1);let i;try{i=new F(t,e,this[V],this[he])}catch(r){return this.warn("TAR_ENTRY_INVALID",r)}if(i.nullBlock)this[je]?(this[ti]=!0,this[B]==="begin"&&(this[B]="header"),this[At]("eof")):(this[je]=!0,this[At]("nullBlock"));else if(this[je]=!1,!i.cksumValid)this.warn("TAR_ENTRY_INVALID","checksum failure",{header:i});else if(!i.path)this.warn("TAR_ENTRY_INVALID","path is required",{header:i});else{let r=i.type;if(/^(Symbolic)?Link$/.test(r)&&!i.linkpath)this.warn("TAR_ENTRY_INVALID","linkpath required",{header:i});else if(!/^(Symbolic)?Link$/.test(r)&&!/^(Global)?ExtendedHeader$/.test(r)&&i.linkpath)this.warn("TAR_ENTRY_INVALID","linkpath forbidden",{header:i});else{let n=this[Nt]=new $e(i,this[V],this[he]);if(!this[It])if(n.remain){let o=()=>{n.invalid||(this[It]=!0)};n.on("end",o)}else this[It]=!0;n.meta?n.size>this.maxMetaEntrySize?(n.ignore=!0,this[At]("ignoredEntry",n),this[B]="ignore",n.resume()):n.size>0&&(this[dt]="",n.on("data",o=>this[dt]+=o),this[B]="meta"):(this[V]=void 0,n.ignore=n.ignore||!this.filter(n.path,n),n.ignore?(this[At]("ignoredEntry",n),this[B]=n.remain?"ignore":"header",n.resume()):(n.remain?this[B]="body":(this[B]="header",n.end()),this[it]?this[st].push(n):(this[st].push(n),this[Zi]())))}}}[$s](){queueMicrotask(()=>this.emit("close"))}[Zs](t){let e=!0;if(!t)this[it]=void 0,e=!1;else if(Array.isArray(t)){let[i,...r]=t;this.emit(i,...r)}else this[it]=t,this.emit("entry",t),t.emittedEnd||(t.on("end",()=>this[Zi]()),e=!1);return e}[Zi](){do;while(this[Zs](this[st].shift()));if(this[st].length===0){let t=this[it];!t||t.flowing||t.size===t.remain?this[Yt]||this.emit("drain"):t.once("drain",()=>this.emit("drain"))}}[Ki](t,e){let i=this[Nt];if(!i)throw new Error("attempt to consume body without entry??");let r=i.blockRemain??0,n=r>=t.length&&e===0?t:t.subarray(e,e+r);return i.write(n),i.blockRemain||(this[B]="header",this[Nt]=void 0,i.end()),n.length}[Ks](t,e){let i=this[Nt],r=this[Ki](t,e);return!this[Nt]&&i&&this[Ys](i),r}[At](t,e,i){this[st].length===0&&!this[it]?this.emit(t,e,i):this[st].push([t,e,i])}[Ys](t){switch(this[At]("meta",this[dt]),t.type){case"ExtendedHeader":case"OldExtendedHeader":this[V]=ft.parse(this[dt],this[V],!1);break;case"GlobalExtendedHeader":this[he]=ft.parse(this[dt],this[he],!0);break;case"NextFileHasLongPath":case"OldGnuLongPath":{let e=this[V]??Object.create(null);this[V]=e,e.path=this[dt].replace(/\0.*/,"");break}case"NextFileHasLongLinkpath":{let e=this[V]||Object.create(null);this[V]=e,e.linkpath=this[dt].replace(/\0.*/,"");break}default:throw new Error("unknown meta: "+t.type)}}abort(t){if(!this[$]){if(this[w]){let e=this[w];e.write=()=>!0,e.end=()=>e,e.emit=()=>!1,e.destroy?.()}this[$]=!0,this.emit("abort",t),this.warn("TAR_ABORT",t,{recoverable:!1})}}[Xs](t){this[$i]+=t.length;let e=this[$i]/this[le];return e>this.maxDecompressionRatio?(this.abort(new Error(`max decompression ratio exceeded: ${e.toFixed(2)} > ${this.maxDecompressionRatio}`)),!1):!0}write(t,e,i){if(typeof e=="function"&&(i=e,e=void 0),typeof t=="string"&&(t=Buffer.from(t,typeof e=="string"?e:"utf8")),this[$])return i?.(),!1;if((this[w]===void 0||this.brotli===void 0&&this[w]===!1)&&t){if(this[p]&&(t=Buffer.concat([this[p],t]),this[p]=void 0),t.length{this[Xs](c)&&this[Xe](c)}),this[w].on("error",c=>{this[$]||this.abort(c)}),this[w].on("end",()=>{this[ut]=!0,this[Xe]()}),this[Yt]=!0,this[le]+=t.length;let l=!!this[w][a?"end":"write"](t);return this[Yt]=!1,i?.(),l}}this[Yt]=!0,this[w]?(this[le]+=t.length,this[w].write(t)):this[Xe](t),this[Yt]=!1;let n=this[st].length>0?!1:this[it]?this[it].flowing:!0;return!n&&this[st].length===0&&this[it]?.once("drain",()=>this.emit("drain")),i?.(),n}[Vi](t){t&&!this[$]&&(this[p]=this[p]?Buffer.concat([this[p],t]):t)}[Qe](){if(this[ut]&&!this[Yi]&&!this[$]&&!this[ae]){this[Yi]=!0;let t=this[Nt];if(t?.blockRemain){let e=this[p]?this[p].length:0;this.warn("TAR_BAD_ARCHIVE",`Truncated input (needed ${t.blockRemain} more bytes, only ${e} available)`,{entry:t}),this[p]&&t.write(this[p]),t.end()}this[At](Je)}}[Xe](t){if(this[ae]&&t)this[Vi](t);else if(!t&&!this[p])this[Qe]();else if(t){if(this[ae]=!0,this[p]){this[Vi](t);let e=this[p];this[p]=void 0,this[qe](e)}else this[qe](t);for(;this[p]&&this[p]?.length>=512&&!this[$]&&!this[ti];){let e=this[p];this[p]=void 0,this[qe](e)}this[ae]=!1}(!this[p]||this[ut])&&this[Qe]()}[qe](t){let e=0,i=t.length;for(;e+512<=i&&!this[$]&&!this[ti];)switch(this[B]){case"begin":case"header":this[Vs](t,e),e+=512;break;case"ignore":case"body":e+=this[Ki](t,e);break;case"meta":e+=this[Ks](t,e);break;default:throw new Error("invalid state: "+this[B])}e{let t=s.length-1,e=-1;for(;t>-1&&s.charAt(t)==="/";)e=t,t--;return e===-1?s:s.slice(0,e)};var vn=s=>{let t=s.onReadEntry;s.onReadEntry=t?e=>{t(e),e.resume()}:e=>e.resume()},Qi=(s,t)=>{let e=new Map(t.map(o=>[mt(o),!0])),i=s.filter,r=100,n=(o,h="",a=0)=>{if(a>=r)return e.set(o,!1),!1;let l=h||kn(o).root||".",c;if(o===l)c=!1;else{let d=e.get(o);c=d!==void 0?d:n(Fn(o),l,a+1)}return e.set(o,c),c};s.filter=i?(o,h)=>i(o,h)&&n(mt(o)):o=>n(mt(o))},Mn=s=>{let t=new rt(s),e=s.file,i;try{i=Kt.openSync(e,"r");let r=Kt.fstatSync(i),n=s.maxReadSize||16*1024*1024;if(r.size{let e=new rt(s),i=s.maxReadSize||16*1024*1024,r=s.file;return new Promise((o,h)=>{e.on("error",h),e.on("end",o),Kt.stat(r,(a,l)=>{if(a)h(a);else{let c=new _t(r,{readSize:i,size:l.size});c.on("error",h),c.pipe(e)}})})},Ct=K(Mn,Bn,s=>new rt(s),s=>new rt(s),(s,t)=>{t?.length&&Qi(s,t),s.noResume||vn(s)});import mi from"fs";import X from"fs";import js from"path";var Ji=(s,t,e)=>(s&=4095,e&&(s=(s|384)&-19),t&&(s&256&&(s|=64),s&32&&(s|=8),s&4&&(s|=1)),s);import{win32 as Pn}from"node:path";var{isAbsolute:zn,parse:qs}=Pn,ce=s=>{let t="",e=qs(s);for(;zn(s)||e.root;){let i=s.charAt(0)==="/"&&s.slice(0,4)!=="//?/"?"/":e.root;s=s.slice(i.length),t+=i,e=qs(s)}return[t,s]};var ei=["|","<",">","?",":"],ji=ei.map(s=>String.fromCodePoint(61440+Number(s.codePointAt(0)))),Un=new Map(ei.map((s,t)=>[s,ji[t]])),Hn=new Map(ji.map((s,t)=>[s,ei[t]])),ts=s=>ei.reduce((t,e)=>t.split(e).join(Un.get(e)),s),Qs=s=>ji.reduce((t,e)=>t.split(e).join(Hn.get(e)),s);var rr=(s,t)=>t?(s=f(s).replace(/^\.(\/|$)/,""),mt(t)+"/"+s):f(s),Wn=16*1024*1024,tr=Symbol("process"),er=Symbol("file"),ir=Symbol("directory"),is=Symbol("symlink"),sr=Symbol("hardlink"),fe=Symbol("header"),ii=Symbol("read"),ss=Symbol("lstat"),si=Symbol("onlstat"),rs=Symbol("onread"),ns=Symbol("onreadlink"),os=Symbol("openfile"),hs=Symbol("onopenfile"),pt=Symbol("close"),ri=Symbol("mode"),as=Symbol("awaitDrain"),es=Symbol("ondrain"),q=Symbol("prefix"),de=class extends A{path;portable;myuid=process.getuid&&process.getuid()||0;myuser=process.env.USER||"";maxReadSize;linkCache;statCache;preservePaths;cwd;strict;mtime;noPax;noMtime;prefix;fd;blockLen=0;blockRemain=0;buf;pos=0;remain=0;length=0;offset=0;win32;absolute;header;type;linkpath;stat;onWriteEntry;#t=!1;constructor(t,e={}){let i=se(e);super(),this.path=f(t),this.portable=!!i.portable,this.maxReadSize=i.maxReadSize||Wn,this.linkCache=i.linkCache||new Map,this.statCache=i.statCache||new Map,this.preservePaths=!!i.preservePaths,this.cwd=f(i.cwd||process.cwd()),this.strict=!!i.strict,this.noPax=!!i.noPax,this.noMtime=!!i.noMtime,this.mtime=i.mtime,this.prefix=i.prefix?f(i.prefix):void 0,this.onWriteEntry=i.onWriteEntry,typeof i.onwarn=="function"&&this.on("warn",i.onwarn);let r=!1;if(!this.preservePaths){let[o,h]=ce(this.path);o&&typeof h=="string"&&(this.path=h,r=o)}this.win32=!!i.win32||process.platform==="win32",this.win32&&(this.path=Qs(this.path.replaceAll(/\\/g,"/")),t=t.replaceAll(/\\/g,"/")),this.absolute=f(i.absolute||js.resolve(this.cwd,t)),this.path===""&&(this.path="./"),r&&this.warn("TAR_ENTRY_INFO",`stripping ${r} from absolute path`,{entry:this,path:r+this.path});let n=this.statCache.get(this.absolute);n?this[si](n):this[ss]()}warn(t,e,i={}){return Dt(this,t,e,i)}emit(t,...e){return t==="error"&&(this.#t=!0),super.emit(t,...e)}[ss](){X.lstat(this.absolute,(t,e)=>{if(t)return this.emit("error",t);this[si](e)})}[si](t){this.statCache.set(this.absolute,t),this.stat=t,t.isFile()||(t.size=0),this.type=Gn(t),this.emit("stat",t),this[tr]()}[tr](){switch(this.type){case"File":return this[er]();case"Directory":return this[ir]();case"SymbolicLink":return this[is]();default:return this.end()}}[ri](t){return Ji(t,this.type==="Directory",this.portable)}[q](t){return rr(t,this.prefix)}[fe](){if(!this.stat)throw new Error("cannot write header before stat");this.type==="Directory"&&this.portable&&(this.noMtime=!0),this.onWriteEntry?.(this),this.header=new F({path:this[q](this.path),linkpath:this.type==="Link"&&this.linkpath!==void 0?this[q](this.linkpath):this.linkpath,mode:this[ri](this.stat.mode),uid:this.portable?void 0:this.stat.uid,gid:this.portable?void 0:this.stat.gid,size:this.stat.size,mtime:this.noMtime?void 0:this.mtime||this.stat.mtime,type:this.type==="Unsupported"?void 0:this.type,uname:this.portable?void 0:this.stat.uid===this.myuid?this.myuser:"",atime:this.portable?void 0:this.stat.atime,ctime:this.portable?void 0:this.stat.ctime}),this.header.encode()&&!this.noPax&&super.write(new ft({atime:this.portable?void 0:this.header.atime,ctime:this.portable?void 0:this.header.ctime,gid:this.portable?void 0:this.header.gid,mtime:this.noMtime?void 0:this.mtime||this.header.mtime,path:this[q](this.path),linkpath:this.type==="Link"&&this.linkpath!==void 0?this[q](this.linkpath):this.linkpath,size:this.header.size,uid:this.portable?void 0:this.header.uid,uname:this.portable?void 0:this.header.uname,dev:this.portable?void 0:this.stat.dev,ino:this.portable?void 0:this.stat.ino,nlink:this.portable?void 0:this.stat.nlink}).encode());let t=this.header?.block;if(!t)throw new Error("failed to encode header");super.write(t)}[ir](){if(!this.stat)throw new Error("cannot create directory entry without stat");this.path.slice(-1)!=="/"&&(this.path+="/"),this.stat.size=0,this[fe](),this.end()}[is](){X.readlink(this.absolute,(t,e)=>{if(t)return this.emit("error",t);this[ns](e)})}[ns](t){this.linkpath=f(t),this[fe](),this.end()}[sr](t){if(!this.stat)throw new Error("cannot create link entry without stat");this.type="Link",this.linkpath=f(js.relative(this.cwd,t)),this.stat.size=0,this[fe](),this.end()}[er](){if(!this.stat)throw new Error("cannot create file entry without stat");if(this.stat.nlink>1){let t=`${this.stat.dev}:${this.stat.ino}`,e=this.linkCache.get(t);if(e?.indexOf(this.cwd)===0)return this[sr](e);this.linkCache.set(t,this.absolute)}if(this[fe](),this.stat.size===0)return this.end();this[os]()}[os](){X.open(this.absolute,"r",(t,e)=>{if(t)return this.emit("error",t);this[hs](e)})}[hs](t){if(this.fd=t,this.#t)return this[pt]();if(!this.stat)throw new Error("should stat before calling onopenfile");this.blockLen=512*Math.ceil(this.stat.size/512),this.blockRemain=this.blockLen;let e=Math.min(this.blockLen,this.maxReadSize);this.buf=Buffer.allocUnsafe(e),this.offset=0,this.pos=0,this.remain=this.stat.size,this.length=this.buf.length,this[ii]()}[ii](){let{fd:t,buf:e,offset:i,length:r,pos:n}=this;if(t===void 0||e===void 0)throw new Error("cannot read file without first opening");X.read(t,e,i,r,n,(o,h)=>{if(o)return this[pt](()=>this.emit("error",o));this[rs](h)})}[pt](t=()=>{}){this.fd!==void 0&&X.close(this.fd,t)}[rs](t){if(t<=0&&this.remain>0){let r=Object.assign(new Error("encountered unexpected EOF"),{path:this.absolute,syscall:"read",code:"EOF"});return this[pt](()=>this.emit("error",r))}if(t>this.remain){let r=Object.assign(new Error("did not encounter expected EOF"),{path:this.absolute,syscall:"read",code:"EOF"});return this[pt](()=>this.emit("error",r))}if(!this.buf)throw new Error("should have created buffer prior to reading");if(t===this.remain)for(let r=t;rthis[es]())}[as](t){this.once("drain",t)}write(t,e,i){if(typeof e=="function"&&(i=e,e=void 0),typeof t=="string"&&(t=Buffer.from(t,typeof e=="string"?e:"utf8")),this.blockRemaint?this.emit("error",t):this.end());if(!this.buf)throw new Error("buffer lost somehow in ONDRAIN");this.offset>=this.length&&(this.buf=Buffer.allocUnsafe(Math.min(this.blockRemain,this.buf.length)),this.offset=0),this.length=this.buf.length-this.offset,this[ii]()}},ni=class extends de{sync=!0;[ss](){this[si](X.lstatSync(this.absolute))}[is](){this[ns](X.readlinkSync(this.absolute))}[os](){this[hs](X.openSync(this.absolute,"r"))}[ii](){let t=!0;try{let{fd:e,buf:i,offset:r,length:n,pos:o}=this;if(e===void 0||i===void 0)throw new Error("fd and buf must be set in READ method");let h=X.readSync(e,i,r,n,o);this[rs](h),t=!1}finally{if(t)try{this[pt](()=>{})}catch{}}}[as](t){t()}[pt](t=()=>{}){this.fd!==void 0&&X.closeSync(this.fd),t()}},oi=class extends A{blockLen=0;blockRemain=0;buf=0;pos=0;remain=0;length=0;preservePaths;portable;strict;noPax;noMtime;readEntry;type;prefix;path;mode;uid;gid;uname;gname;header;mtime;atime;ctime;linkpath;size;onWriteEntry;warn(t,e,i={}){return Dt(this,t,e,i)}constructor(t,e={}){let i=se(e);super(),this.preservePaths=!!i.preservePaths,this.portable=!!i.portable,this.strict=!!i.strict,this.noPax=!!i.noPax,this.noMtime=!!i.noMtime,this.onWriteEntry=i.onWriteEntry,this.readEntry=t;let{type:r}=t;if(r==="Unsupported")throw new Error("writing entry that should be ignored");this.type=r,this.type==="Directory"&&this.portable&&(this.noMtime=!0),this.prefix=i.prefix,this.path=f(t.path),this.mode=t.mode!==void 0?this[ri](t.mode):void 0,this.uid=this.portable?void 0:t.uid,this.gid=this.portable?void 0:t.gid,this.uname=this.portable?void 0:t.uname,this.gname=this.portable?void 0:t.gname,this.size=t.size,this.mtime=this.noMtime?void 0:i.mtime||t.mtime,this.atime=this.portable?void 0:t.atime,this.ctime=this.portable?void 0:t.ctime,this.linkpath=t.linkpath!==void 0?f(t.linkpath):void 0,typeof i.onwarn=="function"&&this.on("warn",i.onwarn);let n=!1;if(!this.preservePaths){let[h,a]=ce(this.path);h&&typeof a=="string"&&(this.path=a,n=h)}this.remain=t.size,this.blockRemain=t.startBlockSize,this.onWriteEntry?.(this),this.header=new F({path:this[q](this.path),linkpath:this.type==="Link"&&this.linkpath!==void 0?this[q](this.linkpath):this.linkpath,mode:this.mode,uid:this.portable?void 0:this.uid,gid:this.portable?void 0:this.gid,size:this.size,mtime:this.noMtime?void 0:this.mtime,type:this.type,uname:this.portable?void 0:this.uname,atime:this.portable?void 0:this.atime,ctime:this.portable?void 0:this.ctime}),n&&this.warn("TAR_ENTRY_INFO",`stripping ${n} from absolute path`,{entry:this,path:n+this.path}),this.header.encode()&&!this.noPax&&super.write(new ft({atime:this.portable?void 0:this.atime,ctime:this.portable?void 0:this.ctime,gid:this.portable?void 0:this.gid,mtime:this.noMtime?void 0:this.mtime,path:this[q](this.path),linkpath:this.type==="Link"&&this.linkpath!==void 0?this[q](this.linkpath):this.linkpath,size:this.size,uid:this.portable?void 0:this.uid,uname:this.portable?void 0:this.uname,dev:this.portable?void 0:this.readEntry.dev,ino:this.portable?void 0:this.readEntry.ino,nlink:this.portable?void 0:this.readEntry.nlink}).encode());let o=this.header?.block;if(!o)throw new Error("failed to encode header");super.write(o),t.pipe(this)}[q](t){return rr(t,this.prefix)}[ri](t){return Ji(t,this.type==="Directory",this.portable)}write(t,e,i){typeof e=="function"&&(i=e,e=void 0),typeof t=="string"&&(t=Buffer.from(t,typeof e=="string"?e:"utf8"));let r=t.length;if(r>this.blockRemain)throw new Error("writing more to entry than is appropriate");return this.blockRemain-=r,super.write(t,i)}end(t,e,i){return this.blockRemain&&super.write(Buffer.alloc(this.blockRemain)),typeof t=="function"&&(i=t,e=void 0,t=void 0),typeof e=="function"&&(i=e,e=void 0),typeof t=="string"&&(t=Buffer.from(t,e??"utf8")),i&&this.once("finish",i),t?super.end(t,i):super.end(i),this}},Gn=s=>s.isFile()?"File":s.isDirectory()?"Directory":s.isSymbolicLink()?"SymbolicLink":"Unsupported";var hi=class s{tail;head;length=0;static create(t=[]){return new s(t)}constructor(t=[]){for(let e of t)this.push(e)}*[Symbol.iterator](){for(let t=this.head;t;t=t.next)yield t.value}removeNode(t){if(t.list!==this)throw new Error("removing node which does not belong to this list");let e=t.next,i=t.prev;return e&&(e.prev=i),i&&(i.next=e),t===this.head&&(this.head=e),t===this.tail&&(this.tail=i),this.length--,t.next=void 0,t.prev=void 0,t.list=void 0,e}unshiftNode(t){if(t===this.head)return;t.list&&t.list.removeNode(t);let e=this.head;t.list=this,t.next=e,e&&(e.prev=t),this.head=t,this.tail||(this.tail=t),this.length++}pushNode(t){if(t===this.tail)return;t.list&&t.list.removeNode(t);let e=this.tail;t.list=this,t.prev=e,e&&(e.next=t),this.tail=t,this.head||(this.head=t),this.length++}push(...t){for(let e=0,i=t.length;e1)i=e;else if(this.head)r=this.head.next,i=this.head.value;else throw new TypeError("Reduce of empty list with no initial value");for(var n=0;r;n++)i=t(i,r.value,n),r=r.next;return i}reduceReverse(t,e){let i,r=this.tail;if(arguments.length>1)i=e;else if(this.tail)r=this.tail.prev,i=this.tail.value;else throw new TypeError("Reduce of empty list with no initial value");for(let n=this.length-1;r;n--)i=t(i,r.value,n),r=r.prev;return i}toArray(){let t=new Array(this.length);for(let e=0,i=this.head;i;e++)t[e]=i.value,i=i.next;return t}toArrayReverse(){let t=new Array(this.length);for(let e=0,i=this.tail;i;e++)t[e]=i.value,i=i.prev;return t}slice(t=0,e=this.length){e<0&&(e+=this.length),t<0&&(t+=this.length);let i=new s;if(ethis.length&&(e=this.length);let r=this.head,n=0;for(n=0;r&&nthis.length&&(e=this.length);let r=this.length,n=this.tail;for(;n&&r>e;r--)n=n.prev;for(;n&&r>t;r--,n=n.prev)i.push(n.value);return i}splice(t,e=0,...i){t>this.length&&(t=this.length-1),t<0&&(t=this.length+t);let r=this.head;for(let o=0;r&&o1)throw new TypeError("gzip, brotli, zstd are mutually exclusive");if(t.gzip&&(typeof t.gzip!="object"&&(t.gzip={}),this.portable&&(t.gzip.portable=!0),this.zip=new ze(t.gzip)),t.brotli&&(typeof t.brotli!="object"&&(t.brotli={}),this.zip=new We(t.brotli)),t.zstd&&(typeof t.zstd!="object"&&(t.zstd={}),this.zip=new Ye(t.zstd)),!this.zip)throw new Error("impossible");let e=this.zip;e.on("data",i=>super.write(i)),e.on("end",()=>super.end()),e.on("drain",()=>this[fs]()),this.on("resume",()=>e.resume())}else this.on("drain",this[fs]);this.noDirRecurse=!!t.noDirRecurse,this.follow=!!t.follow,this.noMtime=!!t.noMtime,t.mtime&&(this.mtime=t.mtime),this.filter=typeof t.filter=="function"?t.filter:()=>!0,this[W]=new hi,this[G]=0,this.jobs=Number(t.jobs)||4,this[Ee]=!1,this[me]=!1}[lr](t){return super.write(t)}add(t){return this.write(t),this}end(t,e,i){return typeof t=="function"&&(i=t,t=void 0),typeof e=="function"&&(i=e,e=void 0),t&&this.add(t),this[me]=!0,this[Ft](),i&&i(),this}write(t){if(this[me])throw new Error("write after end");return typeof t=="string"?this[ci](t):this[or](t),this.flowing}[or](t){let e=f(ar.resolve(this.cwd,t.path));if(!this.filter(t.path,t))t.resume();else{let i=new pi(t.path,e);i.entry=new oi(t,this[cs](i)),i.entry.on("end",()=>this[ls](i)),this[G]+=1,this[W].push(i)}this[Ft]()}[ci](t){let e=f(ar.resolve(this.cwd,t));this[W].push(new pi(t,e)),this[Ft]()}[ds](t){t.pending=!0,this[G]+=1;let e=this.follow?"stat":"lstat";mi[e](t.absolute,(i,r)=>{t.pending=!1,this[G]-=1,i?this.emit("error",i):this[li](t,r)})}[li](t,e){if(this.statCache.set(t.absolute,e),t.stat=e,!this.filter(t.path,e))t.ignore=!0;else if(e.isFile()&&e.nlink>1&&!this.linkCache.get(`${e.dev}:${e.ino}`)&&!this.sync)if(t===this[Et])this[ai](t);else{let i=`${e.dev}:${e.ino}`,r=this[pe].get(i);r?r.push(t):this[pe].set(i,[t]),t.pendingLink=!0,t.pending=!0}this[Ft]()}[us](t){t.pending=!0,this[G]+=1,mi.readdir(t.absolute,(e,i)=>{if(t.pending=!1,this[G]-=1,e)return this.emit("error",e);this[fi](t,i)})}[fi](t,e){this.readdirCache.set(t.absolute,e),t.readdir=e,this[Ft]()}[Ft](){if(!this[Ee]){this[Ee]=!0;for(let t=this[W].head;t&&this[G]1){let i=`${e.dev}:${e.ino}`,r=this[pe].get(i);if(r){this[pe].delete(i);for(let n of r)n.pending=!1,this[ai](n)}}this[Ft]()}[ai](t){if(t.pending&&t.pendingLink&&t===this[Et]&&(t.pending=!1,t.pendingLink=!1),!t.pending){if(t.entry){t===this[Et]&&!t.piped&&this[di](t);return}if(!t.stat){let e=this.statCache.get(t.absolute);e?this[li](t,e):this[ds](t)}if(t.stat&&!t.ignore){if(!this.noDirRecurse&&t.stat.isDirectory()&&!t.readdir){let e=this.readdirCache.get(t.absolute);if(e?this[fi](t,e):this[us](t),!t.readdir)return}if(t.entry=this[hr](t),!t.entry){t.ignore=!0;return}t===this[Et]&&!t.piped&&this[di](t)}}}[cs](t){return{onwarn:(e,i,r)=>this.warn(e,i,r),noPax:this.noPax,cwd:this.cwd,absolute:t.absolute,preservePaths:this.preservePaths,maxReadSize:this.maxReadSize,strict:this.strict,portable:this.portable,linkCache:this.linkCache,statCache:this.statCache,noMtime:this.noMtime,mtime:this.mtime,prefix:this.prefix,onWriteEntry:this.onWriteEntry}}[hr](t){this[G]+=1;try{return new this[ui](t.path,this[cs](t)).on("end",()=>this[ls](t)).on("error",i=>this.emit("error",i))}catch(e){this.emit("error",e)}}[fs](){this[Et]&&this[Et].entry&&this[Et].entry.resume()}[di](t){t.piped=!0,t.readdir&&t.readdir.forEach(r=>{let n=t.path,o=n==="./"?"":n.replace(/\/*$/,"/");this[ci](o+r)});let e=t.entry,i=this.zip;if(!e)throw new Error("cannot pipe without source");i?e.on("data",r=>{i.write(r)||e.pause()}):e.on("data",r=>{super.write(r)||e.pause()})}pause(){return this.zip&&this.zip.pause(),super.pause()}warn(t,e,i={}){Dt(this,t,e,i)}},kt=class extends wt{sync=!0;constructor(t){super(t),this[ui]=ni}pause(){}resume(){}[ds](t){let e=this.follow?"statSync":"lstatSync";this[li](t,mi[e](t.absolute))}[us](t){this[fi](t,mi.readdirSync(t.absolute))}[di](t){let e=t.entry,i=this.zip;if(t.readdir&&t.readdir.forEach(r=>{let n=t.path,o=n==="./"?"":n.replace(/\/*$/,"/");this[ci](o+r)}),!e)throw new Error("Cannot pipe without source");i?e.on("data",r=>{i.write(r)}):e.on("data",r=>{super[lr](r)})}};var Vn=(s,t)=>{let e=new kt(s),i=new Wt(s.file,{mode:s.mode||438});e.pipe(i),fr(e,t)},$n=(s,t)=>{let e=new wt(s),i=new et(s.file,{mode:s.mode||438});e.pipe(i);let r=new Promise((n,o)=>{i.on("error",o),i.on("close",n),e.on("error",o)});return dr(e,t).catch(n=>e.emit("error",n)),r},fr=(s,t)=>{t.forEach(e=>{e.charAt(0)==="@"?Ct({file:cr.resolve(s.cwd,e.slice(1)),sync:!0,noResume:!0,onReadEntry:i=>s.add(i)}):s.add(e)}),s.end()},dr=async(s,t)=>{for(let e of t)e.charAt(0)==="@"?await Ct({file:cr.resolve(String(s.cwd),e.slice(1)),noResume:!0,onReadEntry:i=>{s.add(i)}}):s.add(e);s.end()},Xn=(s,t)=>{let e=new kt(s);return fr(e,t),e},qn=(s,t)=>{let e=new wt(s);return dr(e,t).catch(i=>e.emit("error",i)),e},Qn=K(Vn,$n,Xn,qn,(s,t)=>{if(!t?.length)throw new TypeError("no paths specified to add to archive")});import Br from"node:fs";import co from"node:assert";import{randomBytes as Mr}from"node:crypto";import u from"node:fs";import R from"node:path";import pr from"fs";var Jn=process.env.__FAKE_PLATFORM__||process.platform,Er=Jn==="win32",{O_CREAT:wr,O_NOFOLLOW:ur,O_TRUNC:Sr,O_WRONLY:yr}=pr.constants,Rr=Number(process.env.__FAKE_FS_O_FILENAME__)||pr.constants.UV_FS_O_FILEMAP||0,jn=Er&&!!Rr,to=512*1024,eo=Rr|Sr|wr|yr,mr=!Er&&typeof ur=="number"?ur|Sr|wr|yr:null,ms=mr!==null?()=>mr:jn?s=>s"w";import wi from"node:fs";import we from"node:path";var ps=(s,t,e)=>{try{return wi.lchownSync(s,t,e)}catch(i){if(i?.code!=="ENOENT")throw i}},Ei=(s,t,e,i)=>{wi.lchown(s,t,e,r=>{i(r&&r?.code!=="ENOENT"?r:null)})},io=(s,t,e,i,r)=>{if(t.isDirectory())Es(we.resolve(s,t.name),e,i,n=>{if(n)return r(n);let o=we.resolve(s,t.name);Ei(o,e,i,r)});else{let n=we.resolve(s,t.name);Ei(n,e,i,r)}},Es=(s,t,e,i)=>{wi.readdir(s,{withFileTypes:!0},(r,n)=>{if(r){if(r.code==="ENOENT")return i();if(r.code!=="ENOTDIR"&&r.code!=="ENOTSUP")return i(r)}if(r||!n.length)return Ei(s,t,e,i);let o=n.length,h=null,a=l=>{if(!h){if(l)return i(h=l);if(--o===0)return Ei(s,t,e,i)}};for(let l of n)io(s,l,t,e,a)})},so=(s,t,e,i)=>{t.isDirectory()&&ws(we.resolve(s,t.name),e,i),ps(we.resolve(s,t.name),e,i)},ws=(s,t,e)=>{let i;try{i=wi.readdirSync(s,{withFileTypes:!0})}catch(r){let n=r;if(n?.code==="ENOENT")return;if(n?.code==="ENOTDIR"||n?.code==="ENOTSUP")return ps(s,t,e);throw n}for(let r of i)so(s,r,t,e);return ps(s,t,e)};import k from"node:fs";import ro from"node:fs/promises";import Si from"node:path";var Se=class extends Error{path;code;syscall="chdir";constructor(t,e){super(`${e}: Cannot cd into '${t}'`),this.path=t,this.code=e}get name(){return"CwdError"}};var St=class extends Error{path;symlink;syscall="symlink";code="TAR_SYMLINK_ERROR";constructor(t,e){super("TAR_SYMLINK_ERROR: Cannot extract through symbolic link"),this.symlink=t,this.path=e}get name(){return"SymlinkError"}};var no=(s,t)=>{k.stat(s,(e,i)=>{(e||!i.isDirectory())&&(e=new Se(s,e?.code||"ENOTDIR")),t(e)})},gr=(s,t,e)=>{s=f(s);let i=t.umask??18,r=t.mode|448,n=(r&i)!==0,o=t.uid,h=t.gid,a=typeof o=="number"&&typeof h=="number"&&(o!==t.processUid||h!==t.processGid),l=t.preserve,c=t.unlink,d=f(t.cwd),y=(E,x)=>{E?e(E):x&&a?Es(x,o,h,Le=>y(Le)):n?k.chmod(s,r,e):e()};if(s===d)return no(s,y);if(l)return ro.mkdir(s,{mode:r,recursive:!0}).then(E=>y(null,E??void 0),y);let D=f(Si.relative(d,s)).split("/");Ss(d,D,r,c,d,void 0,y)},Ss=(s,t,e,i,r,n,o)=>{if(t.length===0)return o(null,n);let h=t.shift(),a=f(Si.resolve(s+"/"+h));k.mkdir(a,e,br(a,t,e,i,r,n,o))},br=(s,t,e,i,r,n,o)=>h=>{h?k.lstat(s,(a,l)=>{if(a)a.path=a.path&&f(a.path),o(a);else if(l.isDirectory())Ss(s,t,e,i,r,n,o);else if(i)k.unlink(s,c=>{if(c)return o(c);k.mkdir(s,e,br(s,t,e,i,r,n,o))});else{if(l.isSymbolicLink())return o(new St(s,s+"/"+t.join("/")));o(h)}}):(n=n||s,Ss(s,t,e,i,r,n,o))},oo=s=>{let t=!1,e;try{t=k.statSync(s).isDirectory()}catch(i){e=i?.code}finally{if(!t)throw new Se(s,e??"ENOTDIR")}},_r=(s,t)=>{s=f(s);let e=t.umask??18,i=t.mode|448,r=(i&e)!==0,n=t.uid,o=t.gid,h=typeof n=="number"&&typeof o=="number"&&(n!==t.processUid||o!==t.processGid),a=t.preserve,l=t.unlink,c=f(t.cwd),d=E=>{E&&h&&ws(E,n,o),r&&k.chmodSync(s,i)};if(s===c)return oo(c),d();if(a)return d(k.mkdirSync(s,{mode:i,recursive:!0})??void 0);let T=f(Si.relative(c,s)).split("/"),D;for(let E=T.shift(),x=c;E&&(x+="/"+E);E=T.shift()){x=f(Si.resolve(x));try{k.mkdirSync(x,i),D=D||x}catch{let Le=k.lstatSync(x);if(Le.isDirectory())continue;if(l){k.unlinkSync(x),k.mkdirSync(x,i),D=D||x;continue}else if(Le.isSymbolicLink())return new St(x,x+"/"+T.join("/"))}}return d(D)};import{join as xr}from"node:path";var ys=Object.create(null),Or=1e4,Vt=new Set,Tr=s=>{Vt.has(s)?Vt.delete(s):ys[s]=s.normalize("NFD").toLocaleLowerCase("en").toLocaleUpperCase("en"),Vt.add(s);let t=ys[s],e=Vt.size-Or;if(e>Or/10){for(let i of Vt)if(Vt.delete(i),delete ys[i],--e<=0)break}return t};var ho=process.env.TESTING_TAR_FAKE_PLATFORM||process.platform,ao=ho==="win32",lo=s=>s.split("/").slice(0,-1).reduce((e,i)=>{let r=e.at(-1);return r!==void 0&&(i=xr(r,i)),e.push(i||"/"),e},[]),yi=class{#t=new Map;#i=new Map;#s=new Set;reserve(t,e){t=ao?["win32 parallelization disabled"]:t.map(r=>mt(xr(Tr(r))));let i=new Set(t.map(r=>lo(r)).reduce((r,n)=>r.concat(n)));this.#i.set(e,{dirs:i,paths:t});for(let r of t){let n=this.#t.get(r);n?n.push(e):this.#t.set(r,[e])}for(let r of i){let n=this.#t.get(r);if(!n)this.#t.set(r,[new Set([e])]);else{let o=n.at(-1);o instanceof Set?o.add(e):n.push(new Set([e]))}}return this.#r(e)}#n(t){let e=this.#i.get(t);if(!e)throw new Error("function does not have any path reservations");return{paths:e.paths.map(i=>this.#t.get(i)),dirs:[...e.dirs].map(i=>this.#t.get(i))}}check(t){let{paths:e,dirs:i}=this.#n(t);return e.every(r=>r&&r[0]===t)&&i.every(r=>r&&r[0]instanceof Set&&r[0].has(t))}#r(t){return this.#s.has(t)||!this.check(t)?!1:(this.#s.add(t),t(()=>this.#e(t)),!0)}#e(t){if(!this.#s.has(t))return!1;let e=this.#i.get(t);if(!e)throw new Error("invalid reservation");let{paths:i,dirs:r}=e,n=new Set;for(let o of i){let h=this.#t.get(o);if(!h||h?.[0]!==t)continue;let a=h[1];if(!a){this.#t.delete(o);continue}if(h.shift(),typeof a=="function")n.add(a);else for(let l of a)n.add(l)}for(let o of r){let h=this.#t.get(o),a=h?.[0];if(!(!h||!(a instanceof Set)))if(a.size===1&&h.length===1){this.#t.delete(o);continue}else if(a.size===1){h.shift();let l=h[0];typeof l=="function"&&n.add(l)}else a.delete(t)}return this.#s.delete(t),n.forEach(o=>this.#r(o)),!0}};var Lr=()=>process.umask();var Dr=Symbol("onEntry"),_s=Symbol("checkFs"),Nr=Symbol("checkFs2"),Os=Symbol("isReusable"),P=Symbol("makeFs"),Ts=Symbol("file"),xs=Symbol("directory"),gi=Symbol("link"),Ar=Symbol("symlink"),Ir=Symbol("hardlink"),Re=Symbol("ensureNoSymlink"),Cr=Symbol("unsupported"),Fr=Symbol("checkPath"),Rs=Symbol("stripAbsolutePath"),yt=Symbol("mkdir"),O=Symbol("onError"),Ri=Symbol("pending"),kr=Symbol("pend"),$t=Symbol("unpend"),gs=Symbol("ended"),bs=Symbol("maybeClose"),Ls=Symbol("skip"),ge=Symbol("doChown"),be=Symbol("uid"),_e=Symbol("gid"),Oe=Symbol("checkedCwd"),fo=process.env.TESTING_TAR_FAKE_PLATFORM||process.platform,Te=fo==="win32",uo=1024,mo=(s,t)=>{if(!Te)return u.unlink(s,t);let e=s+".DELETE."+Mr(16).toString("hex");u.rename(s,e,i=>{if(i)return t(i);u.unlink(e,t)})},po=s=>{if(!Te)return u.unlinkSync(s);let t=s+".DELETE."+Mr(16).toString("hex");u.renameSync(s,t),u.unlinkSync(t)},vr=(s,t,e)=>s!==void 0&&s===s>>>0?s:t!==void 0&&t===t>>>0?t:e,Xt=class extends rt{[gs]=!1;[Oe]=!1;[Ri]=0;reservations=new yi;transform;writable=!0;readable=!1;uid;gid;setOwner;preserveOwner;processGid;processUid;maxDepth;forceChown;win32;newer;keep;noMtime;preservePaths;unlink;cwd;strip;processUmask;umask;dmode;fmode;chmod;constructor(t={}){if(t.ondone=()=>{this[gs]=!0,this[bs]()},super(t),this.transform=t.transform,this.chmod=!!t.chmod,typeof t.uid=="number"||typeof t.gid=="number"){if(typeof t.uid!="number"||typeof t.gid!="number")throw new TypeError("cannot set owner without number uid and gid");if(t.preserveOwner)throw new TypeError("cannot preserve owner in archive and also set owner explicitly");this.uid=t.uid,this.gid=t.gid,this.setOwner=!0}else this.uid=void 0,this.gid=void 0,this.setOwner=!1;this.preserveOwner=t.preserveOwner===void 0&&typeof t.uid!="number"?process.getuid?.()===0:!!t.preserveOwner,this.processUid=(this.preserveOwner||this.setOwner)&&process.getuid?process.getuid():void 0,this.processGid=(this.preserveOwner||this.setOwner)&&process.getgid?process.getgid():void 0,this.maxDepth=typeof t.maxDepth=="number"?t.maxDepth:uo,this.forceChown=t.forceChown===!0,this.win32=!!t.win32||Te,this.newer=!!t.newer,this.keep=!!t.keep,this.noMtime=!!t.noMtime,this.preservePaths=!!t.preservePaths,this.unlink=!!t.unlink,this.cwd=f(R.resolve(t.cwd||process.cwd())),this.strip=Number(t.strip)||0,this.processUmask=this.chmod?typeof t.processUmask=="number"?t.processUmask:Lr():0,this.umask=typeof t.umask=="number"?t.umask:this.processUmask,this.dmode=t.dmode||511&~this.umask,this.fmode=t.fmode||438&~this.umask,this.on("entry",e=>this[Dr](e))}warn(t,e,i={}){return(t==="TAR_BAD_ARCHIVE"||t==="TAR_ABORT")&&(i.recoverable=!1),super.warn(t,e,i)}[bs](){this[gs]&&this[Ri]===0&&(this.emit("prefinish"),this.emit("finish"),this.emit("end"))}[Rs](t,e){let i=t[e],{type:r}=t;if(!i||this.preservePaths)return!0;let[n,o]=ce(i),h=o.replaceAll(/\\/g,"/").split("/");if(h.includes("..")||Te&&/^[a-z]:\.\.$/i.test(h[0]??"")){if(e==="path"||r==="Link")return this.warn("TAR_ENTRY_ERROR",`${e} contains '..'`,{entry:t,[e]:i}),!1;let a=R.posix.dirname(t.path),l=R.posix.normalize(R.posix.join(a,h.join("/")));if(l.startsWith("../")||l==="..")return this.warn("TAR_ENTRY_ERROR",`${e} escapes extraction directory`,{entry:t,[e]:i}),!1}return n&&(t[e]=String(o),this.warn("TAR_ENTRY_INFO",`stripping ${n} from absolute ${e}`,{entry:t,[e]:i})),!0}[Fr](t){let e=f(t.path),i=e.split("/");if(this.strip){if(i.length=this.strip)t.linkpath=r.slice(this.strip).join("/");else return!1}i.splice(0,this.strip),t.path=i.join("/")}if(isFinite(this.maxDepth)&&i.length>this.maxDepth)return this.warn("TAR_ENTRY_ERROR","path excessively deep",{entry:t,path:e,depth:i.length,maxDepth:this.maxDepth}),!1;if(!this[Rs](t,"path")||!this[Rs](t,"linkpath"))return!1;if(t.absolute=R.isAbsolute(t.path)?f(R.resolve(t.path)):f(R.resolve(this.cwd,t.path)),!this.preservePaths&&typeof t.absolute=="string"&&t.absolute.indexOf(this.cwd+"/")!==0&&t.absolute!==this.cwd)return this.warn("TAR_ENTRY_ERROR","path escaped extraction target",{entry:t,path:f(t.path),resolvedPath:t.absolute,cwd:this.cwd}),!1;if(t.absolute===this.cwd&&t.type!=="Directory"&&t.type!=="GNUDumpDir")return!1;if(this.win32){let{root:r}=R.win32.parse(String(t.absolute));t.absolute=r+ts(String(t.absolute).slice(r.length));let{root:n}=R.win32.parse(t.path);t.path=n+ts(t.path.slice(n.length))}return!0}[Dr](t){if(!this[Fr](t))return t.resume();switch(co.equal(typeof t.absolute,"string"),t.type){case"Directory":case"GNUDumpDir":t.mode&&(t.mode=t.mode|448);case"File":case"OldFile":case"ContiguousFile":case"Link":case"SymbolicLink":return this[_s](t);default:return this[Cr](t)}}[O](t,e){t.name==="CwdError"?this.emit("error",t):(this.warn("TAR_ENTRY_ERROR",t,{entry:e}),this[$t](),e.resume())}[yt](t,e,i){gr(f(t),{uid:this.uid,gid:this.gid,processUid:this.processUid,processGid:this.processGid,umask:this.processUmask,preserve:this.preservePaths,unlink:this.unlink,cwd:this.cwd,mode:e},i)}[ge](t){return this.forceChown||this.preserveOwner&&(typeof t.uid=="number"&&t.uid!==this.processUid||typeof t.gid=="number"&&t.gid!==this.processGid)||typeof this.uid=="number"&&this.uid!==this.processUid||typeof this.gid=="number"&&this.gid!==this.processGid}[be](t){return vr(this.uid,t.uid,this.processUid)}[_e](t){return vr(this.gid,t.gid,this.processGid)}[Ts](t,e){let i=typeof t.mode=="number"?t.mode&4095:this.fmode,r=new et(String(t.absolute),{flags:ms(t.size),mode:i,autoClose:!1});r.on("error",a=>{r.fd&&u.close(r.fd,()=>{}),r.write=()=>!0,this[O](a,t),e()});let n=1,o=a=>{if(a){r.fd&&u.close(r.fd,()=>{}),this[O](a,t),e();return}--n===0&&r.fd!==void 0&&u.close(r.fd,l=>{l?this[O](l,t):this[$t](),e()})};r.on("finish",()=>{let a=String(t.absolute),l=r.fd;if(typeof l=="number"&&t.mtime&&!this.noMtime){n++;let c=t.atime||new Date,d=t.mtime;u.futimes(l,c,d,y=>y?u.utimes(a,c,d,T=>o(T&&y)):o())}if(typeof l=="number"&&this[ge](t)){n++;let c=this[be](t),d=this[_e](t);typeof c=="number"&&typeof d=="number"&&u.fchown(l,c,d,y=>y?u.chown(a,c,d,T=>o(T&&y)):o())}o()});let h=this.transform&&this.transform(t)||t;h!==t&&(h.on("error",a=>{this[O](a,t),e()}),t.pipe(h)),h.pipe(r)}[xs](t,e){let i=typeof t.mode=="number"?t.mode&4095:this.dmode;this[yt](String(t.absolute),i,r=>{if(r){this[O](r,t),e();return}let n=1,o=()=>{--n===0&&(e(),this[$t](),t.resume())};t.mtime&&!this.noMtime&&(n++,u.utimes(String(t.absolute),t.atime||new Date,t.mtime,o)),this[ge](t)&&(n++,u.chown(String(t.absolute),Number(this[be](t)),Number(this[_e](t)),o)),o()})}[Cr](t){t.unsupported=!0,this.warn("TAR_ENTRY_UNSUPPORTED",`unsupported entry type: ${t.type}`,{entry:t}),t.resume()}[Ar](t,e){let i=f(R.relative(this.cwd,R.resolve(R.dirname(String(t.absolute)),String(t.linkpath)))).split("/");this[Re](t,this.cwd,i,()=>this[gi](t,String(t.linkpath),"symlink",e),r=>{this[O](r,t),e()})}[Ir](t,e){let i=f(R.resolve(this.cwd,String(t.linkpath))),r=f(String(t.linkpath)).split("/");this[Re](t,this.cwd,r,()=>this[gi](t,i,"link",e),n=>{this[O](n,t),e()})}[Re](t,e,i,r,n){let o=i.shift();if(this.preservePaths||o===void 0)return r();let h=R.resolve(e,o);u.lstat(h,(a,l)=>{if(a)return r();if(l?.isSymbolicLink())return n(new St(h,R.resolve(h,i.join("/"))));this[Re](t,h,i,r,n)})}[kr](){this[Ri]++}[$t](){this[Ri]--,this[bs]()}[Ls](t){this[$t](),t.resume()}[Os](t,e){return t.type==="File"&&!this.unlink&&e.isFile()&&e.nlink<=1&&!Te}[_s](t){this[kr]();let e=[t.path];t.linkpath&&e.push(t.linkpath),this.reservations.reserve(e,i=>this[Nr](t,i))}[Nr](t,e){let i=h=>{e(h)},r=()=>{this[yt](this.cwd,this.dmode,h=>{if(h){this[O](h,t),i();return}this[Oe]=!0,n()})},n=()=>{if(t.absolute!==this.cwd){let h=f(R.dirname(String(t.absolute)));if(h!==this.cwd)return this[yt](h,this.dmode,a=>{if(a){this[O](a,t),i();return}o()})}o()},o=()=>{u.lstat(String(t.absolute),(h,a)=>{if(a&&(this.keep||this.newer&&a.mtime>(t.mtime??a.mtime))){this[Ls](t),i();return}if(h||this[Os](t,a))return this[P](null,t,i);if(a.isDirectory()){if(t.type==="Directory"){let l=this.chmod&&t.mode&&(a.mode&4095)!==t.mode,c=d=>this[P](d??null,t,i);return l?u.chmod(String(t.absolute),Number(t.mode),c):c()}if(t.absolute!==this.cwd)return u.rmdir(String(t.absolute),l=>this[P](l??null,t,i))}if(t.absolute===this.cwd)return this[P](null,t,i);mo(String(t.absolute),l=>this[P](l??null,t,i))})};this[Oe]?n():r()}[P](t,e,i){if(t){this[O](t,e),i();return}switch(e.type){case"File":case"OldFile":case"ContiguousFile":return this[Ts](e,i);case"Link":return this[Ir](e,i);case"SymbolicLink":return this[Ar](e,i);case"Directory":case"GNUDumpDir":return this[xs](e,i)}}[gi](t,e,i,r){u[i](e,String(t.absolute),n=>{n?this[O](n,t):(this[$t](),t.resume()),r()})}},ye=s=>{try{return[null,s()]}catch(t){return[t,null]}},xe=class extends Xt{sync=!0;[P](t,e){return super[P](t,e,()=>{})}[_s](t){if(!this[Oe]){let n=this[yt](this.cwd,this.dmode);if(n)return this[O](n,t);this[Oe]=!0}if(t.absolute!==this.cwd){let n=f(R.dirname(String(t.absolute)));if(n!==this.cwd){let o=this[yt](n,this.dmode);if(o)return this[O](o,t)}}let[e,i]=ye(()=>u.lstatSync(String(t.absolute)));if(i&&(this.keep||this.newer&&i.mtime>(t.mtime??i.mtime)))return this[Ls](t);if(e||this[Os](t,i))return this[P](null,t);if(i.isDirectory()){if(t.type==="Directory"){let o=this.chmod&&t.mode&&(i.mode&4095)!==t.mode,[h]=o?ye(()=>{u.chmodSync(String(t.absolute),Number(t.mode))}):[];return this[P](h,t)}let[n]=ye(()=>u.rmdirSync(String(t.absolute)));this[P](n,t)}let[r]=t.absolute===this.cwd?[]:ye(()=>po(String(t.absolute)));this[P](r,t)}[Ts](t,e){let i=typeof t.mode=="number"?t.mode&4095:this.fmode,r=h=>{let a;try{u.closeSync(n)}catch(l){a=l}(h||a)&&this[O](h||a,t),e()},n;try{n=u.openSync(String(t.absolute),ms(t.size),i)}catch(h){return r(h)}let o=this.transform&&this.transform(t)||t;o!==t&&(o.on("error",h=>this[O](h,t)),t.pipe(o)),o.on("data",h=>{try{u.writeSync(n,h,0,h.length)}catch(a){r(a)}}),o.on("end",()=>{let h=null;if(t.mtime&&!this.noMtime){let a=t.atime||new Date,l=t.mtime;try{u.futimesSync(n,a,l)}catch(c){try{u.utimesSync(String(t.absolute),a,l)}catch{h=c}}}if(this[ge](t)){let a=this[be](t),l=this[_e](t);try{u.fchownSync(n,Number(a),Number(l))}catch(c){try{u.chownSync(String(t.absolute),Number(a),Number(l))}catch{h=h||c}}}r(h)})}[xs](t,e){let i=typeof t.mode=="number"?t.mode&4095:this.dmode,r=this[yt](String(t.absolute),i);if(r){this[O](r,t),e();return}if(t.mtime&&!this.noMtime)try{u.utimesSync(String(t.absolute),t.atime||new Date,t.mtime)}catch{}if(this[ge](t))try{u.chownSync(String(t.absolute),Number(this[be](t)),Number(this[_e](t)))}catch{}e(),t.resume()}[yt](t,e){try{return _r(f(t),{uid:this.uid,gid:this.gid,processUid:this.processUid,processGid:this.processGid,umask:this.processUmask,preserve:this.preservePaths,unlink:this.unlink,cwd:this.cwd,mode:e})}catch(i){return i}}[Re](t,e,i,r,n){if(this.preservePaths||i.length===0)return r();let o=e;for(let h of i){o=R.resolve(o,h);let[a,l]=ye(()=>u.lstatSync(o));if(a)return r();if(l.isSymbolicLink())return n(new St(o,R.resolve(e,i.join("/"))))}r()}[gi](t,e,i,r){let n=`${i}Sync`;try{u[n](e,String(t.absolute)),r(),t.resume()}catch(o){return this[O](o,t)}}};var Eo=s=>{let t=new xe(s),e=s.file,i=Br.statSync(e),r=s.maxReadSize||16*1024*1024;new Be(e,{readSize:r,size:i.size}).pipe(t)},wo=(s,t)=>{let e=new Xt(s),i=s.maxReadSize||16*1024*1024,r=s.file;return new Promise((o,h)=>{e.on("error",h),e.on("close",o),Br.stat(r,(a,l)=>{if(a)h(a);else{let c=new _t(r,{readSize:i,size:l.size});c.on("error",h),c.pipe(e)}})})},So=K(Eo,wo,s=>new xe(s),s=>new Xt(s),(s,t)=>{t?.length&&Qi(s,t)});import v from"node:fs";import Pr from"node:path";var yo=(s,t)=>{let e=new kt(s),i=!0,r,n;try{try{r=v.openSync(s.file,"r+")}catch(a){if(a?.code==="ENOENT")r=v.openSync(s.file,"w+");else throw a}let o=v.fstatSync(r),h=Buffer.alloc(512);t:for(n=0;no.size)break;n+=l,s.mtimeCache&&a.mtime&&s.mtimeCache.set(String(a.path),a.mtime)}i=!1,Ro(s,e,n,r,t)}finally{if(i)try{v.closeSync(r)}catch{}}},Ro=(s,t,e,i,r)=>{let n=new Wt(s.file,{fd:i,start:e});t.pipe(n),bo(t,r)},go=(s,t)=>{t=Array.from(t);let e=new wt(s),i=(n,o,h)=>{let a=(T,D)=>{T?v.close(n,E=>h(T)):h(null,D)},l=0;if(o===0)return a(null,0);let c=0,d=Buffer.alloc(512),y=(T,D)=>{if(T||D===void 0)return a(T);if(c+=D,c<512&&D)return v.read(n,d,c,d.length-c,l+c,y);if(l===0&&d[0]===31&&d[1]===139)return a(new Error("cannot append to compressed archives"));if(c<512)return a(null,l);let E=new F(d);if(!E.cksumValid)return a(null,l);let x=512*Math.ceil((E.size??0)/512);if(l+x+512>o||(l+=x+512,l>=o))return a(null,l);s.mtimeCache&&E.mtime&&s.mtimeCache.set(String(E.path),E.mtime),c=0,v.read(n,d,0,512,l,y)};v.read(n,d,0,512,l,y)};return new Promise((n,o)=>{e.on("error",o);let h="r+",a=(l,c)=>{if(l&&l.code==="ENOENT"&&h==="r+")return h="w+",v.open(s.file,h,a);if(l||!c)return o(l);v.fstat(c,(d,y)=>{if(d)return v.close(c,()=>o(d));i(c,y.size,(T,D)=>{if(T)return o(T);let E=new et(s.file,{fd:c,start:D});e.pipe(E),E.on("error",o),E.on("close",n),_o(e,t)})})};v.open(s.file,h,a)})},bo=(s,t)=>{t.forEach(e=>{e.charAt(0)==="@"?Ct({file:Pr.resolve(s.cwd,e.slice(1)),sync:!0,noResume:!0,onReadEntry:i=>s.add(i)}):s.add(e)}),s.end()},_o=async(s,t)=>{for(let e of t)e.charAt(0)==="@"?await Ct({file:Pr.resolve(String(s.cwd),e.slice(1)),noResume:!0,onReadEntry:i=>s.add(i)}):s.add(e);s.end()},vt=K(yo,go,()=>{throw new TypeError("file is required")},()=>{throw new TypeError("file is required")},(s,t)=>{if(!Bs(s))throw new TypeError("file is required");if(s.gzip||s.brotli||s.zstd||s.file.endsWith(".br")||s.file.endsWith(".tbr"))throw new TypeError("cannot append to compressed archives");if(!t?.length)throw new TypeError("no paths specified to add/replace")});var Oo=K(vt.syncFile,vt.asyncFile,vt.syncNoFile,vt.asyncNoFile,(s,t=[])=>{vt.validate?.(s,t),To(s)}),To=s=>{let t=s.filter;s.mtimeCache||(s.mtimeCache=new Map),s.filter=t?(e,i)=>t(e,i)&&!((s.mtimeCache?.get(e)??i.mtime??0)>(i.mtime??0)):(e,i)=>!((s.mtimeCache?.get(e)??i.mtime??0)>(i.mtime??0))};export{F as Header,wt as Pack,pi as PackJob,kt as PackSync,rt as Parser,ft as Pax,$e as ReadEntry,Xt as Unpack,xe as UnpackSync,de as WriteEntry,ni as WriteEntrySync,oi as WriteEntryTar,Qn as c,Qn as create,So as extract,Qi as filesFilter,Ct as list,vt as r,vt as replace,Ct as t,Hi as types,Oo as u,Oo as update,So as x}; //# sourceMappingURL=index.min.js.map diff --git a/deps/npm/node_modules/tar/dist/esm/list.js b/deps/npm/node_modules/tar/dist/esm/list.js index 4c3af58192ec..08bdbe4ad85c 100644 --- a/deps/npm/node_modules/tar/dist/esm/list.js +++ b/deps/npm/node_modules/tar/dist/esm/list.js @@ -20,14 +20,22 @@ const onReadEntryFunction = (opt) => { export const filesFilter = (opt, files) => { const map = new Map(files.map(f => [stripTrailingSlashes(f), true])); const filter = opt.filter; - const mapHas = (file, r = '') => { + // limit recursion to 100 levels + const MAX = 100; + const mapHas = (file, r = '', depth = 0) => { + /* c8 ignore start - excessive caution */ + if (depth >= MAX) { + map.set(file, false); + return false; + } + /* c8 ignore stop */ const root = r || parse(file).root || '.'; let ret; if (file === root) ret = false; else { const m = map.get(file); - ret = m !== undefined ? m : mapHas(dirname(file), root); + ret = m !== undefined ? m : mapHas(dirname(file), root, depth + 1); } map.set(file, ret); return ret; diff --git a/deps/npm/node_modules/tar/dist/esm/parse.js b/deps/npm/node_modules/tar/dist/esm/parse.js index fb303a5171be..92add3a903fd 100644 --- a/deps/npm/node_modules/tar/dist/esm/parse.js +++ b/deps/npm/node_modules/tar/dist/esm/parse.js @@ -373,6 +373,16 @@ export class Parser extends EE { if (this[ABORTED]) { return; } + if (this[UNZIP]) { + // fully nerf the decompressor and close its underlying binding + const u = this[UNZIP]; + /* c8 ignore start */ + u.write = () => true; + u.end = () => u; + u.emit = () => false; + /* c8 ignore stop */ + u.destroy?.(); + } this[ABORTED] = true; this.emit('abort', error); // always throws, even in non-strict mode diff --git a/deps/npm/node_modules/tar/package.json b/deps/npm/node_modules/tar/package.json index 9d082e440494..f19ece377d9d 100644 --- a/deps/npm/node_modules/tar/package.json +++ b/deps/npm/node_modules/tar/package.json @@ -2,7 +2,7 @@ "author": "Isaac Z. Schlueter", "name": "tar", "description": "tar for node", - "version": "7.5.19", + "version": "7.5.22", "repository": { "type": "git", "url": "https://github.com/isaacs/node-tar.git" diff --git a/deps/npm/node_modules/undici/lib/core/request.js b/deps/npm/node_modules/undici/lib/core/request.js index 4da60667ec29..8e7ecc73084b 100644 --- a/deps/npm/node_modules/undici/lib/core/request.js +++ b/deps/npm/node_modules/undici/lib/core/request.js @@ -350,7 +350,13 @@ function processHeader (request, key, val) { } else if (typeof val[i] === 'object') { throw new InvalidArgumentError(`invalid ${key} header`) } else { - arr.push(`${val[i]}`) + // Coerce primitives (and reject unsafe coercions such as functions + // with a crafted toString/Symbol.toPrimitive). + const str = `${val[i]}` + if (!isValidHeaderValue(str)) { + throw new InvalidArgumentError(`invalid ${key} header`) + } + arr.push(str) } } val = arr @@ -361,7 +367,12 @@ function processHeader (request, key, val) { } else if (val === null) { val = '' } else { + // Coerce primitives (and reject unsafe coercions such as functions + // with a crafted toString/Symbol.toPrimitive). val = `${val}` + if (!isValidHeaderValue(val)) { + throw new InvalidArgumentError(`invalid ${key} header`) + } } if (headerName === 'host') { diff --git a/deps/npm/node_modules/undici/lib/dispatcher/client-h1.js b/deps/npm/node_modules/undici/lib/dispatcher/client-h1.js index 9455517a19b1..a801ecb36046 100644 --- a/deps/npm/node_modules/undici/lib/dispatcher/client-h1.js +++ b/deps/npm/node_modules/undici/lib/dispatcher/client-h1.js @@ -10,6 +10,7 @@ const { RequestContentLengthMismatchError, ResponseContentLengthMismatchError, RequestAbortedError, + InvalidArgumentError, HeadersTimeoutError, HeadersOverflowError, SocketError, @@ -993,8 +994,16 @@ function writeH1 (client, request) { } body = bodyStream.stream contentLength = bodyStream.length - } else if (util.isBlobLike(body) && request.contentType == null && body.type) { - headers.push('content-type', body.type) + } else if (util.isBlobLike(body) && request.contentType == null) { + const contentType = body.type + if (contentType) { + const contentTypeValue = `${contentType}` + if (!util.isValidHeaderValue(contentTypeValue)) { + util.errorRequest(client, request, new InvalidArgumentError('invalid content-type header')) + return false + } + headers.push('content-type', contentTypeValue) + } } if (body && typeof body.read === 'function') { diff --git a/deps/npm/node_modules/undici/lib/handler/retry-handler.js b/deps/npm/node_modules/undici/lib/handler/retry-handler.js index 5d1ccf005387..c62a2409f3ae 100644 --- a/deps/npm/node_modules/undici/lib/handler/retry-handler.js +++ b/deps/npm/node_modules/undici/lib/handler/retry-handler.js @@ -15,6 +15,28 @@ function calculateRetryAfterHeader (retryAfter) { return new Date(retryAfter).getTime() - current } +function validatePartialResponseContentLength (headers, range, statusCode, retryCount) { + const contentLength = headers['content-length'] + if (contentLength == null) { + return null + } + + if (!Number.isFinite(range.start) || !Number.isFinite(range.end)) { + return null + } + + const length = Number(contentLength) + const expectedLength = range.end - range.start + 1 + if (!Number.isFinite(length) || length !== expectedLength) { + return new RequestRetryError('Content-Length mismatch', statusCode, { + headers, + data: { count: retryCount } + }) + } + + return null +} + class RetryHandler { constructor (opts, handlers) { const { retryOptions, ...dispatchOpts } = opts @@ -229,6 +251,12 @@ class RetryHandler { return false } + const contentLengthError = validatePartialResponseContentLength(headers, contentRange, statusCode, this.retryCount) + if (contentLengthError != null) { + this.abort(contentLengthError) + return false + } + const { start, size, end = size - 1 } = contentRange assert(this.start === start, 'content-range mismatch') @@ -252,6 +280,12 @@ class RetryHandler { ) } + const contentLengthError = validatePartialResponseContentLength(headers, range, statusCode, this.retryCount) + if (contentLengthError != null) { + this.abort(contentLengthError) + return false + } + const { start, size, end = size - 1 } = range assert( start != null && Number.isFinite(start), diff --git a/deps/npm/node_modules/undici/lib/web/cookies/util.js b/deps/npm/node_modules/undici/lib/web/cookies/util.js index 254f5419e905..ca408e153abb 100644 --- a/deps/npm/node_modules/undici/lib/web/cookies/util.js +++ b/deps/npm/node_modules/undici/lib/web/cookies/util.js @@ -105,7 +105,7 @@ function validateCookiePath (path) { if ( code < 0x20 || // exclude CTLs (0-31) - code === 0x7F || // DEL + code > 0x7E || // exclude DEL and non-ascii code === 0x3B // ; ) { throw new Error('Invalid cookie path') @@ -114,16 +114,80 @@ function validateCookiePath (path) { } /** - * I have no idea why these values aren't allowed to be honest, - * but Deno tests these. - Khafra + * ::= | + * + * ::= any one of the 52 alphabetic characters A through Z in + * upper case and a through z in lower case + * + * ::= any one of the ten digits 0 through 9r + * + * @see https://www.rfc-editor.org/rfc/rfc1034#section-3.5 + * @param {number} code + */ +function isLetterOrDigit (code) { + return ( + (code >= 0x30 && code <= 0x39) || // 0-9 + (code >= 0x41 && code <= 0x5A) || // A-Z + (code >= 0x61 && code <= 0x7A) // a-z + ) +} + +/** + * Validates a cookie domain against the "preferred name syntax". + * + * ::= | " " + * ::=