From ea0121618bb39abc1cff180c258978a02d4e04fd Mon Sep 17 00:00:00 2001
From: Parker Brown <17183625+parkerbxyz@users.noreply.github.com>
Date: Fri, 10 Apr 2026 23:01:59 -0700
Subject: [PATCH 01/29] ci: remove publish-immutable-action workflow (#361)
The `publish-immutable-action` workflow uses `actions/publish-immutable-action@v0.0.4`. The Immutable Actions Publishing feature (OCI-based) has been paused with no GA timeline. This removes the workflow; it can be re-added when the feature becomes generally available.
To fully address #352, the repository-level **immutable releases** setting has also be enabled. This [feature](https://github.blog/changelog/2025-10-28-immutable-releases-are-now-generally-available/) locks release tags and assets after publication, directly preventing the class of attack described in [GHSA-mrrh-fwg8-r2c3](https://github.com/advisories/GHSA-mrrh-fwg8-r2c3).
The existing release workflow is compatible with immutable releases. Build artifacts are committed via `@semantic-release/git` before the tag is created, and major version tags (`v3`, etc.) are plain git tags (not releases) so they remain updatable.
---
.github/workflows/publish-immutable-action.yml | 17 -----------------
1 file changed, 17 deletions(-)
delete mode 100644 .github/workflows/publish-immutable-action.yml
diff --git a/.github/workflows/publish-immutable-action.yml b/.github/workflows/publish-immutable-action.yml
deleted file mode 100644
index dd783deb..00000000
--- a/.github/workflows/publish-immutable-action.yml
+++ /dev/null
@@ -1,17 +0,0 @@
-name: 'Publish Immutable Action'
-
-on:
- release:
- types: [published]
-
-jobs:
- publish:
- runs-on: ubuntu-latest
- permissions:
- contents: read
- id-token: write
- packages: write
- steps:
- - uses: actions/checkout@v6
- - name: Publish Immutable Action
- uses: actions/publish-immutable-action@v0.0.4
From 07e2b760664f080c40eec4eacf7477256582db36 Mon Sep 17 00:00:00 2001
From: Parker Brown <17183625+parkerbxyz@users.noreply.github.com>
Date: Fri, 10 Apr 2026 23:42:53 -0700
Subject: [PATCH 02/29] fix: improve error message when app identifier is empty
(#362)
When `client-id` (or the deprecated `app-id`) resolves to an empty
string, for example because a secret or variable is not available in the
workflow context, the error message from `@octokit/auth-app` is not very
helpful:
```
[@octokit/auth-app] appId option is required
```
A validation check was added recently to catch this earlier, but its
message could be more informative:
```
Either 'client-id' or 'app-id' input must be set
```
This updates the message to clarify that the value resolved to empty and
nudges users toward checking their secret or variable availability:
```
The 'client-id' input must be set to a non-empty string. If using a secret or variable, ensure it is available in this workflow context.
```
Closes #249
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
dist/main.cjs | 2 +-
main.js | 2 +-
tests/index.js.snapshot | 4 ++--
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/dist/main.cjs b/dist/main.cjs
index c7cf562d..b9dc6211 100644
--- a/dist/main.cjs
+++ b/dist/main.cjs
@@ -23352,7 +23352,7 @@ async function run() {
ensureNativeProxySupport();
const clientId = getInput("client-id") || getInput("app-id");
if (!clientId) {
- throw new Error("Either 'client-id' or 'app-id' input must be set");
+ throw new Error("The 'client-id' (or deprecated 'app-id') input must be set to a non-empty string. If using a secret or variable, ensure it is available in this workflow context.");
}
const privateKey = getInput("private-key");
const owner = getInput("owner");
diff --git a/main.js b/main.js
index b6851268..32696dda 100644
--- a/main.js
+++ b/main.js
@@ -20,7 +20,7 @@ async function run() {
const clientId = core.getInput("client-id") || core.getInput("app-id");
if (!clientId) {
- throw new Error("Either 'client-id' or 'app-id' input must be set");
+ throw new Error("The 'client-id' (or deprecated 'app-id') input must be set to a non-empty string. If using a secret or variable, ensure it is available in this workflow context.");
}
const privateKey = core.getInput("private-key");
const owner = core.getInput("owner");
diff --git a/tests/index.js.snapshot b/tests/index.js.snapshot
index d5d5f9b3..4789f44b 100644
--- a/tests/index.js.snapshot
+++ b/tests/index.js.snapshot
@@ -56,11 +56,11 @@ POST /api/v3/app/installations/123456/access_tokens
`;
exports[`main-missing-client-and-app-id.test.js > stderr 1`] = `
-Either 'client-id' or 'app-id' input must be set
+The 'client-id' (or deprecated 'app-id') input must be set to a non-empty string. If using a secret or variable, ensure it is available in this workflow context.
`;
exports[`main-missing-client-and-app-id.test.js > stdout 1`] = `
-::error::Either 'client-id' or 'app-id' input must be set
+::error::The 'client-id' (or deprecated 'app-id') input must be set to a non-empty string. If using a secret or variable, ensure it is available in this workflow context.
`;
exports[`main-missing-owner.test.js > stderr 1`] = `
From 1b10c78c7865c340bc4f6099eb2f838309f1e8c3 Mon Sep 17 00:00:00 2001
From: semantic-release-bot
Date: Sat, 11 Apr 2026 06:43:26 +0000
Subject: [PATCH 03/29] build(release): 3.1.1 [skip ci]
## [3.1.1](https://github.com/actions/create-github-app-token/compare/v3.1.0...v3.1.1) (2026-04-11)
### Bug Fixes
* improve error message when app identifier is empty ([#362](https://github.com/actions/create-github-app-token/issues/362)) ([07e2b76](https://github.com/actions/create-github-app-token/commit/07e2b760664f080c40eec4eacf7477256582db36)), closes [#249](https://github.com/actions/create-github-app-token/issues/249)
---
package-lock.json | 4 ++--
package.json | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index dddbca7f..e37edd3b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "create-github-app-token",
- "version": "3.1.0",
+ "version": "3.1.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "create-github-app-token",
- "version": "3.1.0",
+ "version": "3.1.1",
"license": "MIT",
"dependencies": {
"@actions/core": "^3.0.0",
diff --git a/package.json b/package.json
index 4fb277f0..fbe04802 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
"name": "create-github-app-token",
"private": true,
"type": "module",
- "version": "3.1.0",
+ "version": "3.1.1",
"description": "GitHub Action for creating a GitHub App Installation Access Token",
"engines": {
"node": ">=24.4.0"
From 7989d206df2ffdd9fc88b0eb6d2f0eebee835fd6 Mon Sep 17 00:00:00 2001
From: Josh Johanning
Date: Tue, 21 Apr 2026 11:56:11 -0500
Subject: [PATCH 04/29] docs: use `APP_` prefix instead of reserved `GITHUB_`
prefix (#363)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
---
README.md | 50 +++++++++++++++++++++++++-------------------------
1 file changed, 25 insertions(+), 25 deletions(-)
diff --git a/README.md b/README.md
index c75538ad..2073f975 100644
--- a/README.md
+++ b/README.md
@@ -9,10 +9,10 @@ GitHub Action for creating a GitHub App installation access token.
In order to use this action, you need to:
1. [Register new GitHub App](https://docs.github.com/apps/creating-github-apps/setting-up-a-github-app/creating-a-github-app).
-2. [Store the App's Client ID in your repository environment variables](https://docs.github.com/actions/how-tos/write-workflows/choose-what-workflows-do/use-variables#defining-configuration-variables-for-multiple-workflows) (example: `GITHUB_APP_CLIENT_ID`).
-3. [Store the App's private key in your repository secrets](https://docs.github.com/actions/how-tos/write-workflows/choose-what-workflows-do/use-secrets?tool=webui#creating-secrets-for-a-repository) (example: `GITHUB_APP_PRIVATE_KEY`).
+2. [Store the App's Client ID in your repository variables](https://docs.github.com/actions/how-tos/write-workflows/choose-what-workflows-do/use-variables#defining-configuration-variables-for-multiple-workflows) (example: `APP_CLIENT_ID`).
+3. [Store the App's private key in your repository secrets](https://docs.github.com/actions/how-tos/write-workflows/choose-what-workflows-do/use-secrets?tool=webui#creating-secrets-for-a-repository) (example: `APP_PRIVATE_KEY`).
-> [!IMPORTANT]
+> [!IMPORTANT]
> An installation access token expires after 1 hour. Please [see this comment](https://github.com/actions/create-github-app-token/issues/121#issuecomment-2043214796) for alternative approaches if you have long-running processes.
### Create a token for the current repository
@@ -31,8 +31,8 @@ jobs:
- uses: actions/create-github-app-token@v3
id: app-token
with:
- client-id: ${{ vars.GITHUB_APP_CLIENT_ID }}
- private-key: ${{ secrets.GITHUB_APP_PRIVATE_KEY }}
+ client-id: ${{ vars.APP_CLIENT_ID }}
+ private-key: ${{ secrets.APP_PRIVATE_KEY }}
- uses: ./actions/staging-tests
with:
token: ${{ steps.app-token.outputs.token }}
@@ -51,8 +51,8 @@ jobs:
id: app-token
with:
# required
- client-id: ${{ vars.GITHUB_APP_CLIENT_ID }}
- private-key: ${{ secrets.GITHUB_APP_PRIVATE_KEY }}
+ client-id: ${{ vars.APP_CLIENT_ID }}
+ private-key: ${{ secrets.APP_PRIVATE_KEY }}
- uses: actions/checkout@v6
with:
token: ${{ steps.app-token.outputs.token }}
@@ -77,8 +77,8 @@ jobs:
id: app-token
with:
# required
- client-id: ${{ vars.GITHUB_APP_CLIENT_ID }}
- private-key: ${{ secrets.GITHUB_APP_PRIVATE_KEY }}
+ client-id: ${{ vars.APP_CLIENT_ID }}
+ private-key: ${{ secrets.APP_PRIVATE_KEY }}
- name: Get GitHub App User ID
id: get-user-id
run: echo "user-id=$(gh api "/users/${{ steps.app-token.outputs.app-slug }}[bot]" --jq .id)" >> "$GITHUB_OUTPUT"
@@ -102,8 +102,8 @@ jobs:
id: app-token
with:
# required
- client-id: ${{ vars.GITHUB_APP_CLIENT_ID }}
- private-key: ${{ secrets.GITHUB_APP_PRIVATE_KEY }}
+ client-id: ${{ vars.APP_CLIENT_ID }}
+ private-key: ${{ secrets.APP_PRIVATE_KEY }}
- name: Get GitHub App User ID
id: get-user-id
run: echo "user-id=$(gh api "/users/${{ steps.app-token.outputs.app-slug }}[bot]" --jq .id)" >> "$GITHUB_OUTPUT"
@@ -138,8 +138,8 @@ jobs:
- uses: actions/create-github-app-token@v3
id: app-token
with:
- client-id: ${{ vars.GITHUB_APP_CLIENT_ID }}
- private-key: ${{ secrets.GITHUB_APP_PRIVATE_KEY }}
+ client-id: ${{ vars.APP_CLIENT_ID }}
+ private-key: ${{ secrets.APP_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}
- uses: peter-evans/create-or-update-comment@v4
with:
@@ -160,8 +160,8 @@ jobs:
- uses: actions/create-github-app-token@v3
id: app-token
with:
- client-id: ${{ vars.GITHUB_APP_CLIENT_ID }}
- private-key: ${{ secrets.GITHUB_APP_PRIVATE_KEY }}
+ client-id: ${{ vars.APP_CLIENT_ID }}
+ private-key: ${{ secrets.APP_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}
repositories: |
repo1
@@ -185,8 +185,8 @@ jobs:
- uses: actions/create-github-app-token@v3
id: app-token
with:
- client-id: ${{ vars.GITHUB_APP_CLIENT_ID }}
- private-key: ${{ secrets.GITHUB_APP_PRIVATE_KEY }}
+ client-id: ${{ vars.APP_CLIENT_ID }}
+ private-key: ${{ secrets.APP_PRIVATE_KEY }}
owner: another-owner
- uses: peter-evans/create-or-update-comment@v4
with:
@@ -210,8 +210,8 @@ jobs:
- uses: actions/create-github-app-token@v3
id: app-token
with:
- client-id: ${{ vars.GITHUB_APP_CLIENT_ID }}
- private-key: ${{ secrets.GITHUB_APP_PRIVATE_KEY }}
+ client-id: ${{ vars.APP_CLIENT_ID }}
+ private-key: ${{ secrets.APP_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}
permission-issues: write
- uses: peter-evans/create-or-update-comment@v4
@@ -252,8 +252,8 @@ jobs:
- uses: actions/create-github-app-token@v3
id: app-token
with:
- client-id: ${{ vars.GITHUB_APP_CLIENT_ID }}
- private-key: ${{ secrets.GITHUB_APP_PRIVATE_KEY }}
+ client-id: ${{ vars.APP_CLIENT_ID }}
+ private-key: ${{ secrets.APP_PRIVATE_KEY }}
owner: ${{ matrix.owners-and-repos.owner }}
repositories: ${{ join(matrix.owners-and-repos.repos) }}
- uses: octokit/request-action@v2.x
@@ -310,8 +310,8 @@ If you set `HTTP_PROXY` or `HTTPS_PROXY`, also set `NODE_USE_ENV_PROXY: "1"` on
NO_PROXY: github.example.com
NODE_USE_ENV_PROXY: "1"
with:
- client-id: ${{ vars.GITHUB_APP_CLIENT_ID }}
- private-key: ${{ secrets.GITHUB_APP_PRIVATE_KEY }}
+ client-id: ${{ vars.APP_CLIENT_ID }}
+ private-key: ${{ secrets.APP_PRIVATE_KEY }}
```
## Inputs
@@ -334,14 +334,14 @@ steps:
- name: Decode the GitHub App Private Key
id: decode
run: |
- private_key=$(echo "${{ secrets.GITHUB_APP_PRIVATE_KEY }}" | base64 -d | awk 'BEGIN {ORS="\\n"} {print}' | head -c -2) &> /dev/null
+ private_key=$(echo "${{ secrets.APP_PRIVATE_KEY }}" | base64 -d | awk 'BEGIN {ORS="\\n"} {print}' | head -c -2) &> /dev/null
echo "::add-mask::$private_key"
echo "private-key=$private_key" >> "$GITHUB_OUTPUT"
- name: Generate GitHub App Token
id: app-token
uses: actions/create-github-app-token@v3
with:
- client-id: ${{ vars.GITHUB_APP_CLIENT_ID }}
+ client-id: ${{ vars.APP_CLIENT_ID }}
private-key: ${{ steps.decode.outputs.private-key }}
```
From 6be28c6ca7b413964816a53dc1739dff50d559b5 Mon Sep 17 00:00:00 2001
From: Parker Brown <17183625+parkerbxyz@users.noreply.github.com>
Date: Thu, 7 May 2026 18:13:10 -0700
Subject: [PATCH 05/29] ci: migrate releases to release-please (#367)
## Summary
This updates release automation so the repository can enforce signed
commits. Release version and changelog updates now happen through
release-please PRs instead of direct workflow commits, which allows them
to use the repository's normal signed-commit path.
## Changes
- Replaces semantic-release configuration with release-please manifest
configuration for stable releases and beta prereleases.
- Builds committed `dist/**` assets from the trusted release workflow
after release-please creates or updates a release PR, then commits those
assets back to the release PR branch.
- Keeps floating major version tags, such as `v3`, updated with the
GitHub API after a release is created.
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
.github/workflows/release.yml | 59 ++++++++++++++++++++++++++++-----
.release-please-manifest.json | 3 ++
package.json | 28 ----------------
release-please-config.beta.json | 11 ++++++
release-please-config.json | 8 +++++
5 files changed, 72 insertions(+), 37 deletions(-)
create mode 100644 .release-please-manifest.json
create mode 100644 release-please-config.beta.json
create mode 100644 release-please-config.json
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index c632f2d7..ac5d7c4f 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -1,6 +1,7 @@
name: release
on:
+ workflow_dispatch:
push:
branches:
- "*.x"
@@ -17,24 +18,64 @@ jobs:
name: release
runs-on: ubuntu-latest
steps:
- # build local version to create token
- uses: actions/checkout@v6
+
+ - uses: ./
+ id: app-token
with:
- persist-credentials: false
+ app-id: ${{ vars.RELEASER_APP_ID }}
+ private-key: ${{ secrets.RELEASER_APP_PRIVATE_KEY }}
+
+ - uses: googleapis/release-please-action@45996ed1f6d02564a971a2fa1b5860e934307cf7 # v5.0.0
+ id: release-please
+ with:
+ token: ${{ steps.app-token.outputs.token }}
+ config-file: ${{ github.ref_name == 'beta' && 'release-please-config.beta.json' || 'release-please-config.json' }}
+ manifest-file: .release-please-manifest.json
+ target-branch: ${{ github.ref_name }}
+
+ - uses: actions/checkout@v6
+ if: steps.release-please.outputs.prs_created == 'true'
+ with:
+ ref: ${{ fromJSON(steps.release-please.outputs.pr).headBranchName }}
+ token: ${{ steps.app-token.outputs.token }}
- uses: actions/setup-node@v6
+ if: steps.release-please.outputs.prs_created == 'true'
with:
node-version-file: package.json
- run: npm ci
+ if: steps.release-please.outputs.prs_created == 'true'
+
- run: npm run build
- - uses: ./
- id: app-token
+ if: steps.release-please.outputs.prs_created == 'true'
+
+ - uses: stefanzweifel/git-auto-commit-action@04702edda442b2e678b25b537cec683a1493fcb9 # v7.1.0
+ if: steps.release-please.outputs.prs_created == 'true'
with:
- app-id: ${{ vars.RELEASER_APP_ID }}
- private-key: ${{ secrets.RELEASER_APP_PRIVATE_KEY }}
- # install release dependencies and release
- - run: npm install --no-save @semantic-release/git semantic-release-plugin-github-breaking-version-tag
- - run: npx semantic-release --debug
+ commit_author: "${{ github.actor }} <${{ github.actor_id }}+${{ github.actor }}@users.noreply.github.com>"
+ commit_message: "chore: update dist files"
+ file_pattern: dist/**
+
+ - name: Update major version tag
+ id: update-major-tag
+ if: steps.release-please.outputs.release_created == 'true' && github.ref_name != 'beta'
+ uses: octokit/request-action@b91aabaa861c777dcdb14e2387e30eddf04619ae # v3.0.0
+ continue-on-error: true
+ with:
+ route: PATCH /repos/${{ github.repository }}/git/refs/tags/v${{ steps.release-please.outputs.major }}
+ sha: ${{ steps.release-please.outputs.sha }}
+ force: true
+ env:
+ GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
+
+ - name: Create major version tag
+ if: steps.release-please.outputs.release_created == 'true' && github.ref_name != 'beta' && steps.update-major-tag.outcome == 'failure'
+ uses: octokit/request-action@b91aabaa861c777dcdb14e2387e30eddf04619ae # v3.0.0
+ with:
+ route: POST /repos/${{ github.repository }}/git/refs
+ ref: refs/tags/v${{ steps.release-please.outputs.major }}
+ sha: ${{ steps.release-please.outputs.sha }}
env:
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
new file mode 100644
index 00000000..b4b8d0ff
--- /dev/null
+++ b/.release-please-manifest.json
@@ -0,0 +1,3 @@
+{
+ ".": "3.1.1"
+}
diff --git a/package.json b/package.json
index fbe04802..d12043d9 100644
--- a/package.json
+++ b/package.json
@@ -28,33 +28,5 @@
"open-cli": "^9.0.0",
"undici": "^7.24.6",
"yaml": "^2.8.3"
- },
- "release": {
- "branches": [
- "+([0-9]).x",
- "main",
- {
- "name": "beta",
- "prerelease": true
- }
- ],
- "plugins": [
- "@semantic-release/commit-analyzer",
- "@semantic-release/release-notes-generator",
- "@semantic-release/github",
- "@semantic-release/npm",
- "semantic-release-plugin-github-breaking-version-tag",
- [
- "@semantic-release/git",
- {
- "assets": [
- "package.json",
- "package-lock.json",
- "dist/*"
- ],
- "message": "build(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
- }
- ]
- ]
}
}
diff --git a/release-please-config.beta.json b/release-please-config.beta.json
new file mode 100644
index 00000000..c05cb93c
--- /dev/null
+++ b/release-please-config.beta.json
@@ -0,0 +1,11 @@
+{
+ "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
+ "packages": {
+ ".": {
+ "prerelease": true,
+ "prerelease-type": "beta",
+ "release-type": "node",
+ "versioning": "prerelease"
+ }
+ }
+}
diff --git a/release-please-config.json b/release-please-config.json
new file mode 100644
index 00000000..ee4d8052
--- /dev/null
+++ b/release-please-config.json
@@ -0,0 +1,8 @@
+{
+ "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
+ "packages": {
+ ".": {
+ "release-type": "node"
+ }
+ }
+}
From 6dbbbb1419df9d7e7445c08c9e69e7a0e5b4acde Mon Sep 17 00:00:00 2001
From: Parker Brown <17183625+parkerbxyz@users.noreply.github.com>
Date: Thu, 7 May 2026 18:58:55 -0700
Subject: [PATCH 06/29] ci: use existing release tag format (#369)
## Summary
This updates the release-please manifest configuration to use the
repository's existing `vX.Y.Z` tag format. Without this setting,
manifest mode looks for component-prefixed tags like
`create-github-app-token-v3.1.1`, which do not exist in this repository
and can cause release-please to include already-released commits in a
new release PR.
## Changes
- Sets `include-component-in-tag` to `false` for stable releases.
- Sets `include-component-in-tag` to `false` for beta prereleases.
This should make release-please use tags like `v3.1.1` as the previous
release boundary.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
release-please-config.beta.json | 1 +
release-please-config.json | 1 +
2 files changed, 2 insertions(+)
diff --git a/release-please-config.beta.json b/release-please-config.beta.json
index c05cb93c..a94e3387 100644
--- a/release-please-config.beta.json
+++ b/release-please-config.beta.json
@@ -4,6 +4,7 @@
".": {
"prerelease": true,
"prerelease-type": "beta",
+ "include-component-in-tag": false,
"release-type": "node",
"versioning": "prerelease"
}
diff --git a/release-please-config.json b/release-please-config.json
index ee4d8052..280e4000 100644
--- a/release-please-config.json
+++ b/release-please-config.json
@@ -2,6 +2,7 @@
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
"packages": {
".": {
+ "include-component-in-tag": false,
"release-type": "node"
}
}
From 43e5c345bfd4d4f3ecea019ad0042001a09dd857 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Thu, 7 May 2026 19:09:31 -0700
Subject: [PATCH 07/29] fix(deps): bump @actions/core from 3.0.0 to 3.0.1 in
the production-dependencies group (#364)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Bumps the production-dependencies group with 1 update:
[@actions/core](https://github.com/actions/toolkit/tree/HEAD/packages/core).
Updates `@actions/core` from 3.0.0 to 3.0.1
Changelog
Sourced from @actions/core's
changelog.
3.0.1
- Bump
undici from 6.23.0 to
6.24.1 #2348
Commits
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore ` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore ` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore ` will
remove the ignore condition of the specified dependency and ignore
conditions
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
package-lock.json | 8 ++++----
package.json | 2 +-
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index e37edd3b..83791b4d 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,7 +9,7 @@
"version": "3.1.1",
"license": "MIT",
"dependencies": {
- "@actions/core": "^3.0.0",
+ "@actions/core": "^3.0.1",
"@octokit/auth-app": "^8.2.0",
"@octokit/request": "^10.0.8",
"p-retry": "^8.0.0"
@@ -27,9 +27,9 @@
}
},
"node_modules/@actions/core": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@actions/core/-/core-3.0.0.tgz",
- "integrity": "sha512-zYt6cz+ivnTmiT/ksRVriMBOiuoUpDCJJlZ5KPl2/FRdvwU3f7MPh9qftvbkXJThragzUZieit2nyHUyw53Seg==",
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@actions/core/-/core-3.0.1.tgz",
+ "integrity": "sha512-a6d/Nwahm9fliVGRhdhofo40HjHQasUPusmc7vBfyky+7Z+P2A1J68zyFVaNcEclc/Se+eO595oAr5nwEIoIUA==",
"license": "MIT",
"dependencies": {
"@actions/exec": "^3.0.0",
diff --git a/package.json b/package.json
index d12043d9..5a36f79c 100644
--- a/package.json
+++ b/package.json
@@ -16,7 +16,7 @@
},
"license": "MIT",
"dependencies": {
- "@actions/core": "^3.0.0",
+ "@actions/core": "^3.0.1",
"@octokit/auth-app": "^8.2.0",
"@octokit/request": "^10.0.8",
"p-retry": "^8.0.0"
From 952a2a7073df6bfa5f49bc469ec895b6ec1acea4 Mon Sep 17 00:00:00 2001
From: Stefan
Date: Fri, 8 May 2026 20:56:11 +0200
Subject: [PATCH 08/29] feat: add support for enterprise-level GitHub Apps
(#263)
This pull request adds support for generating GitHub App installation
tokens for enterprise-level installations.
### What changed
- Added a new `enterprise` input to `action.yml`.
- Wired `enterprise` through `main.js` and `lib/main.js`.
- Added validation so `enterprise` cannot be combined with `owner` or
`repositories`.
- Implemented enterprise installation lookup using the direct GitHub API
route `GET /enterprises/{enterprise}/installation`, then used the
returned installation ID to mint an installation token through
`@octokit/auth-app`.
- Updated `README.md` with enterprise installation usage and input
documentation.
- Updated `dist/main.cjs` for the bundled action.
- Shared token creation retry behavior across repository, owner, and
enterprise paths so server errors and transient network errors are
retried, while client errors fail immediately.
### Tests
Added focused test coverage for:
- enterprise token creation
- enterprise token creation with explicit permissions
- enterprise installation not found
- mutual exclusivity with `owner`
- mutual exclusivity with `repositories`
- owner installation client errors are not retried
- transient network errors are retried during token creation
### Notes
- This keeps the existing repository-scoped token behavior unchanged.
- Owner, repository, and enterprise token creation now share the same
retry policy: server errors and recognized transient network errors are
retried, while client errors fail immediately. This intentionally fixes
the previous owner-path behavior that retried client errors.
Refs:
-
https://github.blog/changelog/2025-07-01-enterprise-level-access-for-github-apps-and-installation-automation-apis/
-
https://docs.github.com/en/rest/apps/apps?apiVersion=2022-11-28#get-an-enterprise-installation-for-the-authenticated-app
---------
Co-authored-by: Parker Brown <17183625+parkerbxyz@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
.gitignore | 1 +
README.md | 44 +++-
action.yml | 3 +
dist/main.cjs | 200 ++++++++------
lib/main.js | 244 +++++++++++-------
main.js | 2 +
package-lock.json | 7 +-
package.json | 1 +
tests/index.js | 24 +-
tests/index.js.snapshot | 166 +++++++++++-
tests/main-enterprise-fail-response.test.js | 39 +++
...-enterprise-installation-not-found.test.js | 25 ++
...nterprise-mutual-exclusivity-owner.test.js | 13 +
...se-mutual-exclusivity-repositories.test.js | 13 +
tests/main-enterprise-only-success.test.js | 30 +++
...n-enterprise-token-permissions-set.test.js | 34 +++
...n-token-get-owner-set-client-error.test.js | 23 ++
...n-get-owner-set-repo-network-error.test.js | 39 +++
18 files changed, 714 insertions(+), 194 deletions(-)
create mode 100644 tests/main-enterprise-fail-response.test.js
create mode 100644 tests/main-enterprise-installation-not-found.test.js
create mode 100644 tests/main-enterprise-mutual-exclusivity-owner.test.js
create mode 100644 tests/main-enterprise-mutual-exclusivity-repositories.test.js
create mode 100644 tests/main-enterprise-only-success.test.js
create mode 100644 tests/main-enterprise-token-permissions-set.test.js
create mode 100644 tests/main-token-get-owner-set-client-error.test.js
create mode 100644 tests/main-token-get-owner-set-repo-network-error.test.js
diff --git a/.gitignore b/.gitignore
index b443287f..87966f68 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
.env
coverage
node_modules/
+.DS_Store
diff --git a/README.md b/README.md
index 2073f975..43257164 100644
--- a/README.md
+++ b/README.md
@@ -195,10 +195,32 @@ jobs:
body: "Hello, World!"
```
+### Create a token for an enterprise installation
+
+```yaml
+on: [workflow_dispatch]
+
+jobs:
+ hello-world:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/create-github-app-token@v3
+ id: app-token
+ with:
+ client-id: ${{ vars.APP_CLIENT_ID }}
+ private-key: ${{ secrets.APP_PRIVATE_KEY }}
+ enterprise: my-enterprise-slug
+ - name: Call enterprise management REST API with gh
+ run: |
+ gh api /enterprises/my-enterprise-slug/apps/installable_organizations
+ env:
+ GH_TOKEN: ${{ steps.app-token.outputs.token }}
+```
+
### Create a token with specific permissions
> [!NOTE]
-> Selected permissions must be granted to the installation of the specified app and repository owner. Setting a permission that the installation does not have will result in an error.
+> Selected permissions must be granted to the specified app installation. Setting a permission that the installation does not have will result in an error.
```yaml
on: [issues]
@@ -356,6 +378,13 @@ steps:
> [!NOTE]
> If `owner` is set and `repositories` is empty, access will be scoped to all repositories in the provided repository owner's installation. If `owner` and `repositories` are empty, access will be scoped to only the current repository.
+### `enterprise`
+
+**Optional:** The slug of the enterprise account to generate a token for an enterprise installation.
+
+> [!NOTE]
+> The `enterprise` input is mutually exclusive with `owner` and `repositories`. Use it when the GitHub App is installed on an enterprise account. Enterprise installation tokens can call enterprise APIs, but do not grant organization or repository access.
+
### `permission-`
**Optional:** The permissions to grant to the token. By default, the token inherits all of the installation's permissions. We recommend to explicitly list the permissions that are required for a use case. This follows GitHub's own recommendation to [control permissions of `GITHUB_TOKEN` in workflows](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/controlling-permissions-for-github_token). The documentation also lists all available permissions, just prefix the permission key with `permission-` (e.g., `pull-requests` → `permission-pull-requests`).
@@ -386,13 +415,14 @@ GitHub App slug.
## How it works
-The action creates an installation access token using [the `POST /app/installations/{installation_id}/access_tokens` endpoint](https://docs.github.com/rest/apps/apps?apiVersion=2022-11-28#create-an-installation-access-token-for-an-app). By default,
+The action creates an installation access token using [the `POST /app/installations/{installation_id}/access_tokens` endpoint](https://docs.github.com/rest/apps/apps?apiVersion=2022-11-28#create-an-installation-access-token-for-an-app).
+
+The token target depends on the inputs: `enterprise` creates a token for an enterprise installation, `owner` without `repositories` creates a token for all repositories in the owner's installation, `repositories` scopes the token to those repositories, and no target inputs scopes the token to the current repository.
-1. The token is scoped to the current repository or `repositories` if set.
-2. The token inherits all the installation's permissions.
-3. The token is set as output `token` which can be used in subsequent steps.
-4. Unless the `skip-token-revoke` input is set to true, the token is revoked in the `post` step of the action, which means it cannot be passed to another job.
-5. The token is masked, it cannot be logged accidentally.
+1. The token inherits all the installation's permissions.
+2. The token is set as output `token` which can be used in subsequent steps.
+3. Unless the `skip-token-revoke` input is set to true, the token is revoked in the `post` step of the action, which means it cannot be passed to another job.
+4. The token is masked, it cannot be logged accidentally.
> [!NOTE]
> Installation permissions can differ from the app's permissions they belong to. Installation permissions are set when an app is installed on an account. When the app adds more permissions after the installation, an account administrator will have to approve the new permissions before they are set on the installation.
diff --git a/action.yml b/action.yml
index ce9b276c..a4e11487 100644
--- a/action.yml
+++ b/action.yml
@@ -21,6 +21,9 @@ inputs:
repositories:
description: "Comma or newline-separated list of repositories to install the GitHub App on (defaults to current repository if owner is unset)"
required: false
+ enterprise:
+ description: "The slug of the enterprise account where the GitHub App is installed (cannot be used with 'owner' or 'repositories')"
+ required: false
skip-token-revoke:
description: "If true, the token will not be revoked when the current job is complete"
required: false
diff --git a/dist/main.cjs b/dist/main.cjs
index b9dc6211..dc716995 100644
--- a/dist/main.cjs
+++ b/dist/main.cjs
@@ -22985,7 +22985,7 @@ function isNetworkError(error2) {
return false;
}
const { message, stack } = error2;
- if (message === "Load failed") {
+ if (message === "Load failed" || message.startsWith("Load failed (") && message.endsWith(")")) {
return stack === void 0 || "__sentry_captured__" in error2;
}
if (message.startsWith("error sending request for url")) {
@@ -23196,89 +23196,125 @@ async function pRetry(input, options = {}) {
}
// lib/main.js
-async function main(clientId, privateKey, owner, repositories, permissions, core, createAppAuth2, request2, skipTokenRevoke) {
- let parsedOwner = "";
- let parsedRepositoryNames = [];
+async function main(clientId, privateKey, enterprise, owner, repositories, permissions, core, createAppAuth2, request2, skipTokenRevoke) {
+ if (enterprise && (owner || repositories.length > 0)) {
+ throw new Error("Cannot use 'enterprise' input with 'owner' or 'repositories' inputs");
+ }
+ const target = resolveInstallationTarget(enterprise, owner, repositories, core);
+ const auth5 = createAppAuth2({
+ appId: clientId,
+ privateKey,
+ request: request2
+ });
+ const { authentication, installationId, appSlug } = await pRetry(
+ () => getTokenFromTarget(request2, auth5, target, permissions),
+ createTokenRetryOptions(core, getTokenRetryDescription(target))
+ );
+ core.setSecret(authentication.token);
+ core.setOutput("token", authentication.token);
+ core.setOutput("installation-id", installationId);
+ core.setOutput("app-slug", appSlug);
+ if (!skipTokenRevoke) {
+ core.saveState("token", authentication.token);
+ core.saveState("expiresAt", authentication.expiresAt);
+ }
+}
+function resolveInstallationTarget(enterprise, owner, repositories, core) {
+ if (enterprise) {
+ core.info(`Creating enterprise installation token for enterprise "${enterprise}".`);
+ return { type: "enterprise", enterprise };
+ }
if (!owner && repositories.length === 0) {
- const [owner2, repo] = String(process.env.GITHUB_REPOSITORY).split("/");
- parsedOwner = owner2;
- parsedRepositoryNames = [repo];
+ const [defaultOwner, repo] = String(process.env.GITHUB_REPOSITORY).split("/");
core.info(
- `Inputs 'owner' and 'repositories' are not set. Creating token for this repository (${owner2}/${repo}).`
+ `Inputs 'owner' and 'repositories' are not set. Creating token for this repository (${defaultOwner}/${repo}).`
);
+ return {
+ type: "repository",
+ owner: defaultOwner,
+ repositories: [repo]
+ };
}
if (owner && repositories.length === 0) {
- parsedOwner = owner;
core.info(
`Input 'repositories' is not set. Creating token for all repositories owned by ${owner}.`
);
+ return { type: "owner", owner };
}
- if (!owner && repositories.length > 0) {
- parsedOwner = String(process.env.GITHUB_REPOSITORY_OWNER);
- parsedRepositoryNames = repositories;
+ const parsedOwner = owner || String(process.env.GITHUB_REPOSITORY_OWNER);
+ if (!owner) {
core.info(
`No 'owner' input provided. Using default owner '${parsedOwner}' to create token for the following repositories:${repositories.map((repo) => `
- ${parsedOwner}/${repo}`).join("")}`
);
- }
- if (owner && repositories.length > 0) {
- parsedOwner = owner;
- parsedRepositoryNames = repositories;
+ } else {
core.info(
- `Inputs 'owner' and 'repositories' are set. Creating token for the following repositories:
- ${repositories.map((repo) => `
+ `Inputs 'owner' and 'repositories' are set. Creating token for the following repositories:${repositories.map((repo) => `
- ${parsedOwner}/${repo}`).join("")}`
);
}
- const auth5 = createAppAuth2({
- appId: clientId,
- privateKey,
- request: request2
- });
- let authentication, installationId, appSlug;
- if (parsedRepositoryNames.length > 0) {
- ({ authentication, installationId, appSlug } = await pRetry(
- () => getTokenFromRepository(
+ return {
+ type: "repository",
+ owner: parsedOwner,
+ repositories
+ };
+}
+function getTokenRetryDescription(target) {
+ switch (target.type) {
+ case "enterprise":
+ return `enterprise "${target.enterprise}"`;
+ case "repository":
+ return `"${target.repositories.map((repository) => `${target.owner}/${repository}`).join(",")}"`;
+ case "owner":
+ return `"${target.owner}"`;
+ /* c8 ignore next 2 */
+ default:
+ throw new Error(`Unsupported installation target type: ${target.type}`);
+ }
+}
+function getTokenFromTarget(request2, auth5, target, permissions) {
+ switch (target.type) {
+ case "enterprise":
+ return getTokenFromEnterprise(request2, auth5, target.enterprise, permissions);
+ case "repository":
+ return getTokenFromRepository(
request2,
auth5,
- parsedOwner,
- parsedRepositoryNames,
+ target.owner,
+ target.repositories,
permissions
- ),
- {
- shouldRetry: ({ error: error2 }) => error2.status >= 500,
- onFailedAttempt: (context) => {
- core.info(
- `Failed to create token for "${parsedRepositoryNames.join(
- ","
- )}" (attempt ${context.attemptNumber}): ${context.error.message}`
- );
- },
- retries: 3
- }
- ));
- } else {
- ({ authentication, installationId, appSlug } = await pRetry(
- () => getTokenFromOwner(request2, auth5, parsedOwner, permissions),
- {
- onFailedAttempt: (context) => {
- core.info(
- `Failed to create token for "${parsedOwner}" (attempt ${context.attemptNumber}): ${context.error.message}`
- );
- },
- retries: 3
- }
- ));
- }
- core.setSecret(authentication.token);
- core.setOutput("token", authentication.token);
- core.setOutput("installation-id", installationId);
- core.setOutput("app-slug", appSlug);
- if (!skipTokenRevoke) {
- core.saveState("token", authentication.token);
- core.saveState("expiresAt", authentication.expiresAt);
+ );
+ case "owner":
+ return getTokenFromOwner(request2, auth5, target.owner, permissions);
+ /* c8 ignore next 2 */
+ default:
+ throw new Error(`Unsupported installation target type: ${target.type}`);
}
}
+function createTokenRetryOptions(core, targetDescription) {
+ return {
+ shouldRetry: ({ error: error2 }) => error2.status >= 500 || isNetworkError(error2),
+ onFailedAttempt: (context) => {
+ core.info(
+ `Failed to create token for ${targetDescription} (attempt ${context.attemptNumber}): ${context.error.message}`
+ );
+ },
+ retries: 3
+ };
+}
+async function createInstallationAuthResult(auth5, installation, permissions, options = {}) {
+ const authentication = await auth5({
+ type: "installation",
+ installationId: installation.id,
+ permissions,
+ ...options
+ });
+ return {
+ authentication,
+ installationId: installation.id,
+ appSlug: installation["app_slug"]
+ };
+}
async function getTokenFromOwner(request2, auth5, parsedOwner, permissions) {
const response = await request2("GET /users/{username}/installation", {
username: parsedOwner,
@@ -23286,14 +23322,7 @@ async function getTokenFromOwner(request2, auth5, parsedOwner, permissions) {
hook: auth5.hook
}
});
- const authentication = await auth5({
- type: "installation",
- installationId: response.data.id,
- permissions
- });
- const installationId = response.data.id;
- const appSlug = response.data["app_slug"];
- return { authentication, installationId, appSlug };
+ return createInstallationAuthResult(auth5, response.data, permissions);
}
async function getTokenFromRepository(request2, auth5, parsedOwner, parsedRepositoryNames, permissions) {
const response = await request2("GET /repos/{owner}/{repo}/installation", {
@@ -23303,15 +23332,28 @@ async function getTokenFromRepository(request2, auth5, parsedOwner, parsedReposi
hook: auth5.hook
}
});
- const authentication = await auth5({
- type: "installation",
- installationId: response.data.id,
- repositoryNames: parsedRepositoryNames,
- permissions
+ return createInstallationAuthResult(auth5, response.data, permissions, {
+ repositoryNames: parsedRepositoryNames
});
- const installationId = response.data.id;
- const appSlug = response.data["app_slug"];
- return { authentication, installationId, appSlug };
+}
+async function getTokenFromEnterprise(request2, auth5, enterprise, permissions) {
+ let response;
+ try {
+ response = await request2("GET /enterprises/{enterprise}/installation", {
+ enterprise,
+ request: {
+ hook: auth5.hook
+ }
+ });
+ } catch (error2) {
+ if (error2.status === 404) {
+ throw new Error(
+ `No enterprise installation found matching the enterprise slug "${enterprise}".`
+ );
+ }
+ throw error2;
+ }
+ return createInstallationAuthResult(auth5, response.data, permissions);
}
// lib/request.js
@@ -23355,6 +23397,7 @@ async function run() {
throw new Error("The 'client-id' (or deprecated 'app-id') input must be set to a non-empty string. If using a secret or variable, ensure it is available in this workflow context.");
}
const privateKey = getInput("private-key");
+ const enterprise = getInput("enterprise");
const owner = getInput("owner");
const repositories = getInput("repositories").split(/[\n,]+/).map((s) => s.trim()).filter((x) => x !== "");
const skipTokenRevoke = getBooleanInput("skip-token-revoke");
@@ -23362,6 +23405,7 @@ async function run() {
return main(
clientId,
privateKey,
+ enterprise,
owner,
repositories,
permissions,
diff --git a/lib/main.js b/lib/main.js
index 8f5ef9a0..8fe0942a 100644
--- a/lib/main.js
+++ b/lib/main.js
@@ -1,9 +1,11 @@
import pRetry from "p-retry";
+import isNetworkError from "is-network-error";
// @ts-check
/**
* @param {string} clientId
* @param {string} privateKey
+ * @param {string} enterprise
* @param {string} owner
* @param {string[]} repositories
* @param {undefined | Record} permissions
@@ -15,118 +17,164 @@ import pRetry from "p-retry";
export async function main(
clientId,
privateKey,
+ enterprise,
owner,
repositories,
permissions,
core,
createAppAuth,
request,
- skipTokenRevoke
+ skipTokenRevoke,
) {
- let parsedOwner = "";
- let parsedRepositoryNames = [];
+ // Validate mutual exclusivity of enterprise with owner/repositories
+ if (enterprise && (owner || repositories.length > 0)) {
+ throw new Error("Cannot use 'enterprise' input with 'owner' or 'repositories' inputs");
+ }
+
+ const target = resolveInstallationTarget(enterprise, owner, repositories, core);
+
+ const auth = createAppAuth({
+ appId: clientId,
+ privateKey,
+ request,
+ });
+
+ const { authentication, installationId, appSlug } = await pRetry(
+ () => getTokenFromTarget(request, auth, target, permissions),
+ createTokenRetryOptions(core, getTokenRetryDescription(target))
+ );
+
+ // Register the token with the runner as a secret to ensure it is masked in logs
+ core.setSecret(authentication.token);
+
+ core.setOutput("token", authentication.token);
+ core.setOutput("installation-id", installationId);
+ core.setOutput("app-slug", appSlug);
+
+ // Make token accessible to post function (so we can invalidate it)
+ if (!skipTokenRevoke) {
+ core.saveState("token", authentication.token);
+ core.saveState("expiresAt", authentication.expiresAt);
+ }
+}
+
+function resolveInstallationTarget(enterprise, owner, repositories, core) {
+ if (enterprise) {
+ core.info(`Creating enterprise installation token for enterprise "${enterprise}".`);
+ return { type: "enterprise", enterprise };
+ }
- // If neither owner nor repositories are set, default to current repository
if (!owner && repositories.length === 0) {
- const [owner, repo] = String(process.env.GITHUB_REPOSITORY).split("/");
- parsedOwner = owner;
- parsedRepositoryNames = [repo];
+ const [defaultOwner, repo] = String(process.env.GITHUB_REPOSITORY).split("/");
core.info(
- `Inputs 'owner' and 'repositories' are not set. Creating token for this repository (${owner}/${repo}).`
+ `Inputs 'owner' and 'repositories' are not set. Creating token for this repository (${defaultOwner}/${repo}).`
);
+
+ return {
+ type: "repository",
+ owner: defaultOwner,
+ repositories: [repo],
+ };
}
- // If only an owner is set, default to all repositories from that owner
if (owner && repositories.length === 0) {
- parsedOwner = owner;
-
core.info(
`Input 'repositories' is not set. Creating token for all repositories owned by ${owner}.`
);
+
+ return { type: "owner", owner };
}
- // If repositories are set, but no owner, default to `GITHUB_REPOSITORY_OWNER`
- if (!owner && repositories.length > 0) {
- parsedOwner = String(process.env.GITHUB_REPOSITORY_OWNER);
- parsedRepositoryNames = repositories;
+ const parsedOwner = owner || String(process.env.GITHUB_REPOSITORY_OWNER);
+ if (!owner) {
core.info(
`No 'owner' input provided. Using default owner '${parsedOwner}' to create token for the following repositories:${repositories
.map((repo) => `\n- ${parsedOwner}/${repo}`)
.join("")}`
);
- }
-
- // If both owner and repositories are set, use those values
- if (owner && repositories.length > 0) {
- parsedOwner = owner;
- parsedRepositoryNames = repositories;
-
+ } else {
core.info(
- `Inputs 'owner' and 'repositories' are set. Creating token for the following repositories:
- ${repositories.map((repo) => `\n- ${parsedOwner}/${repo}`).join("")}`
+ `Inputs 'owner' and 'repositories' are set. Creating token for the following repositories:${repositories
+ .map((repo) => `\n- ${parsedOwner}/${repo}`)
+ .join("")}`
);
}
- const auth = createAppAuth({
- appId: clientId,
- privateKey,
- request,
- });
+ return {
+ type: "repository",
+ owner: parsedOwner,
+ repositories,
+ };
+}
- let authentication, installationId, appSlug;
- // If at least one repository is set, get installation ID from that repository
-
- if (parsedRepositoryNames.length > 0) {
- ({ authentication, installationId, appSlug } = await pRetry(
- () =>
- getTokenFromRepository(
- request,
- auth,
- parsedOwner,
- parsedRepositoryNames,
- permissions
- ),
- {
- shouldRetry: ({ error }) => error.status >= 500,
- onFailedAttempt: (context) => {
- core.info(
- `Failed to create token for "${parsedRepositoryNames.join(
- ","
- )}" (attempt ${context.attemptNumber}): ${context.error.message}`
- );
- },
- retries: 3,
- }
- ));
- } else {
- // Otherwise get the installation for the owner, which can either be an organization or a user account
- ({ authentication, installationId, appSlug } = await pRetry(
- () => getTokenFromOwner(request, auth, parsedOwner, permissions),
- {
- onFailedAttempt: (context) => {
- core.info(
- `Failed to create token for "${parsedOwner}" (attempt ${context.attemptNumber}): ${context.error.message}`
- );
- },
- retries: 3,
- }
- ));
+function getTokenRetryDescription(target) {
+ switch (target.type) {
+ case "enterprise":
+ return `enterprise "${target.enterprise}"`;
+ case "repository":
+ return `"${target.repositories
+ .map((repository) => `${target.owner}/${repository}`)
+ .join(",")}"`;
+ case "owner":
+ return `"${target.owner}"`;
+ /* c8 ignore next 2 */
+ default:
+ throw new Error(`Unsupported installation target type: ${target.type}`);
}
+}
- // Register the token with the runner as a secret to ensure it is masked in logs
- core.setSecret(authentication.token);
+function getTokenFromTarget(request, auth, target, permissions) {
+ switch (target.type) {
+ case "enterprise":
+ return getTokenFromEnterprise(request, auth, target.enterprise, permissions);
+ case "repository":
+ return getTokenFromRepository(
+ request,
+ auth,
+ target.owner,
+ target.repositories,
+ permissions
+ );
+ case "owner":
+ return getTokenFromOwner(request, auth, target.owner, permissions);
+ /* c8 ignore next 2 */
+ default:
+ throw new Error(`Unsupported installation target type: ${target.type}`);
+ }
+}
- core.setOutput("token", authentication.token);
- core.setOutput("installation-id", installationId);
- core.setOutput("app-slug", appSlug);
+function createTokenRetryOptions(core, targetDescription) {
+ return {
+ shouldRetry: ({ error }) => error.status >= 500 || isNetworkError(error),
+ onFailedAttempt: (context) => {
+ core.info(
+ `Failed to create token for ${targetDescription} (attempt ${context.attemptNumber}): ${context.error.message}`
+ );
+ },
+ retries: 3,
+ };
+}
- // Make token accessible to post function (so we can invalidate it)
- if (!skipTokenRevoke) {
- core.saveState("token", authentication.token);
- core.saveState("expiresAt", authentication.expiresAt);
- }
+async function createInstallationAuthResult(
+ auth,
+ installation,
+ permissions,
+ options = {},
+) {
+ const authentication = await auth({
+ type: "installation",
+ installationId: installation.id,
+ permissions,
+ ...options,
+ });
+
+ return {
+ authentication,
+ installationId: installation.id,
+ appSlug: installation["app_slug"],
+ };
}
async function getTokenFromOwner(request, auth, parsedOwner, permissions) {
@@ -139,17 +187,8 @@ async function getTokenFromOwner(request, auth, parsedOwner, permissions) {
},
});
- // Get token for for all repositories of the given installation
- const authentication = await auth({
- type: "installation",
- installationId: response.data.id,
- permissions,
- });
-
- const installationId = response.data.id;
- const appSlug = response.data["app_slug"];
-
- return { authentication, installationId, appSlug };
+ // Get token for all repositories of the given installation
+ return createInstallationAuthResult(auth, response.data, permissions);
}
async function getTokenFromRepository(
@@ -169,15 +208,30 @@ async function getTokenFromRepository(
});
// Get token for given repositories
- const authentication = await auth({
- type: "installation",
- installationId: response.data.id,
+ return createInstallationAuthResult(auth, response.data, permissions, {
repositoryNames: parsedRepositoryNames,
- permissions,
});
+}
- const installationId = response.data.id;
- const appSlug = response.data["app_slug"];
+async function getTokenFromEnterprise(request, auth, enterprise, permissions) {
+ let response;
+ try {
+ response = await request("GET /enterprises/{enterprise}/installation", {
+ enterprise,
+ request: {
+ hook: auth.hook,
+ },
+ });
+ } catch (error) {
+ if (error.status === 404) {
+ throw new Error(
+ `No enterprise installation found matching the enterprise slug "${enterprise}".`
+ );
+ }
+
+ throw error;
+ }
- return { authentication, installationId, appSlug };
+ // Get token for the enterprise installation
+ return createInstallationAuthResult(auth, response.data, permissions);
}
diff --git a/main.js b/main.js
index 32696dda..a44409ab 100644
--- a/main.js
+++ b/main.js
@@ -23,6 +23,7 @@ async function run() {
throw new Error("The 'client-id' (or deprecated 'app-id') input must be set to a non-empty string. If using a secret or variable, ensure it is available in this workflow context.");
}
const privateKey = core.getInput("private-key");
+ const enterprise = core.getInput("enterprise");
const owner = core.getInput("owner");
const repositories = core
.getInput("repositories")
@@ -37,6 +38,7 @@ async function run() {
return main(
clientId,
privateKey,
+ enterprise,
owner,
repositories,
permissions,
diff --git a/package-lock.json b/package-lock.json
index 83791b4d..aa183a77 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -12,6 +12,7 @@
"@actions/core": "^3.0.1",
"@octokit/auth-app": "^8.2.0",
"@octokit/request": "^10.0.8",
+ "is-network-error": "^1.3.2",
"p-retry": "^8.0.0"
},
"devDependencies": {
@@ -1252,9 +1253,9 @@
}
},
"node_modules/is-network-error": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.3.1.tgz",
- "integrity": "sha512-6QCxa49rQbmUWLfk0nuGqzql9U8uaV2H6279bRErPBHe/109hCzsLUBUHfbEtvLIHBd6hyXbgedBSHevm43Edw==",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.3.2.tgz",
+ "integrity": "sha512-PhBY86zaxNZUuWP6h13Vu5oFe0XY6/UlKzQnYFELzGVHygP3MxmvTfYSG7GN3aIab/iWudSMgjSnG9Dq+nHrgA==",
"license": "MIT",
"engines": {
"node": ">=16"
diff --git a/package.json b/package.json
index 5a36f79c..60bceff9 100644
--- a/package.json
+++ b/package.json
@@ -19,6 +19,7 @@
"@actions/core": "^3.0.1",
"@octokit/auth-app": "^8.2.0",
"@octokit/request": "^10.0.8",
+ "is-network-error": "^1.3.2",
"p-retry": "^8.0.0"
},
"devDependencies": {
diff --git a/tests/index.js b/tests/index.js
index d3e25211..74cf2723 100644
--- a/tests/index.js
+++ b/tests/index.js
@@ -11,6 +11,13 @@ snapshot.setDefaultSnapshotSerializers([
(value) => (typeof value === "string" ? value : undefined),
]);
+function normalizeStderr(stderr) {
+ return stderr
+ .replaceAll(/\u001B\[[0-9;]*m/g, "")
+ .replaceAll(process.cwd(), "")
+ .replaceAll(/:\d+:\d+/g, "::");
+}
+
// Get all files in tests directory
const files = readdirSync("tests");
@@ -39,10 +46,19 @@ for (const file of testFiles) {
NODE_USE_ENV_PROXY,
...env
} = process.env;
- const { stderr, stdout } = await execFileAsync("node", [`tests/${file}`], {
- env,
- });
- const trimmedStderr = stderr.replace(/\r?\n$/, "");
+ let stderr, stdout;
+ try {
+ ({ stderr, stdout } = await execFileAsync("node", [`tests/${file}`], {
+ env,
+ }));
+ } catch (error) {
+ if (!(error instanceof Error) || !("stderr" in error) || !("stdout" in error)) {
+ throw error;
+ }
+
+ ({ stderr, stdout } = error);
+ }
+ const trimmedStderr = normalizeStderr(stderr).replace(/\r?\n$/, "");
const trimmedStdout = stdout.replace(/\r?\n$/, "");
await t.test("stderr", (t) => {
if (trimmedStderr) t.assert.snapshot(trimmedStderr);
diff --git a/tests/index.js.snapshot b/tests/index.js.snapshot
index 4789f44b..a77b6fa1 100644
--- a/tests/index.js.snapshot
+++ b/tests/index.js.snapshot
@@ -38,7 +38,6 @@ POST /app/installations/123456/access_tokens
exports[`main-custom-github-api-url.test.js > stdout 1`] = `
Inputs 'owner' and 'repositories' are set. Creating token for the following repositories:
-
- actions/create-github-app-token
::add-mask::ghs_16C7e42F292c6912E7710c838347Ae178B4a
@@ -55,6 +54,105 @@ POST /api/v3/app/installations/123456/access_tokens
{"repositories":["create-github-app-token"]}
`;
+exports[`main-enterprise-fail-response.test.js > stdout 1`] = `
+Creating enterprise installation token for enterprise "test-enterprise".
+Failed to create token for enterprise "test-enterprise" (attempt 1): GitHub API not available
+::add-mask::ghs_16C7e42F292c6912E7710c838347Ae178B4a
+
+::set-output name=token::ghs_16C7e42F292c6912E7710c838347Ae178B4a
+
+::set-output name=installation-id::123456
+
+::set-output name=app-slug::github-actions
+::save-state name=token::ghs_16C7e42F292c6912E7710c838347Ae178B4a
+::save-state name=expiresAt::2016-07-11T22:14:10Z
+--- REQUESTS ---
+GET /enterprises/test-enterprise/installation
+GET /enterprises/test-enterprise/installation
+POST /app/installations/123456/access_tokens
+null
+`;
+
+exports[`main-enterprise-installation-not-found.test.js > stderr 1`] = `
+Error: No enterprise installation found matching the enterprise slug "test-enterprise".
+ at getTokenFromEnterprise (file:///lib/main.js::)
+ at process.processTicksAndRejections (node:internal/process/task_queues::)
+ at async pRetry (file:///node_modules/p-retry/index.js::)
+ at async main (file:///lib/main.js::)
+ at async test (file:///tests/main.js::)
+ at async file:///tests/main-enterprise-installation-not-found.test.js::
+`;
+
+exports[`main-enterprise-installation-not-found.test.js > stdout 1`] = `
+Creating enterprise installation token for enterprise "test-enterprise".
+Failed to create token for enterprise "test-enterprise" (attempt 1): No enterprise installation found matching the enterprise slug "test-enterprise".
+::error::No enterprise installation found matching the enterprise slug "test-enterprise".
+--- REQUESTS ---
+GET /enterprises/test-enterprise/installation
+`;
+
+exports[`main-enterprise-mutual-exclusivity-owner.test.js > stderr 1`] = `
+Error: Cannot use 'enterprise' input with 'owner' or 'repositories' inputs
+ at main (file:///lib/main.js::)
+ at run (file:///main.js::)
+ at file:///main.js::
+ at ModuleJob.run (node:internal/modules/esm/module_job::)
+ at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader::)
+ at async file:///tests/main-enterprise-mutual-exclusivity-owner.test.js::
+`;
+
+exports[`main-enterprise-mutual-exclusivity-owner.test.js > stdout 1`] = `
+::error::Cannot use 'enterprise' input with 'owner' or 'repositories' inputs
+`;
+
+exports[`main-enterprise-mutual-exclusivity-repositories.test.js > stderr 1`] = `
+Error: Cannot use 'enterprise' input with 'owner' or 'repositories' inputs
+ at main (file:///lib/main.js::)
+ at run (file:///main.js::)
+ at file:///main.js::
+ at ModuleJob.run (node:internal/modules/esm/module_job::)
+ at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader::)
+ at async file:///tests/main-enterprise-mutual-exclusivity-repositories.test.js::
+`;
+
+exports[`main-enterprise-mutual-exclusivity-repositories.test.js > stdout 1`] = `
+::error::Cannot use 'enterprise' input with 'owner' or 'repositories' inputs
+`;
+
+exports[`main-enterprise-only-success.test.js > stdout 1`] = `
+Creating enterprise installation token for enterprise "test-enterprise".
+::add-mask::ghs_16C7e42F292c6912E7710c838347Ae178B4a
+
+::set-output name=token::ghs_16C7e42F292c6912E7710c838347Ae178B4a
+
+::set-output name=installation-id::123456
+
+::set-output name=app-slug::github-actions
+::save-state name=token::ghs_16C7e42F292c6912E7710c838347Ae178B4a
+::save-state name=expiresAt::2016-07-11T22:14:10Z
+--- REQUESTS ---
+GET /enterprises/test-enterprise/installation
+POST /app/installations/123456/access_tokens
+null
+`;
+
+exports[`main-enterprise-token-permissions-set.test.js > stdout 1`] = `
+Creating enterprise installation token for enterprise "test-enterprise".
+::add-mask::ghs_16C7e42F292c6912E7710c838347Ae178B4a
+
+::set-output name=token::ghs_16C7e42F292c6912E7710c838347Ae178B4a
+
+::set-output name=installation-id::123456
+
+::set-output name=app-slug::github-actions
+::save-state name=token::ghs_16C7e42F292c6912E7710c838347Ae178B4a
+::save-state name=expiresAt::2016-07-11T22:14:10Z
+--- REQUESTS ---
+GET /enterprises/test-enterprise/installation
+POST /app/installations/123456/access_tokens
+{"permissions":{"enterprise_custom_properties_for_organizations":"read"}}
+`;
+
exports[`main-missing-client-and-app-id.test.js > stderr 1`] = `
The 'client-id' (or deprecated 'app-id') input must be set to a non-empty string. If using a secret or variable, ensure it is available in this workflow context.
`;
@@ -103,7 +201,6 @@ exports[`main-repo-skew.test.js > stderr 1`] = `
exports[`main-repo-skew.test.js > stdout 1`] = `
Inputs 'owner' and 'repositories' are set. Creating token for the following repositories:
-
- actions/failed-repo
::add-mask::ghs_16C7e42F292c6912E7710c838347Ae178B4a
@@ -121,6 +218,45 @@ POST /app/installations/123456/access_tokens
{"repositories":["failed-repo"]}
`;
+exports[`main-token-get-owner-set-client-error.test.js > stderr 1`] = `
+RequestError [HttpError]: Forbidden
+ at fetchWrapper (file:///node_modules/@octokit/request/dist-bundle/index.js::)
+ at process.processTicksAndRejections (node:internal/process/task_queues::)
+ at async hook (file:///node_modules/@octokit/auth-app/dist-node/index.js::)
+ at async getTokenFromOwner (file:///lib/main.js::)
+ at async pRetry (file:///node_modules/p-retry/index.js::)
+ at async main (file:///lib/main.js::)
+ at async test (file:///tests/main.js::)
+ at async file:///tests/main-token-get-owner-set-client-error.test.js:: {
+ status: 403,
+ request: {
+ method: 'GET',
+ url: 'https://api.github.com/users/smockle/installation',
+ headers: {
+ accept: 'application/vnd.github.v3+json',
+ 'user-agent': 'actions/create-github-app-token',
+ authorization: 'bearer [REDACTED]'
+ },
+ request: { hook: [Function: bound hook] AsyncFunction }
+ },
+ response: {
+ url: 'https://api.github.com/users/smockle/installation',
+ status: 403,
+ headers: { 'content-type': 'application/json' },
+ data: { message: 'Forbidden' }
+ },
+ [cause]: undefined
+}
+`;
+
+exports[`main-token-get-owner-set-client-error.test.js > stdout 1`] = `
+Input 'repositories' is not set. Creating token for all repositories owned by smockle.
+Failed to create token for "smockle" (attempt 1): Forbidden
+::error::Forbidden
+--- REQUESTS ---
+GET /users/smockle/installation
+`;
+
exports[`main-token-get-owner-set-fail-response.test.js > stdout 1`] = `
Input 'repositories' is not set. Creating token for all repositories owned by smockle.
Failed to create token for "smockle" (attempt 1): GitHub API not available
@@ -142,9 +278,8 @@ null
exports[`main-token-get-owner-set-repo-fail-response.test.js > stdout 1`] = `
Inputs 'owner' and 'repositories' are set. Creating token for the following repositories:
-
- actions/failed-repo
-Failed to create token for "failed-repo" (attempt 1): GitHub API not available
+Failed to create token for "actions/failed-repo" (attempt 1): GitHub API not available
::add-mask::ghs_16C7e42F292c6912E7710c838347Ae178B4a
::set-output name=token::ghs_16C7e42F292c6912E7710c838347Ae178B4a
@@ -161,9 +296,28 @@ POST /app/installations/123456/access_tokens
{"repositories":["failed-repo"]}
`;
+exports[`main-token-get-owner-set-repo-network-error.test.js > stdout 1`] = `
+Inputs 'owner' and 'repositories' are set. Creating token for the following repositories:
+- actions/network-repo
+Failed to create token for "actions/network-repo" (attempt 1): fetch failed
+::add-mask::ghs_16C7e42F292c6912E7710c838347Ae178B4a
+
+::set-output name=token::ghs_16C7e42F292c6912E7710c838347Ae178B4a
+
+::set-output name=installation-id::123456
+
+::set-output name=app-slug::github-actions
+::save-state name=token::ghs_16C7e42F292c6912E7710c838347Ae178B4a
+::save-state name=expiresAt::2016-07-11T22:14:10Z
+--- REQUESTS ---
+GET /repos/actions/network-repo/installation
+GET /repos/actions/network-repo/installation
+POST /app/installations/123456/access_tokens
+{"repositories":["network-repo"]}
+`;
+
exports[`main-token-get-owner-set-repo-set-to-many-newline.test.js > stdout 1`] = `
Inputs 'owner' and 'repositories' are set. Creating token for the following repositories:
-
- actions/create-github-app-token
- actions/toolkit
- actions/checkout
@@ -184,7 +338,6 @@ POST /app/installations/123456/access_tokens
exports[`main-token-get-owner-set-repo-set-to-many.test.js > stdout 1`] = `
Inputs 'owner' and 'repositories' are set. Creating token for the following repositories:
-
- actions/create-github-app-token
- actions/toolkit
- actions/checkout
@@ -205,7 +358,6 @@ POST /app/installations/123456/access_tokens
exports[`main-token-get-owner-set-repo-set-to-one.test.js > stdout 1`] = `
Inputs 'owner' and 'repositories' are set. Creating token for the following repositories:
-
- actions/create-github-app-token
::add-mask::ghs_16C7e42F292c6912E7710c838347Ae178B4a
diff --git a/tests/main-enterprise-fail-response.test.js b/tests/main-enterprise-fail-response.test.js
new file mode 100644
index 00000000..068e2cba
--- /dev/null
+++ b/tests/main-enterprise-fail-response.test.js
@@ -0,0 +1,39 @@
+import { test } from "./main.js";
+
+// Verify enterprise installation lookup retries when the GitHub API returns a 500 error.
+await test((mockPool) => {
+ process.env.INPUT_ENTERPRISE = "test-enterprise";
+ delete process.env.INPUT_OWNER;
+ delete process.env.INPUT_REPOSITORIES;
+
+ const mockInstallationId = "123456";
+ const mockAppSlug = "github-actions";
+
+ mockPool
+ .intercept({
+ path: "/enterprises/test-enterprise/installation",
+ method: "GET",
+ headers: {
+ accept: "application/vnd.github.v3+json",
+ "user-agent": "actions/create-github-app-token",
+ // Intentionally omitting the `authorization` header, since JWT creation is not idempotent.
+ },
+ })
+ .reply(500, "GitHub API not available");
+
+ mockPool
+ .intercept({
+ path: "/enterprises/test-enterprise/installation",
+ method: "GET",
+ headers: {
+ accept: "application/vnd.github.v3+json",
+ "user-agent": "actions/create-github-app-token",
+ // Intentionally omitting the `authorization` header, since JWT creation is not idempotent.
+ },
+ })
+ .reply(
+ 200,
+ { id: mockInstallationId, app_slug: mockAppSlug },
+ { headers: { "content-type": "application/json" } },
+ );
+});
diff --git a/tests/main-enterprise-installation-not-found.test.js b/tests/main-enterprise-installation-not-found.test.js
new file mode 100644
index 00000000..a578967c
--- /dev/null
+++ b/tests/main-enterprise-installation-not-found.test.js
@@ -0,0 +1,25 @@
+import { test } from "./main.js";
+
+// Verify `main` handles when no enterprise installation is found.
+await test((mockPool) => {
+ delete process.env.INPUT_OWNER;
+ delete process.env.INPUT_REPOSITORIES;
+ process.env.INPUT_ENTERPRISE = "test-enterprise";
+
+ // Mock the enterprise installation endpoint to return no matching installation
+ mockPool
+ .intercept({
+ path: "/enterprises/test-enterprise/installation",
+ method: "GET",
+ headers: {
+ accept: "application/vnd.github.v3+json",
+ "user-agent": "actions/create-github-app-token",
+ // Intentionally omitting the `authorization` header, since JWT creation is not idempotent.
+ },
+ })
+ .reply(
+ 404,
+ { message: "Not Found" },
+ { headers: { "content-type": "application/json" } }
+ );
+});
diff --git a/tests/main-enterprise-mutual-exclusivity-owner.test.js b/tests/main-enterprise-mutual-exclusivity-owner.test.js
new file mode 100644
index 00000000..2c2b4131
--- /dev/null
+++ b/tests/main-enterprise-mutual-exclusivity-owner.test.js
@@ -0,0 +1,13 @@
+import { DEFAULT_ENV } from "./main.js";
+
+// Verify `main` exits with an error when `enterprise` is used with `owner` input.
+// Set up environment with enterprise and owner set
+for (const [key, value] of Object.entries(DEFAULT_ENV)) {
+ process.env[key] = value;
+}
+
+process.env.INPUT_ENTERPRISE = "test-enterprise";
+process.env.INPUT_OWNER = "test-owner";
+
+const { default: promise } = await import("../main.js");
+await promise;
diff --git a/tests/main-enterprise-mutual-exclusivity-repositories.test.js b/tests/main-enterprise-mutual-exclusivity-repositories.test.js
new file mode 100644
index 00000000..795a82cc
--- /dev/null
+++ b/tests/main-enterprise-mutual-exclusivity-repositories.test.js
@@ -0,0 +1,13 @@
+import { DEFAULT_ENV } from "./main.js";
+
+// Verify `main` exits with an error when `enterprise` is used with `repositories` input.
+// Set up environment with enterprise and repositories set
+for (const [key, value] of Object.entries(DEFAULT_ENV)) {
+ process.env[key] = value;
+}
+
+process.env.INPUT_ENTERPRISE = "test-enterprise";
+process.env.INPUT_REPOSITORIES = "repo1,repo2";
+
+const { default: promise } = await import("../main.js");
+await promise;
diff --git a/tests/main-enterprise-only-success.test.js b/tests/main-enterprise-only-success.test.js
new file mode 100644
index 00000000..5008375e
--- /dev/null
+++ b/tests/main-enterprise-only-success.test.js
@@ -0,0 +1,30 @@
+import { test } from "./main.js";
+
+// Verify `main` successfully obtains a token when only the `enterprise` input is set.
+await test((mockPool) => {
+ process.env.INPUT_ENTERPRISE = "test-enterprise";
+ delete process.env.INPUT_OWNER;
+ delete process.env.INPUT_REPOSITORIES;
+
+ // Mock the enterprise installation endpoint
+ const mockInstallationId = "123456";
+ const mockAppSlug = "github-actions";
+ mockPool
+ .intercept({
+ path: "/enterprises/test-enterprise/installation",
+ method: "GET",
+ headers: {
+ accept: "application/vnd.github.v3+json",
+ "user-agent": "actions/create-github-app-token",
+ // Intentionally omitting the `authorization` header, since JWT creation is not idempotent.
+ },
+ })
+ .reply(
+ 200,
+ {
+ id: mockInstallationId,
+ app_slug: mockAppSlug,
+ },
+ { headers: { "content-type": "application/json" } }
+ );
+});
diff --git a/tests/main-enterprise-token-permissions-set.test.js b/tests/main-enterprise-token-permissions-set.test.js
new file mode 100644
index 00000000..2073e7b3
--- /dev/null
+++ b/tests/main-enterprise-token-permissions-set.test.js
@@ -0,0 +1,34 @@
+import { test } from "./main.js";
+
+// Use a declared enterprise permission from the generated schema to verify
+// enterprise token requests forward permission inputs to token creation.
+await test((mockPool) => {
+ process.env.INPUT_ENTERPRISE = "test-enterprise";
+ delete process.env.INPUT_OWNER;
+ delete process.env.INPUT_REPOSITORIES;
+ process.env[
+ "INPUT_PERMISSION-ENTERPRISE-CUSTOM-PROPERTIES-FOR-ORGANIZATIONS"
+ ] = "read";
+
+ // Mock the enterprise installation endpoint
+ const mockInstallationId = "123456";
+ const mockAppSlug = "github-actions";
+ mockPool
+ .intercept({
+ path: "/enterprises/test-enterprise/installation",
+ method: "GET",
+ headers: {
+ accept: "application/vnd.github.v3+json",
+ "user-agent": "actions/create-github-app-token",
+ // Intentionally omitting the `authorization` header, since JWT creation is not idempotent.
+ },
+ })
+ .reply(
+ 200,
+ {
+ id: mockInstallationId,
+ app_slug: mockAppSlug,
+ },
+ { headers: { "content-type": "application/json" } }
+ );
+});
diff --git a/tests/main-token-get-owner-set-client-error.test.js b/tests/main-token-get-owner-set-client-error.test.js
new file mode 100644
index 00000000..237b405f
--- /dev/null
+++ b/tests/main-token-get-owner-set-client-error.test.js
@@ -0,0 +1,23 @@
+import { test } from "./main.js";
+
+// Verify client errors are not retried when getting a token for a user or organization.
+await test((mockPool) => {
+ process.env.INPUT_OWNER = "smockle";
+ delete process.env.INPUT_REPOSITORIES;
+
+ mockPool
+ .intercept({
+ path: "/users/smockle/installation",
+ method: "GET",
+ headers: {
+ accept: "application/vnd.github.v3+json",
+ "user-agent": "actions/create-github-app-token",
+ // Intentionally omitting the `authorization` header, since JWT creation is not idempotent.
+ },
+ })
+ .reply(
+ 403,
+ { message: "Forbidden" },
+ { headers: { "content-type": "application/json" } },
+ );
+});
diff --git a/tests/main-token-get-owner-set-repo-network-error.test.js b/tests/main-token-get-owner-set-repo-network-error.test.js
new file mode 100644
index 00000000..3da78f9e
--- /dev/null
+++ b/tests/main-token-get-owner-set-repo-network-error.test.js
@@ -0,0 +1,39 @@
+import { test } from "./main.js";
+
+// Verify transient network errors are retried when getting a repository token.
+await test((mockPool) => {
+ process.env.INPUT_OWNER = "actions";
+ process.env.INPUT_REPOSITORIES = "network-repo";
+ const owner = process.env.INPUT_OWNER;
+ const repo = process.env.INPUT_REPOSITORIES;
+ const mockInstallationId = "123456";
+ const mockAppSlug = "github-actions";
+
+ mockPool
+ .intercept({
+ path: `/repos/${owner}/${repo}/installation`,
+ method: "GET",
+ headers: {
+ accept: "application/vnd.github.v3+json",
+ "user-agent": "actions/create-github-app-token",
+ // Intentionally omitting the `authorization` header, since JWT creation is not idempotent.
+ },
+ })
+ .replyWithError(new TypeError("fetch failed"));
+
+ mockPool
+ .intercept({
+ path: `/repos/${owner}/${repo}/installation`,
+ method: "GET",
+ headers: {
+ accept: "application/vnd.github.v3+json",
+ "user-agent": "actions/create-github-app-token",
+ // Intentionally omitting the `authorization` header, since JWT creation is not idempotent.
+ },
+ })
+ .reply(
+ 200,
+ { id: mockInstallationId, app_slug: mockAppSlug },
+ { headers: { "content-type": "application/json" } },
+ );
+});
From 8d835bfd37aa48fcb8e709925115857568d98bc4 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Fri, 8 May 2026 12:30:30 -0700
Subject: [PATCH 09/29] build(deps-dev): bump esbuild from 0.27.4 to 0.28.0 in
the development-dependencies group (#365)
Bumps the development-dependencies group with 1 update:
[esbuild](https://github.com/evanw/esbuild).
Updates `esbuild` from 0.27.4 to 0.28.0
Release notes
Sourced from esbuild's
releases.
v0.28.0
-
Add support for with { type: 'text' } imports (#4435)
The import
text proposal has reached stage 3 in the TC39 process, which means
that it's recommended for implementation. It has also already been
implemented by Deno and Bun. So with
this release, esbuild also adds support for it. This behaves exactly the
same as esbuild's existing text
loader. Here's an example:
import string from './example.txt' with { type:
'text' }
console.log(string)
-
Add integrity checks to fallback download path (#4343)
Installing esbuild via npm is somewhat complicated with several
different edge cases (see esbuild's
documentation for details). If the regular installation of esbuild's
platform-specific package fails, esbuild's install script attempts to
download the platform-specific package itself (first with the
npm command, and then with a HTTP request to
registry.npmjs.org as a last resort).
This last resort path previously didn't have any integrity checks.
With this release, esbuild will now verify that the hash of the
downloaded binary matches the expected hash for the current release.
This means the hashes for all of esbuild's platform-specific binary
packages will now be embedded in the top-level esbuild
package. Hopefully this should work without any problems. But just in
case, this change is being done as a breaking change release.
-
Update the Go compiler from 1.25.7 to 1.26.1
This upgrade should not affect anything. However, there have been
some significant internal changes to the Go compiler, so esbuild could
potentially behave differently in certain edge cases:
- It now uses the new garbage
collector that comes with Go 1.26.
- The Go compiler is now more aggressive with allocating memory on the
stack.
- The executable format that the Go linker uses has undergone several
changes.
- The WebAssembly build now unconditionally makes use of the sign
extension and non-trapping floating-point to integer conversion
instructions.
You can read the Go 1.26 release
notes for more information.
v0.27.7
-
Fix lowering of define semantics for TypeScript parameter properties
(#4421)
The previous release incorrectly generated class fields for
TypeScript parameter properties even when the configured target
environment does not support class fields. With this release, the
generated class fields will now be correctly lowered in this case:
// Original code
class Foo {
constructor(public x = 1) {}
y = 2
}
// Old output (with --loader=ts --target=es2021)
class Foo {
constructor(x = 1) {
this.x = x;
__publicField(this, "y", 2);
}
x;
}
// New output (with --loader=ts --target=es2021)
class Foo {
... (truncated)
Changelog
Sourced from esbuild's
changelog.
0.28.0
-
Add support for with { type: 'text' } imports (#4435)
The import
text proposal has reached stage 3 in the TC39 process, which means
that it's recommended for implementation. It has also already been
implemented by Deno and Bun. So with
this release, esbuild also adds support for it. This behaves exactly the
same as esbuild's existing text
loader. Here's an example:
import string from './example.txt' with { type:
'text' }
console.log(string)
-
Add integrity checks to fallback download path (#4343)
Installing esbuild via npm is somewhat complicated with several
different edge cases (see esbuild's
documentation for details). If the regular installation of esbuild's
platform-specific package fails, esbuild's install script attempts to
download the platform-specific package itself (first with the
npm command, and then with a HTTP request to
registry.npmjs.org as a last resort).
This last resort path previously didn't have any integrity checks.
With this release, esbuild will now verify that the hash of the
downloaded binary matches the expected hash for the current release.
This means the hashes for all of esbuild's platform-specific binary
packages will now be embedded in the top-level esbuild
package. Hopefully this should work without any problems. But just in
case, this change is being done as a breaking change release.
-
Update the Go compiler from 1.25.7 to 1.26.1
This upgrade should not affect anything. However, there have been
some significant internal changes to the Go compiler, so esbuild could
potentially behave differently in certain edge cases:
- It now uses the new garbage
collector that comes with Go 1.26.
- The Go compiler is now more aggressive with allocating memory on the
stack.
- The executable format that the Go linker uses has undergone several
changes.
- The WebAssembly build now unconditionally makes use of the sign
extension and non-trapping floating-point to integer conversion
instructions.
You can read the Go 1.26 release
notes for more information.
0.27.7
-
Fix lowering of define semantics for TypeScript parameter properties
(#4421)
The previous release incorrectly generated class fields for
TypeScript parameter properties even when the configured target
environment does not support class fields. With this release, the
generated class fields will now be correctly lowered in this case:
// Original code
class Foo {
constructor(public x = 1) {}
y = 2
}
// Old output (with --loader=ts --target=es2021)
class Foo {
constructor(x = 1) {
this.x = x;
__publicField(this, "y", 2);
}
x;
}
... (truncated)
Commits
6a794df
publish 0.28.0 to npm
64ee0ea
fix #4435:
support with { type: text } imports
ef65aee
fix sort order in snapshots_packagejson.txt
1a26a8e
try to fix test-old-ts, also shuffle CI tasks
556ce6c
use '' instead of null to omit build
hashes
8e675a8
ci: allow missing binary hashes for tests
7067763
Reapply "update go 1.25.7 => 1.26.1"
39473a9
fix #4343:
integrity check for binary download
2025c9f
publish 0.27.7 to npm
c6b586e
fix typo in Makefile for
@esbuild/win32-x64
- Additional commits viewable in compare
view
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore ` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore ` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore ` will
remove the ignore condition of the specified dependency and ignore
conditions
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
package-lock.json | 216 +++++++++++++++++++++++-----------------------
package.json | 2 +-
2 files changed, 109 insertions(+), 109 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index aa183a77..46e6b4b6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -18,7 +18,7 @@
"devDependencies": {
"@octokit/openapi": "^22.0.0",
"c8": "^11.0.0",
- "esbuild": "^0.27.4",
+ "esbuild": "^0.28.0",
"open-cli": "^9.0.0",
"undici": "^7.24.6",
"yaml": "^2.8.3"
@@ -92,9 +92,9 @@
}
},
"node_modules/@esbuild/aix-ppc64": {
- "version": "0.27.4",
- "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.4.tgz",
- "integrity": "sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.0.tgz",
+ "integrity": "sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==",
"cpu": [
"ppc64"
],
@@ -109,9 +109,9 @@
}
},
"node_modules/@esbuild/android-arm": {
- "version": "0.27.4",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.4.tgz",
- "integrity": "sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.0.tgz",
+ "integrity": "sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==",
"cpu": [
"arm"
],
@@ -126,9 +126,9 @@
}
},
"node_modules/@esbuild/android-arm64": {
- "version": "0.27.4",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.4.tgz",
- "integrity": "sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.0.tgz",
+ "integrity": "sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==",
"cpu": [
"arm64"
],
@@ -143,9 +143,9 @@
}
},
"node_modules/@esbuild/android-x64": {
- "version": "0.27.4",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.4.tgz",
- "integrity": "sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.0.tgz",
+ "integrity": "sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==",
"cpu": [
"x64"
],
@@ -160,9 +160,9 @@
}
},
"node_modules/@esbuild/darwin-arm64": {
- "version": "0.27.4",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.4.tgz",
- "integrity": "sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.0.tgz",
+ "integrity": "sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==",
"cpu": [
"arm64"
],
@@ -177,9 +177,9 @@
}
},
"node_modules/@esbuild/darwin-x64": {
- "version": "0.27.4",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.4.tgz",
- "integrity": "sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.0.tgz",
+ "integrity": "sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==",
"cpu": [
"x64"
],
@@ -194,9 +194,9 @@
}
},
"node_modules/@esbuild/freebsd-arm64": {
- "version": "0.27.4",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.4.tgz",
- "integrity": "sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.0.tgz",
+ "integrity": "sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==",
"cpu": [
"arm64"
],
@@ -211,9 +211,9 @@
}
},
"node_modules/@esbuild/freebsd-x64": {
- "version": "0.27.4",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.4.tgz",
- "integrity": "sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.0.tgz",
+ "integrity": "sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==",
"cpu": [
"x64"
],
@@ -228,9 +228,9 @@
}
},
"node_modules/@esbuild/linux-arm": {
- "version": "0.27.4",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.4.tgz",
- "integrity": "sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.0.tgz",
+ "integrity": "sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==",
"cpu": [
"arm"
],
@@ -245,9 +245,9 @@
}
},
"node_modules/@esbuild/linux-arm64": {
- "version": "0.27.4",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.4.tgz",
- "integrity": "sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.0.tgz",
+ "integrity": "sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==",
"cpu": [
"arm64"
],
@@ -262,9 +262,9 @@
}
},
"node_modules/@esbuild/linux-ia32": {
- "version": "0.27.4",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.4.tgz",
- "integrity": "sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.0.tgz",
+ "integrity": "sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==",
"cpu": [
"ia32"
],
@@ -279,9 +279,9 @@
}
},
"node_modules/@esbuild/linux-loong64": {
- "version": "0.27.4",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.4.tgz",
- "integrity": "sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.0.tgz",
+ "integrity": "sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==",
"cpu": [
"loong64"
],
@@ -296,9 +296,9 @@
}
},
"node_modules/@esbuild/linux-mips64el": {
- "version": "0.27.4",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.4.tgz",
- "integrity": "sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.0.tgz",
+ "integrity": "sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==",
"cpu": [
"mips64el"
],
@@ -313,9 +313,9 @@
}
},
"node_modules/@esbuild/linux-ppc64": {
- "version": "0.27.4",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.4.tgz",
- "integrity": "sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.0.tgz",
+ "integrity": "sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==",
"cpu": [
"ppc64"
],
@@ -330,9 +330,9 @@
}
},
"node_modules/@esbuild/linux-riscv64": {
- "version": "0.27.4",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.4.tgz",
- "integrity": "sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.0.tgz",
+ "integrity": "sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==",
"cpu": [
"riscv64"
],
@@ -347,9 +347,9 @@
}
},
"node_modules/@esbuild/linux-s390x": {
- "version": "0.27.4",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.4.tgz",
- "integrity": "sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.0.tgz",
+ "integrity": "sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==",
"cpu": [
"s390x"
],
@@ -364,9 +364,9 @@
}
},
"node_modules/@esbuild/linux-x64": {
- "version": "0.27.4",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.4.tgz",
- "integrity": "sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.0.tgz",
+ "integrity": "sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==",
"cpu": [
"x64"
],
@@ -381,9 +381,9 @@
}
},
"node_modules/@esbuild/netbsd-arm64": {
- "version": "0.27.4",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.4.tgz",
- "integrity": "sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.0.tgz",
+ "integrity": "sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==",
"cpu": [
"arm64"
],
@@ -398,9 +398,9 @@
}
},
"node_modules/@esbuild/netbsd-x64": {
- "version": "0.27.4",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.4.tgz",
- "integrity": "sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.0.tgz",
+ "integrity": "sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==",
"cpu": [
"x64"
],
@@ -415,9 +415,9 @@
}
},
"node_modules/@esbuild/openbsd-arm64": {
- "version": "0.27.4",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.4.tgz",
- "integrity": "sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.0.tgz",
+ "integrity": "sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==",
"cpu": [
"arm64"
],
@@ -432,9 +432,9 @@
}
},
"node_modules/@esbuild/openbsd-x64": {
- "version": "0.27.4",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.4.tgz",
- "integrity": "sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.0.tgz",
+ "integrity": "sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==",
"cpu": [
"x64"
],
@@ -449,9 +449,9 @@
}
},
"node_modules/@esbuild/openharmony-arm64": {
- "version": "0.27.4",
- "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.4.tgz",
- "integrity": "sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.0.tgz",
+ "integrity": "sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==",
"cpu": [
"arm64"
],
@@ -466,9 +466,9 @@
}
},
"node_modules/@esbuild/sunos-x64": {
- "version": "0.27.4",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.4.tgz",
- "integrity": "sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.0.tgz",
+ "integrity": "sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==",
"cpu": [
"x64"
],
@@ -483,9 +483,9 @@
}
},
"node_modules/@esbuild/win32-arm64": {
- "version": "0.27.4",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.4.tgz",
- "integrity": "sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.0.tgz",
+ "integrity": "sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==",
"cpu": [
"arm64"
],
@@ -500,9 +500,9 @@
}
},
"node_modules/@esbuild/win32-ia32": {
- "version": "0.27.4",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.4.tgz",
- "integrity": "sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.0.tgz",
+ "integrity": "sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==",
"cpu": [
"ia32"
],
@@ -517,9 +517,9 @@
}
},
"node_modules/@esbuild/win32-x64": {
- "version": "0.27.4",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.4.tgz",
- "integrity": "sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.0.tgz",
+ "integrity": "sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==",
"cpu": [
"x64"
],
@@ -1023,9 +1023,9 @@
}
},
"node_modules/esbuild": {
- "version": "0.27.4",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.4.tgz",
- "integrity": "sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.0.tgz",
+ "integrity": "sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
@@ -1036,32 +1036,32 @@
"node": ">=18"
},
"optionalDependencies": {
- "@esbuild/aix-ppc64": "0.27.4",
- "@esbuild/android-arm": "0.27.4",
- "@esbuild/android-arm64": "0.27.4",
- "@esbuild/android-x64": "0.27.4",
- "@esbuild/darwin-arm64": "0.27.4",
- "@esbuild/darwin-x64": "0.27.4",
- "@esbuild/freebsd-arm64": "0.27.4",
- "@esbuild/freebsd-x64": "0.27.4",
- "@esbuild/linux-arm": "0.27.4",
- "@esbuild/linux-arm64": "0.27.4",
- "@esbuild/linux-ia32": "0.27.4",
- "@esbuild/linux-loong64": "0.27.4",
- "@esbuild/linux-mips64el": "0.27.4",
- "@esbuild/linux-ppc64": "0.27.4",
- "@esbuild/linux-riscv64": "0.27.4",
- "@esbuild/linux-s390x": "0.27.4",
- "@esbuild/linux-x64": "0.27.4",
- "@esbuild/netbsd-arm64": "0.27.4",
- "@esbuild/netbsd-x64": "0.27.4",
- "@esbuild/openbsd-arm64": "0.27.4",
- "@esbuild/openbsd-x64": "0.27.4",
- "@esbuild/openharmony-arm64": "0.27.4",
- "@esbuild/sunos-x64": "0.27.4",
- "@esbuild/win32-arm64": "0.27.4",
- "@esbuild/win32-ia32": "0.27.4",
- "@esbuild/win32-x64": "0.27.4"
+ "@esbuild/aix-ppc64": "0.28.0",
+ "@esbuild/android-arm": "0.28.0",
+ "@esbuild/android-arm64": "0.28.0",
+ "@esbuild/android-x64": "0.28.0",
+ "@esbuild/darwin-arm64": "0.28.0",
+ "@esbuild/darwin-x64": "0.28.0",
+ "@esbuild/freebsd-arm64": "0.28.0",
+ "@esbuild/freebsd-x64": "0.28.0",
+ "@esbuild/linux-arm": "0.28.0",
+ "@esbuild/linux-arm64": "0.28.0",
+ "@esbuild/linux-ia32": "0.28.0",
+ "@esbuild/linux-loong64": "0.28.0",
+ "@esbuild/linux-mips64el": "0.28.0",
+ "@esbuild/linux-ppc64": "0.28.0",
+ "@esbuild/linux-riscv64": "0.28.0",
+ "@esbuild/linux-s390x": "0.28.0",
+ "@esbuild/linux-x64": "0.28.0",
+ "@esbuild/netbsd-arm64": "0.28.0",
+ "@esbuild/netbsd-x64": "0.28.0",
+ "@esbuild/openbsd-arm64": "0.28.0",
+ "@esbuild/openbsd-x64": "0.28.0",
+ "@esbuild/openharmony-arm64": "0.28.0",
+ "@esbuild/sunos-x64": "0.28.0",
+ "@esbuild/win32-arm64": "0.28.0",
+ "@esbuild/win32-ia32": "0.28.0",
+ "@esbuild/win32-x64": "0.28.0"
}
},
"node_modules/escalade": {
diff --git a/package.json b/package.json
index 60bceff9..e3d31548 100644
--- a/package.json
+++ b/package.json
@@ -25,7 +25,7 @@
"devDependencies": {
"@octokit/openapi": "^22.0.0",
"c8": "^11.0.0",
- "esbuild": "^0.27.4",
+ "esbuild": "^0.28.0",
"open-cli": "^9.0.0",
"undici": "^7.24.6",
"yaml": "^2.8.3"
From e02e816e5591415258a53bf735aff57977dcd5e2 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Fri, 8 May 2026 14:40:33 -0700
Subject: [PATCH 10/29] build(deps-dev): bump undici from 7.24.6 to 8.2.0
(#366)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Bumps [undici](https://github.com/nodejs/undici) from 7.24.6 to 8.2.0.
Release notes
Sourced from undici's
releases.
v8.2.0
What's Changed
... (truncated)
Commits
bf684f7
Bumped v8.2.0 (#5152)
0ca054a
fix: replace stale pool clients under connection limit (#5145)
7af90e9
perf: avoid redundant scans in BalancedPool dispatcher selection (#5146)
abb9d06
fix: validate H2CClient maxConcurrentStreams option (#5143)
72a7591
perf(http2): avoid cloning headers when removing status (#5127)
96fd5e9
fix(cache): allow streamed entries at maxEntrySize limit (#5129)
f41e53f
perf: use byteLength property for binary body chunks (#5126)
bec4961
chore(deps): add lockfile (#5139)
86f1242
perf(http2): reduce writeH2 per-request callback allocations (#5138)
cad3f70
perf(client): parse h1 content-length statelessly (#5124)
- Additional commits viewable in compare
view
---------
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Parker Brown <17183625+parkerbxyz@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
package-lock.json | 10 +++++-----
package.json | 2 +-
tests/index.js | 8 +++++++-
tests/main.js | 6 ++----
tests/mock-agent.js | 12 ++++++++++++
tests/post-revoke-token-fail-response.test.js | 6 ++----
tests/post-token-expired.test.js | 6 ++----
tests/post-token-set.test.js | 6 ++----
tests/post-token-skipped.test.js | 6 ++----
9 files changed, 35 insertions(+), 27 deletions(-)
create mode 100644 tests/mock-agent.js
diff --git a/package-lock.json b/package-lock.json
index 46e6b4b6..fca2c7ee 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -20,7 +20,7 @@
"c8": "^11.0.0",
"esbuild": "^0.28.0",
"open-cli": "^9.0.0",
- "undici": "^7.24.6",
+ "undici": "^8.2.0",
"yaml": "^2.8.3"
},
"engines": {
@@ -1786,13 +1786,13 @@
}
},
"node_modules/undici": {
- "version": "7.24.6",
- "resolved": "https://registry.npmjs.org/undici/-/undici-7.24.6.tgz",
- "integrity": "sha512-Xi4agocCbRzt0yYMZGMA6ApD7gvtUFaxm4ZmeacWI4cZxaF6C+8I8QfofC20NAePiB/IcvZmzkJ7XPa471AEtA==",
+ "version": "8.2.0",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-8.2.0.tgz",
+ "integrity": "sha512-Z+4Hx9GE26Lh9Upwfnc8C7SsrpBPGaM/Gm6kMFtiG7c+5IvQKlXi/t+9x9DrrCh29cww5TSP9YdVaBcnLDs5fQ==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">=20.18.1"
+ "node": ">=22.19.0"
}
},
"node_modules/unique-string": {
diff --git a/package.json b/package.json
index e3d31548..c616cfe4 100644
--- a/package.json
+++ b/package.json
@@ -27,7 +27,7 @@
"c8": "^11.0.0",
"esbuild": "^0.28.0",
"open-cli": "^9.0.0",
- "undici": "^7.24.6",
+ "undici": "^8.2.0",
"yaml": "^2.8.3"
}
}
diff --git a/tests/index.js b/tests/index.js
index 74cf2723..159c21c7 100644
--- a/tests/index.js
+++ b/tests/index.js
@@ -22,7 +22,13 @@ function normalizeStderr(stderr) {
const files = readdirSync("tests");
// Files to ignore
-const ignore = ["index.js", "index.js.snapshot", "main.js", "README.md"];
+const ignore = [
+ "index.js",
+ "index.js.snapshot",
+ "main.js",
+ "mock-agent.js",
+ "README.md",
+];
const testFiles = files.filter((file) => !ignore.includes(file)).sort();
diff --git a/tests/main.js b/tests/main.js
index a76c39a4..1edc6433 100644
--- a/tests/main.js
+++ b/tests/main.js
@@ -1,6 +1,6 @@
// Base for all `main` tests.
// @ts-check
-import { MockAgent, setGlobalDispatcher } from "undici";
+import { createMockAgent } from "./mock-agent.js";
export const DEFAULT_ENV = {
GITHUB_REPOSITORY_OWNER: "actions",
@@ -50,9 +50,7 @@ export async function test(cb = (_mockPool) => {}, env = DEFAULT_ENV) {
// Set up mocking
const baseUrl = new URL(env["INPUT_GITHUB-API-URL"]);
const basePath = baseUrl.pathname === "/" ? "" : baseUrl.pathname;
- const mockAgent = new MockAgent({ enableCallHistory: true });
- mockAgent.disableNetConnect();
- setGlobalDispatcher(mockAgent);
+ const mockAgent = createMockAgent({ enableCallHistory: true });
const mockPool = mockAgent.get(baseUrl.origin);
// Calling `auth({ type: "app" })` to obtain a JWT doesn’t make network requests, so no need to intercept.
diff --git a/tests/mock-agent.js b/tests/mock-agent.js
new file mode 100644
index 00000000..fb93d502
--- /dev/null
+++ b/tests/mock-agent.js
@@ -0,0 +1,12 @@
+import { install, MockAgent, setGlobalDispatcher } from "undici";
+
+// Ensure MockAgent intercepts requests made through global fetch.
+install();
+
+export function createMockAgent(options) {
+ const mockAgent = new MockAgent(options);
+ mockAgent.disableNetConnect();
+ setGlobalDispatcher(mockAgent);
+
+ return mockAgent;
+}
diff --git a/tests/post-revoke-token-fail-response.test.js b/tests/post-revoke-token-fail-response.test.js
index b729b556..6318182d 100644
--- a/tests/post-revoke-token-fail-response.test.js
+++ b/tests/post-revoke-token-fail-response.test.js
@@ -1,4 +1,4 @@
-import { MockAgent, setGlobalDispatcher } from "undici";
+import { createMockAgent } from "./mock-agent.js";
// state variables are set as environment variables with the prefix STATE_
// https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#sending-values-to-the-pre-and-post-actions
@@ -14,9 +14,7 @@ process.env.STATE_expiresAt = new Date(
Date.now() + 1000 * 60 * 60
).toISOString();
-const mockAgent = new MockAgent();
-
-setGlobalDispatcher(mockAgent);
+const mockAgent = createMockAgent();
// Provide the base url to the request
const mockPool = mockAgent.get("https://api.github.com");
diff --git a/tests/post-token-expired.test.js b/tests/post-token-expired.test.js
index 62caa6d8..beae3f2e 100644
--- a/tests/post-token-expired.test.js
+++ b/tests/post-token-expired.test.js
@@ -1,4 +1,4 @@
-import { MockAgent, setGlobalDispatcher } from "undici";
+import { createMockAgent } from "./mock-agent.js";
// state variables are set as environment variables with the prefix STATE_
// https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#sending-values-to-the-pre-and-post-actions
@@ -11,9 +11,7 @@ process.env.STATE_expiresAt = new Date(Date.now() - 1000 * 60 * 60).toISOString(
// https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions#example-specifying-inputs
process.env["INPUT_SKIP-TOKEN-REVOKE"] = "false";
-const mockAgent = new MockAgent();
-
-setGlobalDispatcher(mockAgent);
+const mockAgent = createMockAgent();
// Provide the base url to the request
const mockPool = mockAgent.get("https://api.github.com");
diff --git a/tests/post-token-set.test.js b/tests/post-token-set.test.js
index 8ae8c361..c90b4377 100644
--- a/tests/post-token-set.test.js
+++ b/tests/post-token-set.test.js
@@ -1,4 +1,4 @@
-import { MockAgent, setGlobalDispatcher } from "undici";
+import { createMockAgent } from "./mock-agent.js";
// state variables are set as environment variables with the prefix STATE_
// https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#sending-values-to-the-pre-and-post-actions
@@ -12,9 +12,7 @@ process.env["INPUT_SKIP-TOKEN-REVOKE"] = "false";
// 1 hour in the future, not expired
process.env.STATE_expiresAt = new Date(Date.now() + 1000 * 60 * 60).toISOString();
-const mockAgent = new MockAgent();
-
-setGlobalDispatcher(mockAgent);
+const mockAgent = createMockAgent();
// Provide the base url to the request
const mockPool = mockAgent.get("https://api.github.com");
diff --git a/tests/post-token-skipped.test.js b/tests/post-token-skipped.test.js
index f7560522..7c40d5b9 100644
--- a/tests/post-token-skipped.test.js
+++ b/tests/post-token-skipped.test.js
@@ -1,4 +1,4 @@
-import { MockAgent, setGlobalDispatcher } from "undici";
+import { createMockAgent } from "./mock-agent.js";
// state variables are set as environment variables with the prefix STATE_
// https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#sending-values-to-the-pre-and-post-actions
@@ -8,9 +8,7 @@ process.env.STATE_token = "secret123";
// https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions#example-specifying-inputs
process.env["INPUT_SKIP-TOKEN-REVOKE"] = "true";
-const mockAgent = new MockAgent();
-
-setGlobalDispatcher(mockAgent);
+const mockAgent = createMockAgent();
// Provide the base url to the request
const mockPool = mockAgent.get("https://api.github.com");
From c9aabb83728c3bd519212fa657ebc07e1f2a5dec Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Fri, 8 May 2026 14:51:43 -0700
Subject: [PATCH 11/29] build(deps-dev): bump yaml from 2.8.3 to 2.8.4 in the
development-dependencies group (#371)
Bumps the development-dependencies group with 1 update:
[yaml](https://github.com/eemeli/yaml).
Updates `yaml` from 2.8.3 to 2.8.4
Release notes
Sourced from yaml's
releases.
v2.8.4
- Disable alias resolution with
maxAliasCount:0 (#677)
- Handle invalid unicode escapes (e1a1a77)
- Apply
minFractionDigits only to decimal strings (#676)
Commits
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore ` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore ` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore ` will
remove the ignore condition of the specified dependency and ignore
conditions
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
package-lock.json | 8 ++++----
package.json | 2 +-
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index fca2c7ee..0ae4bcb0 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -21,7 +21,7 @@
"esbuild": "^0.28.0",
"open-cli": "^9.0.0",
"undici": "^8.2.0",
- "yaml": "^2.8.3"
+ "yaml": "^2.8.4"
},
"engines": {
"node": ">=24.4.0"
@@ -1966,9 +1966,9 @@
"dev": true
},
"node_modules/yaml": {
- "version": "2.8.3",
- "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.3.tgz",
- "integrity": "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==",
+ "version": "2.8.4",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.4.tgz",
+ "integrity": "sha512-ml/JPOj9fOQK8RNnWojA67GbZ0ApXAUlN2UQclwv2eVgTgn7O9gg9o7paZWKMp4g0H3nTLtS9LVzhkpOFIKzog==",
"dev": true,
"license": "ISC",
"bin": {
diff --git a/package.json b/package.json
index c616cfe4..0fd488c5 100644
--- a/package.json
+++ b/package.json
@@ -28,6 +28,6 @@
"esbuild": "^0.28.0",
"open-cli": "^9.0.0",
"undici": "^8.2.0",
- "yaml": "^2.8.3"
+ "yaml": "^2.8.4"
}
}
From 85eb8dd41472213aed25d1a126460e0069138ab6 Mon Sep 17 00:00:00 2001
From: Parker Brown <17183625+parkerbxyz@users.noreply.github.com>
Date: Mon, 11 May 2026 12:10:57 -0700
Subject: [PATCH 12/29] feat: support full repository names in `repositories`
input (#372)
The `repositories` input currently treats values like `${{
github.repository }}` as a repository name, which can produce a
duplicated owner in the installation lookup. This changes repository
target resolution so entries may be bare repository names or full
`owner/repository` names, while preserving the existing resolved owner
behavior.
Full repository names are accepted only when their owner matches the
`owner` input, or the current repository owner when `owner` is unset.
The action still creates a single installation token for one owner, and
generated `dist` artifacts are left unchanged for release.
Fixes: #177
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
README.md | 8 ++
action.yml | 2 +-
lib/main.js | 50 ++++++++-
tests/index.js.snapshot | 106 ++++++++++++++++++
...token-get-owner-set-repo-full-name.test.js | 8 ++
...-get-owner-set-repo-invalid-format.test.js | 13 +++
...ner-set-repo-non-current-full-name.test.js | 12 ++
...-get-owner-set-repo-owner-mismatch.test.js | 13 +++
...wner-unset-repo-full-name-and-bare.test.js | 8 ++
...et-owner-unset-repo-owner-mismatch.test.js | 13 +++
tests/main.js | 7 +-
11 files changed, 232 insertions(+), 8 deletions(-)
create mode 100644 tests/main-token-get-owner-set-repo-full-name.test.js
create mode 100644 tests/main-token-get-owner-set-repo-invalid-format.test.js
create mode 100644 tests/main-token-get-owner-set-repo-non-current-full-name.test.js
create mode 100644 tests/main-token-get-owner-set-repo-owner-mismatch.test.js
create mode 100644 tests/main-token-get-owner-unset-repo-full-name-and-bare.test.js
create mode 100644 tests/main-token-get-owner-unset-repo-owner-mismatch.test.js
diff --git a/README.md b/README.md
index 43257164..849dc84e 100644
--- a/README.md
+++ b/README.md
@@ -173,6 +173,12 @@ jobs:
body: "Hello, World!"
```
+You can include the current repository in the list with `${{ github.repository }}`:
+
+```yaml
+repositories: ${{ github.repository }},repo2
+```
+
### Create a token for all repositories in another owner's installation
```yaml
@@ -377,6 +383,8 @@ steps:
> [!NOTE]
> If `owner` is set and `repositories` is empty, access will be scoped to all repositories in the provided repository owner's installation. If `owner` and `repositories` are empty, access will be scoped to only the current repository.
+>
+> Repository entries may include an owner, for example `owner/repo1`. The owner portion must match the `owner` input, or the current repository owner if `owner` is unset.
### `enterprise`
diff --git a/action.yml b/action.yml
index a4e11487..9f45ab3e 100644
--- a/action.yml
+++ b/action.yml
@@ -19,7 +19,7 @@ inputs:
description: "The owner of the GitHub App installation (defaults to current repository owner)"
required: false
repositories:
- description: "Comma or newline-separated list of repositories to install the GitHub App on (defaults to current repository if owner is unset)"
+ description: "Comma or newline-separated list of repositories to grant the token access to (defaults to current repository if owner is unset)"
required: false
enterprise:
description: "The slug of the enterprise account where the GitHub App is installed (cannot be used with 'owner' or 'repositories')"
diff --git a/lib/main.js b/lib/main.js
index 8fe0942a..7108c3e5 100644
--- a/lib/main.js
+++ b/lib/main.js
@@ -86,29 +86,67 @@ function resolveInstallationTarget(enterprise, owner, repositories, core) {
return { type: "owner", owner };
}
- const parsedOwner = owner || String(process.env.GITHUB_REPOSITORY_OWNER);
+ const target = normalizeRepositoryTarget(owner, repositories);
if (!owner) {
core.info(
- `No 'owner' input provided. Using default owner '${parsedOwner}' to create token for the following repositories:${repositories
- .map((repo) => `\n- ${parsedOwner}/${repo}`)
+ `No 'owner' input provided. Using default owner '${target.owner}' to create token for the following repositories:${target.repositories
+ .map((repo) => `\n- ${target.owner}/${repo}`)
.join("")}`
);
} else {
core.info(
- `Inputs 'owner' and 'repositories' are set. Creating token for the following repositories:${repositories
- .map((repo) => `\n- ${parsedOwner}/${repo}`)
+ `Inputs 'owner' and 'repositories' are set. Creating token for the following repositories:${target.repositories
+ .map((repo) => `\n- ${target.owner}/${repo}`)
.join("")}`
);
}
return {
type: "repository",
+ owner: target.owner,
+ repositories: target.repositories,
+ };
+}
+
+function normalizeRepositoryTarget(owner, repositories) {
+ const parsedOwner = owner || String(process.env.GITHUB_REPOSITORY_OWNER);
+ const parsedRepositories = repositories.map(parseRepositoryInput);
+
+ const mismatchedRepository = parsedRepositories.find(
+ (repository) =>
+ repository.owner &&
+ repository.owner.toLowerCase() !== parsedOwner.toLowerCase()
+ );
+
+ if (mismatchedRepository) {
+ throw new Error(
+ `Repository '${mismatchedRepository.input}' includes owner '${mismatchedRepository.owner}', which does not match the resolved owner '${parsedOwner}'.`
+ );
+ }
+
+ return {
owner: parsedOwner,
- repositories,
+ repositories: parsedRepositories.map((repository) => repository.name),
};
}
+function parseRepositoryInput(input) {
+ const parts = input.split("/");
+
+ if (parts.length === 1 && parts[0]) {
+ return { input, owner: "", name: parts[0] };
+ }
+
+ if (parts.length === 2 && parts[0] && parts[1]) {
+ return { input, owner: parts[0], name: parts[1] };
+ }
+
+ throw new Error(
+ `Invalid repository '${input}'. Expected 'repository' or 'owner/repository'.`
+ );
+}
+
function getTokenRetryDescription(target) {
switch (target.type) {
case "enterprise":
diff --git a/tests/index.js.snapshot b/tests/index.js.snapshot
index a77b6fa1..10372182 100644
--- a/tests/index.js.snapshot
+++ b/tests/index.js.snapshot
@@ -296,6 +296,42 @@ POST /app/installations/123456/access_tokens
{"repositories":["failed-repo"]}
`;
+exports[`main-token-get-owner-set-repo-full-name.test.js > stdout 1`] = `
+Inputs 'owner' and 'repositories' are set. Creating token for the following repositories:
+- actions/create-github-app-token
+::add-mask::ghs_16C7e42F292c6912E7710c838347Ae178B4a
+
+::set-output name=token::ghs_16C7e42F292c6912E7710c838347Ae178B4a
+
+::set-output name=installation-id::123456
+
+::set-output name=app-slug::github-actions
+::save-state name=token::ghs_16C7e42F292c6912E7710c838347Ae178B4a
+::save-state name=expiresAt::2016-07-11T22:14:10Z
+--- REQUESTS ---
+GET /repos/actions/create-github-app-token/installation
+POST /app/installations/123456/access_tokens
+{"repositories":["create-github-app-token"]}
+`;
+
+exports[`main-token-get-owner-set-repo-invalid-format.test.js > stderr 1`] = `
+Error: Invalid repository 'octocat/hello-world/extra'. Expected 'repository' or 'owner/repository'.
+ at parseRepositoryInput (file:///lib/main.js::)
+ at Array.map ()
+ at normalizeRepositoryTarget (file:///lib/main.js::)
+ at resolveInstallationTarget (file:///lib/main.js::)
+ at main (file:///lib/main.js::)
+ at run (file:///main.js::)
+ at file:///main.js::
+ at ModuleJob.run (node:internal/modules/esm/module_job::)
+ at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader::)
+ at async file:///tests/main-token-get-owner-set-repo-invalid-format.test.js::
+`;
+
+exports[`main-token-get-owner-set-repo-invalid-format.test.js > stdout 1`] = `
+::error::Invalid repository 'octocat/hello-world/extra'. Expected 'repository' or 'owner/repository'.
+`;
+
exports[`main-token-get-owner-set-repo-network-error.test.js > stdout 1`] = `
Inputs 'owner' and 'repositories' are set. Creating token for the following repositories:
- actions/network-repo
@@ -316,6 +352,41 @@ POST /app/installations/123456/access_tokens
{"repositories":["network-repo"]}
`;
+exports[`main-token-get-owner-set-repo-non-current-full-name.test.js > stdout 1`] = `
+Inputs 'owner' and 'repositories' are set. Creating token for the following repositories:
+- actions/toolkit
+- actions/checkout
+::add-mask::ghs_16C7e42F292c6912E7710c838347Ae178B4a
+
+::set-output name=token::ghs_16C7e42F292c6912E7710c838347Ae178B4a
+
+::set-output name=installation-id::123456
+
+::set-output name=app-slug::github-actions
+::save-state name=token::ghs_16C7e42F292c6912E7710c838347Ae178B4a
+::save-state name=expiresAt::2016-07-11T22:14:10Z
+--- REQUESTS ---
+GET /repos/actions/toolkit/installation
+POST /app/installations/123456/access_tokens
+{"repositories":["toolkit","checkout"]}
+`;
+
+exports[`main-token-get-owner-set-repo-owner-mismatch.test.js > stderr 1`] = `
+Error: Repository 'octocat/hello-world' includes owner 'octocat', which does not match the resolved owner 'actions'.
+ at normalizeRepositoryTarget (file:///lib/main.js::)
+ at resolveInstallationTarget (file:///lib/main.js::)
+ at main (file:///lib/main.js::)
+ at run (file:///main.js::)
+ at file:///main.js::
+ at ModuleJob.run (node:internal/modules/esm/module_job::)
+ at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader::)
+ at async file:///tests/main-token-get-owner-set-repo-owner-mismatch.test.js::
+`;
+
+exports[`main-token-get-owner-set-repo-owner-mismatch.test.js > stdout 1`] = `
+::error::Repository 'octocat/hello-world' includes owner 'octocat', which does not match the resolved owner 'actions'.
+`;
+
exports[`main-token-get-owner-set-repo-set-to-many-newline.test.js > stdout 1`] = `
Inputs 'owner' and 'repositories' are set. Creating token for the following repositories:
- actions/create-github-app-token
@@ -391,6 +462,41 @@ POST /app/installations/123456/access_tokens
null
`;
+exports[`main-token-get-owner-unset-repo-full-name-and-bare.test.js > stdout 1`] = `
+No 'owner' input provided. Using default owner 'actions' to create token for the following repositories:
+- actions/create-github-app-token
+- actions/toolkit
+::add-mask::ghs_16C7e42F292c6912E7710c838347Ae178B4a
+
+::set-output name=token::ghs_16C7e42F292c6912E7710c838347Ae178B4a
+
+::set-output name=installation-id::123456
+
+::set-output name=app-slug::github-actions
+::save-state name=token::ghs_16C7e42F292c6912E7710c838347Ae178B4a
+::save-state name=expiresAt::2016-07-11T22:14:10Z
+--- REQUESTS ---
+GET /repos/actions/create-github-app-token/installation
+POST /app/installations/123456/access_tokens
+{"repositories":["create-github-app-token","toolkit"]}
+`;
+
+exports[`main-token-get-owner-unset-repo-owner-mismatch.test.js > stderr 1`] = `
+Error: Repository 'octocat/hello-world' includes owner 'octocat', which does not match the resolved owner 'actions'.
+ at normalizeRepositoryTarget (file:///lib/main.js::)
+ at resolveInstallationTarget (file:///lib/main.js::)
+ at main (file:///lib/main.js::)
+ at run (file:///main.js::)
+ at file:///main.js::
+ at ModuleJob.run (node:internal/modules/esm/module_job::)
+ at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader::)
+ at async file:///tests/main-token-get-owner-unset-repo-owner-mismatch.test.js::
+`;
+
+exports[`main-token-get-owner-unset-repo-owner-mismatch.test.js > stdout 1`] = `
+::error::Repository 'octocat/hello-world' includes owner 'octocat', which does not match the resolved owner 'actions'.
+`;
+
exports[`main-token-get-owner-unset-repo-set.test.js > stdout 1`] = `
No 'owner' input provided. Using default owner 'actions' to create token for the following repositories:
- actions/create-github-app-token
diff --git a/tests/main-token-get-owner-set-repo-full-name.test.js b/tests/main-token-get-owner-set-repo-full-name.test.js
new file mode 100644
index 00000000..856a910b
--- /dev/null
+++ b/tests/main-token-get-owner-set-repo-full-name.test.js
@@ -0,0 +1,8 @@
+import { test } from "./main.js";
+
+// Verify `main` successfully obtains a token when the `owner` and `repositories` inputs are set, and `repositories` contains a full repository name.
+await test(() => {
+ process.env.INPUT_OWNER = process.env.GITHUB_REPOSITORY_OWNER;
+ process.env.INPUT_REPOSITORIES = process.env.GITHUB_REPOSITORY;
+});
+
diff --git a/tests/main-token-get-owner-set-repo-invalid-format.test.js b/tests/main-token-get-owner-set-repo-invalid-format.test.js
new file mode 100644
index 00000000..78014eda
--- /dev/null
+++ b/tests/main-token-get-owner-set-repo-invalid-format.test.js
@@ -0,0 +1,13 @@
+import { DEFAULT_ENV } from "./main.js";
+
+// Verify `main` exits with an error when a repository entry is neither a repository name nor an owner/repository name.
+for (const [key, value] of Object.entries(DEFAULT_ENV)) {
+ process.env[key] = value;
+}
+
+process.env.INPUT_OWNER = process.env.GITHUB_REPOSITORY_OWNER;
+process.env.INPUT_REPOSITORIES = "octocat/hello-world/extra";
+
+const { default: promise } = await import("../main.js");
+await promise;
+
diff --git a/tests/main-token-get-owner-set-repo-non-current-full-name.test.js b/tests/main-token-get-owner-set-repo-non-current-full-name.test.js
new file mode 100644
index 00000000..d73c3472
--- /dev/null
+++ b/tests/main-token-get-owner-set-repo-non-current-full-name.test.js
@@ -0,0 +1,12 @@
+import { DEFAULT_ENV, test } from "./main.js";
+
+// Verify `main` normalizes full repository names before installation lookup and token scoping.
+await test(
+ () => {},
+ {
+ ...DEFAULT_ENV,
+ INPUT_OWNER: DEFAULT_ENV.GITHUB_REPOSITORY_OWNER,
+ INPUT_REPOSITORIES: `${DEFAULT_ENV.GITHUB_REPOSITORY_OWNER}/toolkit,checkout`,
+ },
+);
+
diff --git a/tests/main-token-get-owner-set-repo-owner-mismatch.test.js b/tests/main-token-get-owner-set-repo-owner-mismatch.test.js
new file mode 100644
index 00000000..2a7897b6
--- /dev/null
+++ b/tests/main-token-get-owner-set-repo-owner-mismatch.test.js
@@ -0,0 +1,13 @@
+import { DEFAULT_ENV } from "./main.js";
+
+// Verify `main` exits with an error when a full repository name does not match the `owner` input.
+for (const [key, value] of Object.entries(DEFAULT_ENV)) {
+ process.env[key] = value;
+}
+
+process.env.INPUT_OWNER = process.env.GITHUB_REPOSITORY_OWNER;
+process.env.INPUT_REPOSITORIES = "octocat/hello-world";
+
+const { default: promise } = await import("../main.js");
+await promise;
+
diff --git a/tests/main-token-get-owner-unset-repo-full-name-and-bare.test.js b/tests/main-token-get-owner-unset-repo-full-name-and-bare.test.js
new file mode 100644
index 00000000..5fff1689
--- /dev/null
+++ b/tests/main-token-get-owner-unset-repo-full-name-and-bare.test.js
@@ -0,0 +1,8 @@
+import { test } from "./main.js";
+
+// Verify `main` successfully obtains a token when `owner` is omitted and `repositories` mixes a full repository name with bare repository names.
+await test(() => {
+ delete process.env.INPUT_OWNER;
+ process.env.INPUT_REPOSITORIES = `${process.env.GITHUB_REPOSITORY},toolkit`;
+});
+
diff --git a/tests/main-token-get-owner-unset-repo-owner-mismatch.test.js b/tests/main-token-get-owner-unset-repo-owner-mismatch.test.js
new file mode 100644
index 00000000..b7ba367a
--- /dev/null
+++ b/tests/main-token-get-owner-unset-repo-owner-mismatch.test.js
@@ -0,0 +1,13 @@
+import { DEFAULT_ENV } from "./main.js";
+
+// Verify `main` exits with an error when a full repository name does not match the default owner.
+for (const [key, value] of Object.entries(DEFAULT_ENV)) {
+ process.env[key] = value;
+}
+
+delete process.env.INPUT_OWNER;
+process.env.INPUT_REPOSITORIES = "octocat/hello-world";
+
+const { default: promise } = await import("../main.js");
+await promise;
+
diff --git a/tests/main.js b/tests/main.js
index 1edc6433..3874dbc6 100644
--- a/tests/main.js
+++ b/tests/main.js
@@ -60,8 +60,13 @@ export async function test(cb = (_mockPool) => {}, env = DEFAULT_ENV) {
const mockAppSlug = "github-actions";
const owner = env.INPUT_OWNER ?? env.GITHUB_REPOSITORY_OWNER;
const currentRepoName = env.GITHUB_REPOSITORY.split("/")[1];
+ const firstRepositoryInput =
+ (env.INPUT_REPOSITORIES ?? currentRepoName)
+ .split(/[\n,]+/)
+ .map((repository) => repository.trim())
+ .find(Boolean) ?? currentRepoName;
const repo = encodeURIComponent(
- (env.INPUT_REPOSITORIES ?? currentRepoName).split(",")[0]
+ firstRepositoryInput.split("/").pop() || firstRepositoryInput
);
mockPool
From fd2801133e469d2950f2c5af5e591d6b2ad833c8 Mon Sep 17 00:00:00 2001
From: "Yamamoto, Hirotaka"
Date: Tue, 12 May 2026 12:09:36 +0900
Subject: [PATCH 13/29] docs: update procedure to configure Git (#287)
The current procedure for configuring `git` does not allow it to push
commits
besides the current repository, even if the app token may have access to
other
repositories. It also does not allow `git` to clone such a repository.
This new procedure configures `gh` first and then calls `gh auth
setup-git`
to configure `git` so it will work for any repository that the token has
access to.
---
README.md | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 849dc84e..5882413c 100644
--- a/README.md
+++ b/README.md
@@ -104,6 +104,7 @@ jobs:
# required
client-id: ${{ vars.APP_CLIENT_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
+ permission-contents: write
- name: Get GitHub App User ID
id: get-user-id
run: echo "user-id=$(gh api "/users/${{ steps.app-token.outputs.app-slug }}[bot]" --jq .id)" >> "$GITHUB_OUTPUT"
@@ -112,7 +113,10 @@ jobs:
- run: |
git config --global user.name '${{ steps.app-token.outputs.app-slug }}[bot]'
git config --global user.email '${{ steps.get-user-id.outputs.user-id }}+${{ steps.app-token.outputs.app-slug }}[bot]@users.noreply.github.com'
- # git commands like commit work using the bot user
+ gh auth setup-git
+ env:
+ GH_TOKEN: ${{ steps.app-token.outputs.token }}
+ # git commands like commit and push work using the bot user
- run: |
git add .
git commit -m "Auto-generated changes"
From 363531b6d972a60a00b3f1e6bb139e5e6c764cd9 Mon Sep 17 00:00:00 2001
From: Parker Brown <17183625+parkerbxyz@users.noreply.github.com>
Date: Mon, 11 May 2026 20:21:09 -0700
Subject: [PATCH 14/29] docs: capitalize Git as a proper noun in README (#374)
Capitalizes "Git" in three README locations where it refers to the
version control system as a proper noun; lowercase `git` command
invocations are unchanged.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
README.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/README.md b/README.md
index 5882413c..00ca19dd 100644
--- a/README.md
+++ b/README.md
@@ -64,7 +64,7 @@ jobs:
github_token: ${{ steps.app-token.outputs.token }}
```
-### Create a git committer string for an app installation
+### Create a Git committer string for an app installation
```yaml
on: [pull_request]
@@ -89,7 +89,7 @@ jobs:
- run: echo "committer string is ${{ steps.committer.outputs.string }}"
```
-### Configure git CLI for an app's bot user
+### Configure Git CLI for an app's bot user
```yaml
on: [pull_request]
@@ -116,7 +116,7 @@ jobs:
gh auth setup-git
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
- # git commands like commit and push work using the bot user
+ # Git commands like commit and push work using the bot user
- run: |
git add .
git commit -m "Auto-generated changes"
From f24bbd89643991c0de27ae823c01791b2c6bafdd Mon Sep 17 00:00:00 2001
From: Parker Brown <17183625+parkerbxyz@users.noreply.github.com>
Date: Tue, 12 May 2026 16:05:46 -0700
Subject: [PATCH 15/29] fix: validate private-key input (#376)
## Summary
When `private-key` resolves to an empty value, the action currently lets
Octokit fail with `[@octokit/auth-app] privateKey option is required`,
which points at an implementation detail instead of the action input.
This adds action-level validation so users get the same non-empty input
guidance used for missing `client-id` or `app-id`.
- Validate `private-key` before creating app auth
- Add a regression test and snapshot for the missing private key path
- Leave valid private key handling unchanged, including escaped newlines
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
main.js | 3 +++
tests/index.js.snapshot | 8 ++++++++
tests/main-missing-private-key.test.js | 19 +++++++++++++++++++
3 files changed, 30 insertions(+)
create mode 100644 tests/main-missing-private-key.test.js
diff --git a/main.js b/main.js
index a44409ab..19730411 100644
--- a/main.js
+++ b/main.js
@@ -23,6 +23,9 @@ async function run() {
throw new Error("The 'client-id' (or deprecated 'app-id') input must be set to a non-empty string. If using a secret or variable, ensure it is available in this workflow context.");
}
const privateKey = core.getInput("private-key");
+ if (!privateKey) {
+ throw new Error("The 'private-key' input must be set to a non-empty string. If using a secret or variable, ensure it is available in this workflow context.");
+ }
const enterprise = core.getInput("enterprise");
const owner = core.getInput("owner");
const repositories = core
diff --git a/tests/index.js.snapshot b/tests/index.js.snapshot
index 10372182..2c88dc4e 100644
--- a/tests/index.js.snapshot
+++ b/tests/index.js.snapshot
@@ -165,6 +165,14 @@ exports[`main-missing-owner.test.js > stderr 1`] = `
GITHUB_REPOSITORY_OWNER missing, must be set to ''
`;
+exports[`main-missing-private-key.test.js > stderr 1`] = `
+The 'private-key' input must be set to a non-empty string. If using a secret or variable, ensure it is available in this workflow context.
+`;
+
+exports[`main-missing-private-key.test.js > stdout 1`] = `
+::error::The 'private-key' input must be set to a non-empty string. If using a secret or variable, ensure it is available in this workflow context.
+`;
+
exports[`main-missing-repository.test.js > stderr 1`] = `
GITHUB_REPOSITORY missing, must be set to '/'
`;
diff --git a/tests/main-missing-private-key.test.js b/tests/main-missing-private-key.test.js
new file mode 100644
index 00000000..95be5132
--- /dev/null
+++ b/tests/main-missing-private-key.test.js
@@ -0,0 +1,19 @@
+import { DEFAULT_ENV } from "./main.js";
+
+for (const [key, value] of Object.entries({
+ ...DEFAULT_ENV,
+ "INPUT_PRIVATE-KEY": "",
+})) {
+ process.env[key] = value;
+}
+
+// Log only the error message, not the full stack trace, because the stack
+// trace contains environment-specific paths and ANSI codes that differ
+// between local and CI environments.
+const _error = console.error;
+console.error = (err) => _error(err?.message ?? err);
+
+// Verify `main` exits with an error when `private-key` is not set.
+const { default: promise } = await import("../main.js");
+await promise;
+process.exitCode = 0;
From bcd2ba49218906704ab6c1aa796996da409d3eb1 Mon Sep 17 00:00:00 2001
From: "create-app-token-action-releaser[bot]"
<135574722+create-app-token-action-releaser[bot]@users.noreply.github.com>
Date: Tue, 12 May 2026 16:31:18 -0700
Subject: [PATCH 16/29] chore(main): release 3.2.0 (#370)
:robot: I have created a release *beep* *boop*
---
##
[3.2.0](https://github.com/actions/create-github-app-token/compare/v3.1.1...v3.2.0)
(2026-05-12)
### Features
* add support for enterprise-level GitHub Apps
([#263](https://github.com/actions/create-github-app-token/issues/263))
([952a2a7](https://github.com/actions/create-github-app-token/commit/952a2a7073df6bfa5f49bc469ec895b6ec1acea4))
* support full repository names in `repositories` input
([#372](https://github.com/actions/create-github-app-token/issues/372))
([85eb8dd](https://github.com/actions/create-github-app-token/commit/85eb8dd41472213aed25d1a126460e0069138ab6))
### Bug Fixes
* **deps:** bump @actions/core from 3.0.0 to 3.0.1 in the
production-dependencies group
([#364](https://github.com/actions/create-github-app-token/issues/364))
([43e5c34](https://github.com/actions/create-github-app-token/commit/43e5c345bfd4d4f3ecea019ad0042001a09dd857))
* validate private-key input
([#376](https://github.com/actions/create-github-app-token/issues/376))
([f24bbd8](https://github.com/actions/create-github-app-token/commit/f24bbd89643991c0de27ae823c01791b2c6bafdd))
---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
---------
Co-authored-by: create-app-token-action-releaser[bot] <135574722+create-app-token-action-releaser[bot]@users.noreply.github.com>
Co-authored-by: parkerbxyz <17183625+parkerbxyz@users.noreply.github.com>
---
.release-please-manifest.json | 2 +-
CHANGELOG.md | 15 ++++++++++++
dist/main.cjs | 43 ++++++++++++++++++++++++++++++-----
package-lock.json | 4 ++--
package.json | 2 +-
5 files changed, 56 insertions(+), 10 deletions(-)
create mode 100644 CHANGELOG.md
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index b4b8d0ff..95a37e3e 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "3.1.1"
+ ".": "3.2.0"
}
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 00000000..3dfff070
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,15 @@
+# Changelog
+
+## [3.2.0](https://github.com/actions/create-github-app-token/compare/v3.1.1...v3.2.0) (2026-05-12)
+
+
+### Features
+
+* add support for enterprise-level GitHub Apps ([#263](https://github.com/actions/create-github-app-token/issues/263)) ([952a2a7](https://github.com/actions/create-github-app-token/commit/952a2a7073df6bfa5f49bc469ec895b6ec1acea4))
+* support full repository names in `repositories` input ([#372](https://github.com/actions/create-github-app-token/issues/372)) ([85eb8dd](https://github.com/actions/create-github-app-token/commit/85eb8dd41472213aed25d1a126460e0069138ab6))
+
+
+### Bug Fixes
+
+* **deps:** bump @actions/core from 3.0.0 to 3.0.1 in the production-dependencies group ([#364](https://github.com/actions/create-github-app-token/issues/364)) ([43e5c34](https://github.com/actions/create-github-app-token/commit/43e5c345bfd4d4f3ecea019ad0042001a09dd857))
+* validate private-key input ([#376](https://github.com/actions/create-github-app-token/issues/376)) ([f24bbd8](https://github.com/actions/create-github-app-token/commit/f24bbd89643991c0de27ae823c01791b2c6bafdd))
diff --git a/dist/main.cjs b/dist/main.cjs
index dc716995..20b90dce 100644
--- a/dist/main.cjs
+++ b/dist/main.cjs
@@ -23241,24 +23241,52 @@ function resolveInstallationTarget(enterprise, owner, repositories, core) {
);
return { type: "owner", owner };
}
- const parsedOwner = owner || String(process.env.GITHUB_REPOSITORY_OWNER);
+ const target = normalizeRepositoryTarget(owner, repositories);
if (!owner) {
core.info(
- `No 'owner' input provided. Using default owner '${parsedOwner}' to create token for the following repositories:${repositories.map((repo) => `
-- ${parsedOwner}/${repo}`).join("")}`
+ `No 'owner' input provided. Using default owner '${target.owner}' to create token for the following repositories:${target.repositories.map((repo) => `
+- ${target.owner}/${repo}`).join("")}`
);
} else {
core.info(
- `Inputs 'owner' and 'repositories' are set. Creating token for the following repositories:${repositories.map((repo) => `
-- ${parsedOwner}/${repo}`).join("")}`
+ `Inputs 'owner' and 'repositories' are set. Creating token for the following repositories:${target.repositories.map((repo) => `
+- ${target.owner}/${repo}`).join("")}`
);
}
return {
type: "repository",
+ owner: target.owner,
+ repositories: target.repositories
+ };
+}
+function normalizeRepositoryTarget(owner, repositories) {
+ const parsedOwner = owner || String(process.env.GITHUB_REPOSITORY_OWNER);
+ const parsedRepositories = repositories.map(parseRepositoryInput);
+ const mismatchedRepository = parsedRepositories.find(
+ (repository) => repository.owner && repository.owner.toLowerCase() !== parsedOwner.toLowerCase()
+ );
+ if (mismatchedRepository) {
+ throw new Error(
+ `Repository '${mismatchedRepository.input}' includes owner '${mismatchedRepository.owner}', which does not match the resolved owner '${parsedOwner}'.`
+ );
+ }
+ return {
owner: parsedOwner,
- repositories
+ repositories: parsedRepositories.map((repository) => repository.name)
};
}
+function parseRepositoryInput(input) {
+ const parts = input.split("/");
+ if (parts.length === 1 && parts[0]) {
+ return { input, owner: "", name: parts[0] };
+ }
+ if (parts.length === 2 && parts[0] && parts[1]) {
+ return { input, owner: parts[0], name: parts[1] };
+ }
+ throw new Error(
+ `Invalid repository '${input}'. Expected 'repository' or 'owner/repository'.`
+ );
+}
function getTokenRetryDescription(target) {
switch (target.type) {
case "enterprise":
@@ -23397,6 +23425,9 @@ async function run() {
throw new Error("The 'client-id' (or deprecated 'app-id') input must be set to a non-empty string. If using a secret or variable, ensure it is available in this workflow context.");
}
const privateKey = getInput("private-key");
+ if (!privateKey) {
+ throw new Error("The 'private-key' input must be set to a non-empty string. If using a secret or variable, ensure it is available in this workflow context.");
+ }
const enterprise = getInput("enterprise");
const owner = getInput("owner");
const repositories = getInput("repositories").split(/[\n,]+/).map((s) => s.trim()).filter((x) => x !== "");
diff --git a/package-lock.json b/package-lock.json
index 0ae4bcb0..6120d7e4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "create-github-app-token",
- "version": "3.1.1",
+ "version": "3.2.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "create-github-app-token",
- "version": "3.1.1",
+ "version": "3.2.0",
"license": "MIT",
"dependencies": {
"@actions/core": "^3.0.1",
diff --git a/package.json b/package.json
index 0fd488c5..0584f703 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
"name": "create-github-app-token",
"private": true,
"type": "module",
- "version": "3.1.1",
+ "version": "3.2.0",
"description": "GitHub Action for creating a GitHub App Installation Access Token",
"engines": {
"node": ">=24.4.0"
From d6ebfe3883ae9ebb719ed86c99c1d83daa3a8b9a Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 12 Oct 2026 14:43:24 -0700
Subject: [PATCH 17/29] build(deps-dev): bump the development-dependencies
group across 1 directory with 3 updates (#385)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Bumps the development-dependencies group with 3 updates in the /
directory: [esbuild](https://github.com/evanw/esbuild),
[undici](https://github.com/nodejs/undici) and
[yaml](https://github.com/eemeli/yaml).
Updates `esbuild` from 0.28.0 to 0.28.1
Release notes
Sourced from esbuild's
releases.
v0.28.1
-
Disallow \ in local development server HTTP requests (GHSA-g7r4-m6w7-qqqr)
This release fixes a security issue where HTTP requests to esbuild's
local development server could traverse outside of the serve directory
on Windows using a \ backslash character. It happened due
to the use of Go's path.Clean() function, which only
handles Unix-style / characters. HTTP requests with paths
containing \ are no longer allowed.
Thanks to @dellalibera for
reporting this issue.
-
Add integrity checks to the Deno API (GHSA-gv7w-rqvm-qjhr)
The previous release of esbuild added integrity checks to esbuild's
npm install script. This release also adds integrity checks to esbuild's
Deno install script. Now esbuild's Deno API will also fail with an error
if the downloaded esbuild binary contains something other than the
expected content.
Note that esbuild's Deno API installs from
registry.npmjs.org by default, but allows the
NPM_CONFIG_REGISTRY environment variable to override this
with a custom package registry. This change means that the esbuild
executable served by NPM_CONFIG_REGISTRY must now match the
expected content.
Thanks to @sondt99 for
reporting this issue.
-
Avoid inlining using and await using
declarations (#4482)
Previously esbuild's minifier sometimes incorrectly inlined
using and await using declarations into
subsequent uses of that declaration, which then fails to dispose of the
resource correctly. This bug happened because inlining was done for
let and const declarations by avoiding doing
it for var declarations, which no longer worked when more
declaration types were added. Here's an example:
// Original code
{
using x = new Resource()
x.activate()
}
// Old output (with --minify)
new Resource().activate();
// New output (with --minify)
{using e=new Resource;e.activate()}
-
Fix module evaluation when an error is thrown (#4461,
#4467)
If an error is thrown during module evaluation, esbuild previously
didn't preserve the state of the module for subsequent module
references. This was observable if import() or
require() is used to import a module multiple times. The
thrown error is supposed to be thrown by every call to
import() or require(), not just the first.
With this release, esbuild will now throw the same error every time you
call import() or require() on a module that
throws during its evaluation.
-
Fix some edge cases around the new operator (#4477)
Previously esbuild incorrectly printed certain edge cases involving
complex expressions inside the target of a new expression
(specifically an optional chain and/or a tagged template literal). The
generated code for the new target was not correctly wrapped
with parentheses, and either contained a syntax error or had different
semantics. These edge cases have been fixed so that they now correctly
wrap the new target in parentheses. Here is an example of
some affected code:
// Original code
new (foo()`bar`)()
new (foo()?.bar)()
// Old output
new foo()bar();
new (foo())?.bar();
... (truncated)
Changelog
Sourced from esbuild's
changelog.
0.28.1
-
Disallow \ in local development server HTTP requests (GHSA-g7r4-m6w7-qqqr)
This release fixes a security issue where HTTP requests to esbuild's
local development server could traverse outside of the serve directory
on Windows using a \ backslash character. It happened due
to the use of Go's path.Clean() function, which only
handles Unix-style / characters. HTTP requests with paths
containing \ are no longer allowed.
Thanks to @dellalibera for
reporting this issue.
-
Add integrity checks to the Deno API (GHSA-gv7w-rqvm-qjhr)
The previous release of esbuild added integrity checks to esbuild's
npm install script. This release also adds integrity checks to esbuild's
Deno install script. Now esbuild's Deno API will also fail with an error
if the downloaded esbuild binary contains something other than the
expected content.
Note that esbuild's Deno API installs from
registry.npmjs.org by default, but allows the
NPM_CONFIG_REGISTRY environment variable to override this
with a custom package registry. This change means that the esbuild
executable served by NPM_CONFIG_REGISTRY must now match the
expected content.
Thanks to @sondt99 for
reporting this issue.
-
Avoid inlining using and await using
declarations (#4482)
Previously esbuild's minifier sometimes incorrectly inlined
using and await using declarations into
subsequent uses of that declaration, which then fails to dispose of the
resource correctly. This bug happened because inlining was done for
let and const declarations by avoiding doing
it for var declarations, which no longer worked when more
declaration types were added. Here's an example:
// Original code
{
using x = new Resource()
x.activate()
}
// Old output (with --minify)
new Resource().activate();
// New output (with --minify)
{using e=new Resource;e.activate()}
-
Fix module evaluation when an error is thrown (#4461,
#4467)
If an error is thrown during module evaluation, esbuild previously
didn't preserve the state of the module for subsequent module
references. This was observable if import() or
require() is used to import a module multiple times. The
thrown error is supposed to be thrown by every call to
import() or require(), not just the first.
With this release, esbuild will now throw the same error every time you
call import() or require() on a module that
throws during its evaluation.
-
Fix some edge cases around the new operator (#4477)
Previously esbuild incorrectly printed certain edge cases involving
complex expressions inside the target of a new expression
(specifically an optional chain and/or a tagged template literal). The
generated code for the new target was not correctly wrapped
with parentheses, and either contained a syntax error or had different
semantics. These edge cases have been fixed so that they now correctly
wrap the new target in parentheses. Here is an example of
some affected code:
// Original code
new (foo()`bar`)()
new (foo()?.bar)()
// Old output
new foo()bar();
new (foo())?.bar();
... (truncated)
Commits
Updates `undici` from 8.2.0 to 8.5.0
Release notes
Sourced from undici's
releases.
v8.5.0
⚠️ Security Release
This release line addresses 8 security advisories.
Most are fixed in
v8.5.0; the SOCKS5 pool-reuse issue was fixed earlier
in v8.2.0.
Action required: Upgrade to undici
8.5.0 or later.
npm install undici@^8.5.0
Summary
High severity
WebSocket DoS via fragment count bypass — CVE-2026-12151
GHSA-vxpw-j846-p89q
· CWE-400, CWE-770
Fix: 32dbf0b3
websocket: limit the number of fragments in a message (also c5ed7875
handle empty fragments and stream limits)
A malicious WebSocket server can stream a large number of small or
empty
continuation frames. Undici enforced a limit on cumulative payload size
but did
not limit the number of fragments per message, leading to
unbounded memory
growth and denial of service.
- Affected: applications using
new
WebSocket(...) or WebSocketStream
against untrusted endpoints.
- Workaround: none — upgrade is required.
WebSocket DoS via cumulative fragment bypass — CVE-2026-9675
GHSA-38rv-x7px-6hhq
· CWE-400, CWE-770
Fix: b4c287b3
fix(websocket): enforce max payload size across fragments
Undici validated the size of individual frames but did not track
cumulative size
across a fragmented message. An attacker could send many small fragments
that
each pass per-frame validation but collectively exceed the configured
limit,
causing memory exhaustion. This is a regression introduced in
8.1.0 (the
... (truncated)
Commits
a0806e1
Bumped v8.5.0 (#5429)
8a0392c
test: detect available python command in wpt runner (#5427)
f4045b9
ci: increase Node.js workflow timeout (#5426)
363e44f
chore: removed repro-h2-pipelining-default.mjs and lint (#5420)
c5ed787
websocket: handle empty fragments and stream limits
e114e77
align EventSource with spec (#5418)
6df53c5
fix: preserve h2 queue on out-of-order completion (#5410)
32dbf0b
websocket: limit the number of fragments in a message
0d6ecc5
add bodymixin.textStream() (#5416)
42d4955
fix: honor requestTls when proxy is SOCKS5
- Additional commits viewable in compare
view
Updates `yaml` from 2.8.4 to 2.9.0
Release notes
Sourced from yaml's
releases.
v2.9.0
The changes here are really only patches, but I'm releasing this as a
minor version to note a small change to the documentation of
parseDocument() and parseAllDocuments(): I've
removed the claim that they'll "never throw".
It remains the case that practically all non-malicious inputs will be
handled without emitting an error, but there is a decent chance that
code paths remain where e.g. a RangeError due to call stack exhaustion
can be triggered by malicious inputs. Up to now, I've considered these
as security vulnerabilities, and in fact it's the only category of error
for which yaml CVEs have been issued so far.
Starting from this release, I'll be considering such errors as bugs,
but not vulnerabilities. I do welcome people and/or LLMs looking for
them, but please report them as normal issues rather than suspected
security vulnerabilities. This also applies to previously undiscovered
bugs in earlier releases.
- fix: Avoid calling
Array.prototype.push.apply() with
large source array
- fix(lexer): Avoid recursive calls that may exhaust the call
stack
Commits
ddb21b0
2.9.0
167365b
docs: Clarify that not all errors can be avoided
6eca2a7
fix: Avoid calling Array.prototype.push.apply() with large source
array
0543cd5
fix(lexer): Avoid recursive calls that may exhaust the call stack
- See full diff in compare
view
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore ` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore ` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore ` will
remove the ignore condition of the specified dependency and ignore
conditions
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
package-lock.json | 232 +++++++++++++++++++++++-----------------------
package.json | 6 +-
2 files changed, 119 insertions(+), 119 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 6120d7e4..6cf6282b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -18,10 +18,10 @@
"devDependencies": {
"@octokit/openapi": "^22.0.0",
"c8": "^11.0.0",
- "esbuild": "^0.28.0",
+ "esbuild": "^0.28.1",
"open-cli": "^9.0.0",
- "undici": "^8.2.0",
- "yaml": "^2.8.4"
+ "undici": "^8.5.0",
+ "yaml": "^2.9.0"
},
"engines": {
"node": ">=24.4.0"
@@ -92,9 +92,9 @@
}
},
"node_modules/@esbuild/aix-ppc64": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.0.tgz",
- "integrity": "sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz",
+ "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==",
"cpu": [
"ppc64"
],
@@ -109,9 +109,9 @@
}
},
"node_modules/@esbuild/android-arm": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.0.tgz",
- "integrity": "sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz",
+ "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==",
"cpu": [
"arm"
],
@@ -126,9 +126,9 @@
}
},
"node_modules/@esbuild/android-arm64": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.0.tgz",
- "integrity": "sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz",
+ "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==",
"cpu": [
"arm64"
],
@@ -143,9 +143,9 @@
}
},
"node_modules/@esbuild/android-x64": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.0.tgz",
- "integrity": "sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz",
+ "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==",
"cpu": [
"x64"
],
@@ -160,9 +160,9 @@
}
},
"node_modules/@esbuild/darwin-arm64": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.0.tgz",
- "integrity": "sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz",
+ "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==",
"cpu": [
"arm64"
],
@@ -177,9 +177,9 @@
}
},
"node_modules/@esbuild/darwin-x64": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.0.tgz",
- "integrity": "sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz",
+ "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==",
"cpu": [
"x64"
],
@@ -194,9 +194,9 @@
}
},
"node_modules/@esbuild/freebsd-arm64": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.0.tgz",
- "integrity": "sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz",
+ "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==",
"cpu": [
"arm64"
],
@@ -211,9 +211,9 @@
}
},
"node_modules/@esbuild/freebsd-x64": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.0.tgz",
- "integrity": "sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz",
+ "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==",
"cpu": [
"x64"
],
@@ -228,9 +228,9 @@
}
},
"node_modules/@esbuild/linux-arm": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.0.tgz",
- "integrity": "sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz",
+ "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==",
"cpu": [
"arm"
],
@@ -245,9 +245,9 @@
}
},
"node_modules/@esbuild/linux-arm64": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.0.tgz",
- "integrity": "sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz",
+ "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==",
"cpu": [
"arm64"
],
@@ -262,9 +262,9 @@
}
},
"node_modules/@esbuild/linux-ia32": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.0.tgz",
- "integrity": "sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz",
+ "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==",
"cpu": [
"ia32"
],
@@ -279,9 +279,9 @@
}
},
"node_modules/@esbuild/linux-loong64": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.0.tgz",
- "integrity": "sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz",
+ "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==",
"cpu": [
"loong64"
],
@@ -296,9 +296,9 @@
}
},
"node_modules/@esbuild/linux-mips64el": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.0.tgz",
- "integrity": "sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz",
+ "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==",
"cpu": [
"mips64el"
],
@@ -313,9 +313,9 @@
}
},
"node_modules/@esbuild/linux-ppc64": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.0.tgz",
- "integrity": "sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz",
+ "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==",
"cpu": [
"ppc64"
],
@@ -330,9 +330,9 @@
}
},
"node_modules/@esbuild/linux-riscv64": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.0.tgz",
- "integrity": "sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz",
+ "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==",
"cpu": [
"riscv64"
],
@@ -347,9 +347,9 @@
}
},
"node_modules/@esbuild/linux-s390x": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.0.tgz",
- "integrity": "sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz",
+ "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==",
"cpu": [
"s390x"
],
@@ -364,9 +364,9 @@
}
},
"node_modules/@esbuild/linux-x64": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.0.tgz",
- "integrity": "sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz",
+ "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==",
"cpu": [
"x64"
],
@@ -381,9 +381,9 @@
}
},
"node_modules/@esbuild/netbsd-arm64": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.0.tgz",
- "integrity": "sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz",
+ "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==",
"cpu": [
"arm64"
],
@@ -398,9 +398,9 @@
}
},
"node_modules/@esbuild/netbsd-x64": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.0.tgz",
- "integrity": "sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz",
+ "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==",
"cpu": [
"x64"
],
@@ -415,9 +415,9 @@
}
},
"node_modules/@esbuild/openbsd-arm64": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.0.tgz",
- "integrity": "sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz",
+ "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==",
"cpu": [
"arm64"
],
@@ -432,9 +432,9 @@
}
},
"node_modules/@esbuild/openbsd-x64": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.0.tgz",
- "integrity": "sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz",
+ "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==",
"cpu": [
"x64"
],
@@ -449,9 +449,9 @@
}
},
"node_modules/@esbuild/openharmony-arm64": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.0.tgz",
- "integrity": "sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz",
+ "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==",
"cpu": [
"arm64"
],
@@ -466,9 +466,9 @@
}
},
"node_modules/@esbuild/sunos-x64": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.0.tgz",
- "integrity": "sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz",
+ "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==",
"cpu": [
"x64"
],
@@ -483,9 +483,9 @@
}
},
"node_modules/@esbuild/win32-arm64": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.0.tgz",
- "integrity": "sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz",
+ "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==",
"cpu": [
"arm64"
],
@@ -500,9 +500,9 @@
}
},
"node_modules/@esbuild/win32-ia32": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.0.tgz",
- "integrity": "sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz",
+ "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==",
"cpu": [
"ia32"
],
@@ -517,9 +517,9 @@
}
},
"node_modules/@esbuild/win32-x64": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.0.tgz",
- "integrity": "sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz",
+ "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==",
"cpu": [
"x64"
],
@@ -1023,9 +1023,9 @@
}
},
"node_modules/esbuild": {
- "version": "0.28.0",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.0.tgz",
- "integrity": "sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz",
+ "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
@@ -1036,32 +1036,32 @@
"node": ">=18"
},
"optionalDependencies": {
- "@esbuild/aix-ppc64": "0.28.0",
- "@esbuild/android-arm": "0.28.0",
- "@esbuild/android-arm64": "0.28.0",
- "@esbuild/android-x64": "0.28.0",
- "@esbuild/darwin-arm64": "0.28.0",
- "@esbuild/darwin-x64": "0.28.0",
- "@esbuild/freebsd-arm64": "0.28.0",
- "@esbuild/freebsd-x64": "0.28.0",
- "@esbuild/linux-arm": "0.28.0",
- "@esbuild/linux-arm64": "0.28.0",
- "@esbuild/linux-ia32": "0.28.0",
- "@esbuild/linux-loong64": "0.28.0",
- "@esbuild/linux-mips64el": "0.28.0",
- "@esbuild/linux-ppc64": "0.28.0",
- "@esbuild/linux-riscv64": "0.28.0",
- "@esbuild/linux-s390x": "0.28.0",
- "@esbuild/linux-x64": "0.28.0",
- "@esbuild/netbsd-arm64": "0.28.0",
- "@esbuild/netbsd-x64": "0.28.0",
- "@esbuild/openbsd-arm64": "0.28.0",
- "@esbuild/openbsd-x64": "0.28.0",
- "@esbuild/openharmony-arm64": "0.28.0",
- "@esbuild/sunos-x64": "0.28.0",
- "@esbuild/win32-arm64": "0.28.0",
- "@esbuild/win32-ia32": "0.28.0",
- "@esbuild/win32-x64": "0.28.0"
+ "@esbuild/aix-ppc64": "0.28.1",
+ "@esbuild/android-arm": "0.28.1",
+ "@esbuild/android-arm64": "0.28.1",
+ "@esbuild/android-x64": "0.28.1",
+ "@esbuild/darwin-arm64": "0.28.1",
+ "@esbuild/darwin-x64": "0.28.1",
+ "@esbuild/freebsd-arm64": "0.28.1",
+ "@esbuild/freebsd-x64": "0.28.1",
+ "@esbuild/linux-arm": "0.28.1",
+ "@esbuild/linux-arm64": "0.28.1",
+ "@esbuild/linux-ia32": "0.28.1",
+ "@esbuild/linux-loong64": "0.28.1",
+ "@esbuild/linux-mips64el": "0.28.1",
+ "@esbuild/linux-ppc64": "0.28.1",
+ "@esbuild/linux-riscv64": "0.28.1",
+ "@esbuild/linux-s390x": "0.28.1",
+ "@esbuild/linux-x64": "0.28.1",
+ "@esbuild/netbsd-arm64": "0.28.1",
+ "@esbuild/netbsd-x64": "0.28.1",
+ "@esbuild/openbsd-arm64": "0.28.1",
+ "@esbuild/openbsd-x64": "0.28.1",
+ "@esbuild/openharmony-arm64": "0.28.1",
+ "@esbuild/sunos-x64": "0.28.1",
+ "@esbuild/win32-arm64": "0.28.1",
+ "@esbuild/win32-ia32": "0.28.1",
+ "@esbuild/win32-x64": "0.28.1"
}
},
"node_modules/escalade": {
@@ -1786,9 +1786,9 @@
}
},
"node_modules/undici": {
- "version": "8.2.0",
- "resolved": "https://registry.npmjs.org/undici/-/undici-8.2.0.tgz",
- "integrity": "sha512-Z+4Hx9GE26Lh9Upwfnc8C7SsrpBPGaM/Gm6kMFtiG7c+5IvQKlXi/t+9x9DrrCh29cww5TSP9YdVaBcnLDs5fQ==",
+ "version": "8.5.0",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-8.5.0.tgz",
+ "integrity": "sha512-xamtWoB1EshgjpmlXd7GGm2VfdDtw1+rD8uhry8pSNW3If6S8E0m2T2+orSKeZXEn/aPJMviCpDBA65WJt8zhg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -1966,9 +1966,9 @@
"dev": true
},
"node_modules/yaml": {
- "version": "2.8.4",
- "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.4.tgz",
- "integrity": "sha512-ml/JPOj9fOQK8RNnWojA67GbZ0ApXAUlN2UQclwv2eVgTgn7O9gg9o7paZWKMp4g0H3nTLtS9LVzhkpOFIKzog==",
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz",
+ "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==",
"dev": true,
"license": "ISC",
"bin": {
diff --git a/package.json b/package.json
index 0584f703..e8f59d41 100644
--- a/package.json
+++ b/package.json
@@ -25,9 +25,9 @@
"devDependencies": {
"@octokit/openapi": "^22.0.0",
"c8": "^11.0.0",
- "esbuild": "^0.28.0",
+ "esbuild": "^0.28.1",
"open-cli": "^9.0.0",
- "undici": "^8.2.0",
- "yaml": "^2.8.4"
+ "undici": "^8.5.0",
+ "yaml": "^2.9.0"
}
}
From 7e4e05d60a5a2b2f6ef6cd0466c7fa7a6aaa7b41 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 12 Oct 2026 14:55:18 -0700
Subject: [PATCH 18/29] build(deps-dev): bump brace-expansion from 5.0.5 to
5.0.12 (#397)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Bumps [brace-expansion](https://github.com/juliangruber/brace-expansion)
from 5.0.5 to 5.0.12.
Commits
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/actions/create-github-app-token/network/alerts).
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
package-lock.json | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 6cf6282b..657416e0 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -767,16 +767,16 @@
}
},
"node_modules/brace-expansion": {
- "version": "5.0.5",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz",
- "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==",
+ "version": "5.0.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.12.tgz",
+ "integrity": "sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^4.0.2"
},
"engines": {
- "node": "18 || 20 || >=22"
+ "node": "20 || >=22"
}
},
"node_modules/bundle-name": {
From 941de883d0fba88f65049e42176b418b82e7c7e7 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 12 Oct 2026 15:00:21 -0700
Subject: [PATCH 19/29] build(deps-dev): bump the development-dependencies
group across 1 directory with 3 updates (#398)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Bumps the development-dependencies group with 3 updates in the /
directory: [esbuild](https://github.com/evanw/esbuild),
[undici](https://github.com/nodejs/undici) and
[yaml](https://github.com/eemeli/yaml).
Updates `esbuild` from 0.28.1 to 0.28.2
Release notes
Sourced from esbuild's
releases.
v0.28.2
-
Fix tree shaking bug due to TypeScript import alias (#4507)
This release fixes a bug that could cause esbuild to incorrectly
tree-shake imports that are used in a TypeScript type alias under
certain circumstances. Affected code uses a TypeScript-specific
import assignment and looks something like this:
import Base from './dep.js';
import Alias = Base.SomeType;
-
Fix CSS minification bug involving & (#4497)
This release fixes a bug where esbuild's CSS minifier incorrectly
removed a & when it was unsafe to do so. Here is an
example:
/* Original code */
.a .b {
& .b:not(& .c) {
color: red;
}
}
/* Old output (with --minify) */
.a .b{.b:not(& .c){color:red}}
/* New output (with --minify) */
.a .b{& .b:not(& .c){color:red}}
This should match <span class="a"><span
class="b"><span
class="b">yes</span></span></span>
but not <span class="a"><span
class="b">no</span></span>. The old
output incorrectly matched both.
-
Avoid overwriting input files without --allow-overwrite
(#4484)
For example: esbuild input.js --outfile=input.js tells
esbuild to overwrite input.js with the output of running
esbuild on it. This was supposed to already be prevented by default, but
it accidentally regressed in version 0.17.0 and apparently didn't have
any test coverage. The error message was being printed but the input
file was still being overwritten. Oops.
This release puts the original behavior back. With this release,
esbuild should now actually avoid overwriting input files unless
--allow-overwrite is explicitly present. This is done by
not writing out any files when a build error is encountered.
-
Fix incorrect code generated when using top-level await (#4498)
Previously esbuild could generate code containing a syntax error in
complex scenarios involving top-level await used in a dependency cycle.
The problem was a missing async on one or more module
wrapper closures. With this release, esbuild now uses a fixed-point
iteration algorithm to correctly annotate all dependencies in the cycle
as needing an async module wrapper.
-
Fix a minification bug with lowered logical assignment operators (#4508)
This release fixes a bug that could cause esbuild to generate
incorrect code for logical assignment operators when lowering them to an
older target environment. Specifically the lowering process requires
duplicating the left-hand side, but esbuild incorrectly failed to count
the duplicate as a new usage when the left-hand side is an identifier.
That then caused the minifier to believe that the left-hand side was
only used once and could attempt to incorrectly inline an initializer
into the first usage. This bug has now been fixed:
// Original code
function foo() {
let x
bar(x ||= {})
... (truncated)
Changelog
Sourced from esbuild's
changelog.
0.28.2
-
Fix tree shaking bug due to TypeScript import alias (#4507)
This release fixes a bug that could cause esbuild to incorrectly
tree-shake imports that are used in a TypeScript type alias under
certain circumstances. Affected code uses a TypeScript-specific
import assignment and looks something like this:
import Base from './dep.js';
import Alias = Base.SomeType;
-
Fix CSS minification bug involving & (#4497)
This release fixes a bug where esbuild's CSS minifier incorrectly
removed a & when it was unsafe to do so. Here is an
example:
/* Original code */
.a .b {
& .b:not(& .c) {
color: red;
}
}
/* Old output (with --minify) */
.a .b{.b:not(& .c){color:red}}
/* New output (with --minify) */
.a .b{& .b:not(& .c){color:red}}
This should match <span class="a"><span
class="b"><span
class="b">yes</span></span></span>
but not <span class="a"><span
class="b">no</span></span>. The old
output incorrectly matched both.
-
Avoid overwriting input files without --allow-overwrite
(#4484)
For example: esbuild input.js --outfile=input.js tells
esbuild to overwrite input.js with the output of running
esbuild on it. This was supposed to already be prevented by default, but
it accidentally regressed in version 0.17.0 and apparently didn't have
any test coverage. The error message was being printed but the input
file was still being overwritten. Oops.
This release puts the original behavior back. With this release,
esbuild should now actually avoid overwriting input files unless
--allow-overwrite is explicitly present. This is done by
not writing out any files when a build error is encountered.
-
Fix incorrect code generated when using top-level await (#4498)
Previously esbuild could generate code containing a syntax error in
complex scenarios involving top-level await used in a dependency cycle.
The problem was a missing async on one or more module
wrapper closures. With this release, esbuild now uses a fixed-point
iteration algorithm to correctly annotate all dependencies in the cycle
as needing an async module wrapper.
-
Fix a minification bug with lowered logical assignment operators (#4508)
This release fixes a bug that could cause esbuild to generate
incorrect code for logical assignment operators when lowering them to an
older target environment. Specifically the lowering process requires
duplicating the left-hand side, but esbuild incorrectly failed to count
the duplicate as a new usage when the left-hand side is an identifier.
That then caused the minifier to believe that the left-hand side was
only used once and could attempt to incorrectly inline an initializer
into the first usage. This bug has now been fixed:
// Original code
function foo() {
let x
... (truncated)
Commits
609683d
publish 0.28.2 to npm
11b1fe4
add to release notes
ab50d91
css: fix green/blue channel swap in oklch gamut mapping (#4488)
04627b6
fix #4498:
async TLA checks need a worklist
5c15177
disable gopls in the go folder
fc2ee9b
css: adjust parser to allow --foo: {...}
209db54
release notes for css nesting bugfix
c625d31
fix #4497:
preserve nested ampersands during minification (#4500)
34474e2
better isolation of current part in js parser
07f6e8c
fix #4507:
import assignment tree-shaking bug
- Additional commits viewable in compare
view
Updates `undici` from 8.5.0 to 8.11.2
Release notes
Sourced from undici's
releases.
v8.11.2
What's Changed
New Contributors
Full Changelog: https://github.com/nodejs/undici/compare/v8.11.1...v8.11.2
v8.11.1
What's Changed
Full Changelog: https://github.com/nodejs/undici/compare/v8.11.0...v8.11.1
v8.11.0
What's Changed
... (truncated)
Commits
Updates `yaml` from 2.9.0 to 2.9.1
Release notes
Sourced from yaml's
releases.
v2.9.1
- Limit recursive merge aliases (#685, #713)
- Simplify line unfolding during quoted string parsing (#714)
Commits
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
package-lock.json | 232 +++++++++++++++++++++++-----------------------
package.json | 6 +-
2 files changed, 119 insertions(+), 119 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 657416e0..ba52a1c8 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -18,10 +18,10 @@
"devDependencies": {
"@octokit/openapi": "^22.0.0",
"c8": "^11.0.0",
- "esbuild": "^0.28.1",
+ "esbuild": "^0.28.2",
"open-cli": "^9.0.0",
- "undici": "^8.5.0",
- "yaml": "^2.9.0"
+ "undici": "^8.11.2",
+ "yaml": "^2.9.1"
},
"engines": {
"node": ">=24.4.0"
@@ -92,9 +92,9 @@
}
},
"node_modules/@esbuild/aix-ppc64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz",
- "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.2.tgz",
+ "integrity": "sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==",
"cpu": [
"ppc64"
],
@@ -109,9 +109,9 @@
}
},
"node_modules/@esbuild/android-arm": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz",
- "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.2.tgz",
+ "integrity": "sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==",
"cpu": [
"arm"
],
@@ -126,9 +126,9 @@
}
},
"node_modules/@esbuild/android-arm64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz",
- "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.2.tgz",
+ "integrity": "sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==",
"cpu": [
"arm64"
],
@@ -143,9 +143,9 @@
}
},
"node_modules/@esbuild/android-x64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz",
- "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.2.tgz",
+ "integrity": "sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==",
"cpu": [
"x64"
],
@@ -160,9 +160,9 @@
}
},
"node_modules/@esbuild/darwin-arm64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz",
- "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.2.tgz",
+ "integrity": "sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==",
"cpu": [
"arm64"
],
@@ -177,9 +177,9 @@
}
},
"node_modules/@esbuild/darwin-x64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz",
- "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.2.tgz",
+ "integrity": "sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==",
"cpu": [
"x64"
],
@@ -194,9 +194,9 @@
}
},
"node_modules/@esbuild/freebsd-arm64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz",
- "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.2.tgz",
+ "integrity": "sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==",
"cpu": [
"arm64"
],
@@ -211,9 +211,9 @@
}
},
"node_modules/@esbuild/freebsd-x64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz",
- "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.2.tgz",
+ "integrity": "sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==",
"cpu": [
"x64"
],
@@ -228,9 +228,9 @@
}
},
"node_modules/@esbuild/linux-arm": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz",
- "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.2.tgz",
+ "integrity": "sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==",
"cpu": [
"arm"
],
@@ -245,9 +245,9 @@
}
},
"node_modules/@esbuild/linux-arm64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz",
- "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.2.tgz",
+ "integrity": "sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==",
"cpu": [
"arm64"
],
@@ -262,9 +262,9 @@
}
},
"node_modules/@esbuild/linux-ia32": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz",
- "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.2.tgz",
+ "integrity": "sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==",
"cpu": [
"ia32"
],
@@ -279,9 +279,9 @@
}
},
"node_modules/@esbuild/linux-loong64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz",
- "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.2.tgz",
+ "integrity": "sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==",
"cpu": [
"loong64"
],
@@ -296,9 +296,9 @@
}
},
"node_modules/@esbuild/linux-mips64el": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz",
- "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.2.tgz",
+ "integrity": "sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==",
"cpu": [
"mips64el"
],
@@ -313,9 +313,9 @@
}
},
"node_modules/@esbuild/linux-ppc64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz",
- "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.2.tgz",
+ "integrity": "sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==",
"cpu": [
"ppc64"
],
@@ -330,9 +330,9 @@
}
},
"node_modules/@esbuild/linux-riscv64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz",
- "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.2.tgz",
+ "integrity": "sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==",
"cpu": [
"riscv64"
],
@@ -347,9 +347,9 @@
}
},
"node_modules/@esbuild/linux-s390x": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz",
- "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.2.tgz",
+ "integrity": "sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==",
"cpu": [
"s390x"
],
@@ -364,9 +364,9 @@
}
},
"node_modules/@esbuild/linux-x64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz",
- "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.2.tgz",
+ "integrity": "sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==",
"cpu": [
"x64"
],
@@ -381,9 +381,9 @@
}
},
"node_modules/@esbuild/netbsd-arm64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz",
- "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.2.tgz",
+ "integrity": "sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==",
"cpu": [
"arm64"
],
@@ -398,9 +398,9 @@
}
},
"node_modules/@esbuild/netbsd-x64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz",
- "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.2.tgz",
+ "integrity": "sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==",
"cpu": [
"x64"
],
@@ -415,9 +415,9 @@
}
},
"node_modules/@esbuild/openbsd-arm64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz",
- "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.2.tgz",
+ "integrity": "sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==",
"cpu": [
"arm64"
],
@@ -432,9 +432,9 @@
}
},
"node_modules/@esbuild/openbsd-x64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz",
- "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.2.tgz",
+ "integrity": "sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==",
"cpu": [
"x64"
],
@@ -449,9 +449,9 @@
}
},
"node_modules/@esbuild/openharmony-arm64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz",
- "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.2.tgz",
+ "integrity": "sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==",
"cpu": [
"arm64"
],
@@ -466,9 +466,9 @@
}
},
"node_modules/@esbuild/sunos-x64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz",
- "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.2.tgz",
+ "integrity": "sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==",
"cpu": [
"x64"
],
@@ -483,9 +483,9 @@
}
},
"node_modules/@esbuild/win32-arm64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz",
- "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.2.tgz",
+ "integrity": "sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==",
"cpu": [
"arm64"
],
@@ -500,9 +500,9 @@
}
},
"node_modules/@esbuild/win32-ia32": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz",
- "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.2.tgz",
+ "integrity": "sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==",
"cpu": [
"ia32"
],
@@ -517,9 +517,9 @@
}
},
"node_modules/@esbuild/win32-x64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz",
- "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.2.tgz",
+ "integrity": "sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==",
"cpu": [
"x64"
],
@@ -1023,9 +1023,9 @@
}
},
"node_modules/esbuild": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz",
- "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==",
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.2.tgz",
+ "integrity": "sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
@@ -1036,32 +1036,32 @@
"node": ">=18"
},
"optionalDependencies": {
- "@esbuild/aix-ppc64": "0.28.1",
- "@esbuild/android-arm": "0.28.1",
- "@esbuild/android-arm64": "0.28.1",
- "@esbuild/android-x64": "0.28.1",
- "@esbuild/darwin-arm64": "0.28.1",
- "@esbuild/darwin-x64": "0.28.1",
- "@esbuild/freebsd-arm64": "0.28.1",
- "@esbuild/freebsd-x64": "0.28.1",
- "@esbuild/linux-arm": "0.28.1",
- "@esbuild/linux-arm64": "0.28.1",
- "@esbuild/linux-ia32": "0.28.1",
- "@esbuild/linux-loong64": "0.28.1",
- "@esbuild/linux-mips64el": "0.28.1",
- "@esbuild/linux-ppc64": "0.28.1",
- "@esbuild/linux-riscv64": "0.28.1",
- "@esbuild/linux-s390x": "0.28.1",
- "@esbuild/linux-x64": "0.28.1",
- "@esbuild/netbsd-arm64": "0.28.1",
- "@esbuild/netbsd-x64": "0.28.1",
- "@esbuild/openbsd-arm64": "0.28.1",
- "@esbuild/openbsd-x64": "0.28.1",
- "@esbuild/openharmony-arm64": "0.28.1",
- "@esbuild/sunos-x64": "0.28.1",
- "@esbuild/win32-arm64": "0.28.1",
- "@esbuild/win32-ia32": "0.28.1",
- "@esbuild/win32-x64": "0.28.1"
+ "@esbuild/aix-ppc64": "0.28.2",
+ "@esbuild/android-arm": "0.28.2",
+ "@esbuild/android-arm64": "0.28.2",
+ "@esbuild/android-x64": "0.28.2",
+ "@esbuild/darwin-arm64": "0.28.2",
+ "@esbuild/darwin-x64": "0.28.2",
+ "@esbuild/freebsd-arm64": "0.28.2",
+ "@esbuild/freebsd-x64": "0.28.2",
+ "@esbuild/linux-arm": "0.28.2",
+ "@esbuild/linux-arm64": "0.28.2",
+ "@esbuild/linux-ia32": "0.28.2",
+ "@esbuild/linux-loong64": "0.28.2",
+ "@esbuild/linux-mips64el": "0.28.2",
+ "@esbuild/linux-ppc64": "0.28.2",
+ "@esbuild/linux-riscv64": "0.28.2",
+ "@esbuild/linux-s390x": "0.28.2",
+ "@esbuild/linux-x64": "0.28.2",
+ "@esbuild/netbsd-arm64": "0.28.2",
+ "@esbuild/netbsd-x64": "0.28.2",
+ "@esbuild/openbsd-arm64": "0.28.2",
+ "@esbuild/openbsd-x64": "0.28.2",
+ "@esbuild/openharmony-arm64": "0.28.2",
+ "@esbuild/sunos-x64": "0.28.2",
+ "@esbuild/win32-arm64": "0.28.2",
+ "@esbuild/win32-ia32": "0.28.2",
+ "@esbuild/win32-x64": "0.28.2"
}
},
"node_modules/escalade": {
@@ -1786,9 +1786,9 @@
}
},
"node_modules/undici": {
- "version": "8.5.0",
- "resolved": "https://registry.npmjs.org/undici/-/undici-8.5.0.tgz",
- "integrity": "sha512-xamtWoB1EshgjpmlXd7GGm2VfdDtw1+rD8uhry8pSNW3If6S8E0m2T2+orSKeZXEn/aPJMviCpDBA65WJt8zhg==",
+ "version": "8.11.2",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-8.11.2.tgz",
+ "integrity": "sha512-u4UB2/IrKdU6lFxumHmmo1a3fCQO5tzQllRorfoRS63txhrB7xTpSn1PftwC4qEHkOaqP95fCWW4lJzwErwzhQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -1966,9 +1966,9 @@
"dev": true
},
"node_modules/yaml": {
- "version": "2.9.0",
- "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz",
- "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==",
+ "version": "2.9.1",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.1.tgz",
+ "integrity": "sha512-3NxN8+78OdzbT7C/WjGsyfPAtJaN3FNDsWxv7Y7mcDsT/oOmgW8BpyQQFFBnvZE3j9Y2Sdz1ULFLezL7Eb2yFw==",
"dev": true,
"license": "ISC",
"bin": {
diff --git a/package.json b/package.json
index e8f59d41..0437832c 100644
--- a/package.json
+++ b/package.json
@@ -25,9 +25,9 @@
"devDependencies": {
"@octokit/openapi": "^22.0.0",
"c8": "^11.0.0",
- "esbuild": "^0.28.1",
+ "esbuild": "^0.28.2",
"open-cli": "^9.0.0",
- "undici": "^8.5.0",
- "yaml": "^2.9.0"
+ "undici": "^8.11.2",
+ "yaml": "^2.9.1"
}
}
From 9419396df4d5672241cfb593dadc19758e54a204 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 12 Oct 2026 15:25:53 -0700
Subject: [PATCH 20/29] build(deps-dev): bump c8 from 11.0.0 to 12.0.0 (#400)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Bumps [c8](https://github.com/bcoe/c8) from 11.0.0 to 12.0.0.
Release notes
Sourced from c8's
releases.
v12.0.0
12.0.0
(2026-07-14)
⚠ BREAKING CHANGES
- yargs enforces a stricter range of Node versions ^20.19.0 ||
^22.12.0 || >=23
Features
Changelog
Sourced from c8's
changelog.
12.0.0
(2026-07-14)
⚠ BREAKING CHANGES
- yargs enforces a stricter range of Node versions ^20.19.0 ||
^22.12.0 || >=23
Features
Commits
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
package-lock.json | 345 +++++++++++++++++++---------------------------
package.json | 2 +-
2 files changed, 143 insertions(+), 204 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index ba52a1c8..b8fd0445 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -17,7 +17,7 @@
},
"devDependencies": {
"@octokit/openapi": "^22.0.0",
- "c8": "^11.0.0",
+ "c8": "^12.0.0",
"esbuild": "^0.28.2",
"open-cli": "^9.0.0",
"undici": "^8.11.2",
@@ -756,6 +756,32 @@
"integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==",
"dev": true
},
+ "node_modules/ansi-regex": {
+ "version": "6.4.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.4.0.tgz",
+ "integrity": "sha512-KzTVk2tCWAHtYrvvvaP8bJKJq2pVinhLcGEQdtLIYPbmNGNyYe8QwNaTUYQp2J7/vIsUKt5QCqAfUkYyG9DkOw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz",
+ "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
"node_modules/balanced-match": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
@@ -796,9 +822,9 @@
}
},
"node_modules/c8": {
- "version": "11.0.0",
- "resolved": "https://registry.npmjs.org/c8/-/c8-11.0.0.tgz",
- "integrity": "sha512-e/uRViGHSVIJv7zsaDKM7VRn2390TgHXqUSvYwPHBQaU6L7E9L0n9JbdkwdYPvshDT0KymBmmlwSpms3yBaMNg==",
+ "version": "12.0.0",
+ "resolved": "https://registry.npmjs.org/c8/-/c8-12.0.0.tgz",
+ "integrity": "sha512-4zpJvrd1nKWutnnKC2pXkFmb6iM1l+ffN//o1CzlTNwW7GSOs9a1xrLqkC48nU8oEkjmPZLPiwMsIaOvoF4Pqg==",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -811,14 +837,14 @@
"istanbul-reports": "^3.1.6",
"test-exclude": "^8.0.0",
"v8-to-istanbul": "^9.0.0",
- "yargs": "^17.7.2",
+ "yargs": "^18.0.0",
"yargs-parser": "^21.1.1"
},
"bin": {
"c8": "bin/c8.js"
},
"engines": {
- "node": "20 || >=22"
+ "node": "^20.19.0 || ^22.12.0 || >=23"
},
"peerDependencies": {
"monocart-coverage-reports": "^2"
@@ -830,87 +856,38 @@
}
},
"node_modules/cliui": {
- "version": "8.0.1",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
- "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz",
+ "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==",
"dev": true,
+ "license": "ISC",
"dependencies": {
- "string-width": "^4.2.0",
- "strip-ansi": "^6.0.1",
- "wrap-ansi": "^7.0.0"
+ "string-width": "^7.2.0",
+ "strip-ansi": "^7.1.0",
+ "wrap-ansi": "^9.0.0"
},
"engines": {
- "node": ">=12"
- }
- },
- "node_modules/cliui/node_modules/ansi-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/cliui/node_modules/emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "dev": true
- },
- "node_modules/cliui/node_modules/is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "dev": true,
- "engines": {
- "node": ">=8"
+ "node": ">=20"
}
},
"node_modules/cliui/node_modules/string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "dev": true,
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/cliui/node_modules/strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
+ "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "ansi-regex": "^5.0.1"
+ "emoji-regex": "^10.3.0",
+ "get-east-asian-width": "^1.0.0",
+ "strip-ansi": "^7.1.0"
},
"engines": {
- "node": ">=8"
- }
- },
- "node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
+ "node": ">=18"
},
- "engines": {
- "node": ">=7.0.0"
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
"node_modules/convert-source-map": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
@@ -1022,6 +999,13 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/emoji-regex": {
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz",
+ "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/esbuild": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.2.tgz",
@@ -1065,10 +1049,11 @@
}
},
"node_modules/escalade": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz",
- "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==",
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6"
}
@@ -1146,10 +1131,24 @@
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
"dev": true,
+ "license": "ISC",
"engines": {
"node": "6.* || 8.* || >= 10.*"
}
},
+ "node_modules/get-east-asian-width": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.7.0.tgz",
+ "integrity": "sha512-XjH1AECxf0giL2V1aU8vKyRR2ppRUb5c0EvT7zuJTokQ74bNo52zOtghqdWIqrhUD79fo3x0WfKZdOqxF6LG1Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/glob": {
"version": "13.0.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz",
@@ -1565,15 +1564,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/require-directory": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
- "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/run-applescript": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz",
@@ -1650,6 +1640,39 @@
"url": "https://github.com/sponsors/isaacs"
}
},
+ "node_modules/string-width": {
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.3.0.tgz",
+ "integrity": "sha512-ZbmZM0JCihQN91dWnxoipT2KOEyHqEyfRXUyjuRhW8b/xnqPDoq4gWEVApTVa9db2wN8mmoikgFBbjh71+cGeQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-east-asian-width": "^1.5.0",
+ "strip-ansi": "^7.1.2"
+ },
+ "engines": {
+ "node": ">=20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz",
+ "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^6.2.2"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
"node_modules/strtok3": {
"version": "10.3.5",
"resolved": "https://registry.npmjs.org/strtok3/-/strtok3-10.3.5.tgz",
@@ -1852,85 +1875,39 @@
}
},
"node_modules/wrap-ansi": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
- "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "version": "9.0.2",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz",
+ "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "ansi-styles": "^4.0.0",
- "string-width": "^4.1.0",
- "strip-ansi": "^6.0.0"
+ "ansi-styles": "^6.2.1",
+ "string-width": "^7.0.0",
+ "strip-ansi": "^7.1.0"
},
"engines": {
- "node": ">=10"
+ "node": ">=18"
},
"funding": {
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
}
},
- "node_modules/wrap-ansi/node_modules/ansi-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/wrap-ansi/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/wrap-ansi/node_modules/emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "dev": true
- },
- "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/wrap-ansi/node_modules/string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
+ "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
+ "emoji-regex": "^10.3.0",
+ "get-east-asian-width": "^1.0.0",
+ "strip-ansi": "^7.1.0"
},
"engines": {
- "node": ">=8"
- }
- },
- "node_modules/wrap-ansi/node_modules/strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "dev": true,
- "dependencies": {
- "ansi-regex": "^5.0.1"
+ "node": ">=18"
},
- "engines": {
- "node": ">=8"
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/wsl-utils": {
@@ -1955,6 +1932,7 @@
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
"dev": true,
+ "license": "ISC",
"engines": {
"node": ">=10"
}
@@ -1982,21 +1960,21 @@
}
},
"node_modules/yargs": {
- "version": "17.7.2",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
- "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.2.0.tgz",
+ "integrity": "sha512-9OpKOLeaoNFecEp7P6iYbzze/5CqWoH7N3SMs/6y1XF4nMvFMspEGZzJ6uFi9MmQwXhyzqYoSEKO3tvA3Z/o2w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "cliui": "^8.0.1",
+ "cliui": "^9.0.1",
"escalade": "^3.1.1",
"get-caller-file": "^2.0.5",
- "require-directory": "^2.1.1",
- "string-width": "^4.2.3",
+ "string-width": "^8.2.1",
"y18n": "^5.0.5",
- "yargs-parser": "^21.1.1"
+ "yargs-parser": "^22.0.0"
},
"engines": {
- "node": ">=12"
+ "node": "^20.19.0 || ^22.12.0 || >=23"
}
},
"node_modules/yargs-parser": {
@@ -2004,58 +1982,19 @@
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
"dev": true,
+ "license": "ISC",
"engines": {
"node": ">=12"
}
},
- "node_modules/yargs/node_modules/ansi-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/yargs/node_modules/emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "dev": true
- },
- "node_modules/yargs/node_modules/is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/yargs/node_modules/string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "dev": true,
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/yargs/node_modules/strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "node_modules/yargs/node_modules/yargs-parser": {
+ "version": "22.0.0",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz",
+ "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==",
"dev": true,
- "dependencies": {
- "ansi-regex": "^5.0.1"
- },
+ "license": "ISC",
"engines": {
- "node": ">=8"
+ "node": "^20.19.0 || ^22.12.0 || >=23"
}
},
"node_modules/yocto-queue": {
diff --git a/package.json b/package.json
index 0437832c..45f336e8 100644
--- a/package.json
+++ b/package.json
@@ -24,7 +24,7 @@
},
"devDependencies": {
"@octokit/openapi": "^22.0.0",
- "c8": "^11.0.0",
+ "c8": "^12.0.0",
"esbuild": "^0.28.2",
"open-cli": "^9.0.0",
"undici": "^8.11.2",
From e85f677b44da0d1f08115ce52cdfd8fd2c69874a Mon Sep 17 00:00:00 2001
From: Parker Brown <17183625+parkerbxyz@users.noreply.github.com>
Date: Mon, 12 Oct 2026 15:35:22 -0700
Subject: [PATCH 21/29] test: omit stack traces from snapshots (#401)
The `integration` check fails on `main` because 10 snapshots include
Node.js internal stack frames, and their names changed between Node.js
versions. CI installs the latest Node.js that matches `>=24.4.0`, so
these snapshots can break without any change to the action.
This PR runs each test with `--stack-trace-limit=0`, so error output no
longer includes stack traces. Snapshots still capture the error message,
any HTTP error details, and the `::error::` output users see. Code
coverage is still enforced by `c8 --100`.
Without stack traces, `normalizeStderr` is no longer needed, so this
removes it.
All 120 tests pass with 100% coverage on Node.js 24 and 26.
---------
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b91f96b7-a7f3-4ff3-8f52-3a617307ede2
---
tests/index.js | 18 +++++------
tests/index.js.snapshot | 66 +++++------------------------------------
2 files changed, 14 insertions(+), 70 deletions(-)
diff --git a/tests/index.js b/tests/index.js
index 159c21c7..33ec9147 100644
--- a/tests/index.js
+++ b/tests/index.js
@@ -11,13 +11,6 @@ snapshot.setDefaultSnapshotSerializers([
(value) => (typeof value === "string" ? value : undefined),
]);
-function normalizeStderr(stderr) {
- return stderr
- .replaceAll(/\u001B\[[0-9;]*m/g, "")
- .replaceAll(process.cwd(), "")
- .replaceAll(/:\d+:\d+/g, "::");
-}
-
// Get all files in tests directory
const files = readdirSync("tests");
@@ -54,9 +47,12 @@ for (const file of testFiles) {
} = process.env;
let stderr, stdout;
try {
- ({ stderr, stdout } = await execFileAsync("node", [`tests/${file}`], {
- env,
- }));
+ // Omit stack traces so snapshots don't change with Node.js or dependency updates
+ ({ stderr, stdout } = await execFileAsync(
+ "node",
+ ["--stack-trace-limit=0", `tests/${file}`],
+ { env },
+ ));
} catch (error) {
if (!(error instanceof Error) || !("stderr" in error) || !("stdout" in error)) {
throw error;
@@ -64,7 +60,7 @@ for (const file of testFiles) {
({ stderr, stdout } = error);
}
- const trimmedStderr = normalizeStderr(stderr).replace(/\r?\n$/, "");
+ const trimmedStderr = stderr.replace(/\r?\n$/, "");
const trimmedStdout = stdout.replace(/\r?\n$/, "");
await t.test("stderr", (t) => {
if (trimmedStderr) t.assert.snapshot(trimmedStderr);
diff --git a/tests/index.js.snapshot b/tests/index.js.snapshot
index 2c88dc4e..541d4b3b 100644
--- a/tests/index.js.snapshot
+++ b/tests/index.js.snapshot
@@ -74,13 +74,7 @@ null
`;
exports[`main-enterprise-installation-not-found.test.js > stderr 1`] = `
-Error: No enterprise installation found matching the enterprise slug "test-enterprise".
- at getTokenFromEnterprise (file:///lib/main.js::)
- at process.processTicksAndRejections (node:internal/process/task_queues::)
- at async pRetry (file:///node_modules/p-retry/index.js::)
- at async main (file:///lib/main.js::)
- at async test (file:///tests/main.js::)
- at async file:///tests/main-enterprise-installation-not-found.test.js::
+[Error: No enterprise installation found matching the enterprise slug "test-enterprise".]
`;
exports[`main-enterprise-installation-not-found.test.js > stdout 1`] = `
@@ -92,13 +86,7 @@ GET /enterprises/test-enterprise/installation
`;
exports[`main-enterprise-mutual-exclusivity-owner.test.js > stderr 1`] = `
-Error: Cannot use 'enterprise' input with 'owner' or 'repositories' inputs
- at main (file:///lib/main.js::)
- at run (file:///main.js::)
- at file:///main.js::
- at ModuleJob.run (node:internal/modules/esm/module_job::)
- at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader::)
- at async file:///tests/main-enterprise-mutual-exclusivity-owner.test.js::
+[Error: Cannot use 'enterprise' input with 'owner' or 'repositories' inputs]
`;
exports[`main-enterprise-mutual-exclusivity-owner.test.js > stdout 1`] = `
@@ -106,13 +94,7 @@ exports[`main-enterprise-mutual-exclusivity-owner.test.js > stdout 1`] = `
`;
exports[`main-enterprise-mutual-exclusivity-repositories.test.js > stderr 1`] = `
-Error: Cannot use 'enterprise' input with 'owner' or 'repositories' inputs
- at main (file:///lib/main.js::)
- at run (file:///main.js::)
- at file:///main.js::
- at ModuleJob.run (node:internal/modules/esm/module_job::)
- at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader::)
- at async file:///tests/main-enterprise-mutual-exclusivity-repositories.test.js::
+[Error: Cannot use 'enterprise' input with 'owner' or 'repositories' inputs]
`;
exports[`main-enterprise-mutual-exclusivity-repositories.test.js > stdout 1`] = `
@@ -227,15 +209,7 @@ POST /app/installations/123456/access_tokens
`;
exports[`main-token-get-owner-set-client-error.test.js > stderr 1`] = `
-RequestError [HttpError]: Forbidden
- at fetchWrapper (file:///node_modules/@octokit/request/dist-bundle/index.js::)
- at process.processTicksAndRejections (node:internal/process/task_queues::)
- at async hook (file:///node_modules/@octokit/auth-app/dist-node/index.js::)
- at async getTokenFromOwner (file:///lib/main.js::)
- at async pRetry (file:///node_modules/p-retry/index.js::)
- at async main (file:///lib/main.js::)
- at async test (file:///tests/main.js::)
- at async file:///tests/main-token-get-owner-set-client-error.test.js:: {
+[RequestError [HttpError]: Forbidden] {
status: 403,
request: {
method: 'GET',
@@ -323,17 +297,7 @@ POST /app/installations/123456/access_tokens
`;
exports[`main-token-get-owner-set-repo-invalid-format.test.js > stderr 1`] = `
-Error: Invalid repository 'octocat/hello-world/extra'. Expected 'repository' or 'owner/repository'.
- at parseRepositoryInput (file:///lib/main.js::)
- at Array.map ()
- at normalizeRepositoryTarget (file:///lib/main.js::)
- at resolveInstallationTarget (file:///lib/main.js::)
- at main (file:///lib/main.js::)
- at run (file:///main.js::)
- at file:///main.js::
- at ModuleJob.run (node:internal/modules/esm/module_job::)
- at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader::)
- at async file:///tests/main-token-get-owner-set-repo-invalid-format.test.js::
+[Error: Invalid repository 'octocat/hello-world/extra'. Expected 'repository' or 'owner/repository'.]
`;
exports[`main-token-get-owner-set-repo-invalid-format.test.js > stdout 1`] = `
@@ -380,15 +344,7 @@ POST /app/installations/123456/access_tokens
`;
exports[`main-token-get-owner-set-repo-owner-mismatch.test.js > stderr 1`] = `
-Error: Repository 'octocat/hello-world' includes owner 'octocat', which does not match the resolved owner 'actions'.
- at normalizeRepositoryTarget (file:///lib/main.js::)
- at resolveInstallationTarget (file:///lib/main.js::)
- at main (file:///lib/main.js::)
- at run (file:///main.js::)
- at file:///main.js::
- at ModuleJob.run (node:internal/modules/esm/module_job::)
- at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader::)
- at async file:///tests/main-token-get-owner-set-repo-owner-mismatch.test.js::
+[Error: Repository 'octocat/hello-world' includes owner 'octocat', which does not match the resolved owner 'actions'.]
`;
exports[`main-token-get-owner-set-repo-owner-mismatch.test.js > stdout 1`] = `
@@ -490,15 +446,7 @@ POST /app/installations/123456/access_tokens
`;
exports[`main-token-get-owner-unset-repo-owner-mismatch.test.js > stderr 1`] = `
-Error: Repository 'octocat/hello-world' includes owner 'octocat', which does not match the resolved owner 'actions'.
- at normalizeRepositoryTarget (file:///lib/main.js::)
- at resolveInstallationTarget (file:///lib/main.js::)
- at main (file:///lib/main.js::)
- at run (file:///main.js::)
- at file:///main.js::
- at ModuleJob.run (node:internal/modules/esm/module_job::)
- at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader::)
- at async file:///tests/main-token-get-owner-unset-repo-owner-mismatch.test.js::
+[Error: Repository 'octocat/hello-world' includes owner 'octocat', which does not match the resolved owner 'actions'.]
`;
exports[`main-token-get-owner-unset-repo-owner-mismatch.test.js > stdout 1`] = `
From 575da866bd0a42d7f234a8645831d55573252b09 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 12 Oct 2026 15:41:52 -0700
Subject: [PATCH 22/29] build(deps): bump stefanzweifel/git-auto-commit-action
from 7.1.0 to 7.2.0 in the github-actions group across 1 directory (#383)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Bumps the github-actions group with 1 update in the / directory:
[stefanzweifel/git-auto-commit-action](https://github.com/stefanzweifel/git-auto-commit-action).
Updates `stefanzweifel/git-auto-commit-action` from 7.1.0 to 7.2.0
Release notes
Sourced from stefanzweifel/git-auto-commit-action's
releases.
v7.2.0
Added
Fixed
Dependency Updates
Changelog
Sourced from stefanzweifel/git-auto-commit-action's
changelog.
Changelog
All notable changes to this project will be documented in this
file.
The format is based on Keep a Changelog
and this project adheres to Semantic Versioning.
TBD
v7.2.0
- 2026-06-28
Added
Fixed
Dependency Updates
v7.1.0
- 2025-12-17
Added
Changes
Dependency Updates
v7.0.0
- 2025-10-12
Added
... (truncated)
Commits
4a55954
Update README.md
9f6c933
Add hooks to run shell snippets around git operations (#411)
c365a74
Emit warning for pull_request_target trigger usage (#410)
d28176c
Bump actions/checkout from 6 to 7 (#409)
25df622
Add EXAMPLES.md
32e9844
docs(action): fix input and output descriptions in action.yml (#406)
a3ed46f
docs: fix typos, grammar, and formatting across markdown files (#408)
b4d688c
docs: fix broken and redirecting URLs in README.md (#407)
f53a62c
README: clearify meaning of the repository field (#404)
4fc4bbf
Bump release-drafter/release-drafter from 6 to 7 (#403)
- Additional commits viewable in compare
view
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
.github/workflows/release.yml | 2 +-
.github/workflows/update-permission-inputs.yml | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index ac5d7c4f..99a690b5 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -51,7 +51,7 @@ jobs:
- run: npm run build
if: steps.release-please.outputs.prs_created == 'true'
- - uses: stefanzweifel/git-auto-commit-action@04702edda442b2e678b25b537cec683a1493fcb9 # v7.1.0
+ - uses: stefanzweifel/git-auto-commit-action@4a55954c782fc1ea30b9056cd3e7a2b40ca8887d # v7.2.0
if: steps.release-please.outputs.prs_created == 'true'
with:
commit_author: "${{ github.actor }} <${{ github.actor_id }}+${{ github.actor }}@users.noreply.github.com>"
diff --git a/.github/workflows/update-permission-inputs.yml b/.github/workflows/update-permission-inputs.yml
index daad54f0..c6492bd0 100644
--- a/.github/workflows/update-permission-inputs.yml
+++ b/.github/workflows/update-permission-inputs.yml
@@ -31,7 +31,7 @@ jobs:
run: node scripts/update-permission-inputs.js
- name: Commit changes
id: auto-commit
- uses: stefanzweifel/git-auto-commit-action@04702edda442b2e678b25b537cec683a1493fcb9 # v7.1.0
+ uses: stefanzweifel/git-auto-commit-action@4a55954c782fc1ea30b9056cd3e7a2b40ca8887d # v7.2.0
with:
commit_message: ${{ env.COMMIT_MESSAGE }}
- name: Update PR title
From d5cb7ae41d64331820d88810a4878e0942ec992a Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 12 Oct 2026 15:43:24 -0700
Subject: [PATCH 23/29] build(deps): bump actions/checkout from 6 to 7 (#384)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Bumps [actions/checkout](https://github.com/actions/checkout) from 6 to
7.
Release notes
Sourced from actions/checkout's
releases.
v7.0.0
What's Changed
New Contributors
Full Changelog: https://github.com/actions/checkout/compare/v6.0.3...v7.0.0
v6.1.0
What's Changed
https://github.blog/changelog/2026-06-18-safer-pull_request_target-defaults-for-github-actions-checkout/
for more details about this breaking change
Full Changelog: https://github.com/actions/checkout/compare/v6.0.3...v6.1.0
v6.0.3
What's Changed
New Contributors
Full Changelog: https://github.com/actions/checkout/compare/v6...v6.0.3
v6.0.2
What's Changed
Full Changelog: https://github.com/actions/checkout/compare/v6.0.1...v6.0.2
v6.0.1
What's Changed
... (truncated)
Changelog
Sourced from actions/checkout's
changelog.
Changelog
v7.0.1
v7.0.0
v6.0.3
v6.0.2
v6.0.1
v6.0.0
v5.0.1
v5.0.0
v4.3.1
v4.3.0
v4.2.2
v4.2.1
... (truncated)
Commits
> **Note**
> Automatic rebases have been disabled on this pull request as it has
been open for over 30 days.
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
.github/workflows/release.yml | 4 ++--
.github/workflows/test.yml | 6 +++---
.github/workflows/update-permission-inputs.yml | 2 +-
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 99a690b5..11564e82 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -18,7 +18,7 @@ jobs:
name: release
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v6
+ - uses: actions/checkout@v7
- uses: ./
id: app-token
@@ -34,7 +34,7 @@ jobs:
manifest-file: .release-please-manifest.json
target-branch: ${{ github.ref_name }}
- - uses: actions/checkout@v6
+ - uses: actions/checkout@v7
if: steps.release-please.outputs.prs_created == 'true'
with:
ref: ${{ fromJSON(steps.release-please.outputs.pr).headBranchName }}
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index bd35e0eb..717e743b 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -21,7 +21,7 @@ jobs:
name: integration
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v6
+ - uses: actions/checkout@v7
- uses: actions/setup-node@v6
with:
@@ -36,7 +36,7 @@ jobs:
# do not run from forks, as forks don’t have access to repository secrets
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.owner.login == github.event.pull_request.base.repo.owner.login
steps:
- - uses: actions/checkout@v6
+ - uses: actions/checkout@v7
- uses: actions/setup-node@v6
with:
node-version-file: package.json
@@ -61,7 +61,7 @@ jobs:
# do not run from forks, as forks don’t have access to repository secrets
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.owner.login == github.event.pull_request.base.repo.owner.login
steps:
- - uses: actions/checkout@v6
+ - uses: actions/checkout@v7
- uses: actions/setup-node@v6
with:
node-version-file: package.json
diff --git a/.github/workflows/update-permission-inputs.yml b/.github/workflows/update-permission-inputs.yml
index c6492bd0..da49f429 100644
--- a/.github/workflows/update-permission-inputs.yml
+++ b/.github/workflows/update-permission-inputs.yml
@@ -21,7 +21,7 @@ jobs:
env:
COMMIT_MESSAGE: 'feat: update permission inputs'
steps:
- - uses: actions/checkout@v6
+ - uses: actions/checkout@v7
- uses: actions/setup-node@v6
with:
node-version-file: package.json
From a69c19ddfdf8e1ab093900e0064524ce9309c807 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 12 Oct 2026 15:45:15 -0700
Subject: [PATCH 24/29] fix(deps): bump the production-dependencies group
across 1 directory with 3 updates (#395)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Bumps the production-dependencies group with 3 updates in the /
directory: [@octokit/auth-app](https://github.com/octokit/auth-app.js),
[@octokit/request](https://github.com/octokit/request.js) and
[p-retry](https://github.com/sindresorhus/p-retry).
Updates `@octokit/auth-app` from 8.2.0 to 8.3.1
Release notes
Sourced from @octokit/auth-app's
releases.
v8.3.1
8.3.1
(2026-09-01)
Bug Fixes
- deps: update dependency
@octokit/types to v18 (#761)
(2bb6310)
v8.3.0
8.3.0
(2026-08-02)
Features
- deps: allow bigint (int64) repository IDs and
update dependency
@octokit/types to v17 (#759)
(3df5506)
Commits
2bb6310
fix(deps): update dependency @octokit/types to v18 (#761)
2327287
chore(deps): update dependency typescript to v7 (#755)
3df5506
feat(deps): allow bigint (int64) repository IDs and update dependency @octoki...
9d2ec47
ci(action): update actions/checkout action to v7 (#754)
d149272
build(deps): lock file maintenance (#758)
653732f
build(deps): lock file maintenance (#753)
b898bcf
chore(deps): update dependency esbuild to ^0.28.0 [security] (#751)
9e34287
build(deps): lock file maintenance (#743)
fdf6833
chore(deps): update dependency prettier to v3.8.1 (#735)
50cd126
chore(deps): update dependency fetch-mock to v12 (#649)
- Additional commits viewable in compare
view
Updates `@octokit/request` from 10.0.8 to 10.0.16
Release notes
Sourced from @octokit/request's
releases.
v10.0.16
Bug Fixes
- deps: update dependency
@octokit/types to v18 (#834)
(723070e)
v10.0.15
Bug Fixes
- deps: update dependency content-type to v3 (#833)
(963f5fb)
v10.0.14
Bug Fixes
- deps: update dependency json-with-bigint and undici
[security] (#830)
(9e5fee0),
fixes #831
v10.0.13
Bug Fixes
- deps: update dependency
@octokit/types to v17 (#828)
(e127cfe)
v10.0.12
Bug Fixes
- don't decode application/octet-stream as text when charset is utf-8
(#823)
(facf3cb),
closes #751
v10.0.11
Bug Fixes
- handle primitive JSON error bodies without throwing (#820)
(554e102),
closes #819
v10.0.10
... (truncated)
Commits
723070e
fix(deps): update dependency @octokit/types to v18 (#834)
963f5fb
fix(deps): update dependency content-type to v3 (#833)
f9b5147
chore(deps): update dependency typescript to v7 (#822)
9e5fee0
fix(deps): update dependency json-with-bigint and undici [security] (#830)
3a99e00
chore(deps): update dependency prettier to v3.9.6 (#794)
9282200
ci(action): update actions/checkout action to v7 (#812)
e127cfe
fix(deps): update dependency @octokit/types to v17 (#828)
deadf90
ci(action): update actions/setup-node action to v7 (#824)
facf3cb
fix: don't decode application/octet-stream as text when charset is utf-8
(#823)
554e102
fix: handle primitive JSON error bodies without throwing (#820)
- Additional commits viewable in compare
view
Updates `p-retry` from 8.0.0 to 8.0.1
Release notes
Sourced from p-retry's
releases.
v8.0.1
- Fix error for invalid fractional retry counts 3c22035
https://github.com/sindresorhus/p-retry/compare/v8.0.0...v8.0.1
Commits
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
package-lock.json | 159 +++++++++++++++++++++++-----------------------
package.json | 4 +-
2 files changed, 80 insertions(+), 83 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index b8fd0445..1da661a6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,10 +10,10 @@
"license": "MIT",
"dependencies": {
"@actions/core": "^3.0.1",
- "@octokit/auth-app": "^8.2.0",
+ "@octokit/auth-app": "^8.3.1",
"@octokit/request": "^10.0.8",
"is-network-error": "^1.3.2",
- "p-retry": "^8.0.0"
+ "p-retry": "^8.0.1"
},
"devDependencies": {
"@octokit/openapi": "^22.0.0",
@@ -569,16 +569,16 @@
}
},
"node_modules/@octokit/auth-app": {
- "version": "8.2.0",
- "resolved": "https://registry.npmjs.org/@octokit/auth-app/-/auth-app-8.2.0.tgz",
- "integrity": "sha512-vVjdtQQwomrZ4V46B9LaCsxsySxGoHsyw6IYBov/TqJVROrlYdyNgw5q6tQbB7KZt53v1l1W53RiqTvpzL907g==",
+ "version": "8.3.1",
+ "resolved": "https://registry.npmjs.org/@octokit/auth-app/-/auth-app-8.3.1.tgz",
+ "integrity": "sha512-XHWxZsF4mvGTQCv7AOxgby9t9OjVO19FBuKq+QmyBxFrf+B2hR/P5j/MTF8g95bITf8cRtR17KIXThpFNqiKbg==",
"license": "MIT",
"dependencies": {
- "@octokit/auth-oauth-app": "^9.0.3",
- "@octokit/auth-oauth-user": "^6.0.2",
- "@octokit/request": "^10.0.6",
- "@octokit/request-error": "^7.0.2",
- "@octokit/types": "^16.0.0",
+ "@octokit/auth-oauth-app": "^9.0.5",
+ "@octokit/auth-oauth-user": "^6.0.4",
+ "@octokit/request": "^10.0.16",
+ "@octokit/request-error": "^7.1.2",
+ "@octokit/types": "^18.0.0",
"toad-cache": "^3.7.0",
"universal-github-app-jwt": "^2.2.0",
"universal-user-agent": "^7.0.0"
@@ -588,15 +588,15 @@
}
},
"node_modules/@octokit/auth-oauth-app": {
- "version": "9.0.3",
- "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-app/-/auth-oauth-app-9.0.3.tgz",
- "integrity": "sha512-+yoFQquaF8OxJSxTb7rnytBIC2ZLbLqA/yb71I4ZXT9+Slw4TziV9j/kyGhUFRRTF2+7WlnIWsePZCWHs+OGjg==",
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-app/-/auth-oauth-app-9.0.5.tgz",
+ "integrity": "sha512-Hn2yAlIDjFLGjAz7t+CRu7e9VYoFW1W3LLyOLyahFoJGlCf4PtDkHKtRET8w/2CJpsrC0FxIF5g5Xtx9E4O78w==",
"license": "MIT",
"dependencies": {
- "@octokit/auth-oauth-device": "^8.0.3",
- "@octokit/auth-oauth-user": "^6.0.2",
- "@octokit/request": "^10.0.6",
- "@octokit/types": "^16.0.0",
+ "@octokit/auth-oauth-device": "^8.0.5",
+ "@octokit/auth-oauth-user": "^6.0.4",
+ "@octokit/request": "^10.0.16",
+ "@octokit/types": "^18.0.0",
"universal-user-agent": "^7.0.0"
},
"engines": {
@@ -604,14 +604,14 @@
}
},
"node_modules/@octokit/auth-oauth-device": {
- "version": "8.0.3",
- "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-device/-/auth-oauth-device-8.0.3.tgz",
- "integrity": "sha512-zh2W0mKKMh/VWZhSqlaCzY7qFyrgd9oTWmTmHaXnHNeQRCZr/CXy2jCgHo4e4dJVTiuxP5dLa0YM5p5QVhJHbw==",
+ "version": "8.0.5",
+ "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-device/-/auth-oauth-device-8.0.5.tgz",
+ "integrity": "sha512-kdJtjRhykMLJrMdcoC56XUBDfoUAuWEFKpkDxwYim+bNwYw1MreLolk+PLnwEYT8djm589YepeMuJ8+ECAIzVQ==",
"license": "MIT",
"dependencies": {
- "@octokit/oauth-methods": "^6.0.2",
- "@octokit/request": "^10.0.6",
- "@octokit/types": "^16.0.0",
+ "@octokit/oauth-methods": "^6.0.5",
+ "@octokit/request": "^10.0.16",
+ "@octokit/types": "^18.0.0",
"universal-user-agent": "^7.0.0"
},
"engines": {
@@ -619,15 +619,15 @@
}
},
"node_modules/@octokit/auth-oauth-user": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-user/-/auth-oauth-user-6.0.2.tgz",
- "integrity": "sha512-qLoPPc6E6GJoz3XeDG/pnDhJpTkODTGG4kY0/Py154i/I003O9NazkrwJwRuzgCalhzyIeWQ+6MDvkUmKXjg/A==",
+ "version": "6.0.4",
+ "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-user/-/auth-oauth-user-6.0.4.tgz",
+ "integrity": "sha512-eya2pMJ9pCBq1jrm1Rf6J3NI+NemEpzDMLo9J/GpRoK0KgdxIVXWX4LESIfwJ+GYeoq6QFIlUJNi1lVp5FBgmw==",
"license": "MIT",
"dependencies": {
- "@octokit/auth-oauth-device": "^8.0.3",
- "@octokit/oauth-methods": "^6.0.2",
- "@octokit/request": "^10.0.6",
- "@octokit/types": "^16.0.0",
+ "@octokit/auth-oauth-device": "^8.0.5",
+ "@octokit/oauth-methods": "^6.0.5",
+ "@octokit/request": "^10.0.16",
+ "@octokit/types": "^18.0.0",
"universal-user-agent": "^7.0.0"
},
"engines": {
@@ -635,12 +635,12 @@
}
},
"node_modules/@octokit/endpoint": {
- "version": "11.0.3",
- "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-11.0.3.tgz",
- "integrity": "sha512-FWFlNxghg4HrXkD3ifYbS/IdL/mDHjh9QcsNyhQjN8dplUoZbejsdpmuqdA76nxj2xoWPs7p8uX2SNr9rYu0Ag==",
+ "version": "11.0.5",
+ "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-11.0.5.tgz",
+ "integrity": "sha512-iXa654H3yFafF/ieHkukfbgWo2rmXD2ceD0ZOtrPhw1bc3FDch1d9N/TNs0FQ1/cIbwb7kspUX8jzIs8nzb9DQ==",
"license": "MIT",
"dependencies": {
- "@octokit/types": "^16.0.0",
+ "@octokit/types": "^18.0.0",
"universal-user-agent": "^7.0.2"
},
"engines": {
@@ -657,15 +657,15 @@
}
},
"node_modules/@octokit/oauth-methods": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/@octokit/oauth-methods/-/oauth-methods-6.0.2.tgz",
- "integrity": "sha512-HiNOO3MqLxlt5Da5bZbLV8Zarnphi4y9XehrbaFMkcoJ+FL7sMxH/UlUsCVxpddVu4qvNDrBdaTVE2o4ITK8ng==",
+ "version": "6.0.5",
+ "resolved": "https://registry.npmjs.org/@octokit/oauth-methods/-/oauth-methods-6.0.5.tgz",
+ "integrity": "sha512-/mAz7taDZD7DcV4zcG6TDw3Kr6TOldmYBRpvA62C3WIxRMmcgX8XxsTvVQomqKE7VEk/BgYhUao1aR2tYGyIKg==",
"license": "MIT",
"dependencies": {
"@octokit/oauth-authorization-url": "^8.0.0",
- "@octokit/request": "^10.0.6",
- "@octokit/request-error": "^7.0.2",
- "@octokit/types": "^16.0.0"
+ "@octokit/request": "^10.0.16",
+ "@octokit/request-error": "^7.1.2",
+ "@octokit/types": "^18.0.0"
},
"engines": {
"node": ">= 20"
@@ -682,22 +682,22 @@
}
},
"node_modules/@octokit/openapi-types": {
- "version": "27.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-27.0.0.tgz",
- "integrity": "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA==",
+ "version": "29.0.1",
+ "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-29.0.1.tgz",
+ "integrity": "sha512-9qWOMFNxxLokERcms42rU0PTLqQmVs7g5E41TI4mCOxmpFayD1rfC7XxOL55cG9MBZLFlC31BrR37myMKardwg==",
"license": "MIT"
},
"node_modules/@octokit/request": {
- "version": "10.0.8",
- "resolved": "https://registry.npmjs.org/@octokit/request/-/request-10.0.8.tgz",
- "integrity": "sha512-SJZNwY9pur9Agf7l87ywFi14W+Hd9Jg6Ifivsd33+/bGUQIjNujdFiXII2/qSlN2ybqUHfp5xpekMEjIBTjlSw==",
+ "version": "10.0.16",
+ "resolved": "https://registry.npmjs.org/@octokit/request/-/request-10.0.16.tgz",
+ "integrity": "sha512-A0zWGjHzISIb+9ccG8s0dq7LKO5zVpJLRICjgUb+sJxEWqn8RUHB1rD3AE51+PECvXHIxqZ1VVvs4fHTSD9nUQ==",
"license": "MIT",
"dependencies": {
- "@octokit/endpoint": "^11.0.3",
- "@octokit/request-error": "^7.0.2",
- "@octokit/types": "^16.0.0",
- "fast-content-type-parse": "^3.0.0",
- "json-with-bigint": "^3.5.3",
+ "@octokit/endpoint": "^11.0.5",
+ "@octokit/request-error": "^7.1.2",
+ "@octokit/types": "^18.0.0",
+ "content-type": "^3.0.0",
+ "json-with-bigint": "^3.5.12",
"universal-user-agent": "^7.0.2"
},
"engines": {
@@ -705,24 +705,24 @@
}
},
"node_modules/@octokit/request-error": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-7.1.0.tgz",
- "integrity": "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw==",
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-7.1.2.tgz",
+ "integrity": "sha512-XZRuT3xZ84D3gYErI1DZvhJ33dCWVV6uzBtWkaBB4TvA/L6eOeTZodxLFVB44bBEEo3vEx7y00UfX1tBLrtLRg==",
"license": "MIT",
"dependencies": {
- "@octokit/types": "^16.0.0"
+ "@octokit/types": "^18.0.0"
},
"engines": {
"node": ">= 20"
}
},
"node_modules/@octokit/types": {
- "version": "16.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/types/-/types-16.0.0.tgz",
- "integrity": "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==",
+ "version": "18.0.0",
+ "resolved": "https://registry.npmjs.org/@octokit/types/-/types-18.0.0.tgz",
+ "integrity": "sha512-l6bAF43PNxkJp6g+W4PjoUSSkxHomXw2nOum5CTftJz1NlV3vu93NImgOYtLf6CbBUb5j+fiuzW0PPQ5JTSvZA==",
"license": "MIT",
"dependencies": {
- "@octokit/openapi-types": "^27.0.0"
+ "@octokit/openapi-types": "^29.0.1"
}
},
"node_modules/@tokenizer/inflate": {
@@ -888,6 +888,19 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/content-type": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-3.1.1.tgz",
+ "integrity": "sha512-GW4qUsfFo59d0HbUibDlWv5wPz+vAAcaTWbKIuKCf0JkC7wWkSyf8f13IpXn5JkeMlB2P8iTSSIjwXljorg2vA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=22"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
"node_modules/convert-source-map": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
@@ -1058,22 +1071,6 @@
"node": ">=6"
}
},
- "node_modules/fast-content-type-parse": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-3.0.0.tgz",
- "integrity": "sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/fastify"
- },
- {
- "type": "opencollective",
- "url": "https://opencollective.com/fastify"
- }
- ],
- "license": "MIT"
- },
"node_modules/file-type": {
"version": "21.3.4",
"resolved": "https://registry.npmjs.org/file-type/-/file-type-21.3.4.tgz",
@@ -1351,9 +1348,9 @@
}
},
"node_modules/json-with-bigint": {
- "version": "3.5.7",
- "resolved": "https://registry.npmjs.org/json-with-bigint/-/json-with-bigint-3.5.7.tgz",
- "integrity": "sha512-7ei3MdAI5+fJPVnKlW77TKNKwQ5ppSzWvhPuSuINT/GYW9ZOC1eRKOuhV9yHG5aEsUPj9BBx5JIekkmoLHxZOw==",
+ "version": "3.5.12",
+ "resolved": "https://registry.npmjs.org/json-with-bigint/-/json-with-bigint-3.5.12.tgz",
+ "integrity": "sha512-uwbF/wSSuOgC7qqlq27Xp5B6a2MHVug3t0idZdTqu0JnlFvgJuH7ju+KAk/J06C7GfhoYy2gnb9wz2INqcne7w==",
"license": "MIT"
},
"node_modules/locate-path": {
@@ -1501,9 +1498,9 @@
}
},
"node_modules/p-retry": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-8.0.0.tgz",
- "integrity": "sha512-kFVqH1HxOHp8LupNsOys7bSV09VYTRLxarH/mokO4Rqhk6wGi70E0jh4VzvVGXfEVNggHoHLAMWsQqHyU1Ey9A==",
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-8.0.1.tgz",
+ "integrity": "sha512-NAigyu8hfvJe7MsS18mnc4is0MZtau3QMdBklaJKK23oBQb6occO3UPM3vHmTckW8KhfyjMZaUOqdTFEYliHgg==",
"license": "MIT",
"dependencies": {
"is-network-error": "^1.3.0"
diff --git a/package.json b/package.json
index 45f336e8..20c2f750 100644
--- a/package.json
+++ b/package.json
@@ -17,10 +17,10 @@
"license": "MIT",
"dependencies": {
"@actions/core": "^3.0.1",
- "@octokit/auth-app": "^8.2.0",
+ "@octokit/auth-app": "^8.3.1",
"@octokit/request": "^10.0.8",
"is-network-error": "^1.3.2",
- "p-retry": "^8.0.0"
+ "p-retry": "^8.0.1"
},
"devDependencies": {
"@octokit/openapi": "^22.0.0",
From a47236f79f79fcbc3532af49fe3a5ded89529b6e Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 12 Oct 2026 15:52:54 -0700
Subject: [PATCH 25/29] feat: update permission inputs (#399)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Bumps [@octokit/openapi](https://github.com/octokit/openapi) from 22.0.0
to 24.0.0.
Release notes
Sourced from @octokit/openapi's
releases.
v24.0.0
24.0.0
(2026-10-05)
Features
- delete teams related endpoints, add new endpoints (as of 2026-10-05)
(#542)
(f1e85dc)
BREAKING CHANGES
- Remove the Enterprise Teams REST API endpoints under
/enterprises/{enterprise}/teams.
Co-authored-by: octokit[bot] <171388558+octokit[bot]@users.noreply.github.com>
Co-authored-by: wolfy1339 webmaster@wolfy1339.com
v23.0.3
23.0.3
(2026-10-05)
Bug Fixes
- patch app-installations anyOf in place instead of replacing the
operation (#544)
(c0c9994)
v23.0.2
23.0.2
(2026-09-09)
Bug Fixes
v23.0.1
23.0.1
(2026-08-29)
Bug Fixes
- remove requestBody when no schema is present (#532)
(a0a73ee)
v23.0.0
23.0.0
(2026-08-27)
- feat!: remove deprecated endpoints, major additions up to 2026-08-24
(#538)
(8dda528)
New Endpoints
- GET /agents/repos/{owner}/{repo}/tasks
- POST /agents/repos/{owner}/{repo}/tasks
- GET /agents/repos/{owner}/{repo}/tasks/{task_id}
- GET /agents/tasks
... (truncated)
Commits
f1e85dc
feat: delete teams related endpoints, add new endpoints (as of
2026-10-05) (#...
c0c9994
fix: patch app-installations anyOf in place instead of replacing the
operatio...
da1aaff
ci(action): update actions/checkout action to v7 (#535)
bcfdbca
fix: temporarily hardcode GHES versions (#540)
a0a73ee
fix: remove requestBody when no schema is present (#532)
8dda528
feat!: remove deprecated endpoints, major additions up to 2026-08-24 (#538)
52f0709
ci(action): update actions/add-to-project action to v2 (#534)
dd22170
ci(action): update actions/setup-node action to v7 (#536)
4c6354a
ci(action): update actions/create-github-app-token action to v3 (#525)
7b4325a
build(deps): lock file maintenance (#526)
- Additional commits viewable in compare
view
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
---------
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Parker Brown <17183625+parkerbxyz@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b1df02be-7b54-4bb7-b981-89dea6a89274
---
action.yml | 10 ++++---
package-lock.json | 8 +++---
package.json | 2 +-
scripts/generated/app-permissions.json | 36 +++++++++++++++++++-------
4 files changed, 39 insertions(+), 17 deletions(-)
diff --git a/action.yml b/action.yml
index 9f45ab3e..c6c0f607 100644
--- a/action.yml
+++ b/action.yml
@@ -44,6 +44,8 @@ inputs:
description: "The level of permission to create and retrieve the access token for repository attestations. Can be set to 'read' or 'write'."
permission-checks:
description: "The level of permission to grant the access token for checks on code. Can be set to 'read' or 'write'."
+ permission-code-quality:
+ description: "The level of permission to grant the access token to view and manage code quality data. Can be set to 'read' or 'write'."
permission-codespaces:
description: "The level of permission to grant the access token to create, edit, delete, and list Codespaces. Can be set to 'read' or 'write'."
permission-contents:
@@ -82,8 +84,10 @@ inputs:
description: "The level of permission to grant the access token to manage access to an organization. Can be set to 'read' or 'write'."
permission-organization-announcement-banners:
description: "The level of permission to grant the access token to view and manage announcement banners for an organization. Can be set to 'read' or 'write'."
+ permission-organization-copilot-agent-settings:
+ description: "The level of permission to grant the access token to view and manage Copilot cloud agent settings for an organization. Can be set to 'read' or 'write'."
permission-organization-copilot-seat-management:
- description: "The level of permission to grant the access token for managing access to GitHub Copilot for members of an organization with a Copilot Business subscription. This property is in public preview and is subject to change. Can be set to 'write'."
+ description: "The level of permission to grant the access token for managing access to GitHub Copilot for members of an organization with a Copilot Business subscription. This property is in public preview and is subject to change. Can be set to 'read' or 'write'."
permission-organization-custom-org-roles:
description: "The level of permission to grant the access token for custom organization roles management. Can be set to 'read' or 'write'."
permission-organization-custom-properties:
@@ -92,6 +96,8 @@ inputs:
description: "The level of permission to grant the access token for custom repository roles management. Can be set to 'read' or 'write'."
permission-organization-events:
description: "The level of permission to grant the access token to view events triggered by an activity in an organization. Can be set to 'read'."
+ permission-organization-external-properties-for-repos:
+ description: "The level of permission to grant the access token for managing external custom properties for repositories in an organization. Can be set to 'read', 'write', or 'admin'."
permission-organization-hooks:
description: "The level of permission to grant the access token to manage the post-receive hooks for an organization. Can be set to 'read' or 'write'."
permission-organization-packages:
@@ -136,8 +142,6 @@ inputs:
description: "The level of permission to grant the access token to list and manage repositories a user is starring. Can be set to 'read' or 'write'."
permission-statuses:
description: "The level of permission to grant the access token for commit statuses. Can be set to 'read' or 'write'."
- permission-team-discussions:
- description: "The level of permission to grant the access token to manage team discussions and related comments. Can be set to 'read' or 'write'."
permission-vulnerability-alerts:
description: "The level of permission to grant the access token to manage Dependabot alerts. Can be set to 'read' or 'write'."
permission-workflows:
diff --git a/package-lock.json b/package-lock.json
index 1da661a6..cad2de46 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -16,7 +16,7 @@
"p-retry": "^8.0.1"
},
"devDependencies": {
- "@octokit/openapi": "^22.0.0",
+ "@octokit/openapi": "^24.0.0",
"c8": "^12.0.0",
"esbuild": "^0.28.2",
"open-cli": "^9.0.0",
@@ -672,9 +672,9 @@
}
},
"node_modules/@octokit/openapi": {
- "version": "22.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/openapi/-/openapi-22.0.0.tgz",
- "integrity": "sha512-Rpif7FjTjFEBSU+amIRHUAIAHwgg+tVJdTiQuU2GEWDniZxmWjxZCgJ4V9GEp2GXnq/Bl+TrjEvwAl9PB29NAQ==",
+ "version": "24.0.0",
+ "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@octokit/openapi/-/openapi-24.0.0.tgz",
+ "integrity": "sha512-KIpEIm6oND1tyTT3m/xyJZVJuduifs9BKLevaIjm+MBheg4ossTzLrx2leNgJoXccoIx5SjGGH/Esu/yecjirg==",
"dev": true,
"license": "MIT",
"engines": {
diff --git a/package.json b/package.json
index 20c2f750..5b99346e 100644
--- a/package.json
+++ b/package.json
@@ -23,7 +23,7 @@
"p-retry": "^8.0.1"
},
"devDependencies": {
- "@octokit/openapi": "^22.0.0",
+ "@octokit/openapi": "^24.0.0",
"c8": "^12.0.0",
"esbuild": "^0.28.2",
"open-cli": "^9.0.0",
diff --git a/scripts/generated/app-permissions.json b/scripts/generated/app-permissions.json
index d66d70cb..14402029 100644
--- a/scripts/generated/app-permissions.json
+++ b/scripts/generated/app-permissions.json
@@ -1,7 +1,7 @@
{
"title": "App Permissions",
"type": "object",
- "description": "The permissions granted to the user access token.",
+ "description": "The permissions granted to the fine-grained access token.",
"properties": {
"actions": {
"type": "string",
@@ -43,6 +43,14 @@
"write"
]
},
+ "code_quality": {
+ "type": "string",
+ "description": "The level of permission to grant the access token to view and manage code quality data.",
+ "enum": [
+ "read",
+ "write"
+ ]
+ },
"codespaces": {
"type": "string",
"description": "The level of permission to grant the access token to create, edit, delete, and list Codespaces.",
@@ -272,9 +280,27 @@
"type": "string",
"description": "The level of permission to grant the access token for managing access to GitHub Copilot for members of an organization with a Copilot Business subscription. This property is in public preview and is subject to change.",
"enum": [
+ "read",
+ "write"
+ ]
+ },
+ "organization_copilot_agent_settings": {
+ "type": "string",
+ "description": "The level of permission to grant the access token to view and manage Copilot cloud agent settings for an organization.",
+ "enum": [
+ "read",
"write"
]
},
+ "organization_external_properties_for_repos": {
+ "type": "string",
+ "description": "The level of permission to grant the access token for managing external custom properties for repositories in an organization.",
+ "enum": [
+ "read",
+ "write",
+ "admin"
+ ]
+ },
"organization_announcement_banners": {
"type": "string",
"description": "The level of permission to grant the access token to view and manage announcement banners for an organization.",
@@ -362,14 +388,6 @@
"write"
]
},
- "team_discussions": {
- "type": "string",
- "description": "The level of permission to grant the access token to manage team discussions and related comments.",
- "enum": [
- "read",
- "write"
- ]
- },
"email_addresses": {
"type": "string",
"description": "The level of permission to grant the access token to manage the email addresses belonging to a user.",
From 12461a3a794e67c032f1eff5bb95ece9427eb4fb Mon Sep 17 00:00:00 2001
From: Parker Brown <17183625+parkerbxyz@users.noreply.github.com>
Date: Mon, 12 Oct 2026 16:05:53 -0700
Subject: [PATCH 26/29] fix(deps): bump nested undici from 6.24.0 to 6.29.0
(#403)
Updates the copy of `undici` nested under `@actions/http-client`, which
`@actions/core` depends on, from 6.24.0 to 6.29.0. That's still within
`@actions/http-client`'s `^6.23.0` range.
Dependabot can't update this copy on its own because `undici@8` is also
a direct dev dependency. This PR runs `npm update undici`, which updates
it. The release PR will rebuild `dist/`.
- `npm ls undici` now shows `undici@6.29.0` under `@actions/http-client`
and `undici@8.11.2` at the top level.
- `npm test` passes with 100% coverage.
---------
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 4cae10ea-f068-4e95-983b-af39d7e7e065
---
package-lock.json | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index cad2de46..368387d5 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -57,9 +57,9 @@
}
},
"node_modules/@actions/http-client/node_modules/undici": {
- "version": "6.24.0",
- "resolved": "https://registry.npmjs.org/undici/-/undici-6.24.0.tgz",
- "integrity": "sha512-lVLNosgqo5EkGqh5XUDhGfsMSoO8K0BAN0TyJLvwNRSl4xWGZlCVYsAIpa/OpA3TvmnM01GWcoKmc3ZWo5wKKA==",
+ "version": "6.29.0",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-6.29.0.tgz",
+ "integrity": "sha512-R+RODBqp6i2pPflGdq+xIOUkl+RNfGgHwoinecKu/JCuf2uO06cOKoDbI2P7Dn6KcswdKwrczbU6IYJ6K8X+wg==",
"license": "MIT",
"engines": {
"node": ">=18.17"
From 655017ffa7c6b0c6e4210729fa6bce35cacd8ca0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20Str=C3=BCbe?=
Date: Tue, 13 Oct 2026 01:37:47 +0200
Subject: [PATCH 27/29] docs: clarify when owner grants access to all
repositories (#378)
Clarifies the `repositories` note in the README: the token gets access
to all repositories in the installation only when `owner` is set
explicitly. Leaving `owner` empty scopes the token to the current
repository, even though `owner` defaults to the current repository
owner. Fixes #377.
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 00ca19dd..dfe92e60 100644
--- a/README.md
+++ b/README.md
@@ -386,7 +386,7 @@ steps:
**Optional:** Comma or newline-separated list of repositories to grant access to.
> [!NOTE]
-> If `owner` is set and `repositories` is empty, access will be scoped to all repositories in the provided repository owner's installation. If `owner` and `repositories` are empty, access will be scoped to only the current repository.
+> If `owner` is set explicitly and `repositories` is empty, access will be scoped to all repositories in the provided repository owner's installation. If `owner` and `repositories` are empty, access will be scoped to only the current repository.
>
> Repository entries may include an owner, for example `owner/repo1`. The owner portion must match the `owner` input, or the current repository owner if `owner` is unset.
From f3a828e4b91180d3a46ac1f4b43fa8384b0dea07 Mon Sep 17 00:00:00 2001
From: Parker Brown <17183625+parkerbxyz@users.noreply.github.com>
Date: Mon, 12 Oct 2026 16:40:31 -0700
Subject: [PATCH 28/29] ci: create signed dist commits in release workflow
(#404)
The `main` ruleset requires verified signatures, but the "chore: update
dist files" commit on release-please PRs isn't signed.
`git-auto-commit-action` creates it with plain `git push`. [Unsigned
commits on the head branch can block squash merges
too](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/available-rules-for-rulesets#require-signed-commits),
so the dist commit itself needs a signature.
This replaces `git-auto-commit-action` with
[`dsanders11/github-app-commit-action`](https://github.com/dsanders11/github-app-commit-action),
pinned to the v2.1.0 commit SHA. It creates the commit through the REST
Git Data API with the releaser app token, and GitHub signs commits that
a GitHub App creates that way.
- A new `git add dist` step stages the rebuilt files. The action commits
only staged changes, so this replaces `file_pattern: dist/**`.
- `commit_author` is removed. GitHub signs API commits only when they
don't set a custom author, so the commit is now authored by the releaser
app instead of `github.actor`.
- `fail-on-no-changes: false` keeps the old behavior of skipping the
commit when dist didn't change.
The action uploads files as blobs, so the roughly 900 KB bundles aren't
a problem. The releaser app token is still needed: if the commit used
`GITHUB_TOKEN`, `test` wouldn't run on release PRs.
The first release run after merging will confirm the commit shows as
verified.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: c91009d9-b4f7-4eec-b30f-4b24ae578aa1
---
.github/workflows/release.yml | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 11564e82..3ce40fe1 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -51,12 +51,15 @@ jobs:
- run: npm run build
if: steps.release-please.outputs.prs_created == 'true'
- - uses: stefanzweifel/git-auto-commit-action@4a55954c782fc1ea30b9056cd3e7a2b40ca8887d # v7.2.0
+ - run: git add dist
+ if: steps.release-please.outputs.prs_created == 'true'
+
+ - uses: dsanders11/github-app-commit-action@2bbcd331016d8c950b05a24b56e7eb9cb50d545e # v2.1.0
if: steps.release-please.outputs.prs_created == 'true'
with:
- commit_author: "${{ github.actor }} <${{ github.actor_id }}+${{ github.actor }}@users.noreply.github.com>"
- commit_message: "chore: update dist files"
- file_pattern: dist/**
+ message: "chore: update dist files"
+ token: ${{ steps.app-token.outputs.token }}
+ fail-on-no-changes: false
- name: Update major version tag
id: update-major-tag
From 64ab729a6294000f5aa4a4bc0b73d1f32bc45510 Mon Sep 17 00:00:00 2001
From: "create-app-token-action-releaser[bot]"
<135574722+create-app-token-action-releaser[bot]@users.noreply.github.com>
Date: Mon, 12 Oct 2026 16:42:07 -0700
Subject: [PATCH 29/29] chore(main): release 3.3.0 (#402)
:robot: I have created a release *beep* *boop*
---
##
[3.3.0](https://github.com/actions/create-github-app-token/compare/v3.2.0...v3.3.0)
(2026-10-12)
### Features
* update permission inputs
([#399](https://github.com/actions/create-github-app-token/issues/399))
([a47236f](https://github.com/actions/create-github-app-token/commit/a47236f79f79fcbc3532af49fe3a5ded89529b6e))
### Bug Fixes
* **deps:** bump nested undici from 6.24.0 to 6.29.0
([#403](https://github.com/actions/create-github-app-token/issues/403))
([12461a3](https://github.com/actions/create-github-app-token/commit/12461a3a794e67c032f1eff5bb95ece9427eb4fb))
* **deps:** bump the production-dependencies group across 1 directory
with 3 updates
([#395](https://github.com/actions/create-github-app-token/issues/395))
([a69c19d](https://github.com/actions/create-github-app-token/commit/a69c19ddfdf8e1ab093900e0064524ce9309c807))
---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
---------
Co-authored-by: create-app-token-action-releaser[bot] <135574722+create-app-token-action-releaser[bot]@users.noreply.github.com>
Co-authored-by: parkerbxyz <17183625+parkerbxyz@users.noreply.github.com>
---
.release-please-manifest.json | 2 +-
CHANGELOG.md | 13 +
dist/main.cjs | 1594 +++++++++++++++++++++++++--------
dist/post.cjs | 1562 ++++++++++++++++++++++++--------
package-lock.json | 4 +-
package.json | 2 +-
6 files changed, 2403 insertions(+), 774 deletions(-)
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 95a37e3e..6110c0f0 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "3.2.0"
+ ".": "3.3.0"
}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3dfff070..507d40e9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,18 @@
# Changelog
+## [3.3.0](https://github.com/actions/create-github-app-token/compare/v3.2.0...v3.3.0) (2026-10-12)
+
+
+### Features
+
+* update permission inputs ([#399](https://github.com/actions/create-github-app-token/issues/399)) ([a47236f](https://github.com/actions/create-github-app-token/commit/a47236f79f79fcbc3532af49fe3a5ded89529b6e))
+
+
+### Bug Fixes
+
+* **deps:** bump nested undici from 6.24.0 to 6.29.0 ([#403](https://github.com/actions/create-github-app-token/issues/403)) ([12461a3](https://github.com/actions/create-github-app-token/commit/12461a3a794e67c032f1eff5bb95ece9427eb4fb))
+* **deps:** bump the production-dependencies group across 1 directory with 3 updates ([#395](https://github.com/actions/create-github-app-token/issues/395)) ([a69c19d](https://github.com/actions/create-github-app-token/commit/a69c19ddfdf8e1ab093900e0064524ce9309c807))
+
## [3.2.0](https://github.com/actions/create-github-app-token/compare/v3.1.1...v3.2.0) (2026-05-12)
diff --git a/dist/main.cjs b/dist/main.cjs
index 20b90dce..6158842f 100644
--- a/dist/main.cjs
+++ b/dist/main.cjs
@@ -5,7 +5,11 @@ var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __commonJS = (cb, mod) => function __require() {
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
+ try {
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
+ } catch (e) {
+ throw mod = 0, e;
+ }
};
var __export = (target, all) => {
for (var name in all)
@@ -1855,10 +1859,66 @@ var require_request = __commonJS({
return false;
}
}
- onUpgrade(statusCode, headers, socket) {
+ /**
+ * @param {number|null} statusCode
+ * @param {Buffer[]|null} headers
+ * @param {import('node:stream').Duplex} socket
+ * @param {string} [statusText]
+ */
+ onUpgrade(statusCode, headers, socket, statusText = "") {
+ this.onFinally();
assert(!this.aborted);
assert(!this.completed);
- return this[kHandler].onUpgrade(statusCode, headers, socket);
+ if (statusCode !== null) {
+ this.#publishUpgradeHeaders(statusCode, headers, statusText);
+ }
+ const result = this[kHandler].onUpgrade(statusCode, headers, socket);
+ if (!this.aborted) {
+ this.completed = true;
+ if (statusCode !== null) {
+ this.#publishUpgradeTrailers();
+ }
+ }
+ return result;
+ }
+ /**
+ * @param {number} statusCode
+ * @param {import('node:http2').IncomingHttpHeaders} headers
+ * @param {(headers: import('node:http2').IncomingHttpHeaders) => Buffer[]} parseHeaders
+ * @param {string} [statusText]
+ */
+ onUpgradeResponse(statusCode, headers, parseHeaders, statusText = "") {
+ assert(!this.aborted);
+ assert(this.completed);
+ if (channels.headers.hasSubscribers) {
+ this.#publishUpgradeHeaders(statusCode, parseHeaders(headers), statusText);
+ }
+ this.#publishUpgradeTrailers();
+ }
+ /**
+ * @param {Error} error
+ */
+ onUpgradeError(error2) {
+ assert(!this.aborted);
+ assert(this.completed);
+ if (channels.error.hasSubscribers) {
+ channels.error.publish({ request: this, error: error2 });
+ }
+ }
+ /**
+ * @param {number} statusCode
+ * @param {Buffer[]} headers
+ * @param {string} statusText
+ */
+ #publishUpgradeHeaders(statusCode, headers, statusText) {
+ if (channels.headers.hasSubscribers) {
+ channels.headers.publish({ request: this, response: { statusCode, headers, statusText } });
+ }
+ }
+ #publishUpgradeTrailers() {
+ if (channels.trailers.hasSubscribers) {
+ channels.trailers.publish({ request: this, trailers: [] });
+ }
}
onComplete(trailers) {
this.onFinally();
@@ -1925,7 +1985,11 @@ var require_request = __commonJS({
} else if (typeof val[i] === "object") {
throw new InvalidArgumentError(`invalid ${key} header`);
} else {
- arr.push(`${val[i]}`);
+ const str = `${val[i]}`;
+ if (!isValidHeaderValue(str)) {
+ throw new InvalidArgumentError(`invalid ${key} header`);
+ }
+ arr.push(str);
}
}
val = arr;
@@ -1937,6 +2001,9 @@ var require_request = __commonJS({
val = "";
} else {
val = `${val}`;
+ if (!isValidHeaderValue(val)) {
+ throw new InvalidArgumentError(`invalid ${key} header`);
+ }
}
if (headerName === "host") {
if (request2.host !== null) {
@@ -2046,13 +2113,21 @@ var require_dispatcher_base = __commonJS({
var kOnDestroyed = /* @__PURE__ */ Symbol("onDestroyed");
var kOnClosed = /* @__PURE__ */ Symbol("onClosed");
var kInterceptedDispatch = /* @__PURE__ */ Symbol("Intercepted Dispatch");
+ var kWebSocketOptions = /* @__PURE__ */ Symbol("webSocketOptions");
var DispatcherBase = class extends Dispatcher {
- constructor() {
+ constructor(opts) {
super();
this[kDestroyed] = false;
this[kOnDestroyed] = null;
this[kClosed] = false;
this[kOnClosed] = [];
+ this[kWebSocketOptions] = opts?.webSocket ?? {};
+ }
+ get webSocketOptions() {
+ return {
+ maxFragments: this[kWebSocketOptions].maxFragments ?? 131072,
+ maxPayloadSize: this[kWebSocketOptions].maxPayloadSize ?? 128 * 1024 * 1024
+ };
}
get destroyed() {
return this[kDestroyed];
@@ -5659,6 +5734,7 @@ var require_client_h1 = __commonJS({
RequestContentLengthMismatchError,
ResponseContentLengthMismatchError,
RequestAbortedError,
+ InvalidArgumentError,
HeadersTimeoutError,
HeadersOverflowError,
SocketError,
@@ -5705,6 +5781,9 @@ var require_client_h1 = __commonJS({
var FastBuffer = Buffer[Symbol.species];
var addListener = util.addListener;
var removeAllListeners = util.removeAllListeners;
+ var kIdleSocketValidation = /* @__PURE__ */ Symbol("kIdleSocketValidation");
+ var kIdleSocketValidationTimeout = /* @__PURE__ */ Symbol("kIdleSocketValidationTimeout");
+ var kSocketUsed = /* @__PURE__ */ Symbol("kSocketUsed");
var extractBody;
async function lazyllhttp() {
const llhttpWasmData = process.env.JEST_WORKER_ID ? require_llhttp_wasm() : void 0;
@@ -5867,24 +5946,55 @@ var require_client_h1 = __commonJS({
currentBufferRef = null;
}
const offset = llhttp.llhttp_get_error_pos(this.ptr) - currentBufferPtr;
- if (ret === constants3.ERROR.PAUSED_UPGRADE) {
- this.onUpgrade(data.slice(offset));
- } else if (ret === constants3.ERROR.PAUSED) {
- this.paused = true;
- socket.unshift(data.slice(offset));
- } else if (ret !== constants3.ERROR.OK) {
- const ptr = llhttp.llhttp_get_error_reason(this.ptr);
- let message = "";
- if (ptr) {
- const len = new Uint8Array(llhttp.memory.buffer, ptr).indexOf(0);
- message = "Response does not match the HTTP/1.1 protocol (" + Buffer.from(llhttp.memory.buffer, ptr, len).toString() + ")";
+ if (ret !== constants3.ERROR.OK) {
+ const body = data.subarray(offset);
+ if (ret === constants3.ERROR.PAUSED_UPGRADE) {
+ this.onUpgrade(body);
+ } else if (ret === constants3.ERROR.PAUSED) {
+ this.paused = true;
+ socket.unshift(body);
+ } else {
+ throw this.createError(ret, body);
}
- throw new HTTPParserError(message, constants3.ERROR[ret], data.slice(offset));
}
} catch (err) {
util.destroy(socket, err);
}
}
+ finish() {
+ assert(currentParser === null);
+ assert(this.ptr != null);
+ assert(!this.paused);
+ const { llhttp } = this;
+ let ret;
+ try {
+ currentParser = this;
+ ret = llhttp.llhttp_finish(this.ptr);
+ } finally {
+ currentParser = null;
+ }
+ if (ret === constants3.ERROR.OK) {
+ return null;
+ }
+ if (ret === constants3.ERROR.PAUSED || ret === constants3.ERROR.PAUSED_UPGRADE) {
+ this.paused = true;
+ return null;
+ }
+ return this.createError(ret, EMPTY_BUF);
+ }
+ createError(ret, data) {
+ const { llhttp, contentLength, bytesRead } = this;
+ if (contentLength && bytesRead !== parseInt(contentLength, 10)) {
+ return new ResponseContentLengthMismatchError();
+ }
+ const ptr = llhttp.llhttp_get_error_reason(this.ptr);
+ let message = "";
+ if (ptr) {
+ const len = new Uint8Array(llhttp.memory.buffer, ptr).indexOf(0);
+ message = "Response does not match the HTTP/1.1 protocol (" + Buffer.from(llhttp.memory.buffer, ptr, len).toString() + ")";
+ }
+ return new HTTPParserError(message, constants3.ERROR[ret], data);
+ }
destroy() {
assert(this.ptr != null);
assert(currentParser == null);
@@ -5904,6 +6014,10 @@ var require_client_h1 = __commonJS({
if (socket.destroyed) {
return -1;
}
+ if (client[kRunning] === 0) {
+ util.destroy(socket, new SocketError("bad response", util.getSocketInfo(socket)));
+ return -1;
+ }
const request2 = client[kQueue][client[kRunningIdx]];
if (!request2) {
return -1;
@@ -5947,7 +6061,7 @@ var require_client_h1 = __commonJS({
}
}
onUpgrade(head) {
- const { upgrade, client, socket, headers, statusCode } = this;
+ const { upgrade, client, socket, headers, statusCode, statusText } = this;
assert(upgrade);
assert(client[kSocket] === socket);
assert(!socket.destroyed);
@@ -5972,9 +6086,10 @@ var require_client_h1 = __commonJS({
client[kQueue][client[kRunningIdx]++] = null;
client.emit("disconnect", client[kUrl], [client], new InformationalError("upgrade"));
try {
- request2.onUpgrade(statusCode, headers, socket);
- } catch (err) {
- util.destroy(socket, err);
+ request2.onUpgrade(statusCode, headers, socket, statusText);
+ } catch (error2) {
+ util.errorRequest(client, request2, error2);
+ util.destroy(socket, error2);
}
client[kResume]();
}
@@ -5983,6 +6098,10 @@ var require_client_h1 = __commonJS({
if (socket.destroyed) {
return -1;
}
+ if (client[kRunning] === 0) {
+ util.destroy(socket, new SocketError("bad response", util.getSocketInfo(socket)));
+ return -1;
+ }
const request2 = client[kQueue][client[kRunningIdx]];
if (!request2) {
return -1;
@@ -6108,6 +6227,7 @@ var require_client_h1 = __commonJS({
}
request2.onComplete(headers);
client[kQueue][client[kRunningIdx]++] = null;
+ socket[kSocketUsed] = true;
if (socket[kWriting]) {
assert(client[kRunning] === 0);
util.destroy(socket, new InformationalError("reset"));
@@ -6151,12 +6271,19 @@ var require_client_h1 = __commonJS({
socket[kWriting] = false;
socket[kReset] = false;
socket[kBlocking] = false;
+ socket[kIdleSocketValidation] = 0;
+ socket[kIdleSocketValidationTimeout] = null;
+ socket[kSocketUsed] = false;
socket[kParser] = new Parser(client, socket, llhttpInstance);
addListener(socket, "error", function(err) {
assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID");
const parser = this[kParser];
if (err.code === "ECONNRESET" && parser.statusCode && !parser.shouldKeepAlive) {
- parser.onMessageComplete();
+ const parserErr = parser.finish();
+ if (parserErr) {
+ this[kError] = parserErr;
+ this[kClient][kOnError](parserErr);
+ }
return;
}
this[kError] = err;
@@ -6171,7 +6298,10 @@ var require_client_h1 = __commonJS({
addListener(socket, "end", function() {
const parser = this[kParser];
if (parser.statusCode && !parser.shouldKeepAlive) {
- parser.onMessageComplete();
+ const parserErr = parser.finish();
+ if (parserErr) {
+ util.destroy(this, parserErr);
+ }
return;
}
util.destroy(this, new SocketError("other side closed", util.getSocketInfo(this)));
@@ -6179,9 +6309,10 @@ var require_client_h1 = __commonJS({
addListener(socket, "close", function() {
const client2 = this[kClient];
const parser = this[kParser];
+ clearIdleSocketValidation(this);
if (parser) {
if (!this[kError] && parser.statusCode && !parser.shouldKeepAlive) {
- parser.onMessageComplete();
+ this[kError] = parser.finish() || this[kError];
}
this[kParser].destroy();
this[kParser] = null;
@@ -6230,7 +6361,7 @@ var require_client_h1 = __commonJS({
return socket.destroyed;
},
busy(request2) {
- if (socket[kWriting] || socket[kReset] || socket[kBlocking]) {
+ if (socket[kWriting] || socket[kReset] || socket[kBlocking] || socket[kIdleSocketValidation] === 1) {
return true;
}
if (request2) {
@@ -6248,6 +6379,23 @@ var require_client_h1 = __commonJS({
}
};
}
+ function clearIdleSocketValidation(socket) {
+ if (socket[kIdleSocketValidationTimeout]) {
+ clearImmediate(socket[kIdleSocketValidationTimeout]);
+ socket[kIdleSocketValidationTimeout] = null;
+ }
+ socket[kIdleSocketValidation] = 0;
+ }
+ function scheduleIdleSocketValidation(client, socket) {
+ socket[kIdleSocketValidation] = 1;
+ socket[kIdleSocketValidationTimeout] = setImmediate(() => {
+ socket[kIdleSocketValidationTimeout] = null;
+ socket[kIdleSocketValidation] = 2;
+ if (client[kSocket] === socket && !socket.destroyed) {
+ client[kResume]();
+ }
+ });
+ }
function resumeH1(client) {
const socket = client[kSocket];
if (socket && !socket.destroyed) {
@@ -6260,6 +6408,29 @@ var require_client_h1 = __commonJS({
socket.ref();
socket[kNoRef] = false;
}
+ if (client[kRunning] === 0 && client[kPending] > 0 && socket[kSocketUsed]) {
+ if (socket[kIdleSocketValidation] === 0) {
+ scheduleIdleSocketValidation(client, socket);
+ socket[kParser].readMore();
+ if (socket.destroyed) {
+ return;
+ }
+ return;
+ }
+ if (socket[kIdleSocketValidation] === 1) {
+ socket[kParser].readMore();
+ if (socket.destroyed) {
+ return;
+ }
+ return;
+ }
+ }
+ if (client[kRunning] === 0) {
+ socket[kParser].readMore();
+ if (socket.destroyed) {
+ return;
+ }
+ }
if (client[kSize] === 0) {
if (socket[kParser].timeoutType !== TIMEOUT_KEEP_ALIVE) {
socket[kParser].setTimeout(client[kKeepAliveTimeoutValue], TIMEOUT_KEEP_ALIVE);
@@ -6290,8 +6461,16 @@ var require_client_h1 = __commonJS({
}
body = bodyStream.stream;
contentLength = bodyStream.length;
- } else if (util.isBlobLike(body) && request2.contentType == null && body.type) {
- headers.push("content-type", body.type);
+ } else if (util.isBlobLike(body) && request2.contentType == null) {
+ const contentType = body.type;
+ if (contentType) {
+ const contentTypeValue = `${contentType}`;
+ if (!util.isValidHeaderValue(contentTypeValue)) {
+ util.errorRequest(client, request2, new InvalidArgumentError("invalid content-type header"));
+ return false;
+ }
+ headers.push("content-type", contentTypeValue);
+ }
}
if (body && typeof body.read === "function") {
body.read(0);
@@ -6312,11 +6491,18 @@ var require_client_h1 = __commonJS({
process.emitWarning(new RequestContentLengthMismatchError());
}
const socket = client[kSocket];
- const abort = (err) => {
- if (request2.aborted || request2.completed) {
+ clearIdleSocketValidation(socket);
+ const abort = (error2) => {
+ if (request2.aborted) {
return;
}
- util.errorRequest(client, request2, err || new RequestAbortedError());
+ if (request2.completed) {
+ if (request2.upgrade || request2.method === "CONNECT") {
+ util.destroy(socket, new InformationalError("aborted"));
+ }
+ return;
+ }
+ util.errorRequest(client, request2, error2 || new RequestAbortedError());
util.destroy(body);
util.destroy(socket, new InformationalError("aborted"));
};
@@ -6672,6 +6858,7 @@ var require_client_h2 = __commonJS({
"node_modules/@actions/http-client/node_modules/undici/lib/dispatcher/client-h2.js"(exports2, module2) {
"use strict";
var assert = require("node:assert");
+ var { errorMonitor } = require("node:events");
var { pipeline } = require("node:stream");
var util = require_util();
var {
@@ -6732,6 +6919,10 @@ var require_client_h2 = __commonJS({
}
return result;
}
+ function parseH2ResponseHeaders(headers) {
+ const { [HTTP2_HEADER_STATUS]: _statusCode, ...realHeaders } = headers;
+ return parseH2Headers(realHeaders);
+ }
async function connectH2(client, socket) {
client[kSocket] = socket;
if (!h2ExperimentalWarned) {
@@ -6895,16 +7086,22 @@ var require_client_h2 = __commonJS({
const { hostname, port } = client[kUrl];
headers[HTTP2_HEADER_AUTHORITY] = host || `${hostname}${port ? `:${port}` : ""}`;
headers[HTTP2_HEADER_METHOD] = method;
- const abort = (err) => {
- if (request2.aborted || request2.completed) {
+ const abort = (error2) => {
+ if (request2.aborted) {
return;
}
- err = err || new RequestAbortedError();
- util.errorRequest(client, request2, err);
+ if (request2.completed) {
+ if (method === "CONNECT" && stream != null) {
+ util.destroy(stream, error2 || new RequestAbortedError());
+ }
+ return;
+ }
+ error2 = error2 || new RequestAbortedError();
+ util.errorRequest(client, request2, error2);
if (stream != null) {
- util.destroy(stream, err);
+ util.destroy(stream, error2);
}
- util.destroy(body, err);
+ util.destroy(body, error2);
client[kQueue][client[kRunningIdx]++] = null;
client[kResume]();
};
@@ -6919,18 +7116,42 @@ var require_client_h2 = __commonJS({
if (method === "CONNECT") {
session.ref();
stream = session.request(headers, { endStream: false, signal });
- if (stream.id && !stream.pending) {
- request2.onUpgrade(null, null, stream);
- ++session[kOpenStreams];
- client[kQueue][client[kRunningIdx]++] = null;
- } else {
- stream.once("ready", () => {
+ let upgradeResponseFinished = false;
+ const onResponse = (headers2) => {
+ upgradeResponseFinished = true;
+ stream.off(errorMonitor, onUpgradeError);
+ request2.onUpgradeResponse(Number(headers2[HTTP2_HEADER_STATUS]), headers2, parseH2ResponseHeaders);
+ };
+ const onUpgradeError = (error2) => {
+ upgradeResponseFinished = true;
+ stream.off("response", onResponse);
+ request2.onUpgradeError(error2);
+ };
+ const onReady = () => {
+ try {
request2.onUpgrade(null, null, stream);
- ++session[kOpenStreams];
- client[kQueue][client[kRunningIdx]++] = null;
- });
- }
+ } catch (error2) {
+ stream.off("response", onResponse);
+ abort(error2);
+ return;
+ }
+ if (request2.aborted) {
+ return;
+ }
+ stream.off("error", abort);
+ stream.once(errorMonitor, onUpgradeError);
+ client[kQueue][client[kRunningIdx]++] = null;
+ };
+ stream.once("response", onResponse);
+ stream.once("error", abort);
+ ++session[kOpenStreams];
+ onReady();
stream.once("close", () => {
+ if (!upgradeResponseFinished && request2.completed) {
+ stream.off("response", onResponse);
+ stream.off(errorMonitor, onUpgradeError);
+ request2.onUpgradeError(new InformationalError(`HTTP/2: "stream error" received - code ${stream.rstCode}`));
+ }
session[kOpenStreams] -= 1;
if (session[kOpenStreams] === 0) session.unref();
});
@@ -7491,9 +7712,10 @@ var require_client = __commonJS({
autoSelectFamilyAttemptTimeout,
// h2
maxConcurrentStreams,
- allowH2
+ allowH2,
+ webSocket
} = {}) {
- super();
+ super({ webSocket });
if (keepAlive !== void 0) {
throw new InvalidArgumentError("unsupported keepAlive, use pipelining=0 instead");
}
@@ -7999,8 +8221,8 @@ var require_pool_base = __commonJS({
var kRemoveClient = /* @__PURE__ */ Symbol("remove client");
var kStats = /* @__PURE__ */ Symbol("stats");
var PoolBase = class extends DispatcherBase {
- constructor() {
- super();
+ constructor(opts) {
+ super(opts);
this[kQueue] = new FixedQueue();
this[kClients] = [];
this[kQueued] = 0;
@@ -8171,7 +8393,6 @@ var require_pool = __commonJS({
allowH2,
...options
} = {}) {
- super();
if (connections != null && (!Number.isFinite(connections) || connections < 0)) {
throw new InvalidArgumentError("invalid connections");
}
@@ -8192,6 +8413,7 @@ var require_pool = __commonJS({
...connect
});
}
+ super(options);
this[kInterceptors] = options.interceptors?.Pool && Array.isArray(options.interceptors.Pool) ? options.interceptors.Pool : [];
this[kConnections] = connections || null;
this[kUrl] = util.parseOrigin(origin);
@@ -8391,7 +8613,6 @@ var require_agent = __commonJS({
}
var Agent3 = class extends DispatcherBase {
constructor({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) {
- super();
if (typeof factory !== "function") {
throw new InvalidArgumentError("factory must be a function.");
}
@@ -8401,6 +8622,7 @@ var require_agent = __commonJS({
if (!Number.isInteger(maxRedirections) || maxRedirections < 0) {
throw new InvalidArgumentError("maxRedirections must be a positive number");
}
+ super(options);
if (connect && typeof connect !== "function") {
connect = { ...connect };
}
@@ -8841,6 +9063,24 @@ var require_retry_handler = __commonJS({
const current = Date.now();
return new Date(retryAfter).getTime() - current;
}
+ function validatePartialResponseContentLength(headers, range, statusCode, retryCount) {
+ const contentLength = headers["content-length"];
+ if (contentLength == null) {
+ return null;
+ }
+ if (!Number.isFinite(range.start) || !Number.isFinite(range.end)) {
+ return null;
+ }
+ const length = Number(contentLength);
+ const expectedLength = range.end - range.start + 1;
+ if (!Number.isFinite(length) || length !== expectedLength) {
+ return new RequestRetryError("Content-Length mismatch", statusCode, {
+ headers,
+ data: { count: retryCount }
+ });
+ }
+ return null;
+ }
var RetryHandler = class _RetryHandler {
constructor(opts, handlers) {
const { retryOptions, ...dispatchOpts } = opts;
@@ -8894,6 +9134,7 @@ var require_retry_handler = __commonJS({
this.end = null;
this.etag = null;
this.resume = null;
+ this.headersSent = false;
this.handler.onConnect((reason) => {
this.aborted = true;
if (this.abort) {
@@ -8903,6 +9144,17 @@ var require_retry_handler = __commonJS({
}
});
}
+ checkpointResponseEnd(headers, resume) {
+ if (this.end == null && this.opts.method !== "HEAD") {
+ const contentLength = headers["content-length"];
+ this.end = contentLength != null ? Number(contentLength) - 1 : null;
+ assert(
+ this.end == null || Number.isFinite(this.end),
+ "invalid content-length"
+ );
+ }
+ this.resume = this.end != null ? resume : null;
+ }
onRequestSent() {
if (this.handler.onRequestSent) {
this.handler.onRequestSent();
@@ -8964,7 +9216,9 @@ var require_retry_handler = __commonJS({
const headers = parseHeaders(rawHeaders);
this.retryCount += 1;
if (statusCode >= 300) {
- if (this.retryOpts.statusCodes.includes(statusCode) === false) {
+ if (!this.headersSent && this.retryOpts.statusCodes.includes(statusCode) === false) {
+ this.headersSent = true;
+ this.checkpointResponseEnd(headers, resume);
return this.handler.onHeaders(
statusCode,
rawHeaders,
@@ -9013,9 +9267,21 @@ var require_retry_handler = __commonJS({
);
return false;
}
+ const contentLengthError = validatePartialResponseContentLength(headers, contentRange, statusCode, this.retryCount);
+ if (contentLengthError != null) {
+ this.abort(contentLengthError);
+ return false;
+ }
const { start, size, end = size - 1 } = contentRange;
- assert(this.start === start, "content-range mismatch");
- assert(this.end == null || this.end === end, "content-range mismatch");
+ if (this.start !== start || this.end != null && this.end !== end) {
+ this.abort(
+ new RequestRetryError("Content-Range mismatch", statusCode, {
+ headers,
+ data: { count: this.retryCount }
+ })
+ );
+ return false;
+ }
this.resume = resume;
return true;
}
@@ -9023,6 +9289,7 @@ var require_retry_handler = __commonJS({
if (statusCode === 206) {
const range = parseRangeHeader(headers["content-range"]);
if (range == null) {
+ this.headersSent = true;
return this.handler.onHeaders(
statusCode,
rawHeaders,
@@ -9030,6 +9297,11 @@ var require_retry_handler = __commonJS({
statusMessage
);
}
+ const contentLengthError = validatePartialResponseContentLength(headers, range, statusCode, this.retryCount);
+ if (contentLengthError != null) {
+ this.abort(contentLengthError);
+ return false;
+ }
const { start, size, end = size - 1 } = range;
assert(
start != null && Number.isFinite(start),
@@ -9049,6 +9321,7 @@ var require_retry_handler = __commonJS({
"invalid content-length"
);
this.resume = resume;
+ this.headersSent = true;
this.etag = headers.etag != null ? headers.etag : null;
if (this.etag != null && this.etag.startsWith("W/")) {
this.etag = null;
@@ -9076,7 +9349,7 @@ var require_retry_handler = __commonJS({
return this.handler.onComplete(rawTrailers);
}
onError(err) {
- if (this.aborted || isDisturbed(this.opts.body)) {
+ if (this.aborted || isDisturbed(this.opts.body) || this.headersSent && this.resume == null) {
return this.handler.onError(err);
}
if (this.retryCount - this.retryCountCheckpoint > 0) {
@@ -15875,14 +16148,48 @@ var require_util6 = __commonJS({
for (let i = 0; i < path6.length; ++i) {
const code = path6.charCodeAt(i);
if (code < 32 || // exclude CTLs (0-31)
- code === 127 || // DEL
+ code > 126 || // exclude DEL and non-ascii
code === 59) {
throw new Error("Invalid cookie path");
}
}
}
+ function isLetterOrDigit(code) {
+ return code >= 48 && code <= 57 || // 0-9
+ code >= 65 && code <= 90 || // A-Z
+ code >= 97 && code <= 122;
+ }
function validateCookieDomain(domain) {
- if (domain.startsWith("-") || domain.endsWith(".") || domain.endsWith("-")) {
+ if (domain === " ") {
+ return;
+ }
+ if (domain.length > 255) {
+ throw new Error("Invalid cookie domain");
+ }
+ let labelLength = 0;
+ for (let i = 0; i < domain.length; ++i) {
+ const code = domain.charCodeAt(i);
+ if (code === 46) {
+ if (labelLength === 0) {
+ throw new Error("Invalid cookie domain");
+ }
+ if (domain.charCodeAt(i - 1) === 45) {
+ throw new Error("Invalid cookie domain");
+ }
+ labelLength = 0;
+ continue;
+ }
+ if (labelLength === 0 && !isLetterOrDigit(code)) {
+ throw new Error("Invalid cookie domain");
+ }
+ if (!isLetterOrDigit(code) && code !== 45) {
+ throw new Error("Invalid cookie domain");
+ }
+ if (++labelLength > 63) {
+ throw new Error("Invalid cookie domain");
+ }
+ }
+ if (labelLength === 0 || domain.charCodeAt(domain.length - 1) === 45) {
throw new Error("Invalid cookie domain");
}
}
@@ -15965,7 +16272,11 @@ var require_util6 = __commonJS({
throw new Error("Invalid unparsed");
}
const [key, ...value] = part.split("=");
- out.push(`${key.trim()}=${value.join("=")}`);
+ const trimmedKey = key.trim();
+ const joinedValue = value.join("=");
+ validateCookieName(trimmedKey);
+ validateCookieValue(joinedValue);
+ out.push(`${trimmedKey}=${joinedValue}`);
}
return out.join("; ");
}
@@ -16095,18 +16406,14 @@ var require_parse = __commonJS({
} else if (attributeNameLowercase === "httponly") {
cookieAttributeList.httpOnly = true;
} else if (attributeNameLowercase === "samesite") {
- let enforcement = "Default";
const attributeValueLowercase = attributeValue.toLowerCase();
- if (attributeValueLowercase.includes("none")) {
- enforcement = "None";
- }
- if (attributeValueLowercase.includes("strict")) {
- enforcement = "Strict";
- }
- if (attributeValueLowercase.includes("lax")) {
- enforcement = "Lax";
+ if (attributeValueLowercase === "none") {
+ cookieAttributeList.sameSite = "None";
+ } else if (attributeValueLowercase === "strict") {
+ cookieAttributeList.sameSite = "Strict";
+ } else if (attributeValueLowercase === "lax") {
+ cookieAttributeList.sameSite = "Lax";
}
- cookieAttributeList.sameSite = enforcement;
} else {
cookieAttributeList.unparsed ??= [];
cookieAttributeList.unparsed.push(`${attributeName}=${attributeValue}`);
@@ -16928,7 +17235,7 @@ var require_connection = __commonJS({
const secProtocol = response.headersList.get("Sec-WebSocket-Protocol");
if (secProtocol !== null) {
const requestProtocols = getDecodeSplit("sec-websocket-protocol", request2.headersList);
- if (!requestProtocols.includes(secProtocol)) {
+ if (requestProtocols === null || !requestProtocols.includes(secProtocol)) {
failWebsocketConnection(ws, "Protocol was not set in the opening handshake.");
return;
}
@@ -17034,31 +17341,26 @@ var require_permessage_deflate = __commonJS({
var tail = Buffer.from([0, 0, 255, 255]);
var kBuffer = /* @__PURE__ */ Symbol("kBuffer");
var kLength = /* @__PURE__ */ Symbol("kLength");
- var kDefaultMaxDecompressedSize = 4 * 1024 * 1024;
var PerMessageDeflate = class {
/** @type {import('node:zlib').InflateRaw} */
#inflate;
#options = {};
- /** @type {number} */
- #maxDecompressedSize;
- /** @type {boolean} */
- #aborted = false;
- /** @type {Function|null} */
- #currentCallback = null;
+ #maxPayloadSize = 0;
/**
* @param {Map} extensions
- * @param {{ maxDecompressedMessageSize?: number }} [options]
*/
- constructor(extensions, options = {}) {
+ constructor(extensions, options) {
this.#options.serverNoContextTakeover = extensions.has("server_no_context_takeover");
this.#options.serverMaxWindowBits = extensions.get("server_max_window_bits");
- this.#maxDecompressedSize = options.maxDecompressedMessageSize ?? kDefaultMaxDecompressedSize;
+ this.#maxPayloadSize = options.maxPayloadSize;
}
+ /**
+ * Decompress a compressed payload.
+ * @param {Buffer} chunk Compressed data
+ * @param {boolean} fin Final fragment flag
+ * @param {Function} callback Callback function
+ */
decompress(chunk, fin, callback) {
- if (this.#aborted) {
- callback(new MessageSizeExceededError());
- return;
- }
if (!this.#inflate) {
let windowBits = Z_DEFAULT_WINDOWBITS;
if (this.#options.serverMaxWindowBits) {
@@ -17077,20 +17379,12 @@ var require_permessage_deflate = __commonJS({
this.#inflate[kBuffer] = [];
this.#inflate[kLength] = 0;
this.#inflate.on("data", (data) => {
- if (this.#aborted) {
- return;
- }
this.#inflate[kLength] += data.length;
- if (this.#inflate[kLength] > this.#maxDecompressedSize) {
- this.#aborted = true;
+ if (this.#maxPayloadSize > 0 && this.#inflate[kLength] > this.#maxPayloadSize) {
+ callback(new MessageSizeExceededError());
this.#inflate.removeAllListeners();
this.#inflate.destroy();
this.#inflate = null;
- if (this.#currentCallback) {
- const cb = this.#currentCallback;
- this.#currentCallback = null;
- cb(new MessageSizeExceededError());
- }
return;
}
this.#inflate[kBuffer].push(data);
@@ -17100,19 +17394,17 @@ var require_permessage_deflate = __commonJS({
callback(err);
});
}
- this.#currentCallback = callback;
this.#inflate.write(chunk);
if (fin) {
this.#inflate.write(tail);
}
this.#inflate.flush(() => {
- if (this.#aborted || !this.#inflate) {
+ if (!this.#inflate) {
return;
}
const full = Buffer.concat(this.#inflate[kBuffer], this.#inflate[kLength]);
this.#inflate[kBuffer].length = 0;
this.#inflate[kLength] = 0;
- this.#currentCallback = null;
callback(null, full);
});
}
@@ -17143,8 +17435,14 @@ var require_receiver = __commonJS({
var { WebsocketFrameSend } = require_frame();
var { closeWebSocketConnection } = require_connection();
var { PerMessageDeflate } = require_permessage_deflate();
+ var { MessageSizeExceededError } = require_errors();
+ function failWebsocketConnectionWithCode(ws, code, reason) {
+ closeWebSocketConnection(ws, code, reason, Buffer.byteLength(reason));
+ failWebsocketConnection(ws, reason);
+ }
var ByteParser = class extends Writable {
#buffers = [];
+ #fragmentsBytes = 0;
#byteOffset = 0;
#loop = false;
#state = parserStates.INFO;
@@ -17152,18 +17450,21 @@ var require_receiver = __commonJS({
#fragments = [];
/** @type {Map} */
#extensions;
- /** @type {{ maxDecompressedMessageSize?: number }} */
- #options;
+ /** @type {number} */
+ #maxFragments;
+ /** @type {number} */
+ #maxPayloadSize;
/**
* @param {import('./websocket').WebSocket} ws
* @param {Map|null} extensions
- * @param {{ maxDecompressedMessageSize?: number }} [options]
+ * @param {{ maxFragments?: number, maxPayloadSize?: number }} [options]
*/
constructor(ws, extensions, options = {}) {
super();
this.ws = ws;
this.#extensions = extensions == null ? /* @__PURE__ */ new Map() : extensions;
- this.#options = options;
+ this.#maxFragments = options.maxFragments ?? 0;
+ this.#maxPayloadSize = options.maxPayloadSize ?? 0;
if (this.#extensions.has("permessage-deflate")) {
this.#extensions.set("permessage-deflate", new PerMessageDeflate(extensions, options));
}
@@ -17178,6 +17479,13 @@ var require_receiver = __commonJS({
this.#loop = true;
this.run(callback);
}
+ #validatePayloadLength() {
+ if (this.#maxPayloadSize > 0 && !isControlFrame(this.#info.opcode) && this.#info.payloadLength + this.#fragmentsBytes > this.#maxPayloadSize) {
+ failWebsocketConnectionWithCode(this.ws, 1009, "Payload size exceeds maximum allowed size");
+ return false;
+ }
+ return true;
+ }
/**
* Runs whenever a new chunk is received.
* Callback is called whenever there are no more chunks buffering,
@@ -17237,6 +17545,9 @@ var require_receiver = __commonJS({
if (payloadLength <= 125) {
this.#info.payloadLength = payloadLength;
this.#state = parserStates.READ_DATA;
+ if (!this.#validatePayloadLength()) {
+ return;
+ }
} else if (payloadLength === 126) {
this.#state = parserStates.PAYLOADLENGTH_16;
} else if (payloadLength === 127) {
@@ -17257,6 +17568,9 @@ var require_receiver = __commonJS({
const buffer = this.consume(2);
this.#info.payloadLength = buffer.readUInt16BE(0);
this.#state = parserStates.READ_DATA;
+ if (!this.#validatePayloadLength()) {
+ return;
+ }
} else if (this.#state === parserStates.PAYLOADLENGTH_64) {
if (this.#byteOffset < 8) {
return callback();
@@ -17270,6 +17584,9 @@ var require_receiver = __commonJS({
}
this.#info.payloadLength = lower;
this.#state = parserStates.READ_DATA;
+ if (!this.#validatePayloadLength()) {
+ return;
+ }
} else if (this.#state === parserStates.READ_DATA) {
if (this.#byteOffset < this.#info.payloadLength) {
return callback();
@@ -17280,32 +17597,46 @@ var require_receiver = __commonJS({
this.#state = parserStates.INFO;
} else {
if (!this.#info.compressed) {
- this.#fragments.push(body);
+ if (!this.writeFragments(body)) {
+ return;
+ }
+ if (this.#maxPayloadSize > 0 && this.#fragmentsBytes > this.#maxPayloadSize) {
+ failWebsocketConnectionWithCode(this.ws, 1009, new MessageSizeExceededError().message);
+ return;
+ }
if (!this.#info.fragmented && this.#info.fin) {
- const fullMessage = Buffer.concat(this.#fragments);
- websocketMessageReceived(this.ws, this.#info.binaryType, fullMessage);
- this.#fragments.length = 0;
+ websocketMessageReceived(this.ws, this.#info.binaryType, this.consumeFragments());
}
this.#state = parserStates.INFO;
} else {
- this.#extensions.get("permessage-deflate").decompress(body, this.#info.fin, (error2, data) => {
- if (error2) {
- failWebsocketConnection(this.ws, error2.message);
- return;
- }
- this.#fragments.push(data);
- if (!this.#info.fin) {
- this.#state = parserStates.INFO;
+ this.#extensions.get("permessage-deflate").decompress(
+ body,
+ this.#info.fin,
+ (error2, data) => {
+ if (error2) {
+ const code = error2 instanceof MessageSizeExceededError ? 1009 : 1007;
+ failWebsocketConnectionWithCode(this.ws, code, error2.message);
+ return;
+ }
+ if (!this.writeFragments(data)) {
+ return;
+ }
+ if (this.#maxPayloadSize > 0 && this.#fragmentsBytes > this.#maxPayloadSize) {
+ failWebsocketConnectionWithCode(this.ws, 1009, new MessageSizeExceededError().message);
+ return;
+ }
+ if (!this.#info.fin) {
+ this.#state = parserStates.INFO;
+ this.#loop = true;
+ this.run(callback);
+ return;
+ }
+ websocketMessageReceived(this.ws, this.#info.binaryType, this.consumeFragments());
this.#loop = true;
+ this.#state = parserStates.INFO;
this.run(callback);
- return;
}
- websocketMessageReceived(this.ws, this.#info.binaryType, Buffer.concat(this.#fragments));
- this.#loop = true;
- this.#state = parserStates.INFO;
- this.#fragments.length = 0;
- this.run(callback);
- });
+ );
this.#loop = false;
break;
}
@@ -17348,6 +17679,26 @@ var require_receiver = __commonJS({
this.#byteOffset -= n;
return buffer;
}
+ writeFragments(fragment) {
+ if (this.#maxFragments > 0 && this.#fragments.length === this.#maxFragments) {
+ failWebsocketConnectionWithCode(this.ws, 1008, "Too many message fragments");
+ return false;
+ }
+ this.#fragmentsBytes += fragment.length;
+ this.#fragments.push(fragment);
+ return true;
+ }
+ consumeFragments() {
+ const fragments = this.#fragments;
+ if (fragments.length === 1) {
+ this.#fragmentsBytes = 0;
+ return fragments.shift();
+ }
+ const output = Buffer.concat(fragments, this.#fragmentsBytes);
+ this.#fragments = [];
+ this.#fragmentsBytes = 0;
+ return output;
+ }
parseCloseBody(data) {
assert(data.length !== 1);
let code;
@@ -17559,8 +17910,6 @@ var require_websocket = __commonJS({
#extensions = "";
/** @type {SendQueue} */
#sendQueue;
- /** @type {{ maxDecompressedMessageSize?: number }} */
- #options;
/**
* @param {string} url
* @param {string|string[]} protocols
@@ -17604,9 +17953,6 @@ var require_websocket = __commonJS({
throw new DOMException("Invalid Sec-WebSocket-Protocol value", "SyntaxError");
}
this[kWebSocketURL] = new URL(urlRecord.href);
- this.#options = {
- maxDecompressedMessageSize: options.maxDecompressedMessageSize
- };
const client = environmentSettingsObject.settingsObject;
this[kController] = establishWebSocketConnection(
urlRecord,
@@ -17790,7 +18136,13 @@ var require_websocket = __commonJS({
*/
#onConnectionEstablished(response, parsedExtensions) {
this[kResponse] = response;
- const parser = new ByteParser(this, parsedExtensions, this.#options);
+ const webSocketOptions = this[kController]?.dispatcher?.webSocketOptions;
+ const maxFragments = webSocketOptions?.maxFragments;
+ const maxPayloadSize = webSocketOptions?.maxPayloadSize;
+ const parser = new ByteParser(this, parsedExtensions, {
+ maxFragments,
+ maxPayloadSize
+ });
parser.on("drain", onParserDrain);
parser.on("error", onParserError.bind(this));
response.socket.ws = this;
@@ -17865,19 +18217,6 @@ var require_websocket = __commonJS({
{
key: "headers",
converter: webidl.nullableConverter(webidl.converters.HeadersInit)
- },
- {
- key: "maxDecompressedMessageSize",
- converter: webidl.nullableConverter((V) => {
- V = webidl.converters["unsigned long long"](V);
- if (V <= 0) {
- throw webidl.errors.exception({
- header: "WebSocket constructor",
- message: "maxDecompressedMessageSize must be greater than 0"
- });
- }
- return V;
- })
}
]);
webidl.converters["DOMString or sequence or WebSocketInit"] = function(V) {
@@ -17956,6 +18295,40 @@ var require_eventsource_stream = __commonJS({
var CR = 13;
var COLON = 58;
var SPACE = 32;
+ var DATA = Buffer.from("data");
+ var EVENT = Buffer.from("event");
+ var ID = Buffer.from("id");
+ var RETRY = Buffer.from("retry");
+ function isASCIINumberBytes(buffer, start) {
+ if (start >= buffer.length) {
+ return false;
+ }
+ for (let i = start; i < buffer.length; i++) {
+ if (buffer[i] < 48 || buffer[i] > 57) {
+ return false;
+ }
+ }
+ return true;
+ }
+ function isValidLastEventIdBytes(buffer, start) {
+ for (let i = start; i < buffer.length; i++) {
+ if (buffer[i] === 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+ function isFieldName(line, length, field) {
+ if (length !== field.length) {
+ return false;
+ }
+ for (let i = 0; i < length; i++) {
+ if (line[i] !== field[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
var EventSourceStream = class extends Transform {
/**
* @type {eventSourceSettings}
@@ -17975,10 +18348,13 @@ var require_eventsource_stream = __commonJS({
*/
eventEndCheck = false;
/**
- * @type {Buffer}
+ * @type {Buffer[]}
*/
- buffer = null;
+ chunks = [];
+ chunkIndex = 0;
pos = 0;
+ lineChunkIndex = 0;
+ linePos = 0;
event = {
data: void 0,
event: void 0,
@@ -18009,63 +18385,30 @@ var require_eventsource_stream = __commonJS({
callback();
return;
}
- if (this.buffer) {
- this.buffer = Buffer.concat([this.buffer, chunk]);
- } else {
- this.buffer = chunk;
- }
+ this.chunks.push(chunk);
if (this.checkBOM) {
- switch (this.buffer.length) {
- case 1:
- if (this.buffer[0] === BOM[0]) {
- callback();
- return;
- }
- this.checkBOM = false;
- callback();
- return;
- case 2:
- if (this.buffer[0] === BOM[0] && this.buffer[1] === BOM[1]) {
- callback();
- return;
- }
- this.checkBOM = false;
- break;
- case 3:
- if (this.buffer[0] === BOM[0] && this.buffer[1] === BOM[1] && this.buffer[2] === BOM[2]) {
- this.buffer = Buffer.alloc(0);
- this.checkBOM = false;
- callback();
- return;
- }
- this.checkBOM = false;
- break;
- default:
- if (this.buffer[0] === BOM[0] && this.buffer[1] === BOM[1] && this.buffer[2] === BOM[2]) {
- this.buffer = this.buffer.subarray(3);
- }
- this.checkBOM = false;
- break;
+ if (this.handleBOM()) {
+ callback();
+ return;
}
}
- while (this.pos < this.buffer.length) {
+ while (this.hasCurrentByte()) {
+ const byte = this.currentByte();
if (this.eventEndCheck) {
if (this.crlfCheck) {
- if (this.buffer[this.pos] === LF) {
- this.buffer = this.buffer.subarray(this.pos + 1);
- this.pos = 0;
+ if (byte === LF) {
this.crlfCheck = false;
+ this.consumeCurrentByte();
continue;
}
this.crlfCheck = false;
}
- if (this.buffer[this.pos] === LF || this.buffer[this.pos] === CR) {
- if (this.buffer[this.pos] === CR) {
+ if (byte === LF || byte === CR) {
+ if (byte === CR) {
this.crlfCheck = true;
}
- this.buffer = this.buffer.subarray(this.pos + 1);
- this.pos = 0;
- if (this.event.data !== void 0 || this.event.event || this.event.id || this.event.retry) {
+ this.consumeCurrentByte();
+ if (this.hasPendingEvent()) {
this.processEvent(this.event);
}
this.clearEvent();
@@ -18074,17 +18417,16 @@ var require_eventsource_stream = __commonJS({
this.eventEndCheck = false;
continue;
}
- if (this.buffer[this.pos] === LF || this.buffer[this.pos] === CR) {
- if (this.buffer[this.pos] === CR) {
+ if (byte === LF || byte === CR) {
+ if (byte === CR) {
this.crlfCheck = true;
}
- this.parseLine(this.buffer.subarray(0, this.pos), this.event);
- this.buffer = this.buffer.subarray(this.pos + 1);
- this.pos = 0;
+ this.parseLine(this.readLine(), this.event);
+ this.consumeCurrentByte();
this.eventEndCheck = true;
continue;
}
- this.pos++;
+ this.advanceCursor();
}
callback();
}
@@ -18100,43 +18442,42 @@ var require_eventsource_stream = __commonJS({
if (colonPosition === 0) {
return;
}
- let field = "";
- let value = "";
+ let fieldLength = line.length;
+ let valueStart = line.length;
if (colonPosition !== -1) {
- field = line.subarray(0, colonPosition).toString("utf8");
- let valueStart = colonPosition + 1;
+ fieldLength = colonPosition;
+ valueStart = colonPosition + 1;
if (line[valueStart] === SPACE) {
++valueStart;
}
- value = line.subarray(valueStart).toString("utf8");
- } else {
- field = line.toString("utf8");
- value = "";
}
- switch (field) {
- case "data":
- if (event[field] === void 0) {
- event[field] = value;
- } else {
- event[field] += `
+ if (isFieldName(line, fieldLength, DATA)) {
+ const value = line.toString("utf8", valueStart);
+ if (event.data === void 0) {
+ event.data = value;
+ } else {
+ event.data += `
${value}`;
- }
- break;
- case "retry":
- if (isASCIINumber(value)) {
- event[field] = value;
- }
- break;
- case "id":
- if (isValidLastEventId(value)) {
- event[field] = value;
- }
- break;
- case "event":
- if (value.length > 0) {
- event[field] = value;
- }
- break;
+ }
+ return;
+ }
+ if (isFieldName(line, fieldLength, RETRY)) {
+ if (isASCIINumberBytes(line, valueStart)) {
+ event.retry = line.toString("utf8", valueStart);
+ }
+ return;
+ }
+ if (isFieldName(line, fieldLength, ID)) {
+ if (isValidLastEventIdBytes(line, valueStart)) {
+ event.id = line.toString("utf8", valueStart);
+ }
+ return;
+ }
+ if (isFieldName(line, fieldLength, EVENT)) {
+ const value = line.toString("utf8", valueStart);
+ if (value.length > 0) {
+ event.event = value;
+ }
}
}
/**
@@ -18161,12 +18502,120 @@ ${value}`;
}
}
clearEvent() {
- this.event = {
- data: void 0,
- event: void 0,
- id: void 0,
- retry: void 0
- };
+ this.event.data = void 0;
+ this.event.event = void 0;
+ this.event.id = void 0;
+ this.event.retry = void 0;
+ }
+ hasPendingEvent() {
+ return this.event.data !== void 0 || this.event.event !== void 0 || this.event.id !== void 0 || this.event.retry !== void 0;
+ }
+ hasCurrentByte() {
+ return this.chunkIndex < this.chunks.length && this.pos < this.chunks[this.chunkIndex].length;
+ }
+ currentByte() {
+ return this.chunks[this.chunkIndex][this.pos];
+ }
+ consumeCurrentByte() {
+ this.advanceCursor();
+ this.syncLineStartToCursor();
+ }
+ advanceCursor() {
+ this.pos++;
+ while (this.chunkIndex < this.chunks.length && this.pos >= this.chunks[this.chunkIndex].length) {
+ this.chunkIndex++;
+ this.pos = 0;
+ }
+ }
+ syncLineStartToCursor() {
+ this.lineChunkIndex = this.chunkIndex;
+ this.linePos = this.pos;
+ this.dropConsumedChunks();
+ }
+ dropConsumedChunks() {
+ while (this.lineChunkIndex > 0) {
+ this.chunks.shift();
+ this.lineChunkIndex--;
+ this.chunkIndex--;
+ }
+ if (this.chunkIndex === this.chunks.length) {
+ this.chunks.length = 0;
+ this.chunkIndex = 0;
+ this.pos = 0;
+ this.lineChunkIndex = 0;
+ this.linePos = 0;
+ }
+ }
+ readLine() {
+ if (this.lineChunkIndex === this.chunkIndex) {
+ return this.chunks[this.chunkIndex].subarray(this.linePos, this.pos);
+ }
+ const chunks = [];
+ let length = 0;
+ for (let i = this.lineChunkIndex; i <= this.chunkIndex; i++) {
+ const chunk = this.chunks[i];
+ const start = i === this.lineChunkIndex ? this.linePos : 0;
+ const end = i === this.chunkIndex ? this.pos : chunk.length;
+ const slice = chunk.subarray(start, end);
+ length += slice.length;
+ chunks.push(slice);
+ }
+ return Buffer.concat(chunks, length);
+ }
+ peekBufferedByte(offset) {
+ let chunkIndex = this.lineChunkIndex;
+ let pos = this.linePos;
+ while (chunkIndex < this.chunks.length) {
+ const chunk = this.chunks[chunkIndex];
+ const remaining = chunk.length - pos;
+ if (offset < remaining) {
+ return chunk[pos + offset];
+ }
+ offset -= remaining;
+ chunkIndex++;
+ pos = 0;
+ }
+ }
+ discardLeadingBytes(count) {
+ while (count > 0 && this.lineChunkIndex < this.chunks.length) {
+ const chunk = this.chunks[this.lineChunkIndex];
+ const remaining = chunk.length - this.linePos;
+ if (count < remaining) {
+ this.linePos += count;
+ count = 0;
+ } else {
+ count -= remaining;
+ this.lineChunkIndex++;
+ this.linePos = 0;
+ }
+ }
+ this.chunkIndex = this.lineChunkIndex;
+ this.pos = this.linePos;
+ this.dropConsumedChunks();
+ }
+ handleBOM() {
+ const first = this.peekBufferedByte(0);
+ const second = this.peekBufferedByte(1);
+ const third = this.peekBufferedByte(2);
+ if (second === void 0) {
+ if (first === BOM[0]) {
+ return true;
+ }
+ this.checkBOM = false;
+ return true;
+ }
+ if (third === void 0) {
+ if (first === BOM[0] && second === BOM[1]) {
+ return true;
+ }
+ this.checkBOM = false;
+ return false;
+ }
+ if (first === BOM[0] && second === BOM[1] && third === BOM[2]) {
+ this.discardLeadingBytes(3);
+ }
+ this.checkBOM = false;
+ return !this.hasCurrentByte();
}
};
module2.exports = {
@@ -18614,102 +19063,6 @@ var require_undici = __commonJS({
}
});
-// node_modules/fast-content-type-parse/index.js
-var require_fast_content_type_parse = __commonJS({
- "node_modules/fast-content-type-parse/index.js"(exports2, module2) {
- "use strict";
- var NullObject = function NullObject2() {
- };
- NullObject.prototype = /* @__PURE__ */ Object.create(null);
- var paramRE = /; *([!#$%&'*+.^\w`|~-]+)=("(?:[\v\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\v\u0020-\u00ff])*"|[!#$%&'*+.^\w`|~-]+) */gu;
- var quotedPairRE = /\\([\v\u0020-\u00ff])/gu;
- var mediaTypeRE = /^[!#$%&'*+.^\w|~-]+\/[!#$%&'*+.^\w|~-]+$/u;
- var defaultContentType = { type: "", parameters: new NullObject() };
- Object.freeze(defaultContentType.parameters);
- Object.freeze(defaultContentType);
- function parse2(header) {
- if (typeof header !== "string") {
- throw new TypeError("argument header is required and must be a string");
- }
- let index = header.indexOf(";");
- const type = index !== -1 ? header.slice(0, index).trim() : header.trim();
- if (mediaTypeRE.test(type) === false) {
- throw new TypeError("invalid media type");
- }
- const result = {
- type: type.toLowerCase(),
- parameters: new NullObject()
- };
- if (index === -1) {
- return result;
- }
- let key;
- let match;
- let value;
- paramRE.lastIndex = index;
- while (match = paramRE.exec(header)) {
- if (match.index !== index) {
- throw new TypeError("invalid parameter format");
- }
- index += match[0].length;
- key = match[1].toLowerCase();
- value = match[2];
- if (value[0] === '"') {
- value = value.slice(1, value.length - 1);
- quotedPairRE.test(value) && (value = value.replace(quotedPairRE, "$1"));
- }
- result.parameters[key] = value;
- }
- if (index !== header.length) {
- throw new TypeError("invalid parameter format");
- }
- return result;
- }
- function safeParse2(header) {
- if (typeof header !== "string") {
- return defaultContentType;
- }
- let index = header.indexOf(";");
- const type = index !== -1 ? header.slice(0, index).trim() : header.trim();
- if (mediaTypeRE.test(type) === false) {
- return defaultContentType;
- }
- const result = {
- type: type.toLowerCase(),
- parameters: new NullObject()
- };
- if (index === -1) {
- return result;
- }
- let key;
- let match;
- let value;
- paramRE.lastIndex = index;
- while (match = paramRE.exec(header)) {
- if (match.index !== index) {
- return defaultContentType;
- }
- index += match[0].length;
- key = match[1].toLowerCase();
- value = match[2];
- if (value[0] === '"') {
- value = value.slice(1, value.length - 1);
- quotedPairRE.test(value) && (value = value.replace(quotedPairRE, "$1"));
- }
- result.parameters[key] = value;
- }
- if (index !== header.length) {
- return defaultContentType;
- }
- return result;
- }
- module2.exports.default = { parse: parse2, safeParse: safeParse2 };
- module2.exports.parse = parse2;
- module2.exports.safeParse = safeParse2;
- module2.exports.defaultContentType = defaultContentType;
- }
-});
-
// main.js
var main_exports = {};
__export(main_exports, {
@@ -21314,8 +21667,189 @@ function withDefaults(oldDefaults, newDefaults) {
}
var endpoint = withDefaults(null, DEFAULTS);
-// node_modules/@octokit/request/dist-bundle/index.js
-var import_fast_content_type_parse = __toESM(require_fast_content_type_parse(), 1);
+// node_modules/content-type/dist/index.js
+var SP = 32;
+var HTAB = 9;
+var SEMI = 59;
+var EQ = 61;
+var DQUOTE = 34;
+var BSLASH = 92;
+var COMMA = 44;
+var LOWER_CASE = 1;
+var OWS = 2;
+var SEMI_FLAG = 4;
+var COMMA_FLAG = 8;
+var TOKEN_FLAG = 16;
+var NON_ASCII = 65280;
+var CASE_FLAGS = LOWER_CASE | NON_ASCII;
+var CHAR_MAP = new Uint8Array(256);
+CHAR_MAP[HTAB] |= OWS;
+CHAR_MAP[SP] |= OWS;
+CHAR_MAP[SEMI] |= SEMI_FLAG;
+CHAR_MAP[COMMA] |= COMMA_FLAG;
+for (let code = 128; code <= 255; code++) {
+ CHAR_MAP[code] |= LOWER_CASE;
+}
+for (const char of "!#$%&'*+-.^_`|~") {
+ CHAR_MAP[char.charCodeAt(0)] |= TOKEN_FLAG;
+}
+for (let code = 48; code <= 57; code++) {
+ CHAR_MAP[code] |= TOKEN_FLAG;
+}
+for (let code = 65; code <= 90; code++) {
+ CHAR_MAP[code] |= LOWER_CASE | TOKEN_FLAG;
+}
+for (let code = 97; code <= 122; code++) {
+ CHAR_MAP[code] |= TOKEN_FLAG;
+}
+var NullObject = /* @__PURE__ */ (() => {
+ const C = function() {
+ };
+ C.prototype = /* @__PURE__ */ Object.create(null);
+ return C;
+})();
+function parse2(header, options) {
+ const stopFlags = SEMI_FLAG | (options?.comma === true ? COMMA_FLAG : 0);
+ const len = header.length;
+ let valueStart = options?.start ?? 0;
+ while ((CHAR_MAP[header.charCodeAt(valueStart)] & OWS) !== 0) {
+ valueStart++;
+ }
+ let index = valueStart;
+ let typeFlags = 0;
+ let whitespace = -1;
+ let stop = options?.parameters === false ? COMMA_FLAG : 0;
+ while (index < len) {
+ const code = header.charCodeAt(index);
+ const flags = CHAR_MAP[code];
+ if ((flags & stopFlags) !== 0) {
+ stop |= flags & COMMA_FLAG;
+ break;
+ }
+ if ((flags & OWS) !== 0) {
+ if (whitespace === -1)
+ whitespace = index;
+ } else {
+ whitespace = -1;
+ }
+ typeFlags |= code & NON_ASCII | flags;
+ index++;
+ }
+ const valueEnd = whitespace === -1 ? index : whitespace;
+ const value = header.slice(valueStart, valueEnd);
+ const type = (typeFlags & CASE_FLAGS) === 0 ? value : value.toLowerCase();
+ if (index === len || stop !== 0) {
+ return { type, index, parameters: new NullObject() };
+ }
+ return parseParameters(header, type, index, len, stopFlags);
+}
+function parseParameters(header, type, index, len, stopFlags) {
+ const parameters = new NullObject();
+ parameter: while (index < len) {
+ index++;
+ while ((CHAR_MAP[header.charCodeAt(index)] & OWS) !== 0) {
+ index++;
+ }
+ const keyStart = index;
+ let keyFlags = 0;
+ let keyWhitespace = -1;
+ while (index < len) {
+ const code = header.charCodeAt(index);
+ const flags = CHAR_MAP[code];
+ if ((flags & stopFlags) !== 0) {
+ if ((flags & COMMA_FLAG) !== 0)
+ break parameter;
+ continue parameter;
+ }
+ if (code === EQ) {
+ const keyEnd = keyWhitespace === -1 ? index : keyWhitespace;
+ const value = header.slice(keyStart, keyEnd);
+ const key = (keyFlags & CASE_FLAGS) === 0 ? value : value.toLowerCase();
+ index++;
+ while ((CHAR_MAP[header.charCodeAt(index)] & OWS) !== 0) {
+ index++;
+ }
+ if (index < len && header.charCodeAt(index) === DQUOTE) {
+ const quotedStart = ++index;
+ let escaped = false;
+ while (index < len) {
+ const code2 = header.charCodeAt(index);
+ if (code2 === DQUOTE) {
+ if (parameters[key] === void 0) {
+ parameters[key] = escaped ? unescapeQuotedPairs(header, quotedStart, index) : header.slice(quotedStart, index);
+ }
+ index++;
+ let stop2 = 0;
+ while (index < len) {
+ const code3 = header.charCodeAt(index);
+ const flags2 = CHAR_MAP[code3];
+ if ((flags2 & stopFlags) !== 0) {
+ stop2 = flags2 & COMMA_FLAG;
+ break;
+ }
+ index++;
+ }
+ if (stop2 !== 0)
+ break parameter;
+ continue parameter;
+ }
+ if (code2 === BSLASH && index + 1 < len) {
+ escaped = true;
+ index += 2;
+ continue;
+ }
+ index++;
+ }
+ continue parameter;
+ }
+ const valueStart = index;
+ let stop = 0;
+ let valueWhitespace = -1;
+ while (index < len) {
+ const code2 = header.charCodeAt(index);
+ const flags2 = CHAR_MAP[code2];
+ if ((flags2 & stopFlags) !== 0) {
+ stop = flags2 & COMMA_FLAG;
+ break;
+ }
+ if ((flags2 & OWS) !== 0) {
+ if (valueWhitespace === -1)
+ valueWhitespace = index;
+ } else {
+ valueWhitespace = -1;
+ }
+ index++;
+ }
+ if (parameters[key] === void 0) {
+ const valueEnd = valueWhitespace === -1 ? index : valueWhitespace;
+ parameters[key] = header.slice(valueStart, valueEnd);
+ }
+ if (stop !== 0)
+ break parameter;
+ continue parameter;
+ }
+ if ((flags & OWS) !== 0) {
+ if (keyWhitespace === -1)
+ keyWhitespace = index;
+ } else {
+ keyWhitespace = -1;
+ }
+ keyFlags |= code & NON_ASCII | flags;
+ index++;
+ }
+ }
+ return { type, index, parameters };
+}
+function unescapeQuotedPairs(str, start, end) {
+ let result = "";
+ for (let index = start; index < end; index++) {
+ if (str.charCodeAt(index) === BSLASH) {
+ result += str.slice(start, index);
+ start = ++index;
+ }
+ }
+ return result + str.slice(start, end);
+}
// node_modules/json-with-bigint/json-with-bigint.js
var intRegex = /^-?\d+$/;
@@ -21323,84 +21857,333 @@ var noiseValue = /^-?\d+n+$/;
var originalStringify = JSON.stringify;
var originalParse = JSON.parse;
var customFormat = /^-?\d+n$/;
-var bigIntsStringify = /([\[:])?"(-?\d+)n"($|([\\n]|\s)*(\s|[\\n])*[,\}\]])/g;
-var noiseStringify = /([\[:])?("-?\d+n+)n("$|"([\\n]|\s)*(\s|[\\n])*[,\}\]])/g;
+var bigIntsStringify = /([\[:])?"(-?\d+)n"($|\s*[,\}\]])/g;
+var noiseStringify = /([\[:])?("-?\d+n+)n("$|"\s*[,\}\]])/g;
+var isUnstringifiable = (val) => val === void 0 || typeof val === "function" || typeof val === "symbol";
+var isRawJSON = (val) => val !== null && typeof val === "object" && val.constructor && val.constructor.name === "RawJSON";
+var stringifyIteratively = (rootValue, replacer, spaceParam) => {
+ let space = "";
+ if (typeof spaceParam === "number") {
+ space = " ".repeat(Math.min(10, Math.max(0, Math.floor(spaceParam))));
+ } else if (typeof spaceParam === "string") {
+ space = spaceParam.slice(0, 10);
+ }
+ const isFunctionReplacer = typeof replacer === "function";
+ const propertyList = Array.isArray(replacer) ? new Set(replacer.map(String)) : null;
+ const prepareVal = (parent, key, val) => {
+ const isObject = val !== null && typeof val === "object";
+ const hasToJSON = isObject && typeof val.toJSON === "function";
+ if (hasToJSON) {
+ val = val.toJSON(key);
+ }
+ const isNoise = typeof val === "string" && noiseValue.test(val);
+ if (isNoise) return val + "n";
+ const isBigInt = typeof val === "bigint";
+ if (isBigInt) {
+ const supportsRawJSON = "rawJSON" in JSON;
+ if (supportsRawJSON) return JSON.rawJSON(val.toString());
+ return val.toString() + "n";
+ }
+ if (isFunctionReplacer) {
+ val = replacer.call(parent, key, val);
+ }
+ const isPostReplacerObject = val !== null && typeof val === "object";
+ if (isPostReplacerObject) {
+ const isPrimitiveWrapper = val instanceof Number || val instanceof String || val instanceof Boolean;
+ if (isPrimitiveWrapper) {
+ val = val.valueOf();
+ }
+ }
+ return val;
+ };
+ const rootProcessed = prepareVal({ "": rootValue }, "", rootValue);
+ if (isUnstringifiable(rootProcessed)) {
+ return void 0;
+ }
+ const isRootPrimitive = rootProcessed === null || typeof rootProcessed !== "object";
+ const isRootNativeRawJSON = isRawJSON(rootProcessed);
+ if (isRootPrimitive || isRootNativeRawJSON) {
+ return originalStringify(rootProcessed);
+ }
+ const chunks = [];
+ let level = 0;
+ const stack = [
+ {
+ parent: { "": rootProcessed },
+ key: "",
+ val: rootProcessed,
+ isArray: Array.isArray(rootProcessed),
+ keys: Array.isArray(rootProcessed) ? null : Object.keys(rootProcessed),
+ index: 0,
+ first: true
+ }
+ ];
+ const visited = new WeakSet([rootProcessed]);
+ while (stack.length > 0) {
+ const node = stack[stack.length - 1];
+ if (node.index === 0) {
+ chunks.push(node.isArray ? "[" : "{");
+ level++;
+ }
+ let isDone = false;
+ if (node.isArray) {
+ if (node.index < node.val.length) {
+ if (!node.first) chunks.push(",");
+ if (space) chunks.push("\n" + space.repeat(level));
+ const childRaw = node.val[node.index];
+ const childVal = prepareVal(node.val, String(node.index), childRaw);
+ if (isUnstringifiable(childVal)) {
+ chunks.push("null");
+ node.first = false;
+ node.index++;
+ } else {
+ const isComplexObject = childVal !== null && typeof childVal === "object";
+ const isNativeRaw = isRawJSON(childVal);
+ if (isComplexObject && !isNativeRaw) {
+ if (visited.has(childVal)) {
+ throw new TypeError("Converting circular structure to JSON");
+ }
+ visited.add(childVal);
+ stack.push({
+ parent: node.val,
+ key: String(node.index),
+ val: childVal,
+ isArray: Array.isArray(childVal),
+ keys: Array.isArray(childVal) ? null : Object.keys(childVal),
+ index: 0,
+ first: true
+ });
+ node.first = false;
+ node.index++;
+ } else {
+ chunks.push(originalStringify(childVal));
+ node.first = false;
+ node.index++;
+ }
+ }
+ } else {
+ isDone = true;
+ }
+ } else {
+ while (node.index < node.keys.length) {
+ const k = node.keys[node.index++];
+ const isFilteredOutByArray = propertyList && !propertyList.has(k);
+ if (isFilteredOutByArray) continue;
+ const childRaw = node.val[k];
+ const childVal = prepareVal(node.val, k, childRaw);
+ if (isUnstringifiable(childVal)) continue;
+ if (!node.first) chunks.push(",");
+ if (space) {
+ chunks.push("\n" + space.repeat(level) + originalStringify(k) + ": ");
+ } else {
+ chunks.push(originalStringify(k) + ":");
+ }
+ const isComplexObject = childVal !== null && typeof childVal === "object";
+ const isNativeRaw = isRawJSON(childVal);
+ if (isComplexObject && !isNativeRaw) {
+ if (visited.has(childVal)) {
+ throw new TypeError("Converting circular structure to JSON");
+ }
+ visited.add(childVal);
+ stack.push({
+ parent: node.val,
+ key: k,
+ val: childVal,
+ isArray: Array.isArray(childVal),
+ keys: Array.isArray(childVal) ? null : Object.keys(childVal),
+ index: 0,
+ first: true
+ });
+ node.first = false;
+ break;
+ } else {
+ chunks.push(originalStringify(childVal));
+ node.first = false;
+ }
+ }
+ const isNodeFullyProcessed = node.index >= node.keys.length && stack[stack.length - 1] === node;
+ if (isNodeFullyProcessed) {
+ isDone = true;
+ }
+ }
+ if (isDone) {
+ level--;
+ if (!node.first && space) chunks.push("\n" + space.repeat(level));
+ chunks.push(node.isArray ? "]" : "}");
+ visited.delete(node.val);
+ stack.pop();
+ }
+ }
+ return chunks.join("");
+};
var JSONStringify = (value, replacer, space) => {
- if ("rawJSON" in JSON) {
- return originalStringify(
+ try {
+ const supportsRawJSON = "rawJSON" in JSON;
+ if (supportsRawJSON) {
+ return originalStringify(
+ value,
+ (key, val) => {
+ if (typeof val === "bigint") return JSON.rawJSON(val.toString());
+ const hasFunctionReplacer = typeof replacer === "function";
+ if (hasFunctionReplacer) return replacer(key, val);
+ const isKeyInArrayReplacer = Array.isArray(replacer) && replacer.includes(key);
+ if (isKeyInArrayReplacer) return val;
+ return val;
+ },
+ space
+ );
+ }
+ if (!value) return originalStringify(value, replacer, space);
+ const convertedToCustomJSON = originalStringify(
value,
- (key, value2) => {
- if (typeof value2 === "bigint") return JSON.rawJSON(value2.toString());
- if (typeof replacer === "function") return replacer(key, value2);
- if (Array.isArray(replacer) && replacer.includes(key)) return value2;
- return value2;
+ (key, val) => {
+ const isNoise = typeof val === "string" && noiseValue.test(val);
+ if (isNoise) return val.toString() + "n";
+ if (typeof val === "bigint") return val.toString() + "n";
+ const hasFunctionReplacer = typeof replacer === "function";
+ if (hasFunctionReplacer) return replacer(key, val);
+ const isKeyInArrayReplacer = Array.isArray(replacer) && replacer.includes(key);
+ if (isKeyInArrayReplacer) return val;
+ return val;
},
space
);
+ const processedJSON = convertedToCustomJSON.replace(
+ bigIntsStringify,
+ "$1$2$3"
+ );
+ const denoisedJSON = processedJSON.replace(noiseStringify, "$1$2$3");
+ return denoisedJSON;
+ } catch (error2) {
+ if (error2 instanceof RangeError) {
+ const convertedJSON = stringifyIteratively(value, replacer, space);
+ if (convertedJSON === void 0) return void 0;
+ const supportsRawJSON = "rawJSON" in JSON;
+ if (supportsRawJSON) return convertedJSON;
+ const processedJSON = convertedJSON.replace(bigIntsStringify, "$1$2$3");
+ return processedJSON.replace(noiseStringify, "$1$2$3");
+ }
+ throw error2;
+ }
+};
+var featureCache = /* @__PURE__ */ new Map();
+var isContextSourceSupported = () => {
+ const parseFingerprint = JSON.parse.toString();
+ if (featureCache.has(parseFingerprint)) {
+ return featureCache.get(parseFingerprint);
+ }
+ try {
+ const result = JSON.parse(
+ "1",
+ (_, __, context) => !!context?.source && context.source === "1"
+ );
+ featureCache.set(parseFingerprint, result);
+ return result;
+ } catch {
+ featureCache.set(parseFingerprint, false);
+ return false;
}
- if (!value) return originalStringify(value, replacer, space);
- const convertedToCustomJSON = originalStringify(
- value,
- (key, value2) => {
- const isNoise = typeof value2 === "string" && Boolean(value2.match(noiseValue));
- if (isNoise) return value2.toString() + "n";
- if (typeof value2 === "bigint") return value2.toString() + "n";
- if (typeof replacer === "function") return replacer(key, value2);
- if (Array.isArray(replacer) && replacer.includes(key)) return value2;
- return value2;
- },
- space
- );
- const processedJSON = convertedToCustomJSON.replace(
- bigIntsStringify,
- "$1$2$3"
- );
- const denoisedJSON = processedJSON.replace(noiseStringify, "$1$2$3");
- return denoisedJSON;
};
-var isContextSourceSupported = () => JSON.parse("1", (_, __, context) => !!context && context.source === "1");
var convertMarkedBigIntsReviver = (key, value, context, userReviver) => {
- const isCustomFormatBigInt = typeof value === "string" && value.match(customFormat);
+ const isCustomFormatBigInt = typeof value === "string" && customFormat.test(value);
if (isCustomFormatBigInt) return BigInt(value.slice(0, -1));
- const isNoiseValue = typeof value === "string" && value.match(noiseValue);
+ const isNoiseValue = typeof value === "string" && noiseValue.test(value);
if (isNoiseValue) return value.slice(0, -1);
- if (typeof userReviver !== "function") return value;
+ const hasUserReviver = typeof userReviver === "function";
+ if (!hasUserReviver) return value;
return userReviver(key, value, context);
};
var JSONParseV2 = (text, reviver) => {
return JSON.parse(text, (key, value, context) => {
- const isBigNumber = typeof value === "number" && (value > Number.MAX_SAFE_INTEGER || value < Number.MIN_SAFE_INTEGER);
+ const isNumber = typeof value === "number";
+ const isOutOfBounds = value > Number.MAX_SAFE_INTEGER || value < Number.MIN_SAFE_INTEGER;
+ const isBigNumber = isNumber && isOutOfBounds;
const isInt = context && intRegex.test(context.source);
const isBigInt = isBigNumber && isInt;
if (isBigInt) return BigInt(context.source);
- if (typeof reviver !== "function") return value;
+ const hasCustomReviver = typeof reviver === "function";
+ if (!hasCustomReviver) return value;
return reviver(key, value, context);
});
};
var MAX_INT = Number.MAX_SAFE_INTEGER.toString();
var MAX_DIGITS = MAX_INT.length;
-var stringsOrLargeNumbers = /"(?:\\.|[^"])*"|-?(0|[1-9][0-9]*)(\.[0-9]+)?([eE][+-]?[0-9]+)?/g;
+var stringsOrLargeNumbers = /"(?:[^"\\]|\\.)*"|-?(0|[1-9][0-9]*)(\.[0-9]+)?([eE][+-]?[0-9]+)?/g;
var noiseValueWithQuotes = /^"-?\d+n+"$/;
-var JSONParse = (text, reviver) => {
- if (!text) return originalParse(text, reviver);
- if (isContextSourceSupported()) return JSONParseV2(text, reviver);
- const serializedData = text.replace(
+var applyReviverIteratively = (parsed, userReviver) => {
+ const rootHolder = { "": parsed };
+ const stack = [{ parent: rootHolder, key: "", visited: false }];
+ while (stack.length > 0) {
+ const node = stack[stack.length - 1];
+ if (!node.visited) {
+ node.visited = true;
+ const value = node.parent[node.key];
+ const isComplexObject = value !== null && typeof value === "object";
+ if (isComplexObject) {
+ const keys = Object.keys(value);
+ for (let i = keys.length - 1; i >= 0; i--) {
+ stack.push({ parent: value, key: keys[i], visited: false });
+ }
+ }
+ } else {
+ const { parent, key } = node;
+ let value = parent[key];
+ if (typeof value === "string") {
+ const isCustomFormatBigInt = customFormat.test(value);
+ if (isCustomFormatBigInt) {
+ value = BigInt(value.slice(0, -1));
+ } else {
+ const isNoise = noiseValue.test(value);
+ if (isNoise) value = value.slice(0, -1);
+ }
+ }
+ const hasUserReviver = typeof userReviver === "function";
+ if (hasUserReviver) {
+ value = userReviver.call(parent, key, value);
+ }
+ const isDeleted = value === void 0;
+ if (isDeleted) {
+ delete parent[key];
+ } else {
+ parent[key] = value;
+ }
+ stack.pop();
+ }
+ }
+ return rootHolder[""];
+};
+var serializeBigInts = (text) => {
+ return text.replace(
stringsOrLargeNumbers,
- (text2, digits, fractional, exponential) => {
- const isString = text2[0] === '"';
- const isNoise = isString && Boolean(text2.match(noiseValueWithQuotes));
- if (isNoise) return text2.substring(0, text2.length - 1) + 'n"';
- const isFractionalOrExponential = fractional || exponential;
+ (match, digits, fractional, exponential) => {
+ const isString = match[0] === '"';
+ const isNoise = isString && noiseValueWithQuotes.test(match);
+ if (isNoise) return match.substring(0, match.length - 1) + 'n"';
+ const hasFractionalOrExponential = fractional || exponential;
const isLessThanMaxSafeInt = digits && (digits.length < MAX_DIGITS || digits.length === MAX_DIGITS && digits <= MAX_INT);
- if (isString || isFractionalOrExponential || isLessThanMaxSafeInt)
- return text2;
- return '"' + text2 + 'n"';
+ const isStandardValue = isString || hasFractionalOrExponential || isLessThanMaxSafeInt;
+ if (isStandardValue) return match;
+ return '"' + match + 'n"';
}
);
- return originalParse(
- serializedData,
- (key, value, context) => convertMarkedBigIntsReviver(key, value, context, reviver)
- );
+};
+var JSONParse = (text, reviver) => {
+ if (!text) return originalParse(text, reviver);
+ try {
+ if (isContextSourceSupported()) return JSONParseV2(text, reviver);
+ const serializedData = serializeBigInts(text);
+ return originalParse(
+ serializedData,
+ (key, value, context) => convertMarkedBigIntsReviver(key, value, context, reviver)
+ );
+ } catch (error2) {
+ if (error2 instanceof RangeError) {
+ const serializedData = serializeBigInts(text);
+ const parsed = originalParse(serializedData);
+ return applyReviverIteratively(parsed, reviver);
+ }
+ throw error2;
+ }
};
// node_modules/@octokit/request-error/dist-src/index.js
@@ -21443,7 +22226,7 @@ var RequestError = class extends Error {
};
// node_modules/@octokit/request/dist-bundle/index.js
-var VERSION2 = "10.0.8";
+var VERSION2 = "10.0.16";
var defaults_default = {
headers: {
"user-agent": `octokit-request.js/${VERSION2} ${getUserAgent()}`
@@ -21561,7 +22344,7 @@ async function getResponseData(response) {
if (!contentType) {
return response.text().catch(noop);
}
- const mimetype = (0, import_fast_content_type_parse.safeParse)(contentType);
+ const mimetype = parse2(contentType);
if (isJSONResponse(mimetype)) {
let text = "";
try {
@@ -21570,7 +22353,10 @@ async function getResponseData(response) {
} catch (err) {
return text;
}
- } else if (mimetype.type.startsWith("text/") || mimetype.parameters.charset?.toLowerCase() === "utf-8") {
+ } else if (mimetype.type.startsWith("text/") || // `application/octet-stream` is the canonical "arbitrary binary" type
+ // (RFC 2046) and must never be decoded as text, even when the response
+ // carries a (misleading) `charset=utf-8` parameter — see #751.
+ mimetype.parameters.charset?.toLowerCase() === "utf-8" && mimetype.type !== "application/octet-stream") {
return response.text().catch(noop);
} else {
return response.arrayBuffer().catch(
@@ -21589,9 +22375,10 @@ function toErrorMessage(data) {
if (data instanceof ArrayBuffer) {
return "Unknown error";
}
- if ("message" in data) {
- const suffix = "documentation_url" in data ? ` - ${data.documentation_url}` : "";
- return Array.isArray(data.errors) ? `${data.message}: ${data.errors.map((v) => JSON.stringify(v)).join(", ")}${suffix}` : `${data.message}${suffix}`;
+ if (typeof data === "object" && data !== null && "message" in data) {
+ const objectData = data;
+ const suffix = "documentation_url" in objectData ? ` - ${objectData.documentation_url}` : "";
+ return Array.isArray(objectData.errors) ? `${objectData.message}: ${objectData.errors.map((v) => JSON.stringify(v)).join(", ")}${suffix}` : `${objectData.message}${suffix}`;
}
return `Unknown error: ${JSON.stringify(data)}`;
}
@@ -21623,7 +22410,13 @@ var request = withDefaults2(endpoint, defaults_default);
// node_modules/@octokit/oauth-methods/dist-bundle/index.js
function requestToOAuthBaseUrl(request2) {
const endpointDefaults = request2.endpoint.DEFAULTS;
- return /^https:\/\/(api\.)?github\.com$/.test(endpointDefaults.baseUrl) ? "https://github.com" : endpointDefaults.baseUrl.replace("/api/v3", "");
+ if (/^https:\/\/(api\.)?github\.com$/.test(endpointDefaults.baseUrl)) {
+ return "https://github.com";
+ }
+ if (/^https:\/\/api\..*\.ghe\.com$/.test(endpointDefaults.baseUrl)) {
+ return endpointDefaults.baseUrl.replace("api.", "");
+ }
+ return endpointDefaults.baseUrl.replace("/api/v3", "");
}
async function oauthRequest(request2, route, parameters) {
const withOAuthParameters = {
@@ -22893,7 +23686,7 @@ async function sendRequestWithRetries(state, request2, options, createdAt, retri
return sendRequestWithRetries(state, request2, options, createdAt, retries);
}
}
-var VERSION6 = "8.2.0";
+var VERSION6 = "8.3.1";
function createAppAuth(options) {
if (!options.appId) {
throw new Error("[@octokit/auth-app] appId option is required");
@@ -23006,6 +23799,9 @@ function validateRetries(retries) {
if (Number.isNaN(retries)) {
throw new TypeError("Expected `retries` to be a valid number or Infinity, got NaN.");
}
+ if (Number.isFinite(retries) && !Number.isInteger(retries)) {
+ throw new TypeError("Expected `retries` to be a non-negative integer or Infinity.");
+ }
} else if (retries !== void 0) {
throw new TypeError("Expected `retries` to be a number or Infinity.");
}
@@ -23458,6 +24254,13 @@ undici/lib/web/fetch/body.js:
undici/lib/web/websocket/frame.js:
(*! ws. MIT License. Einar Otto Stangvik *)
+content-type/dist/index.js:
+ (*!
+ * content-type
+ * Copyright(c) 2015 Douglas Christopher Wilson
+ * MIT Licensed
+ *)
+
@octokit/request-error/dist-src/index.js:
(* v8 ignore else -- @preserve -- Bug with vitest coverage where it sees an else branch that doesn't exist *)
@@ -23465,6 +24268,19 @@ undici/lib/web/websocket/frame.js:
(* v8 ignore next -- @preserve *)
(* v8 ignore else -- @preserve *)
+@octokit/oauth-methods/dist-bundle/index.js:
+ (* v8 ignore next: we always pass a custom request in tests -- @preserve *)
+
+@octokit/auth-oauth-device/dist-bundle/index.js:
+ (* v8 ignore next 2 -- @preserve *)
+
+@octokit/auth-oauth-user/dist-bundle/index.js:
+ (* v8 ignore if -- @preserve *)
+ (* v8 ignore next -- @preserve *)
+
+@octokit/auth-oauth-app/dist-bundle/index.js:
+ (* v8 ignore next -- @preserve *)
+
toad-cache/dist/toad-cache.mjs:
(**
* toad-cache
@@ -23473,4 +24289,10 @@ toad-cache/dist/toad-cache.mjs:
* @license MIT
* @version 3.7.0
*)
+
+@octokit/auth-app/dist-node/index.js:
+ (* v8 ignore next - permissions are optional per OpenAPI spec, but we think that is incorrect -- @preserve *)
+ (* v8 ignore next - repositorySelection are optional per OpenAPI spec, but we think that is incorrect -- @preserve *)
+ (* v8 ignore start - due to skipped tests, see https://github.com/octokit/auth-app.js/pull/580 -- @preserve *)
+ (* v8 ignore end -- @preserve *)
*/
diff --git a/dist/post.cjs b/dist/post.cjs
index 8e50446c..7dfd77e0 100644
--- a/dist/post.cjs
+++ b/dist/post.cjs
@@ -5,7 +5,11 @@ var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __commonJS = (cb, mod) => function __require() {
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
+ try {
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
+ } catch (e) {
+ throw mod = 0, e;
+ }
};
var __export = (target, all) => {
for (var name in all)
@@ -1853,10 +1857,66 @@ var require_request = __commonJS({
return false;
}
}
- onUpgrade(statusCode, headers, socket) {
+ /**
+ * @param {number|null} statusCode
+ * @param {Buffer[]|null} headers
+ * @param {import('node:stream').Duplex} socket
+ * @param {string} [statusText]
+ */
+ onUpgrade(statusCode, headers, socket, statusText = "") {
+ this.onFinally();
assert(!this.aborted);
assert(!this.completed);
- return this[kHandler].onUpgrade(statusCode, headers, socket);
+ if (statusCode !== null) {
+ this.#publishUpgradeHeaders(statusCode, headers, statusText);
+ }
+ const result = this[kHandler].onUpgrade(statusCode, headers, socket);
+ if (!this.aborted) {
+ this.completed = true;
+ if (statusCode !== null) {
+ this.#publishUpgradeTrailers();
+ }
+ }
+ return result;
+ }
+ /**
+ * @param {number} statusCode
+ * @param {import('node:http2').IncomingHttpHeaders} headers
+ * @param {(headers: import('node:http2').IncomingHttpHeaders) => Buffer[]} parseHeaders
+ * @param {string} [statusText]
+ */
+ onUpgradeResponse(statusCode, headers, parseHeaders, statusText = "") {
+ assert(!this.aborted);
+ assert(this.completed);
+ if (channels.headers.hasSubscribers) {
+ this.#publishUpgradeHeaders(statusCode, parseHeaders(headers), statusText);
+ }
+ this.#publishUpgradeTrailers();
+ }
+ /**
+ * @param {Error} error
+ */
+ onUpgradeError(error2) {
+ assert(!this.aborted);
+ assert(this.completed);
+ if (channels.error.hasSubscribers) {
+ channels.error.publish({ request: this, error: error2 });
+ }
+ }
+ /**
+ * @param {number} statusCode
+ * @param {Buffer[]} headers
+ * @param {string} statusText
+ */
+ #publishUpgradeHeaders(statusCode, headers, statusText) {
+ if (channels.headers.hasSubscribers) {
+ channels.headers.publish({ request: this, response: { statusCode, headers, statusText } });
+ }
+ }
+ #publishUpgradeTrailers() {
+ if (channels.trailers.hasSubscribers) {
+ channels.trailers.publish({ request: this, trailers: [] });
+ }
}
onComplete(trailers) {
this.onFinally();
@@ -1923,7 +1983,11 @@ var require_request = __commonJS({
} else if (typeof val[i] === "object") {
throw new InvalidArgumentError(`invalid ${key} header`);
} else {
- arr.push(`${val[i]}`);
+ const str = `${val[i]}`;
+ if (!isValidHeaderValue(str)) {
+ throw new InvalidArgumentError(`invalid ${key} header`);
+ }
+ arr.push(str);
}
}
val = arr;
@@ -1935,6 +1999,9 @@ var require_request = __commonJS({
val = "";
} else {
val = `${val}`;
+ if (!isValidHeaderValue(val)) {
+ throw new InvalidArgumentError(`invalid ${key} header`);
+ }
}
if (headerName === "host") {
if (request2.host !== null) {
@@ -2044,13 +2111,21 @@ var require_dispatcher_base = __commonJS({
var kOnDestroyed = /* @__PURE__ */ Symbol("onDestroyed");
var kOnClosed = /* @__PURE__ */ Symbol("onClosed");
var kInterceptedDispatch = /* @__PURE__ */ Symbol("Intercepted Dispatch");
+ var kWebSocketOptions = /* @__PURE__ */ Symbol("webSocketOptions");
var DispatcherBase = class extends Dispatcher {
- constructor() {
+ constructor(opts) {
super();
this[kDestroyed] = false;
this[kOnDestroyed] = null;
this[kClosed] = false;
this[kOnClosed] = [];
+ this[kWebSocketOptions] = opts?.webSocket ?? {};
+ }
+ get webSocketOptions() {
+ return {
+ maxFragments: this[kWebSocketOptions].maxFragments ?? 131072,
+ maxPayloadSize: this[kWebSocketOptions].maxPayloadSize ?? 128 * 1024 * 1024
+ };
}
get destroyed() {
return this[kDestroyed];
@@ -5657,6 +5732,7 @@ var require_client_h1 = __commonJS({
RequestContentLengthMismatchError,
ResponseContentLengthMismatchError,
RequestAbortedError,
+ InvalidArgumentError,
HeadersTimeoutError,
HeadersOverflowError,
SocketError,
@@ -5703,6 +5779,9 @@ var require_client_h1 = __commonJS({
var FastBuffer = Buffer[Symbol.species];
var addListener = util.addListener;
var removeAllListeners = util.removeAllListeners;
+ var kIdleSocketValidation = /* @__PURE__ */ Symbol("kIdleSocketValidation");
+ var kIdleSocketValidationTimeout = /* @__PURE__ */ Symbol("kIdleSocketValidationTimeout");
+ var kSocketUsed = /* @__PURE__ */ Symbol("kSocketUsed");
var extractBody;
async function lazyllhttp() {
const llhttpWasmData = process.env.JEST_WORKER_ID ? require_llhttp_wasm() : void 0;
@@ -5865,24 +5944,55 @@ var require_client_h1 = __commonJS({
currentBufferRef = null;
}
const offset = llhttp.llhttp_get_error_pos(this.ptr) - currentBufferPtr;
- if (ret === constants3.ERROR.PAUSED_UPGRADE) {
- this.onUpgrade(data.slice(offset));
- } else if (ret === constants3.ERROR.PAUSED) {
- this.paused = true;
- socket.unshift(data.slice(offset));
- } else if (ret !== constants3.ERROR.OK) {
- const ptr = llhttp.llhttp_get_error_reason(this.ptr);
- let message = "";
- if (ptr) {
- const len = new Uint8Array(llhttp.memory.buffer, ptr).indexOf(0);
- message = "Response does not match the HTTP/1.1 protocol (" + Buffer.from(llhttp.memory.buffer, ptr, len).toString() + ")";
+ if (ret !== constants3.ERROR.OK) {
+ const body = data.subarray(offset);
+ if (ret === constants3.ERROR.PAUSED_UPGRADE) {
+ this.onUpgrade(body);
+ } else if (ret === constants3.ERROR.PAUSED) {
+ this.paused = true;
+ socket.unshift(body);
+ } else {
+ throw this.createError(ret, body);
}
- throw new HTTPParserError(message, constants3.ERROR[ret], data.slice(offset));
}
} catch (err) {
util.destroy(socket, err);
}
}
+ finish() {
+ assert(currentParser === null);
+ assert(this.ptr != null);
+ assert(!this.paused);
+ const { llhttp } = this;
+ let ret;
+ try {
+ currentParser = this;
+ ret = llhttp.llhttp_finish(this.ptr);
+ } finally {
+ currentParser = null;
+ }
+ if (ret === constants3.ERROR.OK) {
+ return null;
+ }
+ if (ret === constants3.ERROR.PAUSED || ret === constants3.ERROR.PAUSED_UPGRADE) {
+ this.paused = true;
+ return null;
+ }
+ return this.createError(ret, EMPTY_BUF);
+ }
+ createError(ret, data) {
+ const { llhttp, contentLength, bytesRead } = this;
+ if (contentLength && bytesRead !== parseInt(contentLength, 10)) {
+ return new ResponseContentLengthMismatchError();
+ }
+ const ptr = llhttp.llhttp_get_error_reason(this.ptr);
+ let message = "";
+ if (ptr) {
+ const len = new Uint8Array(llhttp.memory.buffer, ptr).indexOf(0);
+ message = "Response does not match the HTTP/1.1 protocol (" + Buffer.from(llhttp.memory.buffer, ptr, len).toString() + ")";
+ }
+ return new HTTPParserError(message, constants3.ERROR[ret], data);
+ }
destroy() {
assert(this.ptr != null);
assert(currentParser == null);
@@ -5902,6 +6012,10 @@ var require_client_h1 = __commonJS({
if (socket.destroyed) {
return -1;
}
+ if (client[kRunning] === 0) {
+ util.destroy(socket, new SocketError("bad response", util.getSocketInfo(socket)));
+ return -1;
+ }
const request2 = client[kQueue][client[kRunningIdx]];
if (!request2) {
return -1;
@@ -5945,7 +6059,7 @@ var require_client_h1 = __commonJS({
}
}
onUpgrade(head) {
- const { upgrade, client, socket, headers, statusCode } = this;
+ const { upgrade, client, socket, headers, statusCode, statusText } = this;
assert(upgrade);
assert(client[kSocket] === socket);
assert(!socket.destroyed);
@@ -5970,9 +6084,10 @@ var require_client_h1 = __commonJS({
client[kQueue][client[kRunningIdx]++] = null;
client.emit("disconnect", client[kUrl], [client], new InformationalError("upgrade"));
try {
- request2.onUpgrade(statusCode, headers, socket);
- } catch (err) {
- util.destroy(socket, err);
+ request2.onUpgrade(statusCode, headers, socket, statusText);
+ } catch (error2) {
+ util.errorRequest(client, request2, error2);
+ util.destroy(socket, error2);
}
client[kResume]();
}
@@ -5981,6 +6096,10 @@ var require_client_h1 = __commonJS({
if (socket.destroyed) {
return -1;
}
+ if (client[kRunning] === 0) {
+ util.destroy(socket, new SocketError("bad response", util.getSocketInfo(socket)));
+ return -1;
+ }
const request2 = client[kQueue][client[kRunningIdx]];
if (!request2) {
return -1;
@@ -6106,6 +6225,7 @@ var require_client_h1 = __commonJS({
}
request2.onComplete(headers);
client[kQueue][client[kRunningIdx]++] = null;
+ socket[kSocketUsed] = true;
if (socket[kWriting]) {
assert(client[kRunning] === 0);
util.destroy(socket, new InformationalError("reset"));
@@ -6149,12 +6269,19 @@ var require_client_h1 = __commonJS({
socket[kWriting] = false;
socket[kReset] = false;
socket[kBlocking] = false;
+ socket[kIdleSocketValidation] = 0;
+ socket[kIdleSocketValidationTimeout] = null;
+ socket[kSocketUsed] = false;
socket[kParser] = new Parser(client, socket, llhttpInstance);
addListener(socket, "error", function(err) {
assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID");
const parser = this[kParser];
if (err.code === "ECONNRESET" && parser.statusCode && !parser.shouldKeepAlive) {
- parser.onMessageComplete();
+ const parserErr = parser.finish();
+ if (parserErr) {
+ this[kError] = parserErr;
+ this[kClient][kOnError](parserErr);
+ }
return;
}
this[kError] = err;
@@ -6169,7 +6296,10 @@ var require_client_h1 = __commonJS({
addListener(socket, "end", function() {
const parser = this[kParser];
if (parser.statusCode && !parser.shouldKeepAlive) {
- parser.onMessageComplete();
+ const parserErr = parser.finish();
+ if (parserErr) {
+ util.destroy(this, parserErr);
+ }
return;
}
util.destroy(this, new SocketError("other side closed", util.getSocketInfo(this)));
@@ -6177,9 +6307,10 @@ var require_client_h1 = __commonJS({
addListener(socket, "close", function() {
const client2 = this[kClient];
const parser = this[kParser];
+ clearIdleSocketValidation(this);
if (parser) {
if (!this[kError] && parser.statusCode && !parser.shouldKeepAlive) {
- parser.onMessageComplete();
+ this[kError] = parser.finish() || this[kError];
}
this[kParser].destroy();
this[kParser] = null;
@@ -6228,7 +6359,7 @@ var require_client_h1 = __commonJS({
return socket.destroyed;
},
busy(request2) {
- if (socket[kWriting] || socket[kReset] || socket[kBlocking]) {
+ if (socket[kWriting] || socket[kReset] || socket[kBlocking] || socket[kIdleSocketValidation] === 1) {
return true;
}
if (request2) {
@@ -6246,6 +6377,23 @@ var require_client_h1 = __commonJS({
}
};
}
+ function clearIdleSocketValidation(socket) {
+ if (socket[kIdleSocketValidationTimeout]) {
+ clearImmediate(socket[kIdleSocketValidationTimeout]);
+ socket[kIdleSocketValidationTimeout] = null;
+ }
+ socket[kIdleSocketValidation] = 0;
+ }
+ function scheduleIdleSocketValidation(client, socket) {
+ socket[kIdleSocketValidation] = 1;
+ socket[kIdleSocketValidationTimeout] = setImmediate(() => {
+ socket[kIdleSocketValidationTimeout] = null;
+ socket[kIdleSocketValidation] = 2;
+ if (client[kSocket] === socket && !socket.destroyed) {
+ client[kResume]();
+ }
+ });
+ }
function resumeH1(client) {
const socket = client[kSocket];
if (socket && !socket.destroyed) {
@@ -6258,6 +6406,29 @@ var require_client_h1 = __commonJS({
socket.ref();
socket[kNoRef] = false;
}
+ if (client[kRunning] === 0 && client[kPending] > 0 && socket[kSocketUsed]) {
+ if (socket[kIdleSocketValidation] === 0) {
+ scheduleIdleSocketValidation(client, socket);
+ socket[kParser].readMore();
+ if (socket.destroyed) {
+ return;
+ }
+ return;
+ }
+ if (socket[kIdleSocketValidation] === 1) {
+ socket[kParser].readMore();
+ if (socket.destroyed) {
+ return;
+ }
+ return;
+ }
+ }
+ if (client[kRunning] === 0) {
+ socket[kParser].readMore();
+ if (socket.destroyed) {
+ return;
+ }
+ }
if (client[kSize] === 0) {
if (socket[kParser].timeoutType !== TIMEOUT_KEEP_ALIVE) {
socket[kParser].setTimeout(client[kKeepAliveTimeoutValue], TIMEOUT_KEEP_ALIVE);
@@ -6288,8 +6459,16 @@ var require_client_h1 = __commonJS({
}
body = bodyStream.stream;
contentLength = bodyStream.length;
- } else if (util.isBlobLike(body) && request2.contentType == null && body.type) {
- headers.push("content-type", body.type);
+ } else if (util.isBlobLike(body) && request2.contentType == null) {
+ const contentType = body.type;
+ if (contentType) {
+ const contentTypeValue = `${contentType}`;
+ if (!util.isValidHeaderValue(contentTypeValue)) {
+ util.errorRequest(client, request2, new InvalidArgumentError("invalid content-type header"));
+ return false;
+ }
+ headers.push("content-type", contentTypeValue);
+ }
}
if (body && typeof body.read === "function") {
body.read(0);
@@ -6310,11 +6489,18 @@ var require_client_h1 = __commonJS({
process.emitWarning(new RequestContentLengthMismatchError());
}
const socket = client[kSocket];
- const abort = (err) => {
- if (request2.aborted || request2.completed) {
+ clearIdleSocketValidation(socket);
+ const abort = (error2) => {
+ if (request2.aborted) {
+ return;
+ }
+ if (request2.completed) {
+ if (request2.upgrade || request2.method === "CONNECT") {
+ util.destroy(socket, new InformationalError("aborted"));
+ }
return;
}
- util.errorRequest(client, request2, err || new RequestAbortedError());
+ util.errorRequest(client, request2, error2 || new RequestAbortedError());
util.destroy(body);
util.destroy(socket, new InformationalError("aborted"));
};
@@ -6670,6 +6856,7 @@ var require_client_h2 = __commonJS({
"node_modules/@actions/http-client/node_modules/undici/lib/dispatcher/client-h2.js"(exports2, module2) {
"use strict";
var assert = require("node:assert");
+ var { errorMonitor } = require("node:events");
var { pipeline } = require("node:stream");
var util = require_util();
var {
@@ -6730,6 +6917,10 @@ var require_client_h2 = __commonJS({
}
return result;
}
+ function parseH2ResponseHeaders(headers) {
+ const { [HTTP2_HEADER_STATUS]: _statusCode, ...realHeaders } = headers;
+ return parseH2Headers(realHeaders);
+ }
async function connectH2(client, socket) {
client[kSocket] = socket;
if (!h2ExperimentalWarned) {
@@ -6893,16 +7084,22 @@ var require_client_h2 = __commonJS({
const { hostname, port } = client[kUrl];
headers[HTTP2_HEADER_AUTHORITY] = host || `${hostname}${port ? `:${port}` : ""}`;
headers[HTTP2_HEADER_METHOD] = method;
- const abort = (err) => {
- if (request2.aborted || request2.completed) {
+ const abort = (error2) => {
+ if (request2.aborted) {
return;
}
- err = err || new RequestAbortedError();
- util.errorRequest(client, request2, err);
+ if (request2.completed) {
+ if (method === "CONNECT" && stream != null) {
+ util.destroy(stream, error2 || new RequestAbortedError());
+ }
+ return;
+ }
+ error2 = error2 || new RequestAbortedError();
+ util.errorRequest(client, request2, error2);
if (stream != null) {
- util.destroy(stream, err);
+ util.destroy(stream, error2);
}
- util.destroy(body, err);
+ util.destroy(body, error2);
client[kQueue][client[kRunningIdx]++] = null;
client[kResume]();
};
@@ -6917,18 +7114,42 @@ var require_client_h2 = __commonJS({
if (method === "CONNECT") {
session.ref();
stream = session.request(headers, { endStream: false, signal });
- if (stream.id && !stream.pending) {
- request2.onUpgrade(null, null, stream);
- ++session[kOpenStreams];
- client[kQueue][client[kRunningIdx]++] = null;
- } else {
- stream.once("ready", () => {
+ let upgradeResponseFinished = false;
+ const onResponse = (headers2) => {
+ upgradeResponseFinished = true;
+ stream.off(errorMonitor, onUpgradeError);
+ request2.onUpgradeResponse(Number(headers2[HTTP2_HEADER_STATUS]), headers2, parseH2ResponseHeaders);
+ };
+ const onUpgradeError = (error2) => {
+ upgradeResponseFinished = true;
+ stream.off("response", onResponse);
+ request2.onUpgradeError(error2);
+ };
+ const onReady = () => {
+ try {
request2.onUpgrade(null, null, stream);
- ++session[kOpenStreams];
- client[kQueue][client[kRunningIdx]++] = null;
- });
- }
+ } catch (error2) {
+ stream.off("response", onResponse);
+ abort(error2);
+ return;
+ }
+ if (request2.aborted) {
+ return;
+ }
+ stream.off("error", abort);
+ stream.once(errorMonitor, onUpgradeError);
+ client[kQueue][client[kRunningIdx]++] = null;
+ };
+ stream.once("response", onResponse);
+ stream.once("error", abort);
+ ++session[kOpenStreams];
+ onReady();
stream.once("close", () => {
+ if (!upgradeResponseFinished && request2.completed) {
+ stream.off("response", onResponse);
+ stream.off(errorMonitor, onUpgradeError);
+ request2.onUpgradeError(new InformationalError(`HTTP/2: "stream error" received - code ${stream.rstCode}`));
+ }
session[kOpenStreams] -= 1;
if (session[kOpenStreams] === 0) session.unref();
});
@@ -7489,9 +7710,10 @@ var require_client = __commonJS({
autoSelectFamilyAttemptTimeout,
// h2
maxConcurrentStreams,
- allowH2
+ allowH2,
+ webSocket
} = {}) {
- super();
+ super({ webSocket });
if (keepAlive !== void 0) {
throw new InvalidArgumentError("unsupported keepAlive, use pipelining=0 instead");
}
@@ -7997,8 +8219,8 @@ var require_pool_base = __commonJS({
var kRemoveClient = /* @__PURE__ */ Symbol("remove client");
var kStats = /* @__PURE__ */ Symbol("stats");
var PoolBase = class extends DispatcherBase {
- constructor() {
- super();
+ constructor(opts) {
+ super(opts);
this[kQueue] = new FixedQueue();
this[kClients] = [];
this[kQueued] = 0;
@@ -8169,7 +8391,6 @@ var require_pool = __commonJS({
allowH2,
...options
} = {}) {
- super();
if (connections != null && (!Number.isFinite(connections) || connections < 0)) {
throw new InvalidArgumentError("invalid connections");
}
@@ -8190,6 +8411,7 @@ var require_pool = __commonJS({
...connect
});
}
+ super(options);
this[kInterceptors] = options.interceptors?.Pool && Array.isArray(options.interceptors.Pool) ? options.interceptors.Pool : [];
this[kConnections] = connections || null;
this[kUrl] = util.parseOrigin(origin);
@@ -8389,7 +8611,6 @@ var require_agent = __commonJS({
}
var Agent3 = class extends DispatcherBase {
constructor({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) {
- super();
if (typeof factory !== "function") {
throw new InvalidArgumentError("factory must be a function.");
}
@@ -8399,6 +8620,7 @@ var require_agent = __commonJS({
if (!Number.isInteger(maxRedirections) || maxRedirections < 0) {
throw new InvalidArgumentError("maxRedirections must be a positive number");
}
+ super(options);
if (connect && typeof connect !== "function") {
connect = { ...connect };
}
@@ -8839,6 +9061,24 @@ var require_retry_handler = __commonJS({
const current = Date.now();
return new Date(retryAfter).getTime() - current;
}
+ function validatePartialResponseContentLength(headers, range, statusCode, retryCount) {
+ const contentLength = headers["content-length"];
+ if (contentLength == null) {
+ return null;
+ }
+ if (!Number.isFinite(range.start) || !Number.isFinite(range.end)) {
+ return null;
+ }
+ const length = Number(contentLength);
+ const expectedLength = range.end - range.start + 1;
+ if (!Number.isFinite(length) || length !== expectedLength) {
+ return new RequestRetryError("Content-Length mismatch", statusCode, {
+ headers,
+ data: { count: retryCount }
+ });
+ }
+ return null;
+ }
var RetryHandler = class _RetryHandler {
constructor(opts, handlers) {
const { retryOptions, ...dispatchOpts } = opts;
@@ -8892,6 +9132,7 @@ var require_retry_handler = __commonJS({
this.end = null;
this.etag = null;
this.resume = null;
+ this.headersSent = false;
this.handler.onConnect((reason) => {
this.aborted = true;
if (this.abort) {
@@ -8901,6 +9142,17 @@ var require_retry_handler = __commonJS({
}
});
}
+ checkpointResponseEnd(headers, resume) {
+ if (this.end == null && this.opts.method !== "HEAD") {
+ const contentLength = headers["content-length"];
+ this.end = contentLength != null ? Number(contentLength) - 1 : null;
+ assert(
+ this.end == null || Number.isFinite(this.end),
+ "invalid content-length"
+ );
+ }
+ this.resume = this.end != null ? resume : null;
+ }
onRequestSent() {
if (this.handler.onRequestSent) {
this.handler.onRequestSent();
@@ -8962,7 +9214,9 @@ var require_retry_handler = __commonJS({
const headers = parseHeaders(rawHeaders);
this.retryCount += 1;
if (statusCode >= 300) {
- if (this.retryOpts.statusCodes.includes(statusCode) === false) {
+ if (!this.headersSent && this.retryOpts.statusCodes.includes(statusCode) === false) {
+ this.headersSent = true;
+ this.checkpointResponseEnd(headers, resume);
return this.handler.onHeaders(
statusCode,
rawHeaders,
@@ -9011,9 +9265,21 @@ var require_retry_handler = __commonJS({
);
return false;
}
+ const contentLengthError = validatePartialResponseContentLength(headers, contentRange, statusCode, this.retryCount);
+ if (contentLengthError != null) {
+ this.abort(contentLengthError);
+ return false;
+ }
const { start, size, end = size - 1 } = contentRange;
- assert(this.start === start, "content-range mismatch");
- assert(this.end == null || this.end === end, "content-range mismatch");
+ if (this.start !== start || this.end != null && this.end !== end) {
+ this.abort(
+ new RequestRetryError("Content-Range mismatch", statusCode, {
+ headers,
+ data: { count: this.retryCount }
+ })
+ );
+ return false;
+ }
this.resume = resume;
return true;
}
@@ -9021,6 +9287,7 @@ var require_retry_handler = __commonJS({
if (statusCode === 206) {
const range = parseRangeHeader(headers["content-range"]);
if (range == null) {
+ this.headersSent = true;
return this.handler.onHeaders(
statusCode,
rawHeaders,
@@ -9028,6 +9295,11 @@ var require_retry_handler = __commonJS({
statusMessage
);
}
+ const contentLengthError = validatePartialResponseContentLength(headers, range, statusCode, this.retryCount);
+ if (contentLengthError != null) {
+ this.abort(contentLengthError);
+ return false;
+ }
const { start, size, end = size - 1 } = range;
assert(
start != null && Number.isFinite(start),
@@ -9047,6 +9319,7 @@ var require_retry_handler = __commonJS({
"invalid content-length"
);
this.resume = resume;
+ this.headersSent = true;
this.etag = headers.etag != null ? headers.etag : null;
if (this.etag != null && this.etag.startsWith("W/")) {
this.etag = null;
@@ -9074,7 +9347,7 @@ var require_retry_handler = __commonJS({
return this.handler.onComplete(rawTrailers);
}
onError(err) {
- if (this.aborted || isDisturbed(this.opts.body)) {
+ if (this.aborted || isDisturbed(this.opts.body) || this.headersSent && this.resume == null) {
return this.handler.onError(err);
}
if (this.retryCount - this.retryCountCheckpoint > 0) {
@@ -15873,14 +16146,48 @@ var require_util6 = __commonJS({
for (let i = 0; i < path6.length; ++i) {
const code = path6.charCodeAt(i);
if (code < 32 || // exclude CTLs (0-31)
- code === 127 || // DEL
+ code > 126 || // exclude DEL and non-ascii
code === 59) {
throw new Error("Invalid cookie path");
}
}
}
+ function isLetterOrDigit(code) {
+ return code >= 48 && code <= 57 || // 0-9
+ code >= 65 && code <= 90 || // A-Z
+ code >= 97 && code <= 122;
+ }
function validateCookieDomain(domain) {
- if (domain.startsWith("-") || domain.endsWith(".") || domain.endsWith("-")) {
+ if (domain === " ") {
+ return;
+ }
+ if (domain.length > 255) {
+ throw new Error("Invalid cookie domain");
+ }
+ let labelLength = 0;
+ for (let i = 0; i < domain.length; ++i) {
+ const code = domain.charCodeAt(i);
+ if (code === 46) {
+ if (labelLength === 0) {
+ throw new Error("Invalid cookie domain");
+ }
+ if (domain.charCodeAt(i - 1) === 45) {
+ throw new Error("Invalid cookie domain");
+ }
+ labelLength = 0;
+ continue;
+ }
+ if (labelLength === 0 && !isLetterOrDigit(code)) {
+ throw new Error("Invalid cookie domain");
+ }
+ if (!isLetterOrDigit(code) && code !== 45) {
+ throw new Error("Invalid cookie domain");
+ }
+ if (++labelLength > 63) {
+ throw new Error("Invalid cookie domain");
+ }
+ }
+ if (labelLength === 0 || domain.charCodeAt(domain.length - 1) === 45) {
throw new Error("Invalid cookie domain");
}
}
@@ -15963,7 +16270,11 @@ var require_util6 = __commonJS({
throw new Error("Invalid unparsed");
}
const [key, ...value] = part.split("=");
- out.push(`${key.trim()}=${value.join("=")}`);
+ const trimmedKey = key.trim();
+ const joinedValue = value.join("=");
+ validateCookieName(trimmedKey);
+ validateCookieValue(joinedValue);
+ out.push(`${trimmedKey}=${joinedValue}`);
}
return out.join("; ");
}
@@ -16093,18 +16404,14 @@ var require_parse = __commonJS({
} else if (attributeNameLowercase === "httponly") {
cookieAttributeList.httpOnly = true;
} else if (attributeNameLowercase === "samesite") {
- let enforcement = "Default";
const attributeValueLowercase = attributeValue.toLowerCase();
- if (attributeValueLowercase.includes("none")) {
- enforcement = "None";
- }
- if (attributeValueLowercase.includes("strict")) {
- enforcement = "Strict";
+ if (attributeValueLowercase === "none") {
+ cookieAttributeList.sameSite = "None";
+ } else if (attributeValueLowercase === "strict") {
+ cookieAttributeList.sameSite = "Strict";
+ } else if (attributeValueLowercase === "lax") {
+ cookieAttributeList.sameSite = "Lax";
}
- if (attributeValueLowercase.includes("lax")) {
- enforcement = "Lax";
- }
- cookieAttributeList.sameSite = enforcement;
} else {
cookieAttributeList.unparsed ??= [];
cookieAttributeList.unparsed.push(`${attributeName}=${attributeValue}`);
@@ -16926,7 +17233,7 @@ var require_connection = __commonJS({
const secProtocol = response.headersList.get("Sec-WebSocket-Protocol");
if (secProtocol !== null) {
const requestProtocols = getDecodeSplit("sec-websocket-protocol", request2.headersList);
- if (!requestProtocols.includes(secProtocol)) {
+ if (requestProtocols === null || !requestProtocols.includes(secProtocol)) {
failWebsocketConnection(ws, "Protocol was not set in the opening handshake.");
return;
}
@@ -17032,31 +17339,26 @@ var require_permessage_deflate = __commonJS({
var tail = Buffer.from([0, 0, 255, 255]);
var kBuffer = /* @__PURE__ */ Symbol("kBuffer");
var kLength = /* @__PURE__ */ Symbol("kLength");
- var kDefaultMaxDecompressedSize = 4 * 1024 * 1024;
var PerMessageDeflate = class {
/** @type {import('node:zlib').InflateRaw} */
#inflate;
#options = {};
- /** @type {number} */
- #maxDecompressedSize;
- /** @type {boolean} */
- #aborted = false;
- /** @type {Function|null} */
- #currentCallback = null;
+ #maxPayloadSize = 0;
/**
* @param {Map} extensions
- * @param {{ maxDecompressedMessageSize?: number }} [options]
*/
- constructor(extensions, options = {}) {
+ constructor(extensions, options) {
this.#options.serverNoContextTakeover = extensions.has("server_no_context_takeover");
this.#options.serverMaxWindowBits = extensions.get("server_max_window_bits");
- this.#maxDecompressedSize = options.maxDecompressedMessageSize ?? kDefaultMaxDecompressedSize;
+ this.#maxPayloadSize = options.maxPayloadSize;
}
+ /**
+ * Decompress a compressed payload.
+ * @param {Buffer} chunk Compressed data
+ * @param {boolean} fin Final fragment flag
+ * @param {Function} callback Callback function
+ */
decompress(chunk, fin, callback) {
- if (this.#aborted) {
- callback(new MessageSizeExceededError());
- return;
- }
if (!this.#inflate) {
let windowBits = Z_DEFAULT_WINDOWBITS;
if (this.#options.serverMaxWindowBits) {
@@ -17075,20 +17377,12 @@ var require_permessage_deflate = __commonJS({
this.#inflate[kBuffer] = [];
this.#inflate[kLength] = 0;
this.#inflate.on("data", (data) => {
- if (this.#aborted) {
- return;
- }
this.#inflate[kLength] += data.length;
- if (this.#inflate[kLength] > this.#maxDecompressedSize) {
- this.#aborted = true;
+ if (this.#maxPayloadSize > 0 && this.#inflate[kLength] > this.#maxPayloadSize) {
+ callback(new MessageSizeExceededError());
this.#inflate.removeAllListeners();
this.#inflate.destroy();
this.#inflate = null;
- if (this.#currentCallback) {
- const cb = this.#currentCallback;
- this.#currentCallback = null;
- cb(new MessageSizeExceededError());
- }
return;
}
this.#inflate[kBuffer].push(data);
@@ -17098,19 +17392,17 @@ var require_permessage_deflate = __commonJS({
callback(err);
});
}
- this.#currentCallback = callback;
this.#inflate.write(chunk);
if (fin) {
this.#inflate.write(tail);
}
this.#inflate.flush(() => {
- if (this.#aborted || !this.#inflate) {
+ if (!this.#inflate) {
return;
}
const full = Buffer.concat(this.#inflate[kBuffer], this.#inflate[kLength]);
this.#inflate[kBuffer].length = 0;
this.#inflate[kLength] = 0;
- this.#currentCallback = null;
callback(null, full);
});
}
@@ -17141,8 +17433,14 @@ var require_receiver = __commonJS({
var { WebsocketFrameSend } = require_frame();
var { closeWebSocketConnection } = require_connection();
var { PerMessageDeflate } = require_permessage_deflate();
+ var { MessageSizeExceededError } = require_errors();
+ function failWebsocketConnectionWithCode(ws, code, reason) {
+ closeWebSocketConnection(ws, code, reason, Buffer.byteLength(reason));
+ failWebsocketConnection(ws, reason);
+ }
var ByteParser = class extends Writable {
#buffers = [];
+ #fragmentsBytes = 0;
#byteOffset = 0;
#loop = false;
#state = parserStates.INFO;
@@ -17150,18 +17448,21 @@ var require_receiver = __commonJS({
#fragments = [];
/** @type {Map} */
#extensions;
- /** @type {{ maxDecompressedMessageSize?: number }} */
- #options;
+ /** @type {number} */
+ #maxFragments;
+ /** @type {number} */
+ #maxPayloadSize;
/**
* @param {import('./websocket').WebSocket} ws
* @param {Map|null} extensions
- * @param {{ maxDecompressedMessageSize?: number }} [options]
+ * @param {{ maxFragments?: number, maxPayloadSize?: number }} [options]
*/
constructor(ws, extensions, options = {}) {
super();
this.ws = ws;
this.#extensions = extensions == null ? /* @__PURE__ */ new Map() : extensions;
- this.#options = options;
+ this.#maxFragments = options.maxFragments ?? 0;
+ this.#maxPayloadSize = options.maxPayloadSize ?? 0;
if (this.#extensions.has("permessage-deflate")) {
this.#extensions.set("permessage-deflate", new PerMessageDeflate(extensions, options));
}
@@ -17176,6 +17477,13 @@ var require_receiver = __commonJS({
this.#loop = true;
this.run(callback);
}
+ #validatePayloadLength() {
+ if (this.#maxPayloadSize > 0 && !isControlFrame(this.#info.opcode) && this.#info.payloadLength + this.#fragmentsBytes > this.#maxPayloadSize) {
+ failWebsocketConnectionWithCode(this.ws, 1009, "Payload size exceeds maximum allowed size");
+ return false;
+ }
+ return true;
+ }
/**
* Runs whenever a new chunk is received.
* Callback is called whenever there are no more chunks buffering,
@@ -17235,6 +17543,9 @@ var require_receiver = __commonJS({
if (payloadLength <= 125) {
this.#info.payloadLength = payloadLength;
this.#state = parserStates.READ_DATA;
+ if (!this.#validatePayloadLength()) {
+ return;
+ }
} else if (payloadLength === 126) {
this.#state = parserStates.PAYLOADLENGTH_16;
} else if (payloadLength === 127) {
@@ -17255,6 +17566,9 @@ var require_receiver = __commonJS({
const buffer = this.consume(2);
this.#info.payloadLength = buffer.readUInt16BE(0);
this.#state = parserStates.READ_DATA;
+ if (!this.#validatePayloadLength()) {
+ return;
+ }
} else if (this.#state === parserStates.PAYLOADLENGTH_64) {
if (this.#byteOffset < 8) {
return callback();
@@ -17268,6 +17582,9 @@ var require_receiver = __commonJS({
}
this.#info.payloadLength = lower;
this.#state = parserStates.READ_DATA;
+ if (!this.#validatePayloadLength()) {
+ return;
+ }
} else if (this.#state === parserStates.READ_DATA) {
if (this.#byteOffset < this.#info.payloadLength) {
return callback();
@@ -17278,32 +17595,46 @@ var require_receiver = __commonJS({
this.#state = parserStates.INFO;
} else {
if (!this.#info.compressed) {
- this.#fragments.push(body);
+ if (!this.writeFragments(body)) {
+ return;
+ }
+ if (this.#maxPayloadSize > 0 && this.#fragmentsBytes > this.#maxPayloadSize) {
+ failWebsocketConnectionWithCode(this.ws, 1009, new MessageSizeExceededError().message);
+ return;
+ }
if (!this.#info.fragmented && this.#info.fin) {
- const fullMessage = Buffer.concat(this.#fragments);
- websocketMessageReceived(this.ws, this.#info.binaryType, fullMessage);
- this.#fragments.length = 0;
+ websocketMessageReceived(this.ws, this.#info.binaryType, this.consumeFragments());
}
this.#state = parserStates.INFO;
} else {
- this.#extensions.get("permessage-deflate").decompress(body, this.#info.fin, (error2, data) => {
- if (error2) {
- failWebsocketConnection(this.ws, error2.message);
- return;
- }
- this.#fragments.push(data);
- if (!this.#info.fin) {
- this.#state = parserStates.INFO;
+ this.#extensions.get("permessage-deflate").decompress(
+ body,
+ this.#info.fin,
+ (error2, data) => {
+ if (error2) {
+ const code = error2 instanceof MessageSizeExceededError ? 1009 : 1007;
+ failWebsocketConnectionWithCode(this.ws, code, error2.message);
+ return;
+ }
+ if (!this.writeFragments(data)) {
+ return;
+ }
+ if (this.#maxPayloadSize > 0 && this.#fragmentsBytes > this.#maxPayloadSize) {
+ failWebsocketConnectionWithCode(this.ws, 1009, new MessageSizeExceededError().message);
+ return;
+ }
+ if (!this.#info.fin) {
+ this.#state = parserStates.INFO;
+ this.#loop = true;
+ this.run(callback);
+ return;
+ }
+ websocketMessageReceived(this.ws, this.#info.binaryType, this.consumeFragments());
this.#loop = true;
+ this.#state = parserStates.INFO;
this.run(callback);
- return;
}
- websocketMessageReceived(this.ws, this.#info.binaryType, Buffer.concat(this.#fragments));
- this.#loop = true;
- this.#state = parserStates.INFO;
- this.#fragments.length = 0;
- this.run(callback);
- });
+ );
this.#loop = false;
break;
}
@@ -17346,6 +17677,26 @@ var require_receiver = __commonJS({
this.#byteOffset -= n;
return buffer;
}
+ writeFragments(fragment) {
+ if (this.#maxFragments > 0 && this.#fragments.length === this.#maxFragments) {
+ failWebsocketConnectionWithCode(this.ws, 1008, "Too many message fragments");
+ return false;
+ }
+ this.#fragmentsBytes += fragment.length;
+ this.#fragments.push(fragment);
+ return true;
+ }
+ consumeFragments() {
+ const fragments = this.#fragments;
+ if (fragments.length === 1) {
+ this.#fragmentsBytes = 0;
+ return fragments.shift();
+ }
+ const output = Buffer.concat(fragments, this.#fragmentsBytes);
+ this.#fragments = [];
+ this.#fragmentsBytes = 0;
+ return output;
+ }
parseCloseBody(data) {
assert(data.length !== 1);
let code;
@@ -17557,8 +17908,6 @@ var require_websocket = __commonJS({
#extensions = "";
/** @type {SendQueue} */
#sendQueue;
- /** @type {{ maxDecompressedMessageSize?: number }} */
- #options;
/**
* @param {string} url
* @param {string|string[]} protocols
@@ -17602,9 +17951,6 @@ var require_websocket = __commonJS({
throw new DOMException("Invalid Sec-WebSocket-Protocol value", "SyntaxError");
}
this[kWebSocketURL] = new URL(urlRecord.href);
- this.#options = {
- maxDecompressedMessageSize: options.maxDecompressedMessageSize
- };
const client = environmentSettingsObject.settingsObject;
this[kController] = establishWebSocketConnection(
urlRecord,
@@ -17788,7 +18134,13 @@ var require_websocket = __commonJS({
*/
#onConnectionEstablished(response, parsedExtensions) {
this[kResponse] = response;
- const parser = new ByteParser(this, parsedExtensions, this.#options);
+ const webSocketOptions = this[kController]?.dispatcher?.webSocketOptions;
+ const maxFragments = webSocketOptions?.maxFragments;
+ const maxPayloadSize = webSocketOptions?.maxPayloadSize;
+ const parser = new ByteParser(this, parsedExtensions, {
+ maxFragments,
+ maxPayloadSize
+ });
parser.on("drain", onParserDrain);
parser.on("error", onParserError.bind(this));
response.socket.ws = this;
@@ -17863,19 +18215,6 @@ var require_websocket = __commonJS({
{
key: "headers",
converter: webidl.nullableConverter(webidl.converters.HeadersInit)
- },
- {
- key: "maxDecompressedMessageSize",
- converter: webidl.nullableConverter((V) => {
- V = webidl.converters["unsigned long long"](V);
- if (V <= 0) {
- throw webidl.errors.exception({
- header: "WebSocket constructor",
- message: "maxDecompressedMessageSize must be greater than 0"
- });
- }
- return V;
- })
}
]);
webidl.converters["DOMString or sequence or WebSocketInit"] = function(V) {
@@ -17954,6 +18293,40 @@ var require_eventsource_stream = __commonJS({
var CR = 13;
var COLON = 58;
var SPACE = 32;
+ var DATA = Buffer.from("data");
+ var EVENT = Buffer.from("event");
+ var ID = Buffer.from("id");
+ var RETRY = Buffer.from("retry");
+ function isASCIINumberBytes(buffer, start) {
+ if (start >= buffer.length) {
+ return false;
+ }
+ for (let i = start; i < buffer.length; i++) {
+ if (buffer[i] < 48 || buffer[i] > 57) {
+ return false;
+ }
+ }
+ return true;
+ }
+ function isValidLastEventIdBytes(buffer, start) {
+ for (let i = start; i < buffer.length; i++) {
+ if (buffer[i] === 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+ function isFieldName(line, length, field) {
+ if (length !== field.length) {
+ return false;
+ }
+ for (let i = 0; i < length; i++) {
+ if (line[i] !== field[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
var EventSourceStream = class extends Transform {
/**
* @type {eventSourceSettings}
@@ -17973,10 +18346,13 @@ var require_eventsource_stream = __commonJS({
*/
eventEndCheck = false;
/**
- * @type {Buffer}
+ * @type {Buffer[]}
*/
- buffer = null;
+ chunks = [];
+ chunkIndex = 0;
pos = 0;
+ lineChunkIndex = 0;
+ linePos = 0;
event = {
data: void 0,
event: void 0,
@@ -18007,63 +18383,30 @@ var require_eventsource_stream = __commonJS({
callback();
return;
}
- if (this.buffer) {
- this.buffer = Buffer.concat([this.buffer, chunk]);
- } else {
- this.buffer = chunk;
- }
+ this.chunks.push(chunk);
if (this.checkBOM) {
- switch (this.buffer.length) {
- case 1:
- if (this.buffer[0] === BOM[0]) {
- callback();
- return;
- }
- this.checkBOM = false;
- callback();
- return;
- case 2:
- if (this.buffer[0] === BOM[0] && this.buffer[1] === BOM[1]) {
- callback();
- return;
- }
- this.checkBOM = false;
- break;
- case 3:
- if (this.buffer[0] === BOM[0] && this.buffer[1] === BOM[1] && this.buffer[2] === BOM[2]) {
- this.buffer = Buffer.alloc(0);
- this.checkBOM = false;
- callback();
- return;
- }
- this.checkBOM = false;
- break;
- default:
- if (this.buffer[0] === BOM[0] && this.buffer[1] === BOM[1] && this.buffer[2] === BOM[2]) {
- this.buffer = this.buffer.subarray(3);
- }
- this.checkBOM = false;
- break;
+ if (this.handleBOM()) {
+ callback();
+ return;
}
}
- while (this.pos < this.buffer.length) {
+ while (this.hasCurrentByte()) {
+ const byte = this.currentByte();
if (this.eventEndCheck) {
if (this.crlfCheck) {
- if (this.buffer[this.pos] === LF) {
- this.buffer = this.buffer.subarray(this.pos + 1);
- this.pos = 0;
+ if (byte === LF) {
this.crlfCheck = false;
+ this.consumeCurrentByte();
continue;
}
this.crlfCheck = false;
}
- if (this.buffer[this.pos] === LF || this.buffer[this.pos] === CR) {
- if (this.buffer[this.pos] === CR) {
+ if (byte === LF || byte === CR) {
+ if (byte === CR) {
this.crlfCheck = true;
}
- this.buffer = this.buffer.subarray(this.pos + 1);
- this.pos = 0;
- if (this.event.data !== void 0 || this.event.event || this.event.id || this.event.retry) {
+ this.consumeCurrentByte();
+ if (this.hasPendingEvent()) {
this.processEvent(this.event);
}
this.clearEvent();
@@ -18072,17 +18415,16 @@ var require_eventsource_stream = __commonJS({
this.eventEndCheck = false;
continue;
}
- if (this.buffer[this.pos] === LF || this.buffer[this.pos] === CR) {
- if (this.buffer[this.pos] === CR) {
+ if (byte === LF || byte === CR) {
+ if (byte === CR) {
this.crlfCheck = true;
}
- this.parseLine(this.buffer.subarray(0, this.pos), this.event);
- this.buffer = this.buffer.subarray(this.pos + 1);
- this.pos = 0;
+ this.parseLine(this.readLine(), this.event);
+ this.consumeCurrentByte();
this.eventEndCheck = true;
continue;
}
- this.pos++;
+ this.advanceCursor();
}
callback();
}
@@ -18098,43 +18440,42 @@ var require_eventsource_stream = __commonJS({
if (colonPosition === 0) {
return;
}
- let field = "";
- let value = "";
+ let fieldLength = line.length;
+ let valueStart = line.length;
if (colonPosition !== -1) {
- field = line.subarray(0, colonPosition).toString("utf8");
- let valueStart = colonPosition + 1;
+ fieldLength = colonPosition;
+ valueStart = colonPosition + 1;
if (line[valueStart] === SPACE) {
++valueStart;
}
- value = line.subarray(valueStart).toString("utf8");
- } else {
- field = line.toString("utf8");
- value = "";
}
- switch (field) {
- case "data":
- if (event[field] === void 0) {
- event[field] = value;
- } else {
- event[field] += `
+ if (isFieldName(line, fieldLength, DATA)) {
+ const value = line.toString("utf8", valueStart);
+ if (event.data === void 0) {
+ event.data = value;
+ } else {
+ event.data += `
${value}`;
- }
- break;
- case "retry":
- if (isASCIINumber(value)) {
- event[field] = value;
- }
- break;
- case "id":
- if (isValidLastEventId(value)) {
- event[field] = value;
- }
- break;
- case "event":
- if (value.length > 0) {
- event[field] = value;
- }
- break;
+ }
+ return;
+ }
+ if (isFieldName(line, fieldLength, RETRY)) {
+ if (isASCIINumberBytes(line, valueStart)) {
+ event.retry = line.toString("utf8", valueStart);
+ }
+ return;
+ }
+ if (isFieldName(line, fieldLength, ID)) {
+ if (isValidLastEventIdBytes(line, valueStart)) {
+ event.id = line.toString("utf8", valueStart);
+ }
+ return;
+ }
+ if (isFieldName(line, fieldLength, EVENT)) {
+ const value = line.toString("utf8", valueStart);
+ if (value.length > 0) {
+ event.event = value;
+ }
}
}
/**
@@ -18159,12 +18500,120 @@ ${value}`;
}
}
clearEvent() {
- this.event = {
- data: void 0,
- event: void 0,
- id: void 0,
- retry: void 0
- };
+ this.event.data = void 0;
+ this.event.event = void 0;
+ this.event.id = void 0;
+ this.event.retry = void 0;
+ }
+ hasPendingEvent() {
+ return this.event.data !== void 0 || this.event.event !== void 0 || this.event.id !== void 0 || this.event.retry !== void 0;
+ }
+ hasCurrentByte() {
+ return this.chunkIndex < this.chunks.length && this.pos < this.chunks[this.chunkIndex].length;
+ }
+ currentByte() {
+ return this.chunks[this.chunkIndex][this.pos];
+ }
+ consumeCurrentByte() {
+ this.advanceCursor();
+ this.syncLineStartToCursor();
+ }
+ advanceCursor() {
+ this.pos++;
+ while (this.chunkIndex < this.chunks.length && this.pos >= this.chunks[this.chunkIndex].length) {
+ this.chunkIndex++;
+ this.pos = 0;
+ }
+ }
+ syncLineStartToCursor() {
+ this.lineChunkIndex = this.chunkIndex;
+ this.linePos = this.pos;
+ this.dropConsumedChunks();
+ }
+ dropConsumedChunks() {
+ while (this.lineChunkIndex > 0) {
+ this.chunks.shift();
+ this.lineChunkIndex--;
+ this.chunkIndex--;
+ }
+ if (this.chunkIndex === this.chunks.length) {
+ this.chunks.length = 0;
+ this.chunkIndex = 0;
+ this.pos = 0;
+ this.lineChunkIndex = 0;
+ this.linePos = 0;
+ }
+ }
+ readLine() {
+ if (this.lineChunkIndex === this.chunkIndex) {
+ return this.chunks[this.chunkIndex].subarray(this.linePos, this.pos);
+ }
+ const chunks = [];
+ let length = 0;
+ for (let i = this.lineChunkIndex; i <= this.chunkIndex; i++) {
+ const chunk = this.chunks[i];
+ const start = i === this.lineChunkIndex ? this.linePos : 0;
+ const end = i === this.chunkIndex ? this.pos : chunk.length;
+ const slice = chunk.subarray(start, end);
+ length += slice.length;
+ chunks.push(slice);
+ }
+ return Buffer.concat(chunks, length);
+ }
+ peekBufferedByte(offset) {
+ let chunkIndex = this.lineChunkIndex;
+ let pos = this.linePos;
+ while (chunkIndex < this.chunks.length) {
+ const chunk = this.chunks[chunkIndex];
+ const remaining = chunk.length - pos;
+ if (offset < remaining) {
+ return chunk[pos + offset];
+ }
+ offset -= remaining;
+ chunkIndex++;
+ pos = 0;
+ }
+ }
+ discardLeadingBytes(count) {
+ while (count > 0 && this.lineChunkIndex < this.chunks.length) {
+ const chunk = this.chunks[this.lineChunkIndex];
+ const remaining = chunk.length - this.linePos;
+ if (count < remaining) {
+ this.linePos += count;
+ count = 0;
+ } else {
+ count -= remaining;
+ this.lineChunkIndex++;
+ this.linePos = 0;
+ }
+ }
+ this.chunkIndex = this.lineChunkIndex;
+ this.pos = this.linePos;
+ this.dropConsumedChunks();
+ }
+ handleBOM() {
+ const first = this.peekBufferedByte(0);
+ const second = this.peekBufferedByte(1);
+ const third = this.peekBufferedByte(2);
+ if (second === void 0) {
+ if (first === BOM[0]) {
+ return true;
+ }
+ this.checkBOM = false;
+ return true;
+ }
+ if (third === void 0) {
+ if (first === BOM[0] && second === BOM[1]) {
+ return true;
+ }
+ this.checkBOM = false;
+ return false;
+ }
+ if (first === BOM[0] && second === BOM[1] && third === BOM[2]) {
+ this.discardLeadingBytes(3);
+ }
+ this.checkBOM = false;
+ return !this.hasCurrentByte();
}
};
module2.exports = {
@@ -18612,102 +19061,6 @@ var require_undici = __commonJS({
}
});
-// node_modules/fast-content-type-parse/index.js
-var require_fast_content_type_parse = __commonJS({
- "node_modules/fast-content-type-parse/index.js"(exports2, module2) {
- "use strict";
- var NullObject = function NullObject2() {
- };
- NullObject.prototype = /* @__PURE__ */ Object.create(null);
- var paramRE = /; *([!#$%&'*+.^\w`|~-]+)=("(?:[\v\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\v\u0020-\u00ff])*"|[!#$%&'*+.^\w`|~-]+) */gu;
- var quotedPairRE = /\\([\v\u0020-\u00ff])/gu;
- var mediaTypeRE = /^[!#$%&'*+.^\w|~-]+\/[!#$%&'*+.^\w|~-]+$/u;
- var defaultContentType = { type: "", parameters: new NullObject() };
- Object.freeze(defaultContentType.parameters);
- Object.freeze(defaultContentType);
- function parse2(header) {
- if (typeof header !== "string") {
- throw new TypeError("argument header is required and must be a string");
- }
- let index = header.indexOf(";");
- const type = index !== -1 ? header.slice(0, index).trim() : header.trim();
- if (mediaTypeRE.test(type) === false) {
- throw new TypeError("invalid media type");
- }
- const result = {
- type: type.toLowerCase(),
- parameters: new NullObject()
- };
- if (index === -1) {
- return result;
- }
- let key;
- let match;
- let value;
- paramRE.lastIndex = index;
- while (match = paramRE.exec(header)) {
- if (match.index !== index) {
- throw new TypeError("invalid parameter format");
- }
- index += match[0].length;
- key = match[1].toLowerCase();
- value = match[2];
- if (value[0] === '"') {
- value = value.slice(1, value.length - 1);
- quotedPairRE.test(value) && (value = value.replace(quotedPairRE, "$1"));
- }
- result.parameters[key] = value;
- }
- if (index !== header.length) {
- throw new TypeError("invalid parameter format");
- }
- return result;
- }
- function safeParse2(header) {
- if (typeof header !== "string") {
- return defaultContentType;
- }
- let index = header.indexOf(";");
- const type = index !== -1 ? header.slice(0, index).trim() : header.trim();
- if (mediaTypeRE.test(type) === false) {
- return defaultContentType;
- }
- const result = {
- type: type.toLowerCase(),
- parameters: new NullObject()
- };
- if (index === -1) {
- return result;
- }
- let key;
- let match;
- let value;
- paramRE.lastIndex = index;
- while (match = paramRE.exec(header)) {
- if (match.index !== index) {
- return defaultContentType;
- }
- index += match[0].length;
- key = match[1].toLowerCase();
- value = match[2];
- if (value[0] === '"') {
- value = value.slice(1, value.length - 1);
- quotedPairRE.test(value) && (value = value.replace(quotedPairRE, "$1"));
- }
- result.parameters[key] = value;
- }
- if (index !== header.length) {
- return defaultContentType;
- }
- return result;
- }
- module2.exports.default = { parse: parse2, safeParse: safeParse2 };
- module2.exports.parse = parse2;
- module2.exports.safeParse = safeParse2;
- module2.exports.defaultContentType = defaultContentType;
- }
-});
-
// node_modules/@actions/core/lib/core.js
var core_exports = {};
__export(core_exports, {
@@ -21339,8 +21692,189 @@ function withDefaults(oldDefaults, newDefaults) {
}
var endpoint = withDefaults(null, DEFAULTS);
-// node_modules/@octokit/request/dist-bundle/index.js
-var import_fast_content_type_parse = __toESM(require_fast_content_type_parse(), 1);
+// node_modules/content-type/dist/index.js
+var SP = 32;
+var HTAB = 9;
+var SEMI = 59;
+var EQ = 61;
+var DQUOTE = 34;
+var BSLASH = 92;
+var COMMA = 44;
+var LOWER_CASE = 1;
+var OWS = 2;
+var SEMI_FLAG = 4;
+var COMMA_FLAG = 8;
+var TOKEN_FLAG = 16;
+var NON_ASCII = 65280;
+var CASE_FLAGS = LOWER_CASE | NON_ASCII;
+var CHAR_MAP = new Uint8Array(256);
+CHAR_MAP[HTAB] |= OWS;
+CHAR_MAP[SP] |= OWS;
+CHAR_MAP[SEMI] |= SEMI_FLAG;
+CHAR_MAP[COMMA] |= COMMA_FLAG;
+for (let code = 128; code <= 255; code++) {
+ CHAR_MAP[code] |= LOWER_CASE;
+}
+for (const char of "!#$%&'*+-.^_`|~") {
+ CHAR_MAP[char.charCodeAt(0)] |= TOKEN_FLAG;
+}
+for (let code = 48; code <= 57; code++) {
+ CHAR_MAP[code] |= TOKEN_FLAG;
+}
+for (let code = 65; code <= 90; code++) {
+ CHAR_MAP[code] |= LOWER_CASE | TOKEN_FLAG;
+}
+for (let code = 97; code <= 122; code++) {
+ CHAR_MAP[code] |= TOKEN_FLAG;
+}
+var NullObject = /* @__PURE__ */ (() => {
+ const C = function() {
+ };
+ C.prototype = /* @__PURE__ */ Object.create(null);
+ return C;
+})();
+function parse2(header, options) {
+ const stopFlags = SEMI_FLAG | (options?.comma === true ? COMMA_FLAG : 0);
+ const len = header.length;
+ let valueStart = options?.start ?? 0;
+ while ((CHAR_MAP[header.charCodeAt(valueStart)] & OWS) !== 0) {
+ valueStart++;
+ }
+ let index = valueStart;
+ let typeFlags = 0;
+ let whitespace = -1;
+ let stop = options?.parameters === false ? COMMA_FLAG : 0;
+ while (index < len) {
+ const code = header.charCodeAt(index);
+ const flags = CHAR_MAP[code];
+ if ((flags & stopFlags) !== 0) {
+ stop |= flags & COMMA_FLAG;
+ break;
+ }
+ if ((flags & OWS) !== 0) {
+ if (whitespace === -1)
+ whitespace = index;
+ } else {
+ whitespace = -1;
+ }
+ typeFlags |= code & NON_ASCII | flags;
+ index++;
+ }
+ const valueEnd = whitespace === -1 ? index : whitespace;
+ const value = header.slice(valueStart, valueEnd);
+ const type = (typeFlags & CASE_FLAGS) === 0 ? value : value.toLowerCase();
+ if (index === len || stop !== 0) {
+ return { type, index, parameters: new NullObject() };
+ }
+ return parseParameters(header, type, index, len, stopFlags);
+}
+function parseParameters(header, type, index, len, stopFlags) {
+ const parameters = new NullObject();
+ parameter: while (index < len) {
+ index++;
+ while ((CHAR_MAP[header.charCodeAt(index)] & OWS) !== 0) {
+ index++;
+ }
+ const keyStart = index;
+ let keyFlags = 0;
+ let keyWhitespace = -1;
+ while (index < len) {
+ const code = header.charCodeAt(index);
+ const flags = CHAR_MAP[code];
+ if ((flags & stopFlags) !== 0) {
+ if ((flags & COMMA_FLAG) !== 0)
+ break parameter;
+ continue parameter;
+ }
+ if (code === EQ) {
+ const keyEnd = keyWhitespace === -1 ? index : keyWhitespace;
+ const value = header.slice(keyStart, keyEnd);
+ const key = (keyFlags & CASE_FLAGS) === 0 ? value : value.toLowerCase();
+ index++;
+ while ((CHAR_MAP[header.charCodeAt(index)] & OWS) !== 0) {
+ index++;
+ }
+ if (index < len && header.charCodeAt(index) === DQUOTE) {
+ const quotedStart = ++index;
+ let escaped = false;
+ while (index < len) {
+ const code2 = header.charCodeAt(index);
+ if (code2 === DQUOTE) {
+ if (parameters[key] === void 0) {
+ parameters[key] = escaped ? unescapeQuotedPairs(header, quotedStart, index) : header.slice(quotedStart, index);
+ }
+ index++;
+ let stop2 = 0;
+ while (index < len) {
+ const code3 = header.charCodeAt(index);
+ const flags2 = CHAR_MAP[code3];
+ if ((flags2 & stopFlags) !== 0) {
+ stop2 = flags2 & COMMA_FLAG;
+ break;
+ }
+ index++;
+ }
+ if (stop2 !== 0)
+ break parameter;
+ continue parameter;
+ }
+ if (code2 === BSLASH && index + 1 < len) {
+ escaped = true;
+ index += 2;
+ continue;
+ }
+ index++;
+ }
+ continue parameter;
+ }
+ const valueStart = index;
+ let stop = 0;
+ let valueWhitespace = -1;
+ while (index < len) {
+ const code2 = header.charCodeAt(index);
+ const flags2 = CHAR_MAP[code2];
+ if ((flags2 & stopFlags) !== 0) {
+ stop = flags2 & COMMA_FLAG;
+ break;
+ }
+ if ((flags2 & OWS) !== 0) {
+ if (valueWhitespace === -1)
+ valueWhitespace = index;
+ } else {
+ valueWhitespace = -1;
+ }
+ index++;
+ }
+ if (parameters[key] === void 0) {
+ const valueEnd = valueWhitespace === -1 ? index : valueWhitespace;
+ parameters[key] = header.slice(valueStart, valueEnd);
+ }
+ if (stop !== 0)
+ break parameter;
+ continue parameter;
+ }
+ if ((flags & OWS) !== 0) {
+ if (keyWhitespace === -1)
+ keyWhitespace = index;
+ } else {
+ keyWhitespace = -1;
+ }
+ keyFlags |= code & NON_ASCII | flags;
+ index++;
+ }
+ }
+ return { type, index, parameters };
+}
+function unescapeQuotedPairs(str, start, end) {
+ let result = "";
+ for (let index = start; index < end; index++) {
+ if (str.charCodeAt(index) === BSLASH) {
+ result += str.slice(start, index);
+ start = ++index;
+ }
+ }
+ return result + str.slice(start, end);
+}
// node_modules/json-with-bigint/json-with-bigint.js
var intRegex = /^-?\d+$/;
@@ -21348,84 +21882,333 @@ var noiseValue = /^-?\d+n+$/;
var originalStringify = JSON.stringify;
var originalParse = JSON.parse;
var customFormat = /^-?\d+n$/;
-var bigIntsStringify = /([\[:])?"(-?\d+)n"($|([\\n]|\s)*(\s|[\\n])*[,\}\]])/g;
-var noiseStringify = /([\[:])?("-?\d+n+)n("$|"([\\n]|\s)*(\s|[\\n])*[,\}\]])/g;
+var bigIntsStringify = /([\[:])?"(-?\d+)n"($|\s*[,\}\]])/g;
+var noiseStringify = /([\[:])?("-?\d+n+)n("$|"\s*[,\}\]])/g;
+var isUnstringifiable = (val) => val === void 0 || typeof val === "function" || typeof val === "symbol";
+var isRawJSON = (val) => val !== null && typeof val === "object" && val.constructor && val.constructor.name === "RawJSON";
+var stringifyIteratively = (rootValue, replacer, spaceParam) => {
+ let space = "";
+ if (typeof spaceParam === "number") {
+ space = " ".repeat(Math.min(10, Math.max(0, Math.floor(spaceParam))));
+ } else if (typeof spaceParam === "string") {
+ space = spaceParam.slice(0, 10);
+ }
+ const isFunctionReplacer = typeof replacer === "function";
+ const propertyList = Array.isArray(replacer) ? new Set(replacer.map(String)) : null;
+ const prepareVal = (parent, key, val) => {
+ const isObject = val !== null && typeof val === "object";
+ const hasToJSON = isObject && typeof val.toJSON === "function";
+ if (hasToJSON) {
+ val = val.toJSON(key);
+ }
+ const isNoise = typeof val === "string" && noiseValue.test(val);
+ if (isNoise) return val + "n";
+ const isBigInt = typeof val === "bigint";
+ if (isBigInt) {
+ const supportsRawJSON = "rawJSON" in JSON;
+ if (supportsRawJSON) return JSON.rawJSON(val.toString());
+ return val.toString() + "n";
+ }
+ if (isFunctionReplacer) {
+ val = replacer.call(parent, key, val);
+ }
+ const isPostReplacerObject = val !== null && typeof val === "object";
+ if (isPostReplacerObject) {
+ const isPrimitiveWrapper = val instanceof Number || val instanceof String || val instanceof Boolean;
+ if (isPrimitiveWrapper) {
+ val = val.valueOf();
+ }
+ }
+ return val;
+ };
+ const rootProcessed = prepareVal({ "": rootValue }, "", rootValue);
+ if (isUnstringifiable(rootProcessed)) {
+ return void 0;
+ }
+ const isRootPrimitive = rootProcessed === null || typeof rootProcessed !== "object";
+ const isRootNativeRawJSON = isRawJSON(rootProcessed);
+ if (isRootPrimitive || isRootNativeRawJSON) {
+ return originalStringify(rootProcessed);
+ }
+ const chunks = [];
+ let level = 0;
+ const stack = [
+ {
+ parent: { "": rootProcessed },
+ key: "",
+ val: rootProcessed,
+ isArray: Array.isArray(rootProcessed),
+ keys: Array.isArray(rootProcessed) ? null : Object.keys(rootProcessed),
+ index: 0,
+ first: true
+ }
+ ];
+ const visited = new WeakSet([rootProcessed]);
+ while (stack.length > 0) {
+ const node = stack[stack.length - 1];
+ if (node.index === 0) {
+ chunks.push(node.isArray ? "[" : "{");
+ level++;
+ }
+ let isDone = false;
+ if (node.isArray) {
+ if (node.index < node.val.length) {
+ if (!node.first) chunks.push(",");
+ if (space) chunks.push("\n" + space.repeat(level));
+ const childRaw = node.val[node.index];
+ const childVal = prepareVal(node.val, String(node.index), childRaw);
+ if (isUnstringifiable(childVal)) {
+ chunks.push("null");
+ node.first = false;
+ node.index++;
+ } else {
+ const isComplexObject = childVal !== null && typeof childVal === "object";
+ const isNativeRaw = isRawJSON(childVal);
+ if (isComplexObject && !isNativeRaw) {
+ if (visited.has(childVal)) {
+ throw new TypeError("Converting circular structure to JSON");
+ }
+ visited.add(childVal);
+ stack.push({
+ parent: node.val,
+ key: String(node.index),
+ val: childVal,
+ isArray: Array.isArray(childVal),
+ keys: Array.isArray(childVal) ? null : Object.keys(childVal),
+ index: 0,
+ first: true
+ });
+ node.first = false;
+ node.index++;
+ } else {
+ chunks.push(originalStringify(childVal));
+ node.first = false;
+ node.index++;
+ }
+ }
+ } else {
+ isDone = true;
+ }
+ } else {
+ while (node.index < node.keys.length) {
+ const k = node.keys[node.index++];
+ const isFilteredOutByArray = propertyList && !propertyList.has(k);
+ if (isFilteredOutByArray) continue;
+ const childRaw = node.val[k];
+ const childVal = prepareVal(node.val, k, childRaw);
+ if (isUnstringifiable(childVal)) continue;
+ if (!node.first) chunks.push(",");
+ if (space) {
+ chunks.push("\n" + space.repeat(level) + originalStringify(k) + ": ");
+ } else {
+ chunks.push(originalStringify(k) + ":");
+ }
+ const isComplexObject = childVal !== null && typeof childVal === "object";
+ const isNativeRaw = isRawJSON(childVal);
+ if (isComplexObject && !isNativeRaw) {
+ if (visited.has(childVal)) {
+ throw new TypeError("Converting circular structure to JSON");
+ }
+ visited.add(childVal);
+ stack.push({
+ parent: node.val,
+ key: k,
+ val: childVal,
+ isArray: Array.isArray(childVal),
+ keys: Array.isArray(childVal) ? null : Object.keys(childVal),
+ index: 0,
+ first: true
+ });
+ node.first = false;
+ break;
+ } else {
+ chunks.push(originalStringify(childVal));
+ node.first = false;
+ }
+ }
+ const isNodeFullyProcessed = node.index >= node.keys.length && stack[stack.length - 1] === node;
+ if (isNodeFullyProcessed) {
+ isDone = true;
+ }
+ }
+ if (isDone) {
+ level--;
+ if (!node.first && space) chunks.push("\n" + space.repeat(level));
+ chunks.push(node.isArray ? "]" : "}");
+ visited.delete(node.val);
+ stack.pop();
+ }
+ }
+ return chunks.join("");
+};
var JSONStringify = (value, replacer, space) => {
- if ("rawJSON" in JSON) {
- return originalStringify(
+ try {
+ const supportsRawJSON = "rawJSON" in JSON;
+ if (supportsRawJSON) {
+ return originalStringify(
+ value,
+ (key, val) => {
+ if (typeof val === "bigint") return JSON.rawJSON(val.toString());
+ const hasFunctionReplacer = typeof replacer === "function";
+ if (hasFunctionReplacer) return replacer(key, val);
+ const isKeyInArrayReplacer = Array.isArray(replacer) && replacer.includes(key);
+ if (isKeyInArrayReplacer) return val;
+ return val;
+ },
+ space
+ );
+ }
+ if (!value) return originalStringify(value, replacer, space);
+ const convertedToCustomJSON = originalStringify(
value,
- (key, value2) => {
- if (typeof value2 === "bigint") return JSON.rawJSON(value2.toString());
- if (typeof replacer === "function") return replacer(key, value2);
- if (Array.isArray(replacer) && replacer.includes(key)) return value2;
- return value2;
+ (key, val) => {
+ const isNoise = typeof val === "string" && noiseValue.test(val);
+ if (isNoise) return val.toString() + "n";
+ if (typeof val === "bigint") return val.toString() + "n";
+ const hasFunctionReplacer = typeof replacer === "function";
+ if (hasFunctionReplacer) return replacer(key, val);
+ const isKeyInArrayReplacer = Array.isArray(replacer) && replacer.includes(key);
+ if (isKeyInArrayReplacer) return val;
+ return val;
},
space
);
+ const processedJSON = convertedToCustomJSON.replace(
+ bigIntsStringify,
+ "$1$2$3"
+ );
+ const denoisedJSON = processedJSON.replace(noiseStringify, "$1$2$3");
+ return denoisedJSON;
+ } catch (error2) {
+ if (error2 instanceof RangeError) {
+ const convertedJSON = stringifyIteratively(value, replacer, space);
+ if (convertedJSON === void 0) return void 0;
+ const supportsRawJSON = "rawJSON" in JSON;
+ if (supportsRawJSON) return convertedJSON;
+ const processedJSON = convertedJSON.replace(bigIntsStringify, "$1$2$3");
+ return processedJSON.replace(noiseStringify, "$1$2$3");
+ }
+ throw error2;
+ }
+};
+var featureCache = /* @__PURE__ */ new Map();
+var isContextSourceSupported = () => {
+ const parseFingerprint = JSON.parse.toString();
+ if (featureCache.has(parseFingerprint)) {
+ return featureCache.get(parseFingerprint);
+ }
+ try {
+ const result = JSON.parse(
+ "1",
+ (_, __, context) => !!context?.source && context.source === "1"
+ );
+ featureCache.set(parseFingerprint, result);
+ return result;
+ } catch {
+ featureCache.set(parseFingerprint, false);
+ return false;
}
- if (!value) return originalStringify(value, replacer, space);
- const convertedToCustomJSON = originalStringify(
- value,
- (key, value2) => {
- const isNoise = typeof value2 === "string" && Boolean(value2.match(noiseValue));
- if (isNoise) return value2.toString() + "n";
- if (typeof value2 === "bigint") return value2.toString() + "n";
- if (typeof replacer === "function") return replacer(key, value2);
- if (Array.isArray(replacer) && replacer.includes(key)) return value2;
- return value2;
- },
- space
- );
- const processedJSON = convertedToCustomJSON.replace(
- bigIntsStringify,
- "$1$2$3"
- );
- const denoisedJSON = processedJSON.replace(noiseStringify, "$1$2$3");
- return denoisedJSON;
};
-var isContextSourceSupported = () => JSON.parse("1", (_, __, context) => !!context && context.source === "1");
var convertMarkedBigIntsReviver = (key, value, context, userReviver) => {
- const isCustomFormatBigInt = typeof value === "string" && value.match(customFormat);
+ const isCustomFormatBigInt = typeof value === "string" && customFormat.test(value);
if (isCustomFormatBigInt) return BigInt(value.slice(0, -1));
- const isNoiseValue = typeof value === "string" && value.match(noiseValue);
+ const isNoiseValue = typeof value === "string" && noiseValue.test(value);
if (isNoiseValue) return value.slice(0, -1);
- if (typeof userReviver !== "function") return value;
+ const hasUserReviver = typeof userReviver === "function";
+ if (!hasUserReviver) return value;
return userReviver(key, value, context);
};
var JSONParseV2 = (text, reviver) => {
return JSON.parse(text, (key, value, context) => {
- const isBigNumber = typeof value === "number" && (value > Number.MAX_SAFE_INTEGER || value < Number.MIN_SAFE_INTEGER);
+ const isNumber = typeof value === "number";
+ const isOutOfBounds = value > Number.MAX_SAFE_INTEGER || value < Number.MIN_SAFE_INTEGER;
+ const isBigNumber = isNumber && isOutOfBounds;
const isInt = context && intRegex.test(context.source);
const isBigInt = isBigNumber && isInt;
if (isBigInt) return BigInt(context.source);
- if (typeof reviver !== "function") return value;
+ const hasCustomReviver = typeof reviver === "function";
+ if (!hasCustomReviver) return value;
return reviver(key, value, context);
});
};
var MAX_INT = Number.MAX_SAFE_INTEGER.toString();
var MAX_DIGITS = MAX_INT.length;
-var stringsOrLargeNumbers = /"(?:\\.|[^"])*"|-?(0|[1-9][0-9]*)(\.[0-9]+)?([eE][+-]?[0-9]+)?/g;
+var stringsOrLargeNumbers = /"(?:[^"\\]|\\.)*"|-?(0|[1-9][0-9]*)(\.[0-9]+)?([eE][+-]?[0-9]+)?/g;
var noiseValueWithQuotes = /^"-?\d+n+"$/;
-var JSONParse = (text, reviver) => {
- if (!text) return originalParse(text, reviver);
- if (isContextSourceSupported()) return JSONParseV2(text, reviver);
- const serializedData = text.replace(
+var applyReviverIteratively = (parsed, userReviver) => {
+ const rootHolder = { "": parsed };
+ const stack = [{ parent: rootHolder, key: "", visited: false }];
+ while (stack.length > 0) {
+ const node = stack[stack.length - 1];
+ if (!node.visited) {
+ node.visited = true;
+ const value = node.parent[node.key];
+ const isComplexObject = value !== null && typeof value === "object";
+ if (isComplexObject) {
+ const keys = Object.keys(value);
+ for (let i = keys.length - 1; i >= 0; i--) {
+ stack.push({ parent: value, key: keys[i], visited: false });
+ }
+ }
+ } else {
+ const { parent, key } = node;
+ let value = parent[key];
+ if (typeof value === "string") {
+ const isCustomFormatBigInt = customFormat.test(value);
+ if (isCustomFormatBigInt) {
+ value = BigInt(value.slice(0, -1));
+ } else {
+ const isNoise = noiseValue.test(value);
+ if (isNoise) value = value.slice(0, -1);
+ }
+ }
+ const hasUserReviver = typeof userReviver === "function";
+ if (hasUserReviver) {
+ value = userReviver.call(parent, key, value);
+ }
+ const isDeleted = value === void 0;
+ if (isDeleted) {
+ delete parent[key];
+ } else {
+ parent[key] = value;
+ }
+ stack.pop();
+ }
+ }
+ return rootHolder[""];
+};
+var serializeBigInts = (text) => {
+ return text.replace(
stringsOrLargeNumbers,
- (text2, digits, fractional, exponential) => {
- const isString = text2[0] === '"';
- const isNoise = isString && Boolean(text2.match(noiseValueWithQuotes));
- if (isNoise) return text2.substring(0, text2.length - 1) + 'n"';
- const isFractionalOrExponential = fractional || exponential;
+ (match, digits, fractional, exponential) => {
+ const isString = match[0] === '"';
+ const isNoise = isString && noiseValueWithQuotes.test(match);
+ if (isNoise) return match.substring(0, match.length - 1) + 'n"';
+ const hasFractionalOrExponential = fractional || exponential;
const isLessThanMaxSafeInt = digits && (digits.length < MAX_DIGITS || digits.length === MAX_DIGITS && digits <= MAX_INT);
- if (isString || isFractionalOrExponential || isLessThanMaxSafeInt)
- return text2;
- return '"' + text2 + 'n"';
+ const isStandardValue = isString || hasFractionalOrExponential || isLessThanMaxSafeInt;
+ if (isStandardValue) return match;
+ return '"' + match + 'n"';
}
);
- return originalParse(
- serializedData,
- (key, value, context) => convertMarkedBigIntsReviver(key, value, context, reviver)
- );
+};
+var JSONParse = (text, reviver) => {
+ if (!text) return originalParse(text, reviver);
+ try {
+ if (isContextSourceSupported()) return JSONParseV2(text, reviver);
+ const serializedData = serializeBigInts(text);
+ return originalParse(
+ serializedData,
+ (key, value, context) => convertMarkedBigIntsReviver(key, value, context, reviver)
+ );
+ } catch (error2) {
+ if (error2 instanceof RangeError) {
+ const serializedData = serializeBigInts(text);
+ const parsed = originalParse(serializedData);
+ return applyReviverIteratively(parsed, reviver);
+ }
+ throw error2;
+ }
};
// node_modules/@octokit/request-error/dist-src/index.js
@@ -21468,7 +22251,7 @@ var RequestError = class extends Error {
};
// node_modules/@octokit/request/dist-bundle/index.js
-var VERSION2 = "10.0.8";
+var VERSION2 = "10.0.16";
var defaults_default = {
headers: {
"user-agent": `octokit-request.js/${VERSION2} ${getUserAgent()}`
@@ -21586,7 +22369,7 @@ async function getResponseData(response) {
if (!contentType) {
return response.text().catch(noop);
}
- const mimetype = (0, import_fast_content_type_parse.safeParse)(contentType);
+ const mimetype = parse2(contentType);
if (isJSONResponse(mimetype)) {
let text = "";
try {
@@ -21595,7 +22378,10 @@ async function getResponseData(response) {
} catch (err) {
return text;
}
- } else if (mimetype.type.startsWith("text/") || mimetype.parameters.charset?.toLowerCase() === "utf-8") {
+ } else if (mimetype.type.startsWith("text/") || // `application/octet-stream` is the canonical "arbitrary binary" type
+ // (RFC 2046) and must never be decoded as text, even when the response
+ // carries a (misleading) `charset=utf-8` parameter — see #751.
+ mimetype.parameters.charset?.toLowerCase() === "utf-8" && mimetype.type !== "application/octet-stream") {
return response.text().catch(noop);
} else {
return response.arrayBuffer().catch(
@@ -21614,9 +22400,10 @@ function toErrorMessage(data) {
if (data instanceof ArrayBuffer) {
return "Unknown error";
}
- if ("message" in data) {
- const suffix = "documentation_url" in data ? ` - ${data.documentation_url}` : "";
- return Array.isArray(data.errors) ? `${data.message}: ${data.errors.map((v) => JSON.stringify(v)).join(", ")}${suffix}` : `${data.message}${suffix}`;
+ if (typeof data === "object" && data !== null && "message" in data) {
+ const objectData = data;
+ const suffix = "documentation_url" in objectData ? ` - ${objectData.documentation_url}` : "";
+ return Array.isArray(objectData.errors) ? `${objectData.message}: ${objectData.errors.map((v) => JSON.stringify(v)).join(", ")}${suffix}` : `${objectData.message}${suffix}`;
}
return `Unknown error: ${JSON.stringify(data)}`;
}
@@ -21689,6 +22476,13 @@ undici/lib/web/fetch/body.js:
undici/lib/web/websocket/frame.js:
(*! ws. MIT License. Einar Otto Stangvik *)
+content-type/dist/index.js:
+ (*!
+ * content-type
+ * Copyright(c) 2015 Douglas Christopher Wilson
+ * MIT Licensed
+ *)
+
@octokit/request-error/dist-src/index.js:
(* v8 ignore else -- @preserve -- Bug with vitest coverage where it sees an else branch that doesn't exist *)
diff --git a/package-lock.json b/package-lock.json
index 368387d5..bb3e6d79 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "create-github-app-token",
- "version": "3.2.0",
+ "version": "3.3.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "create-github-app-token",
- "version": "3.2.0",
+ "version": "3.3.0",
"license": "MIT",
"dependencies": {
"@actions/core": "^3.0.1",
diff --git a/package.json b/package.json
index 5b99346e..57c03041 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
"name": "create-github-app-token",
"private": true,
"type": "module",
- "version": "3.2.0",
+ "version": "3.3.0",
"description": "GitHub Action for creating a GitHub App Installation Access Token",
"engines": {
"node": ">=24.4.0"