From e69783d0a329dc518bd23570275beed715d8403e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Aug 2026 23:45:16 +0000 Subject: [PATCH 01/21] chore(deps-dev): Bump undici from 6.27.0 to 6.28.0 Bumps [undici](https://github.com/nodejs/undici) from 6.27.0 to 6.28.0. - [Release notes](https://github.com/nodejs/undici/releases) - [Commits](https://github.com/nodejs/undici/compare/v6.27.0...v6.28.0) --- updated-dependencies: - dependency-name: undici dependency-version: 6.28.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index b1b12d40..bec0416e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2423,9 +2423,9 @@ } }, "node_modules/undici": { - "version": "6.27.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.27.0.tgz", - "integrity": "sha512-YmfV3YnEDzXRC5lZ2jWtWWHKGUm1zIt8AhesR1tens+HTNv+YZlN/dp6G727LOvMJ8xjP9Be7Y2Sdr96LDm+pg==", + "version": "6.28.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.28.0.tgz", + "integrity": "sha512-LIY910g9TI13YS95lrMFrs8Rm/u/irgHeTWoKCoteeJ04CUJ92eEfj0rVn+7VKMPBpUPiUoBKfhNyLI23EE/KA==", "dev": true, "license": "MIT", "engines": { From c56b7620586f836c8de6a28c53abe7ed5bc87b2f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Aug 2026 20:07:52 +0000 Subject: [PATCH 02/21] chore(deps-dev): Bump @octokit/types from 16.0.0 to 17.0.0 Bumps [@octokit/types](https://github.com/octokit/types.ts) from 16.0.0 to 17.0.0. - [Release notes](https://github.com/octokit/types.ts/releases) - [Commits](https://github.com/octokit/types.ts/compare/v16.0.0...v17.0.0) --- updated-dependencies: - dependency-name: "@octokit/types" dependency-version: 17.0.0 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- package-lock.json | 108 ++++++++++++++++++++++++++++++++++++++++++++-- package.json | 2 +- 2 files changed, 106 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index bec0416e..b765a576 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ "@github/prettier-config": "^0.0.6", "@octokit/core": "^7.0.6", "@octokit/plugin-throttling": "^11.0.3", - "@octokit/types": "^16.0.0", + "@octokit/types": "^17.0.0", "@types/node": "^26.0.0", "eslint": "^10.4.0", "eslint-config-prettier": "^10.1.8", @@ -316,6 +316,23 @@ "node": ">= 20" } }, + "node_modules/@octokit/core/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/@octokit/core/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^27.0.0" + } + }, "node_modules/@octokit/endpoint": { "version": "11.0.2", "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-11.0.2.tgz", @@ -330,6 +347,23 @@ "node": ">= 20" } }, + "node_modules/@octokit/endpoint/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/@octokit/endpoint/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^27.0.0" + } + }, "node_modules/@octokit/graphql": { "version": "9.0.3", "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-9.0.3.tgz", @@ -345,13 +379,30 @@ "node": ">= 20" } }, - "node_modules/@octokit/openapi-types": { + "node_modules/@octokit/graphql/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==", "dev": true, "license": "MIT" }, + "node_modules/@octokit/graphql/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^27.0.0" + } + }, + "node_modules/@octokit/openapi-types": { + "version": "28.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-28.0.0.tgz", + "integrity": "sha512-0rFyLuyHvIj6uuZWuDslxkowFYdPXoNIkeAv4b27dzm2Tf4vGWXnPsMcxs7d65kLdMERgP3wc1AEPlqMz8e1cQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@octokit/plugin-throttling": { "version": "11.0.3", "resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-11.0.3.tgz", @@ -369,6 +420,23 @@ "@octokit/core": "^7.0.0" } }, + "node_modules/@octokit/plugin-throttling/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/@octokit/plugin-throttling/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^27.0.0" + } + }, "node_modules/@octokit/request": { "version": "10.0.6", "resolved": "https://registry.npmjs.org/@octokit/request/-/request-10.0.6.tgz", @@ -399,7 +467,31 @@ "node": ">= 20" } }, - "node_modules/@octokit/types": { + "node_modules/@octokit/request-error/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/@octokit/request-error/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^27.0.0" + } + }, + "node_modules/@octokit/request/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/@octokit/request/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==", @@ -409,6 +501,16 @@ "@octokit/openapi-types": "^27.0.0" } }, + "node_modules/@octokit/types": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-17.0.0.tgz", + "integrity": "sha512-ByP1v7YL5SMveFPP7+sj0/ZuWCOOg/Chs4NafOMpq6WNIM/hdGY0S7C0TCGDBWu1aGmOxmUIhMx3cO+IdwYZ1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^28.0.0" + } + }, "node_modules/@oxc-project/types": { "version": "0.133.0", "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.133.0.tgz", diff --git a/package.json b/package.json index f7cb1176..343fa57d 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "@github/prettier-config": "^0.0.6", "@octokit/core": "^7.0.6", "@octokit/plugin-throttling": "^11.0.3", - "@octokit/types": "^16.0.0", + "@octokit/types": "^17.0.0", "@types/node": "^26.0.0", "eslint": "^10.4.0", "eslint-config-prettier": "^10.1.8", From 25db39fa5d7d4677c548c71d4e1cb542d3139f8c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Aug 2026 20:04:53 +0000 Subject: [PATCH 03/21] chore(deps): Bump rack Bumps the bundler-minor-and-patch group in /sites/site-with-errors with 1 update: [rack](https://github.com/rack/rack). Updates `rack` from 3.2.6 to 3.2.7 - [Release notes](https://github.com/rack/rack/releases) - [Changelog](https://github.com/rack/rack/blob/main/CHANGELOG.md) - [Commits](https://github.com/rack/rack/compare/v3.2.6...v3.2.7) --- updated-dependencies: - dependency-name: rack dependency-version: 3.2.7 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: bundler-minor-and-patch ... Signed-off-by: dependabot[bot] --- sites/site-with-errors/Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sites/site-with-errors/Gemfile.lock b/sites/site-with-errors/Gemfile.lock index 57c5380e..593f7a5d 100644 --- a/sites/site-with-errors/Gemfile.lock +++ b/sites/site-with-errors/Gemfile.lock @@ -101,7 +101,7 @@ GEM public_suffix (7.0.5) puma (8.0.2) nio4r (~> 2.0) - rack (3.2.6) + rack (3.2.7) rake (13.3.0) rb-fsevent (0.11.2) rb-inotify (0.11.1) From e8bd96f1eb491d0cffadeeda6559655cee48bb4b Mon Sep 17 00:00:00 2001 From: Joyce Zhu Date: Fri, 21 Aug 2026 02:51:40 -0400 Subject: [PATCH 04/21] Overhaul plugin docs - new issue template for allowlisting third-party issues from NPM - plugin documentation reorganized and rewritten to organize information about all plugins vs. NPM plugins only vs. local plugins only --- .../allowlist-npm-plugin-request.yml | 15 ++++++ PLUGINS.md | 52 ++++++++++++------- 2 files changed, 48 insertions(+), 19 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/allowlist-npm-plugin-request.yml diff --git a/.github/ISSUE_TEMPLATE/allowlist-npm-plugin-request.yml b/.github/ISSUE_TEMPLATE/allowlist-npm-plugin-request.yml new file mode 100644 index 00000000..bf5489a9 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/allowlist-npm-plugin-request.yml @@ -0,0 +1,15 @@ +name: Allowlist Third Party NPM Plugin Request +description: Fill out the details to request allowlisting your third party plugin hosted on NPM in the scanner. +labels: 'allowlist-plugin-request' +body: + - type: input + attributes: + label: Link to your plugin on NPM + validations: + required: true + - type: textarea + attributes: + label: What does your plugin do? + description: Please provide a brief description of your plugin's functionality. + validations: + required: true diff --git a/PLUGINS.md b/PLUGINS.md index 0ed1262b..e1334a23 100644 --- a/PLUGINS.md +++ b/PLUGINS.md @@ -1,12 +1,17 @@ # Plugins -The plugin system allows teams to create custom scans/tests to run on their pages. An example of this is Axe interaction tests. In some cases, it might be desirable to perform specific interactions on elements of a given page before doing an Axe scan. These interactions are usually unique to each page that is scanned, so it would require the owning team to write a custom plugin that can interact with the page and run the Axe scan when ready. See the existing plugins under [.github/scanner-plugins](https://github.com/github/accessibility-scanner/tree/main/.github/scanner-plugins) for examples of plugin structure. +The plugin system allows teams to create custom scans/tests to run on their pages. An example of this is Axe interaction tests. In some cases, it might be desirable to perform specific interactions on elements of a given page before doing an Axe scan. These interactions are usually unique to each page that is scanned, so it would require the owning team to write a custom plugin that can interact with the page and run the Axe scan when ready. -Some plugins come built-in with the scanner and can be enabled via [actions inputs](https://github.com/github/accessibility-scanner/tree/main/action.yml#L48-L50). +Some first-party plugins come built-in with the scanner repository and can be enabled via [actions inputs](https://github.com/github/accessibility-scanner/tree/main/action.yml#L48-L50). +There are also some [allowlisted](https://github.com/github/accessibility-scanner/blob/7ec4b73ca2fdb471ad6f71a48a88e7b1a84ab3ad/.github/actions/find/src/pluginManager/index.ts#L92) first-party plugins hosted in a different repository; we also have the ability to support loading approved third-party plugins [from NPM](./loading-plugins-from-npm-packages). -## How plugins work +## How to create plugins + +### Plugin folder structure for all plugins -Plugins are dynamically loaded by the scanner when it runs. The scanner will look into the `./.github` folder in your repo (where you run the workflow from) and search for a `scanner-plugins` folder. If it finds it, it will assume each folder under that is a plugin, and attempt to load the `index.ts` (first) or `index.js` (second) file inside it. Once loaded, the scanner will invoke the exported default function from the `index.js/index.ts` file. +- Each plugin should have one `index.ts` OR `index.js` file inside its folder. +- The `index.ts/index.js` file must export a `name` field. This is the name used to pass to the `scans` input. So if the plugin exports a name value of `my-custom-plugin` and we pass the following to the scanner action inputs: `scans: ['my-custom-plugin']`, it would cause the scanner to only run that plugin. +- The `index.ts/index.js` file must export a default function (see [below](./default-function-api)). This is the function that the scanner uses to run the plugin. This can be an async function. ### Default function API @@ -22,15 +27,23 @@ A async function (you must use `await` or `.then` when invoking this function) t - An object that should match the [`Finding` type](https://github.com/github/accessibility-scanner/blob/main/.github/actions/find/src/types.d.ts#L1-L9). -## How to create plugins +### NPM-hosted plugins -As mentioned above, plugins need to exist under `./.github/scanner-plugins`. For a plugin to work, it needs to meet the following criteria: +Create a repository containing the required files/functions mentioned above, then publish it as an NPM package (with a public URL). -- Each separate plugin should be contained in it's own directory in `./.github/scanner-plugins`. For example, `./.github/scanner-plugins/plugin-1` would be 1 plugin loaded by the scanner. -- Each plugin should have one `index.ts` OR `index.js` file inside its folder. -- The `index.ts/index.js` file must export a `name` field. This is the name used to pass to the `scans` input. So if the plugin exports a name value of `my-custom-plugin` and we pass the following to the scanner action inputs: `scans: ['my-custom-plugin']`, it would cause the scanner to only run that plugin. -- The `index.ts/index.js` file must export a default function. This is the function that the scanner uses to run the plugin. This can be an async function. -- In your workflow file, before the scanner step, add `- uses: actions/checkout@v6` (or whatever the current version is). This allows the current repository's files (where your custom plugin's file exists) to be read: +Once the public URL is live, please fill out [this issue template](./.github/ISSUE_TEMPLATE/allowlist-npm-plugin-request.yml) so we can allowlist your plugin in future versions of the scanner. + +To then enable an NPM plugin in the `scans` input, follow the instructions in the [loading plugins from NPM](./loading-plugins-from-npm-packages) section. + +An example of a plugin which can be loaded from NPM is our [alt text scanning plugin](https://github.com/github/accessibility-scanner-alt-text-plugin). + +### Local plugins (located in your repository) + +If you wish, you can create _local plugins_ by creating a folder containing plugin code in `./.github/scanner-plugins/`. Each separate plugin should be contained in its own directory. For example, `./.github/scanner-plugins/plugin-1` would be 1 plugin loaded by the scanner. + +Enabled local plugins (i.e. those listed in the `scans` Action input) are dynamically loaded by the scanner when it runs. The scanner will search for a `./.github/scanner-plugins` folder in your repo (where you run the workflow from). If it finds one, it will assume each folder under that is a plugin, and attempt to load the `index.ts` (first) or `index.js` (second) file inside it. Once loaded, the scanner will invoke the exported default function from the `index.js/index.ts` file. + +In your workflow file, before the scanner step, add `- uses: actions/checkout@v6` (or whatever the current version is). This allows the current repository's files (where your custom plugin's file exists) to be read: ```yaml jobs: @@ -45,8 +58,10 @@ jobs: ## Loading plugins from NPM packages -In addition to local plugins under `./.github/scanner-plugins`, the scanner can install and load plugins published as NPM packages. This avoids having to vendor a plugin's source into your repo. -NPM package loading requires scanner v3.4.1 or later. +> [!IMPORTANT] +> NPM package loading requires scanner v3.4.1 or later. + +The scanner can install and load plugins published as NPM packages. This avoids having to vendor a plugin's source into your repo. To use an NPM plugin, pass an object (instead of a plain string) in the `scans` input with the following fields: @@ -54,7 +69,7 @@ To use an NPM plugin, pass an object (instead of a plain string) in the `scans` - `package` — the NPM package name to install. - `version` — (optional) a version or dist-tag to pin. If omitted, the latest version is installed. -Only the set of [first-party packages](.github/actions/find/src/pluginManager/index.ts#L91) may be loaded from NPM. Any other package is skipped with a warning. +Only the set of [approved packages](.github/actions/find/src/pluginManager/index.ts#L91) may be loaded from NPM. Any other package is skipped with a warning. ```yaml jobs: @@ -68,11 +83,10 @@ jobs: ["axe", {"name": "alt-text-scan", "package": "@github/accessibility-scanner-alt-text-plugin", "version": "1.1.0"}] ``` -Notes: - -- Packages are installed at runtime with `npm install --ignore-scripts`, so install/postinstall scripts in the package will not run. Pin a `version` to avoid silently picking up future releases. -- If an NPM plugin shares a name with a built-in or local plugin, the built-in/local plugin wins and the NPM one is skipped. -- Plugin configuration works the same as local plugins: place a config-only folder at `./.github/scanner-plugins//config.json` in your repo (the plugin reads its config relative to the repo you run the workflow from). +> [!NOTE] +> - Packages are installed at runtime with `npm install --ignore-scripts`, so install/postinstall scripts in the package will not run. Pin a `version` to avoid silently picking up future releases. +> - If an NPM plugin shares a name with a built-in or local plugin, the built-in/local plugin wins and the NPM one is skipped. +> - Plugin configuration works the same as local plugins: place a config-only folder at `./.github/scanner-plugins//config.json` in your repo (the plugin reads its config relative to the repo you run the workflow from). ## Things to look out for From ca690aece6e84cd3f05873a52410e93a547f2898 Mon Sep 17 00:00:00 2001 From: Joyce Zhu Date: Fri, 21 Aug 2026 17:50:01 -0400 Subject: [PATCH 05/21] Address feedback on previous plugins overhaul PR --- .../allowlist-npm-plugin-request.yml | 8 ++++++++ PLUGINS.md | 19 +++++++++---------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/allowlist-npm-plugin-request.yml b/.github/ISSUE_TEMPLATE/allowlist-npm-plugin-request.yml index bf5489a9..f657318d 100644 --- a/.github/ISSUE_TEMPLATE/allowlist-npm-plugin-request.yml +++ b/.github/ISSUE_TEMPLATE/allowlist-npm-plugin-request.yml @@ -3,11 +3,19 @@ description: Fill out the details to request allowlisting your third party plugi labels: 'allowlist-plugin-request' body: - type: input + id: npm-package attributes: label: Link to your plugin on NPM validations: required: true + - type: input + id: github-repo-link + attributes: + label: Link to the source code for your plugin on GitHub + validations: + required: true - type: textarea + id: plugin-description attributes: label: What does your plugin do? description: Please provide a brief description of your plugin's functionality. diff --git a/PLUGINS.md b/PLUGINS.md index e1334a23..f2a3775a 100644 --- a/PLUGINS.md +++ b/PLUGINS.md @@ -3,17 +3,11 @@ The plugin system allows teams to create custom scans/tests to run on their pages. An example of this is Axe interaction tests. In some cases, it might be desirable to perform specific interactions on elements of a given page before doing an Axe scan. These interactions are usually unique to each page that is scanned, so it would require the owning team to write a custom plugin that can interact with the page and run the Axe scan when ready. Some first-party plugins come built-in with the scanner repository and can be enabled via [actions inputs](https://github.com/github/accessibility-scanner/tree/main/action.yml#L48-L50). -There are also some [allowlisted](https://github.com/github/accessibility-scanner/blob/7ec4b73ca2fdb471ad6f71a48a88e7b1a84ab3ad/.github/actions/find/src/pluginManager/index.ts#L92) first-party plugins hosted in a different repository; we also have the ability to support loading approved third-party plugins [from NPM](./loading-plugins-from-npm-packages). +There are also some [allowlisted](https://github.com/github/accessibility-scanner/blob/7ec4b73ca2fdb471ad6f71a48a88e7b1a84ab3ad/.github/actions/find/src/pluginManager/index.ts#L92) first-party plugins hosted in a different repository; we also have the ability to support loading approved third-party plugins [from NPM](#loading-plugins-from-npm-packages). ## How to create plugins -### Plugin folder structure for all plugins - -- Each plugin should have one `index.ts` OR `index.js` file inside its folder. -- The `index.ts/index.js` file must export a `name` field. This is the name used to pass to the `scans` input. So if the plugin exports a name value of `my-custom-plugin` and we pass the following to the scanner action inputs: `scans: ['my-custom-plugin']`, it would cause the scanner to only run that plugin. -- The `index.ts/index.js` file must export a default function (see [below](./default-function-api)). This is the function that the scanner uses to run the plugin. This can be an async function. - -### Default function API +### Default function API (all plugins) When the default function is invoked, the following arguments are passed to the function: @@ -31,9 +25,9 @@ A async function (you must use `await` or `.then` when invoking this function) t Create a repository containing the required files/functions mentioned above, then publish it as an NPM package (with a public URL). -Once the public URL is live, please fill out [this issue template](./.github/ISSUE_TEMPLATE/allowlist-npm-plugin-request.yml) so we can allowlist your plugin in future versions of the scanner. +Once the public URL is live, please fill out [this issue form](https://github.com/github/accessibility-scanner/issues/new?template=allowlist-npm-plugin-request.yml) so we can allowlist your plugin in future versions of the scanner. -To then enable an NPM plugin in the `scans` input, follow the instructions in the [loading plugins from NPM](./loading-plugins-from-npm-packages) section. +To then enable an NPM plugin in the `scans` input, follow the instructions in the [loading plugins from NPM](./loading-plugins-from-npm-packages) section. Since NPM plugins are loaded through their package entry point, ensure that entry point provides a default function following the API described above. An example of a plugin which can be loaded from NPM is our [alt text scanning plugin](https://github.com/github/accessibility-scanner-alt-text-plugin). @@ -55,6 +49,11 @@ jobs: with: # ... the rest of the workflow setup ``` +#### Plugin folder structure for local plugins + +- Each plugin should have one `index.ts` OR `index.js` file inside its folder. +- The `index.ts/index.js` file must export a `name` field. This is the name used to pass to the `scans` input. So if the plugin exports a name value of `my-custom-plugin` and we pass the following to the scanner action inputs: `scans: ['my-custom-plugin']`, it would cause the scanner to only run that plugin. +- The `index.ts/index.js` file must export a default function (see [below](./default-function-api)). This is the function that the scanner uses to run the plugin. This can be an async function. ## Loading plugins from NPM packages From c8c0cbb2d7f05d0dad783810946c4690e663f1a6 Mon Sep 17 00:00:00 2001 From: Joyce Zhu Date: Fri, 21 Aug 2026 17:55:04 -0400 Subject: [PATCH 06/21] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- PLUGINS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PLUGINS.md b/PLUGINS.md index f2a3775a..25c3e997 100644 --- a/PLUGINS.md +++ b/PLUGINS.md @@ -27,7 +27,7 @@ Create a repository containing the required files/functions mentioned above, the Once the public URL is live, please fill out [this issue form](https://github.com/github/accessibility-scanner/issues/new?template=allowlist-npm-plugin-request.yml) so we can allowlist your plugin in future versions of the scanner. -To then enable an NPM plugin in the `scans` input, follow the instructions in the [loading plugins from NPM](./loading-plugins-from-npm-packages) section. Since NPM plugins are loaded through their package entry point, ensure that entry point provides a default function following the API described above. +To then enable an NPM plugin in the `scans` input, follow the instructions in the [loading plugins from NPM](#loading-plugins-from-npm-packages) section. Since NPM plugins are loaded through their package entry point, ensure that entry point provides a default function following the API described above. An example of a plugin which can be loaded from NPM is our [alt text scanning plugin](https://github.com/github/accessibility-scanner-alt-text-plugin). From 13faf4702c1b00443fb7f7b15f83a226694104b2 Mon Sep 17 00:00:00 2001 From: Carie Fisher <15240149+cehfisher@users.noreply.github.com> Date: Fri, 28 Aug 2026 13:24:02 -0500 Subject: [PATCH 07/21] Change demo video link in README Updated demo video link for the a11y scanner. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 718a223b..13040fe0 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ The a11y scanner helps teams: > ⚠️ **Note:** The a11y scanner is currently in public preview. Feature development work is still ongoing. It can help identify accessibility gaps but cannot guarantee fully accessible code suggestions. Always review before merging! -🎥 **[Watch the demo video](https://youtu.be/CvRJcEzCSQM)** to see the a11y scanner in action. +🎥 **[Watch the demo video](https://youtu.be/gzpDNd8ahqE)** to see the a11y scanner in action. --- From 7bfdfe38d4f990aed0bde211c3538caba8dee7af Mon Sep 17 00:00:00 2001 From: Joyce Zhu Date: Fri, 28 Aug 2026 17:10:50 -0400 Subject: [PATCH 08/21] Add more on NPM plugin allowlist --- PLUGINS.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/PLUGINS.md b/PLUGINS.md index 25c3e997..7dd702df 100644 --- a/PLUGINS.md +++ b/PLUGINS.md @@ -25,7 +25,10 @@ A async function (you must use `await` or `.then` when invoking this function) t Create a repository containing the required files/functions mentioned above, then publish it as an NPM package (with a public URL). +Since loaded plugins can run arbitrary code defined by the plugin author, malicious NPM-hosted third-party plugins are a security concern. To help mitigate supply-chain attack risks, we maintain an in-code allowlist of NPM plugins which are permitted to load and execute code. + Once the public URL is live, please fill out [this issue form](https://github.com/github/accessibility-scanner/issues/new?template=allowlist-npm-plugin-request.yml) so we can allowlist your plugin in future versions of the scanner. +A GitHub engineer will review the plugin codebase to check whether it functions as described in the opened issue; if so, it will be approved and the issue closed after an ensuing scanner release which allowlists your plugin. To then enable an NPM plugin in the `scans` input, follow the instructions in the [loading plugins from NPM](#loading-plugins-from-npm-packages) section. Since NPM plugins are loaded through their package entry point, ensure that entry point provides a default function following the API described above. From dcd232ec29d0851b1e41e3aecc51ef39e0506b85 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 6 Sep 2026 01:29:38 +0000 Subject: [PATCH 09/21] chore(deps-dev): Bump postcss from 8.5.15 to 8.5.28 Bumps [postcss](https://github.com/postcss/postcss) from 8.5.15 to 8.5.28. - [Release notes](https://github.com/postcss/postcss/releases) - [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md) - [Commits](https://github.com/postcss/postcss/compare/8.5.15...8.5.28) --- updated-dependencies: - dependency-name: postcss dependency-version: 8.5.28 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index b765a576..c2874fb8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2098,9 +2098,9 @@ "license": "MIT" }, "node_modules/nanoid": { - "version": "3.3.12", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", - "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", + "version": "3.3.18", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz", + "integrity": "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==", "dev": true, "funding": [ { @@ -2232,9 +2232,9 @@ } }, "node_modules/postcss": { - "version": "8.5.15", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", - "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", + "version": "8.5.28", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.28.tgz", + "integrity": "sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==", "dev": true, "funding": [ { @@ -2252,7 +2252,7 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.12", + "nanoid": "^3.3.18", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, From 310bb9b01eca7d39247be5849ce2fac8d9c072b1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Sep 2026 10:22:03 -0700 Subject: [PATCH 10/21] chore(deps-dev): Bump undici from 6.28.0 to 6.28.1 (#267) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [undici](https://github.com/nodejs/undici) from 6.28.0 to 6.28.1.
Release notes

Sourced from undici's releases.

v6.28.1

⚠️ Security fixes

High severity

  • GHSA-rfgv-xxqx-mfg5: a WebSocket server could select a subprotocol when none was requested, causing an uncaught TypeError that could terminate the process. Undici now rejects the handshake with protocol error 1002. Fixed by 2af0faf8.

Medium severity

  • GHSA-3wwx-pv8p-q78v: a malformed permessage-deflate payload exceeding the configured decompression limit could emit an unhandled zlib error and terminate the process. Undici now destroys the inflater after reaching the limit. Fixed by 07c60d9c.

Low severity

  • GHSA-r53p-7pc4-xj5r: the retry interceptor could concatenate a resumed response with inconsistent framing into downstream output, enabling response splitting or corruption. Undici now validates Content-Range against the original response framing before resuming. Fixed by ce31bc82.

What's Changed

Full Changelog: https://github.com/nodejs/undici/compare/v6.28.0...v6.28.1

Commits
  • ffc8aa0 Bumped v6.28.1 (#5773)
  • 3866a3b perf(h1): drop idle-socket timer floor with a ref'd setImmediate (#5707) (#5770)
  • ce31bc8 fix(retry): validate resumed response framing
  • 2af0faf fix(websocket): reject unrequested subprotocols
  • 07c60d9 fix(websocket): destroy inflater after decompression limit
  • bd90fff perf: reduce EventSourceStream parser allocations (#5032) (#5647)
  • See full diff in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=undici&package-manager=npm_and_yarn&previous-version=6.28.0&new-version=6.28.1)](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/github/accessibility-scanner/network/alerts).
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index c2874fb8..3e71448d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2525,9 +2525,9 @@ } }, "node_modules/undici": { - "version": "6.28.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.28.0.tgz", - "integrity": "sha512-LIY910g9TI13YS95lrMFrs8Rm/u/irgHeTWoKCoteeJ04CUJ92eEfj0rVn+7VKMPBpUPiUoBKfhNyLI23EE/KA==", + "version": "6.28.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.28.1.tgz", + "integrity": "sha512-zWpdTVD54H48CIybL0rWQ3ukpb9d23wM7eH5RtfdmeP70cWHNjtfo7P4vZX+5CoDcO53J4Pu5uXp7lNfjc6DRA==", "dev": true, "license": "MIT", "engines": { From fdc4f8f84a662ac838e41abab4dd4d690ac2fac4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Sep 2026 10:37:50 -0700 Subject: [PATCH 11/21] chore(deps-dev): Bump @octokit/types from 17.0.0 to 18.0.0 (#268) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [@octokit/types](https://github.com/octokit/types.ts) from 17.0.0 to 18.0.0.
Release notes

Sourced from @​octokit/types's releases.

v18.0.0

18.0.0 (2026-08-29)

Features

  • update endpoints with major additions as of 2026-08-24 (#723) (c4b93f2)

BREAKING CHANGES

  • remove deprecated endpoints
Commits
  • c4b93f2 feat: update endpoints with major additions as of 2026-08-24 (#723)
  • 4d46114 chore(deps): Temporarily disable docs generation/publish in release workflow...
  • dd020c1 build(deps-dev): remove semantic-release, bump prettier (#719)
  • 8b92916 build(deps-dev): bump markdown-it from 14.1.0 to 14.3.0 (#717)
  • f88ca90 build(deps-dev): bump lodash-es from 4.17.23 to 4.18.1 (#718)
  • 66f2dd6 build(deps-dev): bump brace-expansion from 2.0.1 to 2.0.2 (#715)
  • ce4890d build(deps-dev): bump linkify-it from 5.0.0 to 5.0.2 (#716)
  • afd965b build(deps-dev): bump npm from 11.6.2 to 11.19.0 (#714)
  • e9121d4 build(deps-dev): bump lodash-es from 4.17.21 to 4.17.23 (#700)
  • See full diff in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@octokit/types&package-manager=npm_and_yarn&previous-version=17.0.0&new-version=18.0.0)](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 | 16 ++++++++-------- package.json | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3e71448d..e66bf65f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ "@github/prettier-config": "^0.0.6", "@octokit/core": "^7.0.6", "@octokit/plugin-throttling": "^11.0.3", - "@octokit/types": "^17.0.0", + "@octokit/types": "^18.0.0", "@types/node": "^26.0.0", "eslint": "^10.4.0", "eslint-config-prettier": "^10.1.8", @@ -397,9 +397,9 @@ } }, "node_modules/@octokit/openapi-types": { - "version": "28.0.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-28.0.0.tgz", - "integrity": "sha512-0rFyLuyHvIj6uuZWuDslxkowFYdPXoNIkeAv4b27dzm2Tf4vGWXnPsMcxs7d65kLdMERgP3wc1AEPlqMz8e1cQ==", + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-29.0.1.tgz", + "integrity": "sha512-9qWOMFNxxLokERcms42rU0PTLqQmVs7g5E41TI4mCOxmpFayD1rfC7XxOL55cG9MBZLFlC31BrR37myMKardwg==", "dev": true, "license": "MIT" }, @@ -502,13 +502,13 @@ } }, "node_modules/@octokit/types": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-17.0.0.tgz", - "integrity": "sha512-ByP1v7YL5SMveFPP7+sj0/ZuWCOOg/Chs4NafOMpq6WNIM/hdGY0S7C0TCGDBWu1aGmOxmUIhMx3cO+IdwYZ1Q==", + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-18.0.0.tgz", + "integrity": "sha512-l6bAF43PNxkJp6g+W4PjoUSSkxHomXw2nOum5CTftJz1NlV3vu93NImgOYtLf6CbBUb5j+fiuzW0PPQ5JTSvZA==", "dev": true, "license": "MIT", "dependencies": { - "@octokit/openapi-types": "^28.0.0" + "@octokit/openapi-types": "^29.0.1" } }, "node_modules/@oxc-project/types": { diff --git a/package.json b/package.json index 343fa57d..e5f40f9b 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "@github/prettier-config": "^0.0.6", "@octokit/core": "^7.0.6", "@octokit/plugin-throttling": "^11.0.3", - "@octokit/types": "^17.0.0", + "@octokit/types": "^18.0.0", "@types/node": "^26.0.0", "eslint": "^10.4.0", "eslint-config-prettier": "^10.1.8", From d78e66345b8c6fb105b013cde72f18e871e9a75b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Sep 2026 10:38:07 -0700 Subject: [PATCH 12/21] chore(deps-dev): Bump vitest from 4.1.6 to 5.0.0 (#269) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) from 4.1.6 to 5.0.0.
Release notes

Sourced from vitest's releases.

v5.0.0

Vitest 5 is officially out! This release focuses on performance and brings a lot of new features while fixing long-standing bugs. See our blog post for the official announcement.

   🚨 Breaking Changes

... (truncated)

Commits
  • f441c6f chore: release v5.0.0 (#11130)
  • d46a747 fix: treat test.describe as a suite during static collection (#11128)
  • 584cf30 fix: add a warning if inline project has duplicate plugins due to unexpected ...
  • f08ce4b fix: apply queued mocks from doMock() in queue order (fixes #10706) (#11127)
  • 897f51f chore: release v5.0.0-rc.4 (#11107)
  • 1339b06 chore(deps): update all non-major dependencies (#11104)
  • 51e9494 feat!: parse files statically in vitest list by default (#11088)
  • 2122ffd fix: propagate --maxWorkers to projects (#11102)
  • dc10f5f fix(browser): report the action error when a task times out (#11101)
  • d4fe198 feat: promote clearCache out of experimental (#11086)
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=vitest&package-manager=npm_and_yarn&previous-version=4.1.6&new-version=5.0.0)](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 | 679 ++++++++++++++++++++-------------------------- package.json | 2 +- 2 files changed, 294 insertions(+), 387 deletions(-) diff --git a/package-lock.json b/package-lock.json index e66bf65f..ef2e585b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,7 +19,7 @@ "eslint-config-prettier": "^10.1.8", "prettier": "^3.8.3", "typescript-eslint": "^8.59.4", - "vitest": "^4.1.6" + "vitest": "^5.0.0" } }, "node_modules/@actions/core": { @@ -61,40 +61,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@emnapi/core": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", - "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/wasi-threads": "1.2.1", - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/runtime": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", - "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/wasi-threads": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", - "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, "node_modules/@eslint-community/eslint-utils": { "version": "4.9.1", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", @@ -261,30 +227,32 @@ "url": "https://github.com/sponsors/nzakas" } }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz", + "integrity": "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==", "dev": true, "license": "MIT" }, - "node_modules/@napi-rs/wasm-runtime": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.5.tgz", - "integrity": "sha512-AWPoBRJ9tsnVhor4sjO7rkni+7p+2IAEFj6cx06UgP10jkQHqay/36uRV/bFkgrh18D9vb4cr8Q0Pthskgzy+Q==", + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "dev": true, "license": "MIT", - "optional": true, "dependencies": { - "@tybys/wasm-util": "^0.10.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Brooooooklyn" - }, - "peerDependencies": { - "@emnapi/core": "^1.7.1", - "@emnapi/runtime": "^1.7.1" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, "node_modules/@octokit/auth-token": { @@ -512,19 +480,38 @@ } }, "node_modules/@oxc-project/types": { - "version": "0.133.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.133.0.tgz", - "integrity": "sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==", + "version": "0.148.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.148.0.tgz", + "integrity": "sha512-Nm4s/jB+4FpFsPhWGEC4h7rzksesmtnMXomo6rCMcg/b8zLQuOziRgkCS1fxDCXOlJB/6Q8oABOZ/OP6RIPj9A==", "dev": true, "license": "MIT", + "peer": true, "funding": { - "url": "https://github.com/sponsors/Boshen" + "url": "https://github.com/sponsors/oxc-project" + } + }, + "node_modules/@rolldown/binding-android-arm-eabi": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.7.tgz", + "integrity": "sha512-EypzgnYCwyVY4NDHKzGmNJT5b+XaQEBniHxsMdeIQLB/tcCzZnhqrzHpZFbX9iaxx+5RiB8caATBtfvZP7zVxQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-android-arm64": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.3.tgz", - "integrity": "sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.7.tgz", + "integrity": "sha512-l17HE9EweWaqJZhuUuNBN/FzM62xw+DECVnJyvMsxn8vJFAGLy5QfLDoYAcronkAN8VxKZHezDpulHDPx95vFw==", "cpu": [ "arm64" ], @@ -534,14 +521,15 @@ "os": [ "android" ], + "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-darwin-arm64": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.3.tgz", - "integrity": "sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.7.tgz", + "integrity": "sha512-8ED8ELFvHXc6OCETIn4gXObPiaR6bckM/ipXtbzlPVDRMBfEGjCKgO90F9YtfdpDatVx/ZQw7aZ1vUMf/+T3Mw==", "cpu": [ "arm64" ], @@ -551,14 +539,15 @@ "os": [ "darwin" ], + "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-darwin-x64": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.3.tgz", - "integrity": "sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.7.tgz", + "integrity": "sha512-/WPripjtiAIZ2tWY7ddijORT0Ujg87wxWW/qcoFVCKAWVDPhtY0xr7Dj0M3GyNGz60jGwTElhro/mkF9dT7dDQ==", "cpu": [ "x64" ], @@ -568,14 +557,15 @@ "os": [ "darwin" ], + "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-freebsd-x64": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.3.tgz", - "integrity": "sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.7.tgz", + "integrity": "sha512-14DI4NcqpvbICxSnGLx3PmtDaWqRP/KGSGb6C+JLLVPeZRl6dKdHba3pGsqT3vpdTqhEYIPG0MMQ8c0xYqoJxA==", "cpu": [ "x64" ], @@ -585,14 +575,15 @@ "os": [ "freebsd" ], + "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-linux-arm-gnueabihf": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.3.tgz", - "integrity": "sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.7.tgz", + "integrity": "sha512-bxrWIRvHWQvbJwi+VIie/kDJmQxcNE6xxWwZdqF/ExVAigtHkv54WTLQPb+QsZdnFy18fg7JPfWGL0RH6vwIlQ==", "cpu": [ "arm" ], @@ -602,116 +593,141 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-linux-arm64-gnu": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.3.tgz", - "integrity": "sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.7.tgz", + "integrity": "sha512-toOY2BChBZyuxU7OYX6Tn389di4IzAqPTycVcci0O7FSfBqzRB3RZn+K5Is6ANf4tmgRd/K1yZTsNTXbkXsnLg==", "cpu": [ "arm64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ "linux" ], + "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-linux-arm64-musl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.3.tgz", - "integrity": "sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.7.tgz", + "integrity": "sha512-lAIXTH/aiLRLxsTgQvfhjo4K1ydWIp00+V0voOr9beb/9ZmkUFrSIb03dXNFRgMNvkE6oGsF10ioQ6UsI+vS5Q==", "cpu": [ "arm64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ "linux" ], + "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-linux-ppc64-gnu": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.3.tgz", - "integrity": "sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.7.tgz", + "integrity": "sha512-kdnwS28Pkenp/mZMRwjXXXwxQ7pIsm+bF919LUK93BOyhcLsrVKdP2p9fxpiPNPAbNuch8ypQt0pm2P2LYCAGg==", "cpu": [ "ppc64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ "linux" ], + "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-linux-s390x-gnu": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.3.tgz", - "integrity": "sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.7.tgz", + "integrity": "sha512-516OdsyLdr5E65paF3yBF55t8mfm9+gmtCsK3xI7XKXIT7EfRlHhxL8K/NR6Hu8BWSgF5+1w74lTL0+nxcc8Qw==", "cpu": [ "s390x" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ "linux" ], + "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-linux-x64-gnu": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.3.tgz", - "integrity": "sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.7.tgz", + "integrity": "sha512-r8/z8n7GFaYRln3xmP1Cxy0HH/HLM0uBUPkEuSVEfKGDA89M0FsZRZJRSwe/tJjRx+fpH/gjorfhB8tmEbSFLA==", "cpu": [ "x64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ "linux" ], + "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-linux-x64-musl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.3.tgz", - "integrity": "sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.7.tgz", + "integrity": "sha512-pAsE8iiDxUg1xBqdhrTfg45AVDVpirjz00sblEYClGNNcMnDb+e8beQgqIAw6LvauX/APvgxUnwrgun/YYGBhw==", "cpu": [ "x64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ "linux" ], + "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-openharmony-arm64": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.3.tgz", - "integrity": "sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.7.tgz", + "integrity": "sha512-lTcIYmmnQQA8Or/2DatS6oSqcdLHvendjS+zLu+FwgToynWMRSmQdpM65fTANJgIS4mjbMOo5KT2lnT9SAb96w==", "cpu": [ "arm64" ], @@ -721,33 +737,15 @@ "os": [ "openharmony" ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-wasm32-wasi": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.3.tgz", - "integrity": "sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg==", - "cpu": [ - "wasm32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "1.10.0", - "@emnapi/runtime": "1.10.0", - "@napi-rs/wasm-runtime": "^1.1.4" - }, + "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-win32-arm64-msvc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.3.tgz", - "integrity": "sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.7.tgz", + "integrity": "sha512-e3Gu3WxbNk/UqQhxqU7YIYO+9ZBvWNz3U+h/qRFosscMFzdRPbXYSaSWgSnklv2fz1TgzBTcti2z35c/7irsHw==", "cpu": [ "arm64" ], @@ -757,14 +755,15 @@ "os": [ "win32" ], + "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-win32-x64-msvc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.3.tgz", - "integrity": "sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.7.tgz", + "integrity": "sha512-W/jg5qoRSqjsEv0+dZi4e687mcHqmVuU0P4fK6qS/xjetW2Gmc1W8j//z5nAeNcC8Ttm0hV46IjcYeuVwYhuiw==", "cpu": [ "x64" ], @@ -774,6 +773,7 @@ "os": [ "win32" ], + "peer": true, "engines": { "node": "^20.19.0 || >=22.12.0" } @@ -783,25 +783,8 @@ "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", "dev": true, - "license": "MIT" - }, - "node_modules/@standard-schema/spec": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", - "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", - "dev": true, - "license": "MIT" - }, - "node_modules/@tybys/wasm-util": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz", - "integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==", - "dev": true, "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } + "peer": true }, "node_modules/@types/chai": { "version": "5.2.3", @@ -1082,34 +1065,17 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@vitest/expect": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.6.tgz", - "integrity": "sha512-7EHDquPthALSV0jhhjgEW8FXaviMx7rSqu8W6oqCoAuOhKov814P99QDV1pxMA3QPv21YudvJngIhjrNI4opLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@standard-schema/spec": "^1.1.0", - "@types/chai": "^5.2.2", - "@vitest/spy": "4.1.6", - "@vitest/utils": "4.1.6", - "chai": "^6.2.2", - "tinyrainbow": "^3.1.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, "node_modules/@vitest/mocker": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.6.tgz", - "integrity": "sha512-MCFc63czMjEInOlcY2cpQCvCN+KgbAn+60xu9cMgP4sKaLC5JNAKw7JH8QdAnoAC88hW1IiSNZ+GgVXlN1UcMQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-5.0.0.tgz", + "integrity": "sha512-66PGTMIiVJP3t4a5yxU9qPtf7MdTBs8jmToMvy+HVflB3Yy13WJZTtPePdvU+wjRV02SKK5doLbSA6o9pwOmiA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "4.1.6", + "@jridgewell/trace-mapping": "0.3.31", + "@vitest/spy": "5.0.0", "estree-walker": "^3.0.3", - "magic-string": "^0.30.21" + "magic-string": "^1.2.3" }, "funding": { "url": "https://opencollective.com/vitest" @@ -1127,70 +1093,12 @@ } } }, - "node_modules/@vitest/pretty-format": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.6.tgz", - "integrity": "sha512-h5SxD/IzNhZYnrSZRsUZQIC+vD0GY8cUvq0iwsmkFKixRCKLLWqCXa/FIQ4S1R+sI+PGoojkHsdNrbZiM9Qpgw==", - "dev": true, - "license": "MIT", - "dependencies": { - "tinyrainbow": "^3.1.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/runner": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.6.tgz", - "integrity": "sha512-nOPCmn2+yD0ZNmKdsXGv/UxMMWbMuKeD6GyYncNwdkYDxpQvrPSKYj2rWuDjC2Y4b6w6hjip5dBKFzEUuZe3vA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/utils": "4.1.6", - "pathe": "^2.0.3" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/snapshot": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.6.tgz", - "integrity": "sha512-YhsdE6xAVfTDmzjxL2ZDUvjj+ZsgyOKe+TdQzqkD72wIOmHka8NuGQ6NpTNZv9D2Z63fbwWKJPeVpEw4EQgYxw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/pretty-format": "4.1.6", - "@vitest/utils": "4.1.6", - "magic-string": "^0.30.21", - "pathe": "^2.0.3" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, "node_modules/@vitest/spy": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.6.tgz", - "integrity": "sha512-JFKxMx6udhwKh/Ldo270e17QX710vgunMkuPAvXjHSvC6oqLWAHhVhjg/I71q0u0CBSErIODV1Kjv0FQNSWjdg==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/utils": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.6.tgz", - "integrity": "sha512-FxIY+U81R3LGKCxaHHFRQ5+g6/iRgGLmeHWdp2Amj4ljQRrEIWHmZyDfDYBRZlpyqA7qKxtS9DD1dhk8RnRIVQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-5.0.0.tgz", + "integrity": "sha512-uy+luWBAPw9XfthoHi5AkfHUnuPYEESjl0p/r+meoBnU8bxg5GDQ3Ey8MjcJ6sqahkL4PFyrvfMJJBw7LbU06g==", "dev": true, "license": "MIT", - "dependencies": { - "@vitest/pretty-format": "4.1.6", - "convert-source-map": "^2.0.0", - "tinyrainbow": "^3.1.0" - }, "funding": { "url": "https://opencollective.com/vitest" } @@ -1292,13 +1200,6 @@ "node": ">=18" } }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true, - "license": "MIT" - }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -1345,14 +1246,15 @@ "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", "dev": true, "license": "Apache-2.0", + "peer": true, "engines": { "node": ">=8" } }, "node_modules/es-module-lexer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", - "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.2.tgz", + "integrity": "sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==", "dev": true, "license": "MIT" }, @@ -1548,9 +1450,9 @@ } }, "node_modules/expect-type": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", - "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.4.0.tgz", + "integrity": "sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -1675,6 +1577,7 @@ "os": [ "darwin" ], + "peer": true, "engines": { "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } @@ -1788,11 +1691,12 @@ } }, "node_modules/lightningcss": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", - "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz", + "integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==", "dev": true, "license": "MPL-2.0", + "peer": true, "dependencies": { "detect-libc": "^2.0.3" }, @@ -1804,23 +1708,23 @@ "url": "https://opencollective.com/parcel" }, "optionalDependencies": { - "lightningcss-android-arm64": "1.32.0", - "lightningcss-darwin-arm64": "1.32.0", - "lightningcss-darwin-x64": "1.32.0", - "lightningcss-freebsd-x64": "1.32.0", - "lightningcss-linux-arm-gnueabihf": "1.32.0", - "lightningcss-linux-arm64-gnu": "1.32.0", - "lightningcss-linux-arm64-musl": "1.32.0", - "lightningcss-linux-x64-gnu": "1.32.0", - "lightningcss-linux-x64-musl": "1.32.0", - "lightningcss-win32-arm64-msvc": "1.32.0", - "lightningcss-win32-x64-msvc": "1.32.0" + "lightningcss-android-arm64": "1.33.0", + "lightningcss-darwin-arm64": "1.33.0", + "lightningcss-darwin-x64": "1.33.0", + "lightningcss-freebsd-x64": "1.33.0", + "lightningcss-linux-arm-gnueabihf": "1.33.0", + "lightningcss-linux-arm64-gnu": "1.33.0", + "lightningcss-linux-arm64-musl": "1.33.0", + "lightningcss-linux-x64-gnu": "1.33.0", + "lightningcss-linux-x64-musl": "1.33.0", + "lightningcss-win32-arm64-msvc": "1.33.0", + "lightningcss-win32-x64-msvc": "1.33.0" } }, "node_modules/lightningcss-android-arm64": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", - "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz", + "integrity": "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==", "cpu": [ "arm64" ], @@ -1830,6 +1734,7 @@ "os": [ "android" ], + "peer": true, "engines": { "node": ">= 12.0.0" }, @@ -1839,9 +1744,9 @@ } }, "node_modules/lightningcss-darwin-arm64": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", - "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz", + "integrity": "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==", "cpu": [ "arm64" ], @@ -1851,6 +1756,7 @@ "os": [ "darwin" ], + "peer": true, "engines": { "node": ">= 12.0.0" }, @@ -1860,9 +1766,9 @@ } }, "node_modules/lightningcss-darwin-x64": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", - "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz", + "integrity": "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==", "cpu": [ "x64" ], @@ -1872,6 +1778,7 @@ "os": [ "darwin" ], + "peer": true, "engines": { "node": ">= 12.0.0" }, @@ -1881,9 +1788,9 @@ } }, "node_modules/lightningcss-freebsd-x64": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", - "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz", + "integrity": "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==", "cpu": [ "x64" ], @@ -1893,6 +1800,7 @@ "os": [ "freebsd" ], + "peer": true, "engines": { "node": ">= 12.0.0" }, @@ -1902,9 +1810,9 @@ } }, "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", - "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz", + "integrity": "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==", "cpu": [ "arm" ], @@ -1914,6 +1822,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": ">= 12.0.0" }, @@ -1923,18 +1832,22 @@ } }, "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", - "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz", + "integrity": "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==", "cpu": [ "arm64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MPL-2.0", "optional": true, "os": [ "linux" ], + "peer": true, "engines": { "node": ">= 12.0.0" }, @@ -1944,18 +1857,22 @@ } }, "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", - "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz", + "integrity": "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==", "cpu": [ "arm64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MPL-2.0", "optional": true, "os": [ "linux" ], + "peer": true, "engines": { "node": ">= 12.0.0" }, @@ -1965,18 +1882,22 @@ } }, "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", - "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz", + "integrity": "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==", "cpu": [ "x64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MPL-2.0", "optional": true, "os": [ "linux" ], + "peer": true, "engines": { "node": ">= 12.0.0" }, @@ -1986,18 +1907,22 @@ } }, "node_modules/lightningcss-linux-x64-musl": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", - "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz", + "integrity": "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==", "cpu": [ "x64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MPL-2.0", "optional": true, "os": [ "linux" ], + "peer": true, "engines": { "node": ">= 12.0.0" }, @@ -2007,9 +1932,9 @@ } }, "node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", - "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz", + "integrity": "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==", "cpu": [ "arm64" ], @@ -2019,6 +1944,7 @@ "os": [ "win32" ], + "peer": true, "engines": { "node": ">= 12.0.0" }, @@ -2028,9 +1954,9 @@ } }, "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", - "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz", + "integrity": "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==", "cpu": [ "x64" ], @@ -2040,6 +1966,7 @@ "os": [ "win32" ], + "peer": true, "engines": { "node": ">= 12.0.0" }, @@ -2065,9 +1992,9 @@ } }, "node_modules/magic-string": { - "version": "0.30.21", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", - "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-1.2.3.tgz", + "integrity": "sha512-Bpb0W2TbLKOZ7vJnOUnVRGq3WL2p+ISV29M6hYPL1AFCpyKZpdr5ytiXoTSSxRVhg8YW7f65+6gbG8WG6PCa/g==", "dev": true, "license": "MIT", "dependencies": { @@ -2109,6 +2036,7 @@ } ], "license": "MIT", + "peer": true, "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -2124,15 +2052,18 @@ "license": "MIT" }, "node_modules/obug": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", - "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.4.tgz", + "integrity": "sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA==", "dev": true, "funding": [ "https://github.com/sponsors/sxzz", "https://opencollective.com/debug" ], - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=12.20.0" + } }, "node_modules/optionator": { "version": "0.9.4", @@ -2204,24 +2135,18 @@ "node": ">=8" } }, - "node_modules/pathe": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", - "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", - "dev": true, - "license": "MIT" - }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "dev": true, - "license": "ISC" + "license": "ISC", + "peer": true }, "node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", "dev": true, "license": "MIT", "engines": { @@ -2251,6 +2176,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "nanoid": "^3.3.18", "picocolors": "^1.1.1", @@ -2297,13 +2223,14 @@ } }, "node_modules/rolldown": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.3.tgz", - "integrity": "sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.7.tgz", + "integrity": "sha512-g0EtLvBjTUB7jhyV0S/TCup3v/XSVl45vUIGbOGU4QPiyjTenCe4mKuFvW9fEgYmS2Fo42AUssRmNuMziXdrig==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "@oxc-project/types": "=0.133.0", + "@oxc-project/types": "=0.148.0", "@rolldown/pluginutils": "^1.0.0" }, "bin": { @@ -2313,21 +2240,21 @@ "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { - "@rolldown/binding-android-arm64": "1.0.3", - "@rolldown/binding-darwin-arm64": "1.0.3", - "@rolldown/binding-darwin-x64": "1.0.3", - "@rolldown/binding-freebsd-x64": "1.0.3", - "@rolldown/binding-linux-arm-gnueabihf": "1.0.3", - "@rolldown/binding-linux-arm64-gnu": "1.0.3", - "@rolldown/binding-linux-arm64-musl": "1.0.3", - "@rolldown/binding-linux-ppc64-gnu": "1.0.3", - "@rolldown/binding-linux-s390x-gnu": "1.0.3", - "@rolldown/binding-linux-x64-gnu": "1.0.3", - "@rolldown/binding-linux-x64-musl": "1.0.3", - "@rolldown/binding-openharmony-arm64": "1.0.3", - "@rolldown/binding-wasm32-wasi": "1.0.3", - "@rolldown/binding-win32-arm64-msvc": "1.0.3", - "@rolldown/binding-win32-x64-msvc": "1.0.3" + "@rolldown/binding-android-arm-eabi": "1.2.7", + "@rolldown/binding-android-arm64": "1.2.7", + "@rolldown/binding-darwin-arm64": "1.2.7", + "@rolldown/binding-darwin-x64": "1.2.7", + "@rolldown/binding-freebsd-x64": "1.2.7", + "@rolldown/binding-linux-arm-gnueabihf": "1.2.7", + "@rolldown/binding-linux-arm64-gnu": "1.2.7", + "@rolldown/binding-linux-arm64-musl": "1.2.7", + "@rolldown/binding-linux-ppc64-gnu": "1.2.7", + "@rolldown/binding-linux-s390x-gnu": "1.2.7", + "@rolldown/binding-linux-x64-gnu": "1.2.7", + "@rolldown/binding-linux-x64-musl": "1.2.7", + "@rolldown/binding-openharmony-arm64": "1.2.7", + "@rolldown/binding-win32-arm64-msvc": "1.2.7", + "@rolldown/binding-win32-x64-msvc": "1.2.7" } }, "node_modules/semver": { @@ -2379,6 +2306,7 @@ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true, "license": "BSD-3-Clause", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -2391,23 +2319,26 @@ "license": "MIT" }, "node_modules/std-env": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.1.0.tgz", - "integrity": "sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.2.0.tgz", + "integrity": "sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw==", "dev": true, "license": "MIT" }, "node_modules/tinybench": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", - "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-6.1.4.tgz", + "integrity": "sha512-9APumHG7r4yOk4X4WlkmE71aZcv1gvin1czO3OQ1U9iJcFA5Ja/ygyb0vPOVHTthFozUYs8CLoLUlM8grb2lTQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=20.0.0" + } }, "node_modules/tinyexec": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz", - "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.3.0.tgz", + "integrity": "sha512-QKAl9m8gWWGHV8jZcPeym6j+XULi6tOf1mT83WYJ4Lk2ytW/uwAWkrP0uFsdoYMdueVJ0qs26wZ+23xeB4ibNQ==", "dev": true, "license": "MIT", "engines": { @@ -2431,16 +2362,6 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, - "node_modules/tinyrainbow": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz", - "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, "node_modules/ts-api-utils": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", @@ -2454,14 +2375,6 @@ "typescript": ">=4.8.4" } }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "dev": true, - "license": "0BSD", - "optional": true - }, "node_modules/tunnel": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", @@ -2559,16 +2472,17 @@ } }, "node_modules/vite": { - "version": "8.0.16", - "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.16.tgz", - "integrity": "sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw==", + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.2.2.tgz", + "integrity": "sha512-cFKLV/PRgAUlIRm5WjMjJ86jrftzpqcgH+Us+DS8mI3CDNiH30Whrz8uHL3+MOLPAgqbMBAqWdAHAphOAM+z/Q==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "lightningcss": "^1.32.0", - "picomatch": "^4.0.4", - "postcss": "^8.5.15", - "rolldown": "1.0.3", + "lightningcss": "^1.33.0", + "picomatch": "^4.0.5", + "postcss": "^8.5.26", + "rolldown": "~1.2.4", "tinyglobby": "^0.2.17" }, "bin": { @@ -2585,7 +2499,7 @@ }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", - "@vitejs/devtools": "^0.1.18", + "@vitejs/devtools": "^0.4.0 || ^0.5.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", @@ -2637,38 +2551,31 @@ } }, "node_modules/vitest": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.6.tgz", - "integrity": "sha512-6lvjbS3p9b4CrdCmguzbh2/4uoXhGE2q71R4OX5sqF9R1bo9Xd6fGrMAfvp5wnCzlBnFVdCOp6onuTQVbo8iUQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/expect": "4.1.6", - "@vitest/mocker": "4.1.6", - "@vitest/pretty-format": "4.1.6", - "@vitest/runner": "4.1.6", - "@vitest/snapshot": "4.1.6", - "@vitest/spy": "4.1.6", - "@vitest/utils": "4.1.6", - "es-module-lexer": "^2.0.0", - "expect-type": "^1.3.0", - "magic-string": "^0.30.21", - "obug": "^2.1.1", - "pathe": "^2.0.3", - "picomatch": "^4.0.3", - "std-env": "^4.0.0-rc.1", - "tinybench": "^2.9.0", - "tinyexec": "^1.0.2", - "tinyglobby": "^0.2.15", - "tinyrainbow": "^3.1.0", - "vite": "^6.0.0 || ^7.0.0 || ^8.0.0", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-5.0.0.tgz", + "integrity": "sha512-gpsMNoRhMjMktVxPtstOH4/PJuPyovVaMDr4oDilXaGH1EcqM2OE96SoHT2VIQ6fTGtTjqmHDrEu2X9RQiXf8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/chai": "^5.2.2", + "@vitest/mocker": "5.0.0", + "chai": "^6.2.2", + "es-module-lexer": "^2.3.2", + "expect-type": "^1.4.0", + "magic-string": "^1.2.3", + "obug": "^2.1.4", + "picomatch": "^4.0.7", + "std-env": "^4.2.0", + "tinybench": "6.1.4", + "tinyexec": "1.3.0", + "tinyglobby": "^0.2.17", "why-is-node-running": "^2.3.0" }, "bin": { "vitest": "vitest.mjs" }, "engines": { - "node": "^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^22.12.0 || ^24.0.0 || >=26.0.0" }, "funding": { "url": "https://opencollective.com/vitest" @@ -2676,16 +2583,16 @@ "peerDependencies": { "@edge-runtime/vm": "*", "@opentelemetry/api": "^1.9.0", - "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", - "@vitest/browser-playwright": "4.1.6", - "@vitest/browser-preview": "4.1.6", - "@vitest/browser-webdriverio": "4.1.6", - "@vitest/coverage-istanbul": "4.1.6", - "@vitest/coverage-v8": "4.1.6", - "@vitest/ui": "4.1.6", + "@types/node": "^22.0.0 || >=24.0.0", + "@vitest/browser-playwright": "5.0.0", + "@vitest/browser-preview": "5.0.0", + "@vitest/browser-webdriverio": "^5.0.0-beta.5 || >=5.0.0", + "@vitest/coverage-istanbul": "5.0.0", + "@vitest/coverage-v8": "5.0.0", + "@vitest/ui": "5.0.0", "happy-dom": "*", "jsdom": "*", - "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" + "vite": "^6.4.0 || ^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "@edge-runtime/vm": { diff --git a/package.json b/package.json index e5f40f9b..b9b62211 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,6 @@ "eslint-config-prettier": "^10.1.8", "prettier": "^3.8.3", "typescript-eslint": "^8.59.4", - "vitest": "^4.1.6" + "vitest": "^5.0.0" } } From e18c63630f5f2a9b19b2829c236f06ceff315f2c Mon Sep 17 00:00:00 2001 From: GitHub Security Bot <88103841+github-security-bot@users.noreply.github.com> Date: Fri, 11 Sep 2026 12:18:05 -0400 Subject: [PATCH 13/21] Pin GitHub Actions to commit SHAs (#270) Pins GitHub Actions `uses:` references in `github/accessibility-scanner` to immutable commit SHAs. ## Summary | Metric | Count | | --- | ---: | | Files changed | 3 | | Files scanned | 2 | | Refs found | 3 | | Refs pinned | 3 | | Skipped refs | 0 | | Warnings | 0 | | Errors | 0 | ## Why Pinning actions to full commit SHAs prevents future tag or branch retargeting from changing workflow behavior without review. ## Reviewer notes - Original refs are preserved in inline comments when possible. - Pin comments use the Dependabot-compatible original-ref style. - Branch refs were allowed and pinned to their current HEAD; review mutable-branch pins carefully. - No minimum action age was enforced for this run. ## Pinned refs | Location | Before | After | Resolved as | | --- | --- | --- | --- | | `.github/workflows/lint.yml:26` | `actions/checkout@v7` | `actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1` | `tag` | | `.github/workflows/lint.yml:29` | `actions/setup-node@v7` | `actions/setup-node@820762786026740c76f36085b0efc47a31fe5020` | `tag` | | `.github/workflows/test.yml:34` | `actions/checkout@v7` | `actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1` | `tag` | ## Dependabot - Added a 7-day cooldown (`cooldown: default-days: 7`) to the existing `github-actions` Dependabot configuration. - The cooldown delays applying a newly published action release for 7 days, reducing exposure to a compromised or broken release while keeping you SHA-pinned. --- Generated by pinner 0.1.0. --- .github/dependabot.yml | 2 ++ .github/workflows/lint.yml | 4 ++-- .github/workflows/test.yml | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 883e31d1..fa0f2acc 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -36,6 +36,8 @@ updates: - "*" schedule: interval: "weekly" + cooldown: + default-days: 7 - package-ecosystem: "bundler" directory: "/sites/site-with-errors" groups: diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index e994eaec..446e8c84 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -23,10 +23,10 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Node - uses: actions/setup-node@v7 + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: node-version: 24 cache: npm diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index dd3536b2..84952aec 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -31,7 +31,7 @@ jobs: site: ['sites/site-with-errors'] steps: - name: Checkout - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Ruby uses: ruby/setup-ruby@95ef2b042f9d7a56d8268cba8559e2842e2ad01b From a2c23bdaa0d1fa833e3970b962bfdfd2ba0e1cca Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 25 Sep 2026 20:03:40 +0000 Subject: [PATCH 14/21] chore(deps): Bump ruby/setup-ruby Bumps the github-actions group with 1 update in the / directory: [ruby/setup-ruby](https://github.com/ruby/setup-ruby). Updates `ruby/setup-ruby` from 1.321.0 to 1.324.0 - [Release notes](https://github.com/ruby/setup-ruby/releases) - [Changelog](https://github.com/ruby/setup-ruby/blob/master/release.rb) - [Commits](https://github.com/ruby/setup-ruby/compare/95ef2b042f9d7a56d8268cba8559e2842e2ad01b...a0102e0972be65f351c307e2d64b9314a57c8073) --- updated-dependencies: - dependency-name: ruby/setup-ruby dependency-version: 1.324.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions ... Signed-off-by: dependabot[bot] --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 84952aec..0f095d85 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -34,7 +34,7 @@ jobs: uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Ruby - uses: ruby/setup-ruby@95ef2b042f9d7a56d8268cba8559e2842e2ad01b + uses: ruby/setup-ruby@a0102e0972be65f351c307e2d64b9314a57c8073 with: ruby-version: '3.4' bundler-cache: true From ee18f95fff5412ece8f49ab196b2aac204f080c5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 2 Oct 2026 20:04:37 +0000 Subject: [PATCH 15/21] chore(deps): Bump ruby/setup-ruby Bumps the github-actions group with 1 update in the / directory: [ruby/setup-ruby](https://github.com/ruby/setup-ruby). Updates `ruby/setup-ruby` from 1.324.0 to 1.327.0 - [Release notes](https://github.com/ruby/setup-ruby/releases) - [Changelog](https://github.com/ruby/setup-ruby/blob/master/release.rb) - [Commits](https://github.com/ruby/setup-ruby/compare/a0102e0972be65f351c307e2d64b9314a57c8073...14594264cd68ce8a2345dd349bc3d138a4ef85c8) --- updated-dependencies: - dependency-name: ruby/setup-ruby dependency-version: 1.327.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions ... Signed-off-by: dependabot[bot] --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0f095d85..f90a8505 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -34,7 +34,7 @@ jobs: uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup Ruby - uses: ruby/setup-ruby@a0102e0972be65f351c307e2d64b9314a57c8073 + uses: ruby/setup-ruby@14594264cd68ce8a2345dd349bc3d138a4ef85c8 with: ruby-version: '3.4' bundler-cache: true From 8f8670e40431c9b1f02cca49e2b92835433896e1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 5 Oct 2026 13:13:17 +0000 Subject: [PATCH 16/21] Port URL selector wait config from PR 223 Co-authored-by: abdulahmad307 <204748719+abdulahmad307@users.noreply.github.com> --- .github/actions/find/README.md | 4 + .github/actions/find/action.yml | 3 +- .github/actions/find/src/findForUrl.ts | 9 +- .github/actions/find/src/index.ts | 7 ++ .github/actions/find/src/types.d.ts | 1 + .github/actions/find/tests/findForUrl.test.ts | 113 +++++++++++++++--- .github/actions/find/tests/index.test.ts | 57 +++++++++ README.md | 4 +- action.yml | 2 +- 9 files changed, 177 insertions(+), 23 deletions(-) create mode 100644 .github/actions/find/tests/index.test.ts diff --git a/.github/actions/find/README.md b/.github/actions/find/README.md index a950a2d5..0a0be1f1 100644 --- a/.github/actions/find/README.md +++ b/.github/actions/find/README.md @@ -15,6 +15,10 @@ https://primer.style https://primer.style/octicons/ ``` +#### `url_configs` + +**Optional** Stringified JSON array of per-URL configuration objects. Each object must include a `url` and may include `excludeSelectors` (selectors to exclude from Axe) and `waitForSelectors` (selectors that must become visible within 30 seconds before scanning). When provided, this input takes precedence over `urls`. + #### `auth_context` **Optional** Stringified JSON object containing `username`, `password`, `cookies`, and/or `localStorage` from an authenticated session. For example: `{"username":"some-user","password":"correct-horse-battery-staple","cookies":[{"name":"theme-preference","value":"light","domain":"primer.style","path":"/"}],"localStorage":{"https://primer.style":{"theme-preference":"light"}}}` diff --git a/.github/actions/find/action.yml b/.github/actions/find/action.yml index 0d3907e6..6662d863 100644 --- a/.github/actions/find/action.yml +++ b/.github/actions/find/action.yml @@ -7,7 +7,7 @@ inputs: required: false multiline: true url_configs: - description: "Stringified JSON array of URL config objects, each with a 'url' field and an optional 'excludeSelectors' field (array of CSS selectors to exclude from the Axe scan for that URL). When provided, takes precedence over the 'urls' input." + description: "Stringified JSON array of URL config objects, each with a 'url' field and optional 'excludeSelectors' (selectors to exclude from Axe) and 'waitForSelectors' (selectors that must be visible before scanning) fields. When provided, takes precedence over the 'urls' input." required: false auth_context: description: "Stringified JSON object containing 'username', 'password', 'cookies', and/or 'localStorage' from an authenticated session" @@ -25,7 +25,6 @@ inputs: color_scheme: description: 'Playwright colorScheme setting: https://playwright.dev/docs/api/class-browser#browser-new-context-option-color-scheme' required: false - outputs: findings_file: description: 'Path to a JSON file containing the list of potential accessibility gaps' diff --git a/.github/actions/find/src/findForUrl.ts b/.github/actions/find/src/findForUrl.ts index 32296d74..2d5046eb 100644 --- a/.github/actions/find/src/findForUrl.ts +++ b/.github/actions/find/src/findForUrl.ts @@ -8,6 +8,8 @@ import {loadPlugins, invokePlugin} from './pluginManager/index.js' import {getScansContext} from './scansContextProvider.js' import * as core from '@actions/core' +const SELECTOR_WAIT_TIMEOUT = 30000 + export async function findForUrl( urlConfig: UrlConfig, authContext?: AuthContext, @@ -15,7 +17,7 @@ export async function findForUrl( reducedMotion?: ReducedMotionPreference, colorScheme?: ColorSchemePreference, ): Promise { - const {url, excludeSelectors} = urlConfig + const {url, excludeSelectors, waitForSelectors} = urlConfig const browser = await playwright.chromium.launch({ headless: true, executablePath: process.env.CI ? '/usr/bin/google-chrome' : undefined, @@ -28,6 +30,11 @@ export async function findForUrl( const context = await browser.newContext(contextOptions) const page = await context.newPage() await page.goto(url) + await Promise.all( + (waitForSelectors ?? []).map(selector => + page.locator(selector).waitFor({state: 'visible', timeout: SELECTOR_WAIT_TIMEOUT}), + ), + ) const findings: Finding[] = [] const addFinding = async (findingData: Finding) => { diff --git a/.github/actions/find/src/index.ts b/.github/actions/find/src/index.ts index 675dff6f..138307c0 100644 --- a/.github/actions/find/src/index.ts +++ b/.github/actions/find/src/index.ts @@ -55,6 +55,13 @@ function loadUrlConfigs() { if (typeof item !== 'object' || item === null || typeof item.url !== 'string') { throw new Error("Each entry in 'url_configs' must be an object with a 'url' string field.") } + if ( + item.waitForSelectors !== undefined && + (!Array.isArray(item.waitForSelectors) || + item.waitForSelectors.some((selector: unknown) => typeof selector !== 'string')) + ) { + throw new Error("Each 'waitForSelectors' field in 'url_configs' must be an array of CSS selector strings.") + } } return parsed as UrlConfig[] diff --git a/.github/actions/find/src/types.d.ts b/.github/actions/find/src/types.d.ts index 4102c324..678474d6 100644 --- a/.github/actions/find/src/types.d.ts +++ b/.github/actions/find/src/types.d.ts @@ -50,4 +50,5 @@ export type ColorSchemePreference = 'light' | 'dark' | 'no-preference' | null export type UrlConfig = { url: string excludeSelectors?: string[] + waitForSelectors?: string[] } diff --git a/.github/actions/find/tests/findForUrl.test.ts b/.github/actions/find/tests/findForUrl.test.ts index 23ee53d1..af73ed5c 100644 --- a/.github/actions/find/tests/findForUrl.test.ts +++ b/.github/actions/find/tests/findForUrl.test.ts @@ -8,21 +8,52 @@ import * as pluginManager from '../src/pluginManager/index.js' import type {Plugin} from '../src/pluginManager/types.js' import {clearCache} from '../src/scansContextProvider.js' +const playwrightMocks = vi.hoisted(() => { + const pageGoto = vi.fn() + const locatorWaitFor = vi.fn() + const pageLocator = vi.fn(() => ({ + waitFor: locatorWaitFor, + })) + const pageUrl = vi.fn() + const contextClose = vi.fn() + const browserClose = vi.fn() + const contextNewPage = vi.fn(() => ({ + goto: pageGoto, + locator: pageLocator, + url: pageUrl, + })) + const browserNewContext = vi.fn(() => ({ + newPage: contextNewPage, + close: contextClose, + })) + const browserLaunch = vi.fn(() => ({ + newContext: browserNewContext, + close: browserClose, + })) + + return { + browserLaunch, + browserNewContext, + contextNewPage, + pageGoto, + pageLocator, + locatorWaitFor, + pageUrl, + contextClose, + browserClose, + } +}) + +const pluginMocks = vi.hoisted(() => ({ + loadPlugins: vi.fn(), + invokePlugin: vi.fn(), +})) + vi.mock('@actions/core', {spy: true}) vi.mock('playwright', () => ({ default: { chromium: { - launch: () => ({ - newContext: () => ({ - newPage: () => ({ - pageUrl: '', - goto: () => {}, - url: () => {}, - }), - close: () => {}, - }), - close: () => {}, - }), + launch: playwrightMocks.browserLaunch, }, }, })) @@ -33,6 +64,7 @@ vi.mock('@axe-core/playwright', () => { AxeBuilderMock.prototype.analyze = vi.fn(() => Promise.resolve(rawFinding)) return {AxeBuilder: AxeBuilderMock} }) +vi.mock('../src/pluginManager/index.js', () => pluginMocks) vi.mock('@accesslint/playwright', () => ({ accesslintAudit: vi.fn(() => Promise.resolve({violations: []})), @@ -44,23 +76,70 @@ let loadedPlugins: Plugin[] = [] function clearAll() { clearCache() vi.clearAllMocks() + playwrightMocks.pageGoto.mockResolvedValue(undefined) + playwrightMocks.locatorWaitFor.mockResolvedValue(undefined) + playwrightMocks.pageUrl.mockReturnValue('test.com') } describe('findForUrl', () => { vi.spyOn(core, 'getInput').mockImplementation(() => actionInput) - vi.spyOn(pluginManager, 'loadPlugins').mockImplementation(() => Promise.resolve(loadedPlugins)) - vi.spyOn(pluginManager, 'invokePlugin') + vi.mocked(pluginManager.loadPlugins).mockImplementation(() => Promise.resolve(loadedPlugins)) + vi.mocked(pluginManager.invokePlugin).mockImplementation(({plugin, page, addFinding}) => + plugin.default({page, addFinding}), + ) async function axeOnlyTest() { clearAll() - await findForUrl('test.com') + await findForUrl({url: 'test.com'}) expect(AxeBuilder.prototype.analyze).toHaveBeenCalledTimes(1) expect(accesslintAudit).toHaveBeenCalledTimes(0) expect(pluginManager.loadPlugins).toHaveBeenCalledTimes(0) expect(pluginManager.invokePlugin).toHaveBeenCalledTimes(0) } + describe('page load handling', () => { + it('uses the default navigation readiness when no selectors are configured', async () => { + actionInput = '' + clearAll() + + await findForUrl({url: 'test.com'}) + + expect(playwrightMocks.pageGoto).toHaveBeenCalledWith('test.com') + expect(playwrightMocks.pageLocator).not.toHaveBeenCalled() + expect(AxeBuilder.prototype.analyze).toHaveBeenCalledTimes(1) + }) + + it('waits for each configured selector after navigation and before scanning', async () => { + actionInput = '' + clearAll() + + await findForUrl({url: 'test.com', waitForSelectors: ['#app', '[data-ready]']}) + + expect(playwrightMocks.pageLocator).toHaveBeenNthCalledWith(1, '#app') + expect(playwrightMocks.pageLocator).toHaveBeenNthCalledWith(2, '[data-ready]') + expect(playwrightMocks.locatorWaitFor).toHaveBeenNthCalledWith(1, {state: 'visible', timeout: 30000}) + expect(playwrightMocks.locatorWaitFor).toHaveBeenNthCalledWith(2, {state: 'visible', timeout: 30000}) + expect(playwrightMocks.pageGoto.mock.invocationCallOrder[0]).toBeLessThan( + playwrightMocks.locatorWaitFor.mock.invocationCallOrder[0], + ) + expect(playwrightMocks.locatorWaitFor.mock.invocationCallOrder[1]).toBeLessThan( + AxeBuilder.prototype.analyze.mock.invocationCallOrder[0], + ) + }) + + it('does not scan when a configured selector times out', async () => { + const timeoutError = new Error('Timeout 30000ms exceeded') + actionInput = '' + clearAll() + playwrightMocks.locatorWaitFor.mockRejectedValueOnce(timeoutError) + + await expect(findForUrl({url: 'test.com', waitForSelectors: ['#app']})).rejects.toThrow(timeoutError) + + expect(AxeBuilder.prototype.analyze).not.toHaveBeenCalled() + }) + }) + describe('when no scans list is provided', () => { it('defaults to running only axe scan', async () => { actionInput = '' @@ -86,7 +165,7 @@ describe('findForUrl', () => { actionInput = JSON.stringify(['axe', 'custom-scan-1']) clearAll() - await findForUrl('test.com') + await findForUrl({url: 'test.com'}) expect(AxeBuilder.prototype.analyze).toHaveBeenCalledTimes(1) expect(pluginManager.loadPlugins).toHaveBeenCalledTimes(1) expect(pluginManager.invokePlugin).toHaveBeenCalledTimes(1) @@ -103,7 +182,7 @@ describe('findForUrl', () => { actionInput = JSON.stringify(['custom-scan-1', 'custom-scan-2']) clearAll() - await findForUrl('test.com') + await findForUrl({url: 'test.com'}) expect(AxeBuilder.prototype.analyze).toHaveBeenCalledTimes(0) expect(pluginManager.loadPlugins).toHaveBeenCalledTimes(1) expect(pluginManager.invokePlugin).toHaveBeenCalledTimes(2) @@ -156,7 +235,7 @@ describe('findForUrl', () => { actionInput = JSON.stringify(['custom-scan-1']) clearAll() - await findForUrl('test.com') + await findForUrl({url: 'test.com'}) expect(loadedPlugins[0].default).toHaveBeenCalledTimes(1) expect(loadedPlugins[1].default).toHaveBeenCalledTimes(0) }) diff --git a/.github/actions/find/tests/index.test.ts b/.github/actions/find/tests/index.test.ts new file mode 100644 index 00000000..f5d760fc --- /dev/null +++ b/.github/actions/find/tests/index.test.ts @@ -0,0 +1,57 @@ +import {beforeEach, describe, expect, it, vi} from 'vitest' +import find from '../src/index.js' + +const mocks = vi.hoisted(() => ({ + inputs: {} as Record, + findForUrl: vi.fn(), + writeFileSync: vi.fn(), +})) + +vi.mock('@actions/core', () => ({ + getInput: vi.fn((name: string) => mocks.inputs[name] ?? ''), + getMultilineInput: vi.fn(() => []), + debug: vi.fn(), + info: vi.fn(), + setOutput: vi.fn(), +})) + +vi.mock('node:fs', () => ({ + default: { + writeFileSync: mocks.writeFileSync, + }, +})) + +vi.mock('../src/findForUrl.js', () => ({ + findForUrl: mocks.findForUrl, +})) + +describe('url_configs', () => { + beforeEach(() => { + vi.clearAllMocks() + for (const name of Object.keys(mocks.inputs)) delete mocks.inputs[name] + mocks.findForUrl.mockResolvedValue([]) + }) + + it('passes waitForSelectors through to the URL scan', async () => { + const urlConfig = { + url: 'https://example.com', + excludeSelectors: ['iframe'], + waitForSelectors: ['#app', '[data-ready]'], + } + mocks.inputs.url_configs = JSON.stringify([urlConfig]) + mocks.inputs.include_screenshots = 'false' + + await find() + + expect(mocks.findForUrl).toHaveBeenCalledWith(urlConfig, expect.anything(), false, undefined, undefined) + }) + + it('rejects waitForSelectors values that are not arrays of strings', async () => { + mocks.inputs.url_configs = JSON.stringify([{url: 'https://example.com', waitForSelectors: ['#app', 42]}]) + + await expect(find()).rejects.toThrow( + "Invalid 'url_configs' input: Each 'waitForSelectors' field in 'url_configs' must be an array of CSS selector strings.", + ) + expect(mocks.findForUrl).not.toHaveBeenCalled() + }) +}) diff --git a/README.md b/README.md index 13040fe0..5fac654a 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ jobs: # reduced_motion: no-preference # Optional: Playwright reduced motion configuration option # color_scheme: light # Optional: Playwright color scheme configuration option # scans: '["axe","accesslint","reflow-scan"]' # Optional: An array of scans (or plugins) to be performed. Built-in engines are 'axe' and 'accesslint'; any other entry is a plugin name. If not provided, only Axe will be performed. - # url_configs: '[{"url":"https://example.com","excludeSelectors":["iframe","#widget"]}]' # Optional: Per-URL config with CSS selectors to exclude from the Axe scan. When provided, takes precedence over 'urls'. + # url_configs: '[{"url":"https://example.com","excludeSelectors":["iframe","#widget"],"waitForSelectors":["#app","[data-ready]"]}]' # Optional: Per-URL config with CSS selectors to exclude from Axe or wait for before scanning. When provided, takes precedence over 'urls'. ``` > 👉 Update all `REPLACE_THIS` placeholders with your actual values. See [Action Inputs](#action-inputs) for details. @@ -139,7 +139,7 @@ Trigger the workflow manually or automatically based on your configuration. The | `color_scheme` | No | Playwright `colorScheme` setting for scan contexts. Allowed values: `light`, `dark`, `no-preference` | `dark` | | `scans` | No | An array of scans (or plugins) to be performed. Built-in engines are `axe` and `accesslint`; any other entry is treated as a plugin name. If not provided, only Axe will be performed. | `'["axe", "accesslint", ...other plugins]'` | | `dry_run` | No | When `true`, scan and log the issues that _would_ be filed without opening, closing, reopening, or assigning any issues — and without writing to the `gh-cache` branch. Useful for safely previewing results. Default: `false` | `true` | -| `url_configs` | No | A stringified JSON array of URL config objects. Each object must have a `url` field and may have an optional `excludeSelectors` field (array of CSS selectors to exclude from the Axe scan for that URL). When provided, takes precedence over the `urls` input. | `'[{"url":"https://example.com","excludeSelectors":["iframe","#widget"]}]'` | +| `url_configs` | No | A stringified JSON array of URL config objects. Each object must have a `url` field and may have `excludeSelectors` (selectors to exclude from Axe) and `waitForSelectors` (selectors that must become visible within 30 seconds before scanning). When provided, takes precedence over the `urls` input. | `'[{"url":"https://example.com","excludeSelectors":["iframe","#widget"],"waitForSelectors":["#app"]}]'` | --- diff --git a/action.yml b/action.yml index 7de2f5d8..56b4160b 100644 --- a/action.yml +++ b/action.yml @@ -7,7 +7,7 @@ inputs: required: false multiline: true url_configs: - description: "Stringified JSON array of URL config objects, each with a 'url' field and an optional 'excludeSelectors' field (array of CSS selectors to exclude from the Axe scan for that URL). When provided, takes precedence over the 'urls' input." + description: "Stringified JSON array of URL config objects, each with a 'url' field and optional 'excludeSelectors' (selectors to exclude from Axe) and 'waitForSelectors' (selectors that must be visible before scanning) fields. When provided, takes precedence over the 'urls' input." required: false repository: description: 'Repository (with owner) to file issues in' From b13eadf11f7a4915bc1f909810cbcd7b6f5a640f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 5 Oct 2026 13:29:07 +0000 Subject: [PATCH 17/21] Ensure Playwright cleanup after selector wait failures Co-authored-by: abdulahmad307 <204748719+abdulahmad307@users.noreply.github.com> --- .github/actions/find/src/findForUrl.ts | 87 ++++++++++--------- .github/actions/find/tests/findForUrl.test.ts | 52 ++++++++++- 2 files changed, 97 insertions(+), 42 deletions(-) diff --git a/.github/actions/find/src/findForUrl.ts b/.github/actions/find/src/findForUrl.ts index 2d5046eb..163df959 100644 --- a/.github/actions/find/src/findForUrl.ts +++ b/.github/actions/find/src/findForUrl.ts @@ -27,56 +27,63 @@ export async function findForUrl( ...(reducedMotion ? {reducedMotion} : {}), ...(colorScheme ? {colorScheme} : {}), } - const context = await browser.newContext(contextOptions) - const page = await context.newPage() - await page.goto(url) - await Promise.all( - (waitForSelectors ?? []).map(selector => - page.locator(selector).waitFor({state: 'visible', timeout: SELECTOR_WAIT_TIMEOUT}), - ), - ) + let context: playwright.BrowserContext | undefined + try { + context = await browser.newContext(contextOptions) + const page = await context.newPage() + await page.goto(url) + await Promise.all( + (waitForSelectors ?? []).map(selector => + page.locator(selector).waitFor({state: 'visible', timeout: SELECTOR_WAIT_TIMEOUT}), + ), + ) - const findings: Finding[] = [] - const addFinding = async (findingData: Finding) => { - let screenshotId - if (includeScreenshots) { - screenshotId = await generateScreenshots(page) + const findings: Finding[] = [] + const addFinding = async (findingData: Finding) => { + let screenshotId + if (includeScreenshots) { + screenshotId = await generateScreenshots(page) + } + findings.push({...findingData, screenshotId}) } - findings.push({...findingData, screenshotId}) - } - try { - const scansContext = getScansContext() + try { + const scansContext = getScansContext() - if (scansContext.shouldRunPlugins) { - const plugins = await loadPlugins() - for (const plugin of plugins) { - if (scansContext.scansToPerform.includes(plugin.name)) { - core.info(`Running plugin: ${plugin.name}`) - await invokePlugin({ - plugin, - page, - addFinding, - }) - } else { - core.info(`Skipping plugin ${plugin.name} because it is not included in the 'scans' input`) + if (scansContext.shouldRunPlugins) { + const plugins = await loadPlugins() + for (const plugin of plugins) { + if (scansContext.scansToPerform.includes(plugin.name)) { + core.info(`Running plugin: ${plugin.name}`) + await invokePlugin({ + plugin, + page, + addFinding, + }) + } else { + core.info(`Skipping plugin ${plugin.name} because it is not included in the 'scans' input`) + } } } - } - if (scansContext.shouldPerformAxeScan) { - await runAxeScan({page, addFinding, excludeSelectors}) - } + if (scansContext.shouldPerformAxeScan) { + await runAxeScan({page, addFinding, excludeSelectors}) + } - if (scansContext.shouldPerformAccesslintScan) { - await runAccesslintScan({page, addFinding}) + if (scansContext.shouldPerformAccesslintScan) { + await runAccesslintScan({page, addFinding}) + } + } catch (e) { + core.error(`Error during accessibility scan: ${e}`) + } + return findings + } finally { + try { + await context?.close() + } finally { + await browser.close() } - } catch (e) { - core.error(`Error during accessibility scan: ${e}`) } - await context.close() - await browser.close() - return findings } async function runAxeScan({ diff --git a/.github/actions/find/tests/findForUrl.test.ts b/.github/actions/find/tests/findForUrl.test.ts index af73ed5c..89474f01 100644 --- a/.github/actions/find/tests/findForUrl.test.ts +++ b/.github/actions/find/tests/findForUrl.test.ts @@ -108,6 +108,11 @@ describe('findForUrl', () => { expect(playwrightMocks.pageGoto).toHaveBeenCalledWith('test.com') expect(playwrightMocks.pageLocator).not.toHaveBeenCalled() expect(AxeBuilder.prototype.analyze).toHaveBeenCalledTimes(1) + expect(playwrightMocks.contextClose).toHaveBeenCalledTimes(1) + expect(playwrightMocks.browserClose).toHaveBeenCalledTimes(1) + expect(playwrightMocks.contextClose.mock.invocationCallOrder[0]).toBeLessThan( + playwrightMocks.browserClose.mock.invocationCallOrder[0], + ) }) it('waits for each configured selector after navigation and before scanning', async () => { @@ -128,15 +133,58 @@ describe('findForUrl', () => { ) }) - it('does not scan when a configured selector times out', async () => { + it('closes the context and browser without scanning when a configured selector times out', async () => { const timeoutError = new Error('Timeout 30000ms exceeded') actionInput = '' clearAll() playwrightMocks.locatorWaitFor.mockRejectedValueOnce(timeoutError) - await expect(findForUrl({url: 'test.com', waitForSelectors: ['#app']})).rejects.toThrow(timeoutError) + await expect(findForUrl({url: 'test.com', waitForSelectors: ['#app']})).rejects.toBe(timeoutError) + + expect(AxeBuilder.prototype.analyze).not.toHaveBeenCalled() + expect(playwrightMocks.contextClose).toHaveBeenCalledTimes(1) + expect(playwrightMocks.browserClose).toHaveBeenCalledTimes(1) + }) + + it.each([ + ['context creation', playwrightMocks.browserNewContext, false], + ['page creation', playwrightMocks.contextNewPage, true], + ['navigation', playwrightMocks.pageGoto, true], + ] as const)('cleans up when %s fails', async (_stage, failingOperation, contextCreated) => { + const error = new Error('Page setup failed') + actionInput = '' + clearAll() + failingOperation.mockRejectedValueOnce(error) + + await expect(findForUrl({url: 'test.com'})).rejects.toBe(error) expect(AxeBuilder.prototype.analyze).not.toHaveBeenCalled() + expect(playwrightMocks.contextClose).toHaveBeenCalledTimes(contextCreated ? 1 : 0) + expect(playwrightMocks.browserClose).toHaveBeenCalledTimes(1) + }) + + it('closes the browser even if closing the context fails', async () => { + const error = new Error('Context cleanup failed') + actionInput = '' + clearAll() + playwrightMocks.contextClose.mockRejectedValueOnce(error) + + await expect(findForUrl({url: 'test.com'})).rejects.toBe(error) + + expect(playwrightMocks.browserClose).toHaveBeenCalledTimes(1) + }) + + it('preserves scan error handling and closes the context and browser', async () => { + const error = new Error('Scan failed') + actionInput = '' + clearAll() + vi.mocked(AxeBuilder.prototype.analyze).mockRejectedValueOnce(error) + + await expect(findForUrl({url: 'test.com'})).resolves.toEqual([]) + + expect(core.error).toHaveBeenCalledWith(`Error during accessibility scan: ${error}`) + expect(playwrightMocks.contextClose).toHaveBeenCalledTimes(1) + expect(playwrightMocks.browserClose).toHaveBeenCalledTimes(1) }) }) From bc3517647eae0405e72dd41a7e9a9d9801c93a49 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Oct 2026 12:26:38 +0000 Subject: [PATCH 18/21] chore(deps-dev): Bump flatted from 3.3.3 to 3.4.4 Bumps [flatted](https://github.com/WebReflection/flatted) from 3.3.3 to 3.4.4. - [Commits](https://github.com/WebReflection/flatted/compare/v3.3.3...v3.4.4) --- updated-dependencies: - dependency-name: flatted dependency-version: 3.4.4 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index ef2e585b..ee31576f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1560,9 +1560,9 @@ } }, "node_modules/flatted": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", - "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.4.tgz", + "integrity": "sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==", "dev": true, "license": "ISC" }, From 9a4b1872227b7713a701178c1b315db7e928f21a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Oct 2026 12:26:46 +0000 Subject: [PATCH 19/21] chore(deps-dev): Bump brace-expansion from 5.0.7 to 5.0.12 Bumps [brace-expansion](https://github.com/juliangruber/brace-expansion) from 5.0.7 to 5.0.12. - [Release notes](https://github.com/juliangruber/brace-expansion/releases) - [Commits](https://github.com/juliangruber/brace-expansion/compare/v5.0.7...v5.0.12) --- updated-dependencies: - dependency-name: brace-expansion dependency-version: 5.0.12 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index ef2e585b..3dcb649e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1178,16 +1178,16 @@ "license": "MIT" }, "node_modules/brace-expansion": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz", - "integrity": "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==", + "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/chai": { From 0592777e7a6c5446cc04f2422101baa01a44ed13 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Oct 2026 12:26:54 +0000 Subject: [PATCH 20/21] chore(deps-dev): Bump source-map-js from 1.2.1 to 1.2.2 Bumps [source-map-js](https://github.com/7rulnik/source-map-js) from 1.2.1 to 1.2.2. - [Release notes](https://github.com/7rulnik/source-map-js/releases) - [Changelog](https://github.com/7rulnik/source-map-js/blob/main/CHANGELOG.md) - [Commits](https://github.com/7rulnik/source-map-js/compare/v1.2.1...v1.2.2) --- updated-dependencies: - dependency-name: source-map-js dependency-version: 1.2.2 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index ef2e585b..2e411ec5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2301,9 +2301,9 @@ "license": "ISC" }, "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.2.tgz", + "integrity": "sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==", "dev": true, "license": "BSD-3-Clause", "peer": true, From e01538c1b28b2d46ae8e9eb8e08458fe2968d4fa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Oct 2026 12:26:59 +0000 Subject: [PATCH 21/21] chore(deps-dev): Bump undici from 6.28.1 to 6.29.0 Bumps [undici](https://github.com/nodejs/undici) from 6.28.1 to 6.29.0. - [Release notes](https://github.com/nodejs/undici/releases) - [Commits](https://github.com/nodejs/undici/compare/v6.28.1...v6.29.0) --- updated-dependencies: - dependency-name: undici dependency-version: 6.29.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index ef2e585b..5b312076 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2438,9 +2438,9 @@ } }, "node_modules/undici": { - "version": "6.28.1", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.28.1.tgz", - "integrity": "sha512-zWpdTVD54H48CIybL0rWQ3ukpb9d23wM7eH5RtfdmeP70cWHNjtfo7P4vZX+5CoDcO53J4Pu5uXp7lNfjc6DRA==", + "version": "6.29.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.29.0.tgz", + "integrity": "sha512-R+RODBqp6i2pPflGdq+xIOUkl+RNfGgHwoinecKu/JCuf2uO06cOKoDbI2P7Dn6KcswdKwrczbU6IYJ6K8X+wg==", "dev": true, "license": "MIT", "engines": {