From 57de438810d45fada620110985e0522d92160ea4 Mon Sep 17 00:00:00 2001 From: Jason Saayman Date: Tue, 19 May 2026 13:28:24 +0200 Subject: [PATCH 1/2] feat: externalize bundle size comments --- .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- .github/workflows/bundle-size.yml | 3 - COLLABORATOR_GUIDE.md | 3 +- CONTRIBUTING.md | 11 +- README.md | 179 ++++++++- SECURITY.md | 6 +- THREAT_MODEL.md | 42 +-- action.yml | 11 +- dist/index.js | 6 +- .../externalize-pr-commenting/.openspec.yaml | 2 + .../externalize-pr-commenting/design.md | 81 ++++ .../externalize-pr-commenting/proposal.md | 33 ++ .../specs/pr-bundle-size-comment/spec.md | 144 +++++++ .../externalize-pr-commenting/tasks.md | 35 ++ src/action.ts | 17 +- src/config.ts | 13 +- src/index.ts | 1 - src/pr-comment.ts | 225 ----------- src/report.ts | 14 + src/types.ts | 3 +- tests/action.test.ts | 9 +- tests/comment.test.ts | 29 ++ tests/config.test.ts | 60 +-- tests/pr-comment.test.ts | 350 ------------------ tests/report.test.ts | 28 +- 25 files changed, 599 insertions(+), 708 deletions(-) create mode 100644 openspec/changes/externalize-pr-commenting/.openspec.yaml create mode 100644 openspec/changes/externalize-pr-commenting/design.md create mode 100644 openspec/changes/externalize-pr-commenting/proposal.md create mode 100644 openspec/changes/externalize-pr-commenting/specs/pr-bundle-size-comment/spec.md create mode 100644 openspec/changes/externalize-pr-commenting/tasks.md delete mode 100644 src/pr-comment.ts delete mode 100644 tests/pr-comment.test.ts diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 3218005..7a14892 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -26,7 +26,7 @@ body: id: inputs attributes: label: Action inputs - description: Include values such as `path`, `package-name`, `files`, `output-file`, and whether `comment-pr` is enabled. + description: Include values such as `path`, `package-name`, `release-stream`, `files`, `output-file`, and `markdown-output-file`. render: yaml validations: required: false diff --git a/.github/workflows/bundle-size.yml b/.github/workflows/bundle-size.yml index 2680cbc..895aa88 100644 --- a/.github/workflows/bundle-size.yml +++ b/.github/workflows/bundle-size.yml @@ -14,7 +14,6 @@ jobs: permissions: contents: read checks: write - pull-requests: write steps: - name: Checkout repository @@ -98,5 +97,3 @@ jobs: files: | index.js output-file: "bundle-size-comparison.json" - comment-pr: true - github-token: ${{ github.token }} diff --git a/COLLABORATOR_GUIDE.md b/COLLABORATOR_GUIDE.md index 049d127..df813a2 100644 --- a/COLLABORATOR_GUIDE.md +++ b/COLLABORATOR_GUIDE.md @@ -40,8 +40,7 @@ Give extra scrutiny to changes involving: - `src/paths.ts` path normalization or containment checks. - `src/tarball.ts` archive download, decompression, parsing, entry type handling, or file lookup behavior. - `src/report.ts` report output paths and report contents. -- `src/comment.ts` Markdown rendering and escaping. -- `src/pr-comment.ts` GitHub API calls, token usage, event parsing, or permission handling. +- `src/comment.ts` Markdown rendering and escaping used by documentation examples. - `action.yml` inputs, outputs, runtime version, or entrypoint. - Workflow permissions, third-party actions, or dependency updates. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d4adb94..a6d1560 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -40,14 +40,14 @@ Keep `src/index.ts` thin. Prefer focused modules for behavior: - `src/paths.ts`: path normalization and traversal protection. - `src/tarball.ts`: tarball download and parsing. - `src/comparison.ts`: gzip size calculation and report construction. -- `src/report.ts`: JSON report writing. -- `src/comment.ts` and `src/pr-comment.ts`: optional pull request comments. +- `src/report.ts`: JSON and Markdown report writing. +- `src/comment.ts`: Markdown rendering kept in sync with the documented pull request comment recipe. ## Making Changes - Keep changes small and focused. - Add or update tests for behavior changes. -- Preserve the JSON report as machine-readable output. +- Preserve the JSON report as machine-readable output and the Markdown report as comment-ready output. - Treat configured paths, npm metadata, tarball contents, and pull request input as untrusted. - Avoid new runtime dependencies unless there is a clear need. - Do not make the action build the caller's project; workflows should build artifacts before invoking this action. @@ -82,8 +82,7 @@ Security-sensitive changes should include tests for relevant edge cases, especia - Tarball path normalization and package-root stripping. - Missing local or baseline files. - Malformed or truncated tarball entries. -- Markdown escaping in pull request comments. -- Token permission failures when PR comments are enabled. +- Markdown escaping in the generated pull request comment Markdown. ## OpenSpec Changes @@ -106,7 +105,7 @@ Important security expectations: - Keep local reads and report writes inside the configured `path` root. - Do not extract tarball entries to disk. - Treat tarball bytes and tar entry metadata as untrusted. -- Keep `github-token` out of logs, reports, outputs, and comments. +- Treat generated reports as untrusted input when external workflows publish comments from public fork runs. - Prefer immutable `https:` baseline tarball URLs in examples and workflows. - Keep GitHub workflow permissions minimal. diff --git a/README.md b/README.md index b531719..be8e0f2 100644 --- a/README.md +++ b/README.md @@ -55,8 +55,7 @@ There is no normal `lib/` workflow. Vite bundles the action directly from TypeSc | `release-stream` | No | | Optional leading major version number, such as `0` or `1`, used to select npm release baselines from that release stream. | | `files` | Yes | | Newline-delimited file paths to compare in the local project and npm release baselines. | | `output-file` | No | `bundle-size-comparison.json` | Path, relative to `path`, where the JSON comparison report will be written. | -| `comment-pr` | No | `false` | Post or update a bundle size summary comment on pull requests. | -| `github-token` | No | | GitHub token used to post pull request comments when `comment-pr` is enabled. | +| `markdown-output-file` | No | `bundle-size-comparison.md` | Path, relative to `path`, where the Markdown comparison report will be written. | ## Outputs @@ -64,6 +63,7 @@ There is no normal `lib/` workflow. Vite bundles the action directly from TypeSc |------|-------------| | `size` | Total current gzip size in bytes for all compared files. | | `comparison-file` | Absolute path to the generated JSON comparison file. | +| `markdown-file` | Absolute path to the generated Markdown comparison file. | | `total-current-gzip-size` | Total current gzip size in bytes for all compared files. | | `total-baseline-gzip-size` | Total selected primary-release baseline gzip size in bytes for all compared files. | | `total-delta-gzip-size` | Difference in gzip bytes between current and selected primary-release baseline totals. | @@ -97,13 +97,9 @@ steps: output-file: 'bundle-size-comparison.json' ``` -To post the comparison directly on pull requests, enable `comment-pr` and provide a token with comment write permission: +To compare against a maintained major-version stream instead of the npm `latest` stream, set `release-stream` to the leading major version. For example, this compares the local build against the newest stable axios `1.x` release and up to 10 previous stable `1.x` releases, even if npm `latest` points to another major version: ```yaml -permissions: - contents: read - pull-requests: write - steps: - name: Install dependencies run: pnpm install --frozen-lockfile @@ -111,20 +107,28 @@ steps: - name: Build artifacts run: pnpm run build - - name: Compare Bundle Size + - name: Compare Bundle Size Against Axios 1.x uses: axios/bundle-size@main with: package-name: 'axios' + release-stream: '1' files: | dist/axios.js dist/axios.min.js - comment-pr: true - github-token: ${{ github.token }} ``` -To compare against a maintained major-version stream instead of the npm `latest` stream, set `release-stream` to the leading major version. For example, this compares the local build against the newest stable axios `1.x` release and up to 10 previous stable `1.x` releases, even if npm `latest` points to another major version: +The action does not post pull request comments itself. It writes both a JSON report and a Markdown report. The Markdown file contains the same body the built-in comment path used to post, including the hidden marker used for updates. + +For same-repository pull requests, add a follow-up step that reads the Markdown report and posts or updates the marked comment: ```yaml +on: + pull_request: + +permissions: + contents: read + pull-requests: write + steps: - name: Install dependencies run: pnpm install --frozen-lockfile @@ -132,19 +136,158 @@ steps: - name: Build artifacts run: pnpm run build - - name: Compare Bundle Size Against Axios 1.x + - name: Compare Bundle Size uses: axios/bundle-size@main with: package-name: 'axios' - release-stream: '1' files: | dist/axios.js dist/axios.min.js + + - name: Post Bundle Size Comment + uses: actions/github-script@v8 + env: + BUNDLE_SIZE_MARKDOWN: bundle-size-comparison.md + with: + script: | + const fs = require('node:fs'); + + const marker = ''; + const issue_number = context.payload.pull_request?.number; + if (!issue_number) { + core.info('Skipping bundle size comment because this run is not for a pull request.'); + return; + } + + const { owner, repo } = context.repo; + const body = fs.readFileSync(process.env.BUNDLE_SIZE_MARKDOWN, 'utf8'); + const comments = await github.paginate(github.rest.issues.listComments, { + owner, + repo, + issue_number, + per_page: 100, + }); + const existing = comments.find((comment) => comment.body?.includes(marker)); + + if (existing) { + await github.rest.issues.updateComment({ owner, repo, comment_id: existing.id, body }); + } else { + await github.rest.issues.createComment({ owner, repo, issue_number, body }); + } +``` + +That same-workflow comment recipe does not bypass GitHub's public fork restrictions. Fork pull requests receive a read-only `GITHUB_TOKEN` in `pull_request` workflows regardless of requested permissions. For public repositories that accept fork PRs, run comparison without write credentials, upload the Markdown report, and publish the comment from a trusted `workflow_run` workflow. + +Comparison workflow: + +```yaml +name: Bundle Size + +on: + pull_request: + +permissions: + contents: read + +jobs: + bundle-size: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Build artifacts + run: pnpm run build + + - name: Compare Bundle Size + uses: axios/bundle-size@main + with: + package-name: 'axios' + files: | + dist/axios.js + dist/axios.min.js + + - name: Upload bundle size report + uses: actions/upload-artifact@v5 + with: + name: bundle-size-report + path: bundle-size-comparison.md ``` -When `comment-pr` is enabled outside a pull request event, the action writes the JSON report and skips commenting. Fork pull requests receive a read-only `GITHUB_TOKEN` regardless of the workflow's requested permissions; in that case the action logs a warning, skips commenting, and still produces the JSON report and outputs. +Trusted comment workflow: -The comparison file is JSON: +```yaml +name: Bundle Size Comment + +on: + workflow_run: + workflows: ['Bundle Size'] + types: [completed] + +permissions: + actions: read + contents: read + pull-requests: write + +jobs: + comment: + if: >- + ${{ github.event.workflow_run.event == 'pull_request' && + github.event.workflow_run.conclusion == 'success' }} + runs-on: ubuntu-latest + steps: + - name: Download bundle size report + uses: actions/download-artifact@v6 + with: + name: bundle-size-report + path: bundle-size-report + github-token: ${{ github.token }} + run-id: ${{ github.event.workflow_run.id }} + + - name: Post Bundle Size Comment + uses: actions/github-script@v8 + env: + BUNDLE_SIZE_MARKDOWN: bundle-size-report/bundle-size-comparison.md + with: + script: | + const fs = require('node:fs'); + + const marker = ''; + const pr = context.payload.workflow_run.pull_requests[0]; + if (!pr) { + core.info('Skipping bundle size comment because no pull request is associated with this workflow run.'); + return; + } + + const { owner, repo } = context.repo; + const pull = await github.rest.pulls.get({ owner, repo, pull_number: pr.number }); + if (pull.data.head.sha !== context.payload.workflow_run.head_sha) { + core.info('Skipping stale bundle size comment for an outdated workflow run.'); + return; + } + + const issue_number = pr.number; + const body = fs.readFileSync(process.env.BUNDLE_SIZE_MARKDOWN, 'utf8'); + const comments = await github.paginate(github.rest.issues.listComments, { + owner, + repo, + issue_number, + per_page: 100, + }); + const existing = comments.find((comment) => comment.body?.includes(marker)); + + if (existing) { + await github.rest.issues.updateComment({ owner, repo, comment_id: existing.id, body }); + } else { + await github.rest.issues.createComment({ owner, repo, issue_number, body }); + } +``` + +Do not use `pull_request_target` to checkout, install, build, or otherwise execute pull-request-controlled code with writable credentials. `pull_request_target` can be appropriate for trusted metadata-only automation, but bundle-size comparison requires building untrusted PR code before the report exists. + +The JSON comparison file is machine-readable: ```json { @@ -206,7 +349,9 @@ The comparison file is JSON: } ``` -When `release-stream` is omitted, the npm `latest` release is the primary baseline for top-level `baseline`, `files`, `totals`, and action outputs. The `history` array includes the latest release plus up to 10 previous stable releases ordered by npm publish time. When `release-stream` is configured, the newest stable release in that major-version stream is the primary baseline and `history` is limited to that stream; the report includes a top-level `releaseStream` number and pull request comments describe the configured stream. Previous releases that do not contain every configured file are marked as incomplete instead of failing the action. +The Markdown comparison file is comment-ready and uses the same bundle-size report structure shown in the pull request examples above. + +When `release-stream` is omitted, the npm `latest` release is the primary baseline for top-level `baseline`, `files`, `totals`, and action outputs. The `history` array includes the latest release plus up to 10 previous stable releases ordered by npm publish time. When `release-stream` is configured, the newest stable release in that major-version stream is the primary baseline and `history` is limited to that stream; the JSON report includes a top-level `releaseStream` number and the Markdown report describes the configured stream. Previous releases that do not contain every configured file are marked as incomplete instead of failing the action. Because this repository *is* the action, a workflow inside the same repo can reference it with `./` after preparing local files to compare: @@ -295,7 +440,7 @@ env \ ## Current Behavior -The action fetches npm registry metadata for `package-name`, resolves either the `latest` dist-tag plus up to 10 previous stable releases or the configured `release-stream` plus up to 10 previous stable releases in that major version, downloads each selected release tarball, reads regular file entries, strips a single shared top-level directory such as `package/`, and compares the configured paths against local files under `path`. It measures gzip-compressed bytes for each file and writes a JSON report. It does not enforce budgets or target sizes. +The action fetches npm registry metadata for `package-name`, resolves either the `latest` dist-tag plus up to 10 previous stable releases or the configured `release-stream` plus up to 10 previous stable releases in that major version, downloads each selected release tarball, reads regular file entries, strips a single shared top-level directory such as `package/`, and compares the configured paths against local files under `path`. It measures gzip-compressed bytes for each file and writes JSON and Markdown reports. It does not enforce budgets or target sizes. Suggested next steps: diff --git a/SECURITY.md b/SECURITY.md index caf8b9b..dcc737b 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -43,7 +43,7 @@ In scope examples: - Path traversal that reads or writes outside the configured `path` root. - Tarball parsing flaws that allow workspace overwrite, unexpected file selection, or denial of service. -- Leaks of `github-token`, `GITHUB_TOKEN`, or other secrets through logs, reports, outputs, or comments. +- Leaks of `GITHUB_TOKEN` or other secrets through logs, reports, outputs, or comments. - Pull request comment injection that can mislead reviewers or expose sensitive data. - Runtime bundle divergence that causes reviewed source to differ from executed action behavior. - Workflow permission weaknesses in this repository's own CI configuration. @@ -59,8 +59,8 @@ Out of scope examples: - Configure the intended npm `package-name` and review reports for the resolved latest release version. - Keep `files` and `output-file` relative to the configured `path` root. -- Use minimal workflow permissions. JSON-only comparisons should not need write permissions. -- Enable `comment-pr` only when PR comments are needed, and pass the default `${{ github.token }}` unless a stronger token is strictly required. +- Use minimal workflow permissions. Generating reports should not need write permissions. +- Publish PR comments from external workflow steps that read the Markdown report. For public fork PRs, use a trusted `workflow_run` workflow rather than running PR-controlled code with writable credentials. - Do not include generated files that may contain secrets in the configured `files` list. - Pin third-party actions in workflows and avoid persisting checkout credentials unless needed. diff --git a/THREAT_MODEL.md b/THREAT_MODEL.md index 7a637ec..c34b3bf 100644 --- a/THREAT_MODEL.md +++ b/THREAT_MODEL.md @@ -2,7 +2,7 @@ ## Scope -This threat model covers the `axios/bundle-size` GitHub Action in this repository. The action compares gzip sizes for local build artifacts against matching files from npm release tarball baselines, writes a JSON report, exposes GitHub Action outputs, and can optionally post or update a pull request comment. +This threat model covers the `axios/bundle-size` GitHub Action in this repository. The action compares gzip sizes for local build artifacts against matching files from npm release tarball baselines, writes JSON and Markdown reports, and exposes GitHub Action outputs. The runtime entrypoint is the committed `dist/index.js` bundle referenced by `action.yml`. The TypeScript source under `src/` is the reviewed source of truth, but GitHub Actions executes `dist/index.js` directly. @@ -10,7 +10,7 @@ Out of scope: - Building the caller's project before this action runs. - Enforcing bundle-size budgets or blocking releases based on size changes. -- Uploading artifacts outside the JSON report written into the workspace. +- Uploading artifacts outside the reports written into the workspace. - Securing arbitrary workflow steps before or after this action. ## System Overview @@ -21,8 +21,7 @@ The action accepts these trust-relevant inputs: - `package-name`: npm package whose release tarballs provide baselines. - `files`: newline-delimited artifact paths to compare. - `output-file`: report path relative to `path`. -- `comment-pr`: whether to post or update a pull request comment. -- `github-token`: token used only when `comment-pr` is enabled. +- `markdown-output-file`: Markdown report path relative to `path`. Primary data flow: @@ -33,15 +32,12 @@ Primary data flow: 5. Gunzip and parse regular files from each tar archive into memory. 6. Normalize configured paths and resolve local files under `path`. 7. Gzip local and baseline file bytes and calculate deltas. -8. Write a JSON report under `path` at `output-file`. +8. Write JSON and Markdown reports under `path`. 9. Set action outputs. -10. If enabled and running for a pull request, call the GitHub comments API to update or create one comment identified by a hidden marker. ## Assets - Integrity of the comparison report and action outputs. -- Confidentiality of the `github-token` input and default `GITHUB_TOKEN`. -- Integrity of pull request comments written by the action. - Availability of the CI job running the action. - Integrity of the checked-out workspace, especially files outside the configured project root. - Integrity of the committed `dist/index.js` action bundle. @@ -52,7 +48,7 @@ Primary data flow: - External network to runner: npm metadata and release tarball downloads return untrusted bytes from the npm registry and tarball endpoints. - Tarball contents to parser: archive headers, paths, sizes, and file contents are attacker-controlled if the baseline source is compromised or misconfigured. - Workspace to action: local build artifacts may be produced from untrusted pull request code. -- Action to GitHub API: PR commenting uses a token whose permissions are configured by the workflow and constrained by GitHub event rules. +- Action report to caller workflow: downstream workflow steps may read the generated reports and publish them elsewhere, including pull request comments. - Source to runtime bundle: reviewers inspect `src/`, while users execute `dist/index.js`. ## Threat Actors @@ -66,14 +62,12 @@ Primary data flow: - Release tarball URLs from npm metadata must use `http:` or `https:`. - Configured file paths reject absolute paths, Windows drive paths, UNC-like paths, empty paths, and `..` traversal. -- Local artifact reads and JSON report writes are resolved through `resolveInsideRoot()` to keep them under `path`. +- Local artifact reads and report writes are resolved through `resolveInsideRoot()` to keep them under `path`. - Tarball entries are parsed in memory as regular files only; entries are not extracted to disk, so tar path traversal and symlink entries cannot overwrite workspace files. - Tarball entry paths are normalized and a single shared package root such as `package/` is stripped only for lookup convenience. - Missing local or latest baseline files fail the action; missing previous-release files are marked as incomplete historical comparisons. -- PR commenting is opt-in and requires `github-token` when enabled. -- PR comments are skipped outside pull request events. -- Fork pull request token permission failures are downgraded to warnings so reporting still succeeds without requiring elevated token permissions. -- Markdown table file paths are escaped before rendering in PR comments. +- The action does not consume GitHub comment tokens or call the GitHub comments API. +- The action Markdown renderer escapes Markdown table separators, backslashes, and code span backticks for report-derived file paths. - Repository workflows use reduced permissions, and most third-party GitHub Actions are pinned by commit SHA (the test reporter step is currently version-tagged). - Dependabot updates npm and GitHub Actions dependencies. - A zizmor workflow scans GitHub Actions configuration. @@ -82,14 +76,14 @@ Primary data flow: | Threat | Impact | Existing Mitigation | Residual Risk / Recommendation | |---|---|---|---| -| Malicious `files` or `output-file` escapes the workspace root | Read or overwrite files outside the intended project tree | Path normalization rejects absolute and traversal paths; final resolution checks containment under `path` | Continue testing path handling across POSIX, Windows-like, and backslash inputs | +| Malicious `files`, `output-file`, or `markdown-output-file` escapes the workspace root | Read or overwrite files outside the intended project tree | Path normalization rejects absolute and traversal paths; final resolution checks containment under `path` | Continue testing path handling across POSIX, Windows-like, and backslash inputs | | Malicious tarball attempts path traversal or symlink overwrite | Workspace overwrite or unexpected file selection | Tar entries are never written to disk; only regular file contents are stored in memory | Continue ignoring non-regular entries; avoid future disk extraction unless using hardened extraction rules | | Malicious tarball causes memory or CPU exhaustion | CI job denial of service | Tar size fields are validated as safe integers and truncated entries fail | No hard byte, file count, decompressed size, or fetch timeout limit exists; consider configurable limits if the action will process untrusted baselines | -| Malicious or compromised npm metadata changes comparison results | Misleading report or PR comment | The action resolves releases from npm metadata and failed downloads fail the action | Prefer the public npm registry for public packages; consider integrity verification if future requirements need stronger supply-chain guarantees | +| Malicious or compromised npm metadata changes comparison results | Misleading report or downstream comment | The action resolves releases from npm metadata and failed downloads fail the action | Prefer the public npm registry for public packages; consider integrity verification if future requirements need stronger supply-chain guarantees | | HTTP release tarball URI is intercepted or modified | Misleading report or denial of service | Non-HTTP(S) protocols are rejected | `http:` tarball URLs from metadata are currently allowed; consider rejecting plain HTTP if compatibility allows | -| PR comment token has excessive permissions | Token misuse impact if later code is compromised | README example grants `contents: read` and `pull-requests: write`; workflows use least practical permissions | Keep `github-token` scoped to comment writing only; avoid personal access tokens unless required | -| Malicious PR attempts to exfiltrate `github-token` through comment content | Secret disclosure in PR comment | Current rendered comment includes size data and configured file paths, not token values | Keep token out of reports, logs, errors, and rendered comments; review future comment fields for secret exposure | -| Markdown injection through compared file paths | Misleading PR comment formatting or hidden content | Markdown table separators, backslashes, and code span backticks are escaped | Continue treating rendered file paths as untrusted text | +| Downstream PR comment workflow grants excessive permissions | Token misuse impact if external workflow code is compromised | README examples scope comment publishing to workflow-owned steps and keep report generation at `contents: read` | Keep comment workflows minimal; prefer `pull-requests: write` or `issues: write` over broader permissions | +| Downstream workflow posts Markdown from an untrusted PR run | Misleading PR comment formatting or hidden content | The action renderer escapes report-derived file paths before writing Markdown | Treat artifacts from fork workflows as untrusted input; use trusted action refs and verify PR/head SHA before posting | +| Markdown injection through compared file paths | Misleading downstream comment formatting or hidden content | The action renderer escapes table separators, backslashes, and code span backticks | Continue treating rendered file paths as untrusted text | | Report includes absolute `localRoot` path | Runner path disclosure | Report is intended as local CI output and action output exposes report path | If reports become public artifacts, consider omitting or relativizing `localRoot` | | Runtime bundle diverges from reviewed source | Users execute unreviewed or stale code | Build guidance requires committing updated `dist/`; tests run against source modules | Review `dist/index.js` diffs with source changes; consider CI that verifies `dist/` is current | | Dependency compromise | Arbitrary code execution during development/build or bundled runtime compromise | Runtime dependency footprint is small; lockfile is committed; Dependabot is enabled | Keep dependencies minimal, review dependency updates, and rebuild `dist/` from trusted environments | @@ -98,10 +92,10 @@ Primary data flow: ## Secure Usage Guidance - Configure the intended npm `package-name` and review reports for the resolved latest release version. -- Keep workflow permissions minimal. For JSON-only reports, `contents: read` is sufficient. For PR comments, add only the permission needed to write comments, such as `pull-requests: write` for this repository's workflow pattern. -- Pass `${{ github.token }}` rather than a long-lived personal access token unless GitHub's default token cannot satisfy the use case. +- Keep workflow permissions minimal. Report generation requires only the permissions needed to checkout and build the project, usually `contents: read`. +- Publish pull request comments outside this action from the generated Markdown report. For public fork PRs, use a trusted `workflow_run` workflow and do not execute pull-request-controlled code with writable credentials. - Build artifacts in an explicit step before invoking this action; this action should only compare files, not run arbitrary project build logic. -- Keep `files` and `output-file` relative to `path` and avoid including generated files that may contain secrets. +- Keep `files`, `output-file`, and `markdown-output-file` relative to `path` and avoid including generated files that may contain secrets. - Review both `src/` and `dist/index.js` when accepting changes to this action. ## Security Test Coverage Expectations @@ -111,5 +105,5 @@ Changes to security-sensitive behavior should include tests for: - Rejection of unsafe configured paths and report output paths. - Missing local and baseline file failures. - Tarball parsing behavior for package-root stripping, malformed archives, truncated entries, and non-regular entries. -- PR comment rendering escaping for file paths containing Markdown-sensitive characters. -- PR comment behavior outside pull request events and when token permissions are insufficient. +- Documented comment rendering escaping for file paths containing Markdown-sensitive characters. +- Workflow recipes that publish comments from reports generated by public fork pull requests. diff --git a/action.yml b/action.yml index 7a77e55..565f313 100644 --- a/action.yml +++ b/action.yml @@ -24,19 +24,18 @@ inputs: description: 'Path, relative to the local project root, where the JSON comparison report will be written.' required: false default: 'bundle-size-comparison.json' - comment-pr: - description: 'Post or update a bundle size summary comment on pull requests.' - required: false - default: 'false' - github-token: - description: 'GitHub token used to post pull request comments when comment-pr is enabled.' + markdown-output-file: + description: 'Path, relative to the local project root, where the Markdown comparison report will be written.' required: false + default: 'bundle-size-comparison.md' outputs: size: description: 'Total current gzip size in bytes for all compared files.' comparison-file: description: 'Absolute path to the generated JSON comparison file.' + markdown-file: + description: 'Absolute path to the generated Markdown comparison file.' total-current-gzip-size: description: 'Total current gzip size in bytes for all compared files.' total-baseline-gzip-size: diff --git a/dist/index.js b/dist/index.js index facc7e8..947054c 100644 --- a/dist/index.js +++ b/dist/index.js @@ -14,6 +14,6 @@ ${n.count} ${n.noun} ${n.is} pending: ${e.format(t)} `.trim())}}})),Fe=o(((e,t)=>{var n=Symbol.for(`undici.globalDispatcher.1`),{InvalidArgumentError:r}=M(),i=Q();o()===void 0&&a(new i);function a(e){if(!e||typeof e.dispatch!=`function`)throw new r(`Argument agent must implement Agent`);Object.defineProperty(globalThis,n,{value:e,writable:!0,enumerable:!1,configurable:!1})}function o(){return globalThis[n]}t.exports={setGlobalDispatcher:a,getGlobalDispatcher:o}})),Ie=o(((e,t)=>{t.exports=class{#e;constructor(e){if(typeof e!=`object`||!e)throw TypeError(`handler must be an object`);this.#e=e}onConnect(...e){return this.#e.onConnect?.(...e)}onError(...e){return this.#e.onError?.(...e)}onUpgrade(...e){return this.#e.onUpgrade?.(...e)}onResponseStarted(...e){return this.#e.onResponseStarted?.(...e)}onHeaders(...e){return this.#e.onHeaders?.(...e)}onData(...e){return this.#e.onData?.(...e)}onComplete(...e){return this.#e.onComplete?.(...e)}onBodySent(...e){return this.#e.onBodySent?.(...e)}}})),Le=o(((e,t)=>{var n=ce();t.exports=e=>{let t=e?.maxRedirections;return e=>function(r,i){let{maxRedirections:a=t,...o}=r;return a?e(o,new n(e,a,r,i)):e(r,i)}}})),Re=o(((e,t)=>{var n=he();t.exports=e=>t=>function(r,i){return t(r,new n({...r,retryOptions:{...e,...r.retryOptions}},{handler:i,dispatch:t}))}})),ze=o(((e,t)=>{var n=F(),{InvalidArgumentError:r,RequestAbortedError:i}=M(),a=Ie(),o=class extends a{#e=1024*1024;#t=null;#n=!1;#r=!1;#i=0;#a=null;#o=null;constructor({maxSize:e},t){if(super(t),e!=null&&(!Number.isFinite(e)||e<1))throw new r(`maxSize must be a number greater than 0`);this.#e=e??this.#e,this.#o=t}onConnect(e){this.#t=e,this.#o.onConnect(this.#s.bind(this))}#s(e){this.#r=!0,this.#a=e}onHeaders(e,t,r,a){let o=n.parseHeaders(t)[`content-length`];if(o!=null&&o>this.#e)throw new i(`Response size (${o}) larger than maxSize (${this.#e})`);return this.#r?!0:this.#o.onHeaders(e,t,r,a)}onError(e){this.#n||(e=this.#a??e,this.#o.onError(e))}onData(e){return this.#i+=e.length,this.#i>=this.#e&&(this.#n=!0,this.#r?this.#o.onError(this.#a):this.#o.onComplete([])),!0}onComplete(e){if(!this.#n){if(this.#r){this.#o.onError(this.reason);return}this.#o.onComplete(e)}}};function s({maxSize:e}={maxSize:1024*1024}){return t=>function(n,r){let{dumpMaxSize:i=e}=n;return t(n,new o({maxSize:i},r))}}t.exports=s})),Be=o(((e,t)=>{var{isIP:n}=require(`node:net`),{lookup:r}=require(`node:dns`),i=Ie(),{InvalidArgumentError:a,InformationalError:o}=M(),s=2**31-1,c=class{#e=0;#t=0;#n=new Map;dualStack=!0;affinity=null;lookup=null;pick=null;constructor(e){this.#e=e.maxTTL,this.#t=e.maxItems,this.dualStack=e.dualStack,this.affinity=e.affinity,this.lookup=e.lookup??this.#r,this.pick=e.pick??this.#i}get full(){return this.#n.size===this.#t}runLookup(e,t,n){let r=this.#n.get(e.hostname);if(r==null&&this.full){n(null,e.origin);return}let i={affinity:this.affinity,dualStack:this.dualStack,lookup:this.lookup,pick:this.pick,...t.dns,maxTTL:this.#e,maxItems:this.#t};if(r==null)this.lookup(e,i,(t,r)=>{if(t||r==null||r.length===0){n(t??new o(`No DNS entries found`));return}this.setRecords(e,r);let a=this.#n.get(e.hostname),s=this.pick(e,a,i.affinity),c;c=typeof s.port==`number`?`:${s.port}`:e.port===``?``:`:${e.port}`,n(null,`${e.protocol}//${s.family===6?`[${s.address}]`:s.address}${c}`)});else{let a=this.pick(e,r,i.affinity);if(a==null){this.#n.delete(e.hostname),this.runLookup(e,t,n);return}let o;o=typeof a.port==`number`?`:${a.port}`:e.port===``?``:`:${e.port}`,n(null,`${e.protocol}//${a.family===6?`[${a.address}]`:a.address}${o}`)}}#r(e,t,n){r(e.hostname,{all:!0,family:this.dualStack===!1?this.affinity:0,order:`ipv4first`},(e,t)=>{if(e)return n(e);let r=new Map;for(let e of t)r.set(`${e.address}:${e.family}`,e);n(null,r.values())})}#i(e,t,n){let r=null,{records:i,offset:a}=t,o;if(this.dualStack?(n??(a==null||a===s?(t.offset=0,n=4):(t.offset++,n=(t.offset&1)==1?6:4)),o=i[n]!=null&&i[n].ips.length>0?i[n]:i[n===4?6:4]):o=i[n],o==null||o.ips.length===0)return r;o.offset==null||o.offset===s?o.offset=0:o.offset++;let c=o.offset%o.ips.length;return r=o.ips[c]??null,r==null?r:Date.now()-r.timestamp>r.ttl?(o.ips.splice(c,1),this.pick(e,t,n)):r}setRecords(e,t){let n=Date.now(),r={records:{4:null,6:null}};for(let e of t){e.timestamp=n,typeof e.ttl==`number`?e.ttl=Math.min(e.ttl,this.#e):e.ttl=this.#e;let t=r.records[e.family]??{ips:[]};t.ips.push(e),r.records[e.family]=t}this.#n.set(e.hostname,r)}getHandler(e,t){return new l(this,e,t)}},l=class extends i{#e=null;#t=null;#n=null;#r=null;#i=null;constructor(e,{origin:t,handler:n,dispatch:r},i){super(n),this.#i=t,this.#r=n,this.#t={...i},this.#e=e,this.#n=r}onError(e){switch(e.code){case`ETIMEDOUT`:case`ECONNREFUSED`:if(this.#e.dualStack){this.#e.runLookup(this.#i,this.#t,(e,t)=>{if(e)return this.#r.onError(e);let n={...this.#t,origin:t};this.#n(n,this)});return}this.#r.onError(e);return;case`ENOTFOUND`:this.#e.deleteRecord(this.#i);default:this.#r.onError(e);break}}};t.exports=e=>{if(e?.maxTTL!=null&&(typeof e?.maxTTL!=`number`||e?.maxTTL<0))throw new a(`Invalid maxTTL. Must be a positive number`);if(e?.maxItems!=null&&(typeof e?.maxItems!=`number`||e?.maxItems<1))throw new a(`Invalid maxItems. Must be a positive number and greater than zero`);if(e?.affinity!=null&&e?.affinity!==4&&e?.affinity!==6)throw new a(`Invalid affinity. Must be either 4 or 6`);if(e?.dualStack!=null&&typeof e?.dualStack!=`boolean`)throw new a(`Invalid dualStack. Must be a boolean`);if(e?.lookup!=null&&typeof e?.lookup!=`function`)throw new a(`Invalid lookup. Must be a function`);if(e?.pick!=null&&typeof e?.pick!=`function`)throw new a(`Invalid pick. Must be a function`);let t=e?.dualStack??!0,r;r=t?e?.affinity??null:e?.affinity??4;let i=new c({maxTTL:e?.maxTTL??1e4,lookup:e?.lookup??null,pick:e?.pick??null,dualStack:t,affinity:r,maxItems:e?.maxItems??1/0});return e=>function(t,r){let a=t.origin.constructor===URL?t.origin:new URL(t.origin);return n(a.hostname)===0?(i.runLookup(a,t,(n,o)=>{if(n)return r.onError(n);let s=null;s={...t,servername:a.hostname,origin:o,headers:{host:a.hostname,...t.headers}},e(s,i.getHandler({origin:a,dispatch:e,handler:r},t))}),!0):e(t,r)}}})),Ve=o(((e,t)=>{var{kConstruct:n}=j(),{kEnumerableProperty:r}=F(),{iteratorMixin:i,isValidHeaderName:a,isValidHeaderValue:o}=W(),{webidl:s}=U(),c=require(`node:assert`),l=require(`node:util`),u=Symbol(`headers map`),d=Symbol(`headers map sorted`);function f(e){return e===10||e===13||e===9||e===32}function p(e){let t=0,n=e.length;for(;n>t&&f(e.charCodeAt(n-1));)--n;for(;n>t&&f(e.charCodeAt(t));)++t;return t===0&&n===e.length?e:e.substring(t,n)}function m(e,t){if(Array.isArray(t))for(let n=0;n>`,`record`]})}function h(e,t,n){if(n=p(n),!a(t))throw s.errors.invalidArgument({prefix:`Headers.append`,value:t,type:`header name`});if(!o(n))throw s.errors.invalidArgument({prefix:`Headers.append`,value:n,type:`header value`});if(y(e)===`immutable`)throw TypeError(`immutable`);return x(e).append(t,n,!1)}function g(e,t){return e[0]>1),t[s][0]<=l[0]?o=s+1:a=s;if(r!==s){for(i=r;i>o;)t[i]=t[--i];t[o]=l}}if(!n.next().done)throw TypeError(`Unreachable`);return t}else{let e=0;for(let{0:n,1:{value:r}}of this[u])t[e++]=[n,r],c(r!==null);return t.sort(g)}}},v=class e{#e;#t;constructor(e=void 0){s.util.markAsUncloneable(this),e!==n&&(this.#t=new _,this.#e=`none`,e!==void 0&&(e=s.converters.HeadersInit(e,`Headers contructor`,`init`),m(this,e)))}append(t,n){s.brandCheck(this,e),s.argumentLengthCheck(arguments,2,`Headers.append`);let r=`Headers.append`;return t=s.converters.ByteString(t,r,`name`),n=s.converters.ByteString(n,r,`value`),h(this,t,n)}delete(t){if(s.brandCheck(this,e),s.argumentLengthCheck(arguments,1,`Headers.delete`),t=s.converters.ByteString(t,`Headers.delete`,`name`),!a(t))throw s.errors.invalidArgument({prefix:`Headers.delete`,value:t,type:`header name`});if(this.#e===`immutable`)throw TypeError(`immutable`);this.#t.contains(t,!1)&&this.#t.delete(t,!1)}get(t){s.brandCheck(this,e),s.argumentLengthCheck(arguments,1,`Headers.get`);let n=`Headers.get`;if(t=s.converters.ByteString(t,n,`name`),!a(t))throw s.errors.invalidArgument({prefix:n,value:t,type:`header name`});return this.#t.get(t,!1)}has(t){s.brandCheck(this,e),s.argumentLengthCheck(arguments,1,`Headers.has`);let n=`Headers.has`;if(t=s.converters.ByteString(t,n,`name`),!a(t))throw s.errors.invalidArgument({prefix:n,value:t,type:`header name`});return this.#t.contains(t,!1)}set(t,n){s.brandCheck(this,e),s.argumentLengthCheck(arguments,2,`Headers.set`);let r=`Headers.set`;if(t=s.converters.ByteString(t,r,`name`),n=s.converters.ByteString(n,r,`value`),n=p(n),!a(t))throw s.errors.invalidArgument({prefix:r,value:t,type:`header name`});if(!o(n))throw s.errors.invalidArgument({prefix:r,value:n,type:`header value`});if(this.#e===`immutable`)throw TypeError(`immutable`);this.#t.set(t,n,!1)}getSetCookie(){s.brandCheck(this,e);let t=this.#t.cookies;return t?[...t]:[]}get[d](){if(this.#t[d])return this.#t[d];let e=[],t=this.#t.toSortedArray(),n=this.#t.cookies;if(n===null||n.length===1)return this.#t[d]=t;for(let r=0;r>`](e,t,n,r.bind(e)):s.converters[`record`](e,t,n)}throw s.errors.conversionFailed({prefix:`Headers constructor`,argument:`Argument 1`,types:[`sequence>`,`record`]})},t.exports={fill:m,compareHeaderName:g,Headers:v,HeadersList:_,getHeadersGuard:y,setHeadersGuard:b,setHeadersList:S,getHeadersList:x}})),He=o(((e,t)=>{var{Headers:n,HeadersList:r,fill:i,getHeadersGuard:a,setHeadersGuard:o,setHeadersList:s}=Ve(),{extractBody:c,cloneBody:l,mixinBody:u,hasFinalizationRegistry:d,streamRegistry:f,bodyUnusable:p}=oe(),m=F(),h=require(`node:util`),{kEnumerableProperty:g}=m,{isValidReasonPhrase:_,isCancelled:v,isAborted:y,isBlobLike:b,serializeJavascriptValueToJSONString:x,isErrorLike:S,isomorphicEncode:C,environmentSettingsObject:w}=W(),{redirectStatusSet:T,nullBodyStatus:E}=ie(),{kState:D,kHeaders:O}=G(),{webidl:k}=U(),{FormData:A}=q(),{URLSerializer:M}=H(),{kConstruct:N}=j(),P=require(`node:assert`),{types:I}=require(`node:util`),L=new TextEncoder(`utf-8`),R=class e{static error(){return K(V(),`immutable`)}static json(e,t={}){k.argumentLengthCheck(arguments,1,`Response.json`),t!==null&&(t=k.converters.ResponseInit(t));let n=c(L.encode(x(e))),r=K(B({}),`response`);return ae(r,t,{body:n[0],type:`application/json`}),r}static redirect(e,t=302){k.argumentLengthCheck(arguments,1,`Response.redirect`),e=k.converters.USVString(e),t=k.converters[`unsigned short`](t);let n;try{n=new URL(e,w.settingsObject.baseUrl)}catch(t){throw TypeError(`Failed to parse URL from ${e}`,{cause:t})}if(!T.has(t))throw RangeError(`Invalid status code ${t}`);let r=K(B({}),`immutable`);r[D].status=t;let i=C(M(n));return r[D].headersList.append(`location`,i,!0),r}constructor(e=null,t={}){if(k.util.markAsUncloneable(this),e===N)return;e!==null&&(e=k.converters.BodyInit(e)),t=k.converters.ResponseInit(t),this[D]=B({}),this[O]=new n(N),o(this[O],`response`),s(this[O],this[D].headersList);let r=null;if(e!=null){let[t,n]=c(e);r={body:t,type:n}}ae(this,t,r)}get type(){return k.brandCheck(this,e),this[D].type}get url(){k.brandCheck(this,e);let t=this[D].urlList,n=t[t.length-1]??null;return n===null?``:M(n,!0)}get redirected(){return k.brandCheck(this,e),this[D].urlList.length>1}get status(){return k.brandCheck(this,e),this[D].status}get ok(){return k.brandCheck(this,e),this[D].status>=200&&this[D].status<=299}get statusText(){return k.brandCheck(this,e),this[D].statusText}get headers(){return k.brandCheck(this,e),this[O]}get body(){return k.brandCheck(this,e),this[D].body?this[D].body.stream:null}get bodyUsed(){return k.brandCheck(this,e),!!this[D].body&&m.isDisturbed(this[D].body.stream)}clone(){if(k.brandCheck(this,e),p(this))throw k.errors.exception({header:`Response.clone`,message:`Body has already been consumed.`});let t=z(this[D]);return d&&this[D].body?.stream&&f.register(this,new WeakRef(this[D].body.stream)),K(t,a(this[O]))}[h.inspect.custom](e,t){t.depth===null&&(t.depth=2),t.colors??=!0;let n={status:this.status,statusText:this.statusText,headers:this.headers,body:this.body,bodyUsed:this.bodyUsed,ok:this.ok,redirected:this.redirected,type:this.type,url:this.url};return`Response ${h.formatWithOptions(t,n)}`}};u(R),Object.defineProperties(R.prototype,{type:g,url:g,status:g,ok:g,redirected:g,statusText:g,headers:g,clone:g,body:g,bodyUsed:g,[Symbol.toStringTag]:{value:`Response`,configurable:!0}}),Object.defineProperties(R,{json:g,redirect:g,error:g});function z(e){if(e.internalResponse)return ne(z(e.internalResponse),e.type);let t=B({...e,body:null});return e.body!=null&&(t.body=l(t,e.body)),t}function B(e){return{aborted:!1,rangeRequested:!1,timingAllowPassed:!1,requestIncludesCredentials:!1,type:`default`,status:200,timingInfo:null,cacheState:``,statusText:``,...e,headersList:e?.headersList?new r(e?.headersList):new r,urlList:e?.urlList?[...e.urlList]:[]}}function V(e){return B({type:`error`,status:0,error:S(e)?e:Error(e&&String(e)),aborted:e&&e.name===`AbortError`})}function ee(e){return e.type===`error`&&e.status===0}function te(e,t){return t={internalResponse:e,...t},new Proxy(e,{get(e,n){return n in t?t[n]:e[n]},set(e,n,r){return P(!(n in t)),e[n]=r,!0}})}function ne(e,t){if(t===`basic`)return te(e,{type:`basic`,headersList:e.headersList});if(t===`cors`)return te(e,{type:`cors`,headersList:e.headersList});if(t===`opaque`)return te(e,{type:`opaque`,urlList:Object.freeze([]),status:0,statusText:``,body:null});if(t===`opaqueredirect`)return te(e,{type:`opaqueredirect`,status:0,statusText:``,headersList:[],body:null});P(!1)}function re(e,t=null){return P(v(e)),y(e)?V(Object.assign(new DOMException(`The operation was aborted.`,`AbortError`),{cause:t})):V(Object.assign(new DOMException(`Request was cancelled.`),{cause:t}))}function ae(e,t,n){if(t.status!==null&&(t.status<200||t.status>599))throw RangeError(`init["status"] must be in the range of 200 to 599, inclusive.`);if(`statusText`in t&&t.statusText!=null&&!_(String(t.statusText)))throw TypeError(`Invalid statusText`);if(`status`in t&&t.status!=null&&(e[D].status=t.status),`statusText`in t&&t.statusText!=null&&(e[D].statusText=t.statusText),`headers`in t&&t.headers!=null&&i(e[O],t.headers),n){if(E.includes(e.status))throw k.errors.exception({header:`Response constructor`,message:`Invalid response status code ${e.status}`});e[D].body=n.body,n.type!=null&&!e[D].headersList.contains(`content-type`,!0)&&e[D].headersList.append(`content-type`,n.type,!0)}}function K(e,t){let r=new R(N);return r[D]=e,r[O]=new n(N),s(r[O],e.headersList),o(r[O],t),d&&e.body?.stream&&f.register(r,new WeakRef(e.body.stream)),r}k.converters.ReadableStream=k.interfaceConverter(ReadableStream),k.converters.FormData=k.interfaceConverter(A),k.converters.URLSearchParams=k.interfaceConverter(URLSearchParams),k.converters.XMLHttpRequestBodyInit=function(e,t,n){return typeof e==`string`?k.converters.USVString(e,t,n):b(e)?k.converters.Blob(e,t,n,{strict:!1}):ArrayBuffer.isView(e)||I.isArrayBuffer(e)?k.converters.BufferSource(e,t,n):m.isFormDataLike(e)?k.converters.FormData(e,t,n,{strict:!1}):e instanceof URLSearchParams?k.converters.URLSearchParams(e,t,n):k.converters.DOMString(e,t,n)},k.converters.BodyInit=function(e,t,n){return e instanceof ReadableStream?k.converters.ReadableStream(e,t,n):e?.[Symbol.asyncIterator]?e:k.converters.XMLHttpRequestBodyInit(e,t,n)},k.converters.ResponseInit=k.dictionaryConverter([{key:`status`,converter:k.converters[`unsigned short`],defaultValue:()=>200},{key:`statusText`,converter:k.converters.ByteString,defaultValue:()=>``},{key:`headers`,converter:k.converters.HeadersInit}]),t.exports={isNetworkError:ee,makeNetworkError:V,makeResponse:B,makeAppropriateNetworkError:re,filterResponse:ne,Response:R,cloneResponse:z,fromInnerResponse:K}})),Ue=o(((e,t)=>{var{kConnected:n,kSize:r}=j(),i=class{constructor(e){this.value=e}deref(){return this.value[n]===0&&this.value[r]===0?void 0:this.value}},a=class{constructor(e){this.finalizer=e}register(e,t){e.on&&e.on(`disconnect`,()=>{e[n]===0&&e[r]===0&&this.finalizer(t)})}unregister(e){}};t.exports=function(){return process.env.NODE_V8_COVERAGE&&process.version.startsWith(`v18`)?(process._rawDebug(`Using compatibility WeakRef and FinalizationRegistry`),{WeakRef:i,FinalizationRegistry:a}):{WeakRef,FinalizationRegistry}}})),We=o(((e,t)=>{var{extractBody:n,mixinBody:r,cloneBody:i,bodyUnusable:a}=oe(),{Headers:o,fill:s,HeadersList:c,setHeadersGuard:l,getHeadersGuard:u,setHeadersList:d,getHeadersList:f}=Ve(),{FinalizationRegistry:p}=Ue()(),m=F(),h=require(`node:util`),{isValidHTTPToken:g,sameOrigin:_,environmentSettingsObject:v}=W(),{forbiddenMethodsSet:y,corsSafeListedMethodsSet:b,referrerPolicy:x,requestRedirect:S,requestMode:C,requestCredentials:w,requestCache:T,requestDuplex:E}=ie(),{kEnumerableProperty:D,normalizedMethodRecordsBase:O,normalizedMethodRecords:k}=m,{kHeaders:A,kSignal:M,kState:N,kDispatcher:P}=G(),{webidl:I}=U(),{URLSerializer:L}=H(),{kConstruct:R}=j(),z=require(`node:assert`),{getMaxListeners:B,setMaxListeners:V,getEventListeners:ee,defaultMaxListeners:te}=require(`node:events`),ne=Symbol(`abortController`),re=new p(({signal:e,abort:t})=>{e.removeEventListener(`abort`,t)}),ae=new WeakMap;function K(e){return t;function t(){let n=e.deref();if(n!==void 0){re.unregister(t),this.removeEventListener(`abort`,t),n.abort(this.reason);let e=ae.get(n.signal);if(e!==void 0){if(e.size!==0){for(let t of e){let e=t.deref();e!==void 0&&e.abort(this.reason)}e.clear()}ae.delete(n.signal)}}}}var q=!1,J=class e{constructor(t,r={}){if(I.util.markAsUncloneable(this),t===R)return;let i=`Request constructor`;I.argumentLengthCheck(arguments,1,i),t=I.converters.RequestInfo(t,i,`input`),r=I.converters.RequestInit(r,i,`init`);let u=null,p=null,h=v.settingsObject.baseUrl,x=null;if(typeof t==`string`){this[P]=r.dispatcher;let e;try{e=new URL(t,h)}catch(e){throw TypeError(`Failed to parse URL from `+t,{cause:e})}if(e.username||e.password)throw TypeError(`Request cannot be constructed from a URL that includes credentials: `+t);u=Y({urlList:[e]}),p=`cors`}else this[P]=r.dispatcher||t[P],z(t instanceof e),u=t[N],x=t[M];let S=v.settingsObject.origin,C=`client`;if(u.window?.constructor?.name===`EnvironmentSettingsObject`&&_(u.window,S)&&(C=u.window),r.window!=null)throw TypeError(`'window' option '${C}' must be null`);`window`in r&&(C=`no-window`),u=Y({method:u.method,headersList:u.headersList,unsafeRequest:u.unsafeRequest,client:v.settingsObject,window:C,priority:u.priority,origin:u.origin,referrer:u.referrer,referrerPolicy:u.referrerPolicy,mode:u.mode,credentials:u.credentials,cache:u.cache,redirect:u.redirect,integrity:u.integrity,keepalive:u.keepalive,reloadNavigation:u.reloadNavigation,historyNavigation:u.historyNavigation,urlList:[...u.urlList]});let w=Object.keys(r).length!==0;if(w&&(u.mode===`navigate`&&(u.mode=`same-origin`),u.reloadNavigation=!1,u.historyNavigation=!1,u.origin=`client`,u.referrer=`client`,u.referrerPolicy=``,u.url=u.urlList[u.urlList.length-1],u.urlList=[u.url]),r.referrer!==void 0){let e=r.referrer;if(e===``)u.referrer=`no-referrer`;else{let t;try{t=new URL(e,h)}catch(t){throw TypeError(`Referrer "${e}" is not a valid URL.`,{cause:t})}t.protocol===`about:`&&t.hostname===`client`||S&&!_(t,v.settingsObject.baseUrl)?u.referrer=`client`:u.referrer=t}}r.referrerPolicy!==void 0&&(u.referrerPolicy=r.referrerPolicy);let T;if(T=r.mode===void 0?p:r.mode,T===`navigate`)throw I.errors.exception({header:`Request constructor`,message:`invalid request mode navigate.`});if(T!=null&&(u.mode=T),r.credentials!==void 0&&(u.credentials=r.credentials),r.cache!==void 0&&(u.cache=r.cache),u.cache===`only-if-cached`&&u.mode!==`same-origin`)throw TypeError(`'only-if-cached' can be set only with 'same-origin' mode`);if(r.redirect!==void 0&&(u.redirect=r.redirect),r.integrity!=null&&(u.integrity=String(r.integrity)),r.keepalive!==void 0&&(u.keepalive=!!r.keepalive),r.method!==void 0){let e=r.method,t=k[e];if(t!==void 0)u.method=t;else{if(!g(e))throw TypeError(`'${e}' is not a valid HTTP method.`);let t=e.toUpperCase();if(y.has(t))throw TypeError(`'${e}' HTTP method is unsupported.`);e=O[t]??e,u.method=e}!q&&u.method===`patch`&&(process.emitWarning("Using `patch` is highly likely to result in a `405 Method Not Allowed`. `PATCH` is much more likely to succeed.",{code:`UNDICI-FETCH-patch`}),q=!0)}r.signal!==void 0&&(x=r.signal),this[N]=u;let E=new AbortController;if(this[M]=E.signal,x!=null){if(!x||typeof x.aborted!=`boolean`||typeof x.addEventListener!=`function`)throw TypeError(`Failed to construct 'Request': member signal is not of type AbortSignal.`);if(x.aborted)E.abort(x.reason);else{this[ne]=E;let e=K(new WeakRef(E));try{(typeof B==`function`&&B(x)===te||ee(x,`abort`).length>=te)&&V(1500,x)}catch{}m.addAbortListener(x,e),re.register(E,{signal:x,abort:e},e)}}if(this[A]=new o(R),d(this[A],u.headersList),l(this[A],`request`),T===`no-cors`){if(!b.has(u.method))throw TypeError(`'${u.method} is unsupported in no-cors mode.`);l(this[A],`request-no-cors`)}if(w){let e=f(this[A]),t=r.headers===void 0?new c(e):r.headers;if(e.clear(),t instanceof c){for(let{name:n,value:r}of t.rawValues())e.append(n,r,!1);e.cookies=t.cookies}else s(this[A],t)}let D=t instanceof e?t[N].body:null;if((r.body!=null||D!=null)&&(u.method===`GET`||u.method===`HEAD`))throw TypeError(`Request with GET/HEAD method cannot have body.`);let j=null;if(r.body!=null){let[e,t]=n(r.body,u.keepalive);j=e,t&&!f(this[A]).contains(`content-type`,!0)&&this[A].append(`content-type`,t)}let F=j??D;if(F!=null&&F.source==null){if(j!=null&&r.duplex==null)throw TypeError(`RequestInit: duplex option is required when sending a body.`);if(u.mode!==`same-origin`&&u.mode!==`cors`)throw TypeError(`If request is made from ReadableStream, mode should be "same-origin" or "cors"`);u.useCORSPreflightFlag=!0}let L=F;if(j==null&&D!=null){if(a(t))throw TypeError(`Cannot construct a Request with a Request object that has already been used.`);let e=new TransformStream;D.stream.pipeThrough(e),L={source:D.source,length:D.length,stream:e.readable}}this[N].body=L}get method(){return I.brandCheck(this,e),this[N].method}get url(){return I.brandCheck(this,e),L(this[N].url)}get headers(){return I.brandCheck(this,e),this[A]}get destination(){return I.brandCheck(this,e),this[N].destination}get referrer(){return I.brandCheck(this,e),this[N].referrer===`no-referrer`?``:this[N].referrer===`client`?`about:client`:this[N].referrer.toString()}get referrerPolicy(){return I.brandCheck(this,e),this[N].referrerPolicy}get mode(){return I.brandCheck(this,e),this[N].mode}get credentials(){return this[N].credentials}get cache(){return I.brandCheck(this,e),this[N].cache}get redirect(){return I.brandCheck(this,e),this[N].redirect}get integrity(){return I.brandCheck(this,e),this[N].integrity}get keepalive(){return I.brandCheck(this,e),this[N].keepalive}get isReloadNavigation(){return I.brandCheck(this,e),this[N].reloadNavigation}get isHistoryNavigation(){return I.brandCheck(this,e),this[N].historyNavigation}get signal(){return I.brandCheck(this,e),this[M]}get body(){return I.brandCheck(this,e),this[N].body?this[N].body.stream:null}get bodyUsed(){return I.brandCheck(this,e),!!this[N].body&&m.isDisturbed(this[N].body.stream)}get duplex(){return I.brandCheck(this,e),`half`}clone(){if(I.brandCheck(this,e),a(this))throw TypeError(`unusable`);let t=se(this[N]),n=new AbortController;if(this.signal.aborted)n.abort(this.signal.reason);else{let e=ae.get(this.signal);e===void 0&&(e=new Set,ae.set(this.signal,e));let t=new WeakRef(n);e.add(t),m.addAbortListener(n.signal,K(t))}return ce(t,n.signal,u(this[A]))}[h.inspect.custom](e,t){t.depth===null&&(t.depth=2),t.colors??=!0;let n={method:this.method,url:this.url,headers:this.headers,destination:this.destination,referrer:this.referrer,referrerPolicy:this.referrerPolicy,mode:this.mode,credentials:this.credentials,cache:this.cache,redirect:this.redirect,integrity:this.integrity,keepalive:this.keepalive,isReloadNavigation:this.isReloadNavigation,isHistoryNavigation:this.isHistoryNavigation,signal:this.signal};return`Request ${h.formatWithOptions(t,n)}`}};r(J);function Y(e){return{method:e.method??`GET`,localURLsOnly:e.localURLsOnly??!1,unsafeRequest:e.unsafeRequest??!1,body:e.body??null,client:e.client??null,reservedClient:e.reservedClient??null,replacesClientId:e.replacesClientId??``,window:e.window??`client`,keepalive:e.keepalive??!1,serviceWorkers:e.serviceWorkers??`all`,initiator:e.initiator??``,destination:e.destination??``,priority:e.priority??null,origin:e.origin??`client`,policyContainer:e.policyContainer??`client`,referrer:e.referrer??`client`,referrerPolicy:e.referrerPolicy??``,mode:e.mode??`no-cors`,useCORSPreflightFlag:e.useCORSPreflightFlag??!1,credentials:e.credentials??`same-origin`,useCredentials:e.useCredentials??!1,cache:e.cache??`default`,redirect:e.redirect??`follow`,integrity:e.integrity??``,cryptoGraphicsNonceMetadata:e.cryptoGraphicsNonceMetadata??``,parserMetadata:e.parserMetadata??``,reloadNavigation:e.reloadNavigation??!1,historyNavigation:e.historyNavigation??!1,userActivation:e.userActivation??!1,taintedOrigin:e.taintedOrigin??!1,redirectCount:e.redirectCount??0,responseTainting:e.responseTainting??`basic`,preventNoCacheCacheControlHeaderModification:e.preventNoCacheCacheControlHeaderModification??!1,done:e.done??!1,timingAllowFailed:e.timingAllowFailed??!1,urlList:e.urlList,url:e.urlList[0],headersList:e.headersList?new c(e.headersList):new c}}function se(e){let t=Y({...e,body:null});return e.body!=null&&(t.body=i(t,e.body)),t}function ce(e,t,n){let r=new J(R);return r[N]=e,r[M]=t,r[A]=new o(R),d(r[A],e.headersList),l(r[A],n),r}Object.defineProperties(J.prototype,{method:D,url:D,headers:D,redirect:D,clone:D,signal:D,duplex:D,destination:D,body:D,bodyUsed:D,isHistoryNavigation:D,isReloadNavigation:D,keepalive:D,integrity:D,cache:D,credentials:D,attribute:D,referrerPolicy:D,referrer:D,mode:D,[Symbol.toStringTag]:{value:`Request`,configurable:!0}}),I.converters.Request=I.interfaceConverter(J),I.converters.RequestInfo=function(e,t,n){return typeof e==`string`?I.converters.USVString(e,t,n):e instanceof J?I.converters.Request(e,t,n):I.converters.USVString(e,t,n)},I.converters.AbortSignal=I.interfaceConverter(AbortSignal),I.converters.RequestInit=I.dictionaryConverter([{key:`method`,converter:I.converters.ByteString},{key:`headers`,converter:I.converters.HeadersInit},{key:`body`,converter:I.nullableConverter(I.converters.BodyInit)},{key:`referrer`,converter:I.converters.USVString},{key:`referrerPolicy`,converter:I.converters.DOMString,allowedValues:x},{key:`mode`,converter:I.converters.DOMString,allowedValues:C},{key:`credentials`,converter:I.converters.DOMString,allowedValues:w},{key:`cache`,converter:I.converters.DOMString,allowedValues:T},{key:`redirect`,converter:I.converters.DOMString,allowedValues:S},{key:`integrity`,converter:I.converters.DOMString},{key:`keepalive`,converter:I.converters.boolean},{key:`signal`,converter:I.nullableConverter(e=>I.converters.AbortSignal(e,`RequestInit`,`signal`,{strict:!1}))},{key:`window`,converter:I.converters.any},{key:`duplex`,converter:I.converters.DOMString,allowedValues:E},{key:`dispatcher`,converter:I.converters.any}]),t.exports={Request:J,makeRequest:Y,fromInnerRequest:ce,cloneRequest:se}})),Ge=o(((e,t)=>{var{makeNetworkError:n,makeAppropriateNetworkError:r,filterResponse:i,makeResponse:a,fromInnerResponse:o}=He(),{HeadersList:s}=Ve(),{Request:c,cloneRequest:l}=We(),u=require(`node:zlib`),{bytesMatch:d,makePolicyContainer:f,clonePolicyContainer:p,requestBadPort:m,TAOCheck:h,appendRequestOriginHeader:g,responseLocationURL:_,requestCurrentURL:v,setRequestReferrerPolicyOnRedirect:y,tryUpgradeRequestToAPotentiallyTrustworthyURL:b,createOpaqueTimingInfo:x,appendFetchMetadata:S,corsCheck:C,crossOriginResourcePolicyCheck:w,determineRequestsReferrer:T,coarsenedSharedCurrentTime:E,createDeferredPromise:D,isBlobLike:O,sameOrigin:k,isCancelled:A,isAborted:j,isErrorLike:M,fullyReadBody:N,readableStreamClose:P,isomorphicEncode:I,urlIsLocal:L,urlIsHttpHttpsScheme:R,urlHasHttpsScheme:z,clampAndCoarsenConnectionTimingInfo:B,simpleRangeHeaderValue:V,buildContentRange:ee,createInflate:te,extractMimeType:ne}=W(),{kState:re,kDispatcher:ae}=G(),K=require(`node:assert`),{safelyExtractBody:q,extractBody:J}=oe(),{redirectStatusSet:Y,nullBodyStatus:se,safeMethodsSet:ce,requestBodyHeader:le,subresourceSet:X}=ie(),ue=require(`node:events`),{Readable:de,pipeline:fe,finished:pe}=require(`node:stream`),{addAbortListener:Z,isErrored:Q,isReadable:me,bufferToLowerCasedHeaderName:$}=F(),{dataURLProcessor:he,serializeAMimeType:ge,minimizeSupportedMimeType:_e}=H(),{getGlobalDispatcher:ve}=Fe(),{webidl:ye}=U(),{STATUS_CODES:be}=require(`node:http`),xe=[`GET`,`HEAD`],Se=typeof __UNDICI_IS_NODE__<`u`||typeof esbuildDetection<`u`?`node`:`undici`,Ce,we=class extends ue{constructor(e){super(),this.dispatcher=e,this.connection=null,this.dump=!1,this.state=`ongoing`}terminate(e){this.state===`ongoing`&&(this.state=`terminated`,this.connection?.destroy(e),this.emit(`terminated`,e))}abort(e){this.state===`ongoing`&&(this.state=`aborted`,e||=new DOMException(`The operation was aborted.`,`AbortError`),this.serializedAbortReason=e,this.connection?.destroy(e),this.emit(`terminated`,e))}};function Te(e){De(e,`fetch`)}function Ee(e,t=void 0){ye.argumentLengthCheck(arguments,1,`globalThis.fetch`);let n=D(),r;try{r=new c(e,t)}catch(e){return n.reject(e),n.promise}let i=r[re];if(r.signal.aborted)return ke(n,i,null,r.signal.reason),n.promise;i.client.globalObject?.constructor?.name===`ServiceWorkerGlobalScope`&&(i.serviceWorkers=`none`);let a=null,s=!1,l=null;return Z(r.signal,()=>{s=!0,K(l!=null),l.abort(r.signal.reason);let e=a?.deref();ke(n,i,e,r.signal.reason)}),l=Ae({request:i,processResponseEndOfBody:Te,processResponse:e=>{if(!s){if(e.aborted){ke(n,i,a,l.serializedAbortReason);return}if(e.type===`error`){n.reject(TypeError(`fetch failed`,{cause:e.error}));return}a=new WeakRef(o(e,`immutable`)),n.resolve(a.deref()),n=null}},dispatcher:r[ae]}),n.promise}function De(e,t=`other`){if(e.type===`error`&&e.aborted||!e.urlList?.length)return;let n=e.urlList[0],r=e.timingInfo,i=e.cacheState;R(n)&&r!==null&&(e.timingAllowPassed||(r=x({startTime:r.startTime}),i=``),r.endTime=E(),e.timingInfo=r,Oe(r,n.href,t,globalThis,i))}var Oe=performance.markResourceTiming;function ke(e,t,n,r){if(e&&e.reject(r),t.body!=null&&me(t.body?.stream)&&t.body.stream.cancel(r).catch(e=>{if(e.code!==`ERR_INVALID_STATE`)throw e}),n==null)return;let i=n[re];i.body!=null&&me(i.body?.stream)&&i.body.stream.cancel(r).catch(e=>{if(e.code!==`ERR_INVALID_STATE`)throw e})}function Ae({request:e,processRequestBodyChunkLength:t,processRequestEndOfBody:n,processResponse:r,processResponseEndOfBody:i,processResponseConsumeBody:a,useParallelQueue:o=!1,dispatcher:s=ve()}){K(s);let c=null,l=!1;e.client!=null&&(c=e.client.globalObject,l=e.client.crossOriginIsolatedCapability);let u=x({startTime:E(l)}),d={controller:new we(s),request:e,timingInfo:u,processRequestBodyChunkLength:t,processRequestEndOfBody:n,processResponse:r,processResponseConsumeBody:a,processResponseEndOfBody:i,taskDestination:c,crossOriginIsolatedCapability:l};return K(!e.body||e.body.stream),e.window===`client`&&(e.window=e.client?.globalObject?.constructor?.name===`Window`?e.client:`no-window`),e.origin===`client`&&(e.origin=e.client.origin),e.policyContainer===`client`&&(e.client==null?e.policyContainer=f():e.policyContainer=p(e.client.policyContainer)),e.headersList.contains(`accept`,!0)||e.headersList.append(`accept`,`*/*`,!0),e.headersList.contains(`accept-language`,!0)||e.headersList.append(`accept-language`,`*`,!0),e.priority,X.has(e.destination),je(d).catch(e=>{d.controller.terminate(e)}),d.controller}async function je(e,t=!1){let r=e.request,a=null;if(r.localURLsOnly&&!L(v(r))&&(a=n(`local URLs only`)),b(r),m(r)===`blocked`&&(a=n(`bad port`)),r.referrerPolicy===``&&(r.referrerPolicy=r.policyContainer.referrerPolicy),r.referrer!==`no-referrer`&&(r.referrer=T(r)),a===null&&(a=await(async()=>{let t=v(r);return k(t,r.url)&&r.responseTainting===`basic`||t.protocol===`data:`||r.mode===`navigate`||r.mode===`websocket`?(r.responseTainting=`basic`,await Me(e)):r.mode===`same-origin`?n(`request mode cannot be "same-origin"`):r.mode===`no-cors`?r.redirect===`follow`?(r.responseTainting=`opaque`,await Me(e)):n(`redirect mode cannot be "follow" for "no-cors" request`):R(v(r))?(r.responseTainting=`cors`,await Ie(e)):n(`URL scheme must be a HTTP(S) scheme`)})()),t)return a;a.status!==0&&!a.internalResponse&&(r.responseTainting,r.responseTainting===`basic`?a=i(a,`basic`):r.responseTainting===`cors`?a=i(a,`cors`):r.responseTainting===`opaque`?a=i(a,`opaque`):K(!1));let o=a.status===0?a:a.internalResponse;if(o.urlList.length===0&&o.urlList.push(...r.urlList),r.timingAllowFailed||(a.timingAllowPassed=!0),a.type===`opaque`&&o.status===206&&o.rangeRequested&&!r.headers.contains(`range`,!0)&&(a=o=n()),a.status!==0&&(r.method===`HEAD`||r.method===`CONNECT`||se.includes(o.status))&&(o.body=null,e.controller.dump=!0),r.integrity){let t=t=>Pe(e,n(t));if(r.responseTainting===`opaque`||a.body==null){t(a.error);return}await N(a.body,n=>{if(!d(n,r.integrity)){t(`integrity mismatch`);return}a.body=q(n)[0],Pe(e,a)},t)}else Pe(e,a)}function Me(e){if(A(e)&&e.request.redirectCount===0)return Promise.resolve(r(e));let{request:t}=e,{protocol:i}=v(t);switch(i){case`about:`:return Promise.resolve(n(`about scheme is not supported`));case`blob:`:{Ce||=require(`node:buffer`).resolveObjectURL;let e=v(t);if(e.search.length!==0)return Promise.resolve(n(`NetworkError when attempting to fetch resource.`));let r=Ce(e.toString());if(t.method!==`GET`||!O(r))return Promise.resolve(n(`invalid method`));let i=a(),o=r.size,s=I(`${o}`),c=r.type;if(t.headersList.contains(`range`,!0)){i.rangeRequested=!0;let e=V(t.headersList.get(`range`,!0),!0);if(e===`failure`)return Promise.resolve(n(`failed to fetch the data URL`));let{rangeStartValue:a,rangeEndValue:s}=e;if(a===null)a=o-s,s=a+s-1;else{if(a>=o)return Promise.resolve(n(`Range start is greater than the blob's size.`));(s===null||s>=o)&&(s=o-1)}let l=r.slice(a,s,c);i.body=J(l)[0];let u=I(`${l.size}`),d=ee(a,s,o);i.status=206,i.statusText=`Partial Content`,i.headersList.set(`content-length`,u,!0),i.headersList.set(`content-type`,c,!0),i.headersList.set(`content-range`,d,!0)}else{let e=J(r);i.statusText=`OK`,i.body=e[0],i.headersList.set(`content-length`,s,!0),i.headersList.set(`content-type`,c,!0)}return Promise.resolve(i)}case`data:`:{let e=he(v(t));if(e===`failure`)return Promise.resolve(n(`failed to fetch the data URL`));let r=ge(e.mimeType);return Promise.resolve(a({statusText:`OK`,headersList:[[`content-type`,{name:`Content-Type`,value:r}]],body:q(e.body)[0]}))}case`file:`:return Promise.resolve(n(`not implemented... yet...`));case`http:`:case`https:`:return Ie(e).catch(e=>n(e));default:return Promise.resolve(n(`unknown scheme`))}}function Ne(e,t){e.request.done=!0,e.processResponseDone!=null&&queueMicrotask(()=>e.processResponseDone(t))}function Pe(e,t){let n=e.timingInfo,r=()=>{let r=Date.now();e.request.destination===`document`&&(e.controller.fullTimingInfo=n),e.controller.reportTimingSteps=()=>{if(e.request.url.protocol!==`https:`)return;n.endTime=r;let i=t.cacheState,a=t.bodyInfo;t.timingAllowPassed||(n=x(n),i=``);let o=0;if(e.request.mode!==`navigator`||!t.hasCrossOriginRedirects){o=t.status;let e=ne(t.headersList);e!==`failure`&&(a.contentType=_e(e))}e.request.initiatorType!=null&&Oe(n,e.request.url.href,e.request.initiatorType,globalThis,i,a,o)};let i=()=>{e.request.done=!0,e.processResponseEndOfBody!=null&&queueMicrotask(()=>e.processResponseEndOfBody(t)),e.request.initiatorType!=null&&e.controller.reportTimingSteps()};queueMicrotask(()=>i())};e.processResponse!=null&&queueMicrotask(()=>{e.processResponse(t),e.processResponse=null});let i=t.type===`error`?t:t.internalResponse??t;i.body==null?r():pe(i.body.stream,()=>{r()})}async function Ie(e){let t=e.request,r=null,i=null,a=e.timingInfo;if(t.serviceWorkers,r===null){if(t.redirect===`follow`&&(t.serviceWorkers=`none`),i=r=await Re(e),t.responseTainting===`cors`&&C(t,r)===`failure`)return n(`cors failure`);h(t,r)===`failure`&&(t.timingAllowFailed=!0)}return(t.responseTainting===`opaque`||r.type===`opaque`)&&w(t.origin,t.client,t.destination,i)===`blocked`?n(`blocked`):(Y.has(i.status)&&(t.redirect!==`manual`&&e.controller.connection.destroy(void 0,!1),t.redirect===`error`?r=n(`unexpected redirect`):t.redirect===`manual`?r=i:t.redirect===`follow`?r=await Le(e,r):K(!1)),r.timingInfo=a,r)}function Le(e,t){let r=e.request,i=t.internalResponse?t.internalResponse:t,a;try{if(a=_(i,v(r).hash),a==null)return t}catch(e){return Promise.resolve(n(e))}if(!R(a))return Promise.resolve(n(`URL scheme must be a HTTP(S) scheme`));if(r.redirectCount===20)return Promise.resolve(n(`redirect count exceeded`));if(r.redirectCount+=1,r.mode===`cors`&&(a.username||a.password)&&!k(r,a))return Promise.resolve(n(`cross origin not allowed for request mode "cors"`));if(r.responseTainting===`cors`&&(a.username||a.password))return Promise.resolve(n(`URL cannot contain credentials for request mode "cors"`));if(i.status!==303&&r.body!=null&&r.body.source==null)return Promise.resolve(n());if([301,302].includes(i.status)&&r.method===`POST`||i.status===303&&!xe.includes(r.method)){r.method=`GET`,r.body=null;for(let e of le)r.headersList.delete(e)}k(v(r),a)||(r.headersList.delete(`authorization`,!0),r.headersList.delete(`proxy-authorization`,!0),r.headersList.delete(`cookie`,!0),r.headersList.delete(`host`,!0)),r.body!=null&&(K(r.body.source!=null),r.body=q(r.body.source)[0]);let o=e.timingInfo;return o.redirectEndTime=o.postRedirectStartTime=E(e.crossOriginIsolatedCapability),o.redirectStartTime===0&&(o.redirectStartTime=o.startTime),r.urlList.push(a),y(r,i),je(e,!0)}async function Re(e,t=!1,i=!1){let a=e.request,o=null,s=null,c=null;a.window===`no-window`&&a.redirect===`error`?(o=e,s=a):(s=l(a),o={...e},o.request=s);let u=a.credentials===`include`||a.credentials===`same-origin`&&a.responseTainting===`basic`,d=s.body?s.body.length:null,f=null;if(s.body==null&&[`POST`,`PUT`].includes(s.method)&&(f=`0`),d!=null&&(f=I(`${d}`)),f!=null&&s.headersList.append(`content-length`,f,!0),d!=null&&s.keepalive,s.referrer instanceof URL&&s.headersList.append(`referer`,I(s.referrer.href),!0),g(s),S(s),s.headersList.contains(`user-agent`,!0)||s.headersList.append(`user-agent`,Se),s.cache===`default`&&(s.headersList.contains(`if-modified-since`,!0)||s.headersList.contains(`if-none-match`,!0)||s.headersList.contains(`if-unmodified-since`,!0)||s.headersList.contains(`if-match`,!0)||s.headersList.contains(`if-range`,!0))&&(s.cache=`no-store`),s.cache===`no-cache`&&!s.preventNoCacheCacheControlHeaderModification&&!s.headersList.contains(`cache-control`,!0)&&s.headersList.append(`cache-control`,`max-age=0`,!0),(s.cache===`no-store`||s.cache===`reload`)&&(s.headersList.contains(`pragma`,!0)||s.headersList.append(`pragma`,`no-cache`,!0),s.headersList.contains(`cache-control`,!0)||s.headersList.append(`cache-control`,`no-cache`,!0)),s.headersList.contains(`range`,!0)&&s.headersList.append(`accept-encoding`,`identity`,!0),s.headersList.contains(`accept-encoding`,!0)||(z(v(s))?s.headersList.append(`accept-encoding`,`br, gzip, deflate`,!0):s.headersList.append(`accept-encoding`,`gzip, deflate`,!0)),s.headersList.delete(`host`,!0),s.cache=`no-store`,s.cache!==`no-store`&&s.cache,c==null){if(s.cache===`only-if-cached`)return n(`only if cached`);let e=await ze(o,u,i);!ce.has(s.method)&&e.status>=200&&e.status,c??=e}if(c.urlList=[...s.urlList],s.headersList.contains(`range`,!0)&&(c.rangeRequested=!0),c.requestIncludesCredentials=u,c.status===407)return a.window===`no-window`?n():A(e)?r(e):n(`proxy authentication required`);if(c.status===421&&!i&&(a.body==null||a.body.source!=null)){if(A(e))return r(e);e.controller.connection.destroy(),c=await Re(e,t,!0)}return c}async function ze(e,t=!1,i=!1){K(!e.controller.connection||e.controller.connection.destroyed),e.controller.connection={abort:null,destroyed:!1,destroy(e,t=!0){this.destroyed||(this.destroyed=!0,t&&this.abort?.(e??new DOMException(`The operation was aborted.`,`AbortError`)))}};let o=e.request,c=null,l=e.timingInfo;o.cache=`no-store`,o.mode;let d=null;if(o.body==null&&e.processRequestEndOfBody)queueMicrotask(()=>e.processRequestEndOfBody());else if(o.body!=null){let t=async function*(t){A(e)||(yield t,e.processRequestBodyChunkLength?.(t.byteLength))},n=()=>{A(e)||e.processRequestEndOfBody&&e.processRequestEndOfBody()},r=t=>{A(e)||(t.name===`AbortError`?e.controller.abort():e.controller.terminate(t))};d=(async function*(){try{for await(let e of o.body.stream)yield*t(e);n()}catch(e){r(e)}})()}try{let{body:t,status:n,statusText:r,headersList:i,socket:o}=await g({body:d});if(o)c=a({status:n,statusText:r,headersList:i,socket:o});else{let o=t[Symbol.asyncIterator]();e.controller.next=()=>o.next(),c=a({status:n,statusText:r,headersList:i})}}catch(t){return t.name===`AbortError`?(e.controller.connection.destroy(),r(e,t)):n(t)}let f=async()=>{await e.controller.resume()},p=t=>{A(e)||e.controller.abort(t)},m=new ReadableStream({async start(t){e.controller.controller=t},async pull(e){await f(e)},async cancel(e){await p(e)},type:`bytes`});c.body={stream:m,source:null,length:null},e.controller.onAborted=h,e.controller.on(`terminated`,h),e.controller.resume=async()=>{for(;;){let t,n;try{let{done:n,value:r}=await e.controller.next();if(j(e))break;t=n?void 0:r}catch(r){e.controller.ended&&!l.encodedBodySize?t=void 0:(t=r,n=!0)}if(t===void 0){P(e.controller.controller),Ne(e,c);return}if(l.decodedBodySize+=t?.byteLength??0,n){e.controller.terminate(t);return}let r=new Uint8Array(t);if(r.byteLength&&e.controller.controller.enqueue(r),Q(m)){e.controller.terminate();return}if(e.controller.controller.desiredSize<=0)return}};function h(t){j(e)?(c.aborted=!0,me(m)&&e.controller.controller.error(e.controller.serializedAbortReason)):me(m)&&e.controller.controller.error(TypeError(`terminated`,{cause:M(t)?t:void 0})),e.controller.connection.destroy()}return c;function g({body:t}){let n=v(o),r=e.controller.dispatcher;return new Promise((i,a)=>r.dispatch({path:n.pathname+n.search,origin:n.origin,method:o.method,body:r.isMockActive?o.body&&(o.body.source||o.body.stream):t,headers:o.headersList.entries,maxRedirections:0,upgrade:o.mode===`websocket`?`websocket`:void 0},{body:null,abort:null,onConnect(t){let{connection:n}=e.controller;l.finalConnectionTimingInfo=B(void 0,l.postRedirectStartTime,e.crossOriginIsolatedCapability),n.destroyed?t(new DOMException(`The operation was aborted.`,`AbortError`)):(e.controller.on(`terminated`,t),this.abort=n.abort=t),l.finalNetworkRequestStartTime=E(e.crossOriginIsolatedCapability)},onResponseStarted(){l.finalNetworkResponseStartTime=E(e.crossOriginIsolatedCapability)},onHeaders(e,t,n,r){if(e<200)return;let c=``,l=new s;for(let e=0;e5)return a(Error(`too many content-encodings in response: ${t.length}, maximum allowed is 5`)),!0;for(let e=t.length-1;e>=0;--e){let n=t[e].trim();if(n===`x-gzip`||n===`gzip`)d.push(u.createGunzip({flush:u.constants.Z_SYNC_FLUSH,finishFlush:u.constants.Z_SYNC_FLUSH}));else if(n===`deflate`)d.push(te({flush:u.constants.Z_SYNC_FLUSH,finishFlush:u.constants.Z_SYNC_FLUSH}));else if(n===`br`)d.push(u.createBrotliDecompress({flush:u.constants.BROTLI_OPERATION_FLUSH,finishFlush:u.constants.BROTLI_OPERATION_FLUSH}));else{d.length=0;break}}}let p=this.onError.bind(this);return i({status:e,statusText:r,headersList:l,body:d.length?fe(this.body,...d,e=>{e&&this.onError(e)}).on(`error`,p):this.body.on(`error`,p)}),!0},onData(t){if(e.controller.dump)return;let n=t;return l.encodedBodySize+=n.byteLength,this.body.push(n)},onComplete(){this.abort&&e.controller.off(`terminated`,this.abort),e.controller.onAborted&&e.controller.off(`terminated`,e.controller.onAborted),e.controller.ended=!0,this.body.push(null)},onError(t){this.abort&&e.controller.off(`terminated`,this.abort),this.body?.destroy(t),e.controller.terminate(t),a(t)},onUpgrade(e,t,n){if(e!==101)return;let r=new s;for(let e=0;e{t.exports={kState:Symbol(`FileReader state`),kResult:Symbol(`FileReader result`),kError:Symbol(`FileReader error`),kLastProgressEventFired:Symbol(`FileReader last progress event fired timestamp`),kEvents:Symbol(`FileReader events`),kAborted:Symbol(`FileReader aborted`)}})),qe=o(((e,t)=>{var{webidl:n}=U(),r=Symbol(`ProgressEvent state`),i=class e extends Event{constructor(e,t={}){e=n.converters.DOMString(e,`ProgressEvent constructor`,`type`),t=n.converters.ProgressEventInit(t??{}),super(e,t),this[r]={lengthComputable:t.lengthComputable,loaded:t.loaded,total:t.total}}get lengthComputable(){return n.brandCheck(this,e),this[r].lengthComputable}get loaded(){return n.brandCheck(this,e),this[r].loaded}get total(){return n.brandCheck(this,e),this[r].total}};n.converters.ProgressEventInit=n.dictionaryConverter([{key:`lengthComputable`,converter:n.converters.boolean,defaultValue:()=>!1},{key:`loaded`,converter:n.converters[`unsigned long long`],defaultValue:()=>0},{key:`total`,converter:n.converters[`unsigned long long`],defaultValue:()=>0},{key:`bubbles`,converter:n.converters.boolean,defaultValue:()=>!1},{key:`cancelable`,converter:n.converters.boolean,defaultValue:()=>!1},{key:`composed`,converter:n.converters.boolean,defaultValue:()=>!1}]),t.exports={ProgressEvent:i}})),Je=o(((e,t)=>{function n(e){if(!e)return`failure`;switch(e.trim().toLowerCase()){case`unicode-1-1-utf-8`:case`unicode11utf8`:case`unicode20utf8`:case`utf-8`:case`utf8`:case`x-unicode20utf8`:return`UTF-8`;case`866`:case`cp866`:case`csibm866`:case`ibm866`:return`IBM866`;case`csisolatin2`:case`iso-8859-2`:case`iso-ir-101`:case`iso8859-2`:case`iso88592`:case`iso_8859-2`:case`iso_8859-2:1987`:case`l2`:case`latin2`:return`ISO-8859-2`;case`csisolatin3`:case`iso-8859-3`:case`iso-ir-109`:case`iso8859-3`:case`iso88593`:case`iso_8859-3`:case`iso_8859-3:1988`:case`l3`:case`latin3`:return`ISO-8859-3`;case`csisolatin4`:case`iso-8859-4`:case`iso-ir-110`:case`iso8859-4`:case`iso88594`:case`iso_8859-4`:case`iso_8859-4:1988`:case`l4`:case`latin4`:return`ISO-8859-4`;case`csisolatincyrillic`:case`cyrillic`:case`iso-8859-5`:case`iso-ir-144`:case`iso8859-5`:case`iso88595`:case`iso_8859-5`:case`iso_8859-5:1988`:return`ISO-8859-5`;case`arabic`:case`asmo-708`:case`csiso88596e`:case`csiso88596i`:case`csisolatinarabic`:case`ecma-114`:case`iso-8859-6`:case`iso-8859-6-e`:case`iso-8859-6-i`:case`iso-ir-127`:case`iso8859-6`:case`iso88596`:case`iso_8859-6`:case`iso_8859-6:1987`:return`ISO-8859-6`;case`csisolatingreek`:case`ecma-118`:case`elot_928`:case`greek`:case`greek8`:case`iso-8859-7`:case`iso-ir-126`:case`iso8859-7`:case`iso88597`:case`iso_8859-7`:case`iso_8859-7:1987`:case`sun_eu_greek`:return`ISO-8859-7`;case`csiso88598e`:case`csisolatinhebrew`:case`hebrew`:case`iso-8859-8`:case`iso-8859-8-e`:case`iso-ir-138`:case`iso8859-8`:case`iso88598`:case`iso_8859-8`:case`iso_8859-8:1988`:case`visual`:return`ISO-8859-8`;case`csiso88598i`:case`iso-8859-8-i`:case`logical`:return`ISO-8859-8-I`;case`csisolatin6`:case`iso-8859-10`:case`iso-ir-157`:case`iso8859-10`:case`iso885910`:case`l6`:case`latin6`:return`ISO-8859-10`;case`iso-8859-13`:case`iso8859-13`:case`iso885913`:return`ISO-8859-13`;case`iso-8859-14`:case`iso8859-14`:case`iso885914`:return`ISO-8859-14`;case`csisolatin9`:case`iso-8859-15`:case`iso8859-15`:case`iso885915`:case`iso_8859-15`:case`l9`:return`ISO-8859-15`;case`iso-8859-16`:return`ISO-8859-16`;case`cskoi8r`:case`koi`:case`koi8`:case`koi8-r`:case`koi8_r`:return`KOI8-R`;case`koi8-ru`:case`koi8-u`:return`KOI8-U`;case`csmacintosh`:case`mac`:case`macintosh`:case`x-mac-roman`:return`macintosh`;case`iso-8859-11`:case`iso8859-11`:case`iso885911`:case`tis-620`:case`windows-874`:return`windows-874`;case`cp1250`:case`windows-1250`:case`x-cp1250`:return`windows-1250`;case`cp1251`:case`windows-1251`:case`x-cp1251`:return`windows-1251`;case`ansi_x3.4-1968`:case`ascii`:case`cp1252`:case`cp819`:case`csisolatin1`:case`ibm819`:case`iso-8859-1`:case`iso-ir-100`:case`iso8859-1`:case`iso88591`:case`iso_8859-1`:case`iso_8859-1:1987`:case`l1`:case`latin1`:case`us-ascii`:case`windows-1252`:case`x-cp1252`:return`windows-1252`;case`cp1253`:case`windows-1253`:case`x-cp1253`:return`windows-1253`;case`cp1254`:case`csisolatin5`:case`iso-8859-9`:case`iso-ir-148`:case`iso8859-9`:case`iso88599`:case`iso_8859-9`:case`iso_8859-9:1989`:case`l5`:case`latin5`:case`windows-1254`:case`x-cp1254`:return`windows-1254`;case`cp1255`:case`windows-1255`:case`x-cp1255`:return`windows-1255`;case`cp1256`:case`windows-1256`:case`x-cp1256`:return`windows-1256`;case`cp1257`:case`windows-1257`:case`x-cp1257`:return`windows-1257`;case`cp1258`:case`windows-1258`:case`x-cp1258`:return`windows-1258`;case`x-mac-cyrillic`:case`x-mac-ukrainian`:return`x-mac-cyrillic`;case`chinese`:case`csgb2312`:case`csiso58gb231280`:case`gb2312`:case`gb_2312`:case`gb_2312-80`:case`gbk`:case`iso-ir-58`:case`x-gbk`:return`GBK`;case`gb18030`:return`gb18030`;case`big5`:case`big5-hkscs`:case`cn-big5`:case`csbig5`:case`x-x-big5`:return`Big5`;case`cseucpkdfmtjapanese`:case`euc-jp`:case`x-euc-jp`:return`EUC-JP`;case`csiso2022jp`:case`iso-2022-jp`:return`ISO-2022-JP`;case`csshiftjis`:case`ms932`:case`ms_kanji`:case`shift-jis`:case`shift_jis`:case`sjis`:case`windows-31j`:case`x-sjis`:return`Shift_JIS`;case`cseuckr`:case`csksc56011987`:case`euc-kr`:case`iso-ir-149`:case`korean`:case`ks_c_5601-1987`:case`ks_c_5601-1989`:case`ksc5601`:case`ksc_5601`:case`windows-949`:return`EUC-KR`;case`csiso2022kr`:case`hz-gb-2312`:case`iso-2022-cn`:case`iso-2022-cn-ext`:case`iso-2022-kr`:case`replacement`:return`replacement`;case`unicodefffe`:case`utf-16be`:return`UTF-16BE`;case`csunicode`:case`iso-10646-ucs-2`:case`ucs-2`:case`unicode`:case`unicodefeff`:case`utf-16`:case`utf-16le`:return`UTF-16LE`;case`x-user-defined`:return`x-user-defined`;default:return`failure`}}t.exports={getEncoding:n}})),Ye=o(((e,t)=>{var{kState:n,kError:r,kResult:i,kAborted:a,kLastProgressEventFired:o}=Ke(),{ProgressEvent:s}=qe(),{getEncoding:c}=Je(),{serializeAMimeType:l,parseMIMEType:u}=H(),{types:d}=require(`node:util`),{StringDecoder:f}=require(`string_decoder`),{btoa:p}=require(`node:buffer`),m={enumerable:!0,writable:!1,configurable:!1};function h(e,t,s,c){if(e[n]===`loading`)throw new DOMException(`Invalid state`,`InvalidStateError`);e[n]=`loading`,e[i]=null,e[r]=null;let l=t.stream().getReader(),u=[],f=l.read(),p=!0;(async()=>{for(;!e[a];)try{let{done:m,value:h}=await f;if(p&&!e[a]&&queueMicrotask(()=>{g(`loadstart`,e)}),p=!1,!m&&d.isUint8Array(h))u.push(h),(e[o]===void 0||Date.now()-e[o]>=50)&&!e[a]&&(e[o]=Date.now(),queueMicrotask(()=>{g(`progress`,e)})),f=l.read();else if(m){queueMicrotask(()=>{e[n]=`done`;try{let n=_(u,s,t.type,c);if(e[a])return;e[i]=n,g(`load`,e)}catch(t){e[r]=t,g(`error`,e)}e[n]!==`loading`&&g(`loadend`,e)});break}}catch(t){if(e[a])return;queueMicrotask(()=>{e[n]=`done`,e[r]=t,g(`error`,e),e[n]!==`loading`&&g(`loadend`,e)});break}})()}function g(e,t){let n=new s(e,{bubbles:!1,cancelable:!1});t.dispatchEvent(n)}function _(e,t,n,r){switch(t){case`DataURL`:{let t=`data:`,r=u(n||`application/octet-stream`);r!==`failure`&&(t+=l(r)),t+=`;base64,`;let i=new f(`latin1`);for(let n of e)t+=p(i.write(n));return t+=p(i.end()),t}case`Text`:{let t=`failure`;if(r&&(t=c(r)),t===`failure`&&n){let e=u(n);e!==`failure`&&(t=c(e.parameters.get(`charset`)))}return t===`failure`&&(t=`UTF-8`),v(e,t)}case`ArrayBuffer`:return b(e).buffer;case`BinaryString`:{let t=``,n=new f(`latin1`);for(let r of e)t+=n.write(r);return t+=n.end(),t}}}function v(e,t){let n=b(e),r=y(n),i=0;r!==null&&(t=r,i=r===`UTF-8`?3:2);let a=n.slice(i);return new TextDecoder(t).decode(a)}function y(e){let[t,n,r]=e;return t===239&&n===187&&r===191?`UTF-8`:t===254&&n===255?`UTF-16BE`:t===255&&n===254?`UTF-16LE`:null}function b(e){let t=e.reduce((e,t)=>e+t.byteLength,0),n=0;return e.reduce((e,t)=>(e.set(t,n),n+=t.byteLength,e),new Uint8Array(t))}t.exports={staticPropertyDescriptors:m,readOperation:h,fireAProgressEvent:g}})),Xe=o(((e,t)=>{var{staticPropertyDescriptors:n,readOperation:r,fireAProgressEvent:i}=Ye(),{kState:a,kError:o,kResult:s,kEvents:c,kAborted:l}=Ke(),{webidl:u}=U(),{kEnumerableProperty:d}=F(),f=class e extends EventTarget{constructor(){super(),this[a]=`empty`,this[s]=null,this[o]=null,this[c]={loadend:null,error:null,abort:null,load:null,progress:null,loadstart:null}}readAsArrayBuffer(t){u.brandCheck(this,e),u.argumentLengthCheck(arguments,1,`FileReader.readAsArrayBuffer`),t=u.converters.Blob(t,{strict:!1}),r(this,t,`ArrayBuffer`)}readAsBinaryString(t){u.brandCheck(this,e),u.argumentLengthCheck(arguments,1,`FileReader.readAsBinaryString`),t=u.converters.Blob(t,{strict:!1}),r(this,t,`BinaryString`)}readAsText(t,n=void 0){u.brandCheck(this,e),u.argumentLengthCheck(arguments,1,`FileReader.readAsText`),t=u.converters.Blob(t,{strict:!1}),n!==void 0&&(n=u.converters.DOMString(n,`FileReader.readAsText`,`encoding`)),r(this,t,`Text`,n)}readAsDataURL(t){u.brandCheck(this,e),u.argumentLengthCheck(arguments,1,`FileReader.readAsDataURL`),t=u.converters.Blob(t,{strict:!1}),r(this,t,`DataURL`)}abort(){if(this[a]===`empty`||this[a]===`done`){this[s]=null;return}this[a]===`loading`&&(this[a]=`done`,this[s]=null),this[l]=!0,i(`abort`,this),this[a]!==`loading`&&i(`loadend`,this)}get readyState(){switch(u.brandCheck(this,e),this[a]){case`empty`:return this.EMPTY;case`loading`:return this.LOADING;case`done`:return this.DONE}}get result(){return u.brandCheck(this,e),this[s]}get error(){return u.brandCheck(this,e),this[o]}get onloadend(){return u.brandCheck(this,e),this[c].loadend}set onloadend(t){u.brandCheck(this,e),this[c].loadend&&this.removeEventListener(`loadend`,this[c].loadend),typeof t==`function`?(this[c].loadend=t,this.addEventListener(`loadend`,t)):this[c].loadend=null}get onerror(){return u.brandCheck(this,e),this[c].error}set onerror(t){u.brandCheck(this,e),this[c].error&&this.removeEventListener(`error`,this[c].error),typeof t==`function`?(this[c].error=t,this.addEventListener(`error`,t)):this[c].error=null}get onloadstart(){return u.brandCheck(this,e),this[c].loadstart}set onloadstart(t){u.brandCheck(this,e),this[c].loadstart&&this.removeEventListener(`loadstart`,this[c].loadstart),typeof t==`function`?(this[c].loadstart=t,this.addEventListener(`loadstart`,t)):this[c].loadstart=null}get onprogress(){return u.brandCheck(this,e),this[c].progress}set onprogress(t){u.brandCheck(this,e),this[c].progress&&this.removeEventListener(`progress`,this[c].progress),typeof t==`function`?(this[c].progress=t,this.addEventListener(`progress`,t)):this[c].progress=null}get onload(){return u.brandCheck(this,e),this[c].load}set onload(t){u.brandCheck(this,e),this[c].load&&this.removeEventListener(`load`,this[c].load),typeof t==`function`?(this[c].load=t,this.addEventListener(`load`,t)):this[c].load=null}get onabort(){return u.brandCheck(this,e),this[c].abort}set onabort(t){u.brandCheck(this,e),this[c].abort&&this.removeEventListener(`abort`,this[c].abort),typeof t==`function`?(this[c].abort=t,this.addEventListener(`abort`,t)):this[c].abort=null}};f.EMPTY=f.prototype.EMPTY=0,f.LOADING=f.prototype.LOADING=1,f.DONE=f.prototype.DONE=2,Object.defineProperties(f.prototype,{EMPTY:n,LOADING:n,DONE:n,readAsArrayBuffer:d,readAsBinaryString:d,readAsText:d,readAsDataURL:d,abort:d,readyState:d,result:d,error:d,onloadstart:d,onprogress:d,onload:d,onabort:d,onerror:d,onloadend:d,[Symbol.toStringTag]:{value:`FileReader`,writable:!1,enumerable:!1,configurable:!0}}),Object.defineProperties(f,{EMPTY:n,LOADING:n,DONE:n}),t.exports={FileReader:f}})),Ze=o(((e,t)=>{t.exports={kConstruct:j().kConstruct}})),Qe=o(((e,t)=>{var n=require(`node:assert`),{URLSerializer:r}=H(),{isValidHeaderName:i}=W();function a(e,t,n=!1){return r(e,n)===r(t,n)}function o(e){n(e!==null);let t=[];for(let n of e.split(`,`))n=n.trim(),i(n)&&t.push(n);return t}t.exports={urlEquals:a,getFieldValues:o}})),$e=o(((e,t)=>{var{kConstruct:n}=Ze(),{urlEquals:r,getFieldValues:i}=Qe(),{kEnumerableProperty:a,isDisturbed:o}=F(),{webidl:s}=U(),{Response:c,cloneResponse:l,fromInnerResponse:u}=He(),{Request:d,fromInnerRequest:f}=We(),{kState:p}=G(),{fetching:m}=Ge(),{urlIsHttpHttpsScheme:h,createDeferredPromise:g,readAllBytes:_}=W(),v=require(`node:assert`),y=class e{#e;constructor(){arguments[0]!==n&&s.illegalConstructor(),s.util.markAsUncloneable(this),this.#e=arguments[1]}async match(t,n={}){s.brandCheck(this,e);let r=`Cache.match`;s.argumentLengthCheck(arguments,1,r),t=s.converters.RequestInfo(t,r,`request`),n=s.converters.CacheQueryOptions(n,r,`options`);let i=this.#i(t,n,1);if(i.length!==0)return i[0]}async matchAll(t=void 0,n={}){s.brandCheck(this,e);let r=`Cache.matchAll`;return t!==void 0&&(t=s.converters.RequestInfo(t,r,`request`)),n=s.converters.CacheQueryOptions(n,r,`options`),this.#i(t,n)}async add(t){s.brandCheck(this,e);let n=`Cache.add`;s.argumentLengthCheck(arguments,1,n),t=s.converters.RequestInfo(t,n,`request`);let r=[t];return await this.addAll(r)}async addAll(t){s.brandCheck(this,e);let n=`Cache.addAll`;s.argumentLengthCheck(arguments,1,n);let r=[],a=[];for(let e of t){if(e===void 0)throw s.errors.conversionFailed({prefix:n,argument:`Argument 1`,types:[`undefined is not allowed`]});if(e=s.converters.RequestInfo(e),typeof e==`string`)continue;let t=e[p];if(!h(t.url)||t.method!==`GET`)throw s.errors.exception({header:n,message:`Expected http/s scheme when method is not GET.`})}let o=[];for(let e of t){let t=new d(e)[p];if(!h(t.url))throw s.errors.exception({header:n,message:`Expected http/s scheme.`});t.initiator=`fetch`,t.destination=`subresource`,a.push(t);let c=g();o.push(m({request:t,processResponse(e){if(e.type===`error`||e.status===206||e.status<200||e.status>299)c.reject(s.errors.exception({header:`Cache.addAll`,message:`Received an invalid status code or the request failed.`}));else if(e.headersList.contains(`vary`)){let t=i(e.headersList.get(`vary`));for(let e of t)if(e===`*`){c.reject(s.errors.exception({header:`Cache.addAll`,message:`invalid vary field value`}));for(let e of o)e.abort();return}}},processResponseEndOfBody(e){if(e.aborted){c.reject(new DOMException(`aborted`,`AbortError`));return}c.resolve(e)}})),r.push(c.promise)}let c=await Promise.all(r),l=[],u=0;for(let e of c){let t={type:`put`,request:a[u],response:e};l.push(t),u++}let f=g(),_=null;try{this.#t(l)}catch(e){_=e}return queueMicrotask(()=>{_===null?f.resolve(void 0):f.reject(_)}),f.promise}async put(t,n){s.brandCheck(this,e);let r=`Cache.put`;s.argumentLengthCheck(arguments,2,r),t=s.converters.RequestInfo(t,r,`request`),n=s.converters.Response(n,r,`response`);let a=null;if(a=t instanceof d?t[p]:new d(t)[p],!h(a.url)||a.method!==`GET`)throw s.errors.exception({header:r,message:`Expected an http/s scheme when method is not GET`});let c=n[p];if(c.status===206)throw s.errors.exception({header:r,message:`Got 206 status`});if(c.headersList.contains(`vary`)){let e=i(c.headersList.get(`vary`));for(let t of e)if(t===`*`)throw s.errors.exception({header:r,message:`Got * vary field value`})}if(c.body&&(o(c.body.stream)||c.body.stream.locked))throw s.errors.exception({header:r,message:`Response body is locked or disturbed`});let u=l(c),f=g();c.body==null?f.resolve(void 0):_(c.body.stream.getReader()).then(f.resolve,f.reject);let m=[],v={type:`put`,request:a,response:u};m.push(v);let y=await f.promise;u.body!=null&&(u.body.source=y);let b=g(),x=null;try{this.#t(m)}catch(e){x=e}return queueMicrotask(()=>{x===null?b.resolve():b.reject(x)}),b.promise}async delete(t,n={}){s.brandCheck(this,e);let r=`Cache.delete`;s.argumentLengthCheck(arguments,1,r),t=s.converters.RequestInfo(t,r,`request`),n=s.converters.CacheQueryOptions(n,r,`options`);let i=null;if(t instanceof d){if(i=t[p],i.method!==`GET`&&!n.ignoreMethod)return!1}else v(typeof t==`string`),i=new d(t)[p];let a=[],o={type:`delete`,request:i,options:n};a.push(o);let c=g(),l=null,u;try{u=this.#t(a)}catch(e){l=e}return queueMicrotask(()=>{l===null?c.resolve(!!u?.length):c.reject(l)}),c.promise}async keys(t=void 0,n={}){s.brandCheck(this,e);let r=`Cache.keys`;t!==void 0&&(t=s.converters.RequestInfo(t,r,`request`)),n=s.converters.CacheQueryOptions(n,r,`options`);let i=null;if(t!==void 0)if(t instanceof d){if(i=t[p],i.method!==`GET`&&!n.ignoreMethod)return[]}else typeof t==`string`&&(i=new d(t)[p]);let a=g(),o=[];if(t===void 0)for(let e of this.#e)o.push(e[0]);else{let e=this.#n(i,n);for(let t of e)o.push(t[0])}return queueMicrotask(()=>{let e=[];for(let t of o){let n=f(t,new AbortController().signal,`immutable`);e.push(n)}a.resolve(Object.freeze(e))}),a.promise}#t(e){let t=this.#e,n=[...t],r=[],i=[];try{for(let n of e){if(n.type!==`delete`&&n.type!==`put`)throw s.errors.exception({header:`Cache.#batchCacheOperations`,message:`operation type does not match "delete" or "put"`});if(n.type===`delete`&&n.response!=null)throw s.errors.exception({header:`Cache.#batchCacheOperations`,message:`delete operation should not have an associated response`});if(this.#n(n.request,n.options,r).length)throw new DOMException(`???`,`InvalidStateError`);let e;if(n.type===`delete`){if(e=this.#n(n.request,n.options),e.length===0)return[];for(let n of e){let e=t.indexOf(n);v(e!==-1),t.splice(e,1)}}else if(n.type===`put`){if(n.response==null)throw s.errors.exception({header:`Cache.#batchCacheOperations`,message:`put operation should have an associated response`});let i=n.request;if(!h(i.url))throw s.errors.exception({header:`Cache.#batchCacheOperations`,message:`expected http or https scheme`});if(i.method!==`GET`)throw s.errors.exception({header:`Cache.#batchCacheOperations`,message:`not get method`});if(n.options!=null)throw s.errors.exception({header:`Cache.#batchCacheOperations`,message:`options must not be defined`});e=this.#n(n.request);for(let n of e){let e=t.indexOf(n);v(e!==-1),t.splice(e,1)}t.push([n.request,n.response]),r.push([n.request,n.response])}i.push([n.request,n.response])}return i}catch(e){throw this.#e.length=0,this.#e=n,e}}#n(e,t,n){let r=[],i=n??this.#e;for(let n of i){let[i,a]=n;this.#r(e,i,a,t)&&r.push(n)}return r}#r(e,t,n=null,a){let o=new URL(e.url),s=new URL(t.url);if(a?.ignoreSearch&&(s.search=``,o.search=``),!r(o,s,!0))return!1;if(n==null||a?.ignoreVary||!n.headersList.contains(`vary`))return!0;let c=i(n.headersList.get(`vary`));for(let n of c)if(n===`*`||t.headersList.get(n)!==e.headersList.get(n))return!1;return!0}#i(e,t,n=1/0){let r=null;if(e!==void 0)if(e instanceof d){if(r=e[p],r.method!==`GET`&&!t.ignoreMethod)return[]}else typeof e==`string`&&(r=new d(e)[p]);let i=[];if(e===void 0)for(let e of this.#e)i.push(e[1]);else{let e=this.#n(r,t);for(let t of e)i.push(t[1])}let a=[];for(let e of i){let t=u(e,`immutable`);if(a.push(t.clone()),a.length>=n)break}return Object.freeze(a)}};Object.defineProperties(y.prototype,{[Symbol.toStringTag]:{value:`Cache`,configurable:!0},match:a,matchAll:a,add:a,addAll:a,put:a,delete:a,keys:a});var b=[{key:`ignoreSearch`,converter:s.converters.boolean,defaultValue:()=>!1},{key:`ignoreMethod`,converter:s.converters.boolean,defaultValue:()=>!1},{key:`ignoreVary`,converter:s.converters.boolean,defaultValue:()=>!1}];s.converters.CacheQueryOptions=s.dictionaryConverter(b),s.converters.MultiCacheQueryOptions=s.dictionaryConverter([...b,{key:`cacheName`,converter:s.converters.DOMString}]),s.converters.Response=s.interfaceConverter(c),s.converters[`sequence`]=s.sequenceConverter(s.converters.RequestInfo),t.exports={Cache:y}})),et=o(((e,t)=>{var{kConstruct:n}=Ze(),{Cache:r}=$e(),{webidl:i}=U(),{kEnumerableProperty:a}=F(),o=class e{#e=new Map;constructor(){arguments[0]!==n&&i.illegalConstructor(),i.util.markAsUncloneable(this)}async match(t,a={}){if(i.brandCheck(this,e),i.argumentLengthCheck(arguments,1,`CacheStorage.match`),t=i.converters.RequestInfo(t),a=i.converters.MultiCacheQueryOptions(a),a.cacheName!=null){if(this.#e.has(a.cacheName))return await new r(n,this.#e.get(a.cacheName)).match(t,a)}else for(let e of this.#e.values()){let i=await new r(n,e).match(t,a);if(i!==void 0)return i}}async has(t){i.brandCheck(this,e);let n=`CacheStorage.has`;return i.argumentLengthCheck(arguments,1,n),t=i.converters.DOMString(t,n,`cacheName`),this.#e.has(t)}async open(t){i.brandCheck(this,e);let a=`CacheStorage.open`;if(i.argumentLengthCheck(arguments,1,a),t=i.converters.DOMString(t,a,`cacheName`),this.#e.has(t))return new r(n,this.#e.get(t));let o=[];return this.#e.set(t,o),new r(n,o)}async delete(t){i.brandCheck(this,e);let n=`CacheStorage.delete`;return i.argumentLengthCheck(arguments,1,n),t=i.converters.DOMString(t,n,`cacheName`),this.#e.delete(t)}async keys(){return i.brandCheck(this,e),[...this.#e.keys()]}};Object.defineProperties(o.prototype,{[Symbol.toStringTag]:{value:`CacheStorage`,configurable:!0},match:a,has:a,open:a,delete:a,keys:a}),t.exports={CacheStorage:o}})),tt=o(((e,t)=>{t.exports={maxAttributeValueSize:1024,maxNameValuePairSize:4096}})),nt=o(((e,t)=>{function n(e){for(let t=0;t=0&&n<=8||n>=10&&n<=31||n===127)return!0}return!1}function r(e){for(let t=0;t126||n===34||n===40||n===41||n===60||n===62||n===64||n===44||n===59||n===58||n===92||n===47||n===91||n===93||n===63||n===61||n===123||n===125)throw Error(`Invalid cookie name`)}}function i(e){let t=e.length,n=0;if(e[0]===`"`){if(t===1||e[t-1]!==`"`)throw Error(`Invalid cookie value`);--t,++n}for(;n126||t===34||t===44||t===59||t===92)throw Error(`Invalid cookie value`)}}function a(e){for(let t=0;tt.toString().padStart(2,`0`));function u(e){return typeof e==`number`&&(e=new Date(e)),`${s[e.getUTCDay()]}, ${l[e.getUTCDate()]} ${c[e.getUTCMonth()]} ${e.getUTCFullYear()} ${l[e.getUTCHours()]}:${l[e.getUTCMinutes()]}:${l[e.getUTCSeconds()]} GMT`}function d(e){if(e<0)throw Error(`Invalid cookie max-age`)}function f(e){if(e.name.length===0)return null;r(e.name),i(e.value);let t=[`${e.name}=${e.value}`];e.name.startsWith(`__Secure-`)&&(e.secure=!0),e.name.startsWith(`__Host-`)&&(e.secure=!0,e.domain=null,e.path=`/`),e.secure&&t.push(`Secure`),e.httpOnly&&t.push(`HttpOnly`),typeof e.maxAge==`number`&&(d(e.maxAge),t.push(`Max-Age=${e.maxAge}`)),e.domain&&(o(e.domain),t.push(`Domain=${e.domain}`)),e.path&&(a(e.path),t.push(`Path=${e.path}`)),e.expires&&e.expires.toString()!==`Invalid Date`&&t.push(`Expires=${u(e.expires)}`),e.sameSite&&t.push(`SameSite=${e.sameSite}`);for(let n of e.unparsed){if(!n.includes(`=`))throw Error(`Invalid unparsed`);let[e,...r]=n.split(`=`);t.push(`${e.trim()}=${r.join(`=`)}`)}return t.join(`; `)}t.exports={isCTLExcludingHtab:n,validateCookieName:r,validateCookiePath:a,validateCookieValue:i,toIMFDate:u,stringify:f}})),rt=o(((e,t)=>{var{maxNameValuePairSize:n,maxAttributeValueSize:r}=tt(),{isCTLExcludingHtab:i}=nt(),{collectASequenceOfCodePointsFast:a}=H(),o=require(`node:assert`);function s(e){if(i(e))return null;let t=``,r=``,o=``,s=``;if(e.includes(`;`)){let n={position:0};t=a(`;`,e,n),r=e.slice(n.position)}else t=e;if(!t.includes(`=`))s=t;else{let e={position:0};o=a(`=`,t,e),s=t.slice(e.position+1)}return o=o.trim(),s=s.trim(),o.length+s.length>n?null:{name:o,value:s,...c(r)}}function c(e,t={}){if(e.length===0)return t;o(e[0]===`;`),e=e.slice(1);let n=``;e.includes(`;`)?(n=a(`;`,e,{position:0}),e=e.slice(n.length)):(n=e,e=``);let i=``,s=``;if(n.includes(`=`)){let e={position:0};i=a(`=`,n,e),s=n.slice(e.position+1)}else i=n;if(i=i.trim(),s=s.trim(),s.length>r)return c(e,t);let l=i.toLowerCase();if(l===`expires`)t.expires=new Date(s);else if(l===`max-age`){let n=s.charCodeAt(0);if((n<48||n>57)&&s[0]!==`-`||!/^\d+$/.test(s))return c(e,t);t.maxAge=Number(s)}else if(l===`domain`){let e=s;e[0]===`.`&&(e=e.slice(1)),e=e.toLowerCase(),t.domain=e}else if(l===`path`){let e=``;e=s.length===0||s[0]!==`/`?`/`:s,t.path=e}else if(l===`secure`)t.secure=!0;else if(l===`httponly`)t.httpOnly=!0;else if(l===`samesite`){let e=`Default`,n=s.toLowerCase();n.includes(`none`)&&(e=`None`),n.includes(`strict`)&&(e=`Strict`),n.includes(`lax`)&&(e=`Lax`),t.sameSite=e}else t.unparsed??=[],t.unparsed.push(`${i}=${s}`);return c(e,t)}t.exports={parseSetCookie:s,parseUnparsedAttributes:c}})),it=o(((e,t)=>{var{parseSetCookie:n}=rt(),{stringify:r}=nt(),{webidl:i}=U(),{Headers:a}=Ve();function o(e){i.argumentLengthCheck(arguments,1,`getCookies`),i.brandCheck(e,a,{strict:!1});let t=e.get(`cookie`),n={};if(!t)return n;for(let e of t.split(`;`)){let[t,...r]=e.split(`=`);n[t.trim()]=r.join(`=`)}return n}function s(e,t,n){i.brandCheck(e,a,{strict:!1});let r=`deleteCookie`;i.argumentLengthCheck(arguments,2,r),t=i.converters.DOMString(t,r,`name`),n=i.converters.DeleteCookieAttributes(n),l(e,{name:t,value:``,expires:new Date(0),...n})}function c(e){i.argumentLengthCheck(arguments,1,`getSetCookies`),i.brandCheck(e,a,{strict:!1});let t=e.getSetCookie();return t?t.map(e=>n(e)):[]}function l(e,t){i.argumentLengthCheck(arguments,2,`setCookie`),i.brandCheck(e,a,{strict:!1}),t=i.converters.Cookie(t);let n=r(t);n&&e.append(`Set-Cookie`,n)}i.converters.DeleteCookieAttributes=i.dictionaryConverter([{converter:i.nullableConverter(i.converters.DOMString),key:`path`,defaultValue:()=>null},{converter:i.nullableConverter(i.converters.DOMString),key:`domain`,defaultValue:()=>null}]),i.converters.Cookie=i.dictionaryConverter([{converter:i.converters.DOMString,key:`name`},{converter:i.converters.DOMString,key:`value`},{converter:i.nullableConverter(e=>typeof e==`number`?i.converters[`unsigned long long`](e):new Date(e)),key:`expires`,defaultValue:()=>null},{converter:i.nullableConverter(i.converters[`long long`]),key:`maxAge`,defaultValue:()=>null},{converter:i.nullableConverter(i.converters.DOMString),key:`domain`,defaultValue:()=>null},{converter:i.nullableConverter(i.converters.DOMString),key:`path`,defaultValue:()=>null},{converter:i.nullableConverter(i.converters.boolean),key:`secure`,defaultValue:()=>null},{converter:i.nullableConverter(i.converters.boolean),key:`httpOnly`,defaultValue:()=>null},{converter:i.converters.USVString,key:`sameSite`,allowedValues:[`Strict`,`Lax`,`None`]},{converter:i.sequenceConverter(i.converters.DOMString),key:`unparsed`,defaultValue:()=>[]}]),t.exports={getCookies:o,deleteCookie:s,getSetCookies:c,setCookie:l}})),at=o(((e,t)=>{var{webidl:n}=U(),{kEnumerableProperty:r}=F(),{kConstruct:i}=j(),{MessagePort:a}=require(`node:worker_threads`),o=class e extends Event{#e;constructor(e,t={}){if(e===i){super(arguments[1],arguments[2]),n.util.markAsUncloneable(this);return}let r=`MessageEvent constructor`;n.argumentLengthCheck(arguments,1,r),e=n.converters.DOMString(e,r,`type`),t=n.converters.MessageEventInit(t,r,`eventInitDict`),super(e,t),this.#e=t,n.util.markAsUncloneable(this)}get data(){return n.brandCheck(this,e),this.#e.data}get origin(){return n.brandCheck(this,e),this.#e.origin}get lastEventId(){return n.brandCheck(this,e),this.#e.lastEventId}get source(){return n.brandCheck(this,e),this.#e.source}get ports(){return n.brandCheck(this,e),Object.isFrozen(this.#e.ports)||Object.freeze(this.#e.ports),this.#e.ports}initMessageEvent(t,r=!1,i=!1,a=null,o=``,s=``,c=null,l=[]){return n.brandCheck(this,e),n.argumentLengthCheck(arguments,1,`MessageEvent.initMessageEvent`),new e(t,{bubbles:r,cancelable:i,data:a,origin:o,lastEventId:s,source:c,ports:l})}static createFastMessageEvent(t,n){let r=new e(i,t,n);return r.#e=n,r.#e.data??=null,r.#e.origin??=``,r.#e.lastEventId??=``,r.#e.source??=null,r.#e.ports??=[],r}},{createFastMessageEvent:s}=o;delete o.createFastMessageEvent;var c=class e extends Event{#e;constructor(e,t={}){let r=`CloseEvent constructor`;n.argumentLengthCheck(arguments,1,r),e=n.converters.DOMString(e,r,`type`),t=n.converters.CloseEventInit(t),super(e,t),this.#e=t,n.util.markAsUncloneable(this)}get wasClean(){return n.brandCheck(this,e),this.#e.wasClean}get code(){return n.brandCheck(this,e),this.#e.code}get reason(){return n.brandCheck(this,e),this.#e.reason}},l=class e extends Event{#e;constructor(e,t){let r=`ErrorEvent constructor`;n.argumentLengthCheck(arguments,1,r),super(e,t),n.util.markAsUncloneable(this),e=n.converters.DOMString(e,r,`type`),t=n.converters.ErrorEventInit(t??{}),this.#e=t}get message(){return n.brandCheck(this,e),this.#e.message}get filename(){return n.brandCheck(this,e),this.#e.filename}get lineno(){return n.brandCheck(this,e),this.#e.lineno}get colno(){return n.brandCheck(this,e),this.#e.colno}get error(){return n.brandCheck(this,e),this.#e.error}};Object.defineProperties(o.prototype,{[Symbol.toStringTag]:{value:`MessageEvent`,configurable:!0},data:r,origin:r,lastEventId:r,source:r,ports:r,initMessageEvent:r}),Object.defineProperties(c.prototype,{[Symbol.toStringTag]:{value:`CloseEvent`,configurable:!0},reason:r,code:r,wasClean:r}),Object.defineProperties(l.prototype,{[Symbol.toStringTag]:{value:`ErrorEvent`,configurable:!0},message:r,filename:r,lineno:r,colno:r,error:r}),n.converters.MessagePort=n.interfaceConverter(a),n.converters[`sequence`]=n.sequenceConverter(n.converters.MessagePort);var u=[{key:`bubbles`,converter:n.converters.boolean,defaultValue:()=>!1},{key:`cancelable`,converter:n.converters.boolean,defaultValue:()=>!1},{key:`composed`,converter:n.converters.boolean,defaultValue:()=>!1}];n.converters.MessageEventInit=n.dictionaryConverter([...u,{key:`data`,converter:n.converters.any,defaultValue:()=>null},{key:`origin`,converter:n.converters.USVString,defaultValue:()=>``},{key:`lastEventId`,converter:n.converters.DOMString,defaultValue:()=>``},{key:`source`,converter:n.nullableConverter(n.converters.MessagePort),defaultValue:()=>null},{key:`ports`,converter:n.converters[`sequence`],defaultValue:()=>[]}]),n.converters.CloseEventInit=n.dictionaryConverter([...u,{key:`wasClean`,converter:n.converters.boolean,defaultValue:()=>!1},{key:`code`,converter:n.converters[`unsigned short`],defaultValue:()=>0},{key:`reason`,converter:n.converters.USVString,defaultValue:()=>``}]),n.converters.ErrorEventInit=n.dictionaryConverter([...u,{key:`message`,converter:n.converters.DOMString,defaultValue:()=>``},{key:`filename`,converter:n.converters.USVString,defaultValue:()=>``},{key:`lineno`,converter:n.converters[`unsigned long`],defaultValue:()=>0},{key:`colno`,converter:n.converters[`unsigned long`],defaultValue:()=>0},{key:`error`,converter:n.converters.any}]),t.exports={MessageEvent:o,CloseEvent:c,ErrorEvent:l,createFastMessageEvent:s}})),ot=o(((e,t)=>{t.exports={uid:`258EAFA5-E914-47DA-95CA-C5AB0DC85B11`,sentCloseFrameState:{NOT_SENT:0,PROCESSING:1,SENT:2},staticPropertyDescriptors:{enumerable:!0,writable:!1,configurable:!1},states:{CONNECTING:0,OPEN:1,CLOSING:2,CLOSED:3},opcodes:{CONTINUATION:0,TEXT:1,BINARY:2,CLOSE:8,PING:9,PONG:10},maxUnsigned16Bit:2**16-1,parserStates:{INFO:0,PAYLOADLENGTH_16:2,PAYLOADLENGTH_64:3,READ_DATA:4},emptyBuffer:Buffer.allocUnsafe(0),sendHints:{string:1,typedArray:2,arrayBuffer:3,blob:4}}})),st=o(((e,t)=>{t.exports={kWebSocketURL:Symbol(`url`),kReadyState:Symbol(`ready state`),kController:Symbol(`controller`),kResponse:Symbol(`response`),kBinaryType:Symbol(`binary type`),kSentClose:Symbol(`sent close`),kReceivedClose:Symbol(`received close`),kByteParser:Symbol(`byte parser`)}})),ct=o(((e,t)=>{var{kReadyState:n,kController:r,kResponse:i,kBinaryType:a,kWebSocketURL:o}=st(),{states:s,opcodes:c}=ot(),{ErrorEvent:l,createFastMessageEvent:u}=at(),{isUtf8:d}=require(`node:buffer`),{collectASequenceOfCodePointsFast:f,removeHTTPWhitespace:p}=H();function m(e){return e[n]===s.CONNECTING}function h(e){return e[n]===s.OPEN}function g(e){return e[n]===s.CLOSING}function _(e){return e[n]===s.CLOSED}function v(e,t,n=(e,t)=>new Event(e,t),r={}){let i=n(e,r);t.dispatchEvent(i)}function y(e,t,r){if(e[n]!==s.OPEN)return;let i;if(t===c.TEXT)try{i=M(r)}catch{C(e,`Received invalid UTF-8 in text frame.`);return}else t===c.BINARY&&(i=e[a]===`blob`?new Blob([r]):b(r));v(`message`,e,u,{origin:e[o].origin,data:i})}function b(e){return e.byteLength===e.buffer.byteLength?e.buffer:e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength)}function x(e){if(e.length===0)return!1;for(let t=0;t126||n===34||n===40||n===41||n===44||n===47||n===58||n===59||n===60||n===61||n===62||n===63||n===64||n===91||n===92||n===93||n===123||n===125)return!1}return!0}function S(e){return e>=1e3&&e<1015?e!==1004&&e!==1005&&e!==1006:e>=3e3&&e<=4999}function C(e,t){let{[r]:n,[i]:a}=e;n.abort(),a?.socket&&!a.socket.destroyed&&a.socket.destroy(),t&&v(`error`,e,(e,t)=>new l(e,t),{error:Error(t),message:t})}function w(e){return e===c.CLOSE||e===c.PING||e===c.PONG}function T(e){return e===c.CONTINUATION}function E(e){return e===c.TEXT||e===c.BINARY}function D(e){return E(e)||T(e)||w(e)}function O(e){let t={position:0},n=new Map;for(;t.position57)return!1}let t=Number.parseInt(e,10);return t>=8&&t<=15}var A=typeof process.versions.icu==`string`,j=A?new TextDecoder(`utf-8`,{fatal:!0}):void 0,M=A?j.decode.bind(j):function(e){if(d(e))return e.toString(`utf-8`);throw TypeError(`Invalid utf-8 received.`)};t.exports={isConnecting:m,isEstablished:h,isClosing:g,isClosed:_,fireEvent:v,isValidSubprotocol:x,isValidStatusCode:S,failWebsocketConnection:C,websocketMessageReceived:y,utf8Decode:M,isControlFrame:w,isContinuationFrame:T,isTextBinaryFrame:E,isValidOpcode:D,parseExtensions:O,isValidClientWindowBits:k}})),lt=o(((e,t)=>{var{maxUnsigned16Bit:n}=ot(),r=16386,i,a=null,o=r;try{i=require(`node:crypto`)}catch{i={randomFillSync:function(e,t,n){for(let t=0;tn?(o+=8,a=127):i>125&&(o+=2,a=126);let c=Buffer.allocUnsafe(i+o);c[0]=c[1]=0,c[0]|=128,c[0]=(c[0]&240)+e,c[o-4]=r[0],c[o-3]=r[1],c[o-2]=r[2],c[o-1]=r[3],c[1]=a,a===126?c.writeUInt16BE(i,2):a===127&&(c[2]=c[3]=0,c.writeUIntBE(i,4,6)),c[1]|=128;for(let e=0;e{var{uid:n,states:r,sentCloseFrameState:i,emptyBuffer:a,opcodes:o}=ot(),{kReadyState:s,kSentClose:c,kByteParser:l,kReceivedClose:u,kResponse:d}=st(),{fireEvent:f,failWebsocketConnection:p,isClosing:m,isClosed:h,isEstablished:g,parseExtensions:_}=ct(),{channels:v}=I(),{CloseEvent:y}=at(),{makeRequest:b}=We(),{fetching:x}=Ge(),{Headers:S,getHeadersList:C}=Ve(),{getDecodeSplit:w}=W(),{WebsocketFrameSend:T}=lt(),E;try{E=require(`node:crypto`)}catch{}function D(e,t,r,i,a,o){let s=e;s.protocol=e.protocol===`ws:`?`http:`:`https:`;let c=b({urlList:[s],client:r,serviceWorkers:`none`,referrer:`no-referrer`,mode:`websocket`,credentials:`include`,cache:`no-store`,redirect:`error`});o.headers&&(c.headersList=C(new S(o.headers)));let l=E.randomBytes(16).toString(`base64`);c.headersList.append(`sec-websocket-key`,l),c.headersList.append(`sec-websocket-version`,`13`);for(let e of t)c.headersList.append(`sec-websocket-protocol`,e);return c.headersList.append(`sec-websocket-extensions`,`permessage-deflate; client_max_window_bits`),x({request:c,useParallelQueue:!0,dispatcher:o.dispatcher,processResponse(e){if(e.type===`error`||e.status!==101){p(i,`Received network error or non-101 status code.`);return}if(t.length!==0&&!e.headersList.get(`Sec-WebSocket-Protocol`)){p(i,`Server did not respond with sent protocols.`);return}if(e.headersList.get(`Upgrade`)?.toLowerCase()!==`websocket`){p(i,`Server did not set Upgrade header to "websocket".`);return}if(e.headersList.get(`Connection`)?.toLowerCase()!==`upgrade`){p(i,`Server did not set Connection header to "upgrade".`);return}if(e.headersList.get(`Sec-WebSocket-Accept`)!==E.createHash(`sha1`).update(l+n).digest(`base64`)){p(i,`Incorrect hash received in Sec-WebSocket-Accept header.`);return}let r=e.headersList.get(`Sec-WebSocket-Extensions`),o;if(r!==null&&(o=_(r),!o.has(`permessage-deflate`))){p(i,`Sec-WebSocket-Extensions header does not match.`);return}let s=e.headersList.get(`Sec-WebSocket-Protocol`);if(s!==null&&!w(`sec-websocket-protocol`,c.headersList).includes(s)){p(i,`Protocol was not set in the opening handshake.`);return}e.socket.on(`data`,k),e.socket.on(`close`,A),e.socket.on(`error`,j),v.open.hasSubscribers&&v.open.publish({address:e.socket.address(),protocol:s,extensions:r}),a(e,o)}})}function O(e,t,n,l){if(!(m(e)||h(e)))if(!g(e))p(e,`Connection was closed before it was established.`),e[s]=r.CLOSING;else if(e[c]===i.NOT_SENT){e[c]=i.PROCESSING;let u=new T;t!==void 0&&n===void 0?(u.frameData=Buffer.allocUnsafe(2),u.frameData.writeUInt16BE(t,0)):t!==void 0&&n!==void 0?(u.frameData=Buffer.allocUnsafe(2+l),u.frameData.writeUInt16BE(t,0),u.frameData.write(n,2,`utf-8`)):u.frameData=a,e[d].socket.write(u.createFrame(o.CLOSE)),e[c]=i.SENT,e[s]=r.CLOSING}else e[s]=r.CLOSING}function k(e){this.ws[l].write(e)||this.pause()}function A(){let{ws:e}=this,{[d]:t}=e;t.socket.off(`data`,k),t.socket.off(`close`,A),t.socket.off(`error`,j);let n=e[c]===i.SENT&&e[u],a=1005,o=``,p=e[l].closingInfo;p&&!p.error?(a=p.code??1005,o=p.reason):e[u]||(a=1006),e[s]=r.CLOSED,f(`close`,e,(e,t)=>new y(e,t),{wasClean:n,code:a,reason:o}),v.close.hasSubscribers&&v.close.publish({websocket:e,code:a,reason:o})}function j(e){let{ws:t}=this;t[s]=r.CLOSING,v.socketError.hasSubscribers&&v.socketError.publish(e),this.destroy()}t.exports={establishWebSocketConnection:D,closeWebSocketConnection:O}})),dt=o(((e,t)=>{var{createInflateRaw:n,Z_DEFAULT_WINDOWBITS:r}=require(`node:zlib`),{isValidClientWindowBits:i}=ct(),{MessageSizeExceededError:a}=M(),o=Buffer.from([0,0,255,255]),s=Symbol(`kBuffer`),c=Symbol(`kLength`);t.exports={PerMessageDeflate:class{#e;#t={};#n=0;constructor(e,t){this.#t.serverNoContextTakeover=e.has(`server_no_context_takeover`),this.#t.serverMaxWindowBits=e.get(`server_max_window_bits`),this.#n=t.maxPayloadSize}decompress(e,t,l){if(!this.#e){let e=r;if(this.#t.serverMaxWindowBits){if(!i(this.#t.serverMaxWindowBits)){l(Error(`Invalid server_max_window_bits`));return}e=Number.parseInt(this.#t.serverMaxWindowBits)}try{this.#e=n({windowBits:e})}catch(e){l(e);return}this.#e[s]=[],this.#e[c]=0,this.#e.on(`data`,e=>{if(this.#e[c]+=e.length,this.#n>0&&this.#e[c]>this.#n){l(new a),this.#e.removeAllListeners(),this.#e=null;return}this.#e[s].push(e)}),this.#e.on(`error`,e=>{this.#e=null,l(e)})}this.#e.write(e),t&&this.#e.write(o),this.#e.flush(()=>{if(!this.#e)return;let e=Buffer.concat(this.#e[s],this.#e[c]);this.#e[s].length=0,this.#e[c]=0,l(null,e)})}}}})),ft=o(((e,t)=>{var{Writable:n}=require(`node:stream`),r=require(`node:assert`),{parserStates:i,opcodes:a,states:o,emptyBuffer:s,sentCloseFrameState:c}=ot(),{kReadyState:l,kSentClose:u,kResponse:d,kReceivedClose:f}=st(),{channels:p}=I(),{isValidStatusCode:m,isValidOpcode:h,failWebsocketConnection:g,websocketMessageReceived:_,utf8Decode:v,isControlFrame:y,isTextBinaryFrame:b,isContinuationFrame:x}=ct(),{WebsocketFrameSend:S}=lt(),{closeWebSocketConnection:C}=ut(),{PerMessageDeflate:w}=dt(),{MessageSizeExceededError:T}=M();t.exports={ByteParser:class extends n{#e=[];#t=0;#n=0;#r=!1;#i=i.INFO;#a={};#o=[];#s;#c;constructor(e,t,n={}){super(),this.ws=e,this.#s=t??new Map,this.#c=n.maxPayloadSize??0,this.#s.has(`permessage-deflate`)&&this.#s.set(`permessage-deflate`,new w(t,n))}_write(e,t,n){this.#e.push(e),this.#n+=e.length,this.#r=!0,this.run(n)}#l(){return this.#c>0&&!y(this.#a.opcode)&&this.#a.payloadLength>this.#c?(g(this.ws,`Payload size exceeds maximum allowed size`),!1):!0}run(e){for(;this.#r;)if(this.#i===i.INFO){if(this.#n<2)return e();let t=this.consume(2),n=(t[0]&128)!=0,r=t[0]&15,o=(t[1]&128)==128,s=!n&&r!==a.CONTINUATION,c=t[1]&127,l=t[0]&64,u=t[0]&32,d=t[0]&16;if(!h(r))return g(this.ws,`Invalid opcode received`),e();if(o)return g(this.ws,`Frame cannot be masked`),e();if(l!==0&&!this.#s.has(`permessage-deflate`)){g(this.ws,`Expected RSV1 to be clear.`);return}if(u!==0||d!==0){g(this.ws,`RSV1, RSV2, RSV3 must be clear`);return}if(s&&!b(r)){g(this.ws,`Invalid frame type was fragmented.`);return}if(b(r)&&this.#o.length>0){g(this.ws,`Expected continuation frame`);return}if(this.#a.fragmented&&s){g(this.ws,`Fragmented frame exceeded 125 bytes.`);return}if((c>125||s)&&y(r)){g(this.ws,`Control frame either too large or fragmented`);return}if(x(r)&&this.#o.length===0&&!this.#a.compressed){g(this.ws,`Unexpected continuation frame`);return}if(c<=125){if(this.#a.payloadLength=c,this.#i=i.READ_DATA,!this.#l())return}else c===126?this.#i=i.PAYLOADLENGTH_16:c===127&&(this.#i=i.PAYLOADLENGTH_64);b(r)&&(this.#a.binaryType=r,this.#a.compressed=l!==0),this.#a.opcode=r,this.#a.masked=o,this.#a.fin=n,this.#a.fragmented=s}else if(this.#i===i.PAYLOADLENGTH_16){if(this.#n<2)return e();let t=this.consume(2);if(this.#a.payloadLength=t.readUInt16BE(0),this.#i=i.READ_DATA,!this.#l())return}else if(this.#i===i.PAYLOADLENGTH_64){if(this.#n<8)return e();let t=this.consume(8),n=t.readUInt32BE(0),r=t.readUInt32BE(4);if(n!==0||r>2**31-1){g(this.ws,`Received payload length > 2^31 bytes.`);return}if(this.#a.payloadLength=r,this.#i=i.READ_DATA,!this.#l())return}else if(this.#i===i.READ_DATA){if(this.#n{if(t){g(this.ws,t.message);return}if(this.writeFragments(n),this.#c>0&&this.#t>this.#c){g(this.ws,new T().message);return}if(!this.#a.fin){this.#i=i.INFO,this.#r=!0,this.run(e);return}_(this.ws,this.#a.binaryType,this.consumeFragments()),this.#r=!0,this.#i=i.INFO,this.run(e)}),this.#r=!1;break}else{if(this.writeFragments(t),this.#c>0&&this.#t>this.#c){g(this.ws,new T().message);return}!this.#a.fragmented&&this.#a.fin&&_(this.ws,this.#a.binaryType,this.consumeFragments()),this.#i=i.INFO}}}consume(e){if(e>this.#n)throw Error(`Called consume() before buffers satiated.`);if(e===0)return s;if(this.#e[0].length===e)return this.#n-=this.#e[0].length,this.#e.shift();let t=Buffer.allocUnsafe(e),n=0;for(;n!==e;){let r=this.#e[0],{length:i}=r;if(i+n===e){t.set(this.#e.shift(),n);break}else if(i+n>e){t.set(r.subarray(0,e-n),n),this.#e[0]=r.subarray(e-n);break}else t.set(this.#e.shift(),n),n+=r.length}return this.#n-=e,t}writeFragments(e){this.#t+=e.length,this.#o.push(e)}consumeFragments(){let e=this.#o;if(e.length===1)return this.#t=0,e.shift();let t=Buffer.concat(e,this.#t);return this.#o=[],this.#t=0,t}parseCloseBody(e){r(e.length!==1);let t;if(e.length>=2&&(t=e.readUInt16BE(0)),t!==void 0&&!m(t))return{code:1002,reason:`Invalid status code`,error:!0};let n=e.subarray(2);n[0]===239&&n[1]===187&&n[2]===191&&(n=n.subarray(3));try{n=v(n)}catch{return{code:1007,reason:`Invalid UTF-8`,error:!0}}return{code:t,reason:n,error:!1}}parseControlFrame(e){let{opcode:t,payloadLength:n}=this.#a;if(t===a.CLOSE){if(n===1)return g(this.ws,`Received close frame with a 1-byte body.`),!1;if(this.#a.closeInfo=this.parseCloseBody(e),this.#a.closeInfo.error){let{code:e,reason:t}=this.#a.closeInfo;return C(this.ws,e,t,t.length),g(this.ws,t),!1}if(this.ws[u]!==c.SENT){let e=s;this.#a.closeInfo.code&&(e=Buffer.allocUnsafe(2),e.writeUInt16BE(this.#a.closeInfo.code,0));let t=new S(e);this.ws[d].socket.write(t.createFrame(a.CLOSE),e=>{e||(this.ws[u]=c.SENT)})}return this.ws[l]=o.CLOSING,this.ws[f]=!0,!1}else if(t===a.PING){if(!this.ws[f]){let t=new S(e);this.ws[d].socket.write(t.createFrame(a.PONG)),p.ping.hasSubscribers&&p.ping.publish({payload:e})}}else t===a.PONG&&p.pong.hasSubscribers&&p.pong.publish({payload:e});return!0}get closingInfo(){return this.#a.closeInfo}}}})),pt=o(((e,t)=>{var{WebsocketFrameSend:n}=lt(),{opcodes:r,sendHints:i}=ot(),a=ue(),o=Buffer[Symbol.species],s=class{#e=new a;#t=!1;#n;constructor(e){this.#n=e}add(e,t,n){if(n!==i.blob){let r=c(e,n);if(!this.#t)this.#n.write(r,t);else{let e={promise:null,callback:t,frame:r};this.#e.push(e)}return}let r={promise:e.arrayBuffer().then(e=>{r.promise=null,r.frame=c(e,n)}),callback:t,frame:null};this.#e.push(r),this.#t||this.#r()}async#r(){this.#t=!0;let e=this.#e;for(;!e.isEmpty();){let t=e.shift();t.promise!==null&&await t.promise,this.#n.write(t.frame,t.callback),t.callback=t.frame=null}this.#t=!1}};function c(e,t){return new n(l(e,t)).createFrame(t===i.string?r.TEXT:r.BINARY)}function l(e,t){switch(t){case i.string:return Buffer.from(e);case i.arrayBuffer:case i.blob:return new o(e);case i.typedArray:return new o(e.buffer,e.byteOffset,e.byteLength)}}t.exports={SendQueue:s}})),mt=o(((e,t)=>{var{webidl:n}=U(),{URLSerializer:r}=H(),{environmentSettingsObject:i}=W(),{staticPropertyDescriptors:a,states:o,sentCloseFrameState:s,sendHints:c}=ot(),{kWebSocketURL:l,kReadyState:u,kController:d,kBinaryType:f,kResponse:p,kSentClose:m,kByteParser:h}=st(),{isConnecting:g,isEstablished:_,isClosing:v,isValidSubprotocol:y,fireEvent:b}=ct(),{establishWebSocketConnection:x,closeWebSocketConnection:S}=ut(),{ByteParser:C}=ft(),{kEnumerableProperty:w,isBlobLike:T}=F(),{getGlobalDispatcher:E}=Fe(),{types:D}=require(`node:util`),{ErrorEvent:O,CloseEvent:k}=at(),{SendQueue:A}=pt(),j=class e extends EventTarget{#e={open:null,error:null,close:null,message:null};#t=0;#n=``;#r=``;#i;constructor(t,r=[]){super(),n.util.markAsUncloneable(this);let a=`WebSocket constructor`;n.argumentLengthCheck(arguments,1,a);let o=n.converters[`DOMString or sequence or WebSocketInit`](r,a,`options`);t=n.converters.USVString(t,a,`url`),r=o.protocols;let c=i.settingsObject.baseUrl,p;try{p=new URL(t,c)}catch(e){throw new DOMException(e,`SyntaxError`)}if(p.protocol===`http:`?p.protocol=`ws:`:p.protocol===`https:`&&(p.protocol=`wss:`),p.protocol!==`ws:`&&p.protocol!==`wss:`)throw new DOMException(`Expected a ws: or wss: protocol, got ${p.protocol}`,`SyntaxError`);if(p.hash||p.href.endsWith(`#`))throw new DOMException(`Got fragment`,`SyntaxError`);if(typeof r==`string`&&(r=[r]),r.length!==new Set(r.map(e=>e.toLowerCase())).size||r.length>0&&!r.every(e=>y(e)))throw new DOMException(`Invalid Sec-WebSocket-Protocol value`,`SyntaxError`);this[l]=new URL(p.href);let h=i.settingsObject;this[d]=x(p,r,h,this,(e,t)=>this.#a(e,t),o),this[u]=e.CONNECTING,this[m]=s.NOT_SENT,this[f]=`blob`}close(t=void 0,r=void 0){n.brandCheck(this,e);let i=`WebSocket.close`;if(t!==void 0&&(t=n.converters[`unsigned short`](t,i,`code`,{clamp:!0})),r!==void 0&&(r=n.converters.USVString(r,i,`reason`)),t!==void 0&&t!==1e3&&(t<3e3||t>4999))throw new DOMException(`invalid code`,`InvalidAccessError`);let a=0;if(r!==void 0&&(a=Buffer.byteLength(r),a>123))throw new DOMException(`Reason must be less than 123 bytes; received ${a}`,`SyntaxError`);S(this,t,r,a)}send(t){n.brandCheck(this,e);let r=`WebSocket.send`;if(n.argumentLengthCheck(arguments,1,r),t=n.converters.WebSocketSendData(t,r,`data`),g(this))throw new DOMException(`Sent before connected.`,`InvalidStateError`);if(!(!_(this)||v(this)))if(typeof t==`string`){let e=Buffer.byteLength(t);this.#t+=e,this.#i.add(t,()=>{this.#t-=e},c.string)}else D.isArrayBuffer(t)?(this.#t+=t.byteLength,this.#i.add(t,()=>{this.#t-=t.byteLength},c.arrayBuffer)):ArrayBuffer.isView(t)?(this.#t+=t.byteLength,this.#i.add(t,()=>{this.#t-=t.byteLength},c.typedArray)):T(t)&&(this.#t+=t.size,this.#i.add(t,()=>{this.#t-=t.size},c.blob))}get readyState(){return n.brandCheck(this,e),this[u]}get bufferedAmount(){return n.brandCheck(this,e),this.#t}get url(){return n.brandCheck(this,e),r(this[l])}get extensions(){return n.brandCheck(this,e),this.#r}get protocol(){return n.brandCheck(this,e),this.#n}get onopen(){return n.brandCheck(this,e),this.#e.open}set onopen(t){n.brandCheck(this,e),this.#e.open&&this.removeEventListener(`open`,this.#e.open),typeof t==`function`?(this.#e.open=t,this.addEventListener(`open`,t)):this.#e.open=null}get onerror(){return n.brandCheck(this,e),this.#e.error}set onerror(t){n.brandCheck(this,e),this.#e.error&&this.removeEventListener(`error`,this.#e.error),typeof t==`function`?(this.#e.error=t,this.addEventListener(`error`,t)):this.#e.error=null}get onclose(){return n.brandCheck(this,e),this.#e.close}set onclose(t){n.brandCheck(this,e),this.#e.close&&this.removeEventListener(`close`,this.#e.close),typeof t==`function`?(this.#e.close=t,this.addEventListener(`close`,t)):this.#e.close=null}get onmessage(){return n.brandCheck(this,e),this.#e.message}set onmessage(t){n.brandCheck(this,e),this.#e.message&&this.removeEventListener(`message`,this.#e.message),typeof t==`function`?(this.#e.message=t,this.addEventListener(`message`,t)):this.#e.message=null}get binaryType(){return n.brandCheck(this,e),this[f]}set binaryType(t){n.brandCheck(this,e),t!==`blob`&&t!==`arraybuffer`?this[f]=`blob`:this[f]=t}#a(e,t){this[p]=e;let n=this[d]?.dispatcher?.webSocketOptions?.maxPayloadSize,r=new C(this,t,{maxPayloadSize:n});r.on(`drain`,M),r.on(`error`,N.bind(this)),e.socket.ws=this,this[h]=r,this.#i=new A(e.socket),this[u]=o.OPEN;let i=e.headersList.get(`sec-websocket-extensions`);i!==null&&(this.#r=i);let a=e.headersList.get(`sec-websocket-protocol`);a!==null&&(this.#n=a),b(`open`,this)}};j.CONNECTING=j.prototype.CONNECTING=o.CONNECTING,j.OPEN=j.prototype.OPEN=o.OPEN,j.CLOSING=j.prototype.CLOSING=o.CLOSING,j.CLOSED=j.prototype.CLOSED=o.CLOSED,Object.defineProperties(j.prototype,{CONNECTING:a,OPEN:a,CLOSING:a,CLOSED:a,url:w,readyState:w,bufferedAmount:w,onopen:w,onerror:w,onclose:w,close:w,onmessage:w,binaryType:w,send:w,extensions:w,protocol:w,[Symbol.toStringTag]:{value:`WebSocket`,writable:!1,enumerable:!1,configurable:!0}}),Object.defineProperties(j,{CONNECTING:a,OPEN:a,CLOSING:a,CLOSED:a}),n.converters[`sequence`]=n.sequenceConverter(n.converters.DOMString),n.converters[`DOMString or sequence`]=function(e,t,r){return n.util.Type(e)===`Object`&&Symbol.iterator in e?n.converters[`sequence`](e):n.converters.DOMString(e,t,r)},n.converters.WebSocketInit=n.dictionaryConverter([{key:`protocols`,converter:n.converters[`DOMString or sequence`],defaultValue:()=>[]},{key:`dispatcher`,converter:n.converters.any,defaultValue:()=>E()},{key:`headers`,converter:n.nullableConverter(n.converters.HeadersInit)}]),n.converters[`DOMString or sequence or WebSocketInit`]=function(e){return n.util.Type(e)===`Object`&&!(Symbol.iterator in e)?n.converters.WebSocketInit(e):{protocols:n.converters[`DOMString or sequence`](e)}},n.converters.WebSocketSendData=function(e){if(n.util.Type(e)===`Object`){if(T(e))return n.converters.Blob(e,{strict:!1});if(ArrayBuffer.isView(e)||D.isArrayBuffer(e))return n.converters.BufferSource(e)}return n.converters.USVString(e)};function M(){this.ws[p].socket.resume()}function N(e){let t,n;e instanceof k?(t=e.reason,n=e.code):t=e.message,b(`error`,this,()=>new O(`error`,{error:e,message:t})),S(this,n)}t.exports={WebSocket:j}})),ht=o(((e,t)=>{function n(e){return e.indexOf(`\0`)===-1}function r(e){if(e.length===0)return!1;for(let t=0;t57)return!1;return!0}function i(e){return new Promise(t=>{setTimeout(t,e).unref()})}t.exports={isValidLastEventId:n,isASCIINumber:r,delay:i}})),gt=o(((e,t)=>{var{Transform:n}=require(`node:stream`),{isASCIINumber:r,isValidLastEventId:i}=ht(),a=[239,187,191],o=10,s=13,c=58,l=32;t.exports={EventSourceStream:class extends n{state=null;checkBOM=!0;crlfCheck=!1;eventEndCheck=!1;buffer=null;pos=0;event={data:void 0,event:void 0,id:void 0,retry:void 0};constructor(e={}){e.readableObjectMode=!0,super(e),this.state=e.eventSourceSettings||{},e.push&&(this.push=e.push)}_transform(e,t,n){if(e.length===0){n();return}if(this.buffer?this.buffer=Buffer.concat([this.buffer,e]):this.buffer=e,this.checkBOM)switch(this.buffer.length){case 1:if(this.buffer[0]===a[0]){n();return}this.checkBOM=!1,n();return;case 2:if(this.buffer[0]===a[0]&&this.buffer[1]===a[1]){n();return}this.checkBOM=!1;break;case 3:if(this.buffer[0]===a[0]&&this.buffer[1]===a[1]&&this.buffer[2]===a[2]){this.buffer=Buffer.alloc(0),this.checkBOM=!1,n();return}this.checkBOM=!1;break;default:this.buffer[0]===a[0]&&this.buffer[1]===a[1]&&this.buffer[2]===a[2]&&(this.buffer=this.buffer.subarray(3)),this.checkBOM=!1;break}for(;this.pos0&&(t[a]=o);break}}processEvent(e){e.retry&&r(e.retry)&&(this.state.reconnectionTime=parseInt(e.retry,10)),e.id&&i(e.id)&&(this.state.lastEventId=e.id),e.data!==void 0&&this.push({type:e.event||`message`,options:{data:e.data,lastEventId:this.state.lastEventId,origin:this.state.origin}})}clearEvent(){this.event={data:void 0,event:void 0,id:void 0,retry:void 0}}}}})),_t=o(((e,t)=>{var{pipeline:n}=require(`node:stream`),{fetching:r}=Ge(),{makeRequest:i}=We(),{webidl:a}=U(),{EventSourceStream:o}=gt(),{parseMIMEType:s}=H(),{createFastMessageEvent:c}=at(),{isNetworkError:l}=He(),{delay:u}=ht(),{kEnumerableProperty:d}=F(),{environmentSettingsObject:f}=W(),p=!1,m=3e3,h=0,g=1,_=2,v=`anonymous`,y=`use-credentials`,b=class e extends EventTarget{#e={open:null,error:null,message:null};#t=null;#n=!1;#r=h;#i=null;#a=null;#o;#s;constructor(e,t={}){super(),a.util.markAsUncloneable(this);let n=`EventSource constructor`;a.argumentLengthCheck(arguments,1,n),p||(p=!0,process.emitWarning(`EventSource is experimental, expect them to change at any time.`,{code:`UNDICI-ES`})),e=a.converters.USVString(e,n,`url`),t=a.converters.EventSourceInitDict(t,n,`eventSourceInitDict`),this.#o=t.dispatcher,this.#s={lastEventId:``,reconnectionTime:m};let r=f,o;try{o=new URL(e,r.settingsObject.baseUrl),this.#s.origin=o.origin}catch(e){throw new DOMException(e,`SyntaxError`)}this.#t=o.href;let s=v;t.withCredentials&&(s=y,this.#n=!0);let c={redirect:`follow`,keepalive:!0,mode:`cors`,credentials:s===`anonymous`?`same-origin`:`omit`,referrer:`no-referrer`};c.client=f.settingsObject,c.headersList=[[`accept`,{name:`accept`,value:`text/event-stream`}]],c.cache=`no-store`,c.initiator=`other`,c.urlList=[new URL(this.#t)],this.#i=i(c),this.#c()}get readyState(){return this.#r}get url(){return this.#t}get withCredentials(){return this.#n}#c(){if(this.#r===_)return;this.#r=h;let e={request:this.#i,dispatcher:this.#o};e.processResponseEndOfBody=e=>{l(e)&&(this.dispatchEvent(new Event(`error`)),this.close()),this.#l()},e.processResponse=e=>{if(l(e))if(e.aborted){this.close(),this.dispatchEvent(new Event(`error`));return}else{this.#l();return}let t=e.headersList.get(`content-type`,!0),r=t===null?`failure`:s(t),i=r!==`failure`&&r.essence===`text/event-stream`;if(e.status!==200||i===!1){this.close(),this.dispatchEvent(new Event(`error`));return}this.#r=g,this.dispatchEvent(new Event(`open`)),this.#s.origin=e.urlList[e.urlList.length-1].origin;let a=new o({eventSourceSettings:this.#s,push:e=>{this.dispatchEvent(c(e.type,e.options))}});n(e.body.stream,a,e=>{e?.aborted===!1&&(this.close(),this.dispatchEvent(new Event(`error`)))})},this.#a=r(e)}async#l(){this.#r!==_&&(this.#r=h,this.dispatchEvent(new Event(`error`)),await u(this.#s.reconnectionTime),this.#r===h&&(this.#s.lastEventId.length&&this.#i.headersList.set(`last-event-id`,this.#s.lastEventId,!0),this.#c()))}close(){a.brandCheck(this,e),this.#r!==_&&(this.#r=_,this.#a.abort(),this.#i=null)}get onopen(){return this.#e.open}set onopen(e){this.#e.open&&this.removeEventListener(`open`,this.#e.open),typeof e==`function`?(this.#e.open=e,this.addEventListener(`open`,e)):this.#e.open=null}get onmessage(){return this.#e.message}set onmessage(e){this.#e.message&&this.removeEventListener(`message`,this.#e.message),typeof e==`function`?(this.#e.message=e,this.addEventListener(`message`,e)):this.#e.message=null}get onerror(){return this.#e.error}set onerror(e){this.#e.error&&this.removeEventListener(`error`,this.#e.error),typeof e==`function`?(this.#e.error=e,this.addEventListener(`error`,e)):this.#e.error=null}},x={CONNECTING:{__proto__:null,configurable:!1,enumerable:!0,value:h,writable:!1},OPEN:{__proto__:null,configurable:!1,enumerable:!0,value:g,writable:!1},CLOSED:{__proto__:null,configurable:!1,enumerable:!0,value:_,writable:!1}};Object.defineProperties(b,x),Object.defineProperties(b.prototype,x),Object.defineProperties(b.prototype,{close:d,onerror:d,onmessage:d,onopen:d,readyState:d,url:d,withCredentials:d}),a.converters.EventSourceInitDict=a.dictionaryConverter([{key:`withCredentials`,converter:a.converters.boolean,defaultValue:()=>!1},{key:`dispatcher`,converter:a.converters.any}]),t.exports={EventSource:b,defaultReconnectionTime:m}})),vt=o(((e,t)=>{var n=X(),r=R(),i=pe(),a=Z(),o=Q(),s=me(),c=$(),l=ge(),u=M(),d=F(),{InvalidArgumentError:f}=u,p=Te(),m=V(),h=Ae(),g=Pe(),_=je(),v=Ee(),y=he(),{getGlobalDispatcher:b,setGlobalDispatcher:x}=Fe(),S=Ie(),C=ce(),w=le();Object.assign(r.prototype,p),t.exports.Dispatcher=r,t.exports.Client=n,t.exports.Pool=i,t.exports.BalancedPool=a,t.exports.Agent=o,t.exports.ProxyAgent=s,t.exports.EnvHttpProxyAgent=c,t.exports.RetryAgent=l,t.exports.RetryHandler=y,t.exports.DecoratorHandler=S,t.exports.RedirectHandler=C,t.exports.createRedirectInterceptor=w,t.exports.interceptors={redirect:Le(),retry:Re(),dump:ze(),dns:Be()},t.exports.buildConnector=m,t.exports.errors=u,t.exports.util={parseHeaders:d.parseHeaders,headerNameToString:d.headerNameToString};function T(e){return(t,n,r)=>{if(typeof n==`function`&&(r=n,n=null),!t||typeof t!=`string`&&typeof t!=`object`&&!(t instanceof URL))throw new f(`invalid url`);if(n!=null&&typeof n!=`object`)throw new f(`invalid opts`);if(n&&n.path!=null){if(typeof n.path!=`string`)throw new f(`invalid opts.path`);let e=n.path;n.path.startsWith(`/`)||(e=`/${e}`),t=new URL(d.parseOrigin(t).origin+e)}else n||=typeof t==`object`?t:{},t=d.parseURL(t);let{agent:i,dispatcher:a=b()}=n;if(i)throw new f(`unsupported opts.agent. Did you mean opts.client?`);return e.call(a,{...n,origin:t.origin,path:t.search?`${t.pathname}${t.search}`:t.pathname,method:n.method||(n.body?`PUT`:`GET`)},r)}}t.exports.setGlobalDispatcher=x,t.exports.getGlobalDispatcher=b;var E=Ge().fetch;t.exports.fetch=async function(e,t=void 0){try{return await E(e,t)}catch(e){throw e&&typeof e==`object`&&Error.captureStackTrace(e),e}},t.exports.Headers=Ve().Headers,t.exports.Response=He().Response,t.exports.Request=We().Request,t.exports.FormData=q().FormData,t.exports.File=globalThis.File??require(`node:buffer`).File,t.exports.FileReader=Xe().FileReader;var{setGlobalOrigin:D,getGlobalOrigin:O}=ae();t.exports.setGlobalOrigin=D,t.exports.getGlobalOrigin=O;var{CacheStorage:k}=et(),{kConstruct:A}=Ze();t.exports.caches=new k(A);var{deleteCookie:j,getCookies:N,getSetCookies:P,setCookie:I}=it();t.exports.deleteCookie=j,t.exports.getCookies=N,t.exports.getSetCookies=P,t.exports.setCookie=I;var{parseMIMEType:L,serializeAMimeType:z}=H();t.exports.parseMIMEType=L,t.exports.serializeAMimeType=z;var{CloseEvent:B,ErrorEvent:ee,MessageEvent:te}=at();t.exports.WebSocket=mt().WebSocket,t.exports.CloseEvent=B,t.exports.ErrorEvent=ee,t.exports.MessageEvent=te,t.exports.request=T(p.request),t.exports.stream=T(p.stream),t.exports.pipeline=T(p.pipeline),t.exports.connect=T(p.connect),t.exports.upgrade=T(p.upgrade),t.exports.MockClient=h,t.exports.MockPool=_,t.exports.MockAgent=g,t.exports.mockErrors=v;var{EventSource:ne}=_t();t.exports.EventSource=ne}));A(),vt();var yt;(function(e){e[e.OK=200]=`OK`,e[e.MultipleChoices=300]=`MultipleChoices`,e[e.MovedPermanently=301]=`MovedPermanently`,e[e.ResourceMoved=302]=`ResourceMoved`,e[e.SeeOther=303]=`SeeOther`,e[e.NotModified=304]=`NotModified`,e[e.UseProxy=305]=`UseProxy`,e[e.SwitchProxy=306]=`SwitchProxy`,e[e.TemporaryRedirect=307]=`TemporaryRedirect`,e[e.PermanentRedirect=308]=`PermanentRedirect`,e[e.BadRequest=400]=`BadRequest`,e[e.Unauthorized=401]=`Unauthorized`,e[e.PaymentRequired=402]=`PaymentRequired`,e[e.Forbidden=403]=`Forbidden`,e[e.NotFound=404]=`NotFound`,e[e.MethodNotAllowed=405]=`MethodNotAllowed`,e[e.NotAcceptable=406]=`NotAcceptable`,e[e.ProxyAuthenticationRequired=407]=`ProxyAuthenticationRequired`,e[e.RequestTimeout=408]=`RequestTimeout`,e[e.Conflict=409]=`Conflict`,e[e.Gone=410]=`Gone`,e[e.TooManyRequests=429]=`TooManyRequests`,e[e.InternalServerError=500]=`InternalServerError`,e[e.NotImplemented=501]=`NotImplemented`,e[e.BadGateway=502]=`BadGateway`,e[e.ServiceUnavailable=503]=`ServiceUnavailable`,e[e.GatewayTimeout=504]=`GatewayTimeout`})(yt||={});var bt;(function(e){e.Accept=`accept`,e.ContentType=`content-type`})(bt||={});var xt;(function(e){e.ApplicationJson=`application/json`})(xt||={}),yt.MovedPermanently,yt.ResourceMoved,yt.SeeOther,yt.TemporaryRedirect,yt.PermanentRedirect,yt.BadGateway,yt.ServiceUnavailable,yt.GatewayTimeout;var St=function(e,t,n,r){function i(e){return e instanceof n?e:new n(function(t){t(e)})}return new(n||=Promise)(function(n,a){function o(e){try{c(r.next(e))}catch(e){a(e)}}function s(e){try{c(r.throw(e))}catch(e){a(e)}}function c(e){e.done?n(e.value):i(e.value).then(o,s)}c((r=r.apply(e,t||[])).next())})},{access:Ct,appendFile:wt,writeFile:Tt}=p.promises,Et=`GITHUB_STEP_SUMMARY`;new class{constructor(){this._buffer=``}filePath(){return St(this,void 0,void 0,function*(){if(this._filePath)return this._filePath;let e=process.env[Et];if(!e)throw Error(`Unable to find environment variable for $${Et}. Check if your runtime environment supports job summaries.`);try{yield Ct(e,p.constants.R_OK|p.constants.W_OK)}catch{throw Error(`Unable to access summary file: '${e}'. Check if the file has correct read/write permissions.`)}return this._filePath=e,this._filePath})}wrap(e,t,n={}){let r=Object.entries(n).map(([e,t])=>` ${e}="${t}"`).join(``);return t?`<${e}${r}>${t}`:`<${e}${r}>`}write(e){return St(this,void 0,void 0,function*(){let t=!!e?.overwrite,n=yield this.filePath();return yield(t?Tt:wt)(n,this._buffer,{encoding:`utf8`}),this.emptyBuffer()})}clear(){return St(this,void 0,void 0,function*(){return this.emptyBuffer().write({overwrite:!0})})}stringify(){return this._buffer}isEmptyBuffer(){return this._buffer.length===0}emptyBuffer(){return this._buffer=``,this}addRaw(e,t=!1){return this._buffer+=e,t?this.addEOL():this}addEOL(){return this.addRaw(d.EOL)}addCodeBlock(e,t){let n=Object.assign({},t&&{lang:t}),r=this.wrap(`pre`,this.wrap(`code`,e),n);return this.addRaw(r).addEOL()}addList(e,t=!1){let n=t?`ol`:`ul`,r=e.map(e=>this.wrap(`li`,e)).join(``),i=this.wrap(n,r);return this.addRaw(i).addEOL()}addTable(e){let t=e.map(e=>{let t=e.map(e=>{if(typeof e==`string`)return this.wrap(`td`,e);let{header:t,data:n,colspan:r,rowspan:i}=e,a=t?`th`:`td`,o=Object.assign(Object.assign({},r&&{colspan:r}),i&&{rowspan:i});return this.wrap(a,n,o)}).join(``);return this.wrap(`tr`,t)}).join(``),n=this.wrap(`table`,t);return this.addRaw(n).addEOL()}addDetails(e,t){let n=this.wrap(`details`,this.wrap(`summary`,e)+t);return this.addRaw(n).addEOL()}addImage(e,t,n){let{width:r,height:i}=n||{},a=Object.assign(Object.assign({},r&&{width:r}),i&&{height:i}),o=this.wrap(`img`,null,Object.assign({src:e,alt:t},a));return this.addRaw(o).addEOL()}addHeading(e,t){let n=`h${t}`,r=[`h1`,`h2`,`h3`,`h4`,`h5`,`h6`].includes(n)?n:`h1`,i=this.wrap(r,e);return this.addRaw(i).addEOL()}addSeparator(){let e=this.wrap(`hr`,null);return this.addRaw(e).addEOL()}addBreak(){let e=this.wrap(`br`,null);return this.addRaw(e).addEOL()}addQuote(e,t){let n=Object.assign({},t&&{cite:t}),r=this.wrap(`blockquote`,e,n);return this.addRaw(r).addEOL()}addLink(e,t){let n=this.wrap(`a`,e,{href:t});return this.addRaw(n).addEOL()}};var Dt=function(e,t,n,r){function i(e){return e instanceof n?e:new n(function(t){t(e)})}return new(n||=Promise)(function(n,a){function o(e){try{c(r.next(e))}catch(e){a(e)}}function s(e){try{c(r.throw(e))}catch(e){a(e)}}function c(e){e.done?n(e.value):i(e.value).then(o,s)}c((r=r.apply(e,t||[])).next())})},{chmod:Ot,copyFile:kt,lstat:At,mkdir:jt,open:Mt,readdir:Nt,rename:Pt,rm:Ft,rmdir:It,stat:Lt,symlink:Rt,unlink:zt}=p.promises,Bt=process.platform===`win32`;p.constants.O_RDONLY;function Vt(e){if(e=Ut(e),!e)throw Error(`isRooted() parameter "p" cannot be empty`);return Bt?e.startsWith(`\\`)||/^[A-Z]:/i.test(e):e.startsWith(`/`)}function Ht(e,t){return Dt(this,void 0,void 0,function*(){let n;try{n=yield Lt(e)}catch(t){t.code!==`ENOENT`&&console.log(`Unexpected error attempting to determine if executable file exists '${e}': ${t}`)}if(n&&n.isFile()){if(Bt){let n=m.extname(e).toUpperCase();if(t.some(e=>e.toUpperCase()===n))return e}else if(Wt(n))return e}let r=e;for(let i of t){e=r+i,n=void 0;try{n=yield Lt(e)}catch(t){t.code!==`ENOENT`&&console.log(`Unexpected error attempting to determine if executable file exists '${e}': ${t}`)}if(n&&n.isFile()){if(Bt){try{let t=m.dirname(e),n=m.basename(e).toUpperCase();for(let r of yield Nt(t))if(n===r.toUpperCase()){e=m.join(t,r);break}}catch(t){console.log(`Unexpected error attempting to determine the actual case of the file '${e}': ${t}`)}return e}else if(Wt(n))return e}}return``})}function Ut(e){return e||=``,Bt?(e=e.replace(/\//g,`\\`),e.replace(/\\\\+/g,`\\`)):e.replace(/\/\/+/g,`/`)}function Wt(e){return(e.mode&1)>0||(e.mode&8)>0&&process.getgid!==void 0&&e.gid===process.getgid()||(e.mode&64)>0&&process.getuid!==void 0&&e.uid===process.getuid()}var Gt=function(e,t,n,r){function i(e){return e instanceof n?e:new n(function(t){t(e)})}return new(n||=Promise)(function(n,a){function o(e){try{c(r.next(e))}catch(e){a(e)}}function s(e){try{c(r.throw(e))}catch(e){a(e)}}function c(e){e.done?n(e.value):i(e.value).then(o,s)}c((r=r.apply(e,t||[])).next())})};function Kt(e,t){return Gt(this,void 0,void 0,function*(){if(!e)throw Error(`parameter 'tool' is required`);if(t){let t=yield Kt(e,!1);if(!t)throw Error(Bt?`Unable to locate executable file: ${e}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also verify the file has a valid extension for an executable file.`:`Unable to locate executable file: ${e}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also check the file mode to verify the file is executable.`);return t}let n=yield qt(e);return n&&n.length>0?n[0]:``})}function qt(e){return Gt(this,void 0,void 0,function*(){if(!e)throw Error(`parameter 'tool' is required`);let t=[];if(Bt&&process.env.PATHEXT)for(let e of process.env.PATHEXT.split(m.delimiter))e&&t.push(e);if(Vt(e)){let n=yield Ht(e,t);return n?[n]:[]}if(e.includes(m.sep))return[];let n=[];if(process.env.PATH)for(let e of process.env.PATH.split(m.delimiter))e&&n.push(e);let r=[];for(let i of n){let n=yield Ht(m.join(i,e),t);n&&r.push(n)}return r})}process.platform,h.EventEmitter,h.EventEmitter,d.default.platform(),d.default.arch();var Jt;(function(e){e[e.Success=0]=`Success`,e[e.Failure=1]=`Failure`})(Jt||={});function Yt(e,t){let n=process.env[`INPUT_${e.replace(/ /g,`_`).toUpperCase()}`]||``;if(t&&t.required&&!n)throw Error(`Input required and not supplied: ${e}`);return t&&t.trimWhitespace===!1?n:n.trim()}function Xt(e,t){let n=Yt(e,t).split(` -`).filter(e=>e!==``);return t&&t.trimWhitespace===!1?n:n.map(e=>e.trim())}function Zt(e,t){let n=[`true`,`True`,`TRUE`],r=[`false`,`False`,`FALSE`],i=Yt(e,t);if(n.includes(i))return!0;if(r.includes(i))return!1;throw TypeError(`Input does not meet YAML 1.2 "Core Schema" specification: ${e}\nSupport boolean input list: \`true | True | TRUE | false | False | FALSE\``)}function Qt(e,t){if(process.env.GITHUB_OUTPUT)return D(`OUTPUT`,O(e,t));process.stdout.write(d.EOL),S(`set-output`,{name:e},b(t))}function $t(e){process.exitCode=Jt.Failure,en(e)}function en(e,t={}){S(`error`,x(t),e instanceof Error?e.toString():e)}function tn(e,t={}){S(`warning`,x(t),e instanceof Error?e.toString():e)}function nn(e){process.stdout.write(e+d.EOL)}var rn=``;function an(e){let t=e<0?`-`:``,n=Math.abs(e);return n<1024?`${t}${n} B`:`${t}${(n/1024).toFixed(1)} KiB`}function on(e,t){let n=an(e);return t===null?n:`${n} (${t>0?`+`:``}${t.toFixed(2)}%)`}function sn(e){return e.replace(/\\/g,`\\\\`).replace(/\|/g,`\\|`)}function cn(e){let t=sn(e),n=t.match(/`+/g)??[],r=Math.max(0,...n.map(e=>e.length))+1,i="`".repeat(r),a=t.startsWith("`")||t.endsWith("`")?` `:``;return`${i}${a}${t}${a}${i}`}function ln(e){return e===null?`⚪`:e<=1?`🟢`:e<=3?`🔵`:e<=6?`🟡`:e<=9?`🟠`:`🔴`}function un(e){return`| ${cn(e.path)} | ${an(e.baselineBytes)} | ${an(e.currentBytes)} | ${on(e.deltaBytes,e.deltaPercent)} | ${ln(e.deltaPercent)} |`}function dn(e){let t=e.latest?` latest`:``;return`${cn(e.version)}${t}`}function fn(e){if(!e.totals){let t=e.missingFiles.map(cn).join(`, `);return`| ${dn(e)} | n/a | n/a | Incomplete: missing ${t} | ⚪ |`}return`| ${dn(e)} | ${an(e.totals.baselineBytes)} | ${an(e.totals.currentBytes)} | ${on(e.totals.deltaBytes,e.totals.deltaPercent)} | ${ln(e.totals.deltaPercent)} |`}function pn(e){return e.releaseStream===void 0?`Compared current build against latest npm release ${cn(e.baseline.version)} for ${cn(e.packageName)}.`:`Compared current build against ${cn(`${e.releaseStream}.x`)} release stream baseline ${cn(e.baseline.version)} for ${cn(e.packageName)}.`}function mn(e){return e.releaseStream===void 0?`Historical comparison: latest + 10 previous npm releases`:`Historical comparison: ${e.releaseStream}.x release stream baselines`}function hn(e){let t=e.files.map(un);return t.push(`| **Total** | **${an(e.totals.baselineBytes)}** | **${an(e.totals.currentBytes)}** | **${on(e.totals.deltaBytes,e.totals.deltaPercent)}** | **${ln(e.totals.deltaPercent)}** |`),[rn,``,`## Bundle Size Report`,``,pn(e),``,`| File | Baseline gzip | Current gzip | Difference | Status |`,`|---|---:|---:|---:|:---:|`,...t,``,`
`,`${mn(e)}`,``,`| Release | Baseline gzip | Current gzip | Difference | Status |`,`|---|---:|---:|---:|:---:|`,...e.history.map(fn),``,`
`].join(` -`)}function gn(e){let t=e.trim().replace(/\\/g,`/`);if(/^[A-Za-z]:\//.test(t)||t.startsWith(`//`))throw Error(`Configured file path must be relative and stay inside the project: ${e}`);let n=l.default.posix.normalize(t);if(!n||n===`.`)throw Error(`Configured file paths must not be empty.`);if(n.startsWith(`/`)||n===`..`||n.startsWith(`../`))throw Error(`Configured file path must be relative and stay inside the project: ${e}`);return n}function _n(e){let t=e.split(/\r?\n/).map(e=>e.trim()).filter(Boolean).map(gn);if(t.length===0)throw Error(`At least one file path must be provided via the files input.`);return[...new Set(t)]}function vn(e,t){let n=l.default.resolve(e),r=l.default.resolve(n,t),i=l.default.relative(n,r);if(i===``||i===`..`||i.startsWith(`..${l.default.sep}`)||l.default.isAbsolute(i))throw Error(`Path must stay inside the project root: ${t}`);return r}var yn=(0,g.promisify)(_.gzip);async function bn(e){return(await yn(e,{level:_.constants.Z_BEST_COMPRESSION})).length}function xn(e,t){return t===0?null:Number(((e-t)/t*100).toFixed(2))}async function Sn(e,t,n,r,i){let[a]=r;if(!a)throw Error(`At least one npm release baseline is required.`);let o=[];for(let t of r)o.push(await Cn(e,n,t,t.latest));let[s]=o;if(!s.totals)throw Error(`Primary release comparison is incomplete: ${a.version}`);return{metric:`gzip`,packageName:t,releaseStream:i,baseline:{version:a.version,uri:a.uri},localRoot:e,files:s.files,totals:s.totals,history:o}}async function Cn(e,t,n,r){let i=[],a=[];for(let o of t){let t=n.files.get(o);if(!t){if(r)throw Error(`Baseline file not found in primary release ${n.version}: ${o}`);a.push(o);continue}let s=vn(e,o),c;try{c=await(0,y.readFile)(s)}catch(e){throw Error(`Local file not found: ${o} (${e instanceof Error?e.message:String(e)})`)}let l=await bn(t),u=await bn(c),d=u-l;i.push({path:o,baselineBytes:l,currentBytes:u,deltaBytes:d,deltaPercent:xn(u,l)})}let o=i.reduce((e,t)=>e+t.baselineBytes,0),s=i.reduce((e,t)=>e+t.currentBytes,0),c=a.length>0?null:{baselineBytes:o,currentBytes:s,deltaBytes:s-o,deltaPercent:xn(s,o)};return{version:n.version,uri:n.uri,latest:n.latest,complete:a.length===0,missingFiles:a,files:i,totals:c}}function wn(e){let t=e.trim();if(!t)throw Error(`The package-name input is required.`);if(/\s/.test(t)||t.includes(`:`))throw Error(`Invalid npm package name: ${e}`);if(t.startsWith(`@`)){let n=t.split(`/`);if(n.length!==2||!n[0].slice(1)||!n[1])throw Error(`Invalid npm package name: ${e}`);return t}if(t.includes(`/`))throw Error(`Invalid npm package name: ${e}`);return t}function Tn(e){let t=e.trim();if(t){if(!/^\d+$/.test(t))throw Error(`Invalid release-stream input: ${e}`);return Number(t)}}function En(){let e=l.default.resolve(Yt(`path`,{required:!1})||`.`),t=wn(Yt(`package-name`,{required:!0})),n=Tn(Yt(`release-stream`,{required:!1})),r=Xt(`files`,{required:!0}).join(` -`),i=gn(Yt(`output-file`,{required:!1})||`bundle-size-comparison.json`),a=Zt(`comment-pr`,{required:!1}),o=Yt(`github-token`,{required:!1});if(a&&!o)throw Error(`The github-token input is required when comment-pr is enabled.`);return{localRoot:e,packageName:t,releaseStream:n,filePaths:_n(r),outputFile:i,commentPr:a,githubToken:o}}var Dn=`https://registry.npmjs.org`,On=10;function kn(e){return`${Dn}/${encodeURIComponent(e)}`}function An(e){return!e.includes(`-`)}function jn(e){let t=/^(\d+)\./.exec(e);return t?Number(t[1]):null}function Mn(e,t,n){let r=n.versions?.[t]?.dist?.tarball;if(typeof r!=`string`||!r.trim())throw Error(`Npm package ${e} version ${t} is missing a tarball URL.`);let i;try{i=new URL(r)}catch{throw Error(`Npm package ${e} version ${t} has an invalid tarball URL.`)}if(i.protocol!==`http:`&&i.protocol!==`https:`)throw Error(`Npm package ${e} version ${t} has an unsupported tarball URL protocol: ${i.protocol}`);return r}function Nn(e,t,n){let r=n.time?.[t],i=r?Date.parse(r):NaN;if(Number.isNaN(i))throw Error(`Npm package ${e} version ${t} is missing publish time metadata.`);return i}function Pn(e,t,n){if(n!==void 0){let r=Object.keys(t.versions??{}).filter(e=>An(e)&&jn(e)===n).map(n=>({version:n,publishedAt:Nn(e,n,t)})).sort((e,t)=>t.publishedAt-e.publishedAt).slice(0,On+1).map(e=>e.version);if(r.length===0)throw Error(`Npm package ${e} has no stable releases in release stream ${n}.`);return r.map((n,r)=>({version:n,uri:Mn(e,n,t),latest:r===0}))}let r=t[`dist-tags`]?.latest;if(typeof r!=`string`||!r||!t.versions?.[r])throw Error(`Npm package ${e} does not define a usable latest release.`);let i=Nn(e,r,t);return[r,...Object.keys(t.versions).filter(e=>e!==r&&An(e)).map(n=>({version:n,publishedAt:Nn(e,n,t)})).filter(e=>e.publishedAtt.publishedAt-e.publishedAt).slice(0,On).map(e=>e.version)].map((n,r)=>({version:n,uri:Mn(e,n,t),latest:r===0}))}async function Fn(e,t){let n=kn(e),r;try{r=await fetch(n)}catch(t){throw Error(`Failed to fetch npm metadata for ${e}: ${t instanceof Error?t.message:String(t)}`)}if(!r.ok)throw Error(`Failed to fetch npm metadata for ${e}: HTTP ${r.status} ${r.statusText}`);let i;try{i=await r.json()}catch(t){throw Error(`Failed to parse npm metadata for ${e}: ${t instanceof Error?t.message:String(t)}`)}return Pn(e,i,t)}var In=class extends Error{status;constructor(e,t){super(e),this.name=`GitHubApiError`,this.status=t}};async function Ln(){let e=process.env.GITHUB_EVENT_PATH;if(!e)return null;let t=JSON.parse(await(0,y.readFile)(e,`utf8`)),n=t.pull_request?.number??t.number;return typeof n==`number`?n:null}function Rn(){let e=process.env.GITHUB_REPOSITORY;if(!e)throw Error(`GITHUB_REPOSITORY is required to post a pull request comment.`);let[t,n]=e.split(`/`);if(!t||!n)throw Error(`Invalid GITHUB_REPOSITORY value: ${e}`);return{owner:t,repo:n}}async function zn(e){try{let t=await e.json();return t.message?`: ${t.message}`:``}catch{return``}}function Bn(e){if(!e)return null;for(let t of e.split(`,`))if(t.includes(`rel="next"`))return/<([^>]+)>/.exec(t)?.[1]??null;return null}async function Vn(e,t,n,r){let i=await fetch(n,{method:t,headers:{accept:`application/vnd.github+json`,authorization:`Bearer ${e}`,"content-type":`application/json`,"user-agent":`axios-bundle-size-action`,"x-github-api-version":`2022-11-28`},body:r===void 0?void 0:JSON.stringify(r)});if(!i.ok){let e=await zn(i),t=i.status===401||i.status===403?` Check that github-token has permission to write pull request or issue comments.`:``;throw new In(`GitHub comments API request failed (${i.status} ${i.statusText})${e}.${t}`,i.status)}return{body:await i.json(),nextUrl:Bn(i.headers.get(`link`))}}async function Hn(e,t,n,r){return(await Vn(e,t,n,r)).body}function Un(e){return e.body?.includes(rn)===!0}async function Wn(e,t){let n=t;for(;n;){let t=await Vn(e,`GET`,n),r=t.body.find(Un);if(r)return r;n=t.nextUrl}}async function Gn(e,t){let n=await Ln();if(n===null){nn(`Skipping bundle size PR comment because this run is not for a pull request.`);return}let{owner:r,repo:i}=Rn(),a=`https://api.github.com/repos/${r}/${i}`;try{let r=await Wn(e,`${a}/issues/${n}/comments?per_page=100`);if(r){await Hn(e,`PATCH`,`${a}/issues/comments/${r.id}`,{body:t}),nn(`Updated existing bundle size PR comment.`);return}await Hn(e,`POST`,`${a}/issues/${n}/comments`,{body:t}),nn(`Created bundle size PR comment.`)}catch(e){if(e instanceof In&&(e.status===401||e.status===403)){tn(`Skipping bundle size PR comment: ${e.message}`);return}throw e}}async function Kn(e,t,n){let r=vn(e,t);return await(0,y.mkdir)(l.default.dirname(r),{recursive:!0}),await(0,y.writeFile)(r,`${JSON.stringify(n,null,2)}\n`,`utf8`),r}var qn=(0,g.promisify)(_.gunzip),Jn=512;async function Yn(e){let t;try{t=await fetch(e)}catch(t){throw Error(`Failed to download tarball URI ${e}: ${t instanceof Error?t.message:String(t)}`)}if(!t.ok)throw Error(`Failed to download tarball URI ${e}: HTTP ${t.status} ${t.statusText}`);return Buffer.from(await t.arrayBuffer())}function Xn(e,t,n){let r=e.subarray(t,t+n),i=r.indexOf(0);return(i===-1?r:r.subarray(0,i)).toString(`utf8`).trim()}function Zn(e,t){let n=Xn(e,124,12).replaceAll(`\0`,``).trim();if(!n)return 0;if(!/^[0-7]+$/.test(n))throw Error(`Tarball entry has invalid size field: ${t}`);let r=Number.parseInt(n,8);if(!Number.isSafeInteger(r))throw Error(`Tarball entry size is too large: ${t}`);return r}function Qn(e){return e.every(e=>e===0)}function $n(e){return l.default.posix.normalize(e.replace(/\\/g,`/`)).replace(/^\.\//,``).replace(/^\/+/,``)}async function er(e){let t;try{t=await qn(e)}catch(e){throw Error(`Tarball is not a valid .tar.gz archive: ${e instanceof Error?e.message:String(e)}`)}let n=[],r=0;for(;r+Jn<=t.length;){let e=t.subarray(r,r+Jn);if(Qn(e))break;let i=Xn(e,0,100),a=Xn(e,345,155),o=$n(a?`${a}/${i}`:i),s=Zn(e,o),c=Xn(e,156,1),l=r+Jn,u=l+s;if(u>t.length)throw Error(`Tarball entry is truncated: ${o}`);o&&(c===``||c===`0`)&&n.push({path:o,content:Buffer.from(t.subarray(l,u))}),r=l+Math.ceil(s/Jn)*Jn}if(n.length===0)throw Error(`Tarball did not contain any regular files.`);return n}function tr(e){let t=e.map(e=>e.split(`/`)[0]).filter(Boolean),[n]=t;return!n||t.some(e=>e!==n)?null:e.every(e=>e.includes(`/`))?n:null}function nr(e){let t=new Map,n=tr(e.map(e=>e.path));for(let r of e)t.set(r.path,r.content),n&&r.path.startsWith(`${n}/`)&&t.set(r.path.slice(n.length+1),r.content);return t}async function rr(){try{let e=En();nn(`Local project root: ${e.localRoot}`),nn(`Npm package baseline: ${e.packageName}`),e.releaseStream!==void 0&&nn(`Npm release stream baseline: ${e.releaseStream}.x`),nn(`Comparing ${e.filePaths.length} file(s) using gzip size.`);let t=await Fn(e.packageName,e.releaseStream);nn(`Resolved ${t.length} npm release baseline(s).`);let n=[];for(let r of t){nn(`Downloading ${e.packageName}@${r.version}: ${r.uri}`);let t=await Yn(r.uri);n.push({...r,files:nr(await er(t))})}let r=await Sn(e.localRoot,e.packageName,e.filePaths,n,e.releaseStream),i=await Kn(e.localRoot,e.outputFile,r);nn(`Wrote bundle size comparison file: ${i}`),Qt(`comparison-file`,i),Qt(`size`,String(r.totals.currentBytes)),Qt(`total-current-gzip-size`,String(r.totals.currentBytes)),Qt(`total-baseline-gzip-size`,String(r.totals.baselineBytes)),Qt(`total-delta-gzip-size`,String(r.totals.deltaBytes)),e.commentPr&&await Gn(e.githubToken,hn(r))}catch(e){$t(e instanceof Error?e.message:String(e))}}var ir=process.argv[1];function ar(e=ir,t=process.env){return!!(t.GITHUB_ACTIONS===`true`&&t.INPUT_FILES!==void 0||e&&({}.url===(0,u.pathToFileURL)(e).href||(0,l.normalize)(e).endsWith((0,l.join)(`dist`,`index.js`))))}ar()&&rr(),exports.buildComparisonReport=Sn,exports.createTarballFileMap=nr,exports.extractTarGzEntries=er,exports.getPullRequestNumberFromEvent=Ln,exports.parseFilePaths=_n,exports.renderBundleSizeComment=hn,exports.resolveNpmReleaseBaselines=Fn,exports.run=rr,exports.shouldRunEntrypoint=ar,exports.statusEmoji=ln,exports.upsertPullRequestComment=Gn; \ No newline at end of file +`).filter(e=>e!==``);return t&&t.trimWhitespace===!1?n:n.map(e=>e.trim())}function Zt(e,t){if(process.env.GITHUB_OUTPUT)return D(`OUTPUT`,O(e,t));process.stdout.write(d.EOL),S(`set-output`,{name:e},b(t))}function Qt(e){process.exitCode=Jt.Failure,$t(e)}function $t(e,t={}){S(`error`,x(t),e instanceof Error?e.toString():e)}function en(e){process.stdout.write(e+d.EOL)}var tn=``;function nn(e){let t=e<0?`-`:``,n=Math.abs(e);return n<1024?`${t}${n} B`:`${t}${(n/1024).toFixed(1)} KiB`}function rn(e,t){let n=nn(e);return t===null?n:`${n} (${t>0?`+`:``}${t.toFixed(2)}%)`}function an(e){return e.replace(/\\/g,`\\\\`).replace(/\|/g,`\\|`)}function on(e){let t=an(e),n=t.match(/`+/g)??[],r=Math.max(0,...n.map(e=>e.length))+1,i="`".repeat(r),a=t.startsWith("`")||t.endsWith("`")?` `:``;return`${i}${a}${t}${a}${i}`}function sn(e){return e===null?`⚪`:e<=1?`🟢`:e<=3?`🔵`:e<=6?`🟡`:e<=9?`🟠`:`🔴`}function cn(e){return`| ${on(e.path)} | ${nn(e.baselineBytes)} | ${nn(e.currentBytes)} | ${rn(e.deltaBytes,e.deltaPercent)} | ${sn(e.deltaPercent)} |`}function ln(e){let t=e.latest?` latest`:``;return`${on(e.version)}${t}`}function un(e){if(!e.totals){let t=e.missingFiles.map(on).join(`, `);return`| ${ln(e)} | n/a | n/a | Incomplete: missing ${t} | ⚪ |`}return`| ${ln(e)} | ${nn(e.totals.baselineBytes)} | ${nn(e.totals.currentBytes)} | ${rn(e.totals.deltaBytes,e.totals.deltaPercent)} | ${sn(e.totals.deltaPercent)} |`}function dn(e){return e.releaseStream===void 0?`Compared current build against latest npm release ${on(e.baseline.version)} for ${on(e.packageName)}.`:`Compared current build against ${on(`${e.releaseStream}.x`)} release stream baseline ${on(e.baseline.version)} for ${on(e.packageName)}.`}function fn(e){return e.releaseStream===void 0?`Historical comparison: latest + 10 previous npm releases`:`Historical comparison: ${e.releaseStream}.x release stream baselines`}function pn(e){let t=e.files.map(cn);return t.push(`| **Total** | **${nn(e.totals.baselineBytes)}** | **${nn(e.totals.currentBytes)}** | **${rn(e.totals.deltaBytes,e.totals.deltaPercent)}** | **${sn(e.totals.deltaPercent)}** |`),[tn,``,`## Bundle Size Report`,``,dn(e),``,`| File | Baseline gzip | Current gzip | Difference | Status |`,`|---|---:|---:|---:|:---:|`,...t,``,`
`,`${fn(e)}`,``,`| Release | Baseline gzip | Current gzip | Difference | Status |`,`|---|---:|---:|---:|:---:|`,...e.history.map(un),``,`
`].join(` +`)}function mn(e){let t=e.trim().replace(/\\/g,`/`);if(/^[A-Za-z]:\//.test(t)||t.startsWith(`//`))throw Error(`Configured file path must be relative and stay inside the project: ${e}`);let n=l.default.posix.normalize(t);if(!n||n===`.`)throw Error(`Configured file paths must not be empty.`);if(n.startsWith(`/`)||n===`..`||n.startsWith(`../`))throw Error(`Configured file path must be relative and stay inside the project: ${e}`);return n}function hn(e){let t=e.split(/\r?\n/).map(e=>e.trim()).filter(Boolean).map(mn);if(t.length===0)throw Error(`At least one file path must be provided via the files input.`);return[...new Set(t)]}function gn(e,t){let n=l.default.resolve(e),r=l.default.resolve(n,t),i=l.default.relative(n,r);if(i===``||i===`..`||i.startsWith(`..${l.default.sep}`)||l.default.isAbsolute(i))throw Error(`Path must stay inside the project root: ${t}`);return r}var _n=(0,g.promisify)(_.gzip);async function vn(e){return(await _n(e,{level:_.constants.Z_BEST_COMPRESSION})).length}function yn(e,t){return t===0?null:Number(((e-t)/t*100).toFixed(2))}async function bn(e,t,n,r,i){let[a]=r;if(!a)throw Error(`At least one npm release baseline is required.`);let o=[];for(let t of r)o.push(await xn(e,n,t,t.latest));let[s]=o;if(!s.totals)throw Error(`Primary release comparison is incomplete: ${a.version}`);return{metric:`gzip`,packageName:t,releaseStream:i,baseline:{version:a.version,uri:a.uri},localRoot:e,files:s.files,totals:s.totals,history:o}}async function xn(e,t,n,r){let i=[],a=[];for(let o of t){let t=n.files.get(o);if(!t){if(r)throw Error(`Baseline file not found in primary release ${n.version}: ${o}`);a.push(o);continue}let s=gn(e,o),c;try{c=await(0,y.readFile)(s)}catch(e){throw Error(`Local file not found: ${o} (${e instanceof Error?e.message:String(e)})`)}let l=await vn(t),u=await vn(c),d=u-l;i.push({path:o,baselineBytes:l,currentBytes:u,deltaBytes:d,deltaPercent:yn(u,l)})}let o=i.reduce((e,t)=>e+t.baselineBytes,0),s=i.reduce((e,t)=>e+t.currentBytes,0),c=a.length>0?null:{baselineBytes:o,currentBytes:s,deltaBytes:s-o,deltaPercent:yn(s,o)};return{version:n.version,uri:n.uri,latest:n.latest,complete:a.length===0,missingFiles:a,files:i,totals:c}}function Sn(e){let t=e.trim();if(!t)throw Error(`The package-name input is required.`);if(/\s/.test(t)||t.includes(`:`))throw Error(`Invalid npm package name: ${e}`);if(t.startsWith(`@`)){let n=t.split(`/`);if(n.length!==2||!n[0].slice(1)||!n[1])throw Error(`Invalid npm package name: ${e}`);return t}if(t.includes(`/`))throw Error(`Invalid npm package name: ${e}`);return t}function Cn(e){let t=e.trim();if(t){if(!/^\d+$/.test(t))throw Error(`Invalid release-stream input: ${e}`);return Number(t)}}function wn(){let e=l.default.resolve(Yt(`path`,{required:!1})||`.`),t=Sn(Yt(`package-name`,{required:!0})),n=Cn(Yt(`release-stream`,{required:!1})),r=Xt(`files`,{required:!0}).join(` +`),i=mn(Yt(`output-file`,{required:!1})||`bundle-size-comparison.json`),a=mn(Yt(`markdown-output-file`,{required:!1})||`bundle-size-comparison.md`);return{localRoot:e,packageName:t,releaseStream:n,filePaths:hn(r),outputFile:i,markdownOutputFile:a}}var Tn=`https://registry.npmjs.org`,En=10;function Dn(e){return`${Tn}/${encodeURIComponent(e)}`}function On(e){return!e.includes(`-`)}function kn(e){let t=/^(\d+)\./.exec(e);return t?Number(t[1]):null}function An(e,t,n){let r=n.versions?.[t]?.dist?.tarball;if(typeof r!=`string`||!r.trim())throw Error(`Npm package ${e} version ${t} is missing a tarball URL.`);let i;try{i=new URL(r)}catch{throw Error(`Npm package ${e} version ${t} has an invalid tarball URL.`)}if(i.protocol!==`http:`&&i.protocol!==`https:`)throw Error(`Npm package ${e} version ${t} has an unsupported tarball URL protocol: ${i.protocol}`);return r}function jn(e,t,n){let r=n.time?.[t],i=r?Date.parse(r):NaN;if(Number.isNaN(i))throw Error(`Npm package ${e} version ${t} is missing publish time metadata.`);return i}function Mn(e,t,n){if(n!==void 0){let r=Object.keys(t.versions??{}).filter(e=>On(e)&&kn(e)===n).map(n=>({version:n,publishedAt:jn(e,n,t)})).sort((e,t)=>t.publishedAt-e.publishedAt).slice(0,En+1).map(e=>e.version);if(r.length===0)throw Error(`Npm package ${e} has no stable releases in release stream ${n}.`);return r.map((n,r)=>({version:n,uri:An(e,n,t),latest:r===0}))}let r=t[`dist-tags`]?.latest;if(typeof r!=`string`||!r||!t.versions?.[r])throw Error(`Npm package ${e} does not define a usable latest release.`);let i=jn(e,r,t);return[r,...Object.keys(t.versions).filter(e=>e!==r&&On(e)).map(n=>({version:n,publishedAt:jn(e,n,t)})).filter(e=>e.publishedAtt.publishedAt-e.publishedAt).slice(0,En).map(e=>e.version)].map((n,r)=>({version:n,uri:An(e,n,t),latest:r===0}))}async function Nn(e,t){let n=Dn(e),r;try{r=await fetch(n)}catch(t){throw Error(`Failed to fetch npm metadata for ${e}: ${t instanceof Error?t.message:String(t)}`)}if(!r.ok)throw Error(`Failed to fetch npm metadata for ${e}: HTTP ${r.status} ${r.statusText}`);let i;try{i=await r.json()}catch(t){throw Error(`Failed to parse npm metadata for ${e}: ${t instanceof Error?t.message:String(t)}`)}return Mn(e,i,t)}async function Pn(e,t,n){let r=gn(e,t);return await(0,y.mkdir)(l.default.dirname(r),{recursive:!0}),await(0,y.writeFile)(r,`${JSON.stringify(n,null,2)}\n`,`utf8`),r}async function Fn(e,t,n){let r=gn(e,t);return await(0,y.mkdir)(l.default.dirname(r),{recursive:!0}),await(0,y.writeFile)(r,`${n}\n`,`utf8`),r}var In=(0,g.promisify)(_.gunzip),Ln=512;async function Rn(e){let t;try{t=await fetch(e)}catch(t){throw Error(`Failed to download tarball URI ${e}: ${t instanceof Error?t.message:String(t)}`)}if(!t.ok)throw Error(`Failed to download tarball URI ${e}: HTTP ${t.status} ${t.statusText}`);return Buffer.from(await t.arrayBuffer())}function zn(e,t,n){let r=e.subarray(t,t+n),i=r.indexOf(0);return(i===-1?r:r.subarray(0,i)).toString(`utf8`).trim()}function Bn(e,t){let n=zn(e,124,12).replaceAll(`\0`,``).trim();if(!n)return 0;if(!/^[0-7]+$/.test(n))throw Error(`Tarball entry has invalid size field: ${t}`);let r=Number.parseInt(n,8);if(!Number.isSafeInteger(r))throw Error(`Tarball entry size is too large: ${t}`);return r}function Vn(e){return e.every(e=>e===0)}function Hn(e){return l.default.posix.normalize(e.replace(/\\/g,`/`)).replace(/^\.\//,``).replace(/^\/+/,``)}async function Un(e){let t;try{t=await In(e)}catch(e){throw Error(`Tarball is not a valid .tar.gz archive: ${e instanceof Error?e.message:String(e)}`)}let n=[],r=0;for(;r+Ln<=t.length;){let e=t.subarray(r,r+Ln);if(Vn(e))break;let i=zn(e,0,100),a=zn(e,345,155),o=Hn(a?`${a}/${i}`:i),s=Bn(e,o),c=zn(e,156,1),l=r+Ln,u=l+s;if(u>t.length)throw Error(`Tarball entry is truncated: ${o}`);o&&(c===``||c===`0`)&&n.push({path:o,content:Buffer.from(t.subarray(l,u))}),r=l+Math.ceil(s/Ln)*Ln}if(n.length===0)throw Error(`Tarball did not contain any regular files.`);return n}function Wn(e){let t=e.map(e=>e.split(`/`)[0]).filter(Boolean),[n]=t;return!n||t.some(e=>e!==n)?null:e.every(e=>e.includes(`/`))?n:null}function Gn(e){let t=new Map,n=Wn(e.map(e=>e.path));for(let r of e)t.set(r.path,r.content),n&&r.path.startsWith(`${n}/`)&&t.set(r.path.slice(n.length+1),r.content);return t}async function Kn(){try{let e=wn();en(`Local project root: ${e.localRoot}`),en(`Npm package baseline: ${e.packageName}`),e.releaseStream!==void 0&&en(`Npm release stream baseline: ${e.releaseStream}.x`),en(`Comparing ${e.filePaths.length} file(s) using gzip size.`);let t=await Nn(e.packageName,e.releaseStream);en(`Resolved ${t.length} npm release baseline(s).`);let n=[];for(let r of t){en(`Downloading ${e.packageName}@${r.version}: ${r.uri}`);let t=await Rn(r.uri);n.push({...r,files:Gn(await Un(t))})}let r=await bn(e.localRoot,e.packageName,e.filePaths,n,e.releaseStream),i=await Pn(e.localRoot,e.outputFile,r),a=await Fn(e.localRoot,e.markdownOutputFile,pn(r));en(`Wrote bundle size comparison file: ${i}`),en(`Wrote bundle size Markdown file: ${a}`),Zt(`comparison-file`,i),Zt(`markdown-file`,a),Zt(`size`,String(r.totals.currentBytes)),Zt(`total-current-gzip-size`,String(r.totals.currentBytes)),Zt(`total-baseline-gzip-size`,String(r.totals.baselineBytes)),Zt(`total-delta-gzip-size`,String(r.totals.deltaBytes))}catch(e){Qt(e instanceof Error?e.message:String(e))}}var qn=process.argv[1];function Jn(e=qn,t=process.env){return!!(t.GITHUB_ACTIONS===`true`&&t.INPUT_FILES!==void 0||e&&({}.url===(0,u.pathToFileURL)(e).href||(0,l.normalize)(e).endsWith((0,l.join)(`dist`,`index.js`))))}Jn()&&Kn(),exports.buildComparisonReport=bn,exports.createTarballFileMap=Gn,exports.extractTarGzEntries=Un,exports.parseFilePaths=hn,exports.renderBundleSizeComment=pn,exports.resolveNpmReleaseBaselines=Nn,exports.run=Kn,exports.shouldRunEntrypoint=Jn,exports.statusEmoji=sn; \ No newline at end of file diff --git a/openspec/changes/externalize-pr-commenting/.openspec.yaml b/openspec/changes/externalize-pr-commenting/.openspec.yaml new file mode 100644 index 0000000..28882f7 --- /dev/null +++ b/openspec/changes/externalize-pr-commenting/.openspec.yaml @@ -0,0 +1,2 @@ +schema: spec-driven +created: 2026-05-19 diff --git a/openspec/changes/externalize-pr-commenting/design.md b/openspec/changes/externalize-pr-commenting/design.md new file mode 100644 index 0000000..b4397c5 --- /dev/null +++ b/openspec/changes/externalize-pr-commenting/design.md @@ -0,0 +1,81 @@ +## Context + +The action currently has two responsibilities: compute gzip bundle-size comparisons and optionally publish the rendered result as a pull request comment. The comment-publishing path works for same-repository pull requests when the workflow grants a writable token, but it cannot reliably support public fork pull requests because GitHub makes `GITHUB_TOKEN` read-only for `pull_request` runs from forks. + +The comparison result is already written as a machine-readable JSON report. The action can also write the same safely rendered Markdown body it previously posted directly, making external comment publishing simple without keeping GitHub API calls in the action runtime. + +## Goals / Non-Goals + +**Goals:** + +- Make report generation the action's only runtime publishing contract. +- Write both the machine-readable JSON report and the comment-ready Markdown report. +- Remove the built-in GitHub comments API call path and the token input it requires. +- Provide README recipes that let users post the generated Markdown comment body. +- Show both a simple same-repository PR recipe and a public fork-safe two-workflow recipe. +- Keep Markdown rendering inside the action so users do not need to copy renderer code into workflows. + +**Non-Goals:** + +- Add budget, threshold, or status-check enforcement. +- Add a second action mode, CLI, or reusable renderer package. +- Build the target project inside the action. +- Guarantee comment posting from a `pull_request` workflow that GitHub has intentionally restricted to read-only permissions. + +## Decisions + +### Remove Runtime Comment Posting + +The action should stop accepting `comment-pr` and `github-token`, and `run()` should stop invoking the PR comment upsert path. This keeps the action focused on comparison and report generation. + +Alternative considered: keep `comment-pr` for same-repository PRs and document a separate fork-safe pattern. That preserves convenience but keeps token handling, API behavior, and fork warning complexity inside a comparison action. + +### Generate Markdown Beside JSON + +The action should write a Markdown report file alongside the JSON report. The Markdown report should be the same body that the previous built-in PR comment path rendered, including the stable marker used for comment upserts. + +Alternative considered: document a copy-pasteable `actions/github-script` renderer that reads JSON. That keeps the trusted workflow responsible for rendering, but it is too cumbersome for users and creates drift risk between the action renderer and documentation snippets. + +### Add A Configurable Markdown Output Path + +Add `markdown-output-file` with a default such as `bundle-size-comparison.md`, and add a `markdown-file` action output with the absolute path. This mirrors the existing JSON report path behavior and lets workflows upload or read the Markdown file directly. + +Alternative considered: always derive the Markdown path from `output-file`. A separate input is clearer and avoids surprising users who intentionally place JSON reports in a machine-readable reports directory. + +### Document Two Workflow Patterns + +The documentation should distinguish two cases: + +- Same-repository PRs: run comparison and post/update the generated Markdown file in a later step of the same workflow. +- Public fork PRs: run comparison in `pull_request`, upload the Markdown report as an artifact, then use `workflow_run` in the base repository context to download the artifact, verify the PR/head SHA context, and post/update it. + +Alternative considered: recommend `pull_request_target`. That event has write permission for fork PRs, but it is unsafe for this use case if the workflow checks out, installs, or builds pull-request-controlled code. + +### Keep Comment Shape Stable In Generated Markdown + +The generated Markdown should preserve the existing comment marker, tables, status thresholds, bytes formatting, release stream wording, and historical details section. The renderer remains testable while all GitHub API posting behavior is removed. + +Alternative considered: simplify the documented comment. That would make the recipe shorter, but it would make migration harder for existing users and would not satisfy the goal of producing the same comment. + +## Risks / Trade-offs + +- Breaking input removal may surprise users using `comment-pr` today -> Document a clear migration path and call out the replacement recipes near the input table. +- Generated Markdown drift from current formatting -> Keep renderer semantics covered by tests. +- Public fork recipe complexity -> Provide the simple same-repo recipe first, then clearly explain why fork-safe commenting requires `workflow_run`. +- Stale workflow runs may update a PR comment after a newer run -> The fork-safe recipe should include PR/head SHA validation guidance before posting. +- Markdown artifacts are untrusted when produced by fork code -> The action renderer escapes report-derived file paths, and docs should still advise using trusted action refs and validating PR/head SHA before posting artifacts from `workflow_run`. + +## Migration Plan + +1. Remove the action inputs and runtime comment API call path. +2. Preserve JSON report output and existing numeric outputs unchanged. +3. Add Markdown report output and a `markdown-file` action output. +4. Replace README `comment-pr` examples with external commenting recipes that post the generated Markdown. +5. Update security and contributor docs to describe comment publishing as workflow-owned integration code. +6. Rebuild `dist/index.js` with the runtime changes. + +Rollback is straightforward: restore the previous `comment-pr` and `github-token` inputs plus the PR comment upsert path if built-in posting is needed again. + +## Open Questions + +- Should the README provide a full fork-safe `workflow_run` example, or a focused excerpt that links the artifact handoff pieces together? diff --git a/openspec/changes/externalize-pr-commenting/proposal.md b/openspec/changes/externalize-pr-commenting/proposal.md new file mode 100644 index 0000000..d88c61d --- /dev/null +++ b/openspec/changes/externalize-pr-commenting/proposal.md @@ -0,0 +1,33 @@ +## Why + +Built-in pull request commenting cannot reliably support public fork pull requests because GitHub intentionally gives `pull_request` workflow runs from forks a read-only `GITHUB_TOKEN`. The action should keep the bundle-size comparison itself JSON-first and let workflows publish comments from an appropriate trust boundary. + +## What Changes + +- **BREAKING**: Remove built-in pull request comment posting from the action runtime. +- Remove the `comment-pr` and `github-token` action inputs from the supported action interface. +- Keep the JSON comparison report and existing action outputs as the primary machine-readable integration contract. +- Add a generated Markdown comparison report that uses the same comment body currently produced by the action. +- Document how users can upsert a pull request comment by reading the generated Markdown file. +- Document both same-repository PR commenting and public fork-safe commenting using a two-workflow `pull_request` plus `workflow_run` artifact handoff. +- Keep comment status colors informational only; this change does not add budget or threshold enforcement. + +## Capabilities + +### New Capabilities + +- None. + +### Modified Capabilities + +- `pr-bundle-size-comment`: replace built-in comment posting with generated Markdown output and documented external workflows that post the Markdown file. + +## Impact + +- `action.yml`: remove `comment-pr` and `github-token` inputs. +- `src/action.ts`, `src/config.ts`, `src/types.ts`, `src/report.ts`, `src/index.ts`: remove runtime PR commenting configuration and API invocation surfaces and add Markdown report output. +- `src/pr-comment.ts`, related exports, and `tests/pr-comment.test.ts`: remove built-in GitHub comments API behavior unless retained only as non-runtime test support is explicitly justified during implementation. +- `src/comment.ts` and `tests/comment.test.ts`: preserve Markdown rendering coverage so generated Markdown matches the previous comment structure. +- `README.md`: replace built-in commenting documentation with same-repo and fork-safe external commenting recipes that post the generated Markdown file. +- `THREAT_MODEL.md`, `CONTRIBUTING.md`, `COLLABORATOR_GUIDE.md`: update PR-comment security and ownership notes. +- `dist/index.js`: rebuild because runtime code and action metadata change. diff --git a/openspec/changes/externalize-pr-commenting/specs/pr-bundle-size-comment/spec.md b/openspec/changes/externalize-pr-commenting/specs/pr-bundle-size-comment/spec.md new file mode 100644 index 0000000..173cd47 --- /dev/null +++ b/openspec/changes/externalize-pr-commenting/specs/pr-bundle-size-comment/spec.md @@ -0,0 +1,144 @@ +## ADDED Requirements + +### Requirement: Document External PR Commenting +The documentation SHALL explain that pull request comments are published outside the action from the generated Markdown comparison report. + +#### Scenario: User reads PR comment documentation +- **WHEN** a user needs a pull request comment +- **THEN** the documentation explains that the action writes JSON and Markdown reports +- **AND** the documentation explains that workflow steps outside the action are responsible for publishing pull request comments from the Markdown report + +#### Scenario: User migrates from built-in commenting +- **WHEN** a user has an existing workflow that used built-in PR commenting inputs +- **THEN** the documentation shows how to replace those inputs with an external comment publishing step that reads the generated Markdown report + +### Requirement: Generate Markdown Comment Report +The action SHALL write a Markdown comparison report containing the same body used for pull request comments. + +#### Scenario: Markdown report path uses default +- **WHEN** the workflow invokes the action without configuring the Markdown report path +- **THEN** the action writes the Markdown report under the local project root at `bundle-size-comparison.md` +- **AND** the action exposes the absolute Markdown report path as an output + +#### Scenario: Markdown report path is configured +- **WHEN** the workflow configures the Markdown report path +- **THEN** the action writes the Markdown report under the local project root at the configured relative path +- **AND** the action exposes the absolute Markdown report path as an output + +#### Scenario: Markdown report path is unsafe +- **WHEN** the workflow configures a Markdown report path that is absolute or escapes the local project root +- **THEN** the action fails with a path safety error + +### Requirement: Document Same-Repository Comment Workflow +The documentation SHALL provide a same-repository pull request workflow recipe that upserts a bundle-size comment from the Markdown report. + +#### Scenario: Same-repository pull request comment recipe +- **WHEN** a pull request workflow has permission to write pull request or issue comments +- **THEN** the documentation shows a recipe that reads the Markdown report after the comparison step +- **AND** the recipe creates or updates the pull request comment identified by the bundle-size marker + +#### Scenario: Same-repository recipe limitations +- **WHEN** the documentation presents the same-workflow comment recipe +- **THEN** it states that the recipe does not bypass GitHub's read-only token restrictions for public fork pull requests + +### Requirement: Document Fork-Safe Comment Workflow +The documentation SHALL provide a public fork-safe workflow pattern that separates untrusted comparison execution from trusted comment publishing. + +#### Scenario: Fork-safe comparison workflow +- **WHEN** a public repository accepts pull requests from forks +- **THEN** the documentation shows that the `pull_request` workflow runs the bundle-size comparison without write credentials +- **AND** the documentation shows that the workflow uploads the Markdown comparison report as an artifact + +#### Scenario: Fork-safe comment workflow +- **WHEN** the Markdown comparison artifact is available from a completed pull request workflow run +- **THEN** the documentation shows a trusted `workflow_run` workflow that downloads the Markdown report artifact +- **AND** the workflow posts or updates the pull request comment with the Markdown report and a token that has comment write permission + +#### Scenario: Fork-safe workflow avoids unsafe target event usage +- **WHEN** the documentation explains public fork support +- **THEN** it warns users not to use `pull_request_target` to checkout, install, build, or otherwise execute pull-request-controlled code with writable credentials + +### Requirement: Generate Current Bundle Size Comment Shape +The generated Markdown report SHALL use the same Markdown structure as the previous built-in PR comment. + +#### Scenario: Comment marker is rendered +- **WHEN** the action writes the Markdown report +- **THEN** the comment begins with the stable hidden bundle-size marker + +#### Scenario: Primary comparison table is rendered +- **WHEN** the action writes the Markdown report from a complete comparison report +- **THEN** the comment includes the `Bundle Size Report` heading +- **AND** the comment includes a baseline description with the package name and selected baseline version +- **AND** the comment includes a Markdown table with file path, baseline gzip size, current gzip size, difference, and status columns +- **AND** the table includes one row for each compared file +- **AND** the table includes a total row + +#### Scenario: Historical comparison section is rendered +- **WHEN** the action writes the Markdown report from a report with history +- **THEN** the comment includes a collapsed details section for historical release comparisons +- **AND** the section includes one row for each historical release +- **AND** incomplete historical releases identify the missing files + +#### Scenario: Release stream wording is rendered +- **WHEN** the comparison report includes a release stream +- **THEN** the generated Markdown identifies the configured release stream in the baseline description and history summary + +### Requirement: Document Current Status Color Semantics +The generated Markdown report SHALL assign a colored circle status emoji to each file row, release row, and total row based on percent delta. + +#### Scenario: Percent delta is unavailable +- **WHEN** a comparison result has a null percent delta +- **THEN** the generated Markdown shows a white circle status emoji + +#### Scenario: Percent delta is less than or equal to one percent +- **WHEN** a comparison result has a percent delta less than or equal to `1` +- **THEN** the generated Markdown shows a green circle status emoji + +#### Scenario: Percent delta is greater than one percent and less than or equal to three percent +- **WHEN** a comparison result has a percent delta greater than `1` and less than or equal to `3` +- **THEN** the generated Markdown shows a blue circle status emoji + +#### Scenario: Percent delta is greater than three percent and less than or equal to six percent +- **WHEN** a comparison result has a percent delta greater than `3` and less than or equal to `6` +- **THEN** the generated Markdown shows a yellow circle status emoji + +#### Scenario: Percent delta is greater than six percent and less than or equal to nine percent +- **WHEN** a comparison result has a percent delta greater than `6` and less than or equal to `9` +- **THEN** the generated Markdown shows an orange circle status emoji + +#### Scenario: Percent delta is greater than nine percent +- **WHEN** a comparison result has a percent delta greater than `9` +- **THEN** the generated Markdown shows a red circle status emoji + +### Requirement: Keep External Comment Status Informational +The documented comment workflow SHALL NOT treat status colors as bundle-size budget or threshold enforcement. + +#### Scenario: Total status is red +- **WHEN** the comparison succeeds and the rendered total row has a red status emoji +- **THEN** the documented comment workflow still treats the comparison report as informational unless the user adds separate enforcement logic + +## REMOVED Requirements + +### Requirement: Configure PR Commenting +**Reason**: Built-in comment posting requires a writable GitHub token and cannot reliably support public fork pull requests from the same `pull_request` workflow context. +**Migration**: Run the action to produce the Markdown comparison report, then use a separate workflow step or trusted `workflow_run` workflow to post that report as the pull request comment. + +### Requirement: Comment Only For Pull Requests +**Reason**: Pull request detection and comment publishing move out of the action runtime and into user-owned workflow code. +**Migration**: Use the documented external comment recipe to detect the pull request number from the workflow event or associated workflow run. + +### Requirement: Render Bundle Size Markdown Comment +**Reason**: The action no longer renders a runtime pull request comment body as part of comparison execution. +**Migration**: Use the generated Markdown report as the pull request comment body. + +### Requirement: Show Status Color For Percent Delta +**Reason**: Runtime comment rendering is removed from the action. +**Migration**: Use the generated Markdown report, which preserves the same status color thresholds. + +### Requirement: Avoid Duplicate PR Comments +**Reason**: Comment upsert behavior moves out of the action runtime and into user-owned workflow code. +**Migration**: Use the documented external comment recipe to find an existing comment containing the bundle-size marker and update it instead of creating duplicates. + +### Requirement: Keep Status Informational +**Reason**: Runtime comment rendering is removed from the action. +**Migration**: Treat the documented comment workflow as informational unless the workflow adds separate budget or threshold enforcement. diff --git a/openspec/changes/externalize-pr-commenting/tasks.md b/openspec/changes/externalize-pr-commenting/tasks.md new file mode 100644 index 0000000..5d43d33 --- /dev/null +++ b/openspec/changes/externalize-pr-commenting/tasks.md @@ -0,0 +1,35 @@ +## 1. Remove Built-In Comment Runtime + +- [x] 1.1 Remove `comment-pr` and `github-token` from `action.yml`. +- [x] 1.2 Remove PR comment inputs from configuration parsing, shared config types, and related config tests. +- [x] 1.3 Remove the PR comment API invocation from action orchestration while preserving JSON report writing and existing action outputs. +- [x] 1.4 Remove built-in GitHub comments API code and exports, or document why any remaining renderer-only code is still required. + +## 2. Preserve Comment Rendering Contract For Documentation + +- [x] 2.1 Decide whether to keep a testable Markdown renderer module or move the renderer entirely into documentation examples. +- [x] 2.2 Add or update tests that lock the documented comment structure, marker, byte formatting, delta formatting, status thresholds, release-stream wording, and incomplete historical release wording. +- [x] 2.3 Ensure no runtime path posts comments or calls the GitHub comments API. +- [x] 2.4 Add Markdown report output configuration, file writing, action output, and path-safety tests. + +## 3. Update Documentation + +- [x] 3.1 Update the README input table and basic examples to remove built-in PR comment inputs. +- [x] 3.2 Add a same-repository PR recipe that reads `bundle-size-comparison.md` and creates or updates the marked pull request comment. +- [x] 3.3 Add a public fork-safe recipe that runs comparison in `pull_request`, uploads the Markdown report artifact, and posts the comment from a trusted `workflow_run` workflow. +- [x] 3.4 Document that the same-workflow comment recipe does not bypass read-only `GITHUB_TOKEN` restrictions for public fork pull requests. +- [x] 3.5 Document why `pull_request_target` must not checkout, install, build, or otherwise execute pull-request-controlled code with writable credentials. +- [x] 3.6 Simplify comment recipes so workflows read and post the generated Markdown file instead of rendering Markdown from JSON. + +## 4. Update Security And Contributor Notes + +- [x] 4.1 Update `THREAT_MODEL.md` to reflect that comment publishing is external workflow code and the action no longer consumes a comment token. +- [x] 4.2 Update `CONTRIBUTING.md` and `COLLABORATOR_GUIDE.md` references to built-in PR comment API behavior. +- [x] 4.3 Update this repository's bundle-size workflow if needed to follow the new external-comment action behavior. + +## 5. Verify And Build + +- [x] 5.1 Run `pnpm run lint` and fix reported issues. +- [x] 5.2 Run `pnpm run typecheck` and fix reported issues. +- [x] 5.3 Run `pnpm test` and fix reported issues. +- [x] 5.4 Run `pnpm run build` and commit the updated `dist/index.js` with the source and action metadata changes. diff --git a/src/action.ts b/src/action.ts index c8614d7..e8401b3 100644 --- a/src/action.ts +++ b/src/action.ts @@ -3,8 +3,7 @@ import { renderBundleSizeComment } from "@/comment"; import { buildComparisonReport } from "@/comparison"; import { getConfig } from "@/config"; import { resolveNpmReleaseBaselines } from "@/npm"; -import { upsertPullRequestComment } from "@/pr-comment"; -import { writeComparisonReport } from "@/report"; +import { writeComparisonReport, writeMarkdownReport } from "@/report"; import { createTarballFileMap, downloadTarball, @@ -52,9 +51,16 @@ export async function run(): Promise { config.outputFile, report, ); + const markdownOutputPath = await writeMarkdownReport( + config.localRoot, + config.markdownOutputFile, + renderBundleSizeComment(report), + ); core.info(`Wrote bundle size comparison file: ${outputPath}`); + core.info(`Wrote bundle size Markdown file: ${markdownOutputPath}`); core.setOutput("comparison-file", outputPath); + core.setOutput("markdown-file", markdownOutputPath); core.setOutput("size", String(report.totals.currentBytes)); core.setOutput( "total-current-gzip-size", @@ -65,13 +71,6 @@ export async function run(): Promise { String(report.totals.baselineBytes), ); core.setOutput("total-delta-gzip-size", String(report.totals.deltaBytes)); - - if (config.commentPr) { - await upsertPullRequestComment( - config.githubToken, - renderBundleSizeComment(report), - ); - } } catch (error) { core.setFailed(error instanceof Error ? error.message : String(error)); } diff --git a/src/config.ts b/src/config.ts index e8fbb7e..a8001f0 100644 --- a/src/config.ts +++ b/src/config.ts @@ -62,12 +62,10 @@ export function getConfig(): ActionConfig { core.getInput("output-file", { required: false }) || "bundle-size-comparison.json", ); - const commentPr = core.getBooleanInput("comment-pr", { required: false }); - const githubToken = core.getInput("github-token", { required: false }); - - if (commentPr && !githubToken) { - throw new Error("The github-token input is required when comment-pr is enabled."); - } + const markdownOutputFile = normalizeConfiguredPath( + core.getInput("markdown-output-file", { required: false }) || + "bundle-size-comparison.md", + ); return { localRoot, @@ -75,7 +73,6 @@ export function getConfig(): ActionConfig { releaseStream, filePaths: parseFilePaths(filesInput), outputFile, - commentPr, - githubToken, + markdownOutputFile, }; } diff --git a/src/index.ts b/src/index.ts index 24c2c9a..d819f86 100644 --- a/src/index.ts +++ b/src/index.ts @@ -7,7 +7,6 @@ export { buildComparisonReport } from "@/comparison"; export { renderBundleSizeComment, statusEmoji } from "@/comment"; export { resolveNpmReleaseBaselines } from "@/npm"; export { parseFilePaths } from "@/paths"; -export { getPullRequestNumberFromEvent, upsertPullRequestComment } from "@/pr-comment"; export { createTarballFileMap, extractTarGzEntries } from "@/tarball"; const entrypoint = process.argv[1]; diff --git a/src/pr-comment.ts b/src/pr-comment.ts deleted file mode 100644 index da8efbc..0000000 --- a/src/pr-comment.ts +++ /dev/null @@ -1,225 +0,0 @@ -import * as core from "@actions/core"; -import { readFile } from "node:fs/promises"; -import { BUNDLE_SIZE_COMMENT_MARKER } from "@/comment"; - -interface IssueComment { - id: number; - body?: string; - user?: { - login?: string; - type?: string; - }; -} - -interface PullRequestPayload { - number?: unknown; - pull_request?: { - number?: unknown; - }; -} - -interface GitHubApiErrorBody { - message?: string; -} - -interface GitHubPage { - body: T; - nextUrl: string | null; -} - -class GitHubApiError extends Error { - readonly status: number; - - constructor(message: string, status: number) { - super(message); - this.name = "GitHubApiError"; - this.status = status; - } -} - -export async function getPullRequestNumberFromEvent(): Promise { - const eventPath = process.env.GITHUB_EVENT_PATH; - - if (!eventPath) { - return null; - } - - const payload = JSON.parse( - await readFile(eventPath, "utf8"), - ) as PullRequestPayload; - const pullRequestNumber = payload.pull_request?.number ?? payload.number; - - return typeof pullRequestNumber === "number" ? pullRequestNumber : null; -} - -function getRepository(): { owner: string; repo: string } { - const repository = process.env.GITHUB_REPOSITORY; - - if (!repository) { - throw new Error("GITHUB_REPOSITORY is required to post a pull request comment."); - } - - const [owner, repo] = repository.split("/"); - - if (!owner || !repo) { - throw new Error(`Invalid GITHUB_REPOSITORY value: ${repository}`); - } - - return { owner, repo }; -} - -async function parseErrorMessage(response: Response): Promise { - try { - const body = (await response.json()) as GitHubApiErrorBody; - return body.message ? `: ${body.message}` : ""; - } catch { - return ""; - } -} - -function parseNextLink(linkHeader: string | null): string | null { - if (!linkHeader) { - return null; - } - - for (const link of linkHeader.split(",")) { - if (!link.includes('rel="next"')) { - continue; - } - - const match = /<([^>]+)>/.exec(link); - return match?.[1] ?? null; - } - - return null; -} - -async function requestGitHubPage( - token: string, - method: string, - url: string, - body?: unknown, -): Promise> { - const response = await fetch(url, { - method, - headers: { - accept: "application/vnd.github+json", - authorization: `Bearer ${token}`, - "content-type": "application/json", - "user-agent": "axios-bundle-size-action", - "x-github-api-version": "2022-11-28", - }, - body: body === undefined ? undefined : JSON.stringify(body), - }); - - if (!response.ok) { - const detail = await parseErrorMessage(response); - const permissionHint = - response.status === 401 || response.status === 403 - ? " Check that github-token has permission to write pull request or issue comments." - : ""; - - throw new GitHubApiError( - `GitHub comments API request failed (${response.status} ${response.statusText})${detail}.${permissionHint}`, - response.status, - ); - } - - return { - body: (await response.json()) as T, - nextUrl: parseNextLink(response.headers.get("link")), - }; -} - -async function requestGitHub( - token: string, - method: string, - url: string, - body?: unknown, -): Promise { - const page = await requestGitHubPage(token, method, url, body); - return page.body; -} - -function isBundleSizeComment(comment: IssueComment): boolean { - return comment.body?.includes(BUNDLE_SIZE_COMMENT_MARKER) === true; -} - -async function findExistingBundleSizeComment( - token: string, - commentsUrl: string, -): Promise { - let nextUrl: string | null = commentsUrl; - - while (nextUrl) { - const page: GitHubPage = await requestGitHubPage< - IssueComment[] - >( - token, - "GET", - nextUrl, - ); - const existingComment = page.body.find(isBundleSizeComment); - - if (existingComment) { - return existingComment; - } - - nextUrl = page.nextUrl; - } - - return undefined; -} - -export async function upsertPullRequestComment( - token: string, - body: string, -): Promise { - const pullRequestNumber = await getPullRequestNumberFromEvent(); - - if (pullRequestNumber === null) { - core.info("Skipping bundle size PR comment because this run is not for a pull request."); - return; - } - - const { owner, repo } = getRepository(); - const apiRoot = `https://api.github.com/repos/${owner}/${repo}`; - - try { - const existingComment = await findExistingBundleSizeComment( - token, - `${apiRoot}/issues/${pullRequestNumber}/comments?per_page=100`, - ); - - if (existingComment) { - await requestGitHub( - token, - "PATCH", - `${apiRoot}/issues/comments/${existingComment.id}`, - { body }, - ); - core.info("Updated existing bundle size PR comment."); - return; - } - - await requestGitHub( - token, - "POST", - `${apiRoot}/issues/${pullRequestNumber}/comments`, - { body }, - ); - core.info("Created bundle size PR comment."); - } catch (error) { - // Fork pull requests receive a read-only GITHUB_TOKEN regardless of - // the workflow's requested permissions. Surface that as a warning so - // the comparison report and outputs still succeed. - if ( - error instanceof GitHubApiError && - (error.status === 401 || error.status === 403) - ) { - core.warning(`Skipping bundle size PR comment: ${error.message}`); - return; - } - throw error; - } -} diff --git a/src/report.ts b/src/report.ts index 4cd101a..ca84e80 100644 --- a/src/report.ts +++ b/src/report.ts @@ -16,3 +16,17 @@ export async function writeComparisonReport( return outputPath; } + +export async function writeMarkdownReport( + localRoot: string, + outputFile: string, + markdown: string, +): Promise { + const outputPath = resolveInsideRoot(localRoot, outputFile); + const outputDirectory = path.dirname(outputPath); + + await mkdir(outputDirectory, { recursive: true }); + await writeFile(outputPath, `${markdown}\n`, "utf8"); + + return outputPath; +} diff --git a/src/types.ts b/src/types.ts index 864f29f..6bacdf9 100644 --- a/src/types.ts +++ b/src/types.ts @@ -43,8 +43,7 @@ export interface ActionConfig { releaseStream?: number; filePaths: string[]; outputFile: string; - commentPr: boolean; - githubToken: string; + markdownOutputFile: string; } export interface NpmReleaseBaseline { diff --git a/tests/action.test.ts b/tests/action.test.ts index 5b108cf..051fa4a 100644 --- a/tests/action.test.ts +++ b/tests/action.test.ts @@ -96,8 +96,7 @@ async function withActionEnvironment( 'INPUT_RELEASE-STREAM', 'INPUT_FILES', 'INPUT_OUTPUT-FILE', - 'INPUT_COMMENT-PR', - 'INPUT_GITHUB-TOKEN', + 'INPUT_MARKDOWN-OUTPUT-FILE', ]; const previous = new Map(keys.map((key) => [key, process.env[key]])); const previousExitCode = process.exitCode; @@ -109,8 +108,6 @@ async function withActionEnvironment( delete process.env[key]; } - process.env['INPUT_COMMENT-PR'] = 'false'; - for (const [key, value] of Object.entries(env)) { process.env[key] = value; } @@ -198,6 +195,7 @@ test('run writes outputs and a comparison report for mocked axios npm releases', 'INPUT_PACKAGE-NAME': 'axios', INPUT_FILES: 'dist/axios.min.js', 'INPUT_OUTPUT-FILE': 'reports/comparison.json', + 'INPUT_MARKDOWN-OUTPUT-FILE': 'reports/comparison.md', }, async () => { await run(); @@ -209,9 +207,11 @@ test('run writes outputs and a comparison report for mocked axios npm releases', const outputs = parseGithubOutput(await readFile(outputFile, 'utf8')); const comparisonFile = path.join(tempRoot, 'reports/comparison.json'); + const markdownFile = path.join(tempRoot, 'reports/comparison.md'); const report = JSON.parse(await readFile(comparisonFile, 'utf8')) as ComparisonReport; assert.equal(outputs.get('comparison-file'), comparisonFile); + assert.equal(outputs.get('markdown-file'), markdownFile); assert.equal(outputs.get('size'), String(report.totals.currentBytes)); assert.equal(outputs.get('total-current-gzip-size'), String(report.totals.currentBytes)); assert.equal(outputs.get('total-baseline-gzip-size'), String(report.totals.baselineBytes)); @@ -221,6 +221,7 @@ test('run writes outputs and a comparison report for mocked axios npm releases', assert.equal(report.baseline.uri, AXIOS_LATEST_TARBALL_URL); assert.deepEqual(report.history.map((release) => release.version), ['1.12.2', '1.12.1']); assert.deepEqual(report.files.map((file) => file.path), ['dist/axios.min.js']); + assert.match(await readFile(markdownFile, 'utf8'), /## Bundle Size Report/); } finally { global.fetch = originalFetch; await rm(tempRoot, { force: true, recursive: true }); diff --git a/tests/comment.test.ts b/tests/comment.test.ts index 843fbc0..75a49c2 100644 --- a/tests/comment.test.ts +++ b/tests/comment.test.ts @@ -98,6 +98,35 @@ test('renderBundleSizeComment renders files, totals, marker, sizes, and statuses assert.match(markdown, /\| \*\*Total\*\* \| \*\*3\.0 KiB\*\* \| \*\*3\.0 KiB\*\* \| \*\*-8 B \(-0\.26%\)\*\* \| \*\*🟢\*\* \|/); }); +test('renderBundleSizeComment preserves the documented Markdown contract', () => { + assert.equal( + renderBundleSizeComment(createReport()), + [ + BUNDLE_SIZE_COMMENT_MARKER, + '', + '## Bundle Size Report', + '', + 'Compared current build against latest npm release `1.2.0` for `axios`.', + '', + '| File | Baseline gzip | Current gzip | Difference | Status |', + '|---|---:|---:|---:|:---:|', + '| `dist/a.js` | 1.0 KiB | 1.0 KiB | 30 B (+2.93%) | 🔵 |', + '| `dist/b.js` | 2.0 KiB | 2.0 KiB | -38 B (-1.86%) | 🟢 |', + '| **Total** | **3.0 KiB** | **3.0 KiB** | **-8 B (-0.26%)** | **🟢** |', + '', + '
', + 'Historical comparison: latest + 10 previous npm releases', + '', + '| Release | Baseline gzip | Current gzip | Difference | Status |', + '|---|---:|---:|---:|:---:|', + '| `1.2.0` latest | 3.0 KiB | 3.0 KiB | -8 B (-0.26%) | 🟢 |', + '| `1.1.0` | 2.9 KiB | 3.0 KiB | 64 B (+2.13%) | 🔵 |', + '', + '
', + ].join('\n'), + ); +}); + test('renderBundleSizeComment renders historical release summary in details block', () => { const markdown = renderBundleSizeComment(createReport()); diff --git a/tests/config.test.ts b/tests/config.test.ts index e44b449..44840d9 100644 --- a/tests/config.test.ts +++ b/tests/config.test.ts @@ -11,8 +11,7 @@ const INPUT_KEYS = [ 'INPUT_TARBALL-URI', 'INPUT_FILES', 'INPUT_OUTPUT-FILE', - 'INPUT_COMMENT-PR', - 'INPUT_GITHUB-TOKEN', + 'INPUT_MARKDOWN-OUTPUT-FILE', ]; async function withInputs(inputs: Record, callback: () => T): Promise { @@ -23,8 +22,6 @@ async function withInputs(inputs: Record, callback: () => T): delete process.env[key]; } - process.env['INPUT_COMMENT-PR'] = 'false'; - for (const [key, value] of Object.entries(inputs)) { process.env[key] = value; } @@ -79,8 +76,7 @@ test('getConfig reads defaults and parses multiline files input', async () => { releaseStream: undefined, filePaths: ['dist/a.js', 'dist/b.js'], outputFile: 'bundle-size-comparison.json', - commentPr: false, - githubToken: '', + markdownOutputFile: 'bundle-size-comparison.md', }); }, ); @@ -93,6 +89,7 @@ test('getConfig reads explicit path and output file inputs', async () => { 'INPUT_PACKAGE-NAME': '@scope/package', INPUT_FILES: 'dist/a.js', 'INPUT_OUTPUT-FILE': 'reports/result.json', + 'INPUT_MARKDOWN-OUTPUT-FILE': 'reports/result.md', }, () => { assert.deepEqual(getConfig(), { @@ -101,48 +98,12 @@ test('getConfig reads explicit path and output file inputs', async () => { releaseStream: undefined, filePaths: ['dist/a.js'], outputFile: 'reports/result.json', - commentPr: false, - githubToken: '', - }); - }, - ); -}); - -test('getConfig reads PR comment inputs', async () => { - await withInputs( - { - 'INPUT_PACKAGE-NAME': 'axios', - INPUT_FILES: 'dist/a.js', - 'INPUT_COMMENT-PR': 'true', - 'INPUT_GITHUB-TOKEN': 'token-value', - }, - () => { - assert.deepEqual(getConfig(), { - localRoot: path.resolve('.'), - packageName: 'axios', - releaseStream: undefined, - filePaths: ['dist/a.js'], - outputFile: 'bundle-size-comparison.json', - commentPr: true, - githubToken: 'token-value', + markdownOutputFile: 'reports/result.md', }); }, ); }); -test('getConfig requires github-token when PR comments are enabled', async () => { - await withInputs( - { - 'INPUT_PACKAGE-NAME': 'axios', - INPUT_FILES: 'dist/a.js', - 'INPUT_COMMENT-PR': 'true', - }, - () => { - assert.throws(() => getConfig(), /github-token input is required/); - }, - ); -}); - test('getConfig reads valid release stream inputs', async () => { await withInputs( { @@ -204,6 +165,19 @@ test('getConfig rejects invalid output file paths', async () => { ); }); +test('getConfig rejects invalid markdown output file paths', async () => { + await withInputs( + { + 'INPUT_PACKAGE-NAME': 'axios', + INPUT_FILES: 'dist/a.js', + 'INPUT_MARKDOWN-OUTPUT-FILE': '../result.md', + }, + () => { + assert.throws(() => getConfig(), /must be relative/); + }, + ); +}); + test('getConfig does not accept tarball-uri without package-name', async () => { await withInputs( { diff --git a/tests/pr-comment.test.ts b/tests/pr-comment.test.ts deleted file mode 100644 index 8abfdea..0000000 --- a/tests/pr-comment.test.ts +++ /dev/null @@ -1,350 +0,0 @@ -import assert from 'node:assert/strict'; -import { mkdtemp, rm, writeFile } from 'node:fs/promises'; -import os from 'node:os'; -import path from 'node:path'; -import { test } from 'vitest'; - -import { BUNDLE_SIZE_COMMENT_MARKER } from '@/comment'; -import { - getPullRequestNumberFromEvent, - upsertPullRequestComment, -} from '@/pr-comment'; - -interface JsonResponseOptions { - status: number; - body: unknown; - headers?: Record; - statusText?: string; -} - -interface CapturedRequest { - url: string | URL | Request; - options: RequestInit; -} - -async function withGithubEnvironment( - payload: unknown, - callback: () => Promise, -): Promise { - const tempRoot = await mkdtemp(path.join(os.tmpdir(), 'bundle-size-pr-')); - const eventPath = path.join(tempRoot, 'event.json'); - const keys = ['GITHUB_EVENT_PATH', 'GITHUB_REPOSITORY']; - const previous = new Map(keys.map((key) => [key, process.env[key]])); - - try { - await writeFile(eventPath, `${JSON.stringify(payload)}\n`, 'utf8'); - process.env.GITHUB_EVENT_PATH = eventPath; - process.env.GITHUB_REPOSITORY = 'axios/bundle-size'; - - return await callback(); - } finally { - for (const [key, value] of previous) { - if (value === undefined) { - delete process.env[key]; - } else { - process.env[key] = value; - } - } - - await rm(tempRoot, { force: true, recursive: true }); - } -} - -function jsonResponse({ - status, - body, - headers = {}, - statusText = status === 403 ? 'Forbidden' : 'OK', -}: JsonResponseOptions): Response { - return new Response(JSON.stringify(body), { - status, - statusText, - headers, - }); -} - -test('getPullRequestNumberFromEvent reads pull request event payloads', async () => { - await withGithubEnvironment({ number: 42, pull_request: {} }, async () => { - assert.equal(await getPullRequestNumberFromEvent(), 42); - }); -}); - -test('getPullRequestNumberFromEvent returns null without a pull request number', async () => { - await withGithubEnvironment({ ref: 'refs/heads/main' }, async () => { - assert.equal(await getPullRequestNumberFromEvent(), null); - }); -}); - -test('upsertPullRequestComment updates an existing marked comment', async () => { - const originalFetch = global.fetch; - const requests: CapturedRequest[] = []; - - try { - global.fetch = async (url, options = {}) => { - requests.push({ url, options }); - - if (options.method === 'GET') { - return jsonResponse({ - status: 200, - body: [ - { - id: 12, - body: `existing\n${BUNDLE_SIZE_COMMENT_MARKER}`, - user: { login: 'github-actions[bot]', type: 'Bot' }, - }, - ], - }); - } - - assert.equal(options.method, 'PATCH'); - assert.equal(url, 'https://api.github.com/repos/axios/bundle-size/issues/comments/12'); - assert.deepEqual(JSON.parse(String(options.body)), { body: 'new body' }); - return jsonResponse({ status: 200, body: { id: 12, body: 'new body' } }); - }; - - await withGithubEnvironment({ number: 42, pull_request: {} }, async () => { - await upsertPullRequestComment('token-value', 'new body'); - }); - - assert.equal(requests.length, 2); - const [firstRequest] = requests; - assert.ok(firstRequest); - assert.equal(firstRequest.url, 'https://api.github.com/repos/axios/bundle-size/issues/42/comments?per_page=100'); - assert.equal( - (firstRequest.options.headers as Record).authorization, - 'Bearer token-value', - ); - } finally { - global.fetch = originalFetch; - } -}); - -test('upsertPullRequestComment updates marked comments from other bot tokens', async () => { - const originalFetch = global.fetch; - const requests: CapturedRequest[] = []; - - try { - global.fetch = async (url, options = {}) => { - requests.push({ url, options }); - - if (options.method === 'GET') { - return jsonResponse({ - status: 200, - body: [ - { - id: 14, - body: `existing app bot comment\n${BUNDLE_SIZE_COMMENT_MARKER}`, - user: { login: 'bundle-size-app[bot]', type: 'Bot' }, - }, - ], - }); - } - - assert.equal(options.method, 'PATCH'); - assert.equal(url, 'https://api.github.com/repos/axios/bundle-size/issues/comments/14'); - assert.deepEqual(JSON.parse(String(options.body)), { body: 'new body' }); - return jsonResponse({ status: 200, body: { id: 14, body: 'new body' } }); - }; - - await withGithubEnvironment({ number: 42, pull_request: {} }, async () => { - await upsertPullRequestComment('token-value', 'new body'); - }); - - assert.deepEqual( - requests.map((request) => request.options.method), - ['GET', 'PATCH'], - ); - } finally { - global.fetch = originalFetch; - } -}); - -test('upsertPullRequestComment updates marked comments from personal access tokens', async () => { - const originalFetch = global.fetch; - const requests: CapturedRequest[] = []; - - try { - global.fetch = async (url, options = {}) => { - requests.push({ url, options }); - - if (options.method === 'GET') { - return jsonResponse({ - status: 200, - body: [ - { - id: 12, - body: `existing PAT-authored comment\n${BUNDLE_SIZE_COMMENT_MARKER}`, - user: { login: 'octocat', type: 'User' }, - }, - ], - }); - } - - assert.equal(options.method, 'PATCH'); - assert.equal(url, 'https://api.github.com/repos/axios/bundle-size/issues/comments/12'); - assert.deepEqual(JSON.parse(String(options.body)), { body: 'new body' }); - return jsonResponse({ status: 200, body: { id: 12, body: 'new body' } }); - }; - - await withGithubEnvironment({ number: 42, pull_request: {} }, async () => { - await upsertPullRequestComment('token-value', 'new body'); - }); - - assert.deepEqual( - requests.map((request) => request.options.method), - ['GET', 'PATCH'], - ); - } finally { - global.fetch = originalFetch; - } -}); - -test('upsertPullRequestComment searches paginated comments before creating', async () => { - const originalFetch = global.fetch; - const requests: CapturedRequest[] = []; - const nextUrl = 'https://api.github.com/repos/axios/bundle-size/issues/42/comments?per_page=100&page=2'; - - try { - global.fetch = async (url, options = {}) => { - requests.push({ url, options }); - - if (options.method === 'GET' && !String(url).includes('page=2')) { - return jsonResponse({ - status: 200, - body: [{ id: 1, body: 'first page comment' }], - headers: { link: `<${nextUrl}>; rel="next"` }, - }); - } - - if (options.method === 'GET') { - assert.equal(url, nextUrl); - return jsonResponse({ - status: 200, - body: [ - { - id: 99, - body: `second page\n${BUNDLE_SIZE_COMMENT_MARKER}`, - user: { login: 'github-actions[bot]', type: 'Bot' }, - }, - ], - }); - } - - assert.equal(options.method, 'PATCH'); - assert.equal(url, 'https://api.github.com/repos/axios/bundle-size/issues/comments/99'); - assert.deepEqual(JSON.parse(String(options.body)), { body: 'new body' }); - return jsonResponse({ status: 200, body: { id: 99, body: 'new body' } }); - }; - - await withGithubEnvironment({ number: 42, pull_request: {} }, async () => { - await upsertPullRequestComment('token-value', 'new body'); - }); - - assert.deepEqual( - requests.map((request) => request.options.method), - ['GET', 'GET', 'PATCH'], - ); - } finally { - global.fetch = originalFetch; - } -}); - -test('upsertPullRequestComment creates a comment when no marked comment exists', async () => { - const originalFetch = global.fetch; - const requests: CapturedRequest[] = []; - - try { - global.fetch = async (url, options = {}) => { - requests.push({ url, options }); - - if (options.method === 'GET') { - return jsonResponse({ status: 200, body: [{ id: 1, body: 'different comment' }] }); - } - - assert.equal(options.method, 'POST'); - assert.equal(url, 'https://api.github.com/repos/axios/bundle-size/issues/42/comments'); - assert.deepEqual(JSON.parse(String(options.body)), { body: 'new body' }); - return jsonResponse({ status: 201, body: { id: 13, body: 'new body' }, statusText: 'Created' }); - }; - - await withGithubEnvironment({ number: 42, pull_request: {} }, async () => { - await upsertPullRequestComment('token-value', 'new body'); - }); - - assert.equal(requests.length, 2); - } finally { - global.fetch = originalFetch; - } -}); - -test('upsertPullRequestComment skips API calls outside pull request events', async () => { - const originalFetch = global.fetch; - - try { - global.fetch = async () => { - throw new Error('fetch should not be called'); - }; - - await withGithubEnvironment({ ref: 'refs/heads/main' }, async () => { - await upsertPullRequestComment('token-value', 'new body'); - }); - } finally { - global.fetch = originalFetch; - } -}); - -function captureStdout(callback: () => Promise): Promise { - const originalWrite = process.stdout.write.bind(process.stdout); - const chunks: string[] = []; - process.stdout.write = (( - chunk: string | Uint8Array, - encoding?: BufferEncoding | ((error?: Error | null) => void), - done?: (error?: Error | null) => void, - ) => { - chunks.push(typeof chunk === 'string' ? chunk : Buffer.from(chunk).toString('utf8')); - if (typeof encoding === 'function') encoding(); - if (typeof done === 'function') done(); - return true; - }) as typeof process.stdout.write; - return Promise.resolve(callback()) - .then(() => chunks.join('')) - .finally(() => { - process.stdout.write = originalWrite; - }); -} - -test('upsertPullRequestComment warns and continues when the token cannot comment (fork PR)', async () => { - const originalFetch = global.fetch; - - try { - global.fetch = async () => jsonResponse({ status: 403, body: { message: 'Resource not accessible by integration' } }); - - const output = await withGithubEnvironment({ number: 42, pull_request: {} }, async () => - captureStdout(async () => { - await upsertPullRequestComment('token-value', 'new body'); - }), - ); - - assert.match(output, /::warning::Skipping bundle size PR comment/); - assert.match(output, /permission to write pull request or issue comments/); - } finally { - global.fetch = originalFetch; - } -}); - -test('upsertPullRequestComment rethrows non-permission GitHub API errors', async () => { - const originalFetch = global.fetch; - - try { - global.fetch = async () => jsonResponse({ status: 500, body: { message: 'Server error' } }); - - await withGithubEnvironment({ number: 42, pull_request: {} }, async () => { - await assert.rejects( - upsertPullRequestComment('token-value', 'new body'), - /GitHub comments API request failed \(500/, - ); - }); - } finally { - global.fetch = originalFetch; - } -}); diff --git a/tests/report.test.ts b/tests/report.test.ts index 73557f7..ccf3df6 100644 --- a/tests/report.test.ts +++ b/tests/report.test.ts @@ -4,7 +4,7 @@ import os from 'node:os'; import path from 'node:path'; import { test } from 'vitest'; -import { writeComparisonReport } from '@/report'; +import { writeComparisonReport, writeMarkdownReport } from '@/report'; import type { ComparisonReport } from '@/types'; function createReport(): ComparisonReport { @@ -115,3 +115,29 @@ test('writeComparisonReport rejects unsafe output paths', async () => { await rm(localRoot, { force: true, recursive: true }); } }); + +test('writeMarkdownReport writes Markdown with trailing newline', async () => { + const localRoot = await mkdtemp(path.join(os.tmpdir(), 'bundle-size-')); + + try { + const outputPath = await writeMarkdownReport(localRoot, 'reports/comparison.md', '## Report'); + + assert.equal(outputPath, path.join(localRoot, 'reports/comparison.md')); + assert.equal(await readFile(outputPath, 'utf8'), '## Report\n'); + } finally { + await rm(localRoot, { force: true, recursive: true }); + } +}); + +test('writeMarkdownReport rejects unsafe output paths', async () => { + const localRoot = await mkdtemp(path.join(os.tmpdir(), 'bundle-size-')); + + try { + await assert.rejects( + writeMarkdownReport(localRoot, '../comparison.md', '## Report'), + /stay inside/, + ); + } finally { + await rm(localRoot, { force: true, recursive: true }); + } +}); From 2a70bd9f51faf3eba30438101deb0395d389f1b0 Mon Sep 17 00:00:00 2001 From: Jason Saayman Date: Tue, 19 May 2026 13:39:30 +0200 Subject: [PATCH 2/2] chore: cubic feedback --- dist/index.js | 2 +- src/report.ts | 22 ++++++++++++---------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/dist/index.js b/dist/index.js index 947054c..771ecda 100644 --- a/dist/index.js +++ b/dist/index.js @@ -16,4 +16,4 @@ ${e.format(t)} `.trim())}}})),Fe=o(((e,t)=>{var n=Symbol.for(`undici.globalDispatcher.1`),{InvalidArgumentError:r}=M(),i=Q();o()===void 0&&a(new i);function a(e){if(!e||typeof e.dispatch!=`function`)throw new r(`Argument agent must implement Agent`);Object.defineProperty(globalThis,n,{value:e,writable:!0,enumerable:!1,configurable:!1})}function o(){return globalThis[n]}t.exports={setGlobalDispatcher:a,getGlobalDispatcher:o}})),Ie=o(((e,t)=>{t.exports=class{#e;constructor(e){if(typeof e!=`object`||!e)throw TypeError(`handler must be an object`);this.#e=e}onConnect(...e){return this.#e.onConnect?.(...e)}onError(...e){return this.#e.onError?.(...e)}onUpgrade(...e){return this.#e.onUpgrade?.(...e)}onResponseStarted(...e){return this.#e.onResponseStarted?.(...e)}onHeaders(...e){return this.#e.onHeaders?.(...e)}onData(...e){return this.#e.onData?.(...e)}onComplete(...e){return this.#e.onComplete?.(...e)}onBodySent(...e){return this.#e.onBodySent?.(...e)}}})),Le=o(((e,t)=>{var n=ce();t.exports=e=>{let t=e?.maxRedirections;return e=>function(r,i){let{maxRedirections:a=t,...o}=r;return a?e(o,new n(e,a,r,i)):e(r,i)}}})),Re=o(((e,t)=>{var n=he();t.exports=e=>t=>function(r,i){return t(r,new n({...r,retryOptions:{...e,...r.retryOptions}},{handler:i,dispatch:t}))}})),ze=o(((e,t)=>{var n=F(),{InvalidArgumentError:r,RequestAbortedError:i}=M(),a=Ie(),o=class extends a{#e=1024*1024;#t=null;#n=!1;#r=!1;#i=0;#a=null;#o=null;constructor({maxSize:e},t){if(super(t),e!=null&&(!Number.isFinite(e)||e<1))throw new r(`maxSize must be a number greater than 0`);this.#e=e??this.#e,this.#o=t}onConnect(e){this.#t=e,this.#o.onConnect(this.#s.bind(this))}#s(e){this.#r=!0,this.#a=e}onHeaders(e,t,r,a){let o=n.parseHeaders(t)[`content-length`];if(o!=null&&o>this.#e)throw new i(`Response size (${o}) larger than maxSize (${this.#e})`);return this.#r?!0:this.#o.onHeaders(e,t,r,a)}onError(e){this.#n||(e=this.#a??e,this.#o.onError(e))}onData(e){return this.#i+=e.length,this.#i>=this.#e&&(this.#n=!0,this.#r?this.#o.onError(this.#a):this.#o.onComplete([])),!0}onComplete(e){if(!this.#n){if(this.#r){this.#o.onError(this.reason);return}this.#o.onComplete(e)}}};function s({maxSize:e}={maxSize:1024*1024}){return t=>function(n,r){let{dumpMaxSize:i=e}=n;return t(n,new o({maxSize:i},r))}}t.exports=s})),Be=o(((e,t)=>{var{isIP:n}=require(`node:net`),{lookup:r}=require(`node:dns`),i=Ie(),{InvalidArgumentError:a,InformationalError:o}=M(),s=2**31-1,c=class{#e=0;#t=0;#n=new Map;dualStack=!0;affinity=null;lookup=null;pick=null;constructor(e){this.#e=e.maxTTL,this.#t=e.maxItems,this.dualStack=e.dualStack,this.affinity=e.affinity,this.lookup=e.lookup??this.#r,this.pick=e.pick??this.#i}get full(){return this.#n.size===this.#t}runLookup(e,t,n){let r=this.#n.get(e.hostname);if(r==null&&this.full){n(null,e.origin);return}let i={affinity:this.affinity,dualStack:this.dualStack,lookup:this.lookup,pick:this.pick,...t.dns,maxTTL:this.#e,maxItems:this.#t};if(r==null)this.lookup(e,i,(t,r)=>{if(t||r==null||r.length===0){n(t??new o(`No DNS entries found`));return}this.setRecords(e,r);let a=this.#n.get(e.hostname),s=this.pick(e,a,i.affinity),c;c=typeof s.port==`number`?`:${s.port}`:e.port===``?``:`:${e.port}`,n(null,`${e.protocol}//${s.family===6?`[${s.address}]`:s.address}${c}`)});else{let a=this.pick(e,r,i.affinity);if(a==null){this.#n.delete(e.hostname),this.runLookup(e,t,n);return}let o;o=typeof a.port==`number`?`:${a.port}`:e.port===``?``:`:${e.port}`,n(null,`${e.protocol}//${a.family===6?`[${a.address}]`:a.address}${o}`)}}#r(e,t,n){r(e.hostname,{all:!0,family:this.dualStack===!1?this.affinity:0,order:`ipv4first`},(e,t)=>{if(e)return n(e);let r=new Map;for(let e of t)r.set(`${e.address}:${e.family}`,e);n(null,r.values())})}#i(e,t,n){let r=null,{records:i,offset:a}=t,o;if(this.dualStack?(n??(a==null||a===s?(t.offset=0,n=4):(t.offset++,n=(t.offset&1)==1?6:4)),o=i[n]!=null&&i[n].ips.length>0?i[n]:i[n===4?6:4]):o=i[n],o==null||o.ips.length===0)return r;o.offset==null||o.offset===s?o.offset=0:o.offset++;let c=o.offset%o.ips.length;return r=o.ips[c]??null,r==null?r:Date.now()-r.timestamp>r.ttl?(o.ips.splice(c,1),this.pick(e,t,n)):r}setRecords(e,t){let n=Date.now(),r={records:{4:null,6:null}};for(let e of t){e.timestamp=n,typeof e.ttl==`number`?e.ttl=Math.min(e.ttl,this.#e):e.ttl=this.#e;let t=r.records[e.family]??{ips:[]};t.ips.push(e),r.records[e.family]=t}this.#n.set(e.hostname,r)}getHandler(e,t){return new l(this,e,t)}},l=class extends i{#e=null;#t=null;#n=null;#r=null;#i=null;constructor(e,{origin:t,handler:n,dispatch:r},i){super(n),this.#i=t,this.#r=n,this.#t={...i},this.#e=e,this.#n=r}onError(e){switch(e.code){case`ETIMEDOUT`:case`ECONNREFUSED`:if(this.#e.dualStack){this.#e.runLookup(this.#i,this.#t,(e,t)=>{if(e)return this.#r.onError(e);let n={...this.#t,origin:t};this.#n(n,this)});return}this.#r.onError(e);return;case`ENOTFOUND`:this.#e.deleteRecord(this.#i);default:this.#r.onError(e);break}}};t.exports=e=>{if(e?.maxTTL!=null&&(typeof e?.maxTTL!=`number`||e?.maxTTL<0))throw new a(`Invalid maxTTL. Must be a positive number`);if(e?.maxItems!=null&&(typeof e?.maxItems!=`number`||e?.maxItems<1))throw new a(`Invalid maxItems. Must be a positive number and greater than zero`);if(e?.affinity!=null&&e?.affinity!==4&&e?.affinity!==6)throw new a(`Invalid affinity. Must be either 4 or 6`);if(e?.dualStack!=null&&typeof e?.dualStack!=`boolean`)throw new a(`Invalid dualStack. Must be a boolean`);if(e?.lookup!=null&&typeof e?.lookup!=`function`)throw new a(`Invalid lookup. Must be a function`);if(e?.pick!=null&&typeof e?.pick!=`function`)throw new a(`Invalid pick. Must be a function`);let t=e?.dualStack??!0,r;r=t?e?.affinity??null:e?.affinity??4;let i=new c({maxTTL:e?.maxTTL??1e4,lookup:e?.lookup??null,pick:e?.pick??null,dualStack:t,affinity:r,maxItems:e?.maxItems??1/0});return e=>function(t,r){let a=t.origin.constructor===URL?t.origin:new URL(t.origin);return n(a.hostname)===0?(i.runLookup(a,t,(n,o)=>{if(n)return r.onError(n);let s=null;s={...t,servername:a.hostname,origin:o,headers:{host:a.hostname,...t.headers}},e(s,i.getHandler({origin:a,dispatch:e,handler:r},t))}),!0):e(t,r)}}})),Ve=o(((e,t)=>{var{kConstruct:n}=j(),{kEnumerableProperty:r}=F(),{iteratorMixin:i,isValidHeaderName:a,isValidHeaderValue:o}=W(),{webidl:s}=U(),c=require(`node:assert`),l=require(`node:util`),u=Symbol(`headers map`),d=Symbol(`headers map sorted`);function f(e){return e===10||e===13||e===9||e===32}function p(e){let t=0,n=e.length;for(;n>t&&f(e.charCodeAt(n-1));)--n;for(;n>t&&f(e.charCodeAt(t));)++t;return t===0&&n===e.length?e:e.substring(t,n)}function m(e,t){if(Array.isArray(t))for(let n=0;n>`,`record`]})}function h(e,t,n){if(n=p(n),!a(t))throw s.errors.invalidArgument({prefix:`Headers.append`,value:t,type:`header name`});if(!o(n))throw s.errors.invalidArgument({prefix:`Headers.append`,value:n,type:`header value`});if(y(e)===`immutable`)throw TypeError(`immutable`);return x(e).append(t,n,!1)}function g(e,t){return e[0]>1),t[s][0]<=l[0]?o=s+1:a=s;if(r!==s){for(i=r;i>o;)t[i]=t[--i];t[o]=l}}if(!n.next().done)throw TypeError(`Unreachable`);return t}else{let e=0;for(let{0:n,1:{value:r}}of this[u])t[e++]=[n,r],c(r!==null);return t.sort(g)}}},v=class e{#e;#t;constructor(e=void 0){s.util.markAsUncloneable(this),e!==n&&(this.#t=new _,this.#e=`none`,e!==void 0&&(e=s.converters.HeadersInit(e,`Headers contructor`,`init`),m(this,e)))}append(t,n){s.brandCheck(this,e),s.argumentLengthCheck(arguments,2,`Headers.append`);let r=`Headers.append`;return t=s.converters.ByteString(t,r,`name`),n=s.converters.ByteString(n,r,`value`),h(this,t,n)}delete(t){if(s.brandCheck(this,e),s.argumentLengthCheck(arguments,1,`Headers.delete`),t=s.converters.ByteString(t,`Headers.delete`,`name`),!a(t))throw s.errors.invalidArgument({prefix:`Headers.delete`,value:t,type:`header name`});if(this.#e===`immutable`)throw TypeError(`immutable`);this.#t.contains(t,!1)&&this.#t.delete(t,!1)}get(t){s.brandCheck(this,e),s.argumentLengthCheck(arguments,1,`Headers.get`);let n=`Headers.get`;if(t=s.converters.ByteString(t,n,`name`),!a(t))throw s.errors.invalidArgument({prefix:n,value:t,type:`header name`});return this.#t.get(t,!1)}has(t){s.brandCheck(this,e),s.argumentLengthCheck(arguments,1,`Headers.has`);let n=`Headers.has`;if(t=s.converters.ByteString(t,n,`name`),!a(t))throw s.errors.invalidArgument({prefix:n,value:t,type:`header name`});return this.#t.contains(t,!1)}set(t,n){s.brandCheck(this,e),s.argumentLengthCheck(arguments,2,`Headers.set`);let r=`Headers.set`;if(t=s.converters.ByteString(t,r,`name`),n=s.converters.ByteString(n,r,`value`),n=p(n),!a(t))throw s.errors.invalidArgument({prefix:r,value:t,type:`header name`});if(!o(n))throw s.errors.invalidArgument({prefix:r,value:n,type:`header value`});if(this.#e===`immutable`)throw TypeError(`immutable`);this.#t.set(t,n,!1)}getSetCookie(){s.brandCheck(this,e);let t=this.#t.cookies;return t?[...t]:[]}get[d](){if(this.#t[d])return this.#t[d];let e=[],t=this.#t.toSortedArray(),n=this.#t.cookies;if(n===null||n.length===1)return this.#t[d]=t;for(let r=0;r>`](e,t,n,r.bind(e)):s.converters[`record`](e,t,n)}throw s.errors.conversionFailed({prefix:`Headers constructor`,argument:`Argument 1`,types:[`sequence>`,`record`]})},t.exports={fill:m,compareHeaderName:g,Headers:v,HeadersList:_,getHeadersGuard:y,setHeadersGuard:b,setHeadersList:S,getHeadersList:x}})),He=o(((e,t)=>{var{Headers:n,HeadersList:r,fill:i,getHeadersGuard:a,setHeadersGuard:o,setHeadersList:s}=Ve(),{extractBody:c,cloneBody:l,mixinBody:u,hasFinalizationRegistry:d,streamRegistry:f,bodyUnusable:p}=oe(),m=F(),h=require(`node:util`),{kEnumerableProperty:g}=m,{isValidReasonPhrase:_,isCancelled:v,isAborted:y,isBlobLike:b,serializeJavascriptValueToJSONString:x,isErrorLike:S,isomorphicEncode:C,environmentSettingsObject:w}=W(),{redirectStatusSet:T,nullBodyStatus:E}=ie(),{kState:D,kHeaders:O}=G(),{webidl:k}=U(),{FormData:A}=q(),{URLSerializer:M}=H(),{kConstruct:N}=j(),P=require(`node:assert`),{types:I}=require(`node:util`),L=new TextEncoder(`utf-8`),R=class e{static error(){return K(V(),`immutable`)}static json(e,t={}){k.argumentLengthCheck(arguments,1,`Response.json`),t!==null&&(t=k.converters.ResponseInit(t));let n=c(L.encode(x(e))),r=K(B({}),`response`);return ae(r,t,{body:n[0],type:`application/json`}),r}static redirect(e,t=302){k.argumentLengthCheck(arguments,1,`Response.redirect`),e=k.converters.USVString(e),t=k.converters[`unsigned short`](t);let n;try{n=new URL(e,w.settingsObject.baseUrl)}catch(t){throw TypeError(`Failed to parse URL from ${e}`,{cause:t})}if(!T.has(t))throw RangeError(`Invalid status code ${t}`);let r=K(B({}),`immutable`);r[D].status=t;let i=C(M(n));return r[D].headersList.append(`location`,i,!0),r}constructor(e=null,t={}){if(k.util.markAsUncloneable(this),e===N)return;e!==null&&(e=k.converters.BodyInit(e)),t=k.converters.ResponseInit(t),this[D]=B({}),this[O]=new n(N),o(this[O],`response`),s(this[O],this[D].headersList);let r=null;if(e!=null){let[t,n]=c(e);r={body:t,type:n}}ae(this,t,r)}get type(){return k.brandCheck(this,e),this[D].type}get url(){k.brandCheck(this,e);let t=this[D].urlList,n=t[t.length-1]??null;return n===null?``:M(n,!0)}get redirected(){return k.brandCheck(this,e),this[D].urlList.length>1}get status(){return k.brandCheck(this,e),this[D].status}get ok(){return k.brandCheck(this,e),this[D].status>=200&&this[D].status<=299}get statusText(){return k.brandCheck(this,e),this[D].statusText}get headers(){return k.brandCheck(this,e),this[O]}get body(){return k.brandCheck(this,e),this[D].body?this[D].body.stream:null}get bodyUsed(){return k.brandCheck(this,e),!!this[D].body&&m.isDisturbed(this[D].body.stream)}clone(){if(k.brandCheck(this,e),p(this))throw k.errors.exception({header:`Response.clone`,message:`Body has already been consumed.`});let t=z(this[D]);return d&&this[D].body?.stream&&f.register(this,new WeakRef(this[D].body.stream)),K(t,a(this[O]))}[h.inspect.custom](e,t){t.depth===null&&(t.depth=2),t.colors??=!0;let n={status:this.status,statusText:this.statusText,headers:this.headers,body:this.body,bodyUsed:this.bodyUsed,ok:this.ok,redirected:this.redirected,type:this.type,url:this.url};return`Response ${h.formatWithOptions(t,n)}`}};u(R),Object.defineProperties(R.prototype,{type:g,url:g,status:g,ok:g,redirected:g,statusText:g,headers:g,clone:g,body:g,bodyUsed:g,[Symbol.toStringTag]:{value:`Response`,configurable:!0}}),Object.defineProperties(R,{json:g,redirect:g,error:g});function z(e){if(e.internalResponse)return ne(z(e.internalResponse),e.type);let t=B({...e,body:null});return e.body!=null&&(t.body=l(t,e.body)),t}function B(e){return{aborted:!1,rangeRequested:!1,timingAllowPassed:!1,requestIncludesCredentials:!1,type:`default`,status:200,timingInfo:null,cacheState:``,statusText:``,...e,headersList:e?.headersList?new r(e?.headersList):new r,urlList:e?.urlList?[...e.urlList]:[]}}function V(e){return B({type:`error`,status:0,error:S(e)?e:Error(e&&String(e)),aborted:e&&e.name===`AbortError`})}function ee(e){return e.type===`error`&&e.status===0}function te(e,t){return t={internalResponse:e,...t},new Proxy(e,{get(e,n){return n in t?t[n]:e[n]},set(e,n,r){return P(!(n in t)),e[n]=r,!0}})}function ne(e,t){if(t===`basic`)return te(e,{type:`basic`,headersList:e.headersList});if(t===`cors`)return te(e,{type:`cors`,headersList:e.headersList});if(t===`opaque`)return te(e,{type:`opaque`,urlList:Object.freeze([]),status:0,statusText:``,body:null});if(t===`opaqueredirect`)return te(e,{type:`opaqueredirect`,status:0,statusText:``,headersList:[],body:null});P(!1)}function re(e,t=null){return P(v(e)),y(e)?V(Object.assign(new DOMException(`The operation was aborted.`,`AbortError`),{cause:t})):V(Object.assign(new DOMException(`Request was cancelled.`),{cause:t}))}function ae(e,t,n){if(t.status!==null&&(t.status<200||t.status>599))throw RangeError(`init["status"] must be in the range of 200 to 599, inclusive.`);if(`statusText`in t&&t.statusText!=null&&!_(String(t.statusText)))throw TypeError(`Invalid statusText`);if(`status`in t&&t.status!=null&&(e[D].status=t.status),`statusText`in t&&t.statusText!=null&&(e[D].statusText=t.statusText),`headers`in t&&t.headers!=null&&i(e[O],t.headers),n){if(E.includes(e.status))throw k.errors.exception({header:`Response constructor`,message:`Invalid response status code ${e.status}`});e[D].body=n.body,n.type!=null&&!e[D].headersList.contains(`content-type`,!0)&&e[D].headersList.append(`content-type`,n.type,!0)}}function K(e,t){let r=new R(N);return r[D]=e,r[O]=new n(N),s(r[O],e.headersList),o(r[O],t),d&&e.body?.stream&&f.register(r,new WeakRef(e.body.stream)),r}k.converters.ReadableStream=k.interfaceConverter(ReadableStream),k.converters.FormData=k.interfaceConverter(A),k.converters.URLSearchParams=k.interfaceConverter(URLSearchParams),k.converters.XMLHttpRequestBodyInit=function(e,t,n){return typeof e==`string`?k.converters.USVString(e,t,n):b(e)?k.converters.Blob(e,t,n,{strict:!1}):ArrayBuffer.isView(e)||I.isArrayBuffer(e)?k.converters.BufferSource(e,t,n):m.isFormDataLike(e)?k.converters.FormData(e,t,n,{strict:!1}):e instanceof URLSearchParams?k.converters.URLSearchParams(e,t,n):k.converters.DOMString(e,t,n)},k.converters.BodyInit=function(e,t,n){return e instanceof ReadableStream?k.converters.ReadableStream(e,t,n):e?.[Symbol.asyncIterator]?e:k.converters.XMLHttpRequestBodyInit(e,t,n)},k.converters.ResponseInit=k.dictionaryConverter([{key:`status`,converter:k.converters[`unsigned short`],defaultValue:()=>200},{key:`statusText`,converter:k.converters.ByteString,defaultValue:()=>``},{key:`headers`,converter:k.converters.HeadersInit}]),t.exports={isNetworkError:ee,makeNetworkError:V,makeResponse:B,makeAppropriateNetworkError:re,filterResponse:ne,Response:R,cloneResponse:z,fromInnerResponse:K}})),Ue=o(((e,t)=>{var{kConnected:n,kSize:r}=j(),i=class{constructor(e){this.value=e}deref(){return this.value[n]===0&&this.value[r]===0?void 0:this.value}},a=class{constructor(e){this.finalizer=e}register(e,t){e.on&&e.on(`disconnect`,()=>{e[n]===0&&e[r]===0&&this.finalizer(t)})}unregister(e){}};t.exports=function(){return process.env.NODE_V8_COVERAGE&&process.version.startsWith(`v18`)?(process._rawDebug(`Using compatibility WeakRef and FinalizationRegistry`),{WeakRef:i,FinalizationRegistry:a}):{WeakRef,FinalizationRegistry}}})),We=o(((e,t)=>{var{extractBody:n,mixinBody:r,cloneBody:i,bodyUnusable:a}=oe(),{Headers:o,fill:s,HeadersList:c,setHeadersGuard:l,getHeadersGuard:u,setHeadersList:d,getHeadersList:f}=Ve(),{FinalizationRegistry:p}=Ue()(),m=F(),h=require(`node:util`),{isValidHTTPToken:g,sameOrigin:_,environmentSettingsObject:v}=W(),{forbiddenMethodsSet:y,corsSafeListedMethodsSet:b,referrerPolicy:x,requestRedirect:S,requestMode:C,requestCredentials:w,requestCache:T,requestDuplex:E}=ie(),{kEnumerableProperty:D,normalizedMethodRecordsBase:O,normalizedMethodRecords:k}=m,{kHeaders:A,kSignal:M,kState:N,kDispatcher:P}=G(),{webidl:I}=U(),{URLSerializer:L}=H(),{kConstruct:R}=j(),z=require(`node:assert`),{getMaxListeners:B,setMaxListeners:V,getEventListeners:ee,defaultMaxListeners:te}=require(`node:events`),ne=Symbol(`abortController`),re=new p(({signal:e,abort:t})=>{e.removeEventListener(`abort`,t)}),ae=new WeakMap;function K(e){return t;function t(){let n=e.deref();if(n!==void 0){re.unregister(t),this.removeEventListener(`abort`,t),n.abort(this.reason);let e=ae.get(n.signal);if(e!==void 0){if(e.size!==0){for(let t of e){let e=t.deref();e!==void 0&&e.abort(this.reason)}e.clear()}ae.delete(n.signal)}}}}var q=!1,J=class e{constructor(t,r={}){if(I.util.markAsUncloneable(this),t===R)return;let i=`Request constructor`;I.argumentLengthCheck(arguments,1,i),t=I.converters.RequestInfo(t,i,`input`),r=I.converters.RequestInit(r,i,`init`);let u=null,p=null,h=v.settingsObject.baseUrl,x=null;if(typeof t==`string`){this[P]=r.dispatcher;let e;try{e=new URL(t,h)}catch(e){throw TypeError(`Failed to parse URL from `+t,{cause:e})}if(e.username||e.password)throw TypeError(`Request cannot be constructed from a URL that includes credentials: `+t);u=Y({urlList:[e]}),p=`cors`}else this[P]=r.dispatcher||t[P],z(t instanceof e),u=t[N],x=t[M];let S=v.settingsObject.origin,C=`client`;if(u.window?.constructor?.name===`EnvironmentSettingsObject`&&_(u.window,S)&&(C=u.window),r.window!=null)throw TypeError(`'window' option '${C}' must be null`);`window`in r&&(C=`no-window`),u=Y({method:u.method,headersList:u.headersList,unsafeRequest:u.unsafeRequest,client:v.settingsObject,window:C,priority:u.priority,origin:u.origin,referrer:u.referrer,referrerPolicy:u.referrerPolicy,mode:u.mode,credentials:u.credentials,cache:u.cache,redirect:u.redirect,integrity:u.integrity,keepalive:u.keepalive,reloadNavigation:u.reloadNavigation,historyNavigation:u.historyNavigation,urlList:[...u.urlList]});let w=Object.keys(r).length!==0;if(w&&(u.mode===`navigate`&&(u.mode=`same-origin`),u.reloadNavigation=!1,u.historyNavigation=!1,u.origin=`client`,u.referrer=`client`,u.referrerPolicy=``,u.url=u.urlList[u.urlList.length-1],u.urlList=[u.url]),r.referrer!==void 0){let e=r.referrer;if(e===``)u.referrer=`no-referrer`;else{let t;try{t=new URL(e,h)}catch(t){throw TypeError(`Referrer "${e}" is not a valid URL.`,{cause:t})}t.protocol===`about:`&&t.hostname===`client`||S&&!_(t,v.settingsObject.baseUrl)?u.referrer=`client`:u.referrer=t}}r.referrerPolicy!==void 0&&(u.referrerPolicy=r.referrerPolicy);let T;if(T=r.mode===void 0?p:r.mode,T===`navigate`)throw I.errors.exception({header:`Request constructor`,message:`invalid request mode navigate.`});if(T!=null&&(u.mode=T),r.credentials!==void 0&&(u.credentials=r.credentials),r.cache!==void 0&&(u.cache=r.cache),u.cache===`only-if-cached`&&u.mode!==`same-origin`)throw TypeError(`'only-if-cached' can be set only with 'same-origin' mode`);if(r.redirect!==void 0&&(u.redirect=r.redirect),r.integrity!=null&&(u.integrity=String(r.integrity)),r.keepalive!==void 0&&(u.keepalive=!!r.keepalive),r.method!==void 0){let e=r.method,t=k[e];if(t!==void 0)u.method=t;else{if(!g(e))throw TypeError(`'${e}' is not a valid HTTP method.`);let t=e.toUpperCase();if(y.has(t))throw TypeError(`'${e}' HTTP method is unsupported.`);e=O[t]??e,u.method=e}!q&&u.method===`patch`&&(process.emitWarning("Using `patch` is highly likely to result in a `405 Method Not Allowed`. `PATCH` is much more likely to succeed.",{code:`UNDICI-FETCH-patch`}),q=!0)}r.signal!==void 0&&(x=r.signal),this[N]=u;let E=new AbortController;if(this[M]=E.signal,x!=null){if(!x||typeof x.aborted!=`boolean`||typeof x.addEventListener!=`function`)throw TypeError(`Failed to construct 'Request': member signal is not of type AbortSignal.`);if(x.aborted)E.abort(x.reason);else{this[ne]=E;let e=K(new WeakRef(E));try{(typeof B==`function`&&B(x)===te||ee(x,`abort`).length>=te)&&V(1500,x)}catch{}m.addAbortListener(x,e),re.register(E,{signal:x,abort:e},e)}}if(this[A]=new o(R),d(this[A],u.headersList),l(this[A],`request`),T===`no-cors`){if(!b.has(u.method))throw TypeError(`'${u.method} is unsupported in no-cors mode.`);l(this[A],`request-no-cors`)}if(w){let e=f(this[A]),t=r.headers===void 0?new c(e):r.headers;if(e.clear(),t instanceof c){for(let{name:n,value:r}of t.rawValues())e.append(n,r,!1);e.cookies=t.cookies}else s(this[A],t)}let D=t instanceof e?t[N].body:null;if((r.body!=null||D!=null)&&(u.method===`GET`||u.method===`HEAD`))throw TypeError(`Request with GET/HEAD method cannot have body.`);let j=null;if(r.body!=null){let[e,t]=n(r.body,u.keepalive);j=e,t&&!f(this[A]).contains(`content-type`,!0)&&this[A].append(`content-type`,t)}let F=j??D;if(F!=null&&F.source==null){if(j!=null&&r.duplex==null)throw TypeError(`RequestInit: duplex option is required when sending a body.`);if(u.mode!==`same-origin`&&u.mode!==`cors`)throw TypeError(`If request is made from ReadableStream, mode should be "same-origin" or "cors"`);u.useCORSPreflightFlag=!0}let L=F;if(j==null&&D!=null){if(a(t))throw TypeError(`Cannot construct a Request with a Request object that has already been used.`);let e=new TransformStream;D.stream.pipeThrough(e),L={source:D.source,length:D.length,stream:e.readable}}this[N].body=L}get method(){return I.brandCheck(this,e),this[N].method}get url(){return I.brandCheck(this,e),L(this[N].url)}get headers(){return I.brandCheck(this,e),this[A]}get destination(){return I.brandCheck(this,e),this[N].destination}get referrer(){return I.brandCheck(this,e),this[N].referrer===`no-referrer`?``:this[N].referrer===`client`?`about:client`:this[N].referrer.toString()}get referrerPolicy(){return I.brandCheck(this,e),this[N].referrerPolicy}get mode(){return I.brandCheck(this,e),this[N].mode}get credentials(){return this[N].credentials}get cache(){return I.brandCheck(this,e),this[N].cache}get redirect(){return I.brandCheck(this,e),this[N].redirect}get integrity(){return I.brandCheck(this,e),this[N].integrity}get keepalive(){return I.brandCheck(this,e),this[N].keepalive}get isReloadNavigation(){return I.brandCheck(this,e),this[N].reloadNavigation}get isHistoryNavigation(){return I.brandCheck(this,e),this[N].historyNavigation}get signal(){return I.brandCheck(this,e),this[M]}get body(){return I.brandCheck(this,e),this[N].body?this[N].body.stream:null}get bodyUsed(){return I.brandCheck(this,e),!!this[N].body&&m.isDisturbed(this[N].body.stream)}get duplex(){return I.brandCheck(this,e),`half`}clone(){if(I.brandCheck(this,e),a(this))throw TypeError(`unusable`);let t=se(this[N]),n=new AbortController;if(this.signal.aborted)n.abort(this.signal.reason);else{let e=ae.get(this.signal);e===void 0&&(e=new Set,ae.set(this.signal,e));let t=new WeakRef(n);e.add(t),m.addAbortListener(n.signal,K(t))}return ce(t,n.signal,u(this[A]))}[h.inspect.custom](e,t){t.depth===null&&(t.depth=2),t.colors??=!0;let n={method:this.method,url:this.url,headers:this.headers,destination:this.destination,referrer:this.referrer,referrerPolicy:this.referrerPolicy,mode:this.mode,credentials:this.credentials,cache:this.cache,redirect:this.redirect,integrity:this.integrity,keepalive:this.keepalive,isReloadNavigation:this.isReloadNavigation,isHistoryNavigation:this.isHistoryNavigation,signal:this.signal};return`Request ${h.formatWithOptions(t,n)}`}};r(J);function Y(e){return{method:e.method??`GET`,localURLsOnly:e.localURLsOnly??!1,unsafeRequest:e.unsafeRequest??!1,body:e.body??null,client:e.client??null,reservedClient:e.reservedClient??null,replacesClientId:e.replacesClientId??``,window:e.window??`client`,keepalive:e.keepalive??!1,serviceWorkers:e.serviceWorkers??`all`,initiator:e.initiator??``,destination:e.destination??``,priority:e.priority??null,origin:e.origin??`client`,policyContainer:e.policyContainer??`client`,referrer:e.referrer??`client`,referrerPolicy:e.referrerPolicy??``,mode:e.mode??`no-cors`,useCORSPreflightFlag:e.useCORSPreflightFlag??!1,credentials:e.credentials??`same-origin`,useCredentials:e.useCredentials??!1,cache:e.cache??`default`,redirect:e.redirect??`follow`,integrity:e.integrity??``,cryptoGraphicsNonceMetadata:e.cryptoGraphicsNonceMetadata??``,parserMetadata:e.parserMetadata??``,reloadNavigation:e.reloadNavigation??!1,historyNavigation:e.historyNavigation??!1,userActivation:e.userActivation??!1,taintedOrigin:e.taintedOrigin??!1,redirectCount:e.redirectCount??0,responseTainting:e.responseTainting??`basic`,preventNoCacheCacheControlHeaderModification:e.preventNoCacheCacheControlHeaderModification??!1,done:e.done??!1,timingAllowFailed:e.timingAllowFailed??!1,urlList:e.urlList,url:e.urlList[0],headersList:e.headersList?new c(e.headersList):new c}}function se(e){let t=Y({...e,body:null});return e.body!=null&&(t.body=i(t,e.body)),t}function ce(e,t,n){let r=new J(R);return r[N]=e,r[M]=t,r[A]=new o(R),d(r[A],e.headersList),l(r[A],n),r}Object.defineProperties(J.prototype,{method:D,url:D,headers:D,redirect:D,clone:D,signal:D,duplex:D,destination:D,body:D,bodyUsed:D,isHistoryNavigation:D,isReloadNavigation:D,keepalive:D,integrity:D,cache:D,credentials:D,attribute:D,referrerPolicy:D,referrer:D,mode:D,[Symbol.toStringTag]:{value:`Request`,configurable:!0}}),I.converters.Request=I.interfaceConverter(J),I.converters.RequestInfo=function(e,t,n){return typeof e==`string`?I.converters.USVString(e,t,n):e instanceof J?I.converters.Request(e,t,n):I.converters.USVString(e,t,n)},I.converters.AbortSignal=I.interfaceConverter(AbortSignal),I.converters.RequestInit=I.dictionaryConverter([{key:`method`,converter:I.converters.ByteString},{key:`headers`,converter:I.converters.HeadersInit},{key:`body`,converter:I.nullableConverter(I.converters.BodyInit)},{key:`referrer`,converter:I.converters.USVString},{key:`referrerPolicy`,converter:I.converters.DOMString,allowedValues:x},{key:`mode`,converter:I.converters.DOMString,allowedValues:C},{key:`credentials`,converter:I.converters.DOMString,allowedValues:w},{key:`cache`,converter:I.converters.DOMString,allowedValues:T},{key:`redirect`,converter:I.converters.DOMString,allowedValues:S},{key:`integrity`,converter:I.converters.DOMString},{key:`keepalive`,converter:I.converters.boolean},{key:`signal`,converter:I.nullableConverter(e=>I.converters.AbortSignal(e,`RequestInit`,`signal`,{strict:!1}))},{key:`window`,converter:I.converters.any},{key:`duplex`,converter:I.converters.DOMString,allowedValues:E},{key:`dispatcher`,converter:I.converters.any}]),t.exports={Request:J,makeRequest:Y,fromInnerRequest:ce,cloneRequest:se}})),Ge=o(((e,t)=>{var{makeNetworkError:n,makeAppropriateNetworkError:r,filterResponse:i,makeResponse:a,fromInnerResponse:o}=He(),{HeadersList:s}=Ve(),{Request:c,cloneRequest:l}=We(),u=require(`node:zlib`),{bytesMatch:d,makePolicyContainer:f,clonePolicyContainer:p,requestBadPort:m,TAOCheck:h,appendRequestOriginHeader:g,responseLocationURL:_,requestCurrentURL:v,setRequestReferrerPolicyOnRedirect:y,tryUpgradeRequestToAPotentiallyTrustworthyURL:b,createOpaqueTimingInfo:x,appendFetchMetadata:S,corsCheck:C,crossOriginResourcePolicyCheck:w,determineRequestsReferrer:T,coarsenedSharedCurrentTime:E,createDeferredPromise:D,isBlobLike:O,sameOrigin:k,isCancelled:A,isAborted:j,isErrorLike:M,fullyReadBody:N,readableStreamClose:P,isomorphicEncode:I,urlIsLocal:L,urlIsHttpHttpsScheme:R,urlHasHttpsScheme:z,clampAndCoarsenConnectionTimingInfo:B,simpleRangeHeaderValue:V,buildContentRange:ee,createInflate:te,extractMimeType:ne}=W(),{kState:re,kDispatcher:ae}=G(),K=require(`node:assert`),{safelyExtractBody:q,extractBody:J}=oe(),{redirectStatusSet:Y,nullBodyStatus:se,safeMethodsSet:ce,requestBodyHeader:le,subresourceSet:X}=ie(),ue=require(`node:events`),{Readable:de,pipeline:fe,finished:pe}=require(`node:stream`),{addAbortListener:Z,isErrored:Q,isReadable:me,bufferToLowerCasedHeaderName:$}=F(),{dataURLProcessor:he,serializeAMimeType:ge,minimizeSupportedMimeType:_e}=H(),{getGlobalDispatcher:ve}=Fe(),{webidl:ye}=U(),{STATUS_CODES:be}=require(`node:http`),xe=[`GET`,`HEAD`],Se=typeof __UNDICI_IS_NODE__<`u`||typeof esbuildDetection<`u`?`node`:`undici`,Ce,we=class extends ue{constructor(e){super(),this.dispatcher=e,this.connection=null,this.dump=!1,this.state=`ongoing`}terminate(e){this.state===`ongoing`&&(this.state=`terminated`,this.connection?.destroy(e),this.emit(`terminated`,e))}abort(e){this.state===`ongoing`&&(this.state=`aborted`,e||=new DOMException(`The operation was aborted.`,`AbortError`),this.serializedAbortReason=e,this.connection?.destroy(e),this.emit(`terminated`,e))}};function Te(e){De(e,`fetch`)}function Ee(e,t=void 0){ye.argumentLengthCheck(arguments,1,`globalThis.fetch`);let n=D(),r;try{r=new c(e,t)}catch(e){return n.reject(e),n.promise}let i=r[re];if(r.signal.aborted)return ke(n,i,null,r.signal.reason),n.promise;i.client.globalObject?.constructor?.name===`ServiceWorkerGlobalScope`&&(i.serviceWorkers=`none`);let a=null,s=!1,l=null;return Z(r.signal,()=>{s=!0,K(l!=null),l.abort(r.signal.reason);let e=a?.deref();ke(n,i,e,r.signal.reason)}),l=Ae({request:i,processResponseEndOfBody:Te,processResponse:e=>{if(!s){if(e.aborted){ke(n,i,a,l.serializedAbortReason);return}if(e.type===`error`){n.reject(TypeError(`fetch failed`,{cause:e.error}));return}a=new WeakRef(o(e,`immutable`)),n.resolve(a.deref()),n=null}},dispatcher:r[ae]}),n.promise}function De(e,t=`other`){if(e.type===`error`&&e.aborted||!e.urlList?.length)return;let n=e.urlList[0],r=e.timingInfo,i=e.cacheState;R(n)&&r!==null&&(e.timingAllowPassed||(r=x({startTime:r.startTime}),i=``),r.endTime=E(),e.timingInfo=r,Oe(r,n.href,t,globalThis,i))}var Oe=performance.markResourceTiming;function ke(e,t,n,r){if(e&&e.reject(r),t.body!=null&&me(t.body?.stream)&&t.body.stream.cancel(r).catch(e=>{if(e.code!==`ERR_INVALID_STATE`)throw e}),n==null)return;let i=n[re];i.body!=null&&me(i.body?.stream)&&i.body.stream.cancel(r).catch(e=>{if(e.code!==`ERR_INVALID_STATE`)throw e})}function Ae({request:e,processRequestBodyChunkLength:t,processRequestEndOfBody:n,processResponse:r,processResponseEndOfBody:i,processResponseConsumeBody:a,useParallelQueue:o=!1,dispatcher:s=ve()}){K(s);let c=null,l=!1;e.client!=null&&(c=e.client.globalObject,l=e.client.crossOriginIsolatedCapability);let u=x({startTime:E(l)}),d={controller:new we(s),request:e,timingInfo:u,processRequestBodyChunkLength:t,processRequestEndOfBody:n,processResponse:r,processResponseConsumeBody:a,processResponseEndOfBody:i,taskDestination:c,crossOriginIsolatedCapability:l};return K(!e.body||e.body.stream),e.window===`client`&&(e.window=e.client?.globalObject?.constructor?.name===`Window`?e.client:`no-window`),e.origin===`client`&&(e.origin=e.client.origin),e.policyContainer===`client`&&(e.client==null?e.policyContainer=f():e.policyContainer=p(e.client.policyContainer)),e.headersList.contains(`accept`,!0)||e.headersList.append(`accept`,`*/*`,!0),e.headersList.contains(`accept-language`,!0)||e.headersList.append(`accept-language`,`*`,!0),e.priority,X.has(e.destination),je(d).catch(e=>{d.controller.terminate(e)}),d.controller}async function je(e,t=!1){let r=e.request,a=null;if(r.localURLsOnly&&!L(v(r))&&(a=n(`local URLs only`)),b(r),m(r)===`blocked`&&(a=n(`bad port`)),r.referrerPolicy===``&&(r.referrerPolicy=r.policyContainer.referrerPolicy),r.referrer!==`no-referrer`&&(r.referrer=T(r)),a===null&&(a=await(async()=>{let t=v(r);return k(t,r.url)&&r.responseTainting===`basic`||t.protocol===`data:`||r.mode===`navigate`||r.mode===`websocket`?(r.responseTainting=`basic`,await Me(e)):r.mode===`same-origin`?n(`request mode cannot be "same-origin"`):r.mode===`no-cors`?r.redirect===`follow`?(r.responseTainting=`opaque`,await Me(e)):n(`redirect mode cannot be "follow" for "no-cors" request`):R(v(r))?(r.responseTainting=`cors`,await Ie(e)):n(`URL scheme must be a HTTP(S) scheme`)})()),t)return a;a.status!==0&&!a.internalResponse&&(r.responseTainting,r.responseTainting===`basic`?a=i(a,`basic`):r.responseTainting===`cors`?a=i(a,`cors`):r.responseTainting===`opaque`?a=i(a,`opaque`):K(!1));let o=a.status===0?a:a.internalResponse;if(o.urlList.length===0&&o.urlList.push(...r.urlList),r.timingAllowFailed||(a.timingAllowPassed=!0),a.type===`opaque`&&o.status===206&&o.rangeRequested&&!r.headers.contains(`range`,!0)&&(a=o=n()),a.status!==0&&(r.method===`HEAD`||r.method===`CONNECT`||se.includes(o.status))&&(o.body=null,e.controller.dump=!0),r.integrity){let t=t=>Pe(e,n(t));if(r.responseTainting===`opaque`||a.body==null){t(a.error);return}await N(a.body,n=>{if(!d(n,r.integrity)){t(`integrity mismatch`);return}a.body=q(n)[0],Pe(e,a)},t)}else Pe(e,a)}function Me(e){if(A(e)&&e.request.redirectCount===0)return Promise.resolve(r(e));let{request:t}=e,{protocol:i}=v(t);switch(i){case`about:`:return Promise.resolve(n(`about scheme is not supported`));case`blob:`:{Ce||=require(`node:buffer`).resolveObjectURL;let e=v(t);if(e.search.length!==0)return Promise.resolve(n(`NetworkError when attempting to fetch resource.`));let r=Ce(e.toString());if(t.method!==`GET`||!O(r))return Promise.resolve(n(`invalid method`));let i=a(),o=r.size,s=I(`${o}`),c=r.type;if(t.headersList.contains(`range`,!0)){i.rangeRequested=!0;let e=V(t.headersList.get(`range`,!0),!0);if(e===`failure`)return Promise.resolve(n(`failed to fetch the data URL`));let{rangeStartValue:a,rangeEndValue:s}=e;if(a===null)a=o-s,s=a+s-1;else{if(a>=o)return Promise.resolve(n(`Range start is greater than the blob's size.`));(s===null||s>=o)&&(s=o-1)}let l=r.slice(a,s,c);i.body=J(l)[0];let u=I(`${l.size}`),d=ee(a,s,o);i.status=206,i.statusText=`Partial Content`,i.headersList.set(`content-length`,u,!0),i.headersList.set(`content-type`,c,!0),i.headersList.set(`content-range`,d,!0)}else{let e=J(r);i.statusText=`OK`,i.body=e[0],i.headersList.set(`content-length`,s,!0),i.headersList.set(`content-type`,c,!0)}return Promise.resolve(i)}case`data:`:{let e=he(v(t));if(e===`failure`)return Promise.resolve(n(`failed to fetch the data URL`));let r=ge(e.mimeType);return Promise.resolve(a({statusText:`OK`,headersList:[[`content-type`,{name:`Content-Type`,value:r}]],body:q(e.body)[0]}))}case`file:`:return Promise.resolve(n(`not implemented... yet...`));case`http:`:case`https:`:return Ie(e).catch(e=>n(e));default:return Promise.resolve(n(`unknown scheme`))}}function Ne(e,t){e.request.done=!0,e.processResponseDone!=null&&queueMicrotask(()=>e.processResponseDone(t))}function Pe(e,t){let n=e.timingInfo,r=()=>{let r=Date.now();e.request.destination===`document`&&(e.controller.fullTimingInfo=n),e.controller.reportTimingSteps=()=>{if(e.request.url.protocol!==`https:`)return;n.endTime=r;let i=t.cacheState,a=t.bodyInfo;t.timingAllowPassed||(n=x(n),i=``);let o=0;if(e.request.mode!==`navigator`||!t.hasCrossOriginRedirects){o=t.status;let e=ne(t.headersList);e!==`failure`&&(a.contentType=_e(e))}e.request.initiatorType!=null&&Oe(n,e.request.url.href,e.request.initiatorType,globalThis,i,a,o)};let i=()=>{e.request.done=!0,e.processResponseEndOfBody!=null&&queueMicrotask(()=>e.processResponseEndOfBody(t)),e.request.initiatorType!=null&&e.controller.reportTimingSteps()};queueMicrotask(()=>i())};e.processResponse!=null&&queueMicrotask(()=>{e.processResponse(t),e.processResponse=null});let i=t.type===`error`?t:t.internalResponse??t;i.body==null?r():pe(i.body.stream,()=>{r()})}async function Ie(e){let t=e.request,r=null,i=null,a=e.timingInfo;if(t.serviceWorkers,r===null){if(t.redirect===`follow`&&(t.serviceWorkers=`none`),i=r=await Re(e),t.responseTainting===`cors`&&C(t,r)===`failure`)return n(`cors failure`);h(t,r)===`failure`&&(t.timingAllowFailed=!0)}return(t.responseTainting===`opaque`||r.type===`opaque`)&&w(t.origin,t.client,t.destination,i)===`blocked`?n(`blocked`):(Y.has(i.status)&&(t.redirect!==`manual`&&e.controller.connection.destroy(void 0,!1),t.redirect===`error`?r=n(`unexpected redirect`):t.redirect===`manual`?r=i:t.redirect===`follow`?r=await Le(e,r):K(!1)),r.timingInfo=a,r)}function Le(e,t){let r=e.request,i=t.internalResponse?t.internalResponse:t,a;try{if(a=_(i,v(r).hash),a==null)return t}catch(e){return Promise.resolve(n(e))}if(!R(a))return Promise.resolve(n(`URL scheme must be a HTTP(S) scheme`));if(r.redirectCount===20)return Promise.resolve(n(`redirect count exceeded`));if(r.redirectCount+=1,r.mode===`cors`&&(a.username||a.password)&&!k(r,a))return Promise.resolve(n(`cross origin not allowed for request mode "cors"`));if(r.responseTainting===`cors`&&(a.username||a.password))return Promise.resolve(n(`URL cannot contain credentials for request mode "cors"`));if(i.status!==303&&r.body!=null&&r.body.source==null)return Promise.resolve(n());if([301,302].includes(i.status)&&r.method===`POST`||i.status===303&&!xe.includes(r.method)){r.method=`GET`,r.body=null;for(let e of le)r.headersList.delete(e)}k(v(r),a)||(r.headersList.delete(`authorization`,!0),r.headersList.delete(`proxy-authorization`,!0),r.headersList.delete(`cookie`,!0),r.headersList.delete(`host`,!0)),r.body!=null&&(K(r.body.source!=null),r.body=q(r.body.source)[0]);let o=e.timingInfo;return o.redirectEndTime=o.postRedirectStartTime=E(e.crossOriginIsolatedCapability),o.redirectStartTime===0&&(o.redirectStartTime=o.startTime),r.urlList.push(a),y(r,i),je(e,!0)}async function Re(e,t=!1,i=!1){let a=e.request,o=null,s=null,c=null;a.window===`no-window`&&a.redirect===`error`?(o=e,s=a):(s=l(a),o={...e},o.request=s);let u=a.credentials===`include`||a.credentials===`same-origin`&&a.responseTainting===`basic`,d=s.body?s.body.length:null,f=null;if(s.body==null&&[`POST`,`PUT`].includes(s.method)&&(f=`0`),d!=null&&(f=I(`${d}`)),f!=null&&s.headersList.append(`content-length`,f,!0),d!=null&&s.keepalive,s.referrer instanceof URL&&s.headersList.append(`referer`,I(s.referrer.href),!0),g(s),S(s),s.headersList.contains(`user-agent`,!0)||s.headersList.append(`user-agent`,Se),s.cache===`default`&&(s.headersList.contains(`if-modified-since`,!0)||s.headersList.contains(`if-none-match`,!0)||s.headersList.contains(`if-unmodified-since`,!0)||s.headersList.contains(`if-match`,!0)||s.headersList.contains(`if-range`,!0))&&(s.cache=`no-store`),s.cache===`no-cache`&&!s.preventNoCacheCacheControlHeaderModification&&!s.headersList.contains(`cache-control`,!0)&&s.headersList.append(`cache-control`,`max-age=0`,!0),(s.cache===`no-store`||s.cache===`reload`)&&(s.headersList.contains(`pragma`,!0)||s.headersList.append(`pragma`,`no-cache`,!0),s.headersList.contains(`cache-control`,!0)||s.headersList.append(`cache-control`,`no-cache`,!0)),s.headersList.contains(`range`,!0)&&s.headersList.append(`accept-encoding`,`identity`,!0),s.headersList.contains(`accept-encoding`,!0)||(z(v(s))?s.headersList.append(`accept-encoding`,`br, gzip, deflate`,!0):s.headersList.append(`accept-encoding`,`gzip, deflate`,!0)),s.headersList.delete(`host`,!0),s.cache=`no-store`,s.cache!==`no-store`&&s.cache,c==null){if(s.cache===`only-if-cached`)return n(`only if cached`);let e=await ze(o,u,i);!ce.has(s.method)&&e.status>=200&&e.status,c??=e}if(c.urlList=[...s.urlList],s.headersList.contains(`range`,!0)&&(c.rangeRequested=!0),c.requestIncludesCredentials=u,c.status===407)return a.window===`no-window`?n():A(e)?r(e):n(`proxy authentication required`);if(c.status===421&&!i&&(a.body==null||a.body.source!=null)){if(A(e))return r(e);e.controller.connection.destroy(),c=await Re(e,t,!0)}return c}async function ze(e,t=!1,i=!1){K(!e.controller.connection||e.controller.connection.destroyed),e.controller.connection={abort:null,destroyed:!1,destroy(e,t=!0){this.destroyed||(this.destroyed=!0,t&&this.abort?.(e??new DOMException(`The operation was aborted.`,`AbortError`)))}};let o=e.request,c=null,l=e.timingInfo;o.cache=`no-store`,o.mode;let d=null;if(o.body==null&&e.processRequestEndOfBody)queueMicrotask(()=>e.processRequestEndOfBody());else if(o.body!=null){let t=async function*(t){A(e)||(yield t,e.processRequestBodyChunkLength?.(t.byteLength))},n=()=>{A(e)||e.processRequestEndOfBody&&e.processRequestEndOfBody()},r=t=>{A(e)||(t.name===`AbortError`?e.controller.abort():e.controller.terminate(t))};d=(async function*(){try{for await(let e of o.body.stream)yield*t(e);n()}catch(e){r(e)}})()}try{let{body:t,status:n,statusText:r,headersList:i,socket:o}=await g({body:d});if(o)c=a({status:n,statusText:r,headersList:i,socket:o});else{let o=t[Symbol.asyncIterator]();e.controller.next=()=>o.next(),c=a({status:n,statusText:r,headersList:i})}}catch(t){return t.name===`AbortError`?(e.controller.connection.destroy(),r(e,t)):n(t)}let f=async()=>{await e.controller.resume()},p=t=>{A(e)||e.controller.abort(t)},m=new ReadableStream({async start(t){e.controller.controller=t},async pull(e){await f(e)},async cancel(e){await p(e)},type:`bytes`});c.body={stream:m,source:null,length:null},e.controller.onAborted=h,e.controller.on(`terminated`,h),e.controller.resume=async()=>{for(;;){let t,n;try{let{done:n,value:r}=await e.controller.next();if(j(e))break;t=n?void 0:r}catch(r){e.controller.ended&&!l.encodedBodySize?t=void 0:(t=r,n=!0)}if(t===void 0){P(e.controller.controller),Ne(e,c);return}if(l.decodedBodySize+=t?.byteLength??0,n){e.controller.terminate(t);return}let r=new Uint8Array(t);if(r.byteLength&&e.controller.controller.enqueue(r),Q(m)){e.controller.terminate();return}if(e.controller.controller.desiredSize<=0)return}};function h(t){j(e)?(c.aborted=!0,me(m)&&e.controller.controller.error(e.controller.serializedAbortReason)):me(m)&&e.controller.controller.error(TypeError(`terminated`,{cause:M(t)?t:void 0})),e.controller.connection.destroy()}return c;function g({body:t}){let n=v(o),r=e.controller.dispatcher;return new Promise((i,a)=>r.dispatch({path:n.pathname+n.search,origin:n.origin,method:o.method,body:r.isMockActive?o.body&&(o.body.source||o.body.stream):t,headers:o.headersList.entries,maxRedirections:0,upgrade:o.mode===`websocket`?`websocket`:void 0},{body:null,abort:null,onConnect(t){let{connection:n}=e.controller;l.finalConnectionTimingInfo=B(void 0,l.postRedirectStartTime,e.crossOriginIsolatedCapability),n.destroyed?t(new DOMException(`The operation was aborted.`,`AbortError`)):(e.controller.on(`terminated`,t),this.abort=n.abort=t),l.finalNetworkRequestStartTime=E(e.crossOriginIsolatedCapability)},onResponseStarted(){l.finalNetworkResponseStartTime=E(e.crossOriginIsolatedCapability)},onHeaders(e,t,n,r){if(e<200)return;let c=``,l=new s;for(let e=0;e5)return a(Error(`too many content-encodings in response: ${t.length}, maximum allowed is 5`)),!0;for(let e=t.length-1;e>=0;--e){let n=t[e].trim();if(n===`x-gzip`||n===`gzip`)d.push(u.createGunzip({flush:u.constants.Z_SYNC_FLUSH,finishFlush:u.constants.Z_SYNC_FLUSH}));else if(n===`deflate`)d.push(te({flush:u.constants.Z_SYNC_FLUSH,finishFlush:u.constants.Z_SYNC_FLUSH}));else if(n===`br`)d.push(u.createBrotliDecompress({flush:u.constants.BROTLI_OPERATION_FLUSH,finishFlush:u.constants.BROTLI_OPERATION_FLUSH}));else{d.length=0;break}}}let p=this.onError.bind(this);return i({status:e,statusText:r,headersList:l,body:d.length?fe(this.body,...d,e=>{e&&this.onError(e)}).on(`error`,p):this.body.on(`error`,p)}),!0},onData(t){if(e.controller.dump)return;let n=t;return l.encodedBodySize+=n.byteLength,this.body.push(n)},onComplete(){this.abort&&e.controller.off(`terminated`,this.abort),e.controller.onAborted&&e.controller.off(`terminated`,e.controller.onAborted),e.controller.ended=!0,this.body.push(null)},onError(t){this.abort&&e.controller.off(`terminated`,this.abort),this.body?.destroy(t),e.controller.terminate(t),a(t)},onUpgrade(e,t,n){if(e!==101)return;let r=new s;for(let e=0;e{t.exports={kState:Symbol(`FileReader state`),kResult:Symbol(`FileReader result`),kError:Symbol(`FileReader error`),kLastProgressEventFired:Symbol(`FileReader last progress event fired timestamp`),kEvents:Symbol(`FileReader events`),kAborted:Symbol(`FileReader aborted`)}})),qe=o(((e,t)=>{var{webidl:n}=U(),r=Symbol(`ProgressEvent state`),i=class e extends Event{constructor(e,t={}){e=n.converters.DOMString(e,`ProgressEvent constructor`,`type`),t=n.converters.ProgressEventInit(t??{}),super(e,t),this[r]={lengthComputable:t.lengthComputable,loaded:t.loaded,total:t.total}}get lengthComputable(){return n.brandCheck(this,e),this[r].lengthComputable}get loaded(){return n.brandCheck(this,e),this[r].loaded}get total(){return n.brandCheck(this,e),this[r].total}};n.converters.ProgressEventInit=n.dictionaryConverter([{key:`lengthComputable`,converter:n.converters.boolean,defaultValue:()=>!1},{key:`loaded`,converter:n.converters[`unsigned long long`],defaultValue:()=>0},{key:`total`,converter:n.converters[`unsigned long long`],defaultValue:()=>0},{key:`bubbles`,converter:n.converters.boolean,defaultValue:()=>!1},{key:`cancelable`,converter:n.converters.boolean,defaultValue:()=>!1},{key:`composed`,converter:n.converters.boolean,defaultValue:()=>!1}]),t.exports={ProgressEvent:i}})),Je=o(((e,t)=>{function n(e){if(!e)return`failure`;switch(e.trim().toLowerCase()){case`unicode-1-1-utf-8`:case`unicode11utf8`:case`unicode20utf8`:case`utf-8`:case`utf8`:case`x-unicode20utf8`:return`UTF-8`;case`866`:case`cp866`:case`csibm866`:case`ibm866`:return`IBM866`;case`csisolatin2`:case`iso-8859-2`:case`iso-ir-101`:case`iso8859-2`:case`iso88592`:case`iso_8859-2`:case`iso_8859-2:1987`:case`l2`:case`latin2`:return`ISO-8859-2`;case`csisolatin3`:case`iso-8859-3`:case`iso-ir-109`:case`iso8859-3`:case`iso88593`:case`iso_8859-3`:case`iso_8859-3:1988`:case`l3`:case`latin3`:return`ISO-8859-3`;case`csisolatin4`:case`iso-8859-4`:case`iso-ir-110`:case`iso8859-4`:case`iso88594`:case`iso_8859-4`:case`iso_8859-4:1988`:case`l4`:case`latin4`:return`ISO-8859-4`;case`csisolatincyrillic`:case`cyrillic`:case`iso-8859-5`:case`iso-ir-144`:case`iso8859-5`:case`iso88595`:case`iso_8859-5`:case`iso_8859-5:1988`:return`ISO-8859-5`;case`arabic`:case`asmo-708`:case`csiso88596e`:case`csiso88596i`:case`csisolatinarabic`:case`ecma-114`:case`iso-8859-6`:case`iso-8859-6-e`:case`iso-8859-6-i`:case`iso-ir-127`:case`iso8859-6`:case`iso88596`:case`iso_8859-6`:case`iso_8859-6:1987`:return`ISO-8859-6`;case`csisolatingreek`:case`ecma-118`:case`elot_928`:case`greek`:case`greek8`:case`iso-8859-7`:case`iso-ir-126`:case`iso8859-7`:case`iso88597`:case`iso_8859-7`:case`iso_8859-7:1987`:case`sun_eu_greek`:return`ISO-8859-7`;case`csiso88598e`:case`csisolatinhebrew`:case`hebrew`:case`iso-8859-8`:case`iso-8859-8-e`:case`iso-ir-138`:case`iso8859-8`:case`iso88598`:case`iso_8859-8`:case`iso_8859-8:1988`:case`visual`:return`ISO-8859-8`;case`csiso88598i`:case`iso-8859-8-i`:case`logical`:return`ISO-8859-8-I`;case`csisolatin6`:case`iso-8859-10`:case`iso-ir-157`:case`iso8859-10`:case`iso885910`:case`l6`:case`latin6`:return`ISO-8859-10`;case`iso-8859-13`:case`iso8859-13`:case`iso885913`:return`ISO-8859-13`;case`iso-8859-14`:case`iso8859-14`:case`iso885914`:return`ISO-8859-14`;case`csisolatin9`:case`iso-8859-15`:case`iso8859-15`:case`iso885915`:case`iso_8859-15`:case`l9`:return`ISO-8859-15`;case`iso-8859-16`:return`ISO-8859-16`;case`cskoi8r`:case`koi`:case`koi8`:case`koi8-r`:case`koi8_r`:return`KOI8-R`;case`koi8-ru`:case`koi8-u`:return`KOI8-U`;case`csmacintosh`:case`mac`:case`macintosh`:case`x-mac-roman`:return`macintosh`;case`iso-8859-11`:case`iso8859-11`:case`iso885911`:case`tis-620`:case`windows-874`:return`windows-874`;case`cp1250`:case`windows-1250`:case`x-cp1250`:return`windows-1250`;case`cp1251`:case`windows-1251`:case`x-cp1251`:return`windows-1251`;case`ansi_x3.4-1968`:case`ascii`:case`cp1252`:case`cp819`:case`csisolatin1`:case`ibm819`:case`iso-8859-1`:case`iso-ir-100`:case`iso8859-1`:case`iso88591`:case`iso_8859-1`:case`iso_8859-1:1987`:case`l1`:case`latin1`:case`us-ascii`:case`windows-1252`:case`x-cp1252`:return`windows-1252`;case`cp1253`:case`windows-1253`:case`x-cp1253`:return`windows-1253`;case`cp1254`:case`csisolatin5`:case`iso-8859-9`:case`iso-ir-148`:case`iso8859-9`:case`iso88599`:case`iso_8859-9`:case`iso_8859-9:1989`:case`l5`:case`latin5`:case`windows-1254`:case`x-cp1254`:return`windows-1254`;case`cp1255`:case`windows-1255`:case`x-cp1255`:return`windows-1255`;case`cp1256`:case`windows-1256`:case`x-cp1256`:return`windows-1256`;case`cp1257`:case`windows-1257`:case`x-cp1257`:return`windows-1257`;case`cp1258`:case`windows-1258`:case`x-cp1258`:return`windows-1258`;case`x-mac-cyrillic`:case`x-mac-ukrainian`:return`x-mac-cyrillic`;case`chinese`:case`csgb2312`:case`csiso58gb231280`:case`gb2312`:case`gb_2312`:case`gb_2312-80`:case`gbk`:case`iso-ir-58`:case`x-gbk`:return`GBK`;case`gb18030`:return`gb18030`;case`big5`:case`big5-hkscs`:case`cn-big5`:case`csbig5`:case`x-x-big5`:return`Big5`;case`cseucpkdfmtjapanese`:case`euc-jp`:case`x-euc-jp`:return`EUC-JP`;case`csiso2022jp`:case`iso-2022-jp`:return`ISO-2022-JP`;case`csshiftjis`:case`ms932`:case`ms_kanji`:case`shift-jis`:case`shift_jis`:case`sjis`:case`windows-31j`:case`x-sjis`:return`Shift_JIS`;case`cseuckr`:case`csksc56011987`:case`euc-kr`:case`iso-ir-149`:case`korean`:case`ks_c_5601-1987`:case`ks_c_5601-1989`:case`ksc5601`:case`ksc_5601`:case`windows-949`:return`EUC-KR`;case`csiso2022kr`:case`hz-gb-2312`:case`iso-2022-cn`:case`iso-2022-cn-ext`:case`iso-2022-kr`:case`replacement`:return`replacement`;case`unicodefffe`:case`utf-16be`:return`UTF-16BE`;case`csunicode`:case`iso-10646-ucs-2`:case`ucs-2`:case`unicode`:case`unicodefeff`:case`utf-16`:case`utf-16le`:return`UTF-16LE`;case`x-user-defined`:return`x-user-defined`;default:return`failure`}}t.exports={getEncoding:n}})),Ye=o(((e,t)=>{var{kState:n,kError:r,kResult:i,kAborted:a,kLastProgressEventFired:o}=Ke(),{ProgressEvent:s}=qe(),{getEncoding:c}=Je(),{serializeAMimeType:l,parseMIMEType:u}=H(),{types:d}=require(`node:util`),{StringDecoder:f}=require(`string_decoder`),{btoa:p}=require(`node:buffer`),m={enumerable:!0,writable:!1,configurable:!1};function h(e,t,s,c){if(e[n]===`loading`)throw new DOMException(`Invalid state`,`InvalidStateError`);e[n]=`loading`,e[i]=null,e[r]=null;let l=t.stream().getReader(),u=[],f=l.read(),p=!0;(async()=>{for(;!e[a];)try{let{done:m,value:h}=await f;if(p&&!e[a]&&queueMicrotask(()=>{g(`loadstart`,e)}),p=!1,!m&&d.isUint8Array(h))u.push(h),(e[o]===void 0||Date.now()-e[o]>=50)&&!e[a]&&(e[o]=Date.now(),queueMicrotask(()=>{g(`progress`,e)})),f=l.read();else if(m){queueMicrotask(()=>{e[n]=`done`;try{let n=_(u,s,t.type,c);if(e[a])return;e[i]=n,g(`load`,e)}catch(t){e[r]=t,g(`error`,e)}e[n]!==`loading`&&g(`loadend`,e)});break}}catch(t){if(e[a])return;queueMicrotask(()=>{e[n]=`done`,e[r]=t,g(`error`,e),e[n]!==`loading`&&g(`loadend`,e)});break}})()}function g(e,t){let n=new s(e,{bubbles:!1,cancelable:!1});t.dispatchEvent(n)}function _(e,t,n,r){switch(t){case`DataURL`:{let t=`data:`,r=u(n||`application/octet-stream`);r!==`failure`&&(t+=l(r)),t+=`;base64,`;let i=new f(`latin1`);for(let n of e)t+=p(i.write(n));return t+=p(i.end()),t}case`Text`:{let t=`failure`;if(r&&(t=c(r)),t===`failure`&&n){let e=u(n);e!==`failure`&&(t=c(e.parameters.get(`charset`)))}return t===`failure`&&(t=`UTF-8`),v(e,t)}case`ArrayBuffer`:return b(e).buffer;case`BinaryString`:{let t=``,n=new f(`latin1`);for(let r of e)t+=n.write(r);return t+=n.end(),t}}}function v(e,t){let n=b(e),r=y(n),i=0;r!==null&&(t=r,i=r===`UTF-8`?3:2);let a=n.slice(i);return new TextDecoder(t).decode(a)}function y(e){let[t,n,r]=e;return t===239&&n===187&&r===191?`UTF-8`:t===254&&n===255?`UTF-16BE`:t===255&&n===254?`UTF-16LE`:null}function b(e){let t=e.reduce((e,t)=>e+t.byteLength,0),n=0;return e.reduce((e,t)=>(e.set(t,n),n+=t.byteLength,e),new Uint8Array(t))}t.exports={staticPropertyDescriptors:m,readOperation:h,fireAProgressEvent:g}})),Xe=o(((e,t)=>{var{staticPropertyDescriptors:n,readOperation:r,fireAProgressEvent:i}=Ye(),{kState:a,kError:o,kResult:s,kEvents:c,kAborted:l}=Ke(),{webidl:u}=U(),{kEnumerableProperty:d}=F(),f=class e extends EventTarget{constructor(){super(),this[a]=`empty`,this[s]=null,this[o]=null,this[c]={loadend:null,error:null,abort:null,load:null,progress:null,loadstart:null}}readAsArrayBuffer(t){u.brandCheck(this,e),u.argumentLengthCheck(arguments,1,`FileReader.readAsArrayBuffer`),t=u.converters.Blob(t,{strict:!1}),r(this,t,`ArrayBuffer`)}readAsBinaryString(t){u.brandCheck(this,e),u.argumentLengthCheck(arguments,1,`FileReader.readAsBinaryString`),t=u.converters.Blob(t,{strict:!1}),r(this,t,`BinaryString`)}readAsText(t,n=void 0){u.brandCheck(this,e),u.argumentLengthCheck(arguments,1,`FileReader.readAsText`),t=u.converters.Blob(t,{strict:!1}),n!==void 0&&(n=u.converters.DOMString(n,`FileReader.readAsText`,`encoding`)),r(this,t,`Text`,n)}readAsDataURL(t){u.brandCheck(this,e),u.argumentLengthCheck(arguments,1,`FileReader.readAsDataURL`),t=u.converters.Blob(t,{strict:!1}),r(this,t,`DataURL`)}abort(){if(this[a]===`empty`||this[a]===`done`){this[s]=null;return}this[a]===`loading`&&(this[a]=`done`,this[s]=null),this[l]=!0,i(`abort`,this),this[a]!==`loading`&&i(`loadend`,this)}get readyState(){switch(u.brandCheck(this,e),this[a]){case`empty`:return this.EMPTY;case`loading`:return this.LOADING;case`done`:return this.DONE}}get result(){return u.brandCheck(this,e),this[s]}get error(){return u.brandCheck(this,e),this[o]}get onloadend(){return u.brandCheck(this,e),this[c].loadend}set onloadend(t){u.brandCheck(this,e),this[c].loadend&&this.removeEventListener(`loadend`,this[c].loadend),typeof t==`function`?(this[c].loadend=t,this.addEventListener(`loadend`,t)):this[c].loadend=null}get onerror(){return u.brandCheck(this,e),this[c].error}set onerror(t){u.brandCheck(this,e),this[c].error&&this.removeEventListener(`error`,this[c].error),typeof t==`function`?(this[c].error=t,this.addEventListener(`error`,t)):this[c].error=null}get onloadstart(){return u.brandCheck(this,e),this[c].loadstart}set onloadstart(t){u.brandCheck(this,e),this[c].loadstart&&this.removeEventListener(`loadstart`,this[c].loadstart),typeof t==`function`?(this[c].loadstart=t,this.addEventListener(`loadstart`,t)):this[c].loadstart=null}get onprogress(){return u.brandCheck(this,e),this[c].progress}set onprogress(t){u.brandCheck(this,e),this[c].progress&&this.removeEventListener(`progress`,this[c].progress),typeof t==`function`?(this[c].progress=t,this.addEventListener(`progress`,t)):this[c].progress=null}get onload(){return u.brandCheck(this,e),this[c].load}set onload(t){u.brandCheck(this,e),this[c].load&&this.removeEventListener(`load`,this[c].load),typeof t==`function`?(this[c].load=t,this.addEventListener(`load`,t)):this[c].load=null}get onabort(){return u.brandCheck(this,e),this[c].abort}set onabort(t){u.brandCheck(this,e),this[c].abort&&this.removeEventListener(`abort`,this[c].abort),typeof t==`function`?(this[c].abort=t,this.addEventListener(`abort`,t)):this[c].abort=null}};f.EMPTY=f.prototype.EMPTY=0,f.LOADING=f.prototype.LOADING=1,f.DONE=f.prototype.DONE=2,Object.defineProperties(f.prototype,{EMPTY:n,LOADING:n,DONE:n,readAsArrayBuffer:d,readAsBinaryString:d,readAsText:d,readAsDataURL:d,abort:d,readyState:d,result:d,error:d,onloadstart:d,onprogress:d,onload:d,onabort:d,onerror:d,onloadend:d,[Symbol.toStringTag]:{value:`FileReader`,writable:!1,enumerable:!1,configurable:!0}}),Object.defineProperties(f,{EMPTY:n,LOADING:n,DONE:n}),t.exports={FileReader:f}})),Ze=o(((e,t)=>{t.exports={kConstruct:j().kConstruct}})),Qe=o(((e,t)=>{var n=require(`node:assert`),{URLSerializer:r}=H(),{isValidHeaderName:i}=W();function a(e,t,n=!1){return r(e,n)===r(t,n)}function o(e){n(e!==null);let t=[];for(let n of e.split(`,`))n=n.trim(),i(n)&&t.push(n);return t}t.exports={urlEquals:a,getFieldValues:o}})),$e=o(((e,t)=>{var{kConstruct:n}=Ze(),{urlEquals:r,getFieldValues:i}=Qe(),{kEnumerableProperty:a,isDisturbed:o}=F(),{webidl:s}=U(),{Response:c,cloneResponse:l,fromInnerResponse:u}=He(),{Request:d,fromInnerRequest:f}=We(),{kState:p}=G(),{fetching:m}=Ge(),{urlIsHttpHttpsScheme:h,createDeferredPromise:g,readAllBytes:_}=W(),v=require(`node:assert`),y=class e{#e;constructor(){arguments[0]!==n&&s.illegalConstructor(),s.util.markAsUncloneable(this),this.#e=arguments[1]}async match(t,n={}){s.brandCheck(this,e);let r=`Cache.match`;s.argumentLengthCheck(arguments,1,r),t=s.converters.RequestInfo(t,r,`request`),n=s.converters.CacheQueryOptions(n,r,`options`);let i=this.#i(t,n,1);if(i.length!==0)return i[0]}async matchAll(t=void 0,n={}){s.brandCheck(this,e);let r=`Cache.matchAll`;return t!==void 0&&(t=s.converters.RequestInfo(t,r,`request`)),n=s.converters.CacheQueryOptions(n,r,`options`),this.#i(t,n)}async add(t){s.brandCheck(this,e);let n=`Cache.add`;s.argumentLengthCheck(arguments,1,n),t=s.converters.RequestInfo(t,n,`request`);let r=[t];return await this.addAll(r)}async addAll(t){s.brandCheck(this,e);let n=`Cache.addAll`;s.argumentLengthCheck(arguments,1,n);let r=[],a=[];for(let e of t){if(e===void 0)throw s.errors.conversionFailed({prefix:n,argument:`Argument 1`,types:[`undefined is not allowed`]});if(e=s.converters.RequestInfo(e),typeof e==`string`)continue;let t=e[p];if(!h(t.url)||t.method!==`GET`)throw s.errors.exception({header:n,message:`Expected http/s scheme when method is not GET.`})}let o=[];for(let e of t){let t=new d(e)[p];if(!h(t.url))throw s.errors.exception({header:n,message:`Expected http/s scheme.`});t.initiator=`fetch`,t.destination=`subresource`,a.push(t);let c=g();o.push(m({request:t,processResponse(e){if(e.type===`error`||e.status===206||e.status<200||e.status>299)c.reject(s.errors.exception({header:`Cache.addAll`,message:`Received an invalid status code or the request failed.`}));else if(e.headersList.contains(`vary`)){let t=i(e.headersList.get(`vary`));for(let e of t)if(e===`*`){c.reject(s.errors.exception({header:`Cache.addAll`,message:`invalid vary field value`}));for(let e of o)e.abort();return}}},processResponseEndOfBody(e){if(e.aborted){c.reject(new DOMException(`aborted`,`AbortError`));return}c.resolve(e)}})),r.push(c.promise)}let c=await Promise.all(r),l=[],u=0;for(let e of c){let t={type:`put`,request:a[u],response:e};l.push(t),u++}let f=g(),_=null;try{this.#t(l)}catch(e){_=e}return queueMicrotask(()=>{_===null?f.resolve(void 0):f.reject(_)}),f.promise}async put(t,n){s.brandCheck(this,e);let r=`Cache.put`;s.argumentLengthCheck(arguments,2,r),t=s.converters.RequestInfo(t,r,`request`),n=s.converters.Response(n,r,`response`);let a=null;if(a=t instanceof d?t[p]:new d(t)[p],!h(a.url)||a.method!==`GET`)throw s.errors.exception({header:r,message:`Expected an http/s scheme when method is not GET`});let c=n[p];if(c.status===206)throw s.errors.exception({header:r,message:`Got 206 status`});if(c.headersList.contains(`vary`)){let e=i(c.headersList.get(`vary`));for(let t of e)if(t===`*`)throw s.errors.exception({header:r,message:`Got * vary field value`})}if(c.body&&(o(c.body.stream)||c.body.stream.locked))throw s.errors.exception({header:r,message:`Response body is locked or disturbed`});let u=l(c),f=g();c.body==null?f.resolve(void 0):_(c.body.stream.getReader()).then(f.resolve,f.reject);let m=[],v={type:`put`,request:a,response:u};m.push(v);let y=await f.promise;u.body!=null&&(u.body.source=y);let b=g(),x=null;try{this.#t(m)}catch(e){x=e}return queueMicrotask(()=>{x===null?b.resolve():b.reject(x)}),b.promise}async delete(t,n={}){s.brandCheck(this,e);let r=`Cache.delete`;s.argumentLengthCheck(arguments,1,r),t=s.converters.RequestInfo(t,r,`request`),n=s.converters.CacheQueryOptions(n,r,`options`);let i=null;if(t instanceof d){if(i=t[p],i.method!==`GET`&&!n.ignoreMethod)return!1}else v(typeof t==`string`),i=new d(t)[p];let a=[],o={type:`delete`,request:i,options:n};a.push(o);let c=g(),l=null,u;try{u=this.#t(a)}catch(e){l=e}return queueMicrotask(()=>{l===null?c.resolve(!!u?.length):c.reject(l)}),c.promise}async keys(t=void 0,n={}){s.brandCheck(this,e);let r=`Cache.keys`;t!==void 0&&(t=s.converters.RequestInfo(t,r,`request`)),n=s.converters.CacheQueryOptions(n,r,`options`);let i=null;if(t!==void 0)if(t instanceof d){if(i=t[p],i.method!==`GET`&&!n.ignoreMethod)return[]}else typeof t==`string`&&(i=new d(t)[p]);let a=g(),o=[];if(t===void 0)for(let e of this.#e)o.push(e[0]);else{let e=this.#n(i,n);for(let t of e)o.push(t[0])}return queueMicrotask(()=>{let e=[];for(let t of o){let n=f(t,new AbortController().signal,`immutable`);e.push(n)}a.resolve(Object.freeze(e))}),a.promise}#t(e){let t=this.#e,n=[...t],r=[],i=[];try{for(let n of e){if(n.type!==`delete`&&n.type!==`put`)throw s.errors.exception({header:`Cache.#batchCacheOperations`,message:`operation type does not match "delete" or "put"`});if(n.type===`delete`&&n.response!=null)throw s.errors.exception({header:`Cache.#batchCacheOperations`,message:`delete operation should not have an associated response`});if(this.#n(n.request,n.options,r).length)throw new DOMException(`???`,`InvalidStateError`);let e;if(n.type===`delete`){if(e=this.#n(n.request,n.options),e.length===0)return[];for(let n of e){let e=t.indexOf(n);v(e!==-1),t.splice(e,1)}}else if(n.type===`put`){if(n.response==null)throw s.errors.exception({header:`Cache.#batchCacheOperations`,message:`put operation should have an associated response`});let i=n.request;if(!h(i.url))throw s.errors.exception({header:`Cache.#batchCacheOperations`,message:`expected http or https scheme`});if(i.method!==`GET`)throw s.errors.exception({header:`Cache.#batchCacheOperations`,message:`not get method`});if(n.options!=null)throw s.errors.exception({header:`Cache.#batchCacheOperations`,message:`options must not be defined`});e=this.#n(n.request);for(let n of e){let e=t.indexOf(n);v(e!==-1),t.splice(e,1)}t.push([n.request,n.response]),r.push([n.request,n.response])}i.push([n.request,n.response])}return i}catch(e){throw this.#e.length=0,this.#e=n,e}}#n(e,t,n){let r=[],i=n??this.#e;for(let n of i){let[i,a]=n;this.#r(e,i,a,t)&&r.push(n)}return r}#r(e,t,n=null,a){let o=new URL(e.url),s=new URL(t.url);if(a?.ignoreSearch&&(s.search=``,o.search=``),!r(o,s,!0))return!1;if(n==null||a?.ignoreVary||!n.headersList.contains(`vary`))return!0;let c=i(n.headersList.get(`vary`));for(let n of c)if(n===`*`||t.headersList.get(n)!==e.headersList.get(n))return!1;return!0}#i(e,t,n=1/0){let r=null;if(e!==void 0)if(e instanceof d){if(r=e[p],r.method!==`GET`&&!t.ignoreMethod)return[]}else typeof e==`string`&&(r=new d(e)[p]);let i=[];if(e===void 0)for(let e of this.#e)i.push(e[1]);else{let e=this.#n(r,t);for(let t of e)i.push(t[1])}let a=[];for(let e of i){let t=u(e,`immutable`);if(a.push(t.clone()),a.length>=n)break}return Object.freeze(a)}};Object.defineProperties(y.prototype,{[Symbol.toStringTag]:{value:`Cache`,configurable:!0},match:a,matchAll:a,add:a,addAll:a,put:a,delete:a,keys:a});var b=[{key:`ignoreSearch`,converter:s.converters.boolean,defaultValue:()=>!1},{key:`ignoreMethod`,converter:s.converters.boolean,defaultValue:()=>!1},{key:`ignoreVary`,converter:s.converters.boolean,defaultValue:()=>!1}];s.converters.CacheQueryOptions=s.dictionaryConverter(b),s.converters.MultiCacheQueryOptions=s.dictionaryConverter([...b,{key:`cacheName`,converter:s.converters.DOMString}]),s.converters.Response=s.interfaceConverter(c),s.converters[`sequence`]=s.sequenceConverter(s.converters.RequestInfo),t.exports={Cache:y}})),et=o(((e,t)=>{var{kConstruct:n}=Ze(),{Cache:r}=$e(),{webidl:i}=U(),{kEnumerableProperty:a}=F(),o=class e{#e=new Map;constructor(){arguments[0]!==n&&i.illegalConstructor(),i.util.markAsUncloneable(this)}async match(t,a={}){if(i.brandCheck(this,e),i.argumentLengthCheck(arguments,1,`CacheStorage.match`),t=i.converters.RequestInfo(t),a=i.converters.MultiCacheQueryOptions(a),a.cacheName!=null){if(this.#e.has(a.cacheName))return await new r(n,this.#e.get(a.cacheName)).match(t,a)}else for(let e of this.#e.values()){let i=await new r(n,e).match(t,a);if(i!==void 0)return i}}async has(t){i.brandCheck(this,e);let n=`CacheStorage.has`;return i.argumentLengthCheck(arguments,1,n),t=i.converters.DOMString(t,n,`cacheName`),this.#e.has(t)}async open(t){i.brandCheck(this,e);let a=`CacheStorage.open`;if(i.argumentLengthCheck(arguments,1,a),t=i.converters.DOMString(t,a,`cacheName`),this.#e.has(t))return new r(n,this.#e.get(t));let o=[];return this.#e.set(t,o),new r(n,o)}async delete(t){i.brandCheck(this,e);let n=`CacheStorage.delete`;return i.argumentLengthCheck(arguments,1,n),t=i.converters.DOMString(t,n,`cacheName`),this.#e.delete(t)}async keys(){return i.brandCheck(this,e),[...this.#e.keys()]}};Object.defineProperties(o.prototype,{[Symbol.toStringTag]:{value:`CacheStorage`,configurable:!0},match:a,has:a,open:a,delete:a,keys:a}),t.exports={CacheStorage:o}})),tt=o(((e,t)=>{t.exports={maxAttributeValueSize:1024,maxNameValuePairSize:4096}})),nt=o(((e,t)=>{function n(e){for(let t=0;t=0&&n<=8||n>=10&&n<=31||n===127)return!0}return!1}function r(e){for(let t=0;t126||n===34||n===40||n===41||n===60||n===62||n===64||n===44||n===59||n===58||n===92||n===47||n===91||n===93||n===63||n===61||n===123||n===125)throw Error(`Invalid cookie name`)}}function i(e){let t=e.length,n=0;if(e[0]===`"`){if(t===1||e[t-1]!==`"`)throw Error(`Invalid cookie value`);--t,++n}for(;n126||t===34||t===44||t===59||t===92)throw Error(`Invalid cookie value`)}}function a(e){for(let t=0;tt.toString().padStart(2,`0`));function u(e){return typeof e==`number`&&(e=new Date(e)),`${s[e.getUTCDay()]}, ${l[e.getUTCDate()]} ${c[e.getUTCMonth()]} ${e.getUTCFullYear()} ${l[e.getUTCHours()]}:${l[e.getUTCMinutes()]}:${l[e.getUTCSeconds()]} GMT`}function d(e){if(e<0)throw Error(`Invalid cookie max-age`)}function f(e){if(e.name.length===0)return null;r(e.name),i(e.value);let t=[`${e.name}=${e.value}`];e.name.startsWith(`__Secure-`)&&(e.secure=!0),e.name.startsWith(`__Host-`)&&(e.secure=!0,e.domain=null,e.path=`/`),e.secure&&t.push(`Secure`),e.httpOnly&&t.push(`HttpOnly`),typeof e.maxAge==`number`&&(d(e.maxAge),t.push(`Max-Age=${e.maxAge}`)),e.domain&&(o(e.domain),t.push(`Domain=${e.domain}`)),e.path&&(a(e.path),t.push(`Path=${e.path}`)),e.expires&&e.expires.toString()!==`Invalid Date`&&t.push(`Expires=${u(e.expires)}`),e.sameSite&&t.push(`SameSite=${e.sameSite}`);for(let n of e.unparsed){if(!n.includes(`=`))throw Error(`Invalid unparsed`);let[e,...r]=n.split(`=`);t.push(`${e.trim()}=${r.join(`=`)}`)}return t.join(`; `)}t.exports={isCTLExcludingHtab:n,validateCookieName:r,validateCookiePath:a,validateCookieValue:i,toIMFDate:u,stringify:f}})),rt=o(((e,t)=>{var{maxNameValuePairSize:n,maxAttributeValueSize:r}=tt(),{isCTLExcludingHtab:i}=nt(),{collectASequenceOfCodePointsFast:a}=H(),o=require(`node:assert`);function s(e){if(i(e))return null;let t=``,r=``,o=``,s=``;if(e.includes(`;`)){let n={position:0};t=a(`;`,e,n),r=e.slice(n.position)}else t=e;if(!t.includes(`=`))s=t;else{let e={position:0};o=a(`=`,t,e),s=t.slice(e.position+1)}return o=o.trim(),s=s.trim(),o.length+s.length>n?null:{name:o,value:s,...c(r)}}function c(e,t={}){if(e.length===0)return t;o(e[0]===`;`),e=e.slice(1);let n=``;e.includes(`;`)?(n=a(`;`,e,{position:0}),e=e.slice(n.length)):(n=e,e=``);let i=``,s=``;if(n.includes(`=`)){let e={position:0};i=a(`=`,n,e),s=n.slice(e.position+1)}else i=n;if(i=i.trim(),s=s.trim(),s.length>r)return c(e,t);let l=i.toLowerCase();if(l===`expires`)t.expires=new Date(s);else if(l===`max-age`){let n=s.charCodeAt(0);if((n<48||n>57)&&s[0]!==`-`||!/^\d+$/.test(s))return c(e,t);t.maxAge=Number(s)}else if(l===`domain`){let e=s;e[0]===`.`&&(e=e.slice(1)),e=e.toLowerCase(),t.domain=e}else if(l===`path`){let e=``;e=s.length===0||s[0]!==`/`?`/`:s,t.path=e}else if(l===`secure`)t.secure=!0;else if(l===`httponly`)t.httpOnly=!0;else if(l===`samesite`){let e=`Default`,n=s.toLowerCase();n.includes(`none`)&&(e=`None`),n.includes(`strict`)&&(e=`Strict`),n.includes(`lax`)&&(e=`Lax`),t.sameSite=e}else t.unparsed??=[],t.unparsed.push(`${i}=${s}`);return c(e,t)}t.exports={parseSetCookie:s,parseUnparsedAttributes:c}})),it=o(((e,t)=>{var{parseSetCookie:n}=rt(),{stringify:r}=nt(),{webidl:i}=U(),{Headers:a}=Ve();function o(e){i.argumentLengthCheck(arguments,1,`getCookies`),i.brandCheck(e,a,{strict:!1});let t=e.get(`cookie`),n={};if(!t)return n;for(let e of t.split(`;`)){let[t,...r]=e.split(`=`);n[t.trim()]=r.join(`=`)}return n}function s(e,t,n){i.brandCheck(e,a,{strict:!1});let r=`deleteCookie`;i.argumentLengthCheck(arguments,2,r),t=i.converters.DOMString(t,r,`name`),n=i.converters.DeleteCookieAttributes(n),l(e,{name:t,value:``,expires:new Date(0),...n})}function c(e){i.argumentLengthCheck(arguments,1,`getSetCookies`),i.brandCheck(e,a,{strict:!1});let t=e.getSetCookie();return t?t.map(e=>n(e)):[]}function l(e,t){i.argumentLengthCheck(arguments,2,`setCookie`),i.brandCheck(e,a,{strict:!1}),t=i.converters.Cookie(t);let n=r(t);n&&e.append(`Set-Cookie`,n)}i.converters.DeleteCookieAttributes=i.dictionaryConverter([{converter:i.nullableConverter(i.converters.DOMString),key:`path`,defaultValue:()=>null},{converter:i.nullableConverter(i.converters.DOMString),key:`domain`,defaultValue:()=>null}]),i.converters.Cookie=i.dictionaryConverter([{converter:i.converters.DOMString,key:`name`},{converter:i.converters.DOMString,key:`value`},{converter:i.nullableConverter(e=>typeof e==`number`?i.converters[`unsigned long long`](e):new Date(e)),key:`expires`,defaultValue:()=>null},{converter:i.nullableConverter(i.converters[`long long`]),key:`maxAge`,defaultValue:()=>null},{converter:i.nullableConverter(i.converters.DOMString),key:`domain`,defaultValue:()=>null},{converter:i.nullableConverter(i.converters.DOMString),key:`path`,defaultValue:()=>null},{converter:i.nullableConverter(i.converters.boolean),key:`secure`,defaultValue:()=>null},{converter:i.nullableConverter(i.converters.boolean),key:`httpOnly`,defaultValue:()=>null},{converter:i.converters.USVString,key:`sameSite`,allowedValues:[`Strict`,`Lax`,`None`]},{converter:i.sequenceConverter(i.converters.DOMString),key:`unparsed`,defaultValue:()=>[]}]),t.exports={getCookies:o,deleteCookie:s,getSetCookies:c,setCookie:l}})),at=o(((e,t)=>{var{webidl:n}=U(),{kEnumerableProperty:r}=F(),{kConstruct:i}=j(),{MessagePort:a}=require(`node:worker_threads`),o=class e extends Event{#e;constructor(e,t={}){if(e===i){super(arguments[1],arguments[2]),n.util.markAsUncloneable(this);return}let r=`MessageEvent constructor`;n.argumentLengthCheck(arguments,1,r),e=n.converters.DOMString(e,r,`type`),t=n.converters.MessageEventInit(t,r,`eventInitDict`),super(e,t),this.#e=t,n.util.markAsUncloneable(this)}get data(){return n.brandCheck(this,e),this.#e.data}get origin(){return n.brandCheck(this,e),this.#e.origin}get lastEventId(){return n.brandCheck(this,e),this.#e.lastEventId}get source(){return n.brandCheck(this,e),this.#e.source}get ports(){return n.brandCheck(this,e),Object.isFrozen(this.#e.ports)||Object.freeze(this.#e.ports),this.#e.ports}initMessageEvent(t,r=!1,i=!1,a=null,o=``,s=``,c=null,l=[]){return n.brandCheck(this,e),n.argumentLengthCheck(arguments,1,`MessageEvent.initMessageEvent`),new e(t,{bubbles:r,cancelable:i,data:a,origin:o,lastEventId:s,source:c,ports:l})}static createFastMessageEvent(t,n){let r=new e(i,t,n);return r.#e=n,r.#e.data??=null,r.#e.origin??=``,r.#e.lastEventId??=``,r.#e.source??=null,r.#e.ports??=[],r}},{createFastMessageEvent:s}=o;delete o.createFastMessageEvent;var c=class e extends Event{#e;constructor(e,t={}){let r=`CloseEvent constructor`;n.argumentLengthCheck(arguments,1,r),e=n.converters.DOMString(e,r,`type`),t=n.converters.CloseEventInit(t),super(e,t),this.#e=t,n.util.markAsUncloneable(this)}get wasClean(){return n.brandCheck(this,e),this.#e.wasClean}get code(){return n.brandCheck(this,e),this.#e.code}get reason(){return n.brandCheck(this,e),this.#e.reason}},l=class e extends Event{#e;constructor(e,t){let r=`ErrorEvent constructor`;n.argumentLengthCheck(arguments,1,r),super(e,t),n.util.markAsUncloneable(this),e=n.converters.DOMString(e,r,`type`),t=n.converters.ErrorEventInit(t??{}),this.#e=t}get message(){return n.brandCheck(this,e),this.#e.message}get filename(){return n.brandCheck(this,e),this.#e.filename}get lineno(){return n.brandCheck(this,e),this.#e.lineno}get colno(){return n.brandCheck(this,e),this.#e.colno}get error(){return n.brandCheck(this,e),this.#e.error}};Object.defineProperties(o.prototype,{[Symbol.toStringTag]:{value:`MessageEvent`,configurable:!0},data:r,origin:r,lastEventId:r,source:r,ports:r,initMessageEvent:r}),Object.defineProperties(c.prototype,{[Symbol.toStringTag]:{value:`CloseEvent`,configurable:!0},reason:r,code:r,wasClean:r}),Object.defineProperties(l.prototype,{[Symbol.toStringTag]:{value:`ErrorEvent`,configurable:!0},message:r,filename:r,lineno:r,colno:r,error:r}),n.converters.MessagePort=n.interfaceConverter(a),n.converters[`sequence`]=n.sequenceConverter(n.converters.MessagePort);var u=[{key:`bubbles`,converter:n.converters.boolean,defaultValue:()=>!1},{key:`cancelable`,converter:n.converters.boolean,defaultValue:()=>!1},{key:`composed`,converter:n.converters.boolean,defaultValue:()=>!1}];n.converters.MessageEventInit=n.dictionaryConverter([...u,{key:`data`,converter:n.converters.any,defaultValue:()=>null},{key:`origin`,converter:n.converters.USVString,defaultValue:()=>``},{key:`lastEventId`,converter:n.converters.DOMString,defaultValue:()=>``},{key:`source`,converter:n.nullableConverter(n.converters.MessagePort),defaultValue:()=>null},{key:`ports`,converter:n.converters[`sequence`],defaultValue:()=>[]}]),n.converters.CloseEventInit=n.dictionaryConverter([...u,{key:`wasClean`,converter:n.converters.boolean,defaultValue:()=>!1},{key:`code`,converter:n.converters[`unsigned short`],defaultValue:()=>0},{key:`reason`,converter:n.converters.USVString,defaultValue:()=>``}]),n.converters.ErrorEventInit=n.dictionaryConverter([...u,{key:`message`,converter:n.converters.DOMString,defaultValue:()=>``},{key:`filename`,converter:n.converters.USVString,defaultValue:()=>``},{key:`lineno`,converter:n.converters[`unsigned long`],defaultValue:()=>0},{key:`colno`,converter:n.converters[`unsigned long`],defaultValue:()=>0},{key:`error`,converter:n.converters.any}]),t.exports={MessageEvent:o,CloseEvent:c,ErrorEvent:l,createFastMessageEvent:s}})),ot=o(((e,t)=>{t.exports={uid:`258EAFA5-E914-47DA-95CA-C5AB0DC85B11`,sentCloseFrameState:{NOT_SENT:0,PROCESSING:1,SENT:2},staticPropertyDescriptors:{enumerable:!0,writable:!1,configurable:!1},states:{CONNECTING:0,OPEN:1,CLOSING:2,CLOSED:3},opcodes:{CONTINUATION:0,TEXT:1,BINARY:2,CLOSE:8,PING:9,PONG:10},maxUnsigned16Bit:2**16-1,parserStates:{INFO:0,PAYLOADLENGTH_16:2,PAYLOADLENGTH_64:3,READ_DATA:4},emptyBuffer:Buffer.allocUnsafe(0),sendHints:{string:1,typedArray:2,arrayBuffer:3,blob:4}}})),st=o(((e,t)=>{t.exports={kWebSocketURL:Symbol(`url`),kReadyState:Symbol(`ready state`),kController:Symbol(`controller`),kResponse:Symbol(`response`),kBinaryType:Symbol(`binary type`),kSentClose:Symbol(`sent close`),kReceivedClose:Symbol(`received close`),kByteParser:Symbol(`byte parser`)}})),ct=o(((e,t)=>{var{kReadyState:n,kController:r,kResponse:i,kBinaryType:a,kWebSocketURL:o}=st(),{states:s,opcodes:c}=ot(),{ErrorEvent:l,createFastMessageEvent:u}=at(),{isUtf8:d}=require(`node:buffer`),{collectASequenceOfCodePointsFast:f,removeHTTPWhitespace:p}=H();function m(e){return e[n]===s.CONNECTING}function h(e){return e[n]===s.OPEN}function g(e){return e[n]===s.CLOSING}function _(e){return e[n]===s.CLOSED}function v(e,t,n=(e,t)=>new Event(e,t),r={}){let i=n(e,r);t.dispatchEvent(i)}function y(e,t,r){if(e[n]!==s.OPEN)return;let i;if(t===c.TEXT)try{i=M(r)}catch{C(e,`Received invalid UTF-8 in text frame.`);return}else t===c.BINARY&&(i=e[a]===`blob`?new Blob([r]):b(r));v(`message`,e,u,{origin:e[o].origin,data:i})}function b(e){return e.byteLength===e.buffer.byteLength?e.buffer:e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength)}function x(e){if(e.length===0)return!1;for(let t=0;t126||n===34||n===40||n===41||n===44||n===47||n===58||n===59||n===60||n===61||n===62||n===63||n===64||n===91||n===92||n===93||n===123||n===125)return!1}return!0}function S(e){return e>=1e3&&e<1015?e!==1004&&e!==1005&&e!==1006:e>=3e3&&e<=4999}function C(e,t){let{[r]:n,[i]:a}=e;n.abort(),a?.socket&&!a.socket.destroyed&&a.socket.destroy(),t&&v(`error`,e,(e,t)=>new l(e,t),{error:Error(t),message:t})}function w(e){return e===c.CLOSE||e===c.PING||e===c.PONG}function T(e){return e===c.CONTINUATION}function E(e){return e===c.TEXT||e===c.BINARY}function D(e){return E(e)||T(e)||w(e)}function O(e){let t={position:0},n=new Map;for(;t.position57)return!1}let t=Number.parseInt(e,10);return t>=8&&t<=15}var A=typeof process.versions.icu==`string`,j=A?new TextDecoder(`utf-8`,{fatal:!0}):void 0,M=A?j.decode.bind(j):function(e){if(d(e))return e.toString(`utf-8`);throw TypeError(`Invalid utf-8 received.`)};t.exports={isConnecting:m,isEstablished:h,isClosing:g,isClosed:_,fireEvent:v,isValidSubprotocol:x,isValidStatusCode:S,failWebsocketConnection:C,websocketMessageReceived:y,utf8Decode:M,isControlFrame:w,isContinuationFrame:T,isTextBinaryFrame:E,isValidOpcode:D,parseExtensions:O,isValidClientWindowBits:k}})),lt=o(((e,t)=>{var{maxUnsigned16Bit:n}=ot(),r=16386,i,a=null,o=r;try{i=require(`node:crypto`)}catch{i={randomFillSync:function(e,t,n){for(let t=0;tn?(o+=8,a=127):i>125&&(o+=2,a=126);let c=Buffer.allocUnsafe(i+o);c[0]=c[1]=0,c[0]|=128,c[0]=(c[0]&240)+e,c[o-4]=r[0],c[o-3]=r[1],c[o-2]=r[2],c[o-1]=r[3],c[1]=a,a===126?c.writeUInt16BE(i,2):a===127&&(c[2]=c[3]=0,c.writeUIntBE(i,4,6)),c[1]|=128;for(let e=0;e{var{uid:n,states:r,sentCloseFrameState:i,emptyBuffer:a,opcodes:o}=ot(),{kReadyState:s,kSentClose:c,kByteParser:l,kReceivedClose:u,kResponse:d}=st(),{fireEvent:f,failWebsocketConnection:p,isClosing:m,isClosed:h,isEstablished:g,parseExtensions:_}=ct(),{channels:v}=I(),{CloseEvent:y}=at(),{makeRequest:b}=We(),{fetching:x}=Ge(),{Headers:S,getHeadersList:C}=Ve(),{getDecodeSplit:w}=W(),{WebsocketFrameSend:T}=lt(),E;try{E=require(`node:crypto`)}catch{}function D(e,t,r,i,a,o){let s=e;s.protocol=e.protocol===`ws:`?`http:`:`https:`;let c=b({urlList:[s],client:r,serviceWorkers:`none`,referrer:`no-referrer`,mode:`websocket`,credentials:`include`,cache:`no-store`,redirect:`error`});o.headers&&(c.headersList=C(new S(o.headers)));let l=E.randomBytes(16).toString(`base64`);c.headersList.append(`sec-websocket-key`,l),c.headersList.append(`sec-websocket-version`,`13`);for(let e of t)c.headersList.append(`sec-websocket-protocol`,e);return c.headersList.append(`sec-websocket-extensions`,`permessage-deflate; client_max_window_bits`),x({request:c,useParallelQueue:!0,dispatcher:o.dispatcher,processResponse(e){if(e.type===`error`||e.status!==101){p(i,`Received network error or non-101 status code.`);return}if(t.length!==0&&!e.headersList.get(`Sec-WebSocket-Protocol`)){p(i,`Server did not respond with sent protocols.`);return}if(e.headersList.get(`Upgrade`)?.toLowerCase()!==`websocket`){p(i,`Server did not set Upgrade header to "websocket".`);return}if(e.headersList.get(`Connection`)?.toLowerCase()!==`upgrade`){p(i,`Server did not set Connection header to "upgrade".`);return}if(e.headersList.get(`Sec-WebSocket-Accept`)!==E.createHash(`sha1`).update(l+n).digest(`base64`)){p(i,`Incorrect hash received in Sec-WebSocket-Accept header.`);return}let r=e.headersList.get(`Sec-WebSocket-Extensions`),o;if(r!==null&&(o=_(r),!o.has(`permessage-deflate`))){p(i,`Sec-WebSocket-Extensions header does not match.`);return}let s=e.headersList.get(`Sec-WebSocket-Protocol`);if(s!==null&&!w(`sec-websocket-protocol`,c.headersList).includes(s)){p(i,`Protocol was not set in the opening handshake.`);return}e.socket.on(`data`,k),e.socket.on(`close`,A),e.socket.on(`error`,j),v.open.hasSubscribers&&v.open.publish({address:e.socket.address(),protocol:s,extensions:r}),a(e,o)}})}function O(e,t,n,l){if(!(m(e)||h(e)))if(!g(e))p(e,`Connection was closed before it was established.`),e[s]=r.CLOSING;else if(e[c]===i.NOT_SENT){e[c]=i.PROCESSING;let u=new T;t!==void 0&&n===void 0?(u.frameData=Buffer.allocUnsafe(2),u.frameData.writeUInt16BE(t,0)):t!==void 0&&n!==void 0?(u.frameData=Buffer.allocUnsafe(2+l),u.frameData.writeUInt16BE(t,0),u.frameData.write(n,2,`utf-8`)):u.frameData=a,e[d].socket.write(u.createFrame(o.CLOSE)),e[c]=i.SENT,e[s]=r.CLOSING}else e[s]=r.CLOSING}function k(e){this.ws[l].write(e)||this.pause()}function A(){let{ws:e}=this,{[d]:t}=e;t.socket.off(`data`,k),t.socket.off(`close`,A),t.socket.off(`error`,j);let n=e[c]===i.SENT&&e[u],a=1005,o=``,p=e[l].closingInfo;p&&!p.error?(a=p.code??1005,o=p.reason):e[u]||(a=1006),e[s]=r.CLOSED,f(`close`,e,(e,t)=>new y(e,t),{wasClean:n,code:a,reason:o}),v.close.hasSubscribers&&v.close.publish({websocket:e,code:a,reason:o})}function j(e){let{ws:t}=this;t[s]=r.CLOSING,v.socketError.hasSubscribers&&v.socketError.publish(e),this.destroy()}t.exports={establishWebSocketConnection:D,closeWebSocketConnection:O}})),dt=o(((e,t)=>{var{createInflateRaw:n,Z_DEFAULT_WINDOWBITS:r}=require(`node:zlib`),{isValidClientWindowBits:i}=ct(),{MessageSizeExceededError:a}=M(),o=Buffer.from([0,0,255,255]),s=Symbol(`kBuffer`),c=Symbol(`kLength`);t.exports={PerMessageDeflate:class{#e;#t={};#n=0;constructor(e,t){this.#t.serverNoContextTakeover=e.has(`server_no_context_takeover`),this.#t.serverMaxWindowBits=e.get(`server_max_window_bits`),this.#n=t.maxPayloadSize}decompress(e,t,l){if(!this.#e){let e=r;if(this.#t.serverMaxWindowBits){if(!i(this.#t.serverMaxWindowBits)){l(Error(`Invalid server_max_window_bits`));return}e=Number.parseInt(this.#t.serverMaxWindowBits)}try{this.#e=n({windowBits:e})}catch(e){l(e);return}this.#e[s]=[],this.#e[c]=0,this.#e.on(`data`,e=>{if(this.#e[c]+=e.length,this.#n>0&&this.#e[c]>this.#n){l(new a),this.#e.removeAllListeners(),this.#e=null;return}this.#e[s].push(e)}),this.#e.on(`error`,e=>{this.#e=null,l(e)})}this.#e.write(e),t&&this.#e.write(o),this.#e.flush(()=>{if(!this.#e)return;let e=Buffer.concat(this.#e[s],this.#e[c]);this.#e[s].length=0,this.#e[c]=0,l(null,e)})}}}})),ft=o(((e,t)=>{var{Writable:n}=require(`node:stream`),r=require(`node:assert`),{parserStates:i,opcodes:a,states:o,emptyBuffer:s,sentCloseFrameState:c}=ot(),{kReadyState:l,kSentClose:u,kResponse:d,kReceivedClose:f}=st(),{channels:p}=I(),{isValidStatusCode:m,isValidOpcode:h,failWebsocketConnection:g,websocketMessageReceived:_,utf8Decode:v,isControlFrame:y,isTextBinaryFrame:b,isContinuationFrame:x}=ct(),{WebsocketFrameSend:S}=lt(),{closeWebSocketConnection:C}=ut(),{PerMessageDeflate:w}=dt(),{MessageSizeExceededError:T}=M();t.exports={ByteParser:class extends n{#e=[];#t=0;#n=0;#r=!1;#i=i.INFO;#a={};#o=[];#s;#c;constructor(e,t,n={}){super(),this.ws=e,this.#s=t??new Map,this.#c=n.maxPayloadSize??0,this.#s.has(`permessage-deflate`)&&this.#s.set(`permessage-deflate`,new w(t,n))}_write(e,t,n){this.#e.push(e),this.#n+=e.length,this.#r=!0,this.run(n)}#l(){return this.#c>0&&!y(this.#a.opcode)&&this.#a.payloadLength>this.#c?(g(this.ws,`Payload size exceeds maximum allowed size`),!1):!0}run(e){for(;this.#r;)if(this.#i===i.INFO){if(this.#n<2)return e();let t=this.consume(2),n=(t[0]&128)!=0,r=t[0]&15,o=(t[1]&128)==128,s=!n&&r!==a.CONTINUATION,c=t[1]&127,l=t[0]&64,u=t[0]&32,d=t[0]&16;if(!h(r))return g(this.ws,`Invalid opcode received`),e();if(o)return g(this.ws,`Frame cannot be masked`),e();if(l!==0&&!this.#s.has(`permessage-deflate`)){g(this.ws,`Expected RSV1 to be clear.`);return}if(u!==0||d!==0){g(this.ws,`RSV1, RSV2, RSV3 must be clear`);return}if(s&&!b(r)){g(this.ws,`Invalid frame type was fragmented.`);return}if(b(r)&&this.#o.length>0){g(this.ws,`Expected continuation frame`);return}if(this.#a.fragmented&&s){g(this.ws,`Fragmented frame exceeded 125 bytes.`);return}if((c>125||s)&&y(r)){g(this.ws,`Control frame either too large or fragmented`);return}if(x(r)&&this.#o.length===0&&!this.#a.compressed){g(this.ws,`Unexpected continuation frame`);return}if(c<=125){if(this.#a.payloadLength=c,this.#i=i.READ_DATA,!this.#l())return}else c===126?this.#i=i.PAYLOADLENGTH_16:c===127&&(this.#i=i.PAYLOADLENGTH_64);b(r)&&(this.#a.binaryType=r,this.#a.compressed=l!==0),this.#a.opcode=r,this.#a.masked=o,this.#a.fin=n,this.#a.fragmented=s}else if(this.#i===i.PAYLOADLENGTH_16){if(this.#n<2)return e();let t=this.consume(2);if(this.#a.payloadLength=t.readUInt16BE(0),this.#i=i.READ_DATA,!this.#l())return}else if(this.#i===i.PAYLOADLENGTH_64){if(this.#n<8)return e();let t=this.consume(8),n=t.readUInt32BE(0),r=t.readUInt32BE(4);if(n!==0||r>2**31-1){g(this.ws,`Received payload length > 2^31 bytes.`);return}if(this.#a.payloadLength=r,this.#i=i.READ_DATA,!this.#l())return}else if(this.#i===i.READ_DATA){if(this.#n{if(t){g(this.ws,t.message);return}if(this.writeFragments(n),this.#c>0&&this.#t>this.#c){g(this.ws,new T().message);return}if(!this.#a.fin){this.#i=i.INFO,this.#r=!0,this.run(e);return}_(this.ws,this.#a.binaryType,this.consumeFragments()),this.#r=!0,this.#i=i.INFO,this.run(e)}),this.#r=!1;break}else{if(this.writeFragments(t),this.#c>0&&this.#t>this.#c){g(this.ws,new T().message);return}!this.#a.fragmented&&this.#a.fin&&_(this.ws,this.#a.binaryType,this.consumeFragments()),this.#i=i.INFO}}}consume(e){if(e>this.#n)throw Error(`Called consume() before buffers satiated.`);if(e===0)return s;if(this.#e[0].length===e)return this.#n-=this.#e[0].length,this.#e.shift();let t=Buffer.allocUnsafe(e),n=0;for(;n!==e;){let r=this.#e[0],{length:i}=r;if(i+n===e){t.set(this.#e.shift(),n);break}else if(i+n>e){t.set(r.subarray(0,e-n),n),this.#e[0]=r.subarray(e-n);break}else t.set(this.#e.shift(),n),n+=r.length}return this.#n-=e,t}writeFragments(e){this.#t+=e.length,this.#o.push(e)}consumeFragments(){let e=this.#o;if(e.length===1)return this.#t=0,e.shift();let t=Buffer.concat(e,this.#t);return this.#o=[],this.#t=0,t}parseCloseBody(e){r(e.length!==1);let t;if(e.length>=2&&(t=e.readUInt16BE(0)),t!==void 0&&!m(t))return{code:1002,reason:`Invalid status code`,error:!0};let n=e.subarray(2);n[0]===239&&n[1]===187&&n[2]===191&&(n=n.subarray(3));try{n=v(n)}catch{return{code:1007,reason:`Invalid UTF-8`,error:!0}}return{code:t,reason:n,error:!1}}parseControlFrame(e){let{opcode:t,payloadLength:n}=this.#a;if(t===a.CLOSE){if(n===1)return g(this.ws,`Received close frame with a 1-byte body.`),!1;if(this.#a.closeInfo=this.parseCloseBody(e),this.#a.closeInfo.error){let{code:e,reason:t}=this.#a.closeInfo;return C(this.ws,e,t,t.length),g(this.ws,t),!1}if(this.ws[u]!==c.SENT){let e=s;this.#a.closeInfo.code&&(e=Buffer.allocUnsafe(2),e.writeUInt16BE(this.#a.closeInfo.code,0));let t=new S(e);this.ws[d].socket.write(t.createFrame(a.CLOSE),e=>{e||(this.ws[u]=c.SENT)})}return this.ws[l]=o.CLOSING,this.ws[f]=!0,!1}else if(t===a.PING){if(!this.ws[f]){let t=new S(e);this.ws[d].socket.write(t.createFrame(a.PONG)),p.ping.hasSubscribers&&p.ping.publish({payload:e})}}else t===a.PONG&&p.pong.hasSubscribers&&p.pong.publish({payload:e});return!0}get closingInfo(){return this.#a.closeInfo}}}})),pt=o(((e,t)=>{var{WebsocketFrameSend:n}=lt(),{opcodes:r,sendHints:i}=ot(),a=ue(),o=Buffer[Symbol.species],s=class{#e=new a;#t=!1;#n;constructor(e){this.#n=e}add(e,t,n){if(n!==i.blob){let r=c(e,n);if(!this.#t)this.#n.write(r,t);else{let e={promise:null,callback:t,frame:r};this.#e.push(e)}return}let r={promise:e.arrayBuffer().then(e=>{r.promise=null,r.frame=c(e,n)}),callback:t,frame:null};this.#e.push(r),this.#t||this.#r()}async#r(){this.#t=!0;let e=this.#e;for(;!e.isEmpty();){let t=e.shift();t.promise!==null&&await t.promise,this.#n.write(t.frame,t.callback),t.callback=t.frame=null}this.#t=!1}};function c(e,t){return new n(l(e,t)).createFrame(t===i.string?r.TEXT:r.BINARY)}function l(e,t){switch(t){case i.string:return Buffer.from(e);case i.arrayBuffer:case i.blob:return new o(e);case i.typedArray:return new o(e.buffer,e.byteOffset,e.byteLength)}}t.exports={SendQueue:s}})),mt=o(((e,t)=>{var{webidl:n}=U(),{URLSerializer:r}=H(),{environmentSettingsObject:i}=W(),{staticPropertyDescriptors:a,states:o,sentCloseFrameState:s,sendHints:c}=ot(),{kWebSocketURL:l,kReadyState:u,kController:d,kBinaryType:f,kResponse:p,kSentClose:m,kByteParser:h}=st(),{isConnecting:g,isEstablished:_,isClosing:v,isValidSubprotocol:y,fireEvent:b}=ct(),{establishWebSocketConnection:x,closeWebSocketConnection:S}=ut(),{ByteParser:C}=ft(),{kEnumerableProperty:w,isBlobLike:T}=F(),{getGlobalDispatcher:E}=Fe(),{types:D}=require(`node:util`),{ErrorEvent:O,CloseEvent:k}=at(),{SendQueue:A}=pt(),j=class e extends EventTarget{#e={open:null,error:null,close:null,message:null};#t=0;#n=``;#r=``;#i;constructor(t,r=[]){super(),n.util.markAsUncloneable(this);let a=`WebSocket constructor`;n.argumentLengthCheck(arguments,1,a);let o=n.converters[`DOMString or sequence or WebSocketInit`](r,a,`options`);t=n.converters.USVString(t,a,`url`),r=o.protocols;let c=i.settingsObject.baseUrl,p;try{p=new URL(t,c)}catch(e){throw new DOMException(e,`SyntaxError`)}if(p.protocol===`http:`?p.protocol=`ws:`:p.protocol===`https:`&&(p.protocol=`wss:`),p.protocol!==`ws:`&&p.protocol!==`wss:`)throw new DOMException(`Expected a ws: or wss: protocol, got ${p.protocol}`,`SyntaxError`);if(p.hash||p.href.endsWith(`#`))throw new DOMException(`Got fragment`,`SyntaxError`);if(typeof r==`string`&&(r=[r]),r.length!==new Set(r.map(e=>e.toLowerCase())).size||r.length>0&&!r.every(e=>y(e)))throw new DOMException(`Invalid Sec-WebSocket-Protocol value`,`SyntaxError`);this[l]=new URL(p.href);let h=i.settingsObject;this[d]=x(p,r,h,this,(e,t)=>this.#a(e,t),o),this[u]=e.CONNECTING,this[m]=s.NOT_SENT,this[f]=`blob`}close(t=void 0,r=void 0){n.brandCheck(this,e);let i=`WebSocket.close`;if(t!==void 0&&(t=n.converters[`unsigned short`](t,i,`code`,{clamp:!0})),r!==void 0&&(r=n.converters.USVString(r,i,`reason`)),t!==void 0&&t!==1e3&&(t<3e3||t>4999))throw new DOMException(`invalid code`,`InvalidAccessError`);let a=0;if(r!==void 0&&(a=Buffer.byteLength(r),a>123))throw new DOMException(`Reason must be less than 123 bytes; received ${a}`,`SyntaxError`);S(this,t,r,a)}send(t){n.brandCheck(this,e);let r=`WebSocket.send`;if(n.argumentLengthCheck(arguments,1,r),t=n.converters.WebSocketSendData(t,r,`data`),g(this))throw new DOMException(`Sent before connected.`,`InvalidStateError`);if(!(!_(this)||v(this)))if(typeof t==`string`){let e=Buffer.byteLength(t);this.#t+=e,this.#i.add(t,()=>{this.#t-=e},c.string)}else D.isArrayBuffer(t)?(this.#t+=t.byteLength,this.#i.add(t,()=>{this.#t-=t.byteLength},c.arrayBuffer)):ArrayBuffer.isView(t)?(this.#t+=t.byteLength,this.#i.add(t,()=>{this.#t-=t.byteLength},c.typedArray)):T(t)&&(this.#t+=t.size,this.#i.add(t,()=>{this.#t-=t.size},c.blob))}get readyState(){return n.brandCheck(this,e),this[u]}get bufferedAmount(){return n.brandCheck(this,e),this.#t}get url(){return n.brandCheck(this,e),r(this[l])}get extensions(){return n.brandCheck(this,e),this.#r}get protocol(){return n.brandCheck(this,e),this.#n}get onopen(){return n.brandCheck(this,e),this.#e.open}set onopen(t){n.brandCheck(this,e),this.#e.open&&this.removeEventListener(`open`,this.#e.open),typeof t==`function`?(this.#e.open=t,this.addEventListener(`open`,t)):this.#e.open=null}get onerror(){return n.brandCheck(this,e),this.#e.error}set onerror(t){n.brandCheck(this,e),this.#e.error&&this.removeEventListener(`error`,this.#e.error),typeof t==`function`?(this.#e.error=t,this.addEventListener(`error`,t)):this.#e.error=null}get onclose(){return n.brandCheck(this,e),this.#e.close}set onclose(t){n.brandCheck(this,e),this.#e.close&&this.removeEventListener(`close`,this.#e.close),typeof t==`function`?(this.#e.close=t,this.addEventListener(`close`,t)):this.#e.close=null}get onmessage(){return n.brandCheck(this,e),this.#e.message}set onmessage(t){n.brandCheck(this,e),this.#e.message&&this.removeEventListener(`message`,this.#e.message),typeof t==`function`?(this.#e.message=t,this.addEventListener(`message`,t)):this.#e.message=null}get binaryType(){return n.brandCheck(this,e),this[f]}set binaryType(t){n.brandCheck(this,e),t!==`blob`&&t!==`arraybuffer`?this[f]=`blob`:this[f]=t}#a(e,t){this[p]=e;let n=this[d]?.dispatcher?.webSocketOptions?.maxPayloadSize,r=new C(this,t,{maxPayloadSize:n});r.on(`drain`,M),r.on(`error`,N.bind(this)),e.socket.ws=this,this[h]=r,this.#i=new A(e.socket),this[u]=o.OPEN;let i=e.headersList.get(`sec-websocket-extensions`);i!==null&&(this.#r=i);let a=e.headersList.get(`sec-websocket-protocol`);a!==null&&(this.#n=a),b(`open`,this)}};j.CONNECTING=j.prototype.CONNECTING=o.CONNECTING,j.OPEN=j.prototype.OPEN=o.OPEN,j.CLOSING=j.prototype.CLOSING=o.CLOSING,j.CLOSED=j.prototype.CLOSED=o.CLOSED,Object.defineProperties(j.prototype,{CONNECTING:a,OPEN:a,CLOSING:a,CLOSED:a,url:w,readyState:w,bufferedAmount:w,onopen:w,onerror:w,onclose:w,close:w,onmessage:w,binaryType:w,send:w,extensions:w,protocol:w,[Symbol.toStringTag]:{value:`WebSocket`,writable:!1,enumerable:!1,configurable:!0}}),Object.defineProperties(j,{CONNECTING:a,OPEN:a,CLOSING:a,CLOSED:a}),n.converters[`sequence`]=n.sequenceConverter(n.converters.DOMString),n.converters[`DOMString or sequence`]=function(e,t,r){return n.util.Type(e)===`Object`&&Symbol.iterator in e?n.converters[`sequence`](e):n.converters.DOMString(e,t,r)},n.converters.WebSocketInit=n.dictionaryConverter([{key:`protocols`,converter:n.converters[`DOMString or sequence`],defaultValue:()=>[]},{key:`dispatcher`,converter:n.converters.any,defaultValue:()=>E()},{key:`headers`,converter:n.nullableConverter(n.converters.HeadersInit)}]),n.converters[`DOMString or sequence or WebSocketInit`]=function(e){return n.util.Type(e)===`Object`&&!(Symbol.iterator in e)?n.converters.WebSocketInit(e):{protocols:n.converters[`DOMString or sequence`](e)}},n.converters.WebSocketSendData=function(e){if(n.util.Type(e)===`Object`){if(T(e))return n.converters.Blob(e,{strict:!1});if(ArrayBuffer.isView(e)||D.isArrayBuffer(e))return n.converters.BufferSource(e)}return n.converters.USVString(e)};function M(){this.ws[p].socket.resume()}function N(e){let t,n;e instanceof k?(t=e.reason,n=e.code):t=e.message,b(`error`,this,()=>new O(`error`,{error:e,message:t})),S(this,n)}t.exports={WebSocket:j}})),ht=o(((e,t)=>{function n(e){return e.indexOf(`\0`)===-1}function r(e){if(e.length===0)return!1;for(let t=0;t57)return!1;return!0}function i(e){return new Promise(t=>{setTimeout(t,e).unref()})}t.exports={isValidLastEventId:n,isASCIINumber:r,delay:i}})),gt=o(((e,t)=>{var{Transform:n}=require(`node:stream`),{isASCIINumber:r,isValidLastEventId:i}=ht(),a=[239,187,191],o=10,s=13,c=58,l=32;t.exports={EventSourceStream:class extends n{state=null;checkBOM=!0;crlfCheck=!1;eventEndCheck=!1;buffer=null;pos=0;event={data:void 0,event:void 0,id:void 0,retry:void 0};constructor(e={}){e.readableObjectMode=!0,super(e),this.state=e.eventSourceSettings||{},e.push&&(this.push=e.push)}_transform(e,t,n){if(e.length===0){n();return}if(this.buffer?this.buffer=Buffer.concat([this.buffer,e]):this.buffer=e,this.checkBOM)switch(this.buffer.length){case 1:if(this.buffer[0]===a[0]){n();return}this.checkBOM=!1,n();return;case 2:if(this.buffer[0]===a[0]&&this.buffer[1]===a[1]){n();return}this.checkBOM=!1;break;case 3:if(this.buffer[0]===a[0]&&this.buffer[1]===a[1]&&this.buffer[2]===a[2]){this.buffer=Buffer.alloc(0),this.checkBOM=!1,n();return}this.checkBOM=!1;break;default:this.buffer[0]===a[0]&&this.buffer[1]===a[1]&&this.buffer[2]===a[2]&&(this.buffer=this.buffer.subarray(3)),this.checkBOM=!1;break}for(;this.pos0&&(t[a]=o);break}}processEvent(e){e.retry&&r(e.retry)&&(this.state.reconnectionTime=parseInt(e.retry,10)),e.id&&i(e.id)&&(this.state.lastEventId=e.id),e.data!==void 0&&this.push({type:e.event||`message`,options:{data:e.data,lastEventId:this.state.lastEventId,origin:this.state.origin}})}clearEvent(){this.event={data:void 0,event:void 0,id:void 0,retry:void 0}}}}})),_t=o(((e,t)=>{var{pipeline:n}=require(`node:stream`),{fetching:r}=Ge(),{makeRequest:i}=We(),{webidl:a}=U(),{EventSourceStream:o}=gt(),{parseMIMEType:s}=H(),{createFastMessageEvent:c}=at(),{isNetworkError:l}=He(),{delay:u}=ht(),{kEnumerableProperty:d}=F(),{environmentSettingsObject:f}=W(),p=!1,m=3e3,h=0,g=1,_=2,v=`anonymous`,y=`use-credentials`,b=class e extends EventTarget{#e={open:null,error:null,message:null};#t=null;#n=!1;#r=h;#i=null;#a=null;#o;#s;constructor(e,t={}){super(),a.util.markAsUncloneable(this);let n=`EventSource constructor`;a.argumentLengthCheck(arguments,1,n),p||(p=!0,process.emitWarning(`EventSource is experimental, expect them to change at any time.`,{code:`UNDICI-ES`})),e=a.converters.USVString(e,n,`url`),t=a.converters.EventSourceInitDict(t,n,`eventSourceInitDict`),this.#o=t.dispatcher,this.#s={lastEventId:``,reconnectionTime:m};let r=f,o;try{o=new URL(e,r.settingsObject.baseUrl),this.#s.origin=o.origin}catch(e){throw new DOMException(e,`SyntaxError`)}this.#t=o.href;let s=v;t.withCredentials&&(s=y,this.#n=!0);let c={redirect:`follow`,keepalive:!0,mode:`cors`,credentials:s===`anonymous`?`same-origin`:`omit`,referrer:`no-referrer`};c.client=f.settingsObject,c.headersList=[[`accept`,{name:`accept`,value:`text/event-stream`}]],c.cache=`no-store`,c.initiator=`other`,c.urlList=[new URL(this.#t)],this.#i=i(c),this.#c()}get readyState(){return this.#r}get url(){return this.#t}get withCredentials(){return this.#n}#c(){if(this.#r===_)return;this.#r=h;let e={request:this.#i,dispatcher:this.#o};e.processResponseEndOfBody=e=>{l(e)&&(this.dispatchEvent(new Event(`error`)),this.close()),this.#l()},e.processResponse=e=>{if(l(e))if(e.aborted){this.close(),this.dispatchEvent(new Event(`error`));return}else{this.#l();return}let t=e.headersList.get(`content-type`,!0),r=t===null?`failure`:s(t),i=r!==`failure`&&r.essence===`text/event-stream`;if(e.status!==200||i===!1){this.close(),this.dispatchEvent(new Event(`error`));return}this.#r=g,this.dispatchEvent(new Event(`open`)),this.#s.origin=e.urlList[e.urlList.length-1].origin;let a=new o({eventSourceSettings:this.#s,push:e=>{this.dispatchEvent(c(e.type,e.options))}});n(e.body.stream,a,e=>{e?.aborted===!1&&(this.close(),this.dispatchEvent(new Event(`error`)))})},this.#a=r(e)}async#l(){this.#r!==_&&(this.#r=h,this.dispatchEvent(new Event(`error`)),await u(this.#s.reconnectionTime),this.#r===h&&(this.#s.lastEventId.length&&this.#i.headersList.set(`last-event-id`,this.#s.lastEventId,!0),this.#c()))}close(){a.brandCheck(this,e),this.#r!==_&&(this.#r=_,this.#a.abort(),this.#i=null)}get onopen(){return this.#e.open}set onopen(e){this.#e.open&&this.removeEventListener(`open`,this.#e.open),typeof e==`function`?(this.#e.open=e,this.addEventListener(`open`,e)):this.#e.open=null}get onmessage(){return this.#e.message}set onmessage(e){this.#e.message&&this.removeEventListener(`message`,this.#e.message),typeof e==`function`?(this.#e.message=e,this.addEventListener(`message`,e)):this.#e.message=null}get onerror(){return this.#e.error}set onerror(e){this.#e.error&&this.removeEventListener(`error`,this.#e.error),typeof e==`function`?(this.#e.error=e,this.addEventListener(`error`,e)):this.#e.error=null}},x={CONNECTING:{__proto__:null,configurable:!1,enumerable:!0,value:h,writable:!1},OPEN:{__proto__:null,configurable:!1,enumerable:!0,value:g,writable:!1},CLOSED:{__proto__:null,configurable:!1,enumerable:!0,value:_,writable:!1}};Object.defineProperties(b,x),Object.defineProperties(b.prototype,x),Object.defineProperties(b.prototype,{close:d,onerror:d,onmessage:d,onopen:d,readyState:d,url:d,withCredentials:d}),a.converters.EventSourceInitDict=a.dictionaryConverter([{key:`withCredentials`,converter:a.converters.boolean,defaultValue:()=>!1},{key:`dispatcher`,converter:a.converters.any}]),t.exports={EventSource:b,defaultReconnectionTime:m}})),vt=o(((e,t)=>{var n=X(),r=R(),i=pe(),a=Z(),o=Q(),s=me(),c=$(),l=ge(),u=M(),d=F(),{InvalidArgumentError:f}=u,p=Te(),m=V(),h=Ae(),g=Pe(),_=je(),v=Ee(),y=he(),{getGlobalDispatcher:b,setGlobalDispatcher:x}=Fe(),S=Ie(),C=ce(),w=le();Object.assign(r.prototype,p),t.exports.Dispatcher=r,t.exports.Client=n,t.exports.Pool=i,t.exports.BalancedPool=a,t.exports.Agent=o,t.exports.ProxyAgent=s,t.exports.EnvHttpProxyAgent=c,t.exports.RetryAgent=l,t.exports.RetryHandler=y,t.exports.DecoratorHandler=S,t.exports.RedirectHandler=C,t.exports.createRedirectInterceptor=w,t.exports.interceptors={redirect:Le(),retry:Re(),dump:ze(),dns:Be()},t.exports.buildConnector=m,t.exports.errors=u,t.exports.util={parseHeaders:d.parseHeaders,headerNameToString:d.headerNameToString};function T(e){return(t,n,r)=>{if(typeof n==`function`&&(r=n,n=null),!t||typeof t!=`string`&&typeof t!=`object`&&!(t instanceof URL))throw new f(`invalid url`);if(n!=null&&typeof n!=`object`)throw new f(`invalid opts`);if(n&&n.path!=null){if(typeof n.path!=`string`)throw new f(`invalid opts.path`);let e=n.path;n.path.startsWith(`/`)||(e=`/${e}`),t=new URL(d.parseOrigin(t).origin+e)}else n||=typeof t==`object`?t:{},t=d.parseURL(t);let{agent:i,dispatcher:a=b()}=n;if(i)throw new f(`unsupported opts.agent. Did you mean opts.client?`);return e.call(a,{...n,origin:t.origin,path:t.search?`${t.pathname}${t.search}`:t.pathname,method:n.method||(n.body?`PUT`:`GET`)},r)}}t.exports.setGlobalDispatcher=x,t.exports.getGlobalDispatcher=b;var E=Ge().fetch;t.exports.fetch=async function(e,t=void 0){try{return await E(e,t)}catch(e){throw e&&typeof e==`object`&&Error.captureStackTrace(e),e}},t.exports.Headers=Ve().Headers,t.exports.Response=He().Response,t.exports.Request=We().Request,t.exports.FormData=q().FormData,t.exports.File=globalThis.File??require(`node:buffer`).File,t.exports.FileReader=Xe().FileReader;var{setGlobalOrigin:D,getGlobalOrigin:O}=ae();t.exports.setGlobalOrigin=D,t.exports.getGlobalOrigin=O;var{CacheStorage:k}=et(),{kConstruct:A}=Ze();t.exports.caches=new k(A);var{deleteCookie:j,getCookies:N,getSetCookies:P,setCookie:I}=it();t.exports.deleteCookie=j,t.exports.getCookies=N,t.exports.getSetCookies=P,t.exports.setCookie=I;var{parseMIMEType:L,serializeAMimeType:z}=H();t.exports.parseMIMEType=L,t.exports.serializeAMimeType=z;var{CloseEvent:B,ErrorEvent:ee,MessageEvent:te}=at();t.exports.WebSocket=mt().WebSocket,t.exports.CloseEvent=B,t.exports.ErrorEvent=ee,t.exports.MessageEvent=te,t.exports.request=T(p.request),t.exports.stream=T(p.stream),t.exports.pipeline=T(p.pipeline),t.exports.connect=T(p.connect),t.exports.upgrade=T(p.upgrade),t.exports.MockClient=h,t.exports.MockPool=_,t.exports.MockAgent=g,t.exports.mockErrors=v;var{EventSource:ne}=_t();t.exports.EventSource=ne}));A(),vt();var yt;(function(e){e[e.OK=200]=`OK`,e[e.MultipleChoices=300]=`MultipleChoices`,e[e.MovedPermanently=301]=`MovedPermanently`,e[e.ResourceMoved=302]=`ResourceMoved`,e[e.SeeOther=303]=`SeeOther`,e[e.NotModified=304]=`NotModified`,e[e.UseProxy=305]=`UseProxy`,e[e.SwitchProxy=306]=`SwitchProxy`,e[e.TemporaryRedirect=307]=`TemporaryRedirect`,e[e.PermanentRedirect=308]=`PermanentRedirect`,e[e.BadRequest=400]=`BadRequest`,e[e.Unauthorized=401]=`Unauthorized`,e[e.PaymentRequired=402]=`PaymentRequired`,e[e.Forbidden=403]=`Forbidden`,e[e.NotFound=404]=`NotFound`,e[e.MethodNotAllowed=405]=`MethodNotAllowed`,e[e.NotAcceptable=406]=`NotAcceptable`,e[e.ProxyAuthenticationRequired=407]=`ProxyAuthenticationRequired`,e[e.RequestTimeout=408]=`RequestTimeout`,e[e.Conflict=409]=`Conflict`,e[e.Gone=410]=`Gone`,e[e.TooManyRequests=429]=`TooManyRequests`,e[e.InternalServerError=500]=`InternalServerError`,e[e.NotImplemented=501]=`NotImplemented`,e[e.BadGateway=502]=`BadGateway`,e[e.ServiceUnavailable=503]=`ServiceUnavailable`,e[e.GatewayTimeout=504]=`GatewayTimeout`})(yt||={});var bt;(function(e){e.Accept=`accept`,e.ContentType=`content-type`})(bt||={});var xt;(function(e){e.ApplicationJson=`application/json`})(xt||={}),yt.MovedPermanently,yt.ResourceMoved,yt.SeeOther,yt.TemporaryRedirect,yt.PermanentRedirect,yt.BadGateway,yt.ServiceUnavailable,yt.GatewayTimeout;var St=function(e,t,n,r){function i(e){return e instanceof n?e:new n(function(t){t(e)})}return new(n||=Promise)(function(n,a){function o(e){try{c(r.next(e))}catch(e){a(e)}}function s(e){try{c(r.throw(e))}catch(e){a(e)}}function c(e){e.done?n(e.value):i(e.value).then(o,s)}c((r=r.apply(e,t||[])).next())})},{access:Ct,appendFile:wt,writeFile:Tt}=p.promises,Et=`GITHUB_STEP_SUMMARY`;new class{constructor(){this._buffer=``}filePath(){return St(this,void 0,void 0,function*(){if(this._filePath)return this._filePath;let e=process.env[Et];if(!e)throw Error(`Unable to find environment variable for $${Et}. Check if your runtime environment supports job summaries.`);try{yield Ct(e,p.constants.R_OK|p.constants.W_OK)}catch{throw Error(`Unable to access summary file: '${e}'. Check if the file has correct read/write permissions.`)}return this._filePath=e,this._filePath})}wrap(e,t,n={}){let r=Object.entries(n).map(([e,t])=>` ${e}="${t}"`).join(``);return t?`<${e}${r}>${t}`:`<${e}${r}>`}write(e){return St(this,void 0,void 0,function*(){let t=!!e?.overwrite,n=yield this.filePath();return yield(t?Tt:wt)(n,this._buffer,{encoding:`utf8`}),this.emptyBuffer()})}clear(){return St(this,void 0,void 0,function*(){return this.emptyBuffer().write({overwrite:!0})})}stringify(){return this._buffer}isEmptyBuffer(){return this._buffer.length===0}emptyBuffer(){return this._buffer=``,this}addRaw(e,t=!1){return this._buffer+=e,t?this.addEOL():this}addEOL(){return this.addRaw(d.EOL)}addCodeBlock(e,t){let n=Object.assign({},t&&{lang:t}),r=this.wrap(`pre`,this.wrap(`code`,e),n);return this.addRaw(r).addEOL()}addList(e,t=!1){let n=t?`ol`:`ul`,r=e.map(e=>this.wrap(`li`,e)).join(``),i=this.wrap(n,r);return this.addRaw(i).addEOL()}addTable(e){let t=e.map(e=>{let t=e.map(e=>{if(typeof e==`string`)return this.wrap(`td`,e);let{header:t,data:n,colspan:r,rowspan:i}=e,a=t?`th`:`td`,o=Object.assign(Object.assign({},r&&{colspan:r}),i&&{rowspan:i});return this.wrap(a,n,o)}).join(``);return this.wrap(`tr`,t)}).join(``),n=this.wrap(`table`,t);return this.addRaw(n).addEOL()}addDetails(e,t){let n=this.wrap(`details`,this.wrap(`summary`,e)+t);return this.addRaw(n).addEOL()}addImage(e,t,n){let{width:r,height:i}=n||{},a=Object.assign(Object.assign({},r&&{width:r}),i&&{height:i}),o=this.wrap(`img`,null,Object.assign({src:e,alt:t},a));return this.addRaw(o).addEOL()}addHeading(e,t){let n=`h${t}`,r=[`h1`,`h2`,`h3`,`h4`,`h5`,`h6`].includes(n)?n:`h1`,i=this.wrap(r,e);return this.addRaw(i).addEOL()}addSeparator(){let e=this.wrap(`hr`,null);return this.addRaw(e).addEOL()}addBreak(){let e=this.wrap(`br`,null);return this.addRaw(e).addEOL()}addQuote(e,t){let n=Object.assign({},t&&{cite:t}),r=this.wrap(`blockquote`,e,n);return this.addRaw(r).addEOL()}addLink(e,t){let n=this.wrap(`a`,e,{href:t});return this.addRaw(n).addEOL()}};var Dt=function(e,t,n,r){function i(e){return e instanceof n?e:new n(function(t){t(e)})}return new(n||=Promise)(function(n,a){function o(e){try{c(r.next(e))}catch(e){a(e)}}function s(e){try{c(r.throw(e))}catch(e){a(e)}}function c(e){e.done?n(e.value):i(e.value).then(o,s)}c((r=r.apply(e,t||[])).next())})},{chmod:Ot,copyFile:kt,lstat:At,mkdir:jt,open:Mt,readdir:Nt,rename:Pt,rm:Ft,rmdir:It,stat:Lt,symlink:Rt,unlink:zt}=p.promises,Bt=process.platform===`win32`;p.constants.O_RDONLY;function Vt(e){if(e=Ut(e),!e)throw Error(`isRooted() parameter "p" cannot be empty`);return Bt?e.startsWith(`\\`)||/^[A-Z]:/i.test(e):e.startsWith(`/`)}function Ht(e,t){return Dt(this,void 0,void 0,function*(){let n;try{n=yield Lt(e)}catch(t){t.code!==`ENOENT`&&console.log(`Unexpected error attempting to determine if executable file exists '${e}': ${t}`)}if(n&&n.isFile()){if(Bt){let n=m.extname(e).toUpperCase();if(t.some(e=>e.toUpperCase()===n))return e}else if(Wt(n))return e}let r=e;for(let i of t){e=r+i,n=void 0;try{n=yield Lt(e)}catch(t){t.code!==`ENOENT`&&console.log(`Unexpected error attempting to determine if executable file exists '${e}': ${t}`)}if(n&&n.isFile()){if(Bt){try{let t=m.dirname(e),n=m.basename(e).toUpperCase();for(let r of yield Nt(t))if(n===r.toUpperCase()){e=m.join(t,r);break}}catch(t){console.log(`Unexpected error attempting to determine the actual case of the file '${e}': ${t}`)}return e}else if(Wt(n))return e}}return``})}function Ut(e){return e||=``,Bt?(e=e.replace(/\//g,`\\`),e.replace(/\\\\+/g,`\\`)):e.replace(/\/\/+/g,`/`)}function Wt(e){return(e.mode&1)>0||(e.mode&8)>0&&process.getgid!==void 0&&e.gid===process.getgid()||(e.mode&64)>0&&process.getuid!==void 0&&e.uid===process.getuid()}var Gt=function(e,t,n,r){function i(e){return e instanceof n?e:new n(function(t){t(e)})}return new(n||=Promise)(function(n,a){function o(e){try{c(r.next(e))}catch(e){a(e)}}function s(e){try{c(r.throw(e))}catch(e){a(e)}}function c(e){e.done?n(e.value):i(e.value).then(o,s)}c((r=r.apply(e,t||[])).next())})};function Kt(e,t){return Gt(this,void 0,void 0,function*(){if(!e)throw Error(`parameter 'tool' is required`);if(t){let t=yield Kt(e,!1);if(!t)throw Error(Bt?`Unable to locate executable file: ${e}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also verify the file has a valid extension for an executable file.`:`Unable to locate executable file: ${e}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also check the file mode to verify the file is executable.`);return t}let n=yield qt(e);return n&&n.length>0?n[0]:``})}function qt(e){return Gt(this,void 0,void 0,function*(){if(!e)throw Error(`parameter 'tool' is required`);let t=[];if(Bt&&process.env.PATHEXT)for(let e of process.env.PATHEXT.split(m.delimiter))e&&t.push(e);if(Vt(e)){let n=yield Ht(e,t);return n?[n]:[]}if(e.includes(m.sep))return[];let n=[];if(process.env.PATH)for(let e of process.env.PATH.split(m.delimiter))e&&n.push(e);let r=[];for(let i of n){let n=yield Ht(m.join(i,e),t);n&&r.push(n)}return r})}process.platform,h.EventEmitter,h.EventEmitter,d.default.platform(),d.default.arch();var Jt;(function(e){e[e.Success=0]=`Success`,e[e.Failure=1]=`Failure`})(Jt||={});function Yt(e,t){let n=process.env[`INPUT_${e.replace(/ /g,`_`).toUpperCase()}`]||``;if(t&&t.required&&!n)throw Error(`Input required and not supplied: ${e}`);return t&&t.trimWhitespace===!1?n:n.trim()}function Xt(e,t){let n=Yt(e,t).split(` `).filter(e=>e!==``);return t&&t.trimWhitespace===!1?n:n.map(e=>e.trim())}function Zt(e,t){if(process.env.GITHUB_OUTPUT)return D(`OUTPUT`,O(e,t));process.stdout.write(d.EOL),S(`set-output`,{name:e},b(t))}function Qt(e){process.exitCode=Jt.Failure,$t(e)}function $t(e,t={}){S(`error`,x(t),e instanceof Error?e.toString():e)}function en(e){process.stdout.write(e+d.EOL)}var tn=``;function nn(e){let t=e<0?`-`:``,n=Math.abs(e);return n<1024?`${t}${n} B`:`${t}${(n/1024).toFixed(1)} KiB`}function rn(e,t){let n=nn(e);return t===null?n:`${n} (${t>0?`+`:``}${t.toFixed(2)}%)`}function an(e){return e.replace(/\\/g,`\\\\`).replace(/\|/g,`\\|`)}function on(e){let t=an(e),n=t.match(/`+/g)??[],r=Math.max(0,...n.map(e=>e.length))+1,i="`".repeat(r),a=t.startsWith("`")||t.endsWith("`")?` `:``;return`${i}${a}${t}${a}${i}`}function sn(e){return e===null?`⚪`:e<=1?`🟢`:e<=3?`🔵`:e<=6?`🟡`:e<=9?`🟠`:`🔴`}function cn(e){return`| ${on(e.path)} | ${nn(e.baselineBytes)} | ${nn(e.currentBytes)} | ${rn(e.deltaBytes,e.deltaPercent)} | ${sn(e.deltaPercent)} |`}function ln(e){let t=e.latest?` latest`:``;return`${on(e.version)}${t}`}function un(e){if(!e.totals){let t=e.missingFiles.map(on).join(`, `);return`| ${ln(e)} | n/a | n/a | Incomplete: missing ${t} | ⚪ |`}return`| ${ln(e)} | ${nn(e.totals.baselineBytes)} | ${nn(e.totals.currentBytes)} | ${rn(e.totals.deltaBytes,e.totals.deltaPercent)} | ${sn(e.totals.deltaPercent)} |`}function dn(e){return e.releaseStream===void 0?`Compared current build against latest npm release ${on(e.baseline.version)} for ${on(e.packageName)}.`:`Compared current build against ${on(`${e.releaseStream}.x`)} release stream baseline ${on(e.baseline.version)} for ${on(e.packageName)}.`}function fn(e){return e.releaseStream===void 0?`Historical comparison: latest + 10 previous npm releases`:`Historical comparison: ${e.releaseStream}.x release stream baselines`}function pn(e){let t=e.files.map(cn);return t.push(`| **Total** | **${nn(e.totals.baselineBytes)}** | **${nn(e.totals.currentBytes)}** | **${rn(e.totals.deltaBytes,e.totals.deltaPercent)}** | **${sn(e.totals.deltaPercent)}** |`),[tn,``,`## Bundle Size Report`,``,dn(e),``,`| File | Baseline gzip | Current gzip | Difference | Status |`,`|---|---:|---:|---:|:---:|`,...t,``,`
`,`${fn(e)}`,``,`| Release | Baseline gzip | Current gzip | Difference | Status |`,`|---|---:|---:|---:|:---:|`,...e.history.map(un),``,`
`].join(` `)}function mn(e){let t=e.trim().replace(/\\/g,`/`);if(/^[A-Za-z]:\//.test(t)||t.startsWith(`//`))throw Error(`Configured file path must be relative and stay inside the project: ${e}`);let n=l.default.posix.normalize(t);if(!n||n===`.`)throw Error(`Configured file paths must not be empty.`);if(n.startsWith(`/`)||n===`..`||n.startsWith(`../`))throw Error(`Configured file path must be relative and stay inside the project: ${e}`);return n}function hn(e){let t=e.split(/\r?\n/).map(e=>e.trim()).filter(Boolean).map(mn);if(t.length===0)throw Error(`At least one file path must be provided via the files input.`);return[...new Set(t)]}function gn(e,t){let n=l.default.resolve(e),r=l.default.resolve(n,t),i=l.default.relative(n,r);if(i===``||i===`..`||i.startsWith(`..${l.default.sep}`)||l.default.isAbsolute(i))throw Error(`Path must stay inside the project root: ${t}`);return r}var _n=(0,g.promisify)(_.gzip);async function vn(e){return(await _n(e,{level:_.constants.Z_BEST_COMPRESSION})).length}function yn(e,t){return t===0?null:Number(((e-t)/t*100).toFixed(2))}async function bn(e,t,n,r,i){let[a]=r;if(!a)throw Error(`At least one npm release baseline is required.`);let o=[];for(let t of r)o.push(await xn(e,n,t,t.latest));let[s]=o;if(!s.totals)throw Error(`Primary release comparison is incomplete: ${a.version}`);return{metric:`gzip`,packageName:t,releaseStream:i,baseline:{version:a.version,uri:a.uri},localRoot:e,files:s.files,totals:s.totals,history:o}}async function xn(e,t,n,r){let i=[],a=[];for(let o of t){let t=n.files.get(o);if(!t){if(r)throw Error(`Baseline file not found in primary release ${n.version}: ${o}`);a.push(o);continue}let s=gn(e,o),c;try{c=await(0,y.readFile)(s)}catch(e){throw Error(`Local file not found: ${o} (${e instanceof Error?e.message:String(e)})`)}let l=await vn(t),u=await vn(c),d=u-l;i.push({path:o,baselineBytes:l,currentBytes:u,deltaBytes:d,deltaPercent:yn(u,l)})}let o=i.reduce((e,t)=>e+t.baselineBytes,0),s=i.reduce((e,t)=>e+t.currentBytes,0),c=a.length>0?null:{baselineBytes:o,currentBytes:s,deltaBytes:s-o,deltaPercent:yn(s,o)};return{version:n.version,uri:n.uri,latest:n.latest,complete:a.length===0,missingFiles:a,files:i,totals:c}}function Sn(e){let t=e.trim();if(!t)throw Error(`The package-name input is required.`);if(/\s/.test(t)||t.includes(`:`))throw Error(`Invalid npm package name: ${e}`);if(t.startsWith(`@`)){let n=t.split(`/`);if(n.length!==2||!n[0].slice(1)||!n[1])throw Error(`Invalid npm package name: ${e}`);return t}if(t.includes(`/`))throw Error(`Invalid npm package name: ${e}`);return t}function Cn(e){let t=e.trim();if(t){if(!/^\d+$/.test(t))throw Error(`Invalid release-stream input: ${e}`);return Number(t)}}function wn(){let e=l.default.resolve(Yt(`path`,{required:!1})||`.`),t=Sn(Yt(`package-name`,{required:!0})),n=Cn(Yt(`release-stream`,{required:!1})),r=Xt(`files`,{required:!0}).join(` -`),i=mn(Yt(`output-file`,{required:!1})||`bundle-size-comparison.json`),a=mn(Yt(`markdown-output-file`,{required:!1})||`bundle-size-comparison.md`);return{localRoot:e,packageName:t,releaseStream:n,filePaths:hn(r),outputFile:i,markdownOutputFile:a}}var Tn=`https://registry.npmjs.org`,En=10;function Dn(e){return`${Tn}/${encodeURIComponent(e)}`}function On(e){return!e.includes(`-`)}function kn(e){let t=/^(\d+)\./.exec(e);return t?Number(t[1]):null}function An(e,t,n){let r=n.versions?.[t]?.dist?.tarball;if(typeof r!=`string`||!r.trim())throw Error(`Npm package ${e} version ${t} is missing a tarball URL.`);let i;try{i=new URL(r)}catch{throw Error(`Npm package ${e} version ${t} has an invalid tarball URL.`)}if(i.protocol!==`http:`&&i.protocol!==`https:`)throw Error(`Npm package ${e} version ${t} has an unsupported tarball URL protocol: ${i.protocol}`);return r}function jn(e,t,n){let r=n.time?.[t],i=r?Date.parse(r):NaN;if(Number.isNaN(i))throw Error(`Npm package ${e} version ${t} is missing publish time metadata.`);return i}function Mn(e,t,n){if(n!==void 0){let r=Object.keys(t.versions??{}).filter(e=>On(e)&&kn(e)===n).map(n=>({version:n,publishedAt:jn(e,n,t)})).sort((e,t)=>t.publishedAt-e.publishedAt).slice(0,En+1).map(e=>e.version);if(r.length===0)throw Error(`Npm package ${e} has no stable releases in release stream ${n}.`);return r.map((n,r)=>({version:n,uri:An(e,n,t),latest:r===0}))}let r=t[`dist-tags`]?.latest;if(typeof r!=`string`||!r||!t.versions?.[r])throw Error(`Npm package ${e} does not define a usable latest release.`);let i=jn(e,r,t);return[r,...Object.keys(t.versions).filter(e=>e!==r&&On(e)).map(n=>({version:n,publishedAt:jn(e,n,t)})).filter(e=>e.publishedAtt.publishedAt-e.publishedAt).slice(0,En).map(e=>e.version)].map((n,r)=>({version:n,uri:An(e,n,t),latest:r===0}))}async function Nn(e,t){let n=Dn(e),r;try{r=await fetch(n)}catch(t){throw Error(`Failed to fetch npm metadata for ${e}: ${t instanceof Error?t.message:String(t)}`)}if(!r.ok)throw Error(`Failed to fetch npm metadata for ${e}: HTTP ${r.status} ${r.statusText}`);let i;try{i=await r.json()}catch(t){throw Error(`Failed to parse npm metadata for ${e}: ${t instanceof Error?t.message:String(t)}`)}return Mn(e,i,t)}async function Pn(e,t,n){let r=gn(e,t);return await(0,y.mkdir)(l.default.dirname(r),{recursive:!0}),await(0,y.writeFile)(r,`${JSON.stringify(n,null,2)}\n`,`utf8`),r}async function Fn(e,t,n){let r=gn(e,t);return await(0,y.mkdir)(l.default.dirname(r),{recursive:!0}),await(0,y.writeFile)(r,`${n}\n`,`utf8`),r}var In=(0,g.promisify)(_.gunzip),Ln=512;async function Rn(e){let t;try{t=await fetch(e)}catch(t){throw Error(`Failed to download tarball URI ${e}: ${t instanceof Error?t.message:String(t)}`)}if(!t.ok)throw Error(`Failed to download tarball URI ${e}: HTTP ${t.status} ${t.statusText}`);return Buffer.from(await t.arrayBuffer())}function zn(e,t,n){let r=e.subarray(t,t+n),i=r.indexOf(0);return(i===-1?r:r.subarray(0,i)).toString(`utf8`).trim()}function Bn(e,t){let n=zn(e,124,12).replaceAll(`\0`,``).trim();if(!n)return 0;if(!/^[0-7]+$/.test(n))throw Error(`Tarball entry has invalid size field: ${t}`);let r=Number.parseInt(n,8);if(!Number.isSafeInteger(r))throw Error(`Tarball entry size is too large: ${t}`);return r}function Vn(e){return e.every(e=>e===0)}function Hn(e){return l.default.posix.normalize(e.replace(/\\/g,`/`)).replace(/^\.\//,``).replace(/^\/+/,``)}async function Un(e){let t;try{t=await In(e)}catch(e){throw Error(`Tarball is not a valid .tar.gz archive: ${e instanceof Error?e.message:String(e)}`)}let n=[],r=0;for(;r+Ln<=t.length;){let e=t.subarray(r,r+Ln);if(Vn(e))break;let i=zn(e,0,100),a=zn(e,345,155),o=Hn(a?`${a}/${i}`:i),s=Bn(e,o),c=zn(e,156,1),l=r+Ln,u=l+s;if(u>t.length)throw Error(`Tarball entry is truncated: ${o}`);o&&(c===``||c===`0`)&&n.push({path:o,content:Buffer.from(t.subarray(l,u))}),r=l+Math.ceil(s/Ln)*Ln}if(n.length===0)throw Error(`Tarball did not contain any regular files.`);return n}function Wn(e){let t=e.map(e=>e.split(`/`)[0]).filter(Boolean),[n]=t;return!n||t.some(e=>e!==n)?null:e.every(e=>e.includes(`/`))?n:null}function Gn(e){let t=new Map,n=Wn(e.map(e=>e.path));for(let r of e)t.set(r.path,r.content),n&&r.path.startsWith(`${n}/`)&&t.set(r.path.slice(n.length+1),r.content);return t}async function Kn(){try{let e=wn();en(`Local project root: ${e.localRoot}`),en(`Npm package baseline: ${e.packageName}`),e.releaseStream!==void 0&&en(`Npm release stream baseline: ${e.releaseStream}.x`),en(`Comparing ${e.filePaths.length} file(s) using gzip size.`);let t=await Nn(e.packageName,e.releaseStream);en(`Resolved ${t.length} npm release baseline(s).`);let n=[];for(let r of t){en(`Downloading ${e.packageName}@${r.version}: ${r.uri}`);let t=await Rn(r.uri);n.push({...r,files:Gn(await Un(t))})}let r=await bn(e.localRoot,e.packageName,e.filePaths,n,e.releaseStream),i=await Pn(e.localRoot,e.outputFile,r),a=await Fn(e.localRoot,e.markdownOutputFile,pn(r));en(`Wrote bundle size comparison file: ${i}`),en(`Wrote bundle size Markdown file: ${a}`),Zt(`comparison-file`,i),Zt(`markdown-file`,a),Zt(`size`,String(r.totals.currentBytes)),Zt(`total-current-gzip-size`,String(r.totals.currentBytes)),Zt(`total-baseline-gzip-size`,String(r.totals.baselineBytes)),Zt(`total-delta-gzip-size`,String(r.totals.deltaBytes))}catch(e){Qt(e instanceof Error?e.message:String(e))}}var qn=process.argv[1];function Jn(e=qn,t=process.env){return!!(t.GITHUB_ACTIONS===`true`&&t.INPUT_FILES!==void 0||e&&({}.url===(0,u.pathToFileURL)(e).href||(0,l.normalize)(e).endsWith((0,l.join)(`dist`,`index.js`))))}Jn()&&Kn(),exports.buildComparisonReport=bn,exports.createTarballFileMap=Gn,exports.extractTarGzEntries=Un,exports.parseFilePaths=hn,exports.renderBundleSizeComment=pn,exports.resolveNpmReleaseBaselines=Nn,exports.run=Kn,exports.shouldRunEntrypoint=Jn,exports.statusEmoji=sn; \ No newline at end of file +`),i=mn(Yt(`output-file`,{required:!1})||`bundle-size-comparison.json`),a=mn(Yt(`markdown-output-file`,{required:!1})||`bundle-size-comparison.md`);return{localRoot:e,packageName:t,releaseStream:n,filePaths:hn(r),outputFile:i,markdownOutputFile:a}}var Tn=`https://registry.npmjs.org`,En=10;function Dn(e){return`${Tn}/${encodeURIComponent(e)}`}function On(e){return!e.includes(`-`)}function kn(e){let t=/^(\d+)\./.exec(e);return t?Number(t[1]):null}function An(e,t,n){let r=n.versions?.[t]?.dist?.tarball;if(typeof r!=`string`||!r.trim())throw Error(`Npm package ${e} version ${t} is missing a tarball URL.`);let i;try{i=new URL(r)}catch{throw Error(`Npm package ${e} version ${t} has an invalid tarball URL.`)}if(i.protocol!==`http:`&&i.protocol!==`https:`)throw Error(`Npm package ${e} version ${t} has an unsupported tarball URL protocol: ${i.protocol}`);return r}function jn(e,t,n){let r=n.time?.[t],i=r?Date.parse(r):NaN;if(Number.isNaN(i))throw Error(`Npm package ${e} version ${t} is missing publish time metadata.`);return i}function Mn(e,t,n){if(n!==void 0){let r=Object.keys(t.versions??{}).filter(e=>On(e)&&kn(e)===n).map(n=>({version:n,publishedAt:jn(e,n,t)})).sort((e,t)=>t.publishedAt-e.publishedAt).slice(0,En+1).map(e=>e.version);if(r.length===0)throw Error(`Npm package ${e} has no stable releases in release stream ${n}.`);return r.map((n,r)=>({version:n,uri:An(e,n,t),latest:r===0}))}let r=t[`dist-tags`]?.latest;if(typeof r!=`string`||!r||!t.versions?.[r])throw Error(`Npm package ${e} does not define a usable latest release.`);let i=jn(e,r,t);return[r,...Object.keys(t.versions).filter(e=>e!==r&&On(e)).map(n=>({version:n,publishedAt:jn(e,n,t)})).filter(e=>e.publishedAtt.publishedAt-e.publishedAt).slice(0,En).map(e=>e.version)].map((n,r)=>({version:n,uri:An(e,n,t),latest:r===0}))}async function Nn(e,t){let n=Dn(e),r;try{r=await fetch(n)}catch(t){throw Error(`Failed to fetch npm metadata for ${e}: ${t instanceof Error?t.message:String(t)}`)}if(!r.ok)throw Error(`Failed to fetch npm metadata for ${e}: HTTP ${r.status} ${r.statusText}`);let i;try{i=await r.json()}catch(t){throw Error(`Failed to parse npm metadata for ${e}: ${t instanceof Error?t.message:String(t)}`)}return Mn(e,i,t)}async function Pn(e,t,n){let r=gn(e,t);return await(0,y.mkdir)(l.default.dirname(r),{recursive:!0}),await(0,y.writeFile)(r,`${n}\n`,`utf8`),r}async function Fn(e,t,n){return Pn(e,t,JSON.stringify(n,null,2))}async function In(e,t,n){return Pn(e,t,n)}var Ln=(0,g.promisify)(_.gunzip),Rn=512;async function zn(e){let t;try{t=await fetch(e)}catch(t){throw Error(`Failed to download tarball URI ${e}: ${t instanceof Error?t.message:String(t)}`)}if(!t.ok)throw Error(`Failed to download tarball URI ${e}: HTTP ${t.status} ${t.statusText}`);return Buffer.from(await t.arrayBuffer())}function Bn(e,t,n){let r=e.subarray(t,t+n),i=r.indexOf(0);return(i===-1?r:r.subarray(0,i)).toString(`utf8`).trim()}function Vn(e,t){let n=Bn(e,124,12).replaceAll(`\0`,``).trim();if(!n)return 0;if(!/^[0-7]+$/.test(n))throw Error(`Tarball entry has invalid size field: ${t}`);let r=Number.parseInt(n,8);if(!Number.isSafeInteger(r))throw Error(`Tarball entry size is too large: ${t}`);return r}function Hn(e){return e.every(e=>e===0)}function Un(e){return l.default.posix.normalize(e.replace(/\\/g,`/`)).replace(/^\.\//,``).replace(/^\/+/,``)}async function Wn(e){let t;try{t=await Ln(e)}catch(e){throw Error(`Tarball is not a valid .tar.gz archive: ${e instanceof Error?e.message:String(e)}`)}let n=[],r=0;for(;r+Rn<=t.length;){let e=t.subarray(r,r+Rn);if(Hn(e))break;let i=Bn(e,0,100),a=Bn(e,345,155),o=Un(a?`${a}/${i}`:i),s=Vn(e,o),c=Bn(e,156,1),l=r+Rn,u=l+s;if(u>t.length)throw Error(`Tarball entry is truncated: ${o}`);o&&(c===``||c===`0`)&&n.push({path:o,content:Buffer.from(t.subarray(l,u))}),r=l+Math.ceil(s/Rn)*Rn}if(n.length===0)throw Error(`Tarball did not contain any regular files.`);return n}function Gn(e){let t=e.map(e=>e.split(`/`)[0]).filter(Boolean),[n]=t;return!n||t.some(e=>e!==n)?null:e.every(e=>e.includes(`/`))?n:null}function Kn(e){let t=new Map,n=Gn(e.map(e=>e.path));for(let r of e)t.set(r.path,r.content),n&&r.path.startsWith(`${n}/`)&&t.set(r.path.slice(n.length+1),r.content);return t}async function qn(){try{let e=wn();en(`Local project root: ${e.localRoot}`),en(`Npm package baseline: ${e.packageName}`),e.releaseStream!==void 0&&en(`Npm release stream baseline: ${e.releaseStream}.x`),en(`Comparing ${e.filePaths.length} file(s) using gzip size.`);let t=await Nn(e.packageName,e.releaseStream);en(`Resolved ${t.length} npm release baseline(s).`);let n=[];for(let r of t){en(`Downloading ${e.packageName}@${r.version}: ${r.uri}`);let t=await zn(r.uri);n.push({...r,files:Kn(await Wn(t))})}let r=await bn(e.localRoot,e.packageName,e.filePaths,n,e.releaseStream),i=await Fn(e.localRoot,e.outputFile,r),a=await In(e.localRoot,e.markdownOutputFile,pn(r));en(`Wrote bundle size comparison file: ${i}`),en(`Wrote bundle size Markdown file: ${a}`),Zt(`comparison-file`,i),Zt(`markdown-file`,a),Zt(`size`,String(r.totals.currentBytes)),Zt(`total-current-gzip-size`,String(r.totals.currentBytes)),Zt(`total-baseline-gzip-size`,String(r.totals.baselineBytes)),Zt(`total-delta-gzip-size`,String(r.totals.deltaBytes))}catch(e){Qt(e instanceof Error?e.message:String(e))}}var Jn=process.argv[1];function Yn(e=Jn,t=process.env){return!!(t.GITHUB_ACTIONS===`true`&&t.INPUT_FILES!==void 0||e&&({}.url===(0,u.pathToFileURL)(e).href||(0,l.normalize)(e).endsWith((0,l.join)(`dist`,`index.js`))))}Yn()&&qn(),exports.buildComparisonReport=bn,exports.createTarballFileMap=Kn,exports.extractTarGzEntries=Wn,exports.parseFilePaths=hn,exports.renderBundleSizeComment=pn,exports.resolveNpmReleaseBaselines=Nn,exports.run=qn,exports.shouldRunEntrypoint=Yn,exports.statusEmoji=sn; \ No newline at end of file diff --git a/src/report.ts b/src/report.ts index ca84e80..06fb0cf 100644 --- a/src/report.ts +++ b/src/report.ts @@ -3,30 +3,32 @@ import path from "node:path"; import { resolveInsideRoot } from "@/paths"; import type { ComparisonReport } from "@/types"; -export async function writeComparisonReport( +async function writeReportFile( localRoot: string, outputFile: string, - report: ComparisonReport, + content: string, ): Promise { const outputPath = resolveInsideRoot(localRoot, outputFile); const outputDirectory = path.dirname(outputPath); await mkdir(outputDirectory, { recursive: true }); - await writeFile(outputPath, `${JSON.stringify(report, null, 2)}\n`, "utf8"); + await writeFile(outputPath, `${content}\n`, "utf8"); return outputPath; } +export async function writeComparisonReport( + localRoot: string, + outputFile: string, + report: ComparisonReport, +): Promise { + return writeReportFile(localRoot, outputFile, JSON.stringify(report, null, 2)); +} + export async function writeMarkdownReport( localRoot: string, outputFile: string, markdown: string, ): Promise { - const outputPath = resolveInsideRoot(localRoot, outputFile); - const outputDirectory = path.dirname(outputPath); - - await mkdir(outputDirectory, { recursive: true }); - await writeFile(outputPath, `${markdown}\n`, "utf8"); - - return outputPath; + return writeReportFile(localRoot, outputFile, markdown); }