diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index a588723cb..c9dbc93ed 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -88,7 +88,7 @@ body: label: "Are you willing to submit a PR?" description: "We accept pull requests targeting the develop branch." options: - - "Yes" - "No" + - "Yes" validations: required: true diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index aeebace1c..96ee608ea 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -20,19 +20,19 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 2 persist-credentials: false - name: Initialize CodeQL - uses: github/codeql-action/init@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4 + uses: github/codeql-action/init@2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2 # v4 with: config-file: ./.github/codeql/codeql-configuration.yml languages: javascript - name: Autobuild - uses: github/codeql-action/autobuild@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4 + uses: github/codeql-action/autobuild@2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2 # v4 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4 + uses: github/codeql-action/analyze@2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2 # v4 diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 43cd69196..897eea823 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -19,11 +19,11 @@ jobs: strategy: fail-fast: false matrix: - operating-system: [ubuntu-24.04, ubuntu-22.04, windows-2022, macos-15-intel] - php-versions: ['5.3', '5.4', '5.5', '5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4', '8.5', '8.6'] + operating-system: [ubuntu-24.04, ubuntu-22.04, windows-2022, macos-15] + php-versions: ['5.3', '5.4', '5.5', '5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4', '8.5', '8.6', '8.7'] steps: - name: Setup PHP - uses: shivammathur/setup-php@7c071dfe9dc99bdf297fa79cb49ea005b9fcadbc # v2 + uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # v2 with: php-version: ${{ matrix.php-versions }} tools: none @@ -42,7 +42,7 @@ jobs: run: | php -m | Out-File -FilePath "$env:file.all" -Append - name: Setup PHP - uses: shivammathur/setup-php@7c071dfe9dc99bdf297fa79cb49ea005b9fcadbc # v2 + uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # v2 with: php-version: ${{ matrix.php-versions }} extensions: none @@ -104,7 +104,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: repository: ${{ github.repository }}.wiki persist-credentials: false @@ -125,9 +125,9 @@ jobs: run: | for os in ubuntu-24.04 ubuntu-22.04 windows-2025 windows-2022 windows-2019 macos-13 macos-14 macos-15 macos-26; do echo "These are extensions which are loaded by default on the following PHP versions. More extensions which are available as packages and available on pecl are supported by setup-php. Refer to [php extension support](https://github.com/shivammathur/setup-php#heavy_plus_sign-php-extension-support) for more details." > Php-extensions-loaded-on-"$os".md - for version in 5.3 5.4 5.5 5.6 7.0 7.1 7.2 7.3 7.4 8.0 8.1 8.2 8.3 8.4 8.5 8.6; do + for version in 5.3 5.4 5.5 5.6 7.0 7.1 7.2 7.3 7.4 8.0 8.1 8.2 8.3 8.4 8.5 8.6 8.7; do if [[ "${os%-*}" = "macos" ]]; then - cat lists/php"$version"-macos-15-intel.md >> Php-extensions-loaded-on-"$os".md + cat lists/php"$version"-macos-15.md >> Php-extensions-loaded-on-"$os".md elif [ "${os%-*}" = "windows" ]; then cat lists/php"$version"-windows-2022.md >> Php-extensions-loaded-on-"$os".md else diff --git a/.github/workflows/node.yml b/.github/workflows/node.yml index 41495c183..4eaa8293c 100644 --- a/.github/workflows/node.yml +++ b/.github/workflows/node.yml @@ -33,13 +33,13 @@ jobs: operating-system: [ubuntu-latest, windows-latest, macos-latest] steps: - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 2 persist-credentials: false - name: Setup Node.js 24.x - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v6 with: node-version: 24.x @@ -52,6 +52,9 @@ jobs: - name: ESLint Check run: npm run lint + - name: TypeScript Check + run: npm run typecheck + - name: Run tests run: npm test @@ -59,7 +62,7 @@ jobs: run: npm audit - name: Send Coverage - uses: codecov/codecov-action@e79a6962e0d4c0c17b229090214935d2e33f8354 # v6 + uses: codecov/codecov-action@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7.1.1 with: token: ${{ secrets.CODECOV_TOKEN }} files: coverage/lcov.info diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index 2d55f7c4d..7225d08cc 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -31,8 +31,8 @@ jobs: strategy: fail-fast: false matrix: - operating-system: [ubuntu-24.04, ubuntu-22.04, windows-2022, macos-15-intel] - php-versions: ['5.3', '5.4', '5.5', '5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4', '8.5', '8.6'] + operating-system: [ubuntu-24.04, ubuntu-22.04, windows-2022, macos-15] + php-versions: ['5.3', '5.4', '5.5', '5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4', '8.5', '8.6', '8.7'] include: - operating-system: ubuntu-24.04 php-versions: '' @@ -42,20 +42,20 @@ jobs: key: cache-v5 steps: - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Setup cache environment id: cache-env - uses: shivammathur/cache-extensions@256729b5fef535345e27904657f78048c0990f81 # v1 + uses: shivammathur/cache-extensions@de3c642a5fce0ef91581a1c9831e229f525196d6 # v1 with: php-version: ${{ matrix.php-versions || env.default-php-version }} extensions: ${{ env.extensions }} key: ${{ env.key }} - name: Cache extensions - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v5 with: path: ${{ steps.cache-env.outputs.dir }} key: ${{ steps.cache-env.outputs.key }} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 68f8e832a..51d585d1c 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -26,19 +26,19 @@ jobs: steps: - name: Checkout release if: github.event_name != 'workflow_dispatch' - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Checkout tag - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 if: github.event_name == 'workflow_dispatch' with: ref: ${{ github.event.inputs.tag }} persist-credentials: false - name: Setup Node.js - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v6 with: node-version: '24.x' registry-url: https://registry.npmjs.org @@ -50,12 +50,17 @@ jobs: npm run build sed -i -e '/lib\//d' .gitignore + - name: Select npm distribution tag + id: publish-tag + run: | + jq -r '.version | if test("alpha|beta|rc"; "i") then "tag=next" else "tag=latest" end' package.json >> "$GITHUB_OUTPUT" + - name: Publish to NPM if: "!contains(github.event.inputs.skip, 'skip-npm')" - run: npm publish --access public + run: npm publish --access public --tag "${{ steps.publish-tag.outputs.tag }}" - name: Change to GitHub Packages registry - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v6 with: registry-url: https://npm.pkg.github.com package-manager-cache: false @@ -67,6 +72,6 @@ jobs: - name: Publish to GitHub Packages if: "!contains(github.event.inputs.skip, 'skip-github-packages')" - run: npm publish + run: npm publish --tag "${{ steps.publish-tag.outputs.tag }}" env: NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/README.md b/README.md index c3b6126d1..14c8fb450 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ GitHub Actions status Codecov Code Coverage LICENSE - PHP Versions Supported + PHP Versions Supported

setup-php reddit @@ -18,7 +18,7 @@ setup-php status

-Setup PHP with required extensions, php.ini configuration, code-coverage support and various tools like composer in [GitHub Actions](https://github.com/features/actions "GitHub Actions"). This action gives you a cross-platform interface to set up the PHP environment you need to test your application. Refer to [Usage](#memo-usage "How to use this") section and [examples](#examples "Examples of use") to see how to use this. +Setup PHP with required extensions, php.ini configuration, code-coverage support, and various tools like composer in [GitHub Actions](https://github.com/features/actions "GitHub Actions"). This action gives you a cross-platform interface to set up the PHP environment you need to test your application. Refer to the [Usage](#memo-usage "How to use this") section and [examples](#examples "Examples of use") to see how to use this. ## Contents @@ -68,46 +68,52 @@ Both `GitHub-hosted` and `self-hosted` runners are supported by `setup-php` on t ### GitHub-Hosted Runners -| Virtual environment | Arch | YAML workflow label | Pre-installed PHP | -|---------------------|---------|------------------------------------|-------------------| -| Ubuntu 24.04 | x86_64 | `ubuntu-latest` or `ubuntu-24.04` | `PHP 8.3` | -| Ubuntu 22.04 | x86_64 | `ubuntu-22.04` | `PHP 8.1` | -| Ubuntu 24.04 | aarch64 | `ubuntu-24.04-arm` | `PHP 8.3` | -| Ubuntu 22.04 | aarch64 | `ubuntu-22.04-arm` | `PHP 8.1` | -| Windows Server 2025 | x64 | `windows-2025` | `PHP 8.5` | -| Windows Server 2022 | x64 | `windows-latest` or `windows-2022` | `PHP 8.5` | -| macOS Tahoe 26.x | arm64 | `macos-26` | - | -| macOS Sequoia 15.x | arm64 | `macos-latest` or `macos-15` | - | -| macOS Sonoma 14.x | arm64 | `macos-14` | - | -| macOS Tahoe 26.x | x86_64 | `macos-26-intel` | `PHP 8.5` | -| macOS Sequoia 15.x | x86_64 | `macos-15-intel` | `PHP 8.5` | +| Virtual environment | Arch | YAML workflow label | Pre-installed PHP | +|------------------------|---------|-----------------------------------------------------------|-------------------| +| Ubuntu 26.04 | x86_64 | `ubuntu-26.04` | `PHP 8.5` | +| Ubuntu 24.04 | x86_64 | `ubuntu-latest` or `ubuntu-24.04` | `PHP 8.3` | +| Ubuntu 22.04 | x86_64 | `ubuntu-22.04` | `PHP 8.1` | +| Ubuntu 26.04 | aarch64 | `ubuntu-26.04-arm` | `PHP 8.5` | +| Ubuntu 24.04 | aarch64 | `ubuntu-24.04-arm` | `PHP 8.3` | +| Ubuntu 22.04 | aarch64 | `ubuntu-22.04-arm` | `PHP 8.1` | +| Windows Server 2025 | x64 | `windows-latest`, `windows-2025` or `windows-2025-vs2026` | `PHP 8.5` | +| Windows Server 2022 | x64 | `windows-2022` | `PHP 8.5` | +| Windows 11 ARM | arm64 | `windows-11-arm` or `windows-11-vs2026-arm` | `PHP 8.4` | +| macOS Golden Gate 27.x | arm64 | `xcode-27` | - | +| macOS Tahoe 26.x | arm64 | `macos-latest` or `macos-26` | - | +| macOS Sequoia 15.x | arm64 | `macos-15` | - | +| macOS Tahoe 26.x | x86_64 | `macos-26-intel` | `PHP 8.5` | +| macOS Sequoia 15.x | x86_64 | `macos-15-intel` | `PHP 8.5` | + +> [!NOTE] +> Support for Intel (`x86_64`) macOS runners and macOS Sonoma 14.x (`macos-14`) arm64 runners is deprecated and will be removed completely in a future release of `setup-php`. We recommend migrating to arm64-based macOS runners running macOS 15 or newer, such as `macos-26` or `macos-15`. ### Self-Hosted Runners | Host OS/Virtual environment | YAML workflow label | |----------------------------------|----------------------------| +| Ubuntu 26.04 | `self-hosted` or `Linux` | | Ubuntu 24.04 | `self-hosted` or `Linux` | | Ubuntu 22.04 | `self-hosted` or `Linux` | | Debian 13 | `self-hosted` or `Linux` | | Debian 12 | `self-hosted` or `Linux` | -| Debian 11 | `self-hosted` or `Linux` | | Windows 7 and newer | `self-hosted` or `Windows` | | Windows Server 2012 R2 and newer | `self-hosted` or `Windows` | -| macOS Tahoe 26.x x86_64/arm64 | `self-hosted` or `macOS` | -| macOS Sequoia 15.x x86_64/arm64 | `self-hosted` or `macOS` | -| macOS Sonoma 14.x x86_64/arm64 | `self-hosted` or `macOS` | +| macOS Golden Gate 27.x arm64 | `self-hosted` or `macOS` | +| macOS Tahoe 26.x arm64 | `self-hosted` or `macOS` | +| macOS Sequoia 15.x arm64 | `self-hosted` or `macOS` | - Refer to the [self-hosted setup](#self-hosted-setup) to use the action on self-hosted runners. -- Operating systems based on the above Ubuntu and Debian versions are also supported on best effort basis. +- Operating systems based on the above Ubuntu and Debian versions are also supported on a best effort basis. - If the requested PHP version is pre-installed, `setup-php` switches to it, otherwise it installs the PHP version. ## :tada: PHP Support On all supported OS/Platforms, the following PHP versions can be set up as per the runner. -- PHP 5.3 to PHP 8.6 on GitHub-hosted runners, except for macOS ARM64 runners (macos-14). -- PHP 5.6 to PHP 8.6 on GitHub-hosted macOS ARM64 runners (macos-14). -- PHP 5.6 to PHP 8.6 on self-hosted runners. +- PHP 5.3 to PHP 8.7 on GitHub-hosted runners, except for macOS ARM64 runners. +- PHP 5.6 to PHP 8.7 on GitHub-hosted macOS ARM64 runners. +- PHP 5.6 to PHP 8.7 on self-hosted runners. | PHP Version | Stability | Release Support | Runner Support | |-------------|-----------|-----------------------|--------------------------------| @@ -127,10 +133,11 @@ On all supported OS/Platforms, the following PHP versions can be set up as per t | `8.4` | `Stable` | `Active` | `GitHub-hosted`, `self-hosted` | | `8.5` | `Stable` | `Active` | `GitHub-hosted`, `self-hosted` | | `8.6` | `Nightly` | `In development` | `GitHub-hosted`, `self-hosted` | +| `8.7` | `Nightly` | `In development` | `GitHub-hosted`, `self-hosted` | > [!Note] -> - Specifying `8.6` in `php-version` input installs a nightly build of `PHP 8.6.0-dev` from the master branch of PHP. See [nightly build setup](#nightly-build-setup) for more information. +> - Specifying `8.7` or `master` in `php-version` input installs a nightly build of `PHP 8.7.0-dev` from the master branch of PHP. Specifying `8.6` or `nightly` installs a nightly build of `PHP 8.6.0-dev` from the PHP-8.6 branch. See [nightly build setup](#nightly-build-setup) for more information. > - To use JIT on `PHP 8.0` and above, refer to the [JIT configuration](#jit-configuration) section. ## :heavy_plus_sign: PHP Extension Support @@ -155,7 +162,7 @@ PHP extensions can be set up using the `extensions` input. It accepts a `string` - Extensions installed along with PHP if specified are enabled. -- Specific versions of extensions available on `PECL` can be set up by suffixing the extension's name with the version. This is useful for installing old versions of extensions which support end of life PHP versions. +- Specific versions of extensions available on `PECL` can be set up by suffixing the extension's name with the version. This is useful for installing old versions of extensions which support end-of-life PHP versions. ```yaml - name: Setup PHP with specific version of PECL extension @@ -180,14 +187,14 @@ PHP extensions can be set up using the `extensions` input. It accepts a `string` - Shared extensions can be disabled by prefixing them with a `:`. All extensions depending on the specified extension will also be disabled. ```yaml -- name: Setup PHP and disable opcache +- name: Setup PHP and disable mbstring uses: shivammathur/setup-php@v2 with: php-version: '8.5' extensions: :mbstring ``` -- All shared extensions can be disabled by specifying `none`. When `none` is specified along with other extensions, it is hoisted to the start of the input. So, all the shared extensions will be disabled first, then rest of the extensions in the input will be processed. +- All shared extensions can be disabled by specifying `none`. When `none` is specified along with other extensions, it is hoisted to the start of the input. So, all the shared extensions will be disabled first, then the rest of the extensions in the input will be processed. This disables all core and third-party shared extensions and thus, can break some tools that need them. Required extensions are enabled again when the tools are set up on a best-effort basis. So it is recommended to add the extensions required for your tools after `none` in the `extensions` input to avoid any issues. @@ -216,7 +223,7 @@ This disables all core and third-party shared extensions and thus, can break som - `event`, `gearman`, `geos` and `relay` on `Ubuntu` and `macOS`. - `blackfire`, `couchbase`, `ibm_db2`, `ioncube`, `oci8`, `pdo_firebird`, `pdo_ibm`, `pdo_oci`, `pecl_http`, `phalcon3`, `phalcon4`, `phalcon5`, and `zephir_parser` on all supported OS. -- By default, extensions which cannot be added or disabled gracefully leave an error message in the logs, the execution is not interrupted. To change this behaviour you can set `fail-fast` flag to `true`. +- By default, extensions which cannot be added or disabled gracefully leave an error message in the logs. The execution is not interrupted. To change this behaviour you can set `fail-fast` flag to `true`. ```yaml - name: Setup PHP with fail-fast @@ -232,7 +239,7 @@ This disables all core and third-party shared extensions and thus, can break som These tools can be set up globally using the `tools` input. It accepts a string in csv-format. -[`backward-compatibility-check`], [`behat`], [`blackfire`], [`blackfire-player`], [`box`], [`castor`], [`churn`], [`codeception`], [`composer`], [`composer-dependency-analyser`], [`composer-normalize`], [`composer-prefetcher`], [`composer-require-checker`], [`composer-unused`], [`cs2pr`], [`deployer`], [`ecs`], [`flex`], [`grpc_php_plugin`], [`infection`], [`mago`], [`name-collision-detector`], [`parallel-lint`], [`pecl`], [`phan`], [`phing`], [`phinx`], [`phive`], [`php-config`], [`php-cs-fixer`], [`php-scoper`], [`phpcbf`], [`phpcpd`], [`phpcs`], [`phpdoc`] or [`phpDocumentor`], [`phpize`], [`phplint`], [`phpmd`], [`phpspec`], [`phpstan`], [`phpunit`], [`phpunit-bridge`], [`phpunit-polyfills`], [`pie`], [`pint`], [`prestissimo`], [`protoc`], [`psalm`], [`rector`], [`symfony`] or [`symfony-cli`], [`vapor`] or [`vapor-cli`], [`wp`] or [`wp-cli`] +[`backward-compatibility-check`], [`behat`], [`blackfire`], [`blackfire-player`], [`box`], [`castor`], [`churn`], [`codeception`], [`composer`], [`composer-dependency-analyser`], [`composer-normalize`], [`composer-prefetcher`], [`composer-require-checker`], [`composer-unused`], [`cpx`], [`cs2pr`], [`deployer`], [`ecs`], [`flex`], [`grpc_php_plugin`], [`infection`], [`laravel-cloud`] or [`cloud-cli`], [`mago`], [`name-collision-detector`], [`parallel-lint`], [`pecl`], [`phan`], [`phing`], [`phinx`], [`phive`], [`php-config`], [`php-cs-fixer`], [`php-scoper`], [`phpcbf`], [`phpcpd`], [`phpcs`], [`phpdoc`] or [`phpDocumentor`], [`phpize`], [`phplint`], [`phpmd`], [`phpspec`], [`phpstan`], [`phpunit`], [`phpunit-bridge`], [`phpunit-polyfills`], [`pie`], [`pint`], [`prestissimo`], [`protoc`], [`psalm`], [`rector`], [`symfony`] or [`symfony-cli`], [`vapor`] or [`vapor-cli`], [`wp`] or [`wp-cli`] ```yaml - name: Setup PHP with tools @@ -242,7 +249,7 @@ These tools can be set up globally using the `tools` input. It accepts a string tools: php-cs-fixer, phpunit ``` -- In addition to above tools any composer tool or package can also be set up globally by specifying it as `vendor/package` matching the listing on Packagist. This format accepts the same [version constraints](https://getcomposer.org/doc/articles/versions.md#writing-version-constraints "Composer version constraints") as `composer`. +- In addition to the above tools, any composer tool or package can also be set up globally by specifying it as `vendor/package` matching the listing on Packagist. This format accepts the same [version constraints](https://getcomposer.org/doc/articles/versions.md#writing-version-constraints "Composer version constraints") as `composer`. ```yaml - name: Setup PHP with tools @@ -259,7 +266,19 @@ These tools can be set up globally using the `tools` input. It accepts a string - Major version. For example `tool:1` or `tool:1.x`. - Major and minor version. For example `tool:1.2` or `tool:1.2.x`. - When you specify just the major version or the version in `major.minor` format, the latest patch version matching the input will be setup. + When you specify just the major version or the version in `major.minor` format, the latest patch version matching the input will be set up. + +- To harden your workflow against supply chain attacks, you can pin a tool to a checksum in the form `tool:version@sha256:` or `tool:version@sha512:`. The downloaded tool is verified against the checksum and it is not set up if the verification fails, even if the tool is served from the tools cache. + +```yaml +- name: Setup PHP with tools pinned to a checksum + uses: shivammathur/setup-php@v2 + with: + php-version: '8.5' + tools: composer:2.9.8@sha256:59b2c50e10cafa0d8efc19ede9a326d782f096c674a26baf98cf042ce23de890 +``` + + Checksum verification is supported only for tools downloaded as phar archives with a full version, such as `tool:1.2.3` or `tool:1.2.3-beta1`. Specifying a checksum with an omitted version, a variable tag such as `latest`, `stable`, `preview` or `snapshot`, or a partial version such as `2`, `2.x`, `2.9` or `2.9.x` results in an error. These versions can resolve to different releases with different checksums. Checksum verification is not supported for tools set up using `composer` packages or custom package scripts; specifying a checksum for these tools also results in an error. - The latest stable version of `composer` is set up by default. You can set up the required `composer` version by specifying the major version `v1` or `v2`, or the version in `major.minor` or `semver` format. Additionally, for composer `snapshot` and `preview` can also be specified to set up the respective releases. @@ -299,10 +318,10 @@ These tools can be set up globally using the `tools` input. It accepts a string fail-fast: true ``` -- By default, `composer` blocks all its plugins. If you are using the `tools` input to install a composer plugin it will be added to the allow list, alternatively if your dependencies have composer plugins, you can allow them by setting `COMPOSER_ALLOW_PLUGINS` that accepts a csv string of plugin names. +- By default, `composer` blocks all its plugins. If you are using the `tools` input to install a composer plugin it will be added to the allowlist, alternatively if your dependencies have composer plugins, you can allow them by setting `COMPOSER_ALLOW_PLUGINS` that accepts a csv string of plugin names. ```yaml -- name: Setup PHP with fail-fast +- name: Setup PHP with allow composer plugins uses: shivammathur/setup-php@v2 with: php-version: '8.5' @@ -342,7 +361,7 @@ Runs on all [PHP versions supported](#tada-php-support "List of PHP versions sup ``` - When you specify `coverage: xdebug`, the latest version of Xdebug compatible with the PHP version is set up by default. -- If you need Xdebug 2.x on PHP 7.2, 7.3 or 7.4, you can specify `coverage: xdebug2`. +- If you need Xdebug 2.x on PHP 7.2, 7.3, or 7.4, you can specify `coverage: xdebug2`. ```yaml - name: Setup PHP with Xdebug 2.x @@ -353,7 +372,7 @@ Runs on all [PHP versions supported](#tada-php-support "List of PHP versions sup ``` > [!NOTE] -> Xdebug is enabled by default on Ubuntu GitHub Actions images, so if you are not using it in your workflow it is recommended to disable it as that will have a positive impact on your PHP performance. Please refer to the [disable coverage](#disable-coverage) section for details. +> Xdebug is enabled by default on Ubuntu GitHub Actions images, so if you are not using it in your workflows, it is recommended to disable it as that will have a positive impact on your PHP performance. Please refer to the [disable coverage](#disable-coverage) section for details. ### PCOV @@ -372,7 +391,7 @@ Runs on PHP 7.1 and newer PHP versions. ``` - PHPUnit 8.x and above support PCOV out of the box. -- If you are using PHPUnit 5.x, 6.x or 7.x, you need to set up `pcov/clobber` before executing your tests. +- If you are using PHPUnit 5.x, 6.x, or 7.x, you need to set up `pcov/clobber` before executing your tests. ```yaml - name: Setup PCOV @@ -390,7 +409,7 @@ Disable coverage for these reasons: - You are not generating coverage reports while testing. - You are using `phpdbg` for running your tests. - You are profiling your code using `blackfire`. -- You are using PHP in JIT mode. Please refer to [JIT configuration](#jit-configuration) section for more details. +- You are using PHP in JIT mode. Please refer to the [JIT configuration](#jit-configuration) section for more details. ```yaml - name: Setup PHP with no coverage driver @@ -412,7 +431,8 @@ Disable coverage for these reasons: - Accepts a `string`. For example `'8.5'`. - Accepts `lowest` to set up the lowest supported PHP version. - Accepts `highest` or `latest` to set up the latest stable PHP version. -- Accepts `nightly` to set up a nightly build from the master branch of PHP. +- Accepts `nightly` to set up a nightly build of the next PHP release (`8.6`). +- Accepts `master` to set up a nightly build from the master branch of PHP (`8.7`). - Accepts `pre-installed` to set up the highest pre-installed PHP version. You can combine this with `update: true` to update the pre-installed PHP version. - Accepts the format `d.x`, where `d` is the major version. For example `5.x`, `7.x` and `8.x`. - See [PHP support](#tada-php-support) for the supported PHP versions. @@ -514,6 +534,13 @@ On GitHub Actions you can assign the `setup-php` step an `id`, you can use the s - By default, it is set to `false`. - See [force update setup](#force-update-setup) for more info. +#### `verbose` (optional) + +- Specify to enable verbose output. +- Accepts `true`, `false`, `v`, `vv` and `vvv`. +- By default, it is set to `false`. +- See [verbose setup](#verbose-setup) for more info. + See below for more info. ### Basic Setup @@ -562,7 +589,7 @@ jobs: ### Nightly Build Setup -> Set up a nightly build of `PHP 8.6`. +> Set up a nightly build of `PHP 8.6` or `PHP 8.7`. - These PHP versions are currently in active development and might contain bugs and breaking changes. - Some user space extensions might not support these versions currently. @@ -572,7 +599,7 @@ steps: - name: Setup nightly PHP uses: shivammathur/setup-php@v2 with: - php-version: '8.6' + php-version: '8.7' extensions: mbstring ini-values: post_max_size=256M, max_execution_time=180 coverage: xdebug @@ -642,18 +669,24 @@ jobs: > Debug your workflow -To debug any issues, you can use the `verbose` tag instead of `v2`. +- Set the `verbose` environment variable to `true` or `v` to show command output. +- Set `verbose` to `vv` or `vvv` to also enable `set -x` on Linux and macOS. +- On Windows, `vv` enables `Set-PSDebug -Trace 1` and `vvv` enables `Set-PSDebug -Trace 2`. +- Enabling [GitHub Actions debug logging](https://docs.github.com/en/actions/how-tos/monitor-workflows/enable-debug-logging) (`RUNNER_DEBUG=1`) also enables verbose mode. +- The `verbose` and `more-verbose` tags have been deprecated and will be discontinued in the next major release. ```yaml - name: Setup PHP with logs - uses: shivammathur/setup-php@verbose + uses: shivammathur/setup-php@v2 with: php-version: '8.5' + env: + verbose: true ``` ### Multi-Arch Setup -> Set up PHP on multiple architecture on Ubuntu GitHub Runners. +> Set up PHP on multiple architectures on Ubuntu GitHub Runners. - `PHP 5.6` to `PHP 8.5` are supported by `setup-php` on multiple architecture on `Ubuntu` and `Debian`. - For this, you can use `shivammathur/node` images as containers. These have compatible `Nodejs` and `PHP` installed for `setup-php`. @@ -683,7 +716,7 @@ jobs: > Set up PHP on a self-hosted runner. -- To set up a containerised self-hosted runner, refer to the following guides as per your base operating system. +- To set up a containerized self-hosted runner, refer to the following guides as per your base operating system. - [Linux](https://github.com/shivammathur/setup-php/wiki/Dockerized-self-hosted-runner-on-Linux) - [Windows](https://github.com/shivammathur/setup-php/wiki/Dockerized-self-hosted-runner-on-Windows) @@ -710,7 +743,7 @@ jobs: ``` > [!NOTE] -> - Do not set up multiple self-hosted runners on a single server instance as parallel workflow will conflict with each other. +> - Do not set up multiple self-hosted runners on a single server instance as parallel workflows will conflict with each other. > - Do not set up self-hosted runners on the side of your development environment or your production server. > - Avoid using the same labels for your `self-hosted` runners which are used by `GitHub-hosted` runners. @@ -753,7 +786,7 @@ act -P ubuntu-22.04=shivammathur/node:22.04 - By default, `opcache.jit=1235` and `opcache.jit_buffer_size=256M` (`opcache.jit_buffer_size=128M` on ARM-based environments) are set which can be changed using `ini-values` input. - For detailed information about JIT related directives refer to the [`official PHP documentation`](https://www.php.net/manual/en/opcache.configuration.php#ini.opcache.jit "opcache.jit documentation"). -For example to enable JIT in `tracing` mode with buffer size of `64 MB`. +For example, to enable JIT in `tracing` mode with buffer size of `64 MB`. ```yaml - name: Setup PHP with JIT in tracing mode @@ -833,7 +866,7 @@ If you use Private Packagist for your private composer dependencies, you can set ### Manual Composer Authentication -In addition to GitHub or Private Packagist, if you want to authenticate private repositories hosted elsewhere, you can set the `COMPOSER_AUTH_JSON` environment variable with the authentication methods and the credentials in json format. +In addition to GitHub or Private Packagist, if you want to authenticate private repositories hosted elsewhere, you can set the `COMPOSER_AUTH_JSON` environment variable with the authentication methods and the credentials in JSON format. Please refer to the authentication section in [`composer documentation`](https://getcomposer.org/doc/articles/authentication-for-private-packages.md "composer documentation") for more details. ```yaml @@ -879,7 +912,7 @@ Problem matchers are `json` configurations which identify errors and warnings in #### PHP -Setup problem matchers for your `PHP` output by adding this step after the `setup-php` step. +Set up problem matchers for your `PHP` output by adding this step after the `setup-php` step. ```yaml - name: Setup problem matchers for PHP @@ -888,7 +921,7 @@ Setup problem matchers for your `PHP` output by adding this step after the `setu #### PHPUnit -Setup problem matchers for your `PHPUnit` output by adding this step after the `setup-php` step. +Set up problem matchers for your `PHPUnit` output by adding this step after the `setup-php` step. ```yaml - name: Setup problem matchers for PHPUnit @@ -970,7 +1003,7 @@ Examples of using `setup-php` with various PHP frameworks and packages. | Symfony with `PostgreSQL` | `ubuntu` | [symfony-postgres.yml](./examples/symfony-postgres.yml "GitHub Action for Symfony with PostgreSQL") | | Symfony without services | `macOS`, `ubuntu` and `windows` | [symfony.yml](./examples/symfony.yml "GitHub Action for Symfony without services") | | WordPress plugin | `ubuntu` | [wordpress.yml](./examples/wordpress.yml "GitHub Action for WordPress plugins") | -| WordPress with Roots/Bedrock | `ubuntu` | [bedrock.yml](./examples/bedrock.yml "GitHub Action for WordPress development using @roots/bedrock") | +| WordPress with Roots/Bedrock | `ubuntu` | [bedrock.yml](./examples/bedrock.yml "GitHub Action for WordPress development using @roots/bedrock") | | WordPress with Roots/Sage | `ubuntu` | [sage.yml](./examples/sage.yml "GitHub Action for WordPress development using @roots/sage") | | Yii3 web application with `MySQL` | `ubuntu` | [yii3-mysql.yml](./examples/yii3-mysql.yml "GitHub Action for Yii3 web application with MySQL") | | Yii3 web application with `PostgreSQL` | `ubuntu` | [yii3-postgres.yml](./examples/yii3-postgres.yml "GitHub Action for Yii3 web application with PostgreSQL") | @@ -978,12 +1011,12 @@ Examples of using `setup-php` with various PHP frameworks and packages. ## :bookmark: Versioning -- Use the `v2` tag as `setup-php` version. It is a rolling tag and is synced with the latest minor and patch releases. With `v2` you automatically get the bug fixes, security patches, new features and support for latest PHP releases. +- Use the `v2` tag as `setup-php` version. It is a rolling tag and is synced with the latest minor and patch releases. With `v2` you automatically get the bug fixes, security patches, new features, and support for latest PHP releases. - Semantic release versions can also be used. It is recommended to [use dependabot](https://docs.github.com/en/github/administering-a-repository/keeping-your-actions-up-to-date-with-github-dependabot "Setup Dependabot with GitHub Actions") with semantic versioning to keep the actions in your workflows up to date. -- Commit SHA can also be used, but are not recommended unless you set up tooling to update them with each release of the action. -- A new major version of the action will only be tagged when there are breaking changes in the setup-php API i.e. inputs, outputs, and environment flags. -- For debugging any issues `verbose` tag can be used temporarily. It outputs all the logs and is also synced with the latest releases. -- It is highly discouraged to use the `main` branch as version, it might break your workflow after major releases as they have breaking changes. +- Commit SHA can also be used, but is not recommended unless you set up tooling to update them with each release of the action. +- A new major version of the action will only be tagged when there are breaking changes in the setup-php API i.e. - inputs, outputs, and environment flags. +- For debugging any issues, use the [`verbose` environment variable](#verbose-setup). +- It is highly discouraged to use the `main` branch as the version, it might break your workflow after major releases as they have breaking changes. - If you are using the `v1` tag or a `1.x.y` version, you should [switch to v2](https://github.com/shivammathur/setup-php/wiki/Switch-to-v2 "Guide for switching from setup-php v1 to v2") as `v1` is not supported anymore. ## :scroll: License @@ -1045,7 +1078,7 @@ Many users and organizations support setup-php via [GitHub Sponsors](https://git Sponsor shivammathur -- If you use setup-php, please consider starring the project and share it. +- If you use setup-php, please consider starring the project and sharing it. - If you blog, please share your experience of using `setup-php`. - Please [reach out](mailto:contact@setup-php.com) if you have any questions about sponsoring setup-php. @@ -1081,6 +1114,7 @@ Many users and organizations support setup-php via [GitHub Sponsors](https://git [`box`]: https://github.com/humbug/box [`castor`]: https://github.com/jolicode/castor [`churn`]: https://github.com/bmitch/churn-php +[`cloud-cli`]: https://cloud.laravel.com/docs/api/cli [`codeception`]: https://codeception.com/ [`composer`]: https://getcomposer.org/ [`composer-dependency-analyser`]: https://github.com/shipmonk-rnd/composer-dependency-analyser @@ -1088,12 +1122,14 @@ Many users and organizations support setup-php via [GitHub Sponsors](https://git [`composer-prefetcher`]: https://github.com/narrowspark/automatic-composer-prefetcher [`composer-require-checker`]: https://github.com/maglnet/ComposerRequireChecker [`composer-unused`]: https://github.com/composer-unused/composer-unused +[`cpx`]: https://github.com/laravel/cpx [`cs2pr`]: https://github.com/staabm/annotate-pull-request-from-checkstyle [`deployer`]: https://deployer.org/ [`ecs`]: https://github.com/easy-coding-standard/easy-coding-standard [`flex`]: https://github.com/symfony/flex [`grpc_php_plugin`]: https://grpc.io/ [`infection`]: https://infection.github.io/ +[`laravel-cloud`]: https://cloud.laravel.com/docs/api/cli [`mago`]: https://github.com/carthage-software/mago [`name-collision-detector`]: https://github.com/shipmonk/name-collision-detector [`parallel-lint`]: https://github.com/php-parallel-lint/PHP-Parallel-Lint diff --git a/__tests__/coverage.test.ts b/__tests__/coverage.test.ts index f8e460e8b..fc20ca771 100644 --- a/__tests__/coverage.test.ts +++ b/__tests__/coverage.test.ts @@ -21,7 +21,7 @@ describe('Config tests', () => { ${'xdebug'} | ${'7.4'} | ${'linux'} | ${'Xdebug $xdebug_version enabled as coverage driver'} ${'xdebug'} | ${'7.4'} | ${'darwin'} | ${'add_brew_extension xdebug'} ${'xdebug3'} | ${'7.1'} | ${'darwin'} | ${'xdebug3 is not supported on PHP 7.1'} - ${'xdebug2'} | ${'7.4'} | ${'darwin'} | ${'add_brew_extension xdebug2'} + ${'xdebug2'} | ${'7.4'} | ${'darwin'} | ${'add_brew_extension xdebug2 zend_extension 2.9.8'} ${'xdebug2'} | ${'8.0'} | ${'darwin'} | ${'xdebug2 is not supported on PHP 8.0'} ${'none'} | ${'7.4'} | ${'win32'} | ${'Disable-Extension xdebug false,Disable-Extension pcov false'} ${'none'} | ${'7.4'} | ${'linux'} | ${'disable_extension xdebug false,disable_extension pcov false'} diff --git a/__tests__/extensions.test.ts b/__tests__/extensions.test.ts index b0518d74c..18f0b30ee 100644 --- a/__tests__/extensions.test.ts +++ b/__tests__/extensions.test.ts @@ -107,6 +107,7 @@ describe('Extension tests', () => { ${'pecl_http'} | ${'7.3'} | ${'add_http'} ${'relay-1.2.3'} | ${'7.4'} | ${'add_relay relay-1.2.3'} ${'sqlite'} | ${'7.2'} | ${'add_extension sqlite3'} + ${'xdebug2'} | ${'7.4'} | ${'add_brew_extension xdebug2 zend_extension 2.9.8'} ${'zephir_parser-v1.2.3'} | ${'7.2'} | ${'add_zephir_parser zephir_parser-v1.2.3'} `( 'checking addExtensionOnDarwin for extension $extension on version $version', diff --git a/__tests__/tools.test.ts b/__tests__/tools.test.ts index 6805aa580..24d8349ed 100644 --- a/__tests__/tools.test.ts +++ b/__tests__/tools.test.ts @@ -222,17 +222,51 @@ describe('Tools tests', () => { }); it.each` - input_list | filtered_list - ${'a, b'} | ${'composer, a, b'} - ${'a, b, composer'} | ${'composer, a, b'} - ${'a, b, composer:1.2.3'} | ${'composer:1.2.3, a, b'} - ${'a, b, composer:v1.2.3'} | ${'composer:1.2.3, a, b'} - ${'a, b, composer:snapshot'} | ${'composer:snapshot, a, b'} - ${'a, b, composer:preview'} | ${'composer:preview, a, b'} - ${'a, b, composer:1'} | ${'composer:1, a, b'} - ${'a, b, composer:2'} | ${'composer:2, a, b'} - ${'a, b, composer:v1'} | ${'composer:1, a, b'} - ${'a, b, composer:v2'} | ${'composer:2, a, b'} + release | expected_release | checksum | error + ${'tool:1.2.3'} | ${'tool:1.2.3'} | ${undefined} | ${undefined} + ${'tool:1.2.3@sha256:' + 'a'.repeat(64)} | ${'tool:1.2.3'} | ${'sha256:' + 'a'.repeat(64)} | ${undefined} + ${'tool:1.2.3@sha256:' + 'A'.repeat(64)} | ${'tool:1.2.3'} | ${'sha256:' + 'a'.repeat(64)} | ${undefined} + ${'tool:1.2.3@SHA256:' + 'a'.repeat(64)} | ${'tool:1.2.3'} | ${'sha256:' + 'a'.repeat(64)} | ${undefined} + ${'tool:1.2.3@sha512:' + 'b'.repeat(128)} | ${'tool:1.2.3'} | ${'sha512:' + 'b'.repeat(128)} | ${undefined} + ${'tool:v1.2.3-beta.1+build.2@sha256:' + 'a'.repeat(64)} | ${'tool:v1.2.3-beta.1+build.2'} | ${'sha256:' + 'a'.repeat(64)} | ${undefined} + ${'composer:2.9.8@sha256:' + 'c'.repeat(64)} | ${'composer:2.9.8'} | ${'sha256:' + 'c'.repeat(64)} | ${undefined} + ${'tool:1.2.3@sha256:xyz'} | ${'tool:1.2.3'} | ${undefined} | ${'Invalid sha256 checksum, expected 64 hexadecimal characters'} + ${'tool:1.2.3@sha256:' + 'a'.repeat(63)} | ${'tool:1.2.3'} | ${undefined} | ${'Invalid sha256 checksum, expected 64 hexadecimal characters'} + ${'tool:1.2.3@sha512:' + 'b'.repeat(64)} | ${'tool:1.2.3'} | ${undefined} | ${'Invalid sha512 checksum, expected 128 hexadecimal characters'} + ${'tool:1.2.3@sha384:' + 'b'.repeat(96)} | ${'tool:1.2.3'} | ${undefined} | ${'Unsupported checksum algorithm sha384, expected sha256 or sha512'} + ${'tool:1.2.3@md5:' + 'b'.repeat(32)} | ${'tool:1.2.3'} | ${undefined} | ${'Unsupported checksum algorithm md5, expected sha256 or sha512'} + ${'tool:1.2.3@sha256' + 'a'.repeat(64)} | ${'tool:1.2.3'} | ${undefined} | ${'Invalid checksum syntax, expected @sha256: or @sha512:'} + ${'tool:1.0@dev'} | ${'tool:1.0@dev'} | ${undefined} | ${undefined} + `( + 'checking extractChecksum: $release', + ({release, expected_release, checksum, error}) => { + expect(tools.extractChecksum(release)).toStrictEqual({ + release: expected_release, + ...(checksum !== undefined && {checksum}), + ...(error !== undefined && {error}) + }); + } + ); + + it.each` + input_list | filtered_list + ${'a, b'} | ${'composer, a, b'} + ${'a, b, composer'} | ${'composer, a, b'} + ${'a, b, composer:1.2.3'} | ${'composer:1.2.3, a, b'} + ${'a, b, composer:v1.2.3'} | ${'composer:1.2.3, a, b'} + ${'a, b, composer:snapshot'} | ${'composer:snapshot, a, b'} + ${'a, b, composer:preview'} | ${'composer:preview, a, b'} + ${'a, b, composer:1'} | ${'composer:1, a, b'} + ${'a, b, composer:2'} | ${'composer:2, a, b'} + ${'a, b, composer:v1'} | ${'composer:1, a, b'} + ${'a, b, composer:v2'} | ${'composer:2, a, b'} + ${'a, b, composer:2.7.1@sha256:' + 'a'.repeat(64)} | ${'composer:2.7.1@sha256:' + 'a'.repeat(64) + ', a, b'} + ${'a, b, composer:v2.7.1@sha256:' + 'a'.repeat(64)} | ${'composer:2.7.1@sha256:' + 'a'.repeat(64) + ', a, b'} + ${'a, b, composer:2.7.1@SHA256:' + 'a'.repeat(64)} | ${'composer:2.7.1@SHA256:' + 'a'.repeat(64) + ', a, b'} + ${'a, b, composer:2.7.1@sha384:' + 'a'.repeat(96)} | ${'composer:2.7.1@sha384:' + 'a'.repeat(96) + ', a, b'} + ${'a, b, composer:2.7.1@md5:' + 'a'.repeat(32)} | ${'composer:2.7.1@md5:' + 'a'.repeat(32) + ', a, b'} + ${'a, b, composer:2.7.1@sha256' + 'a'.repeat(64)} | ${'composer:2.7.1@sha256' + 'a'.repeat(64) + ', a, b'} + ${'a, b, composer@sha256:' + 'a'.repeat(64)} | ${'composer@sha256:' + 'a'.repeat(64) + ', a, b'} `('checking filterList $input_list', async ({input_list, filtered_list}) => { expect(await tools.filterList(input_list.split(', '))).toStrictEqual( filtered_list.split(', ') @@ -304,6 +338,23 @@ describe('Tools tests', () => { expect(await tools.addArchive(data)).toContain(script); }); + it.each` + os | script + ${'linux'} | ${'add_tool https://example.com/tool.phar tool "-v" sha256:' + 'a'.repeat(64)} + ${'darwin'} | ${'add_tool https://example.com/tool.phar tool "-v" sha256:' + 'a'.repeat(64)} + ${'win32'} | ${'Add-Tool https://example.com/tool.phar tool "-v" sha256:' + 'a'.repeat(64)} + `('checking addArchive with checksum: $os', async ({os, script}) => { + const data = getData({ + tool: 'tool', + version: '1.2.3', + version_parameter: JSON.stringify('-v'), + os: os, + url: 'https://example.com/tool.phar' + }); + data.checksum = 'sha256:' + 'a'.repeat(64); + expect(await tools.addArchive(data)).toContain(script); + }); + it.each` os | release | scope | script ${'linux'} | ${'tool:1.2.3'} | ${'global'} | ${'add_composer_tool tool tool:1.2.3 user/ global'} @@ -494,7 +545,7 @@ describe('Tools tests', () => { ); } })); - const isolatedTools = await import('../src/tools'); + const isolatedTools = jest.requireActual('../src/tools'); affected = isolatedTools.skipGitHubAuthForComposerVersion('2.9.7'); fixed = isolatedTools.skipGitHubAuthForComposerVersion('2.9.8'); }); @@ -585,13 +636,15 @@ describe('Tools tests', () => { it.each([ [ - 'blackfire, blackfire-player, box, churn, cs2pr, flex, grpc_php_plugin, mago, name-collision-detector, parallel-lint, php-cs-fixer, php-scoper, phpDocumentor, phplint, phpstan, phpunit, pecl, phing, phinx, phinx:1.2.3, phive, phpunit-bridge, phpunit-polyfills, pint, php-config, phpize, protoc, symfony, vapor, wp, pie', + 'blackfire, blackfire-player, box, churn, cloud-cli, cpx, cs2pr, flex, grpc_php_plugin, mago, name-collision-detector, parallel-lint, php-cs-fixer, php-scoper, phpDocumentor, phplint, phpstan, phpunit, pecl, phing, phinx, phinx:1.2.3, phive, phpunit-bridge, phpunit-polyfills, pint, php-config, phpize, protoc, symfony, vapor, wp, pie', [ 'add_tool https://github.com/shivammathur/composer-cache/releases/latest/download/composer-7.4-stable.phar,https://artifacts.setup-php.com/composer/composer-7.4-stable.phar,https://dl.cloudsmith.io/public/shivammathur/composer-cache/raw/files/composer-7.4-stable.phar,https://getcomposer.org/composer-stable.phar composer', 'add_blackfire', 'add_tool https://get.blackfire.io/blackfire-player-v1.22.0.phar blackfire-player "-V"', 'add_tool https://github.com/box-project/box/releases/latest/download/box.phar box "--version"', 'add_tool https://github.com/bmitch/churn-php/releases/latest/download/churn.phar churn "-V"', + 'add_composer_tool cloud-cli cloud-cli laravel/ scoped', + 'add_tool https://github.com/laravel/cpx/releases/latest/download/cpx cpx "--version"', 'add_tool https://github.com/staabm/annotate-pull-request-from-checkstyle/releases/latest/download/cs2pr cs2pr "-V"', 'add_composer_tool flex flex symfony/ global', 'add_grpc_php_plugin latest', @@ -630,7 +683,7 @@ describe('Tools tests', () => { it.each([ [ - 'backward-compatibility-check, behat, blackfire, blackfire-player, churn, composer-dependency-analyser, composer-normalize, composer-require-checker, composer-unused, cs2pr:1.2.3, ecs, flex, grpc_php_plugin:1.2.3, infection, mago:0.26.1, name-collision-detector, phan, phan:1.2.3, phing:1.2.3, phinx, phive:1.2.3, php-config, phpcbf, phpcpd, phpcs, phpdoc, phpize, phpmd, phpspec, phpunit-bridge:5.6, phpunit-polyfills:1.0.1, protoc:v1.2.3, psalm, rector, symfony-cli, vapor-cli, wp-cli, pie', + 'backward-compatibility-check, behat, blackfire, blackfire-player, churn, composer-dependency-analyser, composer-normalize, composer-require-checker, composer-unused, cpx:2.0.0, cs2pr:1.2.3, ecs, flex, grpc_php_plugin:1.2.3, infection, laravel-cloud, mago:0.26.1, name-collision-detector, phan, phan:1.2.3, phing:1.2.3, phinx, phive:1.2.3, php-config, phpcbf, phpcpd, phpcs, phpdoc, phpize, phpmd, phpspec, phpunit-bridge:5.6, phpunit-polyfills:1.0.1, protoc:v1.2.3, psalm, rector, symfony-cli, vapor-cli, wp-cli, pie', [ 'add_tool https://github.com/shivammathur/composer-cache/releases/latest/download/composer-7.4-stable.phar,https://artifacts.setup-php.com/composer/composer-7.4-stable.phar,https://dl.cloudsmith.io/public/shivammathur/composer-cache/raw/files/composer-7.4-stable.phar,https://getcomposer.org/composer-stable.phar composer', 'add_composer_tool behat behat behat/ scoped', @@ -641,10 +694,12 @@ describe('Tools tests', () => { 'add_composer_tool composer-dependency-analyser composer-dependency-analyser shipmonk/ scoped', 'add_composer_tool composer-require-checker composer-require-checker maglnet/ scoped', 'add_tool https://github.com/composer-unused/composer-unused/releases/latest/download/composer-unused.phar composer-unused "-V"', + 'add_tool https://github.com/laravel/cpx/releases/download/v2.0.0/cpx cpx "--version"', 'add_tool https://github.com/staabm/annotate-pull-request-from-checkstyle/releases/download/1.2.3/cs2pr cs2pr "-V"', 'add_composer_tool flex flex symfony/ global', 'add_grpc_php_plugin 1.2.3', 'add_tool https://github.com/infection/infection/releases/latest/download/infection.phar infection "-V"', + 'add_composer_tool cloud-cli cloud-cli laravel/ scoped', 'add_mago 0.26.1', 'add_composer_tool name-collision-detector name-collision-detector shipmonk/ scoped', 'add_tool https://github.com/phan/phan/releases/latest/download/phan.phar phan "-v"', @@ -774,6 +829,102 @@ describe('Tools tests', () => { expect(await tools.addTools(tools_csv, '7.4', 'linux')).toContain(script); }); + it.each` + tools_csv | os | script + ${'phpunit:9.5.0@sha256:' + 'a'.repeat(64)} | ${'linux'} | ${'add_tool https://phar.phpunit.de/phpunit-9.5.0.phar,https://phar.phpunit.de/phpunit-9.phar phpunit "--version" sha256:' + 'a'.repeat(64)} + ${'phpunit:9.5.0@sha256:' + 'a'.repeat(64)} | ${'win32'} | ${'Add-Tool https://phar.phpunit.de/phpunit-9.5.0.phar,https://phar.phpunit.de/phpunit-9.phar phpunit "--version" sha256:' + 'a'.repeat(64)} + ${'composer:2.9.8@sha256:' + 'b'.repeat(64)} | ${'linux'} | ${'composer 2.9.8 sha256:' + 'b'.repeat(64)} + ${'cs2pr:1.2.3@sha256:' + 'd'.repeat(64)} | ${'linux'} | ${'add_tool https://github.com/staabm/annotate-pull-request-from-checkstyle/releases/download/1.2.3/cs2pr cs2pr "-V" sha256:' + 'd'.repeat(64)} + ${'phive:0.15.3@sha512:' + 'c'.repeat(128)} | ${'darwin'} | ${'add_tool https://github.com/phar-io/phive/releases/download/0.15.3/phive-0.15.3.phar phive "status" sha512:' + 'c'.repeat(128)} + ${'phinx:1.2.3@sha256:' + 'a'.repeat(64)} | ${'linux'} | ${'add_log "$cross" "phinx" "Checksum verification is not supported for phinx"'} + ${'pecl:1.2.3@sha256:' + 'a'.repeat(64)} | ${'linux'} | ${'add_log "$cross" "pecl" "Checksum verification is not supported for pecl"'} + ${'phpunit:9.5.0@sha256:invalid'} | ${'linux'} | ${'add_log "$cross" "phpunit" "Invalid sha256 checksum, expected 64 hexadecimal characters"'} + ${'composer:2.9.8@SHA256:' + 'b'.repeat(64)} | ${'linux'} | ${'composer 2.9.8 sha256:' + 'b'.repeat(64)} + ${'composer:2.9.8@sha384:' + 'b'.repeat(96)} | ${'linux'} | ${'add_log "$cross" "composer" "Unsupported checksum algorithm sha384, expected sha256 or sha512"'} + ${'composer:2.9.8@md5:' + 'b'.repeat(32)} | ${'linux'} | ${'add_log "$cross" "composer" "Unsupported checksum algorithm md5, expected sha256 or sha512"'} + ${'composer:2.9.8@sha256' + 'b'.repeat(64)} | ${'linux'} | ${'add_log "$cross" "composer" "Invalid checksum syntax, expected @sha256: or @sha512:"'} + `( + 'checking addTools with checksum: $tools_csv, $os', + async ({tools_csv, os, script}) => { + expect(await tools.addTools(tools_csv, '7.4', os)).toContain(script); + } + ); + + describe.each(['linux', 'darwin', 'win32'])( + 'Checksum version requirements on %s', + os => { + it.each(['2.9.8+build.1', '2.9.8-rc.1', '2.9.8-rc.1+build.2'])( + 'preserves the exact Composer version and checksum for %s', + async version => { + const checksum = 'sha256:' + 'a'.repeat(64); + const release = `composer:${version}@${checksum}`; + expect(await tools.filterList([release])).toEqual([release]); + const script = await tools.addTools(release, '8.4', os); + expect(script).toContain( + `https://github.com/composer/composer/releases/download/${version}/composer.phar` + ); + expect(script).toContain( + `https://getcomposer.org/download/${version}/composer.phar` + ); + expect(script).toContain(`composer ${version} ${checksum}`); + expect(script).not.toContain('latest'); + expect(script).not.toContain('composer-stable.phar'); + } + ); + + it.each([ + '', + ':latest', + ':stable', + ':preview', + ':snapshot', + ':2', + ':2.x', + ':2.9', + ':2.9.x', + ':^2.9.8' + ])( + 'rejects a checksum on a non-full version %s without an unpinned install', + async version => { + for (const tool of ['composer', 'phpunit']) { + const release = `${tool}${version}@sha256:${'a'.repeat(64)}`; + const data = await tools.getData(release, '8.4', os); + expect(data.error).toBe( + 'Checksum pinning requires a full version, for example tool:1.2.3' + ); + expect(data.url).toBe(''); + const script = await tools.addTools(release, '8.4', os); + expect(script).toContain(data.error); + const installations = script + .split('\n') + .filter(line => /^add[-_]tool /i.test(line)); + expect( + installations.some(line => new RegExp(` ${tool}( |$)`).test(line)) + ).toBe(false); + } + } + ); + } + ); + + it.each` + type | tool_function | supported + ${'phar'} | ${undefined} | ${true} + ${'custom-function'} | ${undefined} | ${true} + ${'custom-function'} | ${'composer'} | ${true} + ${'custom-function'} | ${'pecl'} | ${false} + ${'custom-function'} | ${'dev_tools'} | ${false} + ${'composer'} | ${undefined} | ${false} + ${'custom-package'} | ${undefined} | ${false} + `( + 'checking supportsChecksum: $type, $tool_function', + async ({type, tool_function, supported}) => { + const data = getData({tool: 'tool', type: type}); + data.function = tool_function; + expect(await tools.supportsChecksum(data)).toBe(supported); + } + ); + it.each` tools_csv | token | script ${'cs2pr:1.2'} | ${'invalid_token'} | ${'add_log "$cross" "cs2pr" "Invalid token"'} @@ -814,7 +965,7 @@ describe('Tools tests', () => { ); } })); - const isolatedTools = await import('../src/tools'); + const isolatedTools = jest.requireActual('../src/tools'); result = await isolatedTools.addTools('broken-tool', '7.4', 'linux'); }); diff --git a/__tests__/utils.test.ts b/__tests__/utils.test.ts index 7911a276c..0e2248651 100644 --- a/__tests__/utils.test.ts +++ b/__tests__/utils.test.ts @@ -1,4 +1,5 @@ import fs from 'fs'; +import os from 'os'; import * as path from 'path'; import * as utils from '../src/utils'; import * as fetchModule from '../src/fetch'; @@ -39,10 +40,17 @@ describe('Utils tests', () => { }); it('checking parseVersion', async () => { - const fetchSpy = jest - .spyOn(fetchModule, 'fetch') - .mockResolvedValue({data: '{ "latest": "8.1", "5.x": "5.6" }'}); - expect(await utils.parseVersion('latest')).toBe('8.1'); + const fetchSpy = jest.spyOn(fetchModule, 'fetch').mockResolvedValue({ + data: fs.readFileSync( + path.join(__dirname, '../src/configs/php-versions.json'), + 'utf8' + ) + }); + expect(await utils.parseVersion('latest')).toBe('8.5'); + expect(await utils.parseVersion('nightly')).toBe('8.6'); + expect(await utils.parseVersion('master')).toBe('8.7'); + expect(await utils.parseVersion('8.7')).toBe('8.7'); + expect(await utils.parseVersion('8.7.0')).toBe('8.7'); expect(await utils.parseVersion('7')).toBe('7.0'); expect(await utils.parseVersion('7.4')).toBe('7.4'); expect(await utils.parseVersion('5.x')).toBe('5.6'); @@ -54,12 +62,17 @@ describe('Utils tests', () => { await expect(utils.parseVersion('foo')).rejects.toThrow( 'Invalid PHP version:' ); - - fetchSpy.mockResolvedValue({data: '{ "latest": "8.1.0" }'}); - await expect(utils.parseVersion('latest')).rejects.toThrow( - 'Invalid PHP version in manifest:' + await expect(utils.parseVersion('8.4\n$(id)')).rejects.toThrow( + 'Invalid PHP version:' ); + for (const latest of ['8.1.0', 'pre', 8.4, ['8.4']]) { + fetchSpy.mockResolvedValue({data: JSON.stringify({latest})}); + await expect(utils.parseVersion('latest')).rejects.toThrow( + 'Invalid PHP version in manifest:' + ); + } + fetchSpy.mockReset(); fetchSpy.mockResolvedValueOnce({}).mockResolvedValueOnce({}); await expect(utils.parseVersion('latest')).rejects.toThrow( @@ -332,8 +345,30 @@ describe('Utils tests', () => { readFileSync.mockReturnValue('ruby 1.2.3\nphp 8.4.2\nnode 20.1.2'); expect(await utils.readPHPVersion()).toBe('8.4.2'); + readFileSync.mockReturnValue('ruby 1.2.3\nphp 8.4\nnode 20.1.2'); + expect(await utils.readPHPVersion()).toBe('8.4'); + + readFileSync.mockReturnValue('ruby 1.2.3\nphp latest\nnode 20.1.2'); + expect(await utils.readPHPVersion()).toBe('latest'); + + readFileSync.mockReturnValue(' \t8.4 \t\n'); + expect(await utils.readPHPVersion()).toBe('8.4'); + + readFileSync.mockReturnValue( + '#PHP\r\n\r\nruby 1.2.3\r\n \tphp \t latest \t# version\r\nnode 20.1.2' + ); + expect(await utils.readPHPVersion()).toBe('latest'); + + readFileSync.mockReturnValue('php\n8.4'); + await expect(utils.readPHPVersion()).rejects.toThrow('Invalid PHP version'); + + process.env['php-version-file'] = '.tool-versions'; + readFileSync.mockReturnValue("ruby 1.2.3\nphp 8.4';id;#\nnode 20.1.2"); + await expect(utils.readPHPVersion()).rejects.toThrow('.tool-versions'); + delete process.env['php-version-file']; + existsSync.mockReturnValue(true); - readFileSync.mockReturnValue('setup-php'); + readFileSync.mockReturnValue('php 8.4 8.5'); await expect(utils.readPHPVersion()).rejects.toThrow('Invalid PHP version'); existsSync.mockReturnValueOnce(false).mockReturnValueOnce(true); @@ -359,29 +394,44 @@ describe('Utils tests', () => { const existsSync = jest.spyOn(fs, 'existsSync').mockImplementation(); const readFileSync = jest.spyOn(fs, 'readFileSync').mockImplementation(); - process.env['php-version'] = 'bogus'; + process.env['php-version'] = '$0'; await expect(utils.readPHPVersion()).rejects.toThrow('php-version input'); delete process.env['php-version']; existsSync.mockReturnValue(true); - readFileSync.mockReturnValue('bogus'); + readFileSync.mockReturnValue(';id'); await expect(utils.readPHPVersion()).rejects.toThrow('.php-version'); existsSync.mockReturnValueOnce(false).mockReturnValueOnce(true); - readFileSync.mockReturnValue('{"platform-overrides":{"php":"bogus"}}'); + readFileSync.mockReturnValue('{"platform-overrides":{"php":"`w`"}}'); await expect(utils.readPHPVersion()).rejects.toThrow( 'composer.lock platform-overrides.php' ); + existsSync.mockReturnValueOnce(false).mockReturnValueOnce(true); + readFileSync.mockReturnValue('{"platform-overrides":{"php":8.4}}'); + await expect(utils.readPHPVersion()).rejects.toThrow( + 'composer.lock platform-overrides.php: number' + ); + existsSync .mockReturnValueOnce(false) .mockReturnValueOnce(false) .mockReturnValueOnce(true); - readFileSync.mockReturnValue('{"config":{"platform":{"php":"bogus"}}}'); + readFileSync.mockReturnValue('{"config":{"platform":{"php":"8.4$(id)"}}}'); await expect(utils.readPHPVersion()).rejects.toThrow( 'composer.json config.platform.php' ); + existsSync + .mockReturnValueOnce(false) + .mockReturnValueOnce(false) + .mockReturnValueOnce(true); + readFileSync.mockReturnValue('{"config":{"platform":{"php":["8.4"]}}}'); + await expect(utils.readPHPVersion()).rejects.toThrow( + 'composer.json config.platform.php: object' + ); + existsSync.mockClear(); readFileSync.mockClear(); }); @@ -395,3 +445,127 @@ describe('Utils tests', () => { expect(script).toEqual('\n$var = command\n'); }); }); + +describe.each(['linux', 'darwin', 'win32'])( + 'Verbose script preparation on %s', + platform => { + let root: string; + let run: string; + let helper: string; + const env = {...process.env}; + + beforeEach(() => { + jest.restoreAllMocks(); + root = fs.mkdtempSync(path.join(os.tmpdir(), 'setup-php-verbose-')); + const scripts = path.join(root, 'src', 'scripts'); + const extension = platform === 'win32' ? '.ps1' : '.sh'; + fs.mkdirSync(path.join(scripts, 'tools'), {recursive: true}); + helper = path.join(scripts, 'tools', 'helper' + extension); + run = path.join(scripts, 'run' + extension); + fs.writeFileSync(helper, 'echo helper-output\n'); + fs.writeFileSync( + run, + `. '${helper}' ${platform === 'win32' ? '>$null' : '>/dev/null'} 2>&1\n` + ); + delete process.env.verbose; + delete process.env.VERBOSE; + delete process.env.RUNNER_DEBUG; + }); + + afterEach(() => { + process.env = {...env}; + fs.rmSync(root, {recursive: true, force: true}); + }); + + it.each([undefined, '', 'false', 'true', 'v', 'vv', 'vvv', 'invalid'])( + 'prepares scripts for verbose=%s', + async verbose => { + if (verbose !== undefined) process.env.verbose = verbose; + const original = fs.readFileSync(run, 'utf8'); + const enabled = /^(true|v{1,3})$/.test(verbose || ''); + const tracing = /^v{2,3}$/.test(verbose || ''); + const prepared = await utils.addVerbose(run, platform); + const script = fs.readFileSync(prepared, 'utf8'); + expect(prepared !== run).toBe(enabled); + expect( + script.includes(platform === 'win32' ? '>$null' : '>/dev/null') + ).toBe(!enabled); + expect(script.includes('src-verbose')).toBe(enabled); + expect(script.startsWith('. ')).toBe(true); + expect(process.env.SETUP_PHP_TRACE).toBe( + tracing ? String(verbose!.length - 1) : '0' + ); + expect(fs.readFileSync(run, 'utf8')).toBe(original); + } + ); + + it.each(['', ' ', '\t'])( + 'handles pipe spacing %j and subsequent quiet runs', + async space => { + const target = platform === 'win32' ? '$null' : '/dev/null'; + const pipe = `>${space}${target} 2>&1`; + const probe = + platform === 'win32' + ? 'echo probe 2>$null' + : 'command -v sh >/dev/null'; + fs.writeFileSync(helper, `echo nested-output ${pipe}\n${probe}\n`); + process.env.VERBOSE = 'true'; + const prepared = await utils.addVerbose(run, platform); + expect( + fs.readFileSync( + path.join(path.dirname(prepared), 'tools', path.basename(helper)), + 'utf8' + ) + ).toBe( + `echo nested-output ${platform === 'win32' ? '2>&1 | Out-Host' : ''}\n${probe}\n` + ); + expect(fs.readFileSync(helper, 'utf8')).toContain(pipe); + process.env.verbose = 'false'; + expect(await utils.addVerbose(run, platform)).toBe(run); + expect(process.env.SETUP_PHP_TRACE).toBe('0'); + expect(fs.readFileSync(helper, 'utf8')).toContain(pipe); + } + ); + + it.each([undefined, 'false', 'true', 'v', 'vv', 'vvv'])( + 'enables output for runner debug with verbose=%s', + async verbose => { + process.env.RUNNER_DEBUG = '1'; + if (verbose !== undefined) process.env.verbose = verbose; + const prepared = await utils.addVerbose(run, platform); + expect(prepared).not.toBe(run); + expect(fs.readFileSync(prepared, 'utf8')).not.toMatch( + />\s*(?:\/dev\/null|\$null)\s+2>&1/ + ); + expect(process.env.SETUP_PHP_TRACE).toBe( + /^v{2,3}$/.test(verbose || '') ? String(verbose!.length - 1) : '0' + ); + } + ); + + (process.platform === 'win32' ? it.skip : it)( + 'uses fresh copies without writing through source symlinks', + async () => { + const outside = path.join(root, path.basename(helper)); + const original = 'echo original >/dev/null 2>&1\n'; + fs.writeFileSync(outside, original); + fs.unlinkSync(helper); + fs.symlinkSync(outside, helper); + process.env.verbose = 'true'; + const first = await utils.addVerbose(run, platform); + const second = await utils.addVerbose(run, platform); + expect(first).not.toBe(second); + expect(fs.readFileSync(outside, 'utf8')).toBe(original); + expect(fs.readFileSync(helper, 'utf8')).toBe(original); + expect( + fs.readFileSync( + path.join(path.dirname(first), 'tools', path.basename(helper)), + 'utf8' + ) + ).toBe( + `echo original ${platform === 'win32' ? '2>&1 | Out-Host' : ''}\n` + ); + } + ); + } +); diff --git a/dist/index.js b/dist/index.js index 8f918636d..b0563b496 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1 +1 @@ -(()=>{var e={472:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;var i=Object.getOwnPropertyDescriptor(t,r);if(!i||("get"in i?!t.__esModule:i.writable||i.configurable)){i={enumerable:true,get:function(){return t[r]}}}Object.defineProperty(e,n,i)}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var s=this&&this.__importStar||function(){var ownKeys=function(e){ownKeys=Object.getOwnPropertyNames||function(e){var t=[];for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r))t[t.length]=r;return t};return ownKeys(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r=ownKeys(e),s=0;so.escapeForShell(e,"linux"))).join("\n")+'" | sudo tee -a "${pecl_file:-${ini_file[@]}}" >/dev/null 2>&1'+r}async function addINIValuesWindows(e){const t=await o.CSVArray(e);let r="\n";await o.asyncForEach(t,(async function(e){r+=await o.addLog("$tick",e,"Added to php.ini","win32")+"\n"}));return'Add-Content "$php_dir\\php.ini" "'+t.map((e=>o.escapeForShell(e,"win32"))).join("\n")+'"'+r}async function addINIValues(e,t,r=false){let n="\n";switch(r){case true:n+=await o.stepLog("Add php.ini values",t)+await o.suppressOutput(t)+"\n";break;case false:default:n+=await o.stepLog("Add php.ini values",t)+"\n";break}switch(t){case"win32":return n+await addINIValuesWindows(e);case"darwin":case"linux":return n+await addINIValuesUnix(e);default:return await o.log("Platform "+t+" is not supported",t,"error")}}},469:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t.issueCommand=issueCommand;t.error=error;t.setFailed=setFailed;t.getInput=getInput;const n=r(857);function toCommandValue(e){if(e instanceof Error){return e.toString()}return e}function escapeData(e){return toCommandValue(e).replace(/%/g,"%25").replace(/\r/g,"%0D").replace(/\n/g,"%0A")}function escapeProperty(e){return e.replace(/%/g,"%25").replace(/\r/g,"%0D").replace(/\n/g,"%0A").replace(/:/g,"%3A").replace(/,/g,"%2C")}function issueCommand(e,t,r){let i=`::${e}`;if(t&&Object.keys(t).length>0){i+=" ";const e=Object.entries(t).filter((([,e])=>e)).map((([e,t])=>`${e}=${escapeProperty(t)}`)).join(",");i+=e}i+=`::${escapeData(r)}`;process.stdout.write(i+n.EOL)}function error(e){issueCommand("error",{},e)}function setFailed(e){process.exitCode=1;error(e)}function getInput(e,t=false){const r=process.env[`INPUT_${e.replace(/ /g,"_").toUpperCase()}`]||"";if(t&&!r){throw new Error(`Input required and not supplied: ${e}`)}return r.trim()}},524:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;var i=Object.getOwnPropertyDescriptor(t,r);if(!i||("get"in i?!t.__esModule:i.writable||i.configurable)){i={enumerable:true,get:function(){return t[r]}}}Object.defineProperty(e,n,i)}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var s=this&&this.__importStar||function(){var ownKeys=function(e){ownKeys=Object.getOwnPropertyNames||function(e){var t=[];for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r))t[t.length]=r;return t};return ownKeys(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r=ownKeys(e),s=0;s{"use strict";Object.defineProperty(t,"__esModule",{value:true});t.fetch=fetch;const r=new Set([301,302,303,307,308]);async function fetch(e,t,n=5){const i={"User-Agent":`Mozilla/5.0 (${process.platform} ${process.arch}) setup-php`};if(t){i["Authorization"]="Bearer "+t}try{const t=await globalThis.fetch(e,{headers:i,redirect:n>0?"follow":"manual"});if(t.ok){const e=await t.text();return{data:e}}else if(r.has(t.status)&&n<=0){return{error:`${t.status}: Redirect error`}}else{return{error:`${t.status}: ${t.statusText}`}}}catch(e){return{error:`Fetch error: ${e.message}`}}}},755:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;var i=Object.getOwnPropertyDescriptor(t,r);if(!i||("get"in i?!t.__esModule:i.writable||i.configurable)){i={enumerable:true,get:function(){return t[r]}}}Object.defineProperty(e,n,i)}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var s=this&&this.__importStar||function(){var ownKeys=function(e){ownKeys=Object.getOwnPropertyNames||function(e){var t=[];for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r))t[t.length]=r;return t};return ownKeys(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r=ownKeys(e),s=0;s{await run()})().catch((e=>{l.setFailed(e.message)}))},75:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;var i=Object.getOwnPropertyDescriptor(t,r);if(!i||("get"in i?!t.__esModule:i.writable||i.configurable)){i={enumerable:true,get:function(){return t[r]}}}Object.defineProperty(e,n,i)}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var s=this&&this.__importStar||function(){var ownKeys=function(e){ownKeys=Object.getOwnPropertyNames||function(e){var t=[];for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r))t[t.length]=r;return t};return ownKeys(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r=ownKeys(e),s=0;so.compareVersions(t.version,e.version)));const i=r.find((e=>{if(e?.require?.php){return e?.require?.php.split("|").some((e=>e&&o.satisfies(t+".0",e)))}return false}));return i?i.version:null}return null}},159:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;var i=Object.getOwnPropertyDescriptor(t,r);if(!i||("get"in i?!t.__esModule:i.writable||i.configurable)){i={enumerable:true,get:function(){return t[r]}}}Object.defineProperty(e,n,i)}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var s=this&&this.__importStar||function(){var ownKeys=function(e){ownKeys=Object.getOwnPropertyNames||function(e){var t=[];for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r))t[t.length]=r;return t};return ownKeys(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r=ownKeys(e),s=0;s{const[r,n]=t.trim().split(/\s+/);return u.compareVersions(e,r)>=0&&u.compareVersions(e,n)<0}))}function cleanComposerAuthJson(){try{const e=process.env["COMPOSER_AUTH_JSON"]||"";if(!e.includes("github-oauth"))return;const t=JSON.parse(e);delete t["github-oauth"];if(!Object.keys(t).length){delete process.env["COMPOSER_AUTH_JSON"]}else{process.env["COMPOSER_AUTH_JSON"]=JSON.stringify(t)}}catch{return}}async function getSemverVersion(e){const fixSemver=e=>{if(/^\d+\.\d+\.\d+(-|$)/.test(e))return e;const t=e.match(/^(\d+\.\d+\.\d+)([A-Za-z]+[0-9A-Za-z.]+)$/);return t?`${t[1]}-${t[2]}`:e};const t=e["version_prefix"]+e["version"];const r=`https://api.github.com/repos/${e["repository"]}/git/matching-refs/tags%2F${t}.`;const n=await f.readEnv("GITHUB_TOKEN")||await f.readEnv("COMPOSER_TOKEN");const i=await d.fetch(r,n);if(i.error||i.data==="[]"){e.error=i.error??`No version found with prefix ${t}.`;return e.version}else{const e=JSON.parse(i.data);const t=e.map((e=>(e.ref?.split("/").pop()??"").replace(/^v(?=\d)/,""))).filter((e=>e.length>0));const r=new Map;const n=t.map((e=>{const t=fixSemver(e);r.set(t,e);return t}));const s=n.toSorted(((e,t)=>{try{return u.compareVersions(t,e)}catch{return t.localeCompare(e,"en",{numeric:true,sensitivity:"base"})}}));return r.get(s[0])??s[0]}}async function getLatestVersion(e){if(!e.version&&e.fetch_latest==="false"){return"latest"}if(e.fetch_latest==="true"&&!e.repository){return"latest"}const t=await d.fetch(`${e.github}/${e.repository}/releases.atom`);if(t.data){const e=[...t.data.matchAll(/releases\/tag\/([a-zA-Z]*)?(\d+\.\d+\.\d+)"/g)].map((e=>e[2]));const r=e.toSorted(((e,t)=>e.localeCompare(t,undefined,{numeric:true})));return r.at(-1)||"latest"}return"latest"}async function getVersion(e,t){const r=/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/;const n=/^composer:(stable|preview|snapshot|[12])$/;const i=/[><=^~]+.*/;const s=/^\d+(\.\d+)?$/;t.version=e.replace(/v?(\d)/,"$1").replace(/\.x/,"");switch(true){case n.test(t.release):case r.test(t.version):case i.test(t.version)&&t.type==="composer":return t.version;case s.test(t.version)&&t.type==="composer":t.release=`${t.tool}:${t.version}.*`;return`${t.version}.*`;case!!t.repository&&s.test(t.version):return await getSemverVersion(t);default:return t.version.replace(/[^a-zA-Z0-9_.:@+,/-]/g,"")}}async function getRelease(e,t){e=e.includes("/")?e.split("/")[1]:e;return e.includes(":")?[t.tool,e.split(":")[1]].join(":"):t.tool}async function filterList(e){const t=/^composer($|:.*)/;const r=/^composer:?($|preview$|snapshot$|v?\d+(\.\d+)?$|v?\d+\.\d+\.\d+[\w-]*$)/;const n=e.filter((e=>r.test(e)));let i="composer";e=e.filter((e=>!t.test(e)));switch(true){case n[0]==undefined:break;default:i=n.at(-1).replace(/v(\d\S*)/,"$1");break}e.unshift(i);return e}async function getUrl(e){const t=e.version??"latest";if(t==="latest"||t===""){return[e.domain,e.repository,e.prefix,"latest",e.verb,e.tool+e.extension].filter(Boolean).join("/")}else{return[e.domain,e.repository,e.prefix,e.verb,e.version_prefix+e.version,e.tool+e.extension].filter(Boolean).join("/")}}async function getPharUrl(e){if(e.version==="latest"){return e.domain+"/"+e.tool+".phar"}else{return e.domain+"/"+e.tool+"-"+e.version_prefix+e.version+".phar"}}async function addArchive(e){return await f.getCommand(e.os,"tool")+await f.joins(e.url,e.tool,e.version_parameter)}async function addPackage(e){const t=await f.getCommand(e.os,"composer_tool");const r=e.repository.split("/");const n=[r[1],e.release,r[0]+"/",e.scope].map((t=>f.safeArg(t,e.os))).join(" ");return t+n}async function addBlackfirePlayer(e){switch(e.os){case"win32":return await f.addLog("$cross",e.tool,e.tool+" is not a windows tool","win32");default:if(e.version=="latest"){if(/5\.[5-6]|7\.0/.test(e.php_version)){e.version="1.9.3"}else if(/7\.[1-4]|8\.0/.test(e.php_version)){e.version="1.22.0"}}e.url=await getPharUrl(e);return addArchive(e)}}async function addCastor(e){e.tool="castor."+e.os.replace("win32","windows")+"-amd64";e.url=await getUrl(e);e.tool="castor";e.version_parameter=c.default.existsSync("castor.php")?e.version_parameter:"";return await addArchive(e)}async function addComposer(e){const t=e.version.replace("latest","stable");const r=e.github;const n=e.domain;const i="https://dl.cloudsmith.io";const s="https://artifacts.setup-php.com";const o=`composer-${e.php_version}-${t}.phar`;const a=`${r}/shivammathur/composer-cache/releases/latest/download/${o}`;const c=`${i}/public/shivammathur/composer-cache/raw/files/${o}`;const u=`${s}/composer/${o}`;const d=`${n}/download/latest-2.2.x/composer.phar`;const l=/^5\.[3-6]$|^7\.[0-1]$/.test(e.php_version);const p=`${n}/composer-${t}.phar`;const h=`${n}/download/${t}/composer.phar`;let g=`${a},${u},${c}`;let w=`${n}/composer.phar`;let v="";switch(true){case/^snapshot$/.test(t):w=l?d:w;break;case/^preview$|^2$/.test(t):w=l?d:p;break;case/^1$/.test(t):w=p;break;case/^\d+\.\d+\.\d+(?:-[\w-]+)?$/.test(e.version):if(skipGitHubAuthForComposerVersion(e.version)){cleanComposerAuthJson();v=" true"}g=`${r}/${e.repository}/releases/download/${e.version}/composer.phar`;w=h;break;default:w=l?d:p}const m=await f.readEnv("NO_TOOLS_CACHE")!=="true";e.url=m?`${g},${w}`:w;e.version_parameter=e.version+v;return await addArchive(e)}async function addDeployer(e){if(e.version==="latest"){e.url=e.domain+"/deployer.phar"}else{const t=await d.fetch("https://deployer.org/manifest.json");const r=JSON.parse(t.data);const n=Object.keys(r).find((t=>r[t].version===e.version));if(n){e.url=r[n].url}else{return await f.addLog("$cross","deployer","Version missing in deployer manifest",e.os)}}return await addArchive(e)}async function addDevTools(e){switch(e.os){case"linux":case"darwin":return"add_devtools "+e.tool;case"win32":return await f.addLog("$tick",e.tool,e.tool+" is not a windows tool","win32");default:return await f.log("Platform "+e.os+" is not supported",e.os,"error")}}async function addPECL(e){return await f.getCommand(e.os,"pecl")}async function addPhing(e){e.url=e.domain+"/get/phing-"+e.version+e.extension;if(e.version!="latest"){[e.prefix,e.verb]=["releases","download"];e.domain=e.github;e.extension="-"+e.version+e.extension;e.url+=","+await getUrl(e)}return await addArchive(e)}async function addPhive(e){switch(true){case/5\.[3-5]/.test(e.php_version):return await f.addLog("$cross","phive","Phive is not supported on PHP "+e.php_version,e.os);case/5\.6|7\.0/.test(e.php_version):e.version="0.12.1";break;case/7\.1/.test(e.php_version):e.version="0.13.5";break;case/7\.2/.test(e.php_version):e.version="0.14.5";break;case/7\.3|7\.4/.test(e.php_version):e.version="0.15.3";break;case/^latest$/.test(e.version):e.version=await getLatestVersion(e);break}e.extension="-"+e.version+e.extension;e.url=await getUrl(e);return await addArchive(e)}async function addPHPUnitTools(e){if(e.version==="latest"){e.version=await l.search(e.packagist,e.php_version)??"latest"}e.url=await getPharUrl(e);if(e.url.match(/-\d+/)){e.url+=","+e.url.replace(/-(\d+)\.\d+\.\d+/,"-$1")}return await addArchive(e)}async function addWPCLI(e){if(e.version==="latest"){e.uri="wp-cli/builds/blob/gh-pages/phar/wp-cli.phar?raw=true";e.url=[e.domain,e.uri].join("/")}else{e.extension="-"+e.version+e.extension;e.url=await getUrl(e)}return await addArchive(e)}async function getData(e,t,r){const n=a.default.join(__dirname,"../src/configs/tools.json");const i=c.default.readFileSync(n,"utf8");const s=JSON.parse(i);e=e.replace(/\s+/g,"");const o=e.split(":");const u=o[0];const d=o[1];let l;if(Object.hasOwn(s,u)){l={...s[u],tool:u}}else{const e=Object.keys(s).find((e=>s[e].alias==u));if(e){l={...s[e],tool:e}}else if(u.includes("/")){l={tool:u.split("/")[1],repository:u,type:"composer"}}else{l={tool:u}}}const f="https://github.com";const p=l.domain??f;const h={tool:l.tool,version:"",url:"",os:r,php_version:t,github:f,domain:p,extension:l.extension??".phar",repository:l.repository??"",prefix:p===f?"releases":"",verb:p===f?"download":"",fetch_latest:l.fetch_latest??"false",scope:l.scope??"global",version_parameter:l.version_parameter!=null?JSON.stringify(l.version_parameter):"",version_prefix:l.version_prefix??"",release:"",packagist:l.packagist??l.repository??"",type:l.type,function:l.function,alias:l.alias};h.release=await getRelease(e,h);h.version=d?await getVersion(d,h):await getLatestVersion(h);h.url=await getUrl(h);return h}t.functionRecord={castor:addCastor,composer:addComposer,deployer:addDeployer,dev_tools:addDevTools,phive:addPhive,blackfire_player:addBlackfirePlayer,pecl:addPECL,phing:addPhing,phpunit:addPHPUnitTools,phpcpd:addPHPUnitTools,wp_cli:addWPCLI};async function addTools(e,r,n){let i="\n";if(e==="none"){return""}else{i+=await f.stepLog("Setup Tools",n)}const s=await filterList(await f.CSVArray(e));await f.asyncForEach(s,(async function(e){const s=await getData(e,r,n);i+="\n";switch(true){case s.error!==undefined:i+=await f.addLog("$cross",s.tool,s.error,s.os);break;case"phar"===s.type:i+=await addArchive(s);break;case"composer"===s.type:i+=await addPackage(s);break;case"custom-package"===s.type:i+=await f.customPackage(s.tool.split("-")[0],"tools",s.version,s.os);break;case"custom-function"===s.type:if(!s.function){i+=await f.addLog("$cross",s.tool,s.tool+" has no function defined. Please report this issue.",s.os)}else{i+=await t.functionRecord[s.function](s)}break;case/^none$/.test(s.tool):break;default:i+=await f.addLog("$cross",s.tool,"Tool "+s.tool+" is not supported",s.os);break}}));return i}},277:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;var i=Object.getOwnPropertyDescriptor(t,r);if(!i||("get"in i?!t.__esModule:i.writable||i.configurable)){i={enumerable:true,get:function(){return t[r]}}}Object.defineProperty(e,n,i)}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var s=this&&this.__importStar||function(){var ownKeys=function(e){ownKeys=Object.getOwnPropertyNames||function(e){var t=[];for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r))t[t.length]=r;return t};return ownKeys(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r=ownKeys(e),s=0;sr.indexOf(e)===t));return n.map((e=>process.env[e]||"")).find(Boolean)||""}async function getInput(e,t){const r=u.getInput(e);const n=await readEnv(e);switch(true){case r!="":return r;case r==""&&n!="":return n;case r==""&&n==""&&t:throw new Error(`Input required and not supplied: ${e}`);default:return""}}async function getManifestURLS(){return["https://raw.githubusercontent.com/shivammathur/setup-php/develop/src/configs/php-versions.json","https://setup-php.com/php-versions.json"]}async function parseVersion(e){switch(true){case/^pre(-installed)?$/.test(e):return"pre";case/^(latest|lowest|highest|nightly|master|\d+\.x)$/.test(e):for(const t of await getManifestURLS()){const r=await d.fetch(t);if(r["data"]??false){const t=JSON.parse(r["data"])[e];if(t===undefined){throw new Error(`Invalid PHP version: ${e.slice(0,20)}`)}if(!/^\d+\.\d+$/.test(t)){throw new Error(`Invalid PHP version in manifest: ${t.slice(0,10)}`)}return t}}throw new Error(`Could not fetch the PHP version manifest.`);default:if(!/^\d+(\.\d+){0,2}$/.test(e)){throw new Error(`Invalid PHP version: ${e.slice(0,20)}`)}switch(true){case e.length>1:return e.slice(0,3);default:return e+".0"}}}async function parseIniFile(e){if(/^(production|development|none)$/.test(e)){return e}const t=e.match(/php\.ini-(production|development)$/);return t?t[1]:"production"}async function asyncForEach(e,t){for(const[r,n]of e.entries()){await t(n,r,e)}}async function color(e){switch(e){case"error":return"31";default:case"success":return"32";case"warning":return"33"}}async function log(e,t,r){switch(t){case"win32":return'printf "\\033['+await color(r)+";1m"+e+' \\033[0m"';case"linux":case"darwin":default:return'echo "\\033['+await color(r)+";1m"+e+'\\033[0m"'}}async function stepLog(e,t){switch(t){case"win32":return'Step-Log "'+escapeForShell(e,t)+'"';case"linux":case"darwin":return'step_log "'+escapeForShell(e,t)+'"';default:return await log("Platform "+t+" is not supported",t,"error")}}async function addLog(e,t,r,n){const i=escapeForShell(t,n);const s=escapeForShell(r,n);switch(n){case"win32":return`Add-Log "${e}" "${i}" "${s}"`;case"linux":case"darwin":return`add_log "${e}" "${i}" "${s}"`;default:return await log("Platform "+n+" is not supported",n,"error")}}function escapeForShell(e,t){if(t==="win32"){return e.replace(/[`$"]/g,"`$&")}return e.replace(/[\\`$"]/g,"\\$&")}function safeArg(e,t){if(!/^[a-zA-Z0-9_./:@+,~^-]*$/.test(e)){return'"'+escapeForShell(e,t)+'"'}return e}function sanitizeShellInput(e,t=false){const r=t?/[$`"';|&(){}[\]\\<>*?\n\r\t]/g:/[$`"';|&(){}[\]\\\n\r\t]/g;return e.replace(r,"")}async function extensionArray(e){switch(e){case"":case" ":return[];default:return[e.match(/(^|,\s?)none(\s?,|$)/)?"none":"",...e.split(",").map((function(e){e=e.trim().replace(/^\\\s*/,"");if(/.+-.+\/.+@.+/.test(e)){return e}return e.toLowerCase().replace(/^(:)?(php[-_]|none|zend )|(-[^-]*)-/,"$1$3")}))].filter(Boolean)}}async function CSVArray(e){switch(e){case"":case" ":return[];default:return e.split(/,(?=(?:(?:[^"']*["']){2})*[^"']*$)/).map((function(e){return e.trim().replace(/^["']|["']$|(?<==)["']/g,"").replace(/=(((?!E_).)*[?{}|&~![()^]+((?!E_).)+)/,"='$1'").replace(/=(.*?)(=.*)/,"='$1$2'").replace(/:\s*["'](.*?)/g,":$1")})).filter(Boolean)}}async function getExtensionPrefix(e){switch(true){default:return"extension";case/xdebug([2-3])?$|opcache|ioncube|eaccelerator/.test(e):return"zend_extension"}}async function suppressOutput(e){switch(e){case"win32":return" >$null 2>&1";case"linux":case"darwin":return" >/dev/null 2>&1";default:return await log("Platform "+e+" is not supported",e,"error")}}async function getUnsupportedLog(e,t,r){return"\n"+await addLog("$cross",e,[e,"is not supported on PHP",t].join(" "),r)+"\n"}async function getCommand(e,t){switch(e){case"linux":case"darwin":return"add_"+t+" ";case"win32":return"Add-"+t.split("_").map((e=>e.charAt(0).toUpperCase()+e.slice(1))).join("")+" ";default:return await log("Platform "+e+" is not supported",e,"error")}}async function joins(...e){return[...e].join(" ")}async function scriptExtension(e){switch(e){case"win32":return".ps1";case"linux":case"darwin":return".sh";default:return await log("Platform "+e+" is not supported",e,"error")}}async function scriptTool(e){switch(e){case"win32":return"pwsh ";case"linux":case"darwin":return"bash ";default:return await log("Platform "+e+" is not supported",e,"error")}}async function customPackage(e,t,r,n){const i=e.replace(/\d+|(pdo|pecl)[_-]|[_-]db2/,"");const s=await scriptExtension(n);const o=c.join(__dirname,"../src/scripts/"+t+"/"+i+s);const a=await getCommand(n,i);return"\n. "+o+"\n"+a+r}async function parseExtensionSource(e,t){const r=/(\w+)-(\w+:\/\/.{1,253}(?:[.:][^:/\s]{2,63})+\/)?([\w.-]+)\/([\w.-]+)@(.+)/;const n=r.exec(e);n[2]=n[2]?n[2].slice(0,-1):"https://github.com";return await joins("\nadd_extension_from_source",...n.splice(1,n.length),t)}const l=/^(latest|lowest|highest|nightly|master|pre|pre-installed|\d+\.x|\d+(\.\d+){0,2})$/;function validatePHPVersionInput(e,t){if(!l.test(e)){throw new Error(`Invalid PHP version in ${t}: ${e.slice(0,20)}`)}return e}async function readPHPVersion(){const e=await getInput("php-version",false);if(e){return validatePHPVersionInput(e,"php-version input")}const t=await getInput("php-version-file",false)||".php-version";if(a.default.existsSync(t)){const e=a.default.readFileSync(t,"utf8");const r=e.match(/^(?:php\s)?(\d+\.\d+\.\d+)$/m);return validatePHPVersionInput(r?r[1]:e.trim(),t)}else if(t!==".php-version"){throw new Error(`Could not find '${t}' file.`)}const r=await readEnv("COMPOSER_PROJECT_DIR");const n=c.join(r,"composer.lock");if(a.default.existsSync(n)){const e=JSON.parse(a.default.readFileSync(n,"utf8"));if(e["platform-overrides"]?.["php"]){return validatePHPVersionInput(e["platform-overrides"]["php"],"composer.lock platform-overrides.php")}}const i=c.join(r,"composer.json");if(a.default.existsSync(i)){const e=JSON.parse(a.default.readFileSync(i,"utf8"));if(e["config"]?.["platform"]?.["php"]){return validatePHPVersionInput(e["config"]["platform"]["php"],"composer.json config.platform.php")}}return"latest"}async function setVariable(e,t,r){switch(r){case"win32":return"\n$"+e+" = "+t+"\n";case"linux":case"darwin":default:return"\n"+e+'="$('+t+')"\n'}}},236:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;var i=Object.getOwnPropertyDescriptor(t,r);if(!i||("get"in i?!t.__esModule:i.writable||i.configurable)){i={enumerable:true,get:function(){return t[r]}}}Object.defineProperty(e,n,i)}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var s=this&&this.__importStar||function(){var ownKeys=function(e){ownKeys=Object.getOwnPropertyNames||function(e){var t=[];for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r))t[t.length]=r;return t};return ownKeys(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r=ownKeys(e),s=0;s{o+=u.write(e);if(l){l(e)}};const stdOutListener=e=>{s+=c.write(e);if(d){d(e)}};const f=Object.assign(Object.assign({},r===null||r===void 0?void 0:r.listeners),{stdout:stdOutListener,stderr:stdErrListener});const p=yield exec(e,t,Object.assign(Object.assign({},r),{listeners:f}));s+=c.end();o+=u.end();return{exitCode:p,stdout:s,stderr:o}}))}},665:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;var i=Object.getOwnPropertyDescriptor(t,r);if(!i||("get"in i?!t.__esModule:i.writable||i.configurable)){i={enumerable:true,get:function(){return t[r]}}}Object.defineProperty(e,n,i)}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var s=this&&this.__importStar||function(){var ownKeys=function(e){ownKeys=Object.getOwnPropertyNames||function(e){var t=[];for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r))t[t.length]=r;return t};return ownKeys(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r=ownKeys(e),s=0;s-1){const e=n.substring(0,i);r(e);n=n.substring(i+a.EOL.length);i=n.indexOf(a.EOL)}return n}catch(e){this._debug(`error processing line. Failed with error ${e}`);return""}}_getSpawnFileName(){if(h){if(this._isCmdFile()){return process.env["COMSPEC"]||"cmd.exe"}}return this.toolPath}_getSpawnArgs(e){if(h){if(this._isCmdFile()){let t=`/D /S /C "${this._windowsQuoteCmdArg(this.toolPath)}`;for(const r of this.args){t+=" ";t+=e.windowsVerbatimArguments?r:this._windowsQuoteCmdArg(r)}t+='"';return[t]}}return this.args}_endsWith(e,t){return e.endsWith(t)}_isCmdFile(){const e=this.toolPath.toUpperCase();return this._endsWith(e,".CMD")||this._endsWith(e,".BAT")}_windowsQuoteCmdArg(e){if(!this._isCmdFile()){return this._uvQuoteCmdArg(e)}if(!e){return'""'}const t=[" ","\t","&","(",")","[","]","{","}","^","=",";","!","'","+",",","`","~","|","<",">",'"'];let r=false;for(const n of e){if(t.some((e=>e===n))){r=true;break}}if(!r){return e}let n='"';let i=true;for(let t=e.length;t>0;t--){n+=e[t-1];if(i&&e[t-1]==="\\"){n+="\\"}else if(e[t-1]==='"'){i=true;n+='"'}else{i=false}}n+='"';return n.split("").reverse().join("")}_uvQuoteCmdArg(e){if(!e){return'""'}if(!e.includes(" ")&&!e.includes("\t")&&!e.includes('"')){return e}if(!e.includes('"')&&!e.includes("\\")){return`"${e}"`}let t='"';let r=true;for(let n=e.length;n>0;n--){t+=e[n-1];if(r&&e[n-1]==="\\"){t+="\\"}else if(e[n-1]==='"'){r=true;t+="\\"}else{r=false}}t+='"';return t.split("").reverse().join("")}_cloneExecOptions(e){e=e||{};const t={cwd:e.cwd||process.cwd(),env:e.env||process.env,silent:e.silent||false,windowsVerbatimArguments:e.windowsVerbatimArguments||false,failOnStdErr:e.failOnStdErr||false,ignoreReturnCode:e.ignoreReturnCode||false,delay:e.delay||1e4};t.outStream=e.outStream||process.stdout;t.errStream=e.errStream||process.stderr;return t}_getSpawnOptions(e,t){e=e||{};const r={};r.cwd=e.cwd;r.env=e.env;r["windowsVerbatimArguments"]=e.windowsVerbatimArguments||this._isCmdFile();if(e.windowsVerbatimArguments){r.argv0=`"${t}"`}return r}exec(){return o(this,void 0,void 0,(function*(){if(!f.isRooted(this.toolPath)&&(this.toolPath.includes("/")||h&&this.toolPath.includes("\\"))){this.toolPath=d.resolve(process.cwd(),this.options.cwd||process.cwd(),this.toolPath)}this.toolPath=yield l.which(this.toolPath,true);return new Promise(((e,t)=>o(this,void 0,void 0,(function*(){this._debug(`exec tool: ${this.toolPath}`);this._debug("arguments:");for(const e of this.args){this._debug(` ${e}`)}const r=this._cloneExecOptions(this.options);if(!r.silent&&r.outStream){r.outStream.write(this._getCommandString(r)+a.EOL)}const n=new ExecState(r,this.toolPath);n.on("debug",(e=>{this._debug(e)}));if(this.options.cwd&&!(yield f.exists(this.options.cwd))){return t(new Error(`The cwd: ${this.options.cwd} does not exist!`))}const i=this._getSpawnFileName();const s=u.spawn(i,this._getSpawnArgs(r),this._getSpawnOptions(this.options,i));let o="";if(s.stdout){s.stdout.on("data",(e=>{if(this.options.listeners&&this.options.listeners.stdout){this.options.listeners.stdout(e)}if(!r.silent&&r.outStream){r.outStream.write(e)}o=this._processLineBuffer(e,o,(e=>{if(this.options.listeners&&this.options.listeners.stdline){this.options.listeners.stdline(e)}}))}))}let c="";if(s.stderr){s.stderr.on("data",(e=>{n.processStderr=true;if(this.options.listeners&&this.options.listeners.stderr){this.options.listeners.stderr(e)}if(!r.silent&&r.errStream&&r.outStream){const t=r.failOnStdErr?r.errStream:r.outStream;t.write(e)}c=this._processLineBuffer(e,c,(e=>{if(this.options.listeners&&this.options.listeners.errline){this.options.listeners.errline(e)}}))}))}s.on("error",(e=>{n.processError=e.message;n.processExited=true;n.processClosed=true;n.CheckComplete()}));s.on("exit",(e=>{n.processExitCode=e;n.processExited=true;this._debug(`Exit code ${e} received from tool '${this.toolPath}'`);n.CheckComplete()}));s.on("close",(e=>{n.processExitCode=e;n.processExited=true;n.processClosed=true;this._debug(`STDIO streams have closed for tool '${this.toolPath}'`);n.CheckComplete()}));n.on("done",((r,n)=>{if(o.length>0){this.emit("stdline",o)}if(c.length>0){this.emit("errline",c)}s.removeAllListeners();if(r){t(r)}else{e(n)}}));if(this.options.input){if(!s.stdin){throw new Error("child process missing stdin")}s.stdin.end(this.options.input)}}))))}))}}t.ToolRunner=ToolRunner;function argStringToArray(e){const t=[];let r=false;let n=false;let i="";function append(e){if(n&&e!=='"'){i+="\\"}i+=e;n=false}for(let s=0;s0){t.push(i);i=""}continue}append(o)}if(i.length>0){t.push(i.trim())}return t}class ExecState extends c.EventEmitter{constructor(e,t){super();this.processClosed=false;this.processError="";this.processExitCode=0;this.processExited=false;this.processStderr=false;this.delay=1e4;this.done=false;this.timeout=null;if(!t){throw new Error("toolPath must not be empty")}this.options=e;this.toolPath=t;if(e.delay){this.delay=e.delay}}CheckComplete(){if(this.done){return}if(this.processClosed){this._setResult()}else if(this.processExited){this.timeout=(0,p.setTimeout)(ExecState.HandleTimeout,this.delay,this)}}_debug(e){this.emit("debug",e)}_setResult(){let e;if(this.processExited){if(this.processError){e=new Error(`There was an error when attempting to execute the process '${this.toolPath}'. This may indicate the process failed to start. Error: ${this.processError}`)}else if(this.processExitCode!==0&&!this.options.ignoreReturnCode){e=new Error(`The process '${this.toolPath}' failed with exit code ${this.processExitCode}`)}else if(this.processStderr&&this.options.failOnStdErr){e=new Error(`The process '${this.toolPath}' failed because one or more lines were written to the STDERR stream`)}}if(this.timeout){clearTimeout(this.timeout);this.timeout=null}this.done=true;this.emit("done",e,this.processExitCode)}static HandleTimeout(e){if(e.done){return}if(!e.processClosed&&e.processExited){const t=`The STDIO streams did not close within ${e.delay/1e3} seconds of the exit event from process '${e.toolPath}'. This may indicate a child process inherited the STDIO streams and has not yet exited.`;e._debug(t)}e._setResult()}}},207:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;var i=Object.getOwnPropertyDescriptor(t,r);if(!i||("get"in i?!t.__esModule:i.writable||i.configurable)){i={enumerable:true,get:function(){return t[r]}}}Object.defineProperty(e,n,i)}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var s=this&&this.__importStar||function(){var ownKeys=function(e){ownKeys=Object.getOwnPropertyNames||function(e){var t=[];for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r))t[t.length]=r;return t};return ownKeys(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r=ownKeys(e),s=0;se.toUpperCase()===t))){return e}}else{if(isUnixExecutable(n)){return e}}}const i=e;for(const s of r){e=i+s;n=undefined;try{n=yield(0,t.stat)(e)}catch(t){if(t.code!=="ENOENT"){console.log(`Unexpected error attempting to determine if executable file exists '${e}': ${t}`)}}if(n&&n.isFile()){if(t.IS_WINDOWS){try{const r=u.dirname(e);const n=u.basename(e).toUpperCase();for(const i of yield(0,t.readdir)(r)){if(n===i.toUpperCase()){e=u.join(r,i);break}}}catch(t){console.log(`Unexpected error attempting to determine the actual case of the file '${e}': ${t}`)}return e}else{if(isUnixExecutable(n)){return e}}}}return""}))}function normalizeSeparators(e){e=e||"";if(t.IS_WINDOWS){e=e.replace(/\//g,"\\");return e.replace(/\\\\+/g,"\\")}return e.replace(/\/\/+/g,"/")}function isUnixExecutable(e){return(e.mode&1)>0||(e.mode&8)>0&&process.getgid!==undefined&&e.gid===process.getgid()||(e.mode&64)>0&&process.getuid!==undefined&&e.uid===process.getuid()}function getCmdPath(){var e;return(e=process.env["COMSPEC"])!==null&&e!==void 0?e:`cmd.exe`}},994:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;var i=Object.getOwnPropertyDescriptor(t,r);if(!i||("get"in i?!t.__esModule:i.writable||i.configurable)){i={enumerable:true,get:function(){return t[r]}}}Object.defineProperty(e,n,i)}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var s=this&&this.__importStar||function(){var ownKeys=function(e){ownKeys=Object.getOwnPropertyNames||function(e){var t=[];for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r))t[t.length]=r;return t};return ownKeys(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r=ownKeys(e),s=0;s|]/.test(e)){throw new Error('File path must not contain `*`, `"`, `<`, `>` or `|` on Windows')}}try{yield u.rm(e,{force:true,maxRetries:3,recursive:true,retryDelay:300})}catch(e){throw new Error(`File was unable to be removed ${e}`)}}))}function mkdirP(e){return o(this,void 0,void 0,(function*(){(0,a.ok)(e,"a path argument must be provided");yield u.mkdir(e,{recursive:true})}))}function which(e,t){return o(this,void 0,void 0,(function*(){if(!e){throw new Error("parameter 'tool' is required")}if(t){const t=yield which(e,false);if(!t){if(u.IS_WINDOWS){throw new Error(`Unable to locate executable file: ${e}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also verify the file has a valid extension for an executable file.`)}else{throw new Error(`Unable to locate executable file: ${e}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also check the file mode to verify the file is executable.`)}}return t}const r=yield findInPath(e);if(r&&r.length>0){return r[0]}return""}))}function findInPath(e){return o(this,void 0,void 0,(function*(){if(!e){throw new Error("parameter 'tool' is required")}const t=[];if(u.IS_WINDOWS&&process.env["PATHEXT"]){for(const e of process.env["PATHEXT"].split(c.delimiter)){if(e){t.push(e)}}}if(u.isRooted(e)){const r=yield u.tryGetExecutablePath(e,t);if(r){return[r]}return[]}if(e.includes(c.sep)){return[]}const r=[];if(process.env.PATH){for(const e of process.env.PATH.split(c.delimiter)){if(e){r.push(e)}}}const n=[];for(const i of r){const r=yield u.tryGetExecutablePath(c.join(i,e),t);if(r){n.push(r)}}return n}))}function readCopyOptions(e){const t=e.force==null?true:e.force;const r=Boolean(e.recursive);const n=e.copySourceDirectory==null?true:Boolean(e.copySourceDirectory);return{force:t,recursive:r,copySourceDirectory:n}}function cpDirRecursive(e,t,r,n){return o(this,void 0,void 0,(function*(){if(r>=255)return;r++;yield mkdirP(t);const i=yield u.readdir(e);for(const s of i){const i=`${e}/${s}`;const o=`${t}/${s}`;const a=yield u.lstat(i);if(a.isDirectory()){yield cpDirRecursive(i,o,r,n)}else{yield copyFile(i,o,n)}}yield u.chmod(t,(yield u.stat(e)).mode)}))}function copyFile(e,t,r){return o(this,void 0,void 0,(function*(){if((yield u.lstat(e)).isSymbolicLink()){try{yield u.lstat(t);yield u.unlink(t)}catch(e){if(e.code==="EPERM"){yield u.chmod(t,"0666");yield u.unlink(t)}}const r=yield u.readlink(e);yield u.symlink(r,t,u.IS_WINDOWS?"junction":null)}else if(!(yield u.exists(t))||r){yield u.copyFile(e,t)}}))}},26:function(e,t){(function(e,r){true?r(t):0})(this,(function(e){"use strict";const t=/^[v^~<>=]*?(\d+)(?:\.([x*]|\d+)(?:\.([x*]|\d+)(?:\.([x*]|\d+))?(?:-([\da-z\-]+(?:\.[\da-z\-]+)*))?(?:\+[\da-z\-]+(?:\.[\da-z\-]+)*)?)?)?$/i;const validateAndParse=e=>{if(typeof e!=="string"){throw new TypeError("Invalid argument expected string")}const r=e.match(t);if(!r){throw new Error(`Invalid argument not valid semver ('${e}' received)`)}r.shift();return r};const isWildcard=e=>e==="*"||e==="x"||e==="X";const tryParse=e=>{const t=parseInt(e,10);return isNaN(t)?e:t};const forceType=(e,t)=>typeof e!==typeof t?[String(e),String(t)]:[e,t];const compareStrings=(e,t)=>{if(isWildcard(e)||isWildcard(t))return 0;const[r,n]=forceType(tryParse(e),tryParse(t));if(r>n)return 1;if(r{for(let r=0;r{const r=validateAndParse(e);const n=validateAndParse(t);const i=r.pop();const s=n.pop();const o=compareSegments(r,n);if(o!==0)return o;if(i&&s){return compareSegments(i.split("."),s.split("."))}else if(i||s){return i?-1:1}return 0};const compare=(e,t,n)=>{assertValidOperator(n);const i=compareVersions(e,t);return r[n].includes(i)};const r={">":[1],">=":[0,1],"=":[0],"<=":[-1,0],"<":[-1],"!=":[-1,1]};const n=Object.keys(r);const assertValidOperator=e=>{if(typeof e!=="string"){throw new TypeError(`Invalid operator type, expected string but got ${typeof e}`)}if(n.indexOf(e)===-1){throw new Error(`Invalid operator, expected one of ${n.join("|")}`)}};const satisfies=(e,t)=>{t=t.replace(/([><=]+)\s+/g,"$1");if(t.includes("||")){return t.split("||").some((t=>satisfies(e,t)))}else if(t.includes(" - ")){const[r,n]=t.split(" - ",2);return satisfies(e,`>=${r} <=${n}`)}else if(t.includes(" ")){return t.trim().replace(/\s{2,}/g," ").split(" ").every((t=>satisfies(e,t)))}const r=t.match(/^([<>=~^]+)/);const n=r?r[1]:"=";if(n!=="^"&&n!=="~")return compare(e,t,n);const[i,s,o,,a]=validateAndParse(e);const[c,u,d,,l]=validateAndParse(t);const f=[i,s,o];const p=[c,u!==null&&u!==void 0?u:"x",d!==null&&d!==void 0?d:"x"];if(l){if(!a)return false;if(compareSegments(f,p)!==0)return false;if(compareSegments(a.split("."),l.split("."))===-1)return false}const h=p.findIndex((e=>e!=="0"))+1;const g=n==="~"?2:h>1?h:1;if(compareSegments(f.slice(0,g),p.slice(0,g))!==0)return false;if(compareSegments(f.slice(g),p.slice(g))===-1)return false;return true};const validate=e=>typeof e==="string"&&/^[v\d]/.test(e)&&t.test(e);const validateStrict=e=>typeof e==="string"&&/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/.test(e);e.compare=compare;e.compareVersions=compareVersions;e.satisfies=satisfies;e.validate=validate;e.validateStrict=validateStrict}))},613:e=>{"use strict";e.exports=require("assert")},317:e=>{"use strict";e.exports=require("child_process")},434:e=>{"use strict";e.exports=require("events")},896:e=>{"use strict";e.exports=require("fs")},857:e=>{"use strict";e.exports=require("os")},928:e=>{"use strict";e.exports=require("path")},193:e=>{"use strict";e.exports=require("string_decoder")},557:e=>{"use strict";e.exports=require("timers")}};var t={};function __nccwpck_require__(r){var n=t[r];if(n!==undefined){return n.exports}var i=t[r]={exports:{}};var s=true;try{e[r].call(i.exports,i,i.exports,__nccwpck_require__);s=false}finally{if(s)delete t[r]}return i.exports}if(typeof __nccwpck_require__!=="undefined")__nccwpck_require__.ab=__dirname+"/";var r=__nccwpck_require__(755);module.exports=r})(); \ No newline at end of file +(()=>{var e={472:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;var s=Object.getOwnPropertyDescriptor(t,r);if(!s||("get"in s?!t.__esModule:s.writable||s.configurable)){s={enumerable:true,get:function(){return t[r]}}}Object.defineProperty(e,n,s)}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var i=this&&this.__importStar||function(){var ownKeys=function(e){ownKeys=Object.getOwnPropertyNames||function(e){var t=[];for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r))t[t.length]=r;return t};return ownKeys(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r=ownKeys(e),i=0;io.escapeForShell(e,"linux")).join("\n")+'" | sudo tee -a "${pecl_file:-${ini_file[@]}}" >/dev/null 2>&1'+r}async function addINIValuesWindows(e){const t=await o.CSVArray(e);let r="\n";await o.asyncForEach(t,async function(e){r+=await o.addLog("$tick",e,"Added to php.ini","win32")+"\n"});return'Add-Content "$php_dir\\php.ini" "'+t.map(e=>o.escapeForShell(e,"win32")).join("\n")+'"'+r}async function addINIValues(e,t,r=false){let n="\n";switch(r){case true:n+=await o.stepLog("Add php.ini values",t)+await o.suppressOutput(t)+"\n";break;case false:default:n+=await o.stepLog("Add php.ini values",t)+"\n";break}switch(t){case"win32":return n+await addINIValuesWindows(e);case"darwin":case"linux":return n+await addINIValuesUnix(e);default:return await o.log("Platform "+t+" is not supported",t,"error")}}},469:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t.issueCommand=issueCommand;t.error=error;t.setFailed=setFailed;t.getInput=getInput;const n=r(857);function toCommandValue(e){if(e instanceof Error){return e.toString()}return e}function escapeData(e){return toCommandValue(e).replace(/%/g,"%25").replace(/\r/g,"%0D").replace(/\n/g,"%0A")}function escapeProperty(e){return e.replace(/%/g,"%25").replace(/\r/g,"%0D").replace(/\n/g,"%0A").replace(/:/g,"%3A").replace(/,/g,"%2C")}function issueCommand(e,t,r){let s=`::${e}`;if(t&&Object.keys(t).length>0){s+=" ";const e=Object.entries(t).filter(([,e])=>e).map(([e,t])=>`${e}=${escapeProperty(t)}`).join(",");s+=e}s+=`::${escapeData(r)}`;process.stdout.write(s+n.EOL)}function error(e){issueCommand("error",{},e)}function setFailed(e){process.exitCode=1;error(e)}function getInput(e,t=false){const r=process.env[`INPUT_${e.replace(/ /g,"_").toUpperCase()}`]||"";if(t&&!r){throw new Error(`Input required and not supplied: ${e}`)}return r.trim()}},524:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;var s=Object.getOwnPropertyDescriptor(t,r);if(!s||("get"in s?!t.__esModule:s.writable||s.configurable)){s={enumerable:true,get:function(){return t[r]}}}Object.defineProperty(e,n,s)}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var i=this&&this.__importStar||function(){var ownKeys=function(e){ownKeys=Object.getOwnPropertyNames||function(e){var t=[];for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r))t[t.length]=r;return t};return ownKeys(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r=ownKeys(e),i=0;i{"use strict";Object.defineProperty(t,"__esModule",{value:true});t.fetch=fetch;const r=new Set([301,302,303,307,308]);async function fetch(e,t,n=5){const s={"User-Agent":`Mozilla/5.0 (${process.platform} ${process.arch}) setup-php`};if(t){s["Authorization"]="Bearer "+t}try{const t=await globalThis.fetch(e,{headers:s,redirect:n>0?"follow":"manual"});if(t.ok){const e=await t.text();return{data:e}}else if(r.has(t.status)&&n<=0){return{error:`${t.status}: Redirect error`}}else{return{error:`${t.status}: ${t.statusText}`}}}catch(e){return{error:`Fetch error: ${e.message}`}}}},755:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;var s=Object.getOwnPropertyDescriptor(t,r);if(!s||("get"in s?!t.__esModule:s.writable||s.configurable)){s={enumerable:true,get:function(){return t[r]}}}Object.defineProperty(e,n,s)}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var i=this&&this.__importStar||function(){var ownKeys=function(e){ownKeys=Object.getOwnPropertyNames||function(e){var t=[];for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r))t[t.length]=r;return t};return ownKeys(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r=ownKeys(e),i=0;i{await run()})().catch(e=>{l.setFailed(e.message)})},75:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;var s=Object.getOwnPropertyDescriptor(t,r);if(!s||("get"in s?!t.__esModule:s.writable||s.configurable)){s={enumerable:true,get:function(){return t[r]}}}Object.defineProperty(e,n,s)}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var i=this&&this.__importStar||function(){var ownKeys=function(e){ownKeys=Object.getOwnPropertyNames||function(e){var t=[];for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r))t[t.length]=r;return t};return ownKeys(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r=ownKeys(e),i=0;io.compareVersions(t.version,e.version));const s=r.find(e=>{if(e?.require?.php){return e?.require?.php.split("|").some(e=>e&&o.satisfies(t+".0",e))}return false});return s?s.version:null}return null}},159:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;var s=Object.getOwnPropertyDescriptor(t,r);if(!s||("get"in s?!t.__esModule:s.writable||s.configurable)){s={enumerable:true,get:function(){return t[r]}}}Object.defineProperty(e,n,s)}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var i=this&&this.__importStar||function(){var ownKeys=function(e){ownKeys=Object.getOwnPropertyNames||function(e){var t=[];for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r))t[t.length]=r;return t};return ownKeys(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r=ownKeys(e),i=0;i or @sha512:"}}return{release:e}}e=e.slice(0,-t[0].length);const r=t[1].toLowerCase();if(!["sha256","sha512"].includes(r)){return{release:e,error:`Unsupported checksum algorithm ${r}, expected sha256 or sha512`}}const n=t[2].toLowerCase();const s=r==="sha256"?64:128;if(!new RegExp(`^[a-f0-9]{${s}}$`).test(n)){return{release:e,error:`Invalid ${r} checksum, expected ${s} hexadecimal characters`}}if(!/^[^:]+:v?\d+\.\d+\.\d+(?:-[\w.-]+)?(?:\+[\w.-]+)?$/.test(e)){return{release:e,error:"Checksum pinning requires a full version, for example tool:1.2.3"}}return{release:e,checksum:`${r}:${n}`}}function skipGitHubAuthForComposerVersion(e){if(!/^\d+\.\d+\.\d+(?:-[\w-]+)?$/.test(e)){return false}return c.default.readFileSync(a.default.join(__dirname,"../src/configs/composer-gh-auth-no-op"),"utf8").trim().split(/\r?\n/).some(t=>{const[r,n]=t.trim().split(/\s+/);return u.compareVersions(e,r)>=0&&u.compareVersions(e,n)<0})}function cleanComposerAuthJson(){try{const e=process.env["COMPOSER_AUTH_JSON"]||"";if(!e.includes("github-oauth"))return;const t=JSON.parse(e);delete t["github-oauth"];if(!Object.keys(t).length){delete process.env["COMPOSER_AUTH_JSON"]}else{process.env["COMPOSER_AUTH_JSON"]=JSON.stringify(t)}}catch{return}}async function getSemverVersion(e){const fixSemver=e=>{if(/^\d+\.\d+\.\d+(-|$)/.test(e))return e;const t=e.match(/^(\d+\.\d+\.\d+)([A-Za-z]+[0-9A-Za-z.]+)$/);return t?`${t[1]}-${t[2]}`:e};const t=e["version_prefix"]+e["version"];const r=`https://api.github.com/repos/${e["repository"]}/git/matching-refs/tags%2F${t}.`;const n=await f.readEnv("GITHUB_TOKEN")||await f.readEnv("COMPOSER_TOKEN");const s=await d.fetch(r,n);if(s.error||s.data==="[]"){e.error=s.error??`No version found with prefix ${t}.`;return e.version}else{const e=JSON.parse(s.data);const t=e.map(e=>(e.ref?.split("/").pop()??"").replace(/^v(?=\d)/,"")).filter(e=>e.length>0);const r=new Map;const n=t.map(e=>{const t=fixSemver(e);r.set(t,e);return t});const i=n.toSorted((e,t)=>{try{return u.compareVersions(t,e)}catch{return t.localeCompare(e,"en",{numeric:true,sensitivity:"base"})}});return r.get(i[0])??i[0]}}async function getLatestVersion(e){if(!e.version&&e.fetch_latest==="false"){return"latest"}if(e.fetch_latest==="true"&&!e.repository){return"latest"}const t=await d.fetch(`${e.github}/${e.repository}/releases.atom`);if(t.data){const e=[...t.data.matchAll(/releases\/tag\/([a-zA-Z]*)?(\d+\.\d+\.\d+)"/g)].map(e=>e[2]);const r=e.toSorted((e,t)=>e.localeCompare(t,undefined,{numeric:true}));return r.at(-1)||"latest"}return"latest"}async function getVersion(e,t){const r=/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/;const n=/^composer:(stable|preview|snapshot|[12])$/;const s=/[><=^~]+.*/;const i=/^\d+(\.\d+)?$/;t.version=e.replace(/v?(\d)/,"$1").replace(/\.x/,"");switch(true){case n.test(t.release):case r.test(t.version):case s.test(t.version)&&t.type==="composer":return t.version;case i.test(t.version)&&t.type==="composer":t.release=`${t.tool}:${t.version}.*`;return`${t.version}.*`;case!!t.repository&&i.test(t.version):return await getSemverVersion(t);default:return t.version.replace(/[^a-zA-Z0-9_.:@+,/-]/g,"")}}async function getRelease(e,t){e=e.includes("/")?e.split("/")[1]:e;return e.includes(":")?[t.tool,e.split(":")[1]].join(":"):t.tool}async function filterList(e){const t=/^composer($|:.*)/;const r=/^composer:?($|preview$|snapshot$|v?\d+(\.\d+)?$|v?\d+\.\d+\.\d+[\w-]*$)/;const n=e.filter(e=>{const n=extractChecksum(e);return r.test(n.release)||t.test(n.release)&&(n.checksum!==undefined||n.error!==undefined)});let s="composer";e=e.filter(e=>!t.test(extractChecksum(e).release));switch(true){case n[0]==undefined:break;default:s=n.at(-1).replace(/v(\d\S*)/,"$1");break}e.unshift(s);return e}async function getUrl(e){const t=e.version??"latest";if(t==="latest"||t===""){return[e.domain,e.repository,e.prefix,"latest",e.verb,e.tool+e.extension].filter(Boolean).join("/")}else{return[e.domain,e.repository,e.prefix,e.verb,e.version_prefix+e.version,e.tool+e.extension].filter(Boolean).join("/")}}async function getPharUrl(e){if(e.version==="latest"){return e.domain+"/"+e.tool+".phar"}else{return e.domain+"/"+e.tool+"-"+e.version_prefix+e.version+".phar"}}async function addArchive(e){return await f.getCommand(e.os,"tool")+await f.joins(e.url,e.tool,e.version_parameter)+(e.checksum?" "+e.checksum:"")}async function addPackage(e){const t=await f.getCommand(e.os,"composer_tool");const r=e.repository.split("/");const n=[r[1],e.release,r[0]+"/",e.scope].map(t=>f.safeArg(t,e.os)).join(" ");return t+n}async function addBlackfirePlayer(e){switch(e.os){case"win32":return await f.addLog("$cross",e.tool,e.tool+" is not a windows tool","win32");default:if(e.version=="latest"){if(/5\.[5-6]|7\.0/.test(e.php_version)){e.version="1.9.3"}else if(/7\.[1-4]|8\.0/.test(e.php_version)){e.version="1.22.0"}}e.url=await getPharUrl(e);return addArchive(e)}}async function addCastor(e){e.tool="castor."+e.os.replace("win32","windows")+"-amd64";e.url=await getUrl(e);e.tool="castor";e.version_parameter=c.default.existsSync("castor.php")?e.version_parameter:"";return await addArchive(e)}async function addComposer(e){const t=e.version.replace("latest","stable");const r=e.github;const n=e.domain;const s="https://dl.cloudsmith.io";const i="https://artifacts.setup-php.com";const o=`composer-${e.php_version}-${t}.phar`;const a=`${r}/shivammathur/composer-cache/releases/latest/download/${o}`;const c=`${s}/public/shivammathur/composer-cache/raw/files/${o}`;const u=`${i}/composer/${o}`;const d=`${n}/download/latest-2.2.x/composer.phar`;const l=/^5\.[3-6]$|^7\.[0-1]$/.test(e.php_version);const p=`${n}/composer-${t}.phar`;const h=`${n}/download/${t}/composer.phar`;let g=`${a},${u},${c}`;let w=`${n}/composer.phar`;let v="";switch(true){case/^snapshot$/.test(t):w=l?d:w;break;case/^preview$|^2$/.test(t):w=l?d:p;break;case/^1$/.test(t):w=p;break;case/^\d+\.\d+\.\d+(?:-[\w.-]+)?(?:\+[\w.-]+)?$/.test(e.version):if(skipGitHubAuthForComposerVersion(e.version)){cleanComposerAuthJson();v=" true"}g=`${r}/${e.repository}/releases/download/${e.version}/composer.phar`;w=h;break;default:w=l?d:p}const m=await f.readEnv("NO_TOOLS_CACHE")!=="true";e.url=m?`${g},${w}`:w;e.version_parameter=e.version+v;return await addArchive(e)}async function addDeployer(e){if(e.version==="latest"){e.url=e.domain+"/deployer.phar"}else{const t=await d.fetch("https://deployer.org/manifest.json");const r=JSON.parse(t.data);const n=Object.keys(r).find(t=>r[t].version===e.version);if(n){e.url=r[n].url}else{return await f.addLog("$cross","deployer","Version missing in deployer manifest",e.os)}}return await addArchive(e)}async function addDevTools(e){switch(e.os){case"linux":case"darwin":return"add_devtools "+e.tool;case"win32":return await f.addLog("$tick",e.tool,e.tool+" is not a windows tool","win32");default:return await f.log("Platform "+e.os+" is not supported",e.os,"error")}}async function addPECL(e){return await f.getCommand(e.os,"pecl")}async function addPhing(e){e.url=e.domain+"/get/phing-"+e.version+e.extension;if(e.version!="latest"){[e.prefix,e.verb]=["releases","download"];e.domain=e.github;e.extension="-"+e.version+e.extension;e.url+=","+await getUrl(e)}return await addArchive(e)}async function addPhive(e){switch(true){case/5\.[3-5]/.test(e.php_version):return await f.addLog("$cross","phive","Phive is not supported on PHP "+e.php_version,e.os);case/5\.6|7\.0/.test(e.php_version):e.version="0.12.1";break;case/7\.1/.test(e.php_version):e.version="0.13.5";break;case/7\.2/.test(e.php_version):e.version="0.14.5";break;case/7\.3|7\.4/.test(e.php_version):e.version="0.15.3";break;case/^latest$/.test(e.version):e.version=await getLatestVersion(e);break}e.extension="-"+e.version+e.extension;e.url=await getUrl(e);return await addArchive(e)}async function addPHPUnitTools(e){if(e.version==="latest"){e.version=await l.search(e.packagist,e.php_version)??"latest"}e.url=await getPharUrl(e);if(e.url.match(/-\d+/)){e.url+=","+e.url.replace(/-(\d+)\.\d+\.\d+/,"-$1")}return await addArchive(e)}async function addWPCLI(e){if(e.version==="latest"){e.uri="wp-cli/builds/blob/gh-pages/phar/wp-cli.phar?raw=true";e.url=[e.domain,e.uri].join("/")}else{e.extension="-"+e.version+e.extension;e.url=await getUrl(e)}return await addArchive(e)}async function getData(e,t,r){const n=a.default.join(__dirname,"../src/configs/tools.json");const s=c.default.readFileSync(n,"utf8");const i=JSON.parse(s);e=e.replace(/\s+/g,"");const o=extractChecksum(e);e=o.release;const u=e.split(":");const d=u[0];const l=u[1];let f;if(Object.hasOwn(i,d)){f={...i[d],tool:d}}else{const e=Object.keys(i).find(e=>i[e].alias==d);if(e){f={...i[e],tool:e}}else if(d.includes("/")){f={tool:d.split("/")[1],repository:d,type:"composer"}}else{f={tool:d}}}const p="https://github.com";const h=f.domain??p;const g={tool:f.tool,version:"",url:"",os:r,php_version:t,github:p,domain:h,extension:f.extension??".phar",repository:f.repository??"",prefix:h===p?"releases":"",verb:h===p?"download":"",fetch_latest:f.fetch_latest??"false",scope:f.scope??"global",version_parameter:f.version_parameter!=null?JSON.stringify(f.version_parameter):"",version_prefix:f.version_prefix??"",release:"",packagist:f.packagist??f.repository??"",type:f.type,function:f.function,alias:f.alias};g.checksum=o.checksum;g.error=o.error;g.release=await getRelease(e,g);if(g.error!==undefined)return g;g.version=l?await getVersion(l,g):await getLatestVersion(g);g.url=await getUrl(g);return g}t.functionRecord={castor:addCastor,composer:addComposer,deployer:addDeployer,dev_tools:addDevTools,phive:addPhive,blackfire_player:addBlackfirePlayer,pecl:addPECL,phing:addPhing,phpunit:addPHPUnitTools,phpcpd:addPHPUnitTools,wp_cli:addWPCLI};async function supportsChecksum(e){switch(e.type){case"phar":return true;case"custom-function":return!["pecl","dev_tools"].includes(e.function??"");default:return false}}async function addTools(e,r,n){let s="\n";if(e==="none"){return""}else{s+=await f.stepLog("Setup Tools",n)}const i=await filterList(await f.CSVArray(e));await f.asyncForEach(i,async function(e){const i=await getData(e,r,n);s+="\n";switch(true){case i.error!==undefined:s+=await f.addLog("$cross",i.tool,i.error,i.os);break;case i.checksum!==undefined&&!await supportsChecksum(i):s+=await f.addLog("$cross",i.tool,"Checksum verification is not supported for "+i.tool,i.os);break;case"phar"===i.type:s+=await addArchive(i);break;case"composer"===i.type:s+=await addPackage(i);break;case"custom-package"===i.type:s+=await f.customPackage(i.tool.split("-")[0],"tools",i.version,i.os);break;case"custom-function"===i.type:if(!i.function){s+=await f.addLog("$cross",i.tool,i.tool+" has no function defined. Please report this issue.",i.os)}else{s+=await t.functionRecord[i.function](i)}break;case/^none$/.test(i.tool):break;default:s+=await f.addLog("$cross",i.tool,"Tool "+i.tool+" is not supported",i.os);break}});return s}},277:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;var s=Object.getOwnPropertyDescriptor(t,r);if(!s||("get"in s?!t.__esModule:s.writable||s.configurable)){s={enumerable:true,get:function(){return t[r]}}}Object.defineProperty(e,n,s)}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var i=this&&this.__importStar||function(){var ownKeys=function(e){ownKeys=Object.getOwnPropertyNames||function(e){var t=[];for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r))t[t.length]=r;return t};return ownKeys(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r=ownKeys(e),i=0;ir.indexOf(e)===t);return n.map(e=>process.env[e]||"").find(Boolean)||""}async function getInput(e,t){const r=u.getInput(e);const n=await readEnv(e);switch(true){case r!="":return r;case r==""&&n!="":return n;case r==""&&n==""&&t:throw new Error(`Input required and not supplied: ${e}`);default:return""}}async function getManifestURLS(){return["https://raw.githubusercontent.com/shivammathur/setup-php/develop/src/configs/php-versions.json","https://setup-php.com/php-versions.json"]}async function parseVersion(e){switch(true){case/^pre(-installed)?$/.test(e):return"pre";case/^(latest|lowest|highest|nightly|master|\d+\.x)$/.test(e):for(const t of await getManifestURLS()){const r=await d.fetch(t);if(r["data"]??false){const t=JSON.parse(r["data"])[e];if(t===undefined){throw new Error(`Invalid PHP version: ${e.slice(0,20)}`)}if(typeof t!=="string"||!/^\d+\.\d+$/.test(t)){throw new Error(`Invalid PHP version in manifest: ${typeof t==="string"?t.slice(0,10):typeof t}`)}return t}}throw new Error(`Could not fetch the PHP version manifest.`);default:if(!/^\d+(\.\d+){0,2}$/.test(e)){throw new Error(`Invalid PHP version: ${e.slice(0,20)}`)}switch(true){case e.length>1:return e.slice(0,3);default:return e+".0"}}}async function parseIniFile(e){if(/^(production|development|none)$/.test(e)){return e}const t=e.match(/php\.ini-(production|development)$/);return t?t[1]:"production"}async function asyncForEach(e,t){for(const[r,n]of e.entries()){await t(n,r,e)}}async function color(e){switch(e){case"error":return"31";default:case"success":return"32";case"warning":return"33"}}async function log(e,t,r){switch(t){case"win32":return'printf "\\033['+await color(r)+";1m"+e+' \\033[0m"';case"linux":case"darwin":default:return'echo "\\033['+await color(r)+";1m"+e+'\\033[0m"'}}async function stepLog(e,t){switch(t){case"win32":return'Step-Log "'+escapeForShell(e,t)+'"';case"linux":case"darwin":return'step_log "'+escapeForShell(e,t)+'"';default:return await log("Platform "+t+" is not supported",t,"error")}}async function addLog(e,t,r,n){const s=escapeForShell(t,n);const i=escapeForShell(r,n);switch(n){case"win32":return`Add-Log "${e}" "${s}" "${i}"`;case"linux":case"darwin":return`add_log "${e}" "${s}" "${i}"`;default:return await log("Platform "+n+" is not supported",n,"error")}}function escapeForShell(e,t){if(t==="win32"){return e.replace(/[`$"]/g,"`$&")}return e.replace(/[\\`$"]/g,"\\$&")}function safeArg(e,t){if(!/^[a-zA-Z0-9_./:@+,~^-]*$/.test(e)){return'"'+escapeForShell(e,t)+'"'}return e}function sanitizeShellInput(e,t=false){const r=t?/[$`"';|&(){}[\]\\<>*?\n\r\t]/g:/[$`"';|&(){}[\]\\\n\r\t]/g;return e.replace(r,"")}async function extensionArray(e){switch(e){case"":case" ":return[];default:return[e.match(/(^|,\s?)none(\s?,|$)/)?"none":"",...e.split(",").map(function(e){e=e.trim().replace(/^\\\s*/,"");if(/.+-.+\/.+@.+/.test(e)){return e}return e.toLowerCase().replace(/^(:)?(php[-_]|none|zend )|(-[^-]*)-/,"$1$3")})].filter(Boolean)}}async function CSVArray(e){switch(e){case"":case" ":return[];default:return e.split(/,(?=(?:(?:[^"']*["']){2})*[^"']*$)/).map(function(e){return e.trim().replace(/^["']|["']$|(?<==)["']/g,"").replace(/=(((?!E_).)*[?{}|&~![()^]+((?!E_).)+)/,"='$1'").replace(/=(.*?)(=.*)/,"='$1$2'").replace(/:\s*["'](.*?)/g,":$1")}).filter(Boolean)}}async function getExtensionPrefix(e){switch(true){default:return"extension";case/xdebug([2-3])?$|opcache|ioncube|eaccelerator/.test(e):return"zend_extension"}}async function suppressOutput(e){switch(e){case"win32":return" >$null 2>&1";case"linux":case"darwin":return" >/dev/null 2>&1";default:return await log("Platform "+e+" is not supported",e,"error")}}async function addVerbose(e,t){const r=await readEnv("verbose");process.env["SETUP_PHP_TRACE"]=/^v{2,3}$/.test(r)?String(r.length-1):"0";if(!/^(true|v{1,3})$/.test(r)&&process.env["RUNNER_DEBUG"]!=="1"){return e}const n=await scriptExtension(t);const s=c.dirname(c.dirname(e));const i=a.default.mkdtempSync(s+"-verbose-");await a.default.promises.cp(s,i,{recursive:true,dereference:true});const o=c.join(i,"scripts");const u=c.join(o,c.basename(e));const d=/>[ \t]*(?:\/dev\/null|\$null)[ \t]+2>&1/g;for(const e of a.default.readdirSync(o,{recursive:true,encoding:"utf8"})){if(!e.endsWith(n))continue;const r=c.join(o,e);const l=a.default.readFileSync(r,"utf8");let f=l.replace(d,t==="win32"?"2>&1 | Out-Host":"");if(r===u){f=f.replaceAll(s,i)}if(f!==l)a.default.writeFileSync(r,f)}return u}async function getUnsupportedLog(e,t,r){return"\n"+await addLog("$cross",e,[e,"is not supported on PHP",t].join(" "),r)+"\n"}async function getCommand(e,t){switch(e){case"linux":case"darwin":return"add_"+t+" ";case"win32":return"Add-"+t.split("_").map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join("")+" ";default:return await log("Platform "+e+" is not supported",e,"error")}}async function joins(...e){return[...e].join(" ")}async function scriptExtension(e){switch(e){case"win32":return".ps1";case"linux":case"darwin":return".sh";default:return await log("Platform "+e+" is not supported",e,"error")}}async function scriptTool(e){switch(e){case"win32":return"pwsh ";case"linux":case"darwin":return"bash ";default:return await log("Platform "+e+" is not supported",e,"error")}}async function customPackage(e,t,r,n){const s=e.replace(/\d+|(pdo|pecl)[_-]|[_-]db2/,"");const i=await scriptExtension(n);const o=c.join(__dirname,"../src/scripts/"+t+"/"+s+i);const a=await getCommand(n,s);return"\n. "+o+"\n"+a+r}async function parseExtensionSource(e,t){const r=/(\w+)-(\w+:\/\/.{1,253}(?:[.:][^:/\s]{2,63})+\/)?([\w.-]+)\/([\w.-]+)@(.+)/;const n=r.exec(e);n[2]=n[2]?n[2].slice(0,-1):"https://github.com";return await joins("\nadd_extension_from_source",...n.splice(1,n.length),t)}const l=/^(latest|lowest|highest|nightly|master|pre|pre-installed|\d+\.x|\d+(\.\d+){0,2})$/;function validatePHPVersionInput(e,t){if(typeof e!=="string"||!l.test(e)){throw new Error(`Invalid PHP version in ${t}: ${typeof e==="string"?e.slice(0,20):typeof e}`)}return e}async function readPHPVersion(){const e=await getInput("php-version",false);if(e){return validatePHPVersionInput(e,"php-version input")}const t=await getInput("php-version-file",false)||".php-version";if(a.default.existsSync(t)){const e=a.default.readFileSync(t,"utf8");const r=e.match(/^[ \t]*(?:php[ \t]+)?([^\s#]+)[ \t]*(?:#.*)?$/m);return validatePHPVersionInput(r?r[1]:e.trim(),t)}else if(t!==".php-version"){throw new Error(`Could not find '${t}' file.`)}const r=await readEnv("COMPOSER_PROJECT_DIR");const n=c.join(r,"composer.lock");if(a.default.existsSync(n)){const e=JSON.parse(a.default.readFileSync(n,"utf8"));if(e["platform-overrides"]?.["php"]){return validatePHPVersionInput(e["platform-overrides"]["php"],"composer.lock platform-overrides.php")}}const s=c.join(r,"composer.json");if(a.default.existsSync(s)){const e=JSON.parse(a.default.readFileSync(s,"utf8"));if(e["config"]?.["platform"]?.["php"]){return validatePHPVersionInput(e["config"]["platform"]["php"],"composer.json config.platform.php")}}return"latest"}async function setVariable(e,t,r){switch(r){case"win32":return"\n$"+e+" = "+t+"\n";case"linux":case"darwin":default:return"\n"+e+'="$('+t+')"\n'}}},236:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;var s=Object.getOwnPropertyDescriptor(t,r);if(!s||("get"in s?!t.__esModule:s.writable||s.configurable)){s={enumerable:true,get:function(){return t[r]}}}Object.defineProperty(e,n,s)}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var i=this&&this.__importStar||function(){var ownKeys=function(e){ownKeys=Object.getOwnPropertyNames||function(e){var t=[];for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r))t[t.length]=r;return t};return ownKeys(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r=ownKeys(e),i=0;i{o+=u.write(e);if(l){l(e)}};const stdOutListener=e=>{i+=c.write(e);if(d){d(e)}};const f=Object.assign(Object.assign({},r===null||r===void 0?void 0:r.listeners),{stdout:stdOutListener,stderr:stdErrListener});const p=yield exec(e,t,Object.assign(Object.assign({},r),{listeners:f}));i+=c.end();o+=u.end();return{exitCode:p,stdout:i,stderr:o}})}},665:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;var s=Object.getOwnPropertyDescriptor(t,r);if(!s||("get"in s?!t.__esModule:s.writable||s.configurable)){s={enumerable:true,get:function(){return t[r]}}}Object.defineProperty(e,n,s)}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var i=this&&this.__importStar||function(){var ownKeys=function(e){ownKeys=Object.getOwnPropertyNames||function(e){var t=[];for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r))t[t.length]=r;return t};return ownKeys(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r=ownKeys(e),i=0;i-1){const e=n.substring(0,s);r(e);n=n.substring(s+a.EOL.length);s=n.indexOf(a.EOL)}return n}catch(e){this._debug(`error processing line. Failed with error ${e}`);return""}}_getSpawnFileName(){if(h){if(this._isCmdFile()){return process.env["COMSPEC"]||"cmd.exe"}}return this.toolPath}_getSpawnArgs(e){if(h){if(this._isCmdFile()){let t=`/D /S /C "${this._windowsQuoteCmdArg(this.toolPath)}`;for(const r of this.args){t+=" ";t+=e.windowsVerbatimArguments?r:this._windowsQuoteCmdArg(r)}t+='"';return[t]}}return this.args}_endsWith(e,t){return e.endsWith(t)}_isCmdFile(){const e=this.toolPath.toUpperCase();return this._endsWith(e,".CMD")||this._endsWith(e,".BAT")}_windowsQuoteCmdArg(e){if(!this._isCmdFile()){return this._uvQuoteCmdArg(e)}if(!e){return'""'}const t=[" ","\t","&","(",")","[","]","{","}","^","=",";","!","'","+",",","`","~","|","<",">",'"'];let r=false;for(const n of e){if(t.some(e=>e===n)){r=true;break}}if(!r){return e}let n='"';let s=true;for(let t=e.length;t>0;t--){n+=e[t-1];if(s&&e[t-1]==="\\"){n+="\\"}else if(e[t-1]==='"'){s=true;n+='"'}else{s=false}}n+='"';return n.split("").reverse().join("")}_uvQuoteCmdArg(e){if(!e){return'""'}if(!e.includes(" ")&&!e.includes("\t")&&!e.includes('"')){return e}if(!e.includes('"')&&!e.includes("\\")){return`"${e}"`}let t='"';let r=true;for(let n=e.length;n>0;n--){t+=e[n-1];if(r&&e[n-1]==="\\"){t+="\\"}else if(e[n-1]==='"'){r=true;t+="\\"}else{r=false}}t+='"';return t.split("").reverse().join("")}_cloneExecOptions(e){e=e||{};const t={cwd:e.cwd||process.cwd(),env:e.env||process.env,silent:e.silent||false,windowsVerbatimArguments:e.windowsVerbatimArguments||false,failOnStdErr:e.failOnStdErr||false,ignoreReturnCode:e.ignoreReturnCode||false,delay:e.delay||1e4};t.outStream=e.outStream||process.stdout;t.errStream=e.errStream||process.stderr;return t}_getSpawnOptions(e,t){e=e||{};const r={};r.cwd=e.cwd;r.env=e.env;r["windowsVerbatimArguments"]=e.windowsVerbatimArguments||this._isCmdFile();if(e.windowsVerbatimArguments){r.argv0=`"${t}"`}return r}exec(){return o(this,void 0,void 0,function*(){if(!f.isRooted(this.toolPath)&&(this.toolPath.includes("/")||h&&this.toolPath.includes("\\"))){this.toolPath=d.resolve(process.cwd(),this.options.cwd||process.cwd(),this.toolPath)}this.toolPath=yield l.which(this.toolPath,true);return new Promise((e,t)=>o(this,void 0,void 0,function*(){this._debug(`exec tool: ${this.toolPath}`);this._debug("arguments:");for(const e of this.args){this._debug(` ${e}`)}const r=this._cloneExecOptions(this.options);if(!r.silent&&r.outStream){r.outStream.write(this._getCommandString(r)+a.EOL)}const n=new ExecState(r,this.toolPath);n.on("debug",e=>{this._debug(e)});if(this.options.cwd&&!(yield f.exists(this.options.cwd))){return t(new Error(`The cwd: ${this.options.cwd} does not exist!`))}const s=this._getSpawnFileName();const i=u.spawn(s,this._getSpawnArgs(r),this._getSpawnOptions(this.options,s));let o="";if(i.stdout){i.stdout.on("data",e=>{if(this.options.listeners&&this.options.listeners.stdout){this.options.listeners.stdout(e)}if(!r.silent&&r.outStream){r.outStream.write(e)}o=this._processLineBuffer(e,o,e=>{if(this.options.listeners&&this.options.listeners.stdline){this.options.listeners.stdline(e)}})})}let c="";if(i.stderr){i.stderr.on("data",e=>{n.processStderr=true;if(this.options.listeners&&this.options.listeners.stderr){this.options.listeners.stderr(e)}if(!r.silent&&r.errStream&&r.outStream){const t=r.failOnStdErr?r.errStream:r.outStream;t.write(e)}c=this._processLineBuffer(e,c,e=>{if(this.options.listeners&&this.options.listeners.errline){this.options.listeners.errline(e)}})})}i.on("error",e=>{n.processError=e.message;n.processExited=true;n.processClosed=true;n.CheckComplete()});i.on("exit",e=>{n.processExitCode=e;n.processExited=true;this._debug(`Exit code ${e} received from tool '${this.toolPath}'`);n.CheckComplete()});i.on("close",e=>{n.processExitCode=e;n.processExited=true;n.processClosed=true;this._debug(`STDIO streams have closed for tool '${this.toolPath}'`);n.CheckComplete()});n.on("done",(r,n)=>{if(o.length>0){this.emit("stdline",o)}if(c.length>0){this.emit("errline",c)}i.removeAllListeners();if(r){t(r)}else{e(n)}});if(this.options.input){if(!i.stdin){throw new Error("child process missing stdin")}i.stdin.end(this.options.input)}}))})}}t.ToolRunner=ToolRunner;function argStringToArray(e){const t=[];let r=false;let n=false;let s="";function append(e){if(n&&e!=='"'){s+="\\"}s+=e;n=false}for(let i=0;i0){t.push(s);s=""}continue}append(o)}if(s.length>0){t.push(s.trim())}return t}class ExecState extends c.EventEmitter{constructor(e,t){super();this.processClosed=false;this.processError="";this.processExitCode=0;this.processExited=false;this.processStderr=false;this.delay=1e4;this.done=false;this.timeout=null;if(!t){throw new Error("toolPath must not be empty")}this.options=e;this.toolPath=t;if(e.delay){this.delay=e.delay}}CheckComplete(){if(this.done){return}if(this.processClosed){this._setResult()}else if(this.processExited){this.timeout=(0,p.setTimeout)(ExecState.HandleTimeout,this.delay,this)}}_debug(e){this.emit("debug",e)}_setResult(){let e;if(this.processExited){if(this.processError){e=new Error(`There was an error when attempting to execute the process '${this.toolPath}'. This may indicate the process failed to start. Error: ${this.processError}`)}else if(this.processExitCode!==0&&!this.options.ignoreReturnCode){e=new Error(`The process '${this.toolPath}' failed with exit code ${this.processExitCode}`)}else if(this.processStderr&&this.options.failOnStdErr){e=new Error(`The process '${this.toolPath}' failed because one or more lines were written to the STDERR stream`)}}if(this.timeout){clearTimeout(this.timeout);this.timeout=null}this.done=true;this.emit("done",e,this.processExitCode)}static HandleTimeout(e){if(e.done){return}if(!e.processClosed&&e.processExited){const t=`The STDIO streams did not close within ${e.delay/1e3} seconds of the exit event from process '${e.toolPath}'. This may indicate a child process inherited the STDIO streams and has not yet exited.`;e._debug(t)}e._setResult()}}},207:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;var s=Object.getOwnPropertyDescriptor(t,r);if(!s||("get"in s?!t.__esModule:s.writable||s.configurable)){s={enumerable:true,get:function(){return t[r]}}}Object.defineProperty(e,n,s)}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var i=this&&this.__importStar||function(){var ownKeys=function(e){ownKeys=Object.getOwnPropertyNames||function(e){var t=[];for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r))t[t.length]=r;return t};return ownKeys(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r=ownKeys(e),i=0;ie.toUpperCase()===t)){return e}}else{if(isUnixExecutable(n)){return e}}}const s=e;for(const i of r){e=s+i;n=undefined;try{n=yield(0,t.stat)(e)}catch(t){if(t.code!=="ENOENT"){console.log(`Unexpected error attempting to determine if executable file exists '${e}': ${t}`)}}if(n&&n.isFile()){if(t.IS_WINDOWS){try{const r=u.dirname(e);const n=u.basename(e).toUpperCase();for(const s of yield(0,t.readdir)(r)){if(n===s.toUpperCase()){e=u.join(r,s);break}}}catch(t){console.log(`Unexpected error attempting to determine the actual case of the file '${e}': ${t}`)}return e}else{if(isUnixExecutable(n)){return e}}}}return""})}function normalizeSeparators(e){e=e||"";if(t.IS_WINDOWS){e=e.replace(/\//g,"\\");return e.replace(/\\\\+/g,"\\")}return e.replace(/\/\/+/g,"/")}function isUnixExecutable(e){return(e.mode&1)>0||(e.mode&8)>0&&process.getgid!==undefined&&e.gid===process.getgid()||(e.mode&64)>0&&process.getuid!==undefined&&e.uid===process.getuid()}function getCmdPath(){var e;return(e=process.env["COMSPEC"])!==null&&e!==void 0?e:`cmd.exe`}},994:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;var s=Object.getOwnPropertyDescriptor(t,r);if(!s||("get"in s?!t.__esModule:s.writable||s.configurable)){s={enumerable:true,get:function(){return t[r]}}}Object.defineProperty(e,n,s)}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var i=this&&this.__importStar||function(){var ownKeys=function(e){ownKeys=Object.getOwnPropertyNames||function(e){var t=[];for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r))t[t.length]=r;return t};return ownKeys(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r=ownKeys(e),i=0;i|]/.test(e)){throw new Error('File path must not contain `*`, `"`, `<`, `>` or `|` on Windows')}}try{yield u.rm(e,{force:true,maxRetries:3,recursive:true,retryDelay:300})}catch(e){throw new Error(`File was unable to be removed ${e}`)}})}function mkdirP(e){return o(this,void 0,void 0,function*(){(0,a.ok)(e,"a path argument must be provided");yield u.mkdir(e,{recursive:true})})}function which(e,t){return o(this,void 0,void 0,function*(){if(!e){throw new Error("parameter 'tool' is required")}if(t){const t=yield which(e,false);if(!t){if(u.IS_WINDOWS){throw new Error(`Unable to locate executable file: ${e}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also verify the file has a valid extension for an executable file.`)}else{throw new Error(`Unable to locate executable file: ${e}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also check the file mode to verify the file is executable.`)}}return t}const r=yield findInPath(e);if(r&&r.length>0){return r[0]}return""})}function findInPath(e){return o(this,void 0,void 0,function*(){if(!e){throw new Error("parameter 'tool' is required")}const t=[];if(u.IS_WINDOWS&&process.env["PATHEXT"]){for(const e of process.env["PATHEXT"].split(c.delimiter)){if(e){t.push(e)}}}if(u.isRooted(e)){const r=yield u.tryGetExecutablePath(e,t);if(r){return[r]}return[]}if(e.includes(c.sep)){return[]}const r=[];if(process.env.PATH){for(const e of process.env.PATH.split(c.delimiter)){if(e){r.push(e)}}}const n=[];for(const s of r){const r=yield u.tryGetExecutablePath(c.join(s,e),t);if(r){n.push(r)}}return n})}function readCopyOptions(e){const t=e.force==null?true:e.force;const r=Boolean(e.recursive);const n=e.copySourceDirectory==null?true:Boolean(e.copySourceDirectory);return{force:t,recursive:r,copySourceDirectory:n}}function cpDirRecursive(e,t,r,n){return o(this,void 0,void 0,function*(){if(r>=255)return;r++;yield mkdirP(t);const s=yield u.readdir(e);for(const i of s){const s=`${e}/${i}`;const o=`${t}/${i}`;const a=yield u.lstat(s);if(a.isDirectory()){yield cpDirRecursive(s,o,r,n)}else{yield copyFile(s,o,n)}}yield u.chmod(t,(yield u.stat(e)).mode)})}function copyFile(e,t,r){return o(this,void 0,void 0,function*(){if((yield u.lstat(e)).isSymbolicLink()){try{yield u.lstat(t);yield u.unlink(t)}catch(e){if(e.code==="EPERM"){yield u.chmod(t,"0666");yield u.unlink(t)}}const r=yield u.readlink(e);yield u.symlink(r,t,u.IS_WINDOWS?"junction":null)}else if(!(yield u.exists(t))||r){yield u.copyFile(e,t)}})}},26:function(e,t){(function(e,r){true?r(t):0})(this,function(e){"use strict";const t=/^[v^~<>=]*?(\d+)(?:\.([x*]|\d+)(?:\.([x*]|\d+)(?:\.([x*]|\d+))?(?:-([\da-z\-]+(?:\.[\da-z\-]+)*))?(?:\+[\da-z\-]+(?:\.[\da-z\-]+)*)?)?)?$/i;const validateAndParse=e=>{if(typeof e!=="string"){throw new TypeError("Invalid argument expected string")}const r=e.match(t);if(!r){throw new Error(`Invalid argument not valid semver ('${e}' received)`)}r.shift();return r};const isWildcard=e=>e==="*"||e==="x"||e==="X";const tryParse=e=>{const t=parseInt(e,10);return isNaN(t)?e:t};const forceType=(e,t)=>typeof e!==typeof t?[String(e),String(t)]:[e,t];const compareStrings=(e,t)=>{if(isWildcard(e)||isWildcard(t))return 0;const[r,n]=forceType(tryParse(e),tryParse(t));if(r>n)return 1;if(r{for(let r=0;r{const r=validateAndParse(e);const n=validateAndParse(t);const s=r.pop();const i=n.pop();const o=compareSegments(r,n);if(o!==0)return o;if(s&&i){return compareSegments(s.split("."),i.split("."))}else if(s||i){return s?-1:1}return 0};const compare=(e,t,n)=>{assertValidOperator(n);const s=compareVersions(e,t);return r[n].includes(s)};const r={">":[1],">=":[0,1],"=":[0],"<=":[-1,0],"<":[-1],"!=":[-1,1]};const n=Object.keys(r);const assertValidOperator=e=>{if(typeof e!=="string"){throw new TypeError(`Invalid operator type, expected string but got ${typeof e}`)}if(n.indexOf(e)===-1){throw new Error(`Invalid operator, expected one of ${n.join("|")}`)}};const satisfies=(e,t)=>{t=t.replace(/([><=]+)\s+/g,"$1");if(t.includes("||")){return t.split("||").some(t=>satisfies(e,t))}else if(t.includes(" - ")){const[r,n]=t.split(" - ",2);return satisfies(e,`>=${r} <=${n}`)}else if(t.includes(" ")){return t.trim().replace(/\s{2,}/g," ").split(" ").every(t=>satisfies(e,t))}const r=t.match(/^([<>=~^]+)/);const n=r?r[1]:"=";if(n!=="^"&&n!=="~")return compare(e,t,n);const[s,i,o,,a]=validateAndParse(e);const[c,u,d,,l]=validateAndParse(t);const f=[s,i,o];const p=[c,u!==null&&u!==void 0?u:"x",d!==null&&d!==void 0?d:"x"];if(l){if(!a)return false;if(compareSegments(f,p)!==0)return false;if(compareSegments(a.split("."),l.split("."))===-1)return false}const h=p.findIndex(e=>e!=="0")+1;const g=n==="~"?2:h>1?h:1;if(compareSegments(f.slice(0,g),p.slice(0,g))!==0)return false;if(compareSegments(f.slice(g),p.slice(g))===-1)return false;return true};const validate=e=>typeof e==="string"&&/^[v\d]/.test(e)&&t.test(e);const validateStrict=e=>typeof e==="string"&&/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/.test(e);e.compare=compare;e.compareVersions=compareVersions;e.satisfies=satisfies;e.validate=validate;e.validateStrict=validateStrict})},613:e=>{"use strict";e.exports=require("assert")},317:e=>{"use strict";e.exports=require("child_process")},434:e=>{"use strict";e.exports=require("events")},896:e=>{"use strict";e.exports=require("fs")},857:e=>{"use strict";e.exports=require("os")},928:e=>{"use strict";e.exports=require("path")},193:e=>{"use strict";e.exports=require("string_decoder")},557:e=>{"use strict";e.exports=require("timers")}};var t={};function __nccwpck_require__(r){var n=t[r];if(n!==undefined){return n.exports}var s=t[r]={exports:{}};var i=true;try{e[r].call(s.exports,s,s.exports,__nccwpck_require__);i=false}finally{if(i)delete t[r]}return s.exports}if(typeof __nccwpck_require__!=="undefined")__nccwpck_require__.ab=__dirname+"/";var r=__nccwpck_require__(755);module.exports=r})(); \ No newline at end of file diff --git a/jest.config.js b/jest.config.js index f670531b1..313638e66 100644 --- a/jest.config.js +++ b/jest.config.js @@ -5,7 +5,7 @@ module.exports = { testMatch: ['**/*.test.ts'], testRunner: 'jest-circus/runner', transform: { - '^.+\\.ts$': 'ts-jest' + '^.+\\.ts$': ['ts-jest', {tsconfig: 'tsconfig.test.json'}] }, verbose: true, collectCoverage: true diff --git a/package-lock.json b/package-lock.json index e59ab0e5a..2591ff76d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,39 +1,40 @@ { "name": "setup-php", - "version": "2.37.2", + "version": "2.40.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "setup-php", - "version": "2.37.2", + "version": "2.40.0", "license": "MIT", "dependencies": { "@actions/exec": "^2.0.0", "compare-versions": "^6.1.1" }, "devDependencies": { - "@eslint/compat": "^2.1.0", + "@eslint/compat": "^2.1.1", "@eslint/js": "^10.0.1", "@types/jest": "^30.0.0", - "@types/node": "^25.9.2", - "@typescript-eslint/eslint-plugin": "^8.60.1", - "@typescript-eslint/parser": "^8.60.1", - "@vercel/ncc": "^0.38.4", - "eslint": "^10.4.1", + "@types/node": "^26.6.4", + "@typescript-eslint/eslint-plugin": "^8.71.0", + "@typescript-eslint/parser": "^8.71.0", + "@typescript/native": "npm:typescript@^7.0.2", + "@vercel/ncc": "^0.45.0", + "eslint": "^10.12.0", "eslint-config-prettier": "^10.1.8", "eslint-import-resolver-typescript": "^4.4.5", - "eslint-plugin-import-x": "^4.16.2", - "eslint-plugin-jest": "^29.15.2", + "eslint-plugin-import-x": "^4.17.1", + "eslint-plugin-jest": "^29.16.6", "eslint-plugin-prettier": "^5.5.6", - "globals": "^17.6.0", - "jest": "^30.4.2", - "jest-circus": "^30.4.2", - "nock": "^14.0.15", - "prettier": "^3.8.3", - "simple-git-hooks": "^2.13.1", - "ts-jest": "^29.4.11", - "typescript": "^5.9.3" + "globals": "^17.13.0", + "jest": "^30.5.2", + "jest-circus": "^30.5.2", + "nock": "^14.0.17", + "prettier": "^3.9.9", + "simple-git-hooks": "^2.14.0", + "ts-jest": "^29.4.14", + "typescript": "npm:@typescript/typescript6@^6.0.2" } }, "node_modules/@actions/exec": { @@ -52,13 +53,13 @@ "license": "MIT" }, "node_modules/@babel/code-frame": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", - "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.28.5", + "@babel/helper-validator-identifier": "^7.29.7", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" }, @@ -67,9 +68,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.29.3", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.3.tgz", - "integrity": "sha512-LIVqM46zQWZhj17qA8wb4nW/ixr2y1Nw+r1etiAWgRM6U1IqP+LNhL1yg440jYZR72jCWcWbLWzIosH+uP1fqg==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", "dev": true, "license": "MIT", "engines": { @@ -77,21 +78,21 @@ } }, "node_modules/@babel/core": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", - "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", + "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.29.0", - "@babel/generator": "^7.29.0", - "@babel/helper-compilation-targets": "^7.28.6", - "@babel/helper-module-transforms": "^7.28.6", - "@babel/helpers": "^7.28.6", - "@babel/parser": "^7.29.0", - "@babel/template": "^7.28.6", - "@babel/traverse": "^7.29.0", - "@babel/types": "^7.29.0", + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helpers": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", @@ -118,14 +119,14 @@ } }, "node_modules/@babel/generator": { - "version": "7.29.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", - "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.8.tgz", + "integrity": "sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.29.0", - "@babel/types": "^7.29.0", + "@babel/parser": "^7.29.8", + "@babel/types": "^7.29.8", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" @@ -135,14 +136,14 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", - "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", "dev": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.28.6", - "@babel/helper-validator-option": "^7.27.1", + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" @@ -162,9 +163,9 @@ } }, "node_modules/@babel/helper-globals": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", - "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", "dev": true, "license": "MIT", "engines": { @@ -172,29 +173,29 @@ } }, "node_modules/@babel/helper-module-imports": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", - "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", "dev": true, "license": "MIT", "dependencies": { - "@babel/traverse": "^7.28.6", - "@babel/types": "^7.28.6" + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", - "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", + "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.28.6", - "@babel/helper-validator-identifier": "^7.28.5", - "@babel/traverse": "^7.28.6" + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -204,9 +205,9 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", - "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz", + "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==", "dev": true, "license": "MIT", "engines": { @@ -214,9 +215,9 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", "dev": true, "license": "MIT", "engines": { @@ -224,9 +225,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", - "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", "dev": true, "license": "MIT", "engines": { @@ -234,9 +235,9 @@ } }, "node_modules/@babel/helper-validator-option": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", - "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", "dev": true, "license": "MIT", "engines": { @@ -244,27 +245,27 @@ } }, "node_modules/@babel/helpers": { - "version": "7.29.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz", - "integrity": "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==", + "version": "7.29.10", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.10.tgz", + "integrity": "sha512-EMCx3AGZ3WfAl6ht7AyQoPm2Lh+BGYEMdc4Q6Hf7uSCDOZFuLq44qNwL+iaim8VlyYhRAo4X43+weadK8ZB4Yg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/template": "^7.28.6", - "@babel/types": "^7.29.0" + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.8" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.29.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.3.tgz", - "integrity": "sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==", + "version": "7.29.9", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.9.tgz", + "integrity": "sha512-CjXrNHTnvqBVqHgdBysY3vk2T8tpJHb5/RMeHJBTyVa9xgugCB0CJTx/3oO8RV2QRQP391RWpB7D6hLjm8V9uA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.29.0" + "@babel/types": "^7.29.8" }, "bin": { "parser": "bin/babel-parser.js" @@ -329,13 +330,13 @@ } }, "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.28.6.tgz", - "integrity": "sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.29.7.tgz", + "integrity": "sha512-zGYcYfq/WmZ4V+kBIXQon9dSSc8ircGZqw9ZaNhhGj9nZkeBu1jHLBDQqYYi5WA9uawvA2sIMbry2nCFhf5Djg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -371,13 +372,13 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.28.6.tgz", - "integrity": "sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.29.7.tgz", + "integrity": "sha512-TSu8+mHCoEaaCDEZ0I3+6mvTBYR4PCxQwf2z9/r5Tbztv6NaLR3B9thGTTxX2WGuGHJqRiAbKPeGTJ5XWXVg6A==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -497,13 +498,13 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.28.6.tgz", - "integrity": "sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.29.7.tgz", + "integrity": "sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -513,33 +514,33 @@ } }, "node_modules/@babel/template": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", - "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.28.6", - "@babel/parser": "^7.28.6", - "@babel/types": "^7.28.6" + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", - "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", + "version": "7.29.10", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.10.tgz", + "integrity": "sha512-B3lYAs2nkKskbgQ1nfy8Ma9ao9Q1rntTAQHrzzyDuj+TSO+X3le6PfWwqDvodsb+OumE10eMFfuMCTQSQ5iuIQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.29.0", - "@babel/generator": "^7.29.0", - "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.29.0", - "@babel/template": "^7.28.6", - "@babel/types": "^7.29.0", + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.8", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.9", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.8", "debug": "^4.3.1" }, "engines": { @@ -547,14 +548,14 @@ } }, "node_modules/@babel/types": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", - "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz", + "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.28.5" + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -567,6 +568,30 @@ "dev": true, "license": "MIT" }, + "node_modules/@cacheable/memory": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cacheable/memory/-/memory-2.2.0.tgz", + "integrity": "sha512-CTLKqLItRCEixEAewD3/j9DB3/o96gpTPD4eJ1v+DGOlxZRZncRQkGYqqnAGCscYd6RNeXfGeiuCphsPtqyIfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cacheable/utils": "^2.5.0", + "@keyv/bigmap": "^1.3.1", + "hookified": "^1.15.1", + "keyv": "^5.6.0" + } + }, + "node_modules/@cacheable/utils": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@cacheable/utils/-/utils-2.5.0.tgz", + "integrity": "sha512-buipgOVDkkPXNR5+xBpDw7Zk2n1EvU7qBJCNUcL7rhQ//kfpOXPAvQ511Os0vpLYJ1pZnvudNytkQt2hst3wqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hashery": "^1.5.1", + "keyv": "^5.6.0" + } + }, "node_modules/@emnapi/core": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", @@ -602,9 +627,9 @@ } }, "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", - "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.10.1.tgz", + "integrity": "sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==", "dev": true, "license": "MIT", "dependencies": { @@ -631,9 +656,9 @@ } }, "node_modules/@eslint/compat": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@eslint/compat/-/compat-2.1.0.tgz", - "integrity": "sha512-LgaSCymEpw7tF53xvDw9SNsraPb1IBHxpdABIOM0hW8UAlP8znrjYtuxfR58FSJ3L9BhwD+FaPRFQpZq84Nh6g==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@eslint/compat/-/compat-2.1.1.tgz", + "integrity": "sha512-rMcy8GSrwNzcISX/BlTDY/GLB4eCopEuy9woIls3To+15OLxykZrxxq+WUcylCPCQ6F4MujjBM1DX5V1aqI3Vw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -667,9 +692,9 @@ } }, "node_modules/@eslint/config-helpers": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.6.0.tgz", - "integrity": "sha512-ii6Bw9jJ2zi2cWA2Z+9/QZ/+3DX6kwaV5Q986D/CdP3Lap3w/pgQZ373FV7byY/i7L4IRH/G43I5dz1ClsCbpA==", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.7.0.tgz", + "integrity": "sha512-DObd/KKUsU+FaFv4PLxSRenpXfQWmPXXP3pPZ6/K1PCrMu2vQpMDMuQe/BqYeoLcz8ro0bVDF1RxOJgfVEdhUw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -724,9 +749,9 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.2.tgz", - "integrity": "sha512-+CNAzxglkrpNf/kKywqQfk74QjtceuOE7Qm+AF8miRvPF/wmmK5+OJOgVh3AVTT3RP2mH3+FOaxlE5v72owk0A==", + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.3.tgz", + "integrity": "sha512-IkO+/KEUvwbVpiURZg+P7zF74z5Jxe0UgJxVni+RtoHQ6IZieXaO02kmadomap/q+l6bc/jdPGGqTjhuZnuz1Q==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -887,17 +912,17 @@ } }, "node_modules/@jest/console": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-30.4.1.tgz", - "integrity": "sha512-v3bhyxUh9Hgmo5p6hAOXe14/R3ZxZDOsvHleh4B07z3m/x4/ngPUXEm9XwK4sF4u+f+P2ORb0Ge+MgpaqRMVDA==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-30.5.2.tgz", + "integrity": "sha512-e8sQC4pCMHPBrPX7Hk8TJr+DM5dkUnImSTNag8SEWFAFAF6xIz4AJvCKapnrdHnZxep4bxw4PhG+ZbimYBMyKw==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "30.4.1", + "@jest/types": "30.5.1", "@types/node": "*", "chalk": "^4.1.2", - "jest-message-util": "30.4.1", - "jest-util": "30.4.1", + "jest-message-util": "30.5.1", + "jest-util": "30.5.1", "slash": "^3.0.0" }, "engines": { @@ -905,18 +930,18 @@ } }, "node_modules/@jest/core": { - "version": "30.4.2", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-30.4.2.tgz", - "integrity": "sha512-TZJA6cPJUFxoWhxaLo8t0VX/MZX2wPWr0uIDvLSHIvN4gu9h02vSzqI2kBADG1ExqQlC+cY09xKMSreivvrChQ==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-30.5.2.tgz", + "integrity": "sha512-/jqvFWoJF7LV1a6AUpYMbMm+2yIYsHJfR474H0SCzr9k8tnO/jl9wRg6zSG6lxgf6EozNlCG4amFzWsbZSvvZA==", "dev": true, "license": "MIT", "dependencies": { - "@jest/console": "30.4.1", - "@jest/pattern": "30.4.0", - "@jest/reporters": "30.4.1", - "@jest/test-result": "30.4.1", - "@jest/transform": "30.4.1", - "@jest/types": "30.4.1", + "@jest/console": "30.5.2", + "@jest/pattern": "30.5.0", + "@jest/reporters": "30.5.2", + "@jest/test-result": "30.5.2", + "@jest/transform": "30.5.2", + "@jest/types": "30.5.1", "@types/node": "*", "ansi-escapes": "^4.3.2", "chalk": "^4.1.2", @@ -924,20 +949,20 @@ "exit-x": "^0.2.2", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.11", - "jest-changed-files": "30.4.1", - "jest-config": "30.4.2", - "jest-haste-map": "30.4.1", - "jest-message-util": "30.4.1", - "jest-regex-util": "30.4.0", - "jest-resolve": "30.4.1", - "jest-resolve-dependencies": "30.4.2", - "jest-runner": "30.4.2", - "jest-runtime": "30.4.2", - "jest-snapshot": "30.4.1", - "jest-util": "30.4.1", - "jest-validate": "30.4.1", - "jest-watcher": "30.4.1", - "pretty-format": "30.4.1", + "jest-changed-files": "30.5.1", + "jest-config": "30.5.2", + "jest-haste-map": "30.5.1", + "jest-message-util": "30.5.1", + "jest-regex-util": "30.5.0", + "jest-resolve": "30.5.1", + "jest-resolve-dependencies": "30.5.2", + "jest-runner": "30.5.2", + "jest-runtime": "30.5.2", + "jest-snapshot": "30.5.2", + "jest-util": "30.5.1", + "jest-validate": "30.5.1", + "jest-watcher": "30.5.2", + "pretty-format": "30.5.1", "slash": "^3.0.0" }, "engines": { @@ -953,9 +978,9 @@ } }, "node_modules/@jest/diff-sequences": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.4.0.tgz", - "integrity": "sha512-zOpzlfUs45l6u7jm39qr87JCHUDsaeCtvL+kQe/Vn9jSnRB4/5IPXISm0h9I1vZW/o00Kn4UTJ2MOlhnUGwv3g==", + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.5.0.tgz", + "integrity": "sha512-OsqBjHXCn8cadasoAZBP6nWYvMsRhpMzGXTpxJ5aO04NlbdhIz+FVe3q49l0AwVhsz/cEmIpBes6gAFl1/dWQg==", "dev": true, "license": "MIT", "engines": { @@ -963,70 +988,70 @@ } }, "node_modules/@jest/environment": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.4.1.tgz", - "integrity": "sha512-AK9yNRqgKxiabqMoe4oW+3/TSSeV8vkdC7BGaxZdU0AFXfOpofTLqdru2GXKZghP3sdgwE9XXpnVwfZ8JnFV4w==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.5.2.tgz", + "integrity": "sha512-nwFPOUMbmsjNNRCpnJpB9HbSZu4C07wDDds++5j+j1MezzPLxMPDdbdUVjr2o4RULDOValnDd70taPFI1EtxAg==", "dev": true, "license": "MIT", "dependencies": { - "@jest/fake-timers": "30.4.1", - "@jest/types": "30.4.1", + "@jest/fake-timers": "30.5.2", + "@jest/types": "30.5.1", "@types/node": "*", - "jest-mock": "30.4.1" + "jest-mock": "30.5.2" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/expect": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.4.1.tgz", - "integrity": "sha512-ginrj6TMgh2GshLUGCjO94Ptx9HhdZA/I6A9iUfyeLKFtdAjnKzHDgzgP9HYQgbxM1lbXScQ2eUBz2lGeVDPWA==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.5.2.tgz", + "integrity": "sha512-2E+1Pg6jJxbRjLNLpciC71iri/3qsKJL222/aXJEFwC0VdUSvfS+JZQQLEVjUYYc8t8pQu2MGE3cF2+bNTYRsg==", "dev": true, "license": "MIT", "dependencies": { - "expect": "30.4.1", - "jest-snapshot": "30.4.1" + "expect": "30.5.2", + "jest-snapshot": "30.5.2" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/expect-utils": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.4.1.tgz", - "integrity": "sha512-ZBn5CglH8fBsQsvs4VWNzD4aWfUYks+IdOOQU3MEK71ol/BcVm+P+rtb1KpiFBpSWSCE27uOahyyf1vfqOVbcQ==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.5.2.tgz", + "integrity": "sha512-d/HOLSrJUlBIl6n3LzOa7cjW3xdePm5H5gQw2lixZ/0h157l9sw3mLblzFqnPcTbhDzhRQdBOX3A3KcG73nm5Q==", "dev": true, "license": "MIT", "dependencies": { - "@jest/get-type": "30.1.0" + "@jest/get-type": "30.5.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/fake-timers": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.4.1.tgz", - "integrity": "sha512-iW5umdmfPeWzehrVhugFQZqCchSCud5S1l2YT0O9ZhjRR0ExclANDZkiSBwzqtnlOn0J1JXvO+HZ6rkuyOVOgQ==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.5.2.tgz", + "integrity": "sha512-GKk0h0tKT5SpDPxDhPg3r9mm5s8/YCBzVNMOGdRiQXwUiMsjU10mVPlMaQstH6/cu50vOb8N9oQUMETHuwwxKw==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "30.4.1", + "@jest/types": "30.5.1", "@sinonjs/fake-timers": "^15.4.0", "@types/node": "*", - "jest-message-util": "30.4.1", - "jest-mock": "30.4.1", - "jest-util": "30.4.1" + "jest-message-util": "30.5.1", + "jest-mock": "30.5.2", + "jest-util": "30.5.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/get-type": { - "version": "30.1.0", - "resolved": "https://registry.npmjs.org/@jest/get-type/-/get-type-30.1.0.tgz", - "integrity": "sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==", + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/@jest/get-type/-/get-type-30.5.0.tgz", + "integrity": "sha512-9/2VUPitAjmBzbvDvqrxmvB7BzWsBW0WmkkojX1ODuxX1NLGxx9gfaZpHB0z8DtJ9uhGNmZG/VXBhf8uO0OV8Q==", "dev": true, "license": "MIT", "engines": { @@ -1034,62 +1059,78 @@ } }, "node_modules/@jest/globals": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.4.1.tgz", - "integrity": "sha512-ZbuY4cmXC8DkxYjfvT2DbcHWL2T6vmsMhXCDcmTB2T0y0gaezBI77ufq5ZAIdcRkYZ7NEQEDg1xFeKbxUJ5v5Q==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.5.2.tgz", + "integrity": "sha512-62zfS+dL+M5aTNHXCNLyqD+j4oqxTIzDYrZbpqMP8Yn+gvlAGyzC6BSPNb1ZmFOakV1RtFYX/O3FCQXSWmQdgg==", "dev": true, "license": "MIT", "dependencies": { - "@jest/environment": "30.4.1", - "@jest/expect": "30.4.1", - "@jest/types": "30.4.1", - "jest-mock": "30.4.1" + "@jest/environment": "30.5.2", + "@jest/expect": "30.5.2", + "@jest/types": "30.5.1", + "jest-mock": "30.5.2" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/pattern": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.4.0.tgz", - "integrity": "sha512-RAWn3+f9u8BsHijKJ71uHcFp6vmyEt6VvoWXkl6hKF3qVIuWNmudVjg12DlBPGup/frIl5UcUlH5HfEuvHpEXg==", + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.5.0.tgz", + "integrity": "sha512-HdNQYSdRTEBNrginaqzQtTjG0HRMfrra/z6Ok7uL3S87vSlarIVohEsJsSj5edu3MiHoHjAkvPROz5ZjoKai+w==", "dev": true, "license": "MIT", "dependencies": { "@types/node": "*", - "jest-regex-util": "30.4.0" + "jest-regex-util": "30.5.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, + "node_modules/@jest/react-is-18": { + "name": "react-is", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jest/react-is-19": { + "name": "react-is", + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.3.0.tgz", + "integrity": "sha512-UpMYezM4v5/18F28aC66AEsjXIgE02kyEMH6yLdgLXu/UTfa1Ntwck/nNLrbqJsEXW7gPb0coNO9FQse9WTovA==", + "dev": true, + "license": "MIT" + }, "node_modules/@jest/reporters": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-30.4.1.tgz", - "integrity": "sha512-/SnkPCzEQpUaBH81kjdEdDdo2WZl5hxw+BmLDGWjRkm8o7XlhjwsU36cqwe5PGBE5WYpBvDzRSdXx9rbGuJtNA==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-30.5.2.tgz", + "integrity": "sha512-ev6E9iG73twQcfAfoTnviuYkr3yOrYbzAtMFCimv2fxHXPIp9PBt2u1wNMt0aYWgl8FPwIcS8oqRJg6alnht4Q==", "dev": true, "license": "MIT", "dependencies": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "30.4.1", - "@jest/test-result": "30.4.1", - "@jest/transform": "30.4.1", - "@jest/types": "30.4.1", - "@jridgewell/trace-mapping": "^0.3.25", + "@jest/console": "30.5.2", + "@jest/test-result": "30.5.2", + "@jest/transform": "30.5.2", + "@jest/types": "30.5.1", + "@jridgewell/trace-mapping": "^0.3.31", "@types/node": "*", "chalk": "^4.1.2", "collect-v8-coverage": "^1.0.2", "exit-x": "^0.2.2", - "glob": "^10.5.0", + "glob": "^13.0.6", "graceful-fs": "^4.2.11", "istanbul-lib-coverage": "^3.0.0", "istanbul-lib-instrument": "^6.0.0", "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^5.0.0", "istanbul-reports": "^3.1.3", - "jest-message-util": "30.4.1", - "jest-util": "30.4.1", - "jest-worker": "30.4.1", + "jest-message-util": "30.5.1", + "jest-util": "30.5.1", + "jest-worker": "30.5.1", "slash": "^3.0.0", "string-length": "^4.0.2", "v8-to-istanbul": "^9.0.1" @@ -1107,9 +1148,9 @@ } }, "node_modules/@jest/schemas": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz", - "integrity": "sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==", + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.5.0.tgz", + "integrity": "sha512-/hunigyNpc4RCjC0VaW3f5RCUZVM2+WQ65qP7z083Gmvac7or2LI50XVNOtE4YPgBpV0yxYiAgorAPGniCoJmg==", "dev": true, "license": "MIT", "dependencies": { @@ -1120,13 +1161,13 @@ } }, "node_modules/@jest/snapshot-utils": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.4.1.tgz", - "integrity": "sha512-ObY4ljvQ95mt6iwKtVLetR/4yXiAgl3H4nJxhztr0MTjrN97TwDYrnCp/kF60Ec9HdhkWTHSu+Hg05aXfngpOA==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.5.1.tgz", + "integrity": "sha512-V3wnxNtiVmw5PPVg433Cn3VdXnsOeu/ofLw3KC04Bn2y1wIlU5kozXQn48rhrgj/02LrCVtntTEF1yBha0XSUw==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "30.4.1", + "@jest/types": "30.5.1", "chalk": "^4.1.2", "graceful-fs": "^4.2.11", "natural-compare": "^1.4.0" @@ -1136,14 +1177,15 @@ } }, "node_modules/@jest/source-map": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-30.0.1.tgz", - "integrity": "sha512-MIRWMUUR3sdbP36oyNyhbThLHyJ2eEDClPCiHVbrYAe5g3CHRArIVpBw7cdSB5fr+ofSfIb2Tnsw8iEHL0PYQg==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-30.5.2.tgz", + "integrity": "sha512-c5CehvkbfHX6yyNg7bMn2ylqlp9AHXuZ/3hPH/Lh5bxD/vefd/lV9HBjMqXef9yQNqkdwyZvkLSVSwB38hy8Qw==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.25", + "@jridgewell/trace-mapping": "^0.3.31", "callsites": "^3.1.0", + "convert-source-map": "^2.0.0", "graceful-fs": "^4.2.11" }, "engines": { @@ -1151,14 +1193,14 @@ } }, "node_modules/@jest/test-result": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-30.4.1.tgz", - "integrity": "sha512-/ZG7pgEiOmmWkN9TplKbOu4id2N5lh7FHwRwlkgBVAzGdRH+OkkQ8wX/kIxg4zmd3ZQvAL1RwL2yWsvNYYECTw==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-30.5.2.tgz", + "integrity": "sha512-eO6YU5rsLfs60ne694e0IAmRgeBnoA8mu0nlxXDbl/1j5km0o2vO9/VbbUIKIH+WRKKEI+ELgwraRGn2Lhep8g==", "dev": true, "license": "MIT", "dependencies": { - "@jest/console": "30.4.1", - "@jest/types": "30.4.1", + "@jest/console": "30.5.2", + "@jest/types": "30.5.1", "@types/istanbul-lib-coverage": "^2.0.6", "collect-v8-coverage": "^1.0.2" }, @@ -1167,15 +1209,15 @@ } }, "node_modules/@jest/test-sequencer": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.4.1.tgz", - "integrity": "sha512-PeYE+4td5rKjoRPxztObrXU+H8hsjZfxKMXOcmrr34JerSyB/ROOxbbicz8B7A5j9R9VayDnVPvBmedqCsFCdw==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.5.2.tgz", + "integrity": "sha512-bmij8jZyYAC47ExT2GeP7PcrlwSNS+Bp3KeRuBH88gpcxqDv6fljN8PemS4J/lLZ79xb6mpaennQTTq0zUAVVg==", "dev": true, "license": "MIT", "dependencies": { - "@jest/test-result": "30.4.1", + "@jest/test-result": "30.5.2", "graceful-fs": "^4.2.11", - "jest-haste-map": "30.4.1", + "jest-haste-map": "30.5.1", "slash": "^3.0.0" }, "engines": { @@ -1183,23 +1225,23 @@ } }, "node_modules/@jest/transform": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.4.1.tgz", - "integrity": "sha512-Wz0LyktlTvRefoymh+n64hQ84KNXsRGcwdoZ8CSa0Ea+fgYcHZlnk+hDP7v2MS7il2bQ5uTEIxf4/NNfhMN4KQ==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.5.2.tgz", + "integrity": "sha512-LBGwmaE886C41jDZ65eqR1YbXM7642MK3ZhTowZd5+xDlrDLuf4ePuDdDmVSvcr8NTVJ3MqxLkMbUCzuigUaoQ==", "dev": true, "license": "MIT", "dependencies": { "@babel/core": "^7.27.4", - "@jest/types": "30.4.1", - "@jridgewell/trace-mapping": "^0.3.25", - "babel-plugin-istanbul": "^7.0.1", + "@jest/types": "30.5.1", + "@jridgewell/trace-mapping": "^0.3.31", + "babel-plugin-istanbul": "^8.0.0", "chalk": "^4.1.2", "convert-source-map": "^2.0.0", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.11", - "jest-haste-map": "30.4.1", - "jest-regex-util": "30.4.0", - "jest-util": "30.4.1", + "jest-haste-map": "30.5.1", + "jest-regex-util": "30.5.0", + "jest-util": "30.5.1", "pirates": "^4.0.7", "slash": "^3.0.0", "write-file-atomic": "^5.0.1" @@ -1209,14 +1251,14 @@ } }, "node_modules/@jest/types": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.4.1.tgz", - "integrity": "sha512-f1x/vJXIfjOlEmejYpbkbgw1gOqpPECwMvMEtBqe47j7H2Hg8h8w3o3ikhSXq3MI15kg+oQ0exWO0uCtTNJLoQ==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.5.1.tgz", + "integrity": "sha512-LvVYn83nnXPl+Rg98nvcFgjx6nRMTArhSn6RAX/w3ELn54S8A42TYZvsCMdGUqTM8S0wyXbtlQdU6Hi6dykj9g==", "dev": true, "license": "MIT", "dependencies": { - "@jest/pattern": "30.4.0", - "@jest/schemas": "30.4.1", + "@jest/pattern": "30.5.0", + "@jest/schemas": "30.5.0", "@types/istanbul-lib-coverage": "^2.0.6", "@types/istanbul-reports": "^3.0.4", "@types/node": "*", @@ -1260,9 +1302,9 @@ } }, "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" }, @@ -1277,6 +1319,30 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@keyv/bigmap": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@keyv/bigmap/-/bigmap-1.3.1.tgz", + "integrity": "sha512-WbzE9sdmQtKy8vrNPa9BRnwZh5UF4s1KTmSK0KUVLo3eff5BlQNNWDnFOouNpKfPKDnms9xynJjsMYjMaT/aFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "hashery": "^1.4.0", + "hookified": "^1.15.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "keyv": "^5.6.0" + } + }, + "node_modules/@keyv/serialize": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.1.1.tgz", + "integrity": "sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA==", + "dev": true, + "license": "MIT" + }, "node_modules/@mswjs/interceptors": { "version": "0.41.9", "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.41.9.tgz", @@ -1296,16 +1362,25 @@ } }, "node_modules/@napi-rs/wasm-runtime": { - "version": "0.2.12", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", - "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.2.5.tgz", + "integrity": "sha512-HshSvXzmBxNzqejd3k/KemgQ3hdREUYFRRrgxOZ+gPljDIsO2SDZrVZMd4Z/HsxudQbE62OVyVFE8z9BCurfjA==", "dev": true, "license": "MIT", "optional": true, "dependencies": { - "@emnapi/core": "^1.4.3", - "@emnapi/runtime": "^1.4.3", - "@tybys/wasm-util": "^0.10.0" + "@tybys/wasm-util": "^0.10.3" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=23.5.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1 || ^2.0.0-alpha.4", + "@emnapi/runtime": "^1.7.1 || ^2.0.0-alpha.4" } }, "node_modules/@open-draft/deferred-promise": { @@ -1333,120 +1408,418 @@ "dev": true, "license": "MIT" }, - "node_modules/@package-json/types": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/@package-json/types/-/types-0.0.12.tgz", - "integrity": "sha512-uu43FGU34B5VM9mCNjXCwLaGHYjXdNincqKLaraaCW+7S2+SmiBg1Nv8bPnmschrIfZmfKNY9f3fC376MRrObw==", + "node_modules/@parcel/watcher": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.6.0.tgz", + "integrity": "sha512-7FNeNl8NCE7aINx7WXiKQrPYZWC/hvrTsmk6zmxbI7LTXE7hVek/n8AfVgpe2y82zl3w0HvCHN0bVKMBoJcC0w==", "dev": true, - "license": "MIT" - }, - "node_modules/@pkgr/core": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.3.6.tgz", - "integrity": "sha512-SEeaJLb3qBNF/OaXnaR1NmmBbFYk1zC0ZH/52fATcRPLFg/p791YrcyFFy44Bo9sLaGuSuLp5Q6axbb/O+v/RA==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "detect-libc": "^2.0.3", + "is-glob": "^4.0.3", + "node-addon-api": "^7.0.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.6.0", + "@parcel/watcher-darwin-arm64": "2.6.0", + "@parcel/watcher-darwin-x64": "2.6.0", + "@parcel/watcher-freebsd-x64": "2.6.0", + "@parcel/watcher-linux-arm-glibc": "2.6.0", + "@parcel/watcher-linux-arm-musl": "2.6.0", + "@parcel/watcher-linux-arm64-glibc": "2.6.0", + "@parcel/watcher-linux-arm64-musl": "2.6.0", + "@parcel/watcher-linux-x64-glibc": "2.6.0", + "@parcel/watcher-linux-x64-musl": "2.6.0", + "@parcel/watcher-win32-arm64": "2.6.0", + "@parcel/watcher-win32-x64": "2.6.0" + } + }, + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.6.0.tgz", + "integrity": "sha512-trgpLSCKRC/huFjXX/Smh+0sWe4+YtKfktIToiMl59ghz7z+qkH6kMvNnUbLyRs9N11t8l4svSCs1+5B3rOAhA==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": "^14.18.0 || >=16.0.0" + "node": ">= 10.0.0" }, "funding": { - "url": "https://opencollective.com/pkgr" + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/@sinclair/typebox": { - "version": "0.34.49", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", - "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.6.0.tgz", + "integrity": "sha512-Y3QV0gl7Q1zbfueunkWIERICbEojQFCgpyG7YqOGNFLsckXyI1xu9mAIUpKY9QBYzBtSkN8dBPwd3yiAO9ovMw==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } }, - "node_modules/@sinonjs/commons": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", - "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.6.0.tgz", + "integrity": "sha512-Ohv6OpzhUfKYD7Beb8kDvG0jbIxORCYY1JRdZnaBtnjjkJxgD7ZVL0nw2sCYd0yTMKTvz3nnTnOF3cDifK+kvw==", + "cpu": [ + "x64" + ], "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "type-detect": "4.0.8" + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/@sinonjs/fake-timers": { - "version": "15.4.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.4.0.tgz", - "integrity": "sha512-DsG+8/LscQIQg68J6Ef3dv10u6nVyetYn923s3/sus5eaGfTo1of5WMZSLf0UJc9KDuKPilPH0UDJCjvNbDNCA==", + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.6.0.tgz", + "integrity": "sha512-5HmXvDgs8VK+74jF9y9/2FE3/OnlcKmc56tjmSrEuZjpSZOGL+fvAu+HKJBdPs9uwoP2hE6TlSUpXZ/C5jUFmQ==", + "cpu": [ + "x64" + ], "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@sinonjs/commons": "^3.0.1" + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "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==", + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.6.0.tgz", + "integrity": "sha512-Ps/hui3A+vMbjdqlqAowK2ZL8+BO8dBjxeWXj6npTBs3jx4wWmbPpaLuqwrQrSqIVMCnpWo238bJ1U37GhQOYg==", + "cpu": [ + "arm" + ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, - "dependencies": { - "tslib": "^2.4.0" + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/@types/babel__core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.6.0.tgz", + "integrity": "sha512-9c6AUHgHoG+IY88MRIHupztQiQnrbqHYQjkM2btA+Bf/wQnQMuiD0Wfk1EVv3TlNT3x41uU71rn6E4xh/+zvkw==", + "cpu": [ + "arm" + ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", - "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/@types/babel__generator": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", - "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.6.0.tgz", + "integrity": "sha512-yHRqS2owEXe6Hic9z6Mh1ECsCd+ODVOGvZDyciqRd21+v+o+DnXMOrw50DSpIG2sb8GPEaPPmfeCAWKPJdq46g==", + "cpu": [ + "arm64" + ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", - "dependencies": { - "@babel/types": "^7.0.0" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.6.0.tgz", + "integrity": "sha512-WhB2e/V7rqdHHWZusBSPuy5Ei8S6lSz6FE5TKKQz5h3a0O+C+mhY7vxU9b/stqvMb8beLnPY82ZrFTLKs+SrKA==", + "cpu": [ + "arm64" + ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/@types/babel__traverse": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", - "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.6.0.tgz", + "integrity": "sha512-ulGE6x6Oz6iAwg75T8YQSoguBWasniIbX+QWpaYPcCnDOpdWX3k+4xbEYPZVLxOuoJI+svJJPD3sEj8G7lrQ3A==", + "cpu": [ + "x64" + ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", - "dependencies": { - "@babel/types": "^7.28.2" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/@types/esrecurse": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", - "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.6.0.tgz", + "integrity": "sha512-tkBYKt7YQrjIJWYDnto2YgO8MRkjlMTSNoRHzsXinBqbLdeOM3L32wPZJvIZxqaLMfSlS/4sUjH/6STVP/XDLw==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT" + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } }, - "node_modules/@types/estree": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", - "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.6.0.tgz", + "integrity": "sha512-gIZAP23jaHjGWasY/TY6yL7NHFClf0Ga7FN+iINvk+KN94rhm94lYZhFsbYFNcA04/onvGD9kKmiJLJB2HbNwQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.6.0.tgz", + "integrity": "sha512-cA+/pXV2YkfxlIcXOQ5fSWqAzzPyD78/x5qbK/I0vUkrlYHA8TIz+MXjAbGouguKVSI4bOmkTSJ1/poVSsgt+A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@pkgr/core": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.3.6.tgz", + "integrity": "sha512-SEeaJLb3qBNF/OaXnaR1NmmBbFYk1zC0ZH/52fATcRPLFg/p791YrcyFFy44Bo9sLaGuSuLp5Q6axbb/O+v/RA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/pkgr" + } + }, + "node_modules/@sinclair/typebox": { + "version": "0.34.52", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.52.tgz", + "integrity": "sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "15.4.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.4.0.tgz", + "integrity": "sha512-DsG+8/LscQIQg68J6Ef3dv10u6nVyetYn923s3/sus5eaGfTo1of5WMZSLf0UJc9KDuKPilPH0UDJCjvNbDNCA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.1" + } + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.4.tgz", + "integrity": "sha512-W3c4gRigFS0T/Ma4qIYF3GDAc5AQdHb1yL5znJT1Zv1YaD9Kitx656wBjvr19qbiosmZT8lWDM5BEMynUqX65A==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/esrecurse": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", + "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", "dev": true, "license": "MIT" }, @@ -1496,13 +1869,13 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "25.9.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.9.2.tgz", - "integrity": "sha512-G05zqtJhcDLb8uslf5EjCxXg9G1KQxiV8OS0R26IC//Eoyitzqe8z37I7cqvnZlrlSfgocQRfSn/AHBZJJFyGw==", + "version": "26.6.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-26.6.4.tgz", + "integrity": "sha512-ldVPDCzj7fsaGZrLB0NuHuTvJcsNasysBAqMolr/cgxrLd1xbqxIr3XJiPnHHJUCxj5sNF1vnRj9aWnrVh5Jcg==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": ">=7.24.0 <7.24.7" + "undici-types": "~8.9.0" } }, "node_modules/@types/stack-utils": { @@ -1530,17 +1903,17 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.60.1.tgz", - "integrity": "sha512-JQ4S5GB0tfjO8BuJ4fcX+HodkzJjYBV+7OJ+wLygaX7OGQ7FudyHL4NSCA6ob+w3Yn+5MkKIozOwQhXeM7opVg==", + "version": "8.71.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.71.1.tgz", + "integrity": "sha512-nNlBf6HuotqMgZvSkWD5hNdemiBIxQ2NmrlgfcUIeZRs+BbakjscCQRq/Hb74EFVnFiSWWdL12JruqwBy3ERDw==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.60.1", - "@typescript-eslint/type-utils": "8.60.1", - "@typescript-eslint/utils": "8.60.1", - "@typescript-eslint/visitor-keys": "8.60.1", + "@typescript-eslint/scope-manager": "8.71.1", + "@typescript-eslint/type-utils": "8.71.1", + "@typescript-eslint/utils": "8.71.1", + "@typescript-eslint/visitor-keys": "8.71.1", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.5.0" @@ -1553,22 +1926,22 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.60.1", + "@typescript-eslint/parser": "^8.71.1", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/parser": { - "version": "8.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.60.1.tgz", - "integrity": "sha512-A0M6ua6H252bVjPvvtSgl2QA4+ET9S5Mtkb2GDyTxIhH/C4qDItT7RQNO5PhMC6NXGYXOR9dIalcDDgBKT7oFA==", + "version": "8.71.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.71.1.tgz", + "integrity": "sha512-oM/5sAqz/l1v/zYK1qTOPrn2+JIrBGC1V6uNYucRO5gh6eT9vWJ/RhPbGE59byvZEUQ4VP6XkLBaS5Jti5jpvw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.60.1", - "@typescript-eslint/types": "8.60.1", - "@typescript-eslint/typescript-estree": "8.60.1", - "@typescript-eslint/visitor-keys": "8.60.1", + "@typescript-eslint/scope-manager": "8.71.1", + "@typescript-eslint/types": "8.71.1", + "@typescript-eslint/typescript-estree": "8.71.1", + "@typescript-eslint/visitor-keys": "8.71.1", "debug": "^4.4.3" }, "engines": { @@ -1584,14 +1957,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.60.1.tgz", - "integrity": "sha512-eXkTH2bxmXlqD1RnOPmLZ9ZM9D3VwSx04JOwBnP9RQ+yUA5a2Mu7SfW8uaV2Aon53NJzZlZYuX7tn91Izf+xaw==", + "version": "8.71.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.71.1.tgz", + "integrity": "sha512-Oijc9RUsohHjncg6iGi7gCtjnEjYt9FWv9u6ygK8uKcHK5eLjLAkqERQ9BaytbpceOFdk6kifPCS/zAZE+A99g==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.60.1", - "@typescript-eslint/types": "^8.60.1", + "@typescript-eslint/tsconfig-utils": "^8.71.1", + "@typescript-eslint/types": "^8.71.1", "debug": "^4.4.3" }, "engines": { @@ -1606,14 +1979,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.60.1.tgz", - "integrity": "sha512-gvI5OQoptnxQnchOirukCuQ55svJSTuD/4k5+pC267xyBtYry748R9/c3tYUzb/iE6RZfllRz2lVulLCHkTm4w==", + "version": "8.71.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.71.1.tgz", + "integrity": "sha512-1YUDZXdTnXLlob03SFHBipdyMBsDVm7zoSz0ytTJ39dk5J1TgsTK03VlR/dLXG/RLLUrPcYbD4rp23BmHxHP0w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.60.1", - "@typescript-eslint/visitor-keys": "8.60.1" + "@typescript-eslint/types": "8.71.1", + "@typescript-eslint/visitor-keys": "8.71.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1624,9 +1997,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.60.1.tgz", - "integrity": "sha512-nh8w4qAteiKuZu3pSSzG/yGKpw0OlkrKnzFmbVRenKaD4qc+7i1GrmZaLVkr8rk4uipiPGMOW4YsM6WmKZ5CvA==", + "version": "8.71.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.71.1.tgz", + "integrity": "sha512-oTvkml5SxXhgg+WWKhod5qWQICDXtOB+/Hi9VdPKFAANJ2b7YOgMffgvzXuqog7R6A/JtrzRf128dsxummyWhg==", "dev": true, "license": "MIT", "engines": { @@ -1641,15 +2014,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.60.1.tgz", - "integrity": "sha512-sdwTrpjosW7ANQYJ39ZBF1ZyEMEGVB2UsikrserVM/30a/F1dTLnu9bGxEdosugyu5caigjLrR2qiD11asjI1A==", + "version": "8.71.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.71.1.tgz", + "integrity": "sha512-kH3t3jZCYv2PZSBEWPKTariLrCaoF1CLoPitYFBJOhAGEwWnSRAtGEifrfrpBa4K9JlwWNZotgA5w3/wLSk/FQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.60.1", - "@typescript-eslint/typescript-estree": "8.60.1", - "@typescript-eslint/utils": "8.60.1", + "@typescript-eslint/types": "8.71.1", + "@typescript-eslint/typescript-estree": "8.71.1", + "@typescript-eslint/utils": "8.71.1", "debug": "^4.4.3", "ts-api-utils": "^2.5.0" }, @@ -1666,9 +2039,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.60.1.tgz", - "integrity": "sha512-4h0tY8ppCkdCzcrl2YM5M3my0xsE1Tf8om3owEu5oPWmXwkKRmk0j0LGDzYBGUcAlesEbxBhazqu/K4cu3Ug7w==", + "version": "8.71.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.71.1.tgz", + "integrity": "sha512-ybYnPTUwg3VQQOFEiBPLs8Jxl1ry2vXdn1kVKguomBbvxpetdu3MKTNDqFNUrlG8ylP9MpZosmXMFYlGQHk1oQ==", "dev": true, "license": "MIT", "engines": { @@ -1680,16 +2053,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.60.1.tgz", - "integrity": "sha512-alpRkfG8hlVE5kdJW2GkfgDgXxold3e8e4l6EnmhRmRLbekgAPCCGDVD++sABy9FcgPFroq+uFcCSM1vR57Cew==", + "version": "8.71.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.71.1.tgz", + "integrity": "sha512-pSKSEK1JJpHs6KiKVtABCE4iJK5d7FLFzDXQNBQ2oRY7LEd3UwOt3TZemTgu9syTIf56dJWlTn/pdmrO9oKUXQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.60.1", - "@typescript-eslint/tsconfig-utils": "8.60.1", - "@typescript-eslint/types": "8.60.1", - "@typescript-eslint/visitor-keys": "8.60.1", + "@typescript-eslint/project-service": "8.71.1", + "@typescript-eslint/tsconfig-utils": "8.71.1", + "@typescript-eslint/types": "8.71.1", + "@typescript-eslint/visitor-keys": "8.71.1", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", @@ -1697,82 +2070,473 @@ "ts-api-utils": "^2.5.0" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.1.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.71.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.71.1.tgz", + "integrity": "sha512-CBjT6gfAz3DW2j9Q4moFnqt208Aq+506sVGXfpRcyAeqn0EpayL0mjdWoCO2t3RC7GewNrFxdeehuEaPg6DMzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.71.1", + "@typescript-eslint/types": "8.71.1", + "@typescript-eslint/typescript-estree": "8.71.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.71.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.71.1.tgz", + "integrity": "sha512-0GxiUGqMU0qXJt58cBsiG3DP8lUmBaFo2vChtUX+CT7PnR3v/VGLLrzVP4K9r1lNiZXjHYefMBbPunplr09v6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.71.1", + "eslint-visitor-keys": "^5.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@typescript/native": { + "name": "typescript", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-7.0.2.tgz", + "integrity": "sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc" + }, + "engines": { + "node": ">=16.20.0" + }, + "optionalDependencies": { + "@typescript/typescript-aix-ppc64": "7.0.2", + "@typescript/typescript-darwin-arm64": "7.0.2", + "@typescript/typescript-darwin-x64": "7.0.2", + "@typescript/typescript-freebsd-arm64": "7.0.2", + "@typescript/typescript-freebsd-x64": "7.0.2", + "@typescript/typescript-linux-arm": "7.0.2", + "@typescript/typescript-linux-arm64": "7.0.2", + "@typescript/typescript-linux-loong64": "7.0.2", + "@typescript/typescript-linux-mips64el": "7.0.2", + "@typescript/typescript-linux-ppc64": "7.0.2", + "@typescript/typescript-linux-riscv64": "7.0.2", + "@typescript/typescript-linux-s390x": "7.0.2", + "@typescript/typescript-linux-x64": "7.0.2", + "@typescript/typescript-netbsd-arm64": "7.0.2", + "@typescript/typescript-netbsd-x64": "7.0.2", + "@typescript/typescript-openbsd-arm64": "7.0.2", + "@typescript/typescript-openbsd-x64": "7.0.2", + "@typescript/typescript-sunos-x64": "7.0.2", + "@typescript/typescript-win32-arm64": "7.0.2", + "@typescript/typescript-win32-x64": "7.0.2" + } + }, + "node_modules/@typescript/old": { + "name": "typescript", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", + "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/@typescript/typescript-aix-ppc64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-aix-ppc64/-/typescript-aix-ppc64-7.0.2.tgz", + "integrity": "sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-darwin-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-darwin-arm64/-/typescript-darwin-arm64-7.0.2.tgz", + "integrity": "sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-darwin-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-darwin-x64/-/typescript-darwin-x64-7.0.2.tgz", + "integrity": "sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-freebsd-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-freebsd-arm64/-/typescript-freebsd-arm64-7.0.2.tgz", + "integrity": "sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-freebsd-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-freebsd-x64/-/typescript-freebsd-x64-7.0.2.tgz", + "integrity": "sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-arm": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-arm/-/typescript-linux-arm-7.0.2.tgz", + "integrity": "sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-arm64/-/typescript-linux-arm64-7.0.2.tgz", + "integrity": "sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-loong64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-loong64/-/typescript-linux-loong64-7.0.2.tgz", + "integrity": "sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-mips64el": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-mips64el/-/typescript-linux-mips64el-7.0.2.tgz", + "integrity": "sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-ppc64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-ppc64/-/typescript-linux-ppc64-7.0.2.tgz", + "integrity": "sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-riscv64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-riscv64/-/typescript-linux-riscv64-7.0.2.tgz", + "integrity": "sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-s390x": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-s390x/-/typescript-linux-s390x-7.0.2.tgz", + "integrity": "sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-x64/-/typescript-linux-x64-7.0.2.tgz", + "integrity": "sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-netbsd-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-netbsd-arm64/-/typescript-netbsd-arm64-7.0.2.tgz", + "integrity": "sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-netbsd-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-netbsd-x64/-/typescript-netbsd-x64-7.0.2.tgz", + "integrity": "sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-openbsd-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-openbsd-arm64/-/typescript-openbsd-arm64-7.0.2.tgz", + "integrity": "sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-openbsd-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-openbsd-x64/-/typescript-openbsd-x64-7.0.2.tgz", + "integrity": "sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=16.20.0" } }, - "node_modules/@typescript-eslint/utils": { - "version": "8.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.60.1.tgz", - "integrity": "sha512-h2MPBLoNtjc3qZWfY3Tl51yPorQ2McHn8pJfcMNTcIvrrZrr90Ykffit0yjrPFWQcRcUxzH20+6OcVdW4yHtUg==", + "node_modules/@typescript/typescript-sunos-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-sunos-x64/-/typescript-sunos-x64-7.0.2.tgz", + "integrity": "sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.60.1", - "@typescript-eslint/types": "8.60.1", - "@typescript-eslint/typescript-estree": "8.60.1" - }, + "license": "Apache-2.0", + "optional": true, + "os": [ + "sunos" + ], "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.1.0" + "node": ">=16.20.0" } }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.60.1.tgz", - "integrity": "sha512-EbGRQg4FhrmwLodl+t3JNAnXHWVr9Vp+Zl1QBZVPY4ByfkzIT8cX3K6QWODHtkIZqqJVEWvhHSx3v5PDHsaQag==", + "node_modules/@typescript/typescript-win32-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-win32-arm64/-/typescript-win32-arm64-7.0.2.tgz", + "integrity": "sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.60.1", - "eslint-visitor-keys": "^5.0.0" - }, + "license": "Apache-2.0", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">=16.20.0" } }, - "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", - "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "node_modules/@typescript/typescript-win32-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-win32-x64/-/typescript-win32-x64-7.0.2.tgz", + "integrity": "sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g==", + "cpu": [ + "x64" + ], "dev": true, "license": "Apache-2.0", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": ">=16.20.0" } }, "node_modules/@ungap/structured-clone": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.1.tgz", - "integrity": "sha512-mUFwbeTqrVgDQxFveS+df2yfap6iuP20NAKAsBt5jDEoOTDew+zwLAOilHCeQJOVSvmgCX4ogqIrA0mnyr08yQ==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.4.0.tgz", + "integrity": "sha512-1mEZtMKPM09vDmQt5y7YvmN2+DFTP7Tg0EWXdic8/C6VRnpb33e4ghisCIE3WZjsE2N8mf+QV1Zqh7ZFYLWInQ==", "dev": true, "license": "ISC" }, "node_modules/@unrs/resolver-binding-android-arm-eabi": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz", - "integrity": "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.12.2.tgz", + "integrity": "sha512-g5T90pqg1bo/7mytQx6F4iBNC0Wsh9cu+z9veDbFjc7HjpesJFWD7QMS0NGStXM075+7dJPPVvBbpZlnrdpi/w==", "cpu": [ "arm" ], @@ -1784,9 +2548,9 @@ ] }, "node_modules/@unrs/resolver-binding-android-arm64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.1.tgz", - "integrity": "sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.12.2.tgz", + "integrity": "sha512-YGCRZv/9GLhwmz6mYDeTsm/92BAyR28l6c2ReweVW5pWgfsitWLY8upvfRlGdoyD8HjeTHSYJWyZGD4KJA/nFQ==", "cpu": [ "arm64" ], @@ -1798,9 +2562,9 @@ ] }, "node_modules/@unrs/resolver-binding-darwin-arm64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.1.tgz", - "integrity": "sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.12.2.tgz", + "integrity": "sha512-u9DiNT1auQMO20A9SyTuG3wUgQWB9Z7KjAg0uFuCDR1FsAY8A0CG2S6JpHS1xwm/w1G08bjXZDcyOCjv1WAm2w==", "cpu": [ "arm64" ], @@ -1812,9 +2576,9 @@ ] }, "node_modules/@unrs/resolver-binding-darwin-x64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.1.tgz", - "integrity": "sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.12.2.tgz", + "integrity": "sha512-f7rPLi/T1HVKZu/u6t87lroib16n8vrSzcyxI7lg4BGO9UF26KhQL44sd9eOUgrTYhvRXtWOIZT5PejdPyJfUA==", "cpu": [ "x64" ], @@ -1826,9 +2590,9 @@ ] }, "node_modules/@unrs/resolver-binding-freebsd-x64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.1.tgz", - "integrity": "sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.12.2.tgz", + "integrity": "sha512-BpcOjWCJub6nRZUS2zA20pmLvjtqAtGejETaIyRLiZiQf++cbrjltLA5NN/xaXfqeOBOSlMFbemIl5/S5tljmg==", "cpu": [ "x64" ], @@ -1840,9 +2604,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.1.tgz", - "integrity": "sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.12.2.tgz", + "integrity": "sha512-vZTDvdSISZjJx66OzJqtsOhzifbqRjbmI1Mnu49fQDwog5GtDI4QidRiEAYbZCRj9C8YZEW+3ZjqsyS9GR4k2A==", "cpu": [ "arm" ], @@ -1854,9 +2618,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.1.tgz", - "integrity": "sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.12.2.tgz", + "integrity": "sha512-BiPI+IrIlwcW4nLLMM21+B1dFPzd55yAVgVGrdgDjNef+ch03GdxrcyaIz8X9SsQirh/kCQ7mviyWlMxdh2D7g==", "cpu": [ "arm" ], @@ -1868,9 +2632,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.1.tgz", - "integrity": "sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.12.2.tgz", + "integrity": "sha512-zJc0H99FEPoFfSrNpa91HYfxzfAJCr502oxNK1cfdC9hlaFI43RT+JFCann9JUgZmLzzntChHyn13Sgn9ljHNg==", "cpu": [ "arm64" ], @@ -1885,9 +2649,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-arm64-musl": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.1.tgz", - "integrity": "sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.12.2.tgz", + "integrity": "sha512-KQ3Lki6l+Pz1k/eBipN41ES+YUK30beLGb9YqcB1O542cyLCNE6GaxrfcY3T6EezmGGk84wb5XyO9loTM9tkcA==", "cpu": [ "arm64" ], @@ -1901,10 +2665,44 @@ "linux" ] }, + "node_modules/@unrs/resolver-binding-linux-loong64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-loong64-gnu/-/resolver-binding-linux-loong64-gnu-1.12.2.tgz", + "integrity": "sha512-3SJGEh1DborhG6pyxvhPzCT4bbSIVihsvgJc13P1bHG7KLdNDaF9T3gsTwFc7Jw/5Y5/iWOjkEx7Zy0NvCGX3Q==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-loong64-musl": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-loong64-musl/-/resolver-binding-linux-loong64-musl-1.12.2.tgz", + "integrity": "sha512-jiuG/Obbel7uw1PwHNFfrkiKhLAF6mnyZ6aWlOAVN9WqKm8v0OFGnciJIHu8+CMvXLQ8AD51LPzAoUfT21D5Ew==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.1.tgz", - "integrity": "sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.12.2.tgz", + "integrity": "sha512-q7xRvVpmcfeL+LlZg8Pbbo6QaTZwDU5BaGZbwfhkEsXJn3Was8xYfE0RBH266xZt0rM6B7i8xAYIvjthuUIWHg==", "cpu": [ "ppc64" ], @@ -1919,9 +2717,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.1.tgz", - "integrity": "sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.12.2.tgz", + "integrity": "sha512-0CVdx6lcnT3Q9inOH8tsMIOJ6ImndllMjqJHg8RLVdB7Vq4SfkEXl9mCSsVNuNA4MCYycRicCUxPCabVHJRr6A==", "cpu": [ "riscv64" ], @@ -1936,9 +2734,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.1.tgz", - "integrity": "sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.12.2.tgz", + "integrity": "sha512-iOwlRo9vnp6R6ohHQS11n0NnfdXx/omhkocmIfaPRpQhKZ+3BDMkkdRVh53qjkFkpPddf+FETA28NwGN7l5l+w==", "cpu": [ "riscv64" ], @@ -1953,9 +2751,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.1.tgz", - "integrity": "sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.12.2.tgz", + "integrity": "sha512-HYJtLfXq94q8iZNFT1lknx258wlkkWhZeUXJRqzKBBUJ00CvZ+N33zgbCqimLjsyw5Va6uUxhVa12mI+kaveEw==", "cpu": [ "s390x" ], @@ -1970,9 +2768,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-x64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.1.tgz", - "integrity": "sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.12.2.tgz", + "integrity": "sha512-mPsUhunKKDih5O96Y6enDQyHc1SqBPlY1E/SfMWDM3EdJ95Z9CArPeCVwCCqbP45ljvivdEk8Fxn+SIb1rDAJQ==", "cpu": [ "x64" ], @@ -1987,9 +2785,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-x64-musl": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.1.tgz", - "integrity": "sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.12.2.tgz", + "integrity": "sha512-azrt6+5ydLd8Vt210AAFis/lZevSfPw93EJRIJG+xPu4WCJ8K0kppCTpMyLPcKT7H15M4Jnt2tMp5bOvCkRC6A==", "cpu": [ "x64" ], @@ -2003,10 +2801,24 @@ "linux" ] }, + "node_modules/@unrs/resolver-binding-openharmony-arm64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-openharmony-arm64/-/resolver-binding-openharmony-arm64-1.12.2.tgz", + "integrity": "sha512-YZ9hP4O0X9PQb8eO980qmLNGH4zT3I9+SZTdt0Pr0YyuGQhYKoOZkV02VzrzyOZJ5xIJ3UFIenKkUkGg8GjgWQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, "node_modules/@unrs/resolver-binding-wasm32-wasi": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.1.tgz", - "integrity": "sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.12.2.tgz", + "integrity": "sha512-tYFDIkMxSflfEc/h92ZWNsZlHSwgimbNHSO3PL2JWQHfCuC2q316jMyYU9TIWZsFK2bQwyK5VAdYgn8ygPj69A==", "cpu": [ "wasm32" ], @@ -2014,16 +2826,18 @@ "license": "MIT", "optional": true, "dependencies": { - "@napi-rs/wasm-runtime": "^0.2.11" + "@emnapi/core": "1.10.0", + "@emnapi/runtime": "1.10.0", + "@napi-rs/wasm-runtime": "^1.1.4" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.1.tgz", - "integrity": "sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.12.2.tgz", + "integrity": "sha512-qzNyg3xL0VPQmCaUh+N5jSitce6k+uCBfMDesWRnlULOZaqUkaJ0ybdT+UqlAWJoQjuqfIU/0Ptx9bteN4D82g==", "cpu": [ "arm64" ], @@ -2035,9 +2849,9 @@ ] }, "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.1.tgz", - "integrity": "sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.12.2.tgz", + "integrity": "sha512-WD9sY00OfpHVGfsnHZoA8jVT+esS/Bg8z8jzxp5BnDCjjwsuKsPQrzswwpFy4J1AUJbXPRfkpcX0mXrzeXW79g==", "cpu": [ "ia32" ], @@ -2049,9 +2863,9 @@ ] }, "node_modules/@unrs/resolver-binding-win32-x64-msvc": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz", - "integrity": "sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.12.2.tgz", + "integrity": "sha512-nAB74NfSNKknqQ1RrYj6uz8FcXEomu/MATJZxh/x+BArzN2U3JbOYC0APYzUIGhVY3m5hRxA8VPNdPBoG8txlA==", "cpu": [ "x64" ], @@ -2063,9 +2877,9 @@ ] }, "node_modules/@vercel/ncc": { - "version": "0.38.4", - "resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.38.4.tgz", - "integrity": "sha512-8LwjnlP39s08C08J5NstzriPvW1SP8Zfpp1BvC2sI35kPeZnHfxVkCwu4/+Wodgnd60UtT1n8K8zw+Mp7J9JmQ==", + "version": "0.45.0", + "resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.45.0.tgz", + "integrity": "sha512-8zPi1yO2mHpoKTD+e+Bf0ZT3e+sWHSOyGapm9s7b5R0gxJi3CiFTqmeQiMEyu6ejrz2s09M8JkEoUaTWjBJPQQ==", "dev": true, "license": "MIT", "bin": { @@ -2073,9 +2887,9 @@ } }, "node_modules/acorn": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", - "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.19.0.tgz", + "integrity": "sha512-oJlA3XiRm7Cyk6qFD2Jn8ak9B7jSy0qy00ADO3+8dpT0LSjFihQYv4C02LFCSYJV3Q37xYwwRy5m+IpIiUzqWw==", "dev": true, "license": "MIT", "bin": { @@ -2182,26 +2996,23 @@ } }, "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true, - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } + "license": "Python-2.0" }, "node_modules/babel-jest": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.4.1.tgz", - "integrity": "sha512-fATAbM8piYxkiXQp3RBXmZHxZVNJZAVXXfyeyCN2Tida3+qJ8ea9UxhiJ2y4fLO90ZImKt6k9FlcH2+rLkJGhw==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.5.2.tgz", + "integrity": "sha512-ES8WeJ2fNWPEDunyAtUfJ12nHyaWUloCHdkfK2oW5uSoQSUmjNKdWiGaXJITJwvFEWoD/evHEg/QoCXAvLaQqQ==", "dev": true, "license": "MIT", "dependencies": { - "@jest/transform": "30.4.1", + "@jest/transform": "30.5.2", "@types/babel__core": "^7.20.5", - "babel-plugin-istanbul": "^7.0.1", - "babel-preset-jest": "30.4.0", + "babel-plugin-istanbul": "^8.0.0", + "babel-preset-jest": "30.5.0", "chalk": "^4.1.2", "graceful-fs": "^4.2.11", "slash": "^3.0.0" @@ -2214,9 +3025,9 @@ } }, "node_modules/babel-plugin-istanbul": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-7.0.1.tgz", - "integrity": "sha512-D8Z6Qm8jCvVXtIRkBnqNHX0zJ37rQcFJ9u8WOS6tkYOsRdHBzypCstaxWiu5ZIlqQtviRYbgnRLSoCEvjqcqbA==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-8.0.0.tgz", + "integrity": "sha512-18wCskrN3DgbuBmp1gr7LBGT8xdz5xhQQqFvFhVxbkl8VBCrMKQ2YtqBWtUal1Zrc1HTuX0011+Brjw78TCFkg==", "dev": true, "license": "BSD-3-Clause", "workspaces": [ @@ -2227,16 +3038,16 @@ "@istanbuljs/load-nyc-config": "^1.0.0", "@istanbuljs/schema": "^0.1.3", "istanbul-lib-instrument": "^6.0.2", - "test-exclude": "^6.0.0" + "test-exclude": "^7.0.1" }, "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/babel-plugin-jest-hoist": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.4.0.tgz", - "integrity": "sha512-9EdtWM/sSfXLOGLwSn+GS6pIXyBnL07/8gyJlwFXjWy4DxMOyItqyUT29d4lQiS380EZwYlX7/At4PgBS+m2aA==", + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.5.0.tgz", + "integrity": "sha512-gtGo1B+u14jrZQv6TdSWIWkTqclboo7Qn+dFAGUOIuXLFuJKAdg3U5MIWzZnW4vfUb4dX9skmAMiby86e/SF4A==", "dev": true, "license": "MIT", "dependencies": { @@ -2274,20 +3085,20 @@ } }, "node_modules/babel-preset-jest": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-30.4.0.tgz", - "integrity": "sha512-lBY4jxsNmCnSiu7kquw8ZC9F4+XLMOKypT3RnNHPvU2Kpd4W0xaPuLr5ZkRyOsvLYAY4yaW1ZwTW4xB7NIiZzg==", + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-30.5.0.tgz", + "integrity": "sha512-ZGPn5ClP4lBDpuOK8W1yQIOy359HmbnZv3suucAlIe+SEE9yDsxV4S2PjSbH2Vc97U+WmzYD7vw3kr8NsQ/i6w==", "dev": true, "license": "MIT", "dependencies": { - "babel-plugin-jest-hoist": "30.4.0", + "babel-plugin-jest-hoist": "30.5.0", "babel-preset-current-node-syntax": "^1.2.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" }, "peerDependencies": { - "@babel/core": "^7.11.0 || ^8.0.0-beta.1" + "@babel/core": "^7.11.0 || ^8.0.0-beta.1 || ^8.0.0" } }, "node_modules/balanced-match": { @@ -2301,9 +3112,9 @@ } }, "node_modules/baseline-browser-mapping": { - "version": "2.10.29", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.29.tgz", - "integrity": "sha512-Asa2krT+XTPZINCS+2QcyS8WTkObE77RwkydwF7h6DmnKqbvlalz93m/dnphUyCa6SWSP51VgtEUf2FN+gelFQ==", + "version": "2.11.27", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.27.tgz", + "integrity": "sha512-ElY12DaROGuan+lMmZ8Cvo/ZUbXPe7Enc/9VU/b1T3Kp4dwytRcNdR8DoSJN5SNJT/CuvcCA0DHDVmMOCePdRQ==", "dev": true, "license": "Apache-2.0", "bin": { @@ -2314,22 +3125,22 @@ } }, "node_modules/brace-expansion": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", - "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", + "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/browserslist": { - "version": "4.28.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", - "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", + "version": "4.29.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.29.3.tgz", + "integrity": "sha512-1R4kiYKXGViqEN0CnoDrXc1StD9niAwu+j2dukWzrD4bJgsD4lDmEp0CRbc6E/vYJIfTHwPmwyaKtVSudICdPA==", "dev": true, "funding": [ { @@ -2347,11 +3158,11 @@ ], "license": "MIT", "dependencies": { - "baseline-browser-mapping": "^2.10.12", - "caniuse-lite": "^1.0.30001782", - "electron-to-chromium": "^1.5.328", - "node-releases": "^2.0.36", - "update-browserslist-db": "^1.2.3" + "baseline-browser-mapping": "^2.11.26", + "caniuse-lite": "^1.0.30001813", + "electron-to-chromium": "^1.5.439", + "node-releases": "^2.0.57", + "update-browserslist-db": "^1.3.3" }, "bin": { "browserslist": "cli.js" @@ -2383,12 +3194,19 @@ "node-int64": "^0.4.0" } }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "node_modules/cacheable": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-2.5.0.tgz", + "integrity": "sha512-60cyAOytib/OzBw1JNSoSV/boK1AtHryDIjvVBk7XbN4ugfkM3+Sry7fEjNgPMGgOjuaZPAp8ruZ0Cxafwyq9g==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "@cacheable/memory": "^2.2.0", + "@cacheable/utils": "^2.5.0", + "hookified": "^1.15.0", + "keyv": "^5.6.0", + "qified": "^0.10.1" + } }, "node_modules/callsites": { "version": "3.1.0", @@ -2411,9 +3229,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001792", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001792.tgz", - "integrity": "sha512-hVLMUZFgR4JJ6ACt1uEESvQN1/dBVqPAKY0hgrV70eN3391K6juAfTjKZLKvOMsx8PxA7gsY1/tLMMTcfFLLpw==", + "version": "1.0.30001815", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001815.tgz", + "integrity": "sha512-uDybUEyfgbyJJ93J1vikTylBX31AkdVYeVPeffMQpf8XN7hSfr0oZOn4VFOIMNvtU5+rHvC5Udg2TgtJKHm23Q==", "dev": true, "funding": [ { @@ -2475,9 +3293,9 @@ } }, "node_modules/cjs-module-lexer": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.2.0.tgz", - "integrity": "sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.3.0.tgz", + "integrity": "sha512-lmNyBzi6iYiqyrExTctfmjd8tInx+dHu9PBomTfH5RXS53c27JMFJgzNv5TyAnm3PgGf+MLy0+Ws41/HlVxdKQ==", "dev": true, "license": "MIT" }, @@ -2535,9 +3353,9 @@ "license": "MIT" }, "node_modules/comment-parser": { - "version": "1.4.6", - "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.6.tgz", - "integrity": "sha512-ObxuY6vnbWTN6Od72xfwN9DbzC7Y2vv8u1Soi9ahRKL37gb6y1qk6/dgjs+3JWuXJHWvsg3BXIwzd/rkmAwavg==", + "version": "1.4.9", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.9.tgz", + "integrity": "sha512-+2AvZKjJaNq9GQljm3tr0utwrig5BL+jgJGvz5rDpGKNIp+ojcRXWUwBbh/sGIi1QCprR6PsKFakub+w1v+4hQ==", "dev": true, "license": "MIT", "engines": { @@ -2622,6 +3440,16 @@ "node": ">=0.10.0" } }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -2633,9 +3461,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.354", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.354.tgz", - "integrity": "sha512-JaBHwWcfIdmSAfWM5l3uwjGd431j8YEMikZ+K/2nXVuBqJKyZ0f+2h4n4JY5AyNiZmnY9qQr2RU3v9DxDmHMNg==", + "version": "1.5.451", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.451.tgz", + "integrity": "sha512-vUNKPrUzw8ByEMOxloq0a71iD/mPuPxVkbDm3G5YhnxTzOw/I6qAg2MUS0cYj/c267lWmw26yW4Vv7foxTxPLg==", "dev": true, "license": "ISC" }, @@ -2669,6 +3497,13 @@ "is-arrayish": "^0.2.1" } }, + "node_modules/es-module-lexer": { + "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" + }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", @@ -2693,18 +3528,21 @@ } }, "node_modules/eslint": { - "version": "10.4.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.4.1.tgz", - "integrity": "sha512-AyIKhnOBuOAdueD7RB3xB+YeAWScb9jHsJBgH2Hcde8InP5JYhqrRR6iTMHyTEwgENK54Cp44e4v8BwNhsuHuw==", + "version": "10.12.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.12.0.tgz", + "integrity": "sha512-npHjrHb2o4ehH3mE+YuxABR+0gyb0aVWCIolgJDArwCiHEIsonBm3ZKjel5b0U5+a+MbEvIyRCGCzD3eKKK2NA==", "dev": true, "license": "MIT", + "workspaces": [ + "packages/*" + ], "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.2", "@eslint/config-array": "^0.23.5", - "@eslint/config-helpers": "^0.6.0", + "@eslint/config-helpers": "^0.7.0", "@eslint/core": "^1.2.1", - "@eslint/plugin-kit": "^0.7.2", + "@eslint/plugin-kit": "^0.7.3", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", @@ -2719,14 +3557,14 @@ "esquery": "^1.7.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^8.0.0", + "file-entry-cache": "11.1.5 || >11.1.6 <12", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", - "minimatch": "^10.2.4", + "minimatch": "^10.2.5", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, @@ -2825,13 +3663,12 @@ } }, "node_modules/eslint-plugin-import-x": { - "version": "4.16.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-import-x/-/eslint-plugin-import-x-4.16.2.tgz", - "integrity": "sha512-rM9K8UBHcWKpzQzStn1YRN2T5NvdeIfSVoKu/lKF41znQXHAUcBbYXe5wd6GNjZjTrP7viQ49n1D83x/2gYgIw==", + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import-x/-/eslint-plugin-import-x-4.17.1.tgz", + "integrity": "sha512-4cdstYkKCyjumM2Q9NSI03K8D2a9F4Ssz33K2lv2hQa4KmR9jPLwk3uWGtNvclfqBrPGfGuMBwsGMbe6dMRbfg==", "dev": true, "license": "MIT", "dependencies": { - "@package-json/types": "^0.0.12", "@typescript-eslint/types": "^8.56.0", "comment-parser": "^1.4.1", "debug": "^4.4.1", @@ -2863,9 +3700,9 @@ } }, "node_modules/eslint-plugin-jest": { - "version": "29.15.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-29.15.2.tgz", - "integrity": "sha512-kEN4r9RZl1xcsb4arGq89LrcVdOUFII/JSCwtTPJyv16mDwmPrcuEQwpxqZHeINvcsd7oK5O/rhdGlxFRaZwvQ==", + "version": "29.16.6", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-29.16.6.tgz", + "integrity": "sha512-q8TVr0rlNvUD0XnafGWkwtPeX+tTl2llP86EDl3sJtwWrQA/JT9SIu2hLLZbhhX6fT5SDE4O0gIKyZUujKnkYA==", "dev": true, "license": "MIT", "dependencies": { @@ -2878,7 +3715,7 @@ "@typescript-eslint/eslint-plugin": "^8.0.0", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "jest": "*", - "typescript": ">=4.8.4 <7.0.0" + "typescript": ">=4.8.4 <8.0.0" }, "peerDependenciesMeta": { "@typescript-eslint/eslint-plugin": { @@ -3009,20 +3846,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "license": "BSD-2-Clause", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/esquery": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", @@ -3104,18 +3927,18 @@ } }, "node_modules/expect": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-30.4.1.tgz", - "integrity": "sha512-PMARsyh/JtqC20HoGqlFcIlQAyqUtW4PlI1rup1uhYJtKuwAjbvWi3GQMAn+STdHum/dk8xrKfUM1+5SAwpolA==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-30.5.2.tgz", + "integrity": "sha512-0LNuMvs8/5mRYhnCR4k+lGV7fqPMs6Bnksda4S3zsCUmdxBpAn4zU4NNzXdq1pMKe/H4W5t/zVIDSJ/H3e0vDA==", "dev": true, "license": "MIT", "dependencies": { - "@jest/expect-utils": "30.4.1", - "@jest/get-type": "30.1.0", - "jest-matcher-utils": "30.4.1", - "jest-message-util": "30.4.1", - "jest-mock": "30.4.1", - "jest-util": "30.4.1" + "@jest/expect-utils": "30.5.2", + "@jest/get-type": "30.5.0", + "jest-matcher-utils": "30.5.2", + "jest-message-util": "30.5.1", + "jest-mock": "30.5.2", + "jest-util": "30.5.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" @@ -3178,16 +4001,13 @@ } }, "node_modules/file-entry-cache": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "version": "11.1.5", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-11.1.5.tgz", + "integrity": "sha512-+PFTHITI08JIGhnNpGNI8T8inUpgZfk3GNEqfT9R2zZV2iFXg3CvqzSl/uEhs7TSGujYRELEANyDvS8Fj7+S7Q==", "dev": true, "license": "MIT", "dependencies": { - "flat-cache": "^4.0.0" - }, - "engines": { - "node": ">=16.0.0" + "flat-cache": "^6.1.23" } }, "node_modules/find-up": { @@ -3208,41 +4028,24 @@ } }, "node_modules/flat-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "version": "6.1.23", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-6.1.23.tgz", + "integrity": "sha512-f++BY9pTk+983xK1FLzlLpmM0i0z+jHmx3QESGkURMXujQZz1k5wzwX6hjnQ8goaD0B+sYnDK1yZ6MTyZfUaqA==", "dev": true, "license": "MIT", "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.4" - }, - "engines": { - "node": ">=16" + "cacheable": "^2.5.0", + "flatted": "^3.4.2", + "hookified": "^1.15.0" } }, "node_modules/flatted": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", - "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "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" }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -3287,9 +4090,9 @@ } }, "node_modules/get-tsconfig": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.14.0.tgz", - "integrity": "sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==", + "version": "4.14.3", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.14.3.tgz", + "integrity": "sha512-++QEw4DIY7WGoukz+/+A/8dGYPT9l9yIadnmSgZ8Rjr3YVSVDipQSO9CdnJo9ePqFqUUqh+wk9uIaoiAwsiPkA==", "dev": true, "license": "MIT", "dependencies": { @@ -3331,9 +4134,9 @@ } }, "node_modules/globals": { - "version": "17.6.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-17.6.0.tgz", - "integrity": "sha512-sepffkT8stwnIYbsMBpoCHJuJM5l98FUF2AnE07hfvE0m/qp3R586hw4jF4uadbhvg1ooIdzuu7CsfD2jzCaNA==", + "version": "17.13.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.13.0.tgz", + "integrity": "sha512-RwMTC61u7hrG3ZJMkZQOK4JLJrKS8QtoTii63EmWvFXHqycY9FObBJQCbsLxSO8kjKhWE5kV1GC+Vb1g3RI0Zg==", "dev": true, "license": "MIT", "engines": { @@ -3351,13 +4154,13 @@ "license": "ISC" }, "node_modules/handlebars": { - "version": "4.7.9", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.9.tgz", - "integrity": "sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==", + "version": "4.7.10", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.10.tgz", + "integrity": "sha512-P5VJMVM7qgBn6vjXMw8WG9uVI+ncf2pi72j4de4yz5ZULLj2RGqLYaKOYGsgyrViQ0tePOVlN1tDCCXXtFqXKg==", "dev": true, "license": "MIT", "dependencies": { - "minimist": "^1.2.5", + "minimist": "^1.2.8", "neo-async": "^2.6.2", "source-map": "^0.6.1", "wordwrap": "^1.0.0" @@ -3382,6 +4185,26 @@ "node": ">=8" } }, + "node_modules/hashery": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/hashery/-/hashery-1.5.1.tgz", + "integrity": "sha512-iZyKG96/JwPz1N55vj2Ie2vXbhu440zfUfJvSwEqEbeLluk7NnapfGqa7LH0mOsnDxTF85Mx8/dyR6HfqcbmbQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "hookified": "^1.15.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/hookified": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/hookified/-/hookified-1.15.1.tgz", + "integrity": "sha512-MvG/clsADq1GPM2KGo2nyfaWVyn9naPiXrqIe4jYjXNZQt238kWyOGrsyc/DmRAQ+Re6yeo6yX/yoNCG5KAEVg==", + "dev": true, + "license": "MIT" + }, "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", @@ -3400,9 +4223,9 @@ } }, "node_modules/ignore": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", - "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "version": "7.0.12", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.12.tgz", + "integrity": "sha512-/8UvqAPU9DGTI9k4mxtf49U37Isfwr8Uts96+SBHIkFxPJnHS0Ew4f00sM4Scd8V8EjM0jUNtVDdv1kPdt35lg==", "dev": true, "license": "MIT", "engines": { @@ -3598,16 +4421,16 @@ } }, "node_modules/jest": { - "version": "30.4.2", - "resolved": "https://registry.npmjs.org/jest/-/jest-30.4.2.tgz", - "integrity": "sha512-Yi1jqNC/Oq0N4hBgNH/YvBpP1P57QqundgytzYqy3yqAa7NZPNjSoi4SGbRAXDMdBzNE6xBCi5U7RgfrvMEUVQ==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/jest/-/jest-30.5.2.tgz", + "integrity": "sha512-3gnpdBIza8ijCl3iMV9ChE3hSt1+46865qqod863gQtJr1DixOkAU5DoGbi3u+XlRcw++BhZQMu/y4xBdHBvSQ==", "dev": true, "license": "MIT", "dependencies": { - "@jest/core": "30.4.2", - "@jest/types": "30.4.1", + "@jest/core": "30.5.2", + "@jest/types": "30.5.1", "import-local": "^3.2.0", - "jest-cli": "30.4.2" + "jest-cli": "30.5.2" }, "bin": { "jest": "bin/jest.js" @@ -3625,14 +4448,14 @@ } }, "node_modules/jest-changed-files": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-30.4.1.tgz", - "integrity": "sha512-IuctmYrxi21iOSOaIXpJWalHyPAsVv0GeBHKDn8C1CA4W5htHn7INL+wdnL4Bo0+olEndvAFkmb++tIQJG+vvg==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-30.5.1.tgz", + "integrity": "sha512-0+bvMM/ENhDI29Z8q1r4HxiDIi4G5tnBmSw4esfPQoj9q8Nik7KIyuxHkTVnnniJQf05SxpGaKDQ+4h28ynGPg==", "dev": true, "license": "MIT", "dependencies": { "execa": "^5.1.1", - "jest-util": "30.4.1", + "jest-util": "30.5.1", "p-limit": "^3.1.0" }, "engines": { @@ -3640,29 +4463,29 @@ } }, "node_modules/jest-circus": { - "version": "30.4.2", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-30.4.2.tgz", - "integrity": "sha512-rvHH7VlY6LgbJXJTQ87GW62g1FntOtbhh0zT+v04kC+pgL6aBKyYINXxWukCpj3dcIBMw5/XUbtDS9dU9JTXeQ==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-30.5.2.tgz", + "integrity": "sha512-vffFgjs5JSJ9q4ds1vNW3klKYPJfYfIY61LT/zaZgvTeASJOWZUt8LBfHgIcV4rwxlPBLl/ePBGccHEclS4PlQ==", "dev": true, "license": "MIT", "dependencies": { - "@jest/environment": "30.4.1", - "@jest/expect": "30.4.1", - "@jest/test-result": "30.4.1", - "@jest/types": "30.4.1", + "@jest/environment": "30.5.2", + "@jest/expect": "30.5.2", + "@jest/test-result": "30.5.2", + "@jest/types": "30.5.1", "@types/node": "*", "chalk": "^4.1.2", "co": "^4.6.0", "dedent": "^1.6.0", "is-generator-fn": "^2.1.0", - "jest-each": "30.4.1", - "jest-matcher-utils": "30.4.1", - "jest-message-util": "30.4.1", - "jest-runtime": "30.4.2", - "jest-snapshot": "30.4.1", - "jest-util": "30.4.1", + "jest-each": "30.5.2", + "jest-matcher-utils": "30.5.2", + "jest-message-util": "30.5.1", + "jest-runtime": "30.5.2", + "jest-snapshot": "30.5.2", + "jest-util": "30.5.1", "p-limit": "^3.1.0", - "pretty-format": "30.4.1", + "pretty-format": "30.5.1", "pure-rand": "^7.0.0", "slash": "^3.0.0", "stack-utils": "^2.0.6" @@ -3672,21 +4495,21 @@ } }, "node_modules/jest-cli": { - "version": "30.4.2", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-30.4.2.tgz", - "integrity": "sha512-jfA2ocvVHMXS2QijrJ0d31ektP+d/W0T5RpcTX2Pq+3sVqHlsXVCM2+FmwpL+bdY8OfHpIg9xMxLF17Zg0U49Q==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-30.5.2.tgz", + "integrity": "sha512-YYYxUUVjFgPvgEleKNKMaYGIFgR3l3832Cl0kRL/oCiDZ03v7wImUtquHl2OOBCCNgprjZgBN5bczS/JklPBDg==", "dev": true, "license": "MIT", "dependencies": { - "@jest/core": "30.4.2", - "@jest/test-result": "30.4.1", - "@jest/types": "30.4.1", + "@jest/core": "30.5.2", + "@jest/test-result": "30.5.2", + "@jest/types": "30.5.1", "chalk": "^4.1.2", "exit-x": "^0.2.2", "import-local": "^3.2.0", - "jest-config": "30.4.2", - "jest-util": "30.4.1", - "jest-validate": "30.4.1", + "jest-config": "30.5.2", + "jest-util": "30.5.1", + "jest-validate": "30.5.1", "yargs": "^17.7.2" }, "bin": { @@ -3705,33 +4528,33 @@ } }, "node_modules/jest-config": { - "version": "30.4.2", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-30.4.2.tgz", - "integrity": "sha512-rNHAShJQqQwFNoL0hbf3BphSBOWnpOUAKvidLS/AjNVLPfoj5mSf4jQMfW3cYOs6hXeZC7nF7mDHaBnbxELOzg==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-30.5.2.tgz", + "integrity": "sha512-U6221OZekabePvGcGPf4raIBKMvYQWFHvhobDJRojOYaFMj2HaGytAdknjDhYc6JTz2fdHW9+6k0wWUDaNeOFQ==", "dev": true, "license": "MIT", "dependencies": { "@babel/core": "^7.27.4", - "@jest/get-type": "30.1.0", - "@jest/pattern": "30.4.0", - "@jest/test-sequencer": "30.4.1", - "@jest/types": "30.4.1", - "babel-jest": "30.4.1", + "@jest/get-type": "30.5.0", + "@jest/pattern": "30.5.0", + "@jest/test-sequencer": "30.5.2", + "@jest/types": "30.5.1", + "babel-jest": "30.5.2", "chalk": "^4.1.2", "ci-info": "^4.2.0", "deepmerge": "^4.3.1", - "glob": "^10.5.0", + "glob": "^13.0.6", "graceful-fs": "^4.2.11", - "jest-circus": "30.4.2", - "jest-docblock": "30.4.0", - "jest-environment-node": "30.4.1", - "jest-regex-util": "30.4.0", - "jest-resolve": "30.4.1", - "jest-runner": "30.4.2", - "jest-util": "30.4.1", - "jest-validate": "30.4.1", + "jest-circus": "30.5.2", + "jest-docblock": "30.5.0", + "jest-environment-node": "30.5.2", + "jest-regex-util": "30.5.0", + "jest-resolve": "30.5.1", + "jest-runner": "30.5.2", + "jest-util": "30.5.1", + "jest-validate": "30.5.1", "parse-json": "^5.2.0", - "pretty-format": "30.4.1", + "pretty-format": "30.5.1", "slash": "^3.0.0", "strip-json-comments": "^3.1.1" }, @@ -3756,25 +4579,25 @@ } }, "node_modules/jest-diff": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.4.1.tgz", - "integrity": "sha512-CRpFK0RtLriVDGcPPAnR6HMVI8bSR2jnUIgralhauzYQZIb4RH9AtEInTuQr65LmmGggGcRT6HIASxwqsVsmlA==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.5.2.tgz", + "integrity": "sha512-rBtHnI6BWTiWj3lM7fOLVfChx7R9B0u9VV3PRHawKs79x6ZjW1QoSrKenaigNGWlvhtoi2BqvDbABDie+Os3xQ==", "dev": true, "license": "MIT", "dependencies": { - "@jest/diff-sequences": "30.4.0", - "@jest/get-type": "30.1.0", + "@jest/diff-sequences": "30.5.0", + "@jest/get-type": "30.5.0", "chalk": "^4.1.2", - "pretty-format": "30.4.1" + "pretty-format": "30.5.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-docblock": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-30.4.0.tgz", - "integrity": "sha512-ZPMabUZCx5MpbZ2eBYSvZ0J8fvo3dR9oM+eeUpb3aKNQFuS2tu3Duw1TNlMoP8k3WQgKGJuhcMFvwcVuq6T7oA==", + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-30.5.0.tgz", + "integrity": "sha512-NwDqcxtoZi33RhuW+zJS/RVA3rmheQ8BnwpYZuc/Eruaz6seQb7+aoCeDZu/3X7W2XmD8DbSo9Pn72DbKsBFYw==", "dev": true, "license": "MIT", "dependencies": { @@ -3785,111 +4608,110 @@ } }, "node_modules/jest-each": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-30.4.1.tgz", - "integrity": "sha512-/8MJbH6fuj48TstjrMf+u/pd06Qezz5xOXvZA6442heNOWr8bdeoGZX2d9fCn028CoMgYmroH9//zky5GfyYmA==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-30.5.2.tgz", + "integrity": "sha512-GRrW+7fmmgmkvyfEBqc1QFdWnF1Ex5yG6Y6AWL4TTxnkWlKIT98dsKh3P3UuWm6v4XsQwVE6DEzXIPMzWJ3ZbA==", "dev": true, "license": "MIT", "dependencies": { - "@jest/get-type": "30.1.0", - "@jest/types": "30.4.1", + "@jest/get-type": "30.5.0", + "@jest/types": "30.5.1", "chalk": "^4.1.2", - "jest-util": "30.4.1", - "pretty-format": "30.4.1" + "jest-regex-util": "30.5.0", + "jest-util": "30.5.1", + "pretty-format": "30.5.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-environment-node": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-30.4.1.tgz", - "integrity": "sha512-4FZYVOk85hz2AyT6BbarKy9u37g6DbrDyCdFhsnDdXqyrueYQvB+0zO4f/kqLCRD0BsPRXPMNJeQwihKZV8naw==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-30.5.2.tgz", + "integrity": "sha512-Ciz4KgTGIbojxSKpuFImgWJj5EyqfE8xMq9NxWmOXnQywHHS03H9Mv+vaCB29J5pr3JBrY27WbRV18rBdjh8Dg==", "dev": true, "license": "MIT", "dependencies": { - "@jest/environment": "30.4.1", - "@jest/fake-timers": "30.4.1", - "@jest/types": "30.4.1", + "@jest/environment": "30.5.2", + "@jest/fake-timers": "30.5.2", + "@jest/types": "30.5.1", "@types/node": "*", - "jest-mock": "30.4.1", - "jest-util": "30.4.1", - "jest-validate": "30.4.1" + "jest-mock": "30.5.2", + "jest-util": "30.5.1", + "jest-validate": "30.5.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-haste-map": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.4.1.tgz", - "integrity": "sha512-rFrcONd8jeFsyw+Z9CrScJgglRf2+NFmNam8dKu7n+SoHqNYT47mn0DdEcVUZJpvh7Iz6/si7f7yUH7GJHVgnw==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.5.1.tgz", + "integrity": "sha512-VIFgt67jW480YDxKfEv9IYQKrFpYt7bOCMn3VsnjK7AK9qo7p6acpnA1DHwsVOULE3dTaYew/6JaTD/d0VDHoQ==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "30.4.1", + "@jest/types": "30.5.1", + "@parcel/watcher": "^2.6.0", "@types/node": "*", "anymatch": "^3.1.3", "fb-watchman": "^2.0.2", + "fdir": "^6.5.0", "graceful-fs": "^4.2.11", - "jest-regex-util": "30.4.0", - "jest-util": "30.4.1", - "jest-worker": "30.4.1", - "picomatch": "^4.0.3", - "walker": "^1.0.8" + "jest-regex-util": "30.5.0", + "jest-util": "30.5.1", + "jest-worker": "30.5.1", + "picomatch": "^4.0.3" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.3" } }, "node_modules/jest-leak-detector": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-30.4.1.tgz", - "integrity": "sha512-IpmyiioeHxiWDhesHnUFmOxcTzwCwKpgACgWajtAP+nYQXiY7DakTxB6Bx9JFiRMljr0AX1PvnQdaU1KFoz6NQ==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-30.5.1.tgz", + "integrity": "sha512-gt4GT2aWgEoCNTcBe4rqS74xTIUJxi+UD9SNSu9aOk5LmTEd6fS5KSTmAKAfitCCktQHNN+upUuL6EkBfFbMDQ==", "dev": true, "license": "MIT", "dependencies": { - "@jest/get-type": "30.1.0", - "pretty-format": "30.4.1" + "@jest/get-type": "30.5.0", + "pretty-format": "30.5.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-matcher-utils": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.4.1.tgz", - "integrity": "sha512-zvYfX5CaeEkFrrLS9suWe9rvJrm9J1Iv3ua8kIBv9GEPzcnsfBf0bob37la7s67fs0nlBC3EuvkOLnXQKxtx4A==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.5.2.tgz", + "integrity": "sha512-lFkB365PTIHOhPzwrb9T6gvlDnPpOZ7/c3ewOKKB7bzztqjVrtlyRL2MkyfJXpyY2u2SKw001JKrTx14fBUFcQ==", "dev": true, "license": "MIT", "dependencies": { - "@jest/get-type": "30.1.0", + "@jest/get-type": "30.5.0", "chalk": "^4.1.2", - "jest-diff": "30.4.1", - "pretty-format": "30.4.1" + "jest-diff": "30.5.2", + "pretty-format": "30.5.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-message-util": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.4.1.tgz", - "integrity": "sha512-kwCKIvq0MCW1HzLoGola9Te6JUdzgV0loyKJ3Qghrkz9i5/RRIHsL95BMQc2HBBhlBKC4j22K9p11TGHH8RBpQ==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.5.1.tgz", + "integrity": "sha512-UdQlLdd9wL/Ys7xRErckqwD6wPlSZYueosSWuHc1r2ztGLwlgPvtSJq2+BPEgaEY13WLvfFbmhTj8pba0Sd1jg==", "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", - "@jest/types": "30.4.1", + "@jest/types": "30.5.1", "@types/stack-utils": "^2.0.3", "chalk": "^4.1.2", "graceful-fs": "^4.2.11", - "jest-util": "30.4.1", + "jest-util": "30.5.1", "picomatch": "^4.0.3", - "pretty-format": "30.4.1", + "pretty-format": "30.5.1", "slash": "^3.0.0", "stack-utils": "^2.0.6" }, @@ -3898,42 +4720,25 @@ } }, "node_modules/jest-mock": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.4.1.tgz", - "integrity": "sha512-/i8SVb8/NSB7RfNi8gfqu8gxLV23KaL5EpAttyb9iz8qWRIqXRLflycz/32wXsYkOnaUlx8NAKnJYtpsmXUmfw==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.5.2.tgz", + "integrity": "sha512-KTHb37Fhj8xY8qPFvTFaFJHcdsumQp+ExsUlgoX232Agmc706gagBs53+CYvulV7MVQo9AgXOUxsqzzVBoJlrA==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "30.4.1", + "@jest/expect-utils": "30.5.2", + "@jest/types": "30.5.1", "@types/node": "*", - "jest-util": "30.4.1" + "jest-util": "30.5.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/jest-pnp-resolver": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", - "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "jest-resolve": "*" - }, - "peerDependenciesMeta": { - "jest-resolve": { - "optional": true - } - } - }, "node_modules/jest-regex-util": { - "version": "30.4.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.4.0.tgz", - "integrity": "sha512-mWlvLviKIgIQ8VCuM1xRdD0TWp3zlzionlmDBjuXVBs+VkmXq6FgW9T4Emr7oGz/Rk6feDCGyiugolcQEyp3mg==", + "version": "30.5.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.5.0.tgz", + "integrity": "sha512-Mg0WK7A6xRHLSA1udJ8y9f3lM0uUhFTBnLKzwPmqB9AylvpleJ6BLemR8K9dK27DY+cesDryoA7yLZCAHsPG1A==", "dev": true, "license": "MIT", "engines": { @@ -3941,100 +4746,100 @@ } }, "node_modules/jest-resolve": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.4.1.tgz", - "integrity": "sha512-Zry8Yq/yJcNAZ7dJ5F2heic8AheXvbFZ7XI5V+h28nrYZ7Qoyy4dItq8OodjnYD270mvX+ZudmrNV9cysqhW5Q==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.5.1.tgz", + "integrity": "sha512-wprhLejRtwN6h8ZgaqC0eYjGJ1uMdGPT/+b3eFncbG4NWuuP9QL+vWwRinu9waw7hkOLcpMJGVJAMgBwsPssMQ==", "dev": true, "license": "MIT", "dependencies": { "chalk": "^4.1.2", "graceful-fs": "^4.2.11", - "jest-haste-map": "30.4.1", - "jest-pnp-resolver": "^1.2.3", - "jest-util": "30.4.1", - "jest-validate": "30.4.1", + "jest-haste-map": "30.5.1", + "jest-util": "30.5.1", + "jest-validate": "30.5.1", "slash": "^3.0.0", - "unrs-resolver": "^1.7.11" + "unrs-resolver": "^1.12.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-resolve-dependencies": { - "version": "30.4.2", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-30.4.2.tgz", - "integrity": "sha512-gDiVh1I+GxYzz9oXlyw+1wv6VOYX1WYxMOfjsA3iGKePV2oxmbHhwxfkALxNxYy1ciw6APWwkW2zZONwP97aEQ==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-30.5.2.tgz", + "integrity": "sha512-GMI0DP5enX9Z2qW2zFy1bOkrCfWAOPRJQ7qHt0pdfrxBPsgWxglMPrRSK2TX/wRWYxcPRSLFg3Z88qPOzHx7FQ==", "dev": true, "license": "MIT", "dependencies": { - "jest-regex-util": "30.4.0", - "jest-snapshot": "30.4.1" + "jest-regex-util": "30.5.0", + "jest-snapshot": "30.5.2" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-runner": { - "version": "30.4.2", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-30.4.2.tgz", - "integrity": "sha512-2dw0PslVYXxffXGpLo+Ejad+KcI1Qkjn7f4X4619gf21oCUmL+SPfjqIa/losUem3yEOvfNZe/F1HWUcNpODcg==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-30.5.2.tgz", + "integrity": "sha512-/B6px7hiiNhVSRwuv9AGn0nawYvwsHeQZ3ItTd5Gp2diFd0EOKaWVeWqcbw3L88vx1GfpCKjQkxWItZCTl11Rw==", "dev": true, "license": "MIT", "dependencies": { - "@jest/console": "30.4.1", - "@jest/environment": "30.4.1", - "@jest/test-result": "30.4.1", - "@jest/transform": "30.4.1", - "@jest/types": "30.4.1", + "@jest/console": "30.5.2", + "@jest/environment": "30.5.2", + "@jest/source-map": "30.5.2", + "@jest/test-result": "30.5.2", + "@jest/transform": "30.5.2", + "@jest/types": "30.5.1", "@types/node": "*", "chalk": "^4.1.2", "emittery": "^0.13.1", "exit-x": "^0.2.2", "graceful-fs": "^4.2.11", - "jest-docblock": "30.4.0", - "jest-environment-node": "30.4.1", - "jest-haste-map": "30.4.1", - "jest-leak-detector": "30.4.1", - "jest-message-util": "30.4.1", - "jest-resolve": "30.4.1", - "jest-runtime": "30.4.2", - "jest-util": "30.4.1", - "jest-watcher": "30.4.1", - "jest-worker": "30.4.1", - "p-limit": "^3.1.0", - "source-map-support": "0.5.13" + "jest-docblock": "30.5.0", + "jest-environment-node": "30.5.2", + "jest-haste-map": "30.5.1", + "jest-leak-detector": "30.5.1", + "jest-message-util": "30.5.1", + "jest-resolve": "30.5.1", + "jest-runtime": "30.5.2", + "jest-util": "30.5.1", + "jest-watcher": "30.5.2", + "jest-worker": "30.5.1", + "p-limit": "^3.1.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-runtime": { - "version": "30.4.2", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-30.4.2.tgz", - "integrity": "sha512-3/5e8iPz2k/VLqlr8DgTftYyLUv8Su3FkCAO2/Od81UsUTpSxOrS6O5x5KkoQwyUjmpYyDJKeyAvg2T2nvpNkQ==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-30.5.2.tgz", + "integrity": "sha512-0paUAHBlheai10A3XSy9Xh+YBG0IROy+/qzcDPzQ/nbbXrznQzeWy5qniICWK6d3W3scaRQCVAbXdcK0ibBq4w==", "dev": true, "license": "MIT", "dependencies": { - "@jest/environment": "30.4.1", - "@jest/fake-timers": "30.4.1", - "@jest/globals": "30.4.1", - "@jest/source-map": "30.0.1", - "@jest/test-result": "30.4.1", - "@jest/transform": "30.4.1", - "@jest/types": "30.4.1", + "@jest/environment": "30.5.2", + "@jest/fake-timers": "30.5.2", + "@jest/globals": "30.5.2", + "@jest/source-map": "30.5.2", + "@jest/test-result": "30.5.2", + "@jest/transform": "30.5.2", + "@jest/types": "30.5.1", "@types/node": "*", "chalk": "^4.1.2", - "cjs-module-lexer": "^2.1.0", + "cjs-module-lexer": "^2.2.0", "collect-v8-coverage": "^1.0.2", - "glob": "^10.5.0", + "es-module-lexer": "^2.1.0", + "glob": "^13.0.6", "graceful-fs": "^4.2.11", - "jest-haste-map": "30.4.1", - "jest-message-util": "30.4.1", - "jest-mock": "30.4.1", - "jest-regex-util": "30.4.0", - "jest-resolve": "30.4.1", - "jest-snapshot": "30.4.1", - "jest-util": "30.4.1", + "jest-haste-map": "30.5.1", + "jest-message-util": "30.5.1", + "jest-mock": "30.5.2", + "jest-regex-util": "30.5.0", + "jest-resolve": "30.5.1", + "jest-snapshot": "30.5.2", + "jest-util": "30.5.1", "slash": "^3.0.0", "strip-bom": "^4.0.0" }, @@ -4043,9 +4848,9 @@ } }, "node_modules/jest-snapshot": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.4.1.tgz", - "integrity": "sha512-tEOkkfOMppUyeiHwjZswOQ3lcnoTnws/q5FnGIaeIh/jmoU0ZlgMYRR8sTlTj+nNGCoJ0RDq6SfxGxCsyMTPmw==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.5.2.tgz", + "integrity": "sha512-jKIdes25AnAH73dOCi2qE6J6vHJ6L2vyBS11M89kT50DVJcLTf2AOjvcc+2vVaN8lUbY5v2R83aqXo3Ro9fqYA==", "dev": true, "license": "MIT", "dependencies": { @@ -4054,20 +4859,20 @@ "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.27.1", "@babel/types": "^7.27.3", - "@jest/expect-utils": "30.4.1", - "@jest/get-type": "30.1.0", - "@jest/snapshot-utils": "30.4.1", - "@jest/transform": "30.4.1", - "@jest/types": "30.4.1", + "@jest/expect-utils": "30.5.2", + "@jest/get-type": "30.5.0", + "@jest/snapshot-utils": "30.5.1", + "@jest/transform": "30.5.2", + "@jest/types": "30.5.1", "babel-preset-current-node-syntax": "^1.2.0", "chalk": "^4.1.2", - "expect": "30.4.1", + "expect": "30.5.2", "graceful-fs": "^4.2.11", - "jest-diff": "30.4.1", - "jest-matcher-utils": "30.4.1", - "jest-message-util": "30.4.1", - "jest-util": "30.4.1", - "pretty-format": "30.4.1", + "jest-diff": "30.5.2", + "jest-matcher-utils": "30.5.2", + "jest-message-util": "30.5.1", + "jest-util": "30.5.1", + "pretty-format": "30.5.1", "semver": "^7.7.2", "synckit": "^0.11.8" }, @@ -4076,13 +4881,13 @@ } }, "node_modules/jest-util": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.4.1.tgz", - "integrity": "sha512-vjQb1sACEiv13DKJMDToJpzVW0joCsIQrmbg0fi7CyOOt+g9jTuQl2A216pWRBYhOVt53XbL/2LbMKg1BECWOw==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.5.1.tgz", + "integrity": "sha512-yKuxmNy2rSbTXw+3SIPanJo+nV4/BS1p26v44IYBFMsswSQySfMMcPHErnOncda7i9HEz0q605rIhSTBVgrZTg==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "30.4.1", + "@jest/types": "30.5.1", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", @@ -4094,18 +4899,18 @@ } }, "node_modules/jest-validate": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-30.4.1.tgz", - "integrity": "sha512-PDWi4SOwLnwqNDfHZjOcsEFyZ4fc/2W2gVL3DEoyqnB6jCQMLRtfBong8s6omIw3lI0HWOus12xfnFmQtjW3fw==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-30.5.1.tgz", + "integrity": "sha512-i/buJ56wTpxihE93hQYNMfdOThS87+HGvLZzZJmU4xggPcdTYQq051iwALLCHp3q+SkCGH+EFejQZz5EbBSkkg==", "dev": true, "license": "MIT", "dependencies": { - "@jest/get-type": "30.1.0", - "@jest/types": "30.4.1", + "@jest/get-type": "30.5.0", + "@jest/types": "30.5.1", "camelcase": "^6.3.0", "chalk": "^4.1.2", "leven": "^3.1.0", - "pretty-format": "30.4.1" + "pretty-format": "30.5.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" @@ -4125,19 +4930,19 @@ } }, "node_modules/jest-watcher": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-30.4.1.tgz", - "integrity": "sha512-/l9UonmvCwjHH7d2h3iAwIloLc1H0S8mJZ/LNK3i86hqwPAz8otUJjP9MfYtz9Tt77Su5FD2xGjZn8d31IZHlw==", + "version": "30.5.2", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-30.5.2.tgz", + "integrity": "sha512-rqRgg4R11GA9m1UsEZwQeixHsgZReCn6TOHAHtIH33yXrIvoX0OGPA20Yzzjkz7X40fZvcRSxEpQppYPcWzmcQ==", "dev": true, "license": "MIT", "dependencies": { - "@jest/test-result": "30.4.1", - "@jest/types": "30.4.1", + "@jest/test-result": "30.5.2", + "@jest/types": "30.5.1", "@types/node": "*", "ansi-escapes": "^4.3.2", "chalk": "^4.1.2", "emittery": "^0.13.1", - "jest-util": "30.4.1", + "jest-util": "30.5.1", "string-length": "^4.0.2" }, "engines": { @@ -4145,15 +4950,15 @@ } }, "node_modules/jest-worker": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.4.1.tgz", - "integrity": "sha512-SHynN/q/QD++iNyvMdy+WMmbCGk8jIsNcRxycXbWubSOhvo6T+j2afcfUSl+3hYsiBebOTo0cT7c2H7CXugu1g==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.5.1.tgz", + "integrity": "sha512-Cbxh5v7AoLuFRmFJSM4/aHdQ68rjXvUWr716EE0Dh3I7T+T/3FgFKhOERGXHcU2Meftq9+9zxPM3TSNyI9D+HA==", "dev": true, "license": "MIT", "dependencies": { "@types/node": "*", "@ungap/structured-clone": "^1.3.0", - "jest-util": "30.4.1", + "jest-util": "30.5.1", "merge-stream": "^2.0.0", "supports-color": "^8.1.1" }, @@ -4185,14 +4990,23 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", - "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.2.tgz", + "integrity": "sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], "license": "MIT", "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" @@ -4211,13 +5025,6 @@ "node": ">=6" } }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true, - "license": "MIT" - }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", @@ -4260,13 +5067,13 @@ } }, "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.6.0.tgz", + "integrity": "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==", "dev": true, "license": "MIT", "dependencies": { - "json-buffer": "3.0.1" + "@keyv/serialize": "^1.1.1" } }, "node_modules/leven": { @@ -4356,16 +5163,6 @@ "dev": true, "license": "ISC" }, - "node_modules/makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "tmpl": "1.0.5" - } - }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -4384,13 +5181,13 @@ } }, "node_modules/minimatch": { - "version": "10.2.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", - "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "version": "10.2.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz", + "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^5.0.5" + "brace-expansion": "^5.0.8" }, "engines": { "node": "18 || 20 || >=22" @@ -4457,9 +5254,9 @@ "license": "MIT" }, "node_modules/nock": { - "version": "14.0.15", - "resolved": "https://registry.npmjs.org/nock/-/nock-14.0.15.tgz", - "integrity": "sha512-S0a47C9pLvcYx/Ugf0H30BVBEcUgMMBDk9VJIDlJ8XGrfH2QDUD4Tgdp45qDIiHttokBG+IbsOtsvIjGR/j3bg==", + "version": "14.0.17", + "resolved": "https://registry.npmjs.org/nock/-/nock-14.0.17.tgz", + "integrity": "sha512-EjRr1weMa4ALQX35AgZTEnP+weJJjlW1KGDiNM2IQC2069YDHas4f4B4UUYR+TTLyKWxJvOz2wObDKQs/LNreA==", "dev": true, "license": "MIT", "dependencies": { @@ -4471,6 +5268,13 @@ "node": ">=18.20.0 <20 || >=20.12.1" } }, + "node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "dev": true, + "license": "MIT" + }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -4479,11 +5283,14 @@ "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.44", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.44.tgz", - "integrity": "sha512-5WUyunoPMsvvEhS8AxHtRzP+oA8UCkJ7YRxatWKjngndhDGLiqEVAQKWjFAiAiuL8zMRGzGSJxFnLetoa43qGQ==", + "version": "2.0.57", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.57.tgz", + "integrity": "sha512-kQK9LGGFiHtrWiNhZtA7Qbw17AQz+dmsEKODRIVTXA9+e5MS/2gZEBhYJt13GrAz5/IOZKddH/0Z3TP/Zgo+yw==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=18" + } }, "node_modules/normalize-path": { "version": "3.0.0", @@ -4648,9 +5455,9 @@ } }, "node_modules/path-scurry/node_modules/lru-cache": { - "version": "11.3.6", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.6.tgz", - "integrity": "sha512-Gf/KoL3C/MlI7Bt0PGI9I+TeTC/I6r/csU58N4BSNc4lppLBeKsOdFYkK+dX0ABDUMJNfCHTyPpzwwO21Awd3A==", + "version": "11.5.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.3.tgz", + "integrity": "sha512-U4N8FgzmWxc8k1VH8Kr6lQg18U7Fjvby6wXHVRX/ZZ7IwWbRMgrRbP0Wrb5q5NVinryp4SQampHKdvtecItxUg==", "dev": true, "license": "BlueOak-1.0.0", "engines": { @@ -4665,9 +5472,9 @@ "license": "ISC" }, "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": { @@ -4767,9 +5574,9 @@ } }, "node_modules/prettier": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.3.tgz", - "integrity": "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==", + "version": "3.9.9", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.9.9.tgz", + "integrity": "sha512-Z/CJHIkdujO/OtN7nXUii0Rf3VT5SRuhjBA82Xvu2XhBUgX3nhP67T0LHceBdQLex7OOFGTox+Q5Yg8Jk2Qivg==", "dev": true, "license": "MIT", "bin": { @@ -4796,16 +5603,16 @@ } }, "node_modules/pretty-format": { - "version": "30.4.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.4.1.tgz", - "integrity": "sha512-K6KiKMHTL4jjX4u3Kir2EW07nRfcqVTXIImx50wbjHQTcZPgg+gjVeNTIT3l3L1Rd4UefxfogquC9J37SoFyyw==", + "version": "30.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.5.1.tgz", + "integrity": "sha512-byhRAPguVKMQIj4kjJwJ5lAskVhfuiSdiYl/aLTWpgkGEmic2jYhJh1yE9ih8Ox44Xg9ccCT11/S6QrzSJuNrg==", "dev": true, "license": "MIT", "dependencies": { - "@jest/schemas": "30.4.1", - "ansi-styles": "^5.2.0", - "react-is-18": "npm:react-is@^18.3.1", - "react-is-19": "npm:react-is@^19.2.5" + "@jest/react-is-18": "npm:react-is@^18.3.1", + "@jest/react-is-19": "npm:react-is@^19.2.5", + "@jest/schemas": "30.5.0", + "ansi-styles": "^5.2.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" @@ -4861,19 +5668,23 @@ ], "license": "MIT" }, - "node_modules/react-is-18": { - "name": "react-is", - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "node_modules/qified": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/qified/-/qified-0.10.1.tgz", + "integrity": "sha512-+Owyggi9IxT1ePKGafcI87ubSmxol6smwJ+RAHDQlx9+9cPwFWDiKFFCPuWhr9ignlGpZ9vDQLw67N4dcTVFEA==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "hookified": "^2.1.1" + }, + "engines": { + "node": ">=20" + } }, - "node_modules/react-is-19": { - "name": "react-is", - "version": "19.2.6", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.6.tgz", - "integrity": "sha512-XjBR15BhXuylgWGuslhDKqlSayuqvqBX91BP8pauG8kd1zY8kotkNWbXksTCNRarse4kuGbe2kIY05ARtwNIvw==", + "node_modules/qified/node_modules/hookified": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/hookified/-/hookified-2.2.0.tgz", + "integrity": "sha512-p/LgFzRN5FeoD3DLS6bkUapeye6E4SI6yJs6KetENd18S+FBthqYq2amJUWpt5z0EQwwHemidjY5OqJGEKm5uA==", "dev": true, "license": "MIT" }, @@ -4921,9 +5732,9 @@ } }, "node_modules/semver": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz", - "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==", + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", "dev": true, "license": "ISC", "bin": { @@ -4964,9 +5775,9 @@ "license": "ISC" }, "node_modules/simple-git-hooks": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/simple-git-hooks/-/simple-git-hooks-2.13.1.tgz", - "integrity": "sha512-WszCLXwT4h2k1ufIXAgsbiTOazqqevFCIncOuUBZJ91DdvWcC5+OFkluWRQPrcuSYd8fjq+o2y1QfWqYMoAToQ==", + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/simple-git-hooks/-/simple-git-hooks-2.14.0.tgz", + "integrity": "sha512-kkTORPAuxQz2g1QUuN0J8yGWT28tjGBfPOdJ4xT7Vbeu30veKUZQIoID2qGgCDAakaQn59UeZJJ4cFGB8PVP2A==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -4994,24 +5805,6 @@ "node": ">=0.10.0" } }, - "node_modules/source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true, - "license": "BSD-3-Clause" - }, "node_modules/stable-hash-x": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/stable-hash-x/-/stable-hash-x-0.2.0.tgz", @@ -5172,9 +5965,9 @@ } }, "node_modules/tinyglobby": { - "version": "0.2.16", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", - "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", "dev": true, "license": "MIT", "dependencies": { @@ -5188,13 +5981,6 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, - "node_modules/tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true, - "license": "BSD-3-Clause" - }, "node_modules/ts-api-utils": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", @@ -5209,9 +5995,9 @@ } }, "node_modules/ts-jest": { - "version": "29.4.11", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.11.tgz", - "integrity": "sha512-IrFl7l9AuB/qrNw5quqvAv/hmKMb8dhWOH4jQOGo0Oq8tCeo1O86/iTFG1FaRimgUkF13l4PcepO8ATFT6Ns4g==", + "version": "29.4.14", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.14.tgz", + "integrity": "sha512-+943G6wCX5E3VpzTQhBGBFntCmdT+QAkTvUlp03edTONFBvqskuXPhpyX16xdUotO4P5HQKyppldSWjocoltLQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5221,7 +6007,7 @@ "json5": "^2.2.3", "lodash.memoize": "^4.1.2", "make-error": "^1.3.6", - "semver": "^7.8.0", + "semver": "^7.8.5", "type-fest": "^4.41.0", "yargs-parser": "^21.1.1" }, @@ -5232,7 +6018,7 @@ "node": "^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0" }, "peerDependencies": { - "@babel/core": ">=7.0.0-beta.0 <8", + "@babel/core": ">=7.0.0-beta.0 <9", "@jest/transform": "^29.0.0 || ^30.0.0", "@jest/types": "^29.0.0 || ^30.0.0", "babel-jest": "^29.0.0 || ^30.0.0", @@ -5319,17 +6105,17 @@ } }, "node_modules/typescript": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "name": "@typescript/typescript6", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript6/-/typescript6-6.0.2.tgz", + "integrity": "sha512-mbCddXd+jm7hfx7w2YU64/Av4/NqqeG3GoRZgxPcgoTxYjhrcfJRw9ULch71SS4G+Q3bOXFhRvPqjguN0Hyp5w==", "dev": true, "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" + "dependencies": { + "@typescript/old": "npm:typescript@^6" }, - "engines": { - "node": ">=14.17" + "bin": { + "tsc6": "bin/tsc6" } }, "node_modules/uglify-js": { @@ -5347,51 +6133,54 @@ } }, "node_modules/undici-types": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz", - "integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==", + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.9.0.tgz", + "integrity": "sha512-KTDyRTYX8sWmKXAikPHHSyc63CRPETMctyjKFupcC6OBLXT3xsN0e9aF7m+mIXutFWpUXuedtowG7iLOzp0kQg==", "dev": true, "license": "MIT" }, "node_modules/unrs-resolver": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.1.tgz", - "integrity": "sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.12.2.tgz", + "integrity": "sha512-dmlRxBJJayXjqTwC+JtF1HhJmgf3ftQ3YejFcZrf4+KKtJv0qDsK1pjqaaVjG7wJ5NJ6UVP1OqRMQ71Z4C3rxQ==", "dev": true, "hasInstallScript": true, "license": "MIT", "dependencies": { - "napi-postinstall": "^0.3.0" + "napi-postinstall": "^0.3.4" }, "funding": { "url": "https://opencollective.com/unrs-resolver" }, "optionalDependencies": { - "@unrs/resolver-binding-android-arm-eabi": "1.11.1", - "@unrs/resolver-binding-android-arm64": "1.11.1", - "@unrs/resolver-binding-darwin-arm64": "1.11.1", - "@unrs/resolver-binding-darwin-x64": "1.11.1", - "@unrs/resolver-binding-freebsd-x64": "1.11.1", - "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.1", - "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.1", - "@unrs/resolver-binding-linux-arm64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-arm64-musl": "1.11.1", - "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-riscv64-musl": "1.11.1", - "@unrs/resolver-binding-linux-s390x-gnu": "1.11.1", - "@unrs/resolver-binding-linux-x64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-x64-musl": "1.11.1", - "@unrs/resolver-binding-wasm32-wasi": "1.11.1", - "@unrs/resolver-binding-win32-arm64-msvc": "1.11.1", - "@unrs/resolver-binding-win32-ia32-msvc": "1.11.1", - "@unrs/resolver-binding-win32-x64-msvc": "1.11.1" + "@unrs/resolver-binding-android-arm-eabi": "1.12.2", + "@unrs/resolver-binding-android-arm64": "1.12.2", + "@unrs/resolver-binding-darwin-arm64": "1.12.2", + "@unrs/resolver-binding-darwin-x64": "1.12.2", + "@unrs/resolver-binding-freebsd-x64": "1.12.2", + "@unrs/resolver-binding-linux-arm-gnueabihf": "1.12.2", + "@unrs/resolver-binding-linux-arm-musleabihf": "1.12.2", + "@unrs/resolver-binding-linux-arm64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-arm64-musl": "1.12.2", + "@unrs/resolver-binding-linux-loong64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-loong64-musl": "1.12.2", + "@unrs/resolver-binding-linux-ppc64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-riscv64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-riscv64-musl": "1.12.2", + "@unrs/resolver-binding-linux-s390x-gnu": "1.12.2", + "@unrs/resolver-binding-linux-x64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-x64-musl": "1.12.2", + "@unrs/resolver-binding-openharmony-arm64": "1.12.2", + "@unrs/resolver-binding-wasm32-wasi": "1.12.2", + "@unrs/resolver-binding-win32-arm64-msvc": "1.12.2", + "@unrs/resolver-binding-win32-ia32-msvc": "1.12.2", + "@unrs/resolver-binding-win32-x64-msvc": "1.12.2" } }, "node_modules/update-browserslist-db": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", - "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.4.tgz", + "integrity": "sha512-t8wonIOdQyOjtPd2VktlBu6QjTVTks6v8bSi7kd0r2Vll8TK1JYDZtRRdbmCHOAMphkZgrzK+L+vXK4pyZ8t4A==", "dev": true, "funding": [ { @@ -5444,16 +6233,6 @@ "node": ">=10.12.0" } }, - "node_modules/walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "makeerror": "1.0.12" - } - }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -5550,9 +6329,9 @@ "license": "ISC" }, "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "version": "17.7.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.3.tgz", + "integrity": "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==", "dev": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 02a76144c..aba68c8be 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "setup-php", - "version": "2.37.2", + "version": "2.40.0", "private": false, "description": "Setup PHP for use with GitHub Actions", "main": "lib/install.js", @@ -20,6 +20,7 @@ "format": "prettier --write **/src/*.ts **/__tests__/*.ts && git add -f __tests__/ ", "format-check": "prettier --check **/src/*.ts **/__tests__/*.ts", "release": "ncc build -m -o dist && git add -f dist/", + "typecheck": "tsc --project tsconfig.test.json --noEmit", "test": "jest" }, "repository": { @@ -38,29 +39,32 @@ "compare-versions": "^6.1.1" }, "devDependencies": { - "@eslint/compat": "^2.1.0", + "@eslint/compat": "^2.1.1", "@eslint/js": "^10.0.1", "@types/jest": "^30.0.0", - "@types/node": "^25.9.2", - "@typescript-eslint/eslint-plugin": "^8.60.1", - "@typescript-eslint/parser": "^8.60.1", - "@vercel/ncc": "^0.38.4", - "eslint": "^10.4.1", + "@types/node": "^26.6.4", + "@typescript-eslint/eslint-plugin": "^8.71.0", + "@typescript-eslint/parser": "^8.71.0", + "@typescript/native": "npm:typescript@^7.0.2", + "@vercel/ncc": "^0.45.0", + "eslint": "^10.12.0", "eslint-config-prettier": "^10.1.8", "eslint-import-resolver-typescript": "^4.4.5", - "eslint-plugin-import-x": "^4.16.2", - "eslint-plugin-jest": "^29.15.2", + "eslint-plugin-import-x": "^4.17.1", + "eslint-plugin-jest": "^29.16.6", "eslint-plugin-prettier": "^5.5.6", - "globals": "^17.6.0", - "jest": "^30.4.2", - "jest-circus": "^30.4.2", - "nock": "^14.0.15", - "prettier": "^3.8.3", - "simple-git-hooks": "^2.13.1", - "ts-jest": "^29.4.11", - "typescript": "^5.9.3" + "globals": "^17.13.0", + "jest": "^30.5.2", + "jest-circus": "^30.5.2", + "nock": "^14.0.17", + "prettier": "^3.9.9", + "simple-git-hooks": "^2.14.0", + "ts-jest": "^29.4.14", + "typescript": "npm:@typescript/typescript6@^6.0.2" }, "overrides": { + "@babel/core": "^7.29.7", + "js-yaml": "^4.2.0", "test-exclude": "^7.0.1", "glob": "^13.0.6", "minimatch": "^10.2.1" @@ -70,5 +74,10 @@ }, "simple-git-hooks": { "pre-commit": "npm run format && npm run lint && npm run test && npm run build && npm run release" + }, + "allowScripts": { + "fsevents@2.3.3": true, + "simple-git-hooks@2.13.1": true, + "unrs-resolver@1.11.1": true } } diff --git a/src/configs/brew_extensions b/src/configs/brew_extensions index dd1c3f4b8..c442c384a 100644 --- a/src/configs/brew_extensions +++ b/src/configs/brew_extensions @@ -8,6 +8,7 @@ event=event excimer=excimer expect=expect gearman=gearman +geos=geos gmagick=gmagick gnupg=gnupg grpc=grpc diff --git a/src/configs/linux_libs b/src/configs/linux_libs index 5d59557ef..81990cb8c 100644 --- a/src/configs/linux_libs +++ b/src/configs/linux_libs @@ -7,6 +7,7 @@ gmagick=graphicsmagick-libmagick-dev-compat gnupg=libgpgme-dev grpc=libgrpc-dev libprotobuf-dev protobuf-compiler imagick=libmagickwand-dev libmagickcore-dev +krb5=libkrb5-dev memcached=libmemcached-dev libevent-dev protobuf=libprotobuf-dev protobuf-compiler rdkafka=librdkafka-dev diff --git a/src/configs/mod_priority b/src/configs/mod_priority index 8a293ac23..859d69600 100644 --- a/src/configs/mod_priority +++ b/src/configs/mod_priority @@ -11,6 +11,7 @@ grpc=30 http=25 pecl_http=25 pecl-http=25 +ibm_db2=40 inotify=30 libvirt-php=40 mailparse=25 diff --git a/src/configs/php-versions.json b/src/configs/php-versions.json index 0ed946cef..c8f7480fb 100644 --- a/src/configs/php-versions.json +++ b/src/configs/php-versions.json @@ -3,7 +3,7 @@ "highest": "8.5", "latest": "8.5", "nightly": "8.6", - "master": "8.6", + "master": "8.7", "5.x": "5.6", "7.x": "7.4", "8.x": "8.5" diff --git a/src/configs/tools.json b/src/configs/tools.json index a339e2c4d..4e0a7852d 100644 --- a/src/configs/tools.json +++ b/src/configs/tools.json @@ -42,6 +42,14 @@ "version_prefix": "", "version_parameter": "diagnose" }, + "cpx": { + "type": "phar", + "repository": "laravel/cpx", + "extension": "", + "domain": "https://github.com", + "version_prefix": "v", + "version_parameter": "--version" + }, "cs2pr": { "type": "phar", "repository": "staabm/annotate-pull-request-from-checkstyle", @@ -234,6 +242,12 @@ "repository": "laravel/vapor-cli", "scope": "scoped" }, + "cloud-cli": { + "type": "composer", + "alias": "laravel-cloud", + "repository": "laravel/cloud-cli", + "scope": "scoped" + }, "rector": { "type": "composer", "repository": "rector/rector", diff --git a/src/extensions.ts b/src/extensions.ts index 41e023ec7..5bf0fcc1b 100644 --- a/src/extensions.ts +++ b/src/extensions.ts @@ -84,12 +84,21 @@ export async function addExtensionDarwin( case /(5\.[3-6]|7\.0)pcov/.test(version_extension): add_script += await utils.getUnsupportedLog('pcov', version, 'darwin'); return; + // match 7.2xdebug2 to 7.4xdebug2 + case /^7\.[2-4]xdebug2$/.test(version_extension): + add_script += await utils.joins( + '\nadd_brew_extension', + 'xdebug2', + ext_prefix, + '2.9.8' + ); + return; // match brew extensions - case /(? { fs.writeFileSync(run_path, script, {mode: 0o755}); - return run_path; + return await utils.addVerbose(run_path, os); } /** diff --git a/src/scripts/darwin.sh b/src/scripts/darwin.sh index f6fe5ea65..ed0c29329 100644 --- a/src/scripts/darwin.sh +++ b/src/scripts/darwin.sh @@ -17,7 +17,7 @@ handle_dependency_extensions() { for dependency_extension in "${dependency_extensions[@]}"; do safe_brew install --skip-link "${brew_opts[@]}" "$ext_tap/$dependency_extension@$version" >/dev/null 2>&1 && brew link --overwrite --force "$dependency_extension@$version" >/dev/null 2>&1 && - copy_brew_extensions "$dependency_extension" + copy_brew_extensions "$dependency_extension" || return $? done fi } @@ -71,25 +71,42 @@ copy_brew_extensions() { fi } +# Install an extension and its variant-specific dependencies with the current Brew state. +install_brew_extension() { + local formula=$1 + local extension=$2 + handle_dependency_extensions "$formula" "$extension" && + safe_brew install --skip-link "${brew_opts[@]}" "$ext_tap/$formula@$version" && + brew link --overwrite --force "$formula@$version" && + copy_brew_extensions "$formula" +} + # Function to install a php extension from shivammathur/extensions tap. add_brew_extension() { formula=$1 prefix=$2 + expected_version=${3:-} extension="$(get_extension_from_formula "$formula")" enable_extension "$extension" "$prefix" - if check_extension "$extension"; then + if check_extension "$extension" && { [ -z "$expected_version" ] || check_extension_version "$extension" "$expected_version"; }; then add_log "${tick:?}" "$extension" "Enabled" else add_brew_tap "$php_tap" add_brew_tap "$ext_tap" formula="$(get_renamed_formula "$formula")" - update_dependencies >/dev/null 2>&1 - handle_dependency_extensions "$formula" "$extension" >/dev/null 2>&1 ( - safe_brew install --skip-link "${brew_opts[@]}" "$ext_tap/$formula@$version" >/dev/null 2>&1 && - brew link --overwrite --force "$formula@$version" >/dev/null 2>&1 && - copy_brew_extensions "$formula" - ) || pecl_install "$extension" >/dev/null 2>&1 + patch_brew + # Keep the watchdog, but refresh before retrying a failed first attempt. + SETUP_PHP_BREW_RETRY_ATTEMPTS=1 install_brew_extension "$formula" "$extension" || { + update_dependencies && install_brew_extension "$formula" "$extension" + } + ) >/dev/null 2>&1 || { + if [ -n "$expected_version" ]; then + pecl_install "$extension-$expected_version" || pecl_install "$extension" + else + pecl_install "$extension" + fi + } >/dev/null 2>&1 add_extension_log "$extension" "Installed and enabled" fi } @@ -150,15 +167,15 @@ patch_brew() { # Function to update dependencies. update_dependencies() { - patch_brew if ! [ -e /tmp/update_dependencies ]; then for repo in "$brew_repo" "${core_repo:?}"; do if [ -e "$repo" ]; then - git_retry -C "$repo" fetch origin main && git -C "$repo" reset --hard origin/main + git_retry -C "$repo" fetch origin main && git -C "$repo" reset --hard origin/main || return $? fi done echo '' | sudo tee /tmp/update_dependencies >/dev/null 2>&1 fi + patch_brew } # Function to get PHP version if it is already installed using Homebrew. @@ -174,27 +191,49 @@ get_brewed_php() { fi } +# Function to setup PHP from the cached builds. +setup_cached_versions() { + latest="releases/download/php-$version" run_script \ + "php-darwin" "$version" "${debug:?}" "${ts:?}" "" "${INPUT_EXTENSIONS:-}" >/dev/null 2>&1 +} + # Function to setup PHP 5.6 and newer using Homebrew. add_php() { + local exit_code php_alias action=$1 existing_version=$2 suffix="$(get_php_formula_suffix)" php_keg="php@$version$suffix" php_formula="shivammathur/php/$php_keg" if [[ "$existing_version" = "false" || -n "$suffix" || "$action" = "upgrade" ]]; then + if [ "$(uname -m)" = "x86_64" ] || { [ "${runner:?}" != "self-hosted" ] && [ "${use_builds_cache:-true}" != "false" ]; }; then + setup_cached_versions && return 0 + [ "$(uname -m)" != "x86_64" ] || return 1 + fi update_dependencies add_brew_tap "$php_tap" fi + # Resolve PHP aliases before invoking brew to avoid scanning unrelated installed formulae. + php_alias="$tap_dir/$php_tap/Aliases/$php_keg" + if [ -L "$php_alias" ]; then + php_keg="$(basename "$(readlink "$php_alias")" .rb)" + php_formula="shivammathur/php/$php_keg" + fi if [[ "$existing_version" != "false" && -z "$suffix" ]]; then if [ "$action" = "upgrade" ]; then - safe_brew install --only-dependencies "$php_formula" - safe_brew upgrade -f --overwrite "$php_formula" + safe_brew install --only-dependencies "$php_formula" || return $? + safe_brew upgrade -f --overwrite "$php_formula" || return $? else brew unlink "$php_keg" fi else - safe_brew install --only-dependencies "$php_formula" - safe_brew install --skip-link -f --overwrite "$php_formula" 2>/dev/null || safe_brew upgrade -f --overwrite "$php_formula" + safe_brew install --only-dependencies "$php_formula" || return $? + safe_brew install --skip-link -f --overwrite "$php_formula" 2>/dev/null || { + exit_code=$? + # A timeout has exhausted its retries; do not start another build via upgrade. + [ "$exit_code" -ne 124 ] || return "$exit_code" + safe_brew upgrade -f --overwrite "$php_formula" || return $? + } fi brew link --force --overwrite "$php_keg" || (sudo chown -R "$(id -un)":"$(id -gn)" "$brew_prefix" && brew link --force --overwrite "$php_keg") } @@ -247,18 +286,24 @@ setup_php() { php_config="$(command -v php-config 2>/dev/null)" update=true check_pre_installed - existing_version=$(get_brewed_php) + existing_version=$([ "$(uname -m)" != "x86_64" ] && get_brewed_php || echo false) status="Found" if [[ "$version" =~ ${old_versions:?} ]]; then run_script "php5-darwin" "${version/./}" >/dev/null 2>&1 status="Installed" - elif [ "${existing_version:0:3}" != "$version" ]; then - add_php "install" "$existing_version" >/dev/null 2>&1 + elif [[ "${existing_version:0:3}" != "$version" || -n "$(get_php_formula_suffix)" ]]; then + add_php "install" "$existing_version" >/dev/null 2>&1 || { + add_log "${cross:?}" "PHP" "Could not install PHP $version" + exit 1 + } status="Installed" elif [[ "${existing_version:0:3}" = "$version" && "${update:?}" = "true" ]]; then brew_php_version="$(brew info --json "php@$version" 2>/dev/null | jq -r '.[].versions.stable')" if [ "$brew_php_version" != "$existing_version" ]; then - add_php "upgrade" "$existing_version" >/dev/null 2>&1 + add_php "upgrade" "$existing_version" >/dev/null 2>&1 || { + add_log "${cross:?}" "PHP" "Could not upgrade PHP $version" + exit 1 + } status="Upgraded" fi fi diff --git a/src/scripts/extensions/add_extensions.ps1 b/src/scripts/extensions/add_extensions.ps1 index cdc2189a7..1626d89fd 100644 --- a/src/scripts/extensions/add_extensions.ps1 +++ b/src/scripts/extensions/add_extensions.ps1 @@ -104,11 +104,50 @@ Function Add-Extension { [string] $extension_version = '' ) + $extension_backup = '' + $restore_startup_errors = $false try { - $extension_info = Get-PhpExtension -Path $php_dir | Where-Object { $_.Name -eq $extension -or $_.Handle -eq $extension } $deps_dir = "$ext_dir\$extension-vc$($installed.VCVersion)-$arch" New-Item $deps_dir -Type Directory -Force > $null 2>&1 - if ($null -ne $extension_info) { + $cached = $extension_version -ne '' -and (Test-Path "$ext_dir\$extension-$extension_version") + $extension_info = $null + if(-not $cached) { + $extension_info = Get-PhpExtension -Path $php_dir | Where-Object { $_.Name -eq $extension -or $_.Handle -eq $extension } + } + # Only suppress startup errors while probing a cached DLL or replacing an installed DLL. + if($cached -or ($extension_version -ne '' -and $extension_info.Version -ne $extension_version -and (Test-Path "$ext_dir\php_$extension.dll"))) { + $startup_errors = Get-PhpIniKey -Key display_startup_errors -Path "$php_dir\php.ini" + if($startup_errors -notmatch '^(0|off|false|no)$') { + $restore_startup_errors = $true + Set-PhpIniKey -Key display_startup_errors -Value Off -Path "$php_dir\php.ini" + } + } + if($cached) { + # Preserve the active DLL before probing a cache entry for another PHP build. + if(Test-Path "$ext_dir\php_$extension.dll") { + $extension_info = Get-PhpExtension -Path "$ext_dir\php_$extension.dll" + $backup_name = if($extension_info.Version) { "$extension-$($extension_info.Version)" } else { "$extension.bak" } + Copy-Item "$ext_dir\php_$extension.dll" "$ext_dir\$backup_name" -Force -ErrorAction Stop + $extension_backup = "$ext_dir\$backup_name" + } + Copy-Item "$ext_dir\$extension-$extension_version" "$ext_dir\php_$extension.dll" -Force + try { + Enable-ExtensionDependencies $extension + Enable-PhpExtension -Extension $extension -Path $php_dir + Set-ExtensionPrerequisites $extension + $cached_extension = Get-PhpExtension -Path $php_dir | Where-Object { ($_.Name -eq $extension -or $_.Handle -eq $extension) -and $_.State -eq 'Enabled' } + if($null -ne $cached_extension) { + Add-Log $tick $extension "Enabled" + return + } + } catch { + Write-Verbose "Could not enable cached ${extension}: $_" + } + # A cached DLL may target another PHP build; install it again if it did not load. + Remove-Item "$ext_dir\php_$extension.dll" -Force + $extension_info = $null + } + if ($null -ne $extension_info -and ($extension_version -eq '' -or $extension_info.Version -eq $extension_version)) { switch ($extension_info.State) { 'Builtin' { Add-Log $tick $extension "Enabled" @@ -138,15 +177,32 @@ Function Add-Extension { } # If extension for a different version exists if(Test-Path $ext_dir\php_$extension.dll) { - Move-Item $ext_dir\php_$extension.dll $ext_dir\php_$extension.bak.dll -Force + # Keep backups outside PhpManager's DLL scan and reuse known versions as cache entries. + $backup_name = if($extension_info.Version) { "$extension-$($extension_info.Version)" } else { "$extension.bak" } + Move-Item $ext_dir\php_$extension.dll "$ext_dir\$backup_name" -Force -ErrorAction Stop + $extension_backup = "$ext_dir\$backup_name" } Install-PhpExtension @params Set-ExtensionPrerequisites $extension } Add-Log $tick $extension "Installed and enabled" } + if($extension_version -ne '' -and (Test-Path "$ext_dir\php_$extension.dll")) { + Copy-Item "$ext_dir\php_$extension.dll" "$ext_dir\$extension-$extension_version" -Force + } } catch { + if($extension_backup -ne '') { + Copy-Item $extension_backup "$ext_dir\php_$extension.dll" -Force + } Add-Log $cross $extension "Could not install $extension on PHP $( $installed.FullVersion )" + } finally { + if($restore_startup_errors) { + if($null -eq $startup_errors) { + Set-PhpIniKey -Key display_startup_errors -Delete -Path "$php_dir\php.ini" + } else { + Set-PhpIniKey -Key display_startup_errors -Value $startup_errors -Path "$php_dir\php.ini" + } + } } } diff --git a/src/scripts/extensions/add_extensions.sh b/src/scripts/extensions/add_extensions.sh index b4e27b78b..46b862ced 100644 --- a/src/scripts/extensions/add_extensions.sh +++ b/src/scripts/extensions/add_extensions.sh @@ -21,6 +21,13 @@ check_extension() { fi } +# Function to test the loaded version of an extension. +check_extension_version() { + local extension=$1 + local ext_version=$2 + php -d display_errors=0 -r "exit(phpversion(\$argv[1]) === \$argv[2] ? 0 : 1);" -- "$extension" "$ext_version" >/dev/null 2>&1 +} + # Function to check if extension is shared shared_extension() { [ -e "${ext_dir:?}/$1.so" ] @@ -188,17 +195,18 @@ pecl_install() { check_extension "${extension%-*}" && return 0 || return 1; else cpu_count="$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo '1')" - prefix_opts="$(parse_args "$extension" CONFIGURE_PREFIX_OPTS) MAKEFLAGS='-j $cpu_count'" + local prefix_opts=() + IFS=' ' read -r -a prefix_opts <<<"$(parse_args "$extension" CONFIGURE_PREFIX_OPTS)" suffix_opts="$(parse_args "$extension" CONFIGURE_OPTS) $(parse_args "$extension" CONFIGURE_SUFFIX_OPTS)" IFS=' ' read -r -a libraries <<<"$(parse_args "$extension" LIBS) $(parse_args "$extension" "$(uname -s)"_LIBS)" (( ${#libraries[@]} )) && add_libs "${libraries[@]}" >/dev/null 2>&1 if [ "$version" = "5.3" ]; then - yes '' 2>/dev/null | sudo "$prefix_opts" pecl install -f "$extension" >/dev/null 2>&1 + yes '' 2>/dev/null | sudo env "${prefix_opts[@]}" MAKEFLAGS="-j $cpu_count" pecl install -f "$extension" >/dev/null 2>&1 else - yes '' 2>/dev/null | sudo "$prefix_opts" pecl install -f -D "$(parse_pecl_configure_options "$suffix_opts")" "$extension" >/dev/null 2>&1 + yes '' 2>/dev/null | sudo env "${prefix_opts[@]}" MAKEFLAGS="-j $cpu_count" pecl install -f -D "$(parse_pecl_configure_options "$suffix_opts")" "$extension" >/dev/null 2>&1 fi local exit_code=$? - sudo pecl info "$extension" | grep -iq 'zend extension' && prefix=zend_extension + sudo pecl info "$extension" 2>/dev/null | grep -iq 'zend extension' && prefix=zend_extension enable_extension "${extension%-*}" "$prefix" return "$exit_code" fi @@ -209,17 +217,27 @@ add_pecl_extension() { local extension=$1 local pecl_version=$2 local prefix=$3 - enable_extension "$extension" "$prefix" if [[ $pecl_version =~ .*(alpha|beta|rc|snapshot|preview).* ]]; then pecl_version=$(get_pecl_version "$extension" "$pecl_version") fi - ext_version=$(php -r "echo phpversion('$extension');") + # Cache versioned extensions using suffixless copies in extension_dir. + if [ -n "$pecl_version" ] && [ -e "${ext_dir:?}/$extension-$pecl_version" ]; then + sudo cp "${ext_dir:?}/$extension-$pecl_version" "${ext_dir:?}/$extension.so" + sudo rm -f /tmp/php"${version:?}"_extensions + fi + enable_extension "$extension" "$prefix" + ext_version=$(php -d display_errors=0 -r "echo phpversion('$extension');" 2>/dev/null) if check_extension "$extension" && [[ -z "$pecl_version" || (-n "$pecl_version" && "${ext_version/-/}" == "$pecl_version") ]]; then + [ -n "$pecl_version" ] && sudo cp "${ext_dir:?}/$extension.so" "${ext_dir:?}/$extension-$pecl_version" 2>/dev/null || true add_log "${tick:?}" "$extension" "Enabled" else + [ -n "$pecl_version" ] && sudo rm -f "${ext_dir:?}/$extension-$pecl_version" [ -n "$pecl_version" ] && pecl_version="-$pecl_version" pecl_install "$extension$pecl_version" || ( [ "${fail_fast:?}" = "false" ] && add_extension "$extension" "$(get_extension_prefix "$extension")" >/dev/null 2>&1) extension_version="$(php -r "echo phpversion('$extension');")" + if [ -n "$pecl_version" ] && [ "${extension_version/-/}" = "${pecl_version#-}" ]; then + sudo cp "${ext_dir:?}/$extension.so" "${ext_dir:?}/$extension-$extension_version" 2>/dev/null || true + fi [ -n "$extension_version" ] && extension_version="-$extension_version" add_extension_log "$extension$extension_version" "Installed and enabled" fi diff --git a/src/scripts/extensions/couchbase.sh b/src/scripts/extensions/couchbase.sh index ef4b87629..78a5bd7b3 100644 --- a/src/scripts/extensions/couchbase.sh +++ b/src/scripts/extensions/couchbase.sh @@ -7,8 +7,8 @@ add_couchbase_clibs() { else release=$(get -s -n "" "$trunk"/latest | grep -Eo -m 1 "[0-9]+\.[0-9]+\.[0-9]+" | head -n 1) fi - [ "$VERSION_ID" = "24.04" ] && vid=22.04 || vid="$VERSION_ID" - [ "$VERSION_CODENAME" = "noble" ] && vcn=jammy || vcn="$VERSION_CODENAME" + [[ "$VERSION_ID" = "24.04" || "$VERSION_ID" = "26.04" ]] && vid=22.04 || vid="$VERSION_ID" + [[ "$VERSION_CODENAME" = "noble" || "$VERSION_CODENAME" = "resolute" ]] && vcn=jammy || vcn="$VERSION_CODENAME" deb_url="$trunk/download/$release/libcouchbase-${release}_ubuntu${vid/./}_${vcn}_amd64.tar" get -q -n /tmp/libcouchbase.tar "$deb_url" if ! [ -e /tmp/libcouchbase.tar ] || ! file /tmp/libcouchbase.tar | grep -q 'tar archive'; then @@ -22,9 +22,9 @@ add_couchbase_clibs() { } add_old_libssl() { - if [[ "$VERSION_ID" = "24.04" ]]; then + if [[ "$VERSION_ID" = "24.04" || "$VERSION_ID" = "26.04" ]]; then get -q -n /tmp/libssl.deb http://archive.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2_amd64.deb - [ -e /tmp/libssl.deb ] && sudo dpkg -i /tmp/libssl.deb || add_extension_log "couchbase" "Could not install libssl1.1" + ([ -e /tmp/libssl.deb ] && sudo dpkg -i /tmp/libssl.deb) || add_extension_log "couchbase" "Could not install libssl1.1" fi } @@ -59,22 +59,32 @@ add_couchbase() { ext=$(get_couchbase_version) fi if [[ "$ext" =~ couchbase-[2-3].+ ]]; then + export COUCHBASE_CONFIGURE_PREFIX_OPTS="${COUCHBASE_CONFIGURE_PREFIX_OPTS:-} SED=sed CFLAGS=-Wno-error=incompatible-pointer-types" add_couchbase_clibs "$ext" >/dev/null 2>&1 else add_couchbase_cxxlibs >/dev/null 2>&1 + if [[ "$ext" =~ ^couchbase-4\.1\. ]]; then + export COUCHBASE_CONFIGURE_PREFIX_OPTS="${COUCHBASE_CONFIGURE_PREFIX_OPTS:-} COUCHBASE_CMAKE_EXTRA=-DCMAKE_POLICY_VERSION_MINIMUM=3.5" + fi fi enable_extension "couchbase" "extension" if check_extension "couchbase"; then add_log "${tick:?}" "couchbase" "Enabled" else + local install_method=pecl_install if [ "$ext" = "couchbase" ]; then ext="couchbase-$(get_pecl_version "couchbase" "stable")" n_proc="$(nproc)" export COUCHBASE_SUFFIX_OPTS="CMAKE_BUILD_TYPE=Release" export CMAKE_BUILD_PARALLEL_LEVEL="$n_proc" + install_method=add_extension_from_source + elif [[ "$ext" =~ ^couchbase-4\.1\. ]]; then + install_method=add_extension_from_source + fi + if [ "$install_method" = add_extension_from_source ]; then add_extension_from_source couchbase https://pecl.php.net couchbase couchbase "${ext##*-}" extension pecl >/dev/null 2>&1 else - pecl_install "${ext}" >/dev/null 2>&1 + "$install_method" "${ext}" >/dev/null 2>&1 fi add_extension_log "couchbase" "Installed and enabled" fi diff --git a/src/scripts/extensions/geos.sh b/src/scripts/extensions/geos.sh index c685f8664..9bb031a70 100644 --- a/src/scripts/extensions/geos.sh +++ b/src/scripts/extensions/geos.sh @@ -1,8 +1,12 @@ # Helper function to compile and install geos add_geos_helper() { - export GEOS_LINUX_LIBS='libgeos-dev' - export GEOS_DARWIN_LIBS='geos' - add_extension_from_source geos https://github.com libgeos php-geos 1.0.0 extension get + if [[ "$os" = "Linux" || "${version:?}" =~ 5.[3-5] ]]; then + export GEOS_LINUX_LIBS='libgeos-dev' + export GEOS_DARWIN_LIBS='geos' + add_extension_from_source geos https://github.com libgeos php-geos 1.0.0 extension get + else + add_brew_extension geos extension + fi } # Function to add geos @@ -15,3 +19,5 @@ add_geos() { add_extension_log "geos" "Installed and enabled" fi } + +os="$(uname -s)" diff --git a/src/scripts/extensions/ibm.sh b/src/scripts/extensions/ibm.sh index cd2c62574..302487123 100644 --- a/src/scripts/extensions/ibm.sh +++ b/src/scripts/extensions/ibm.sh @@ -35,6 +35,15 @@ get_cli_archive() { esac } +# Function to add the libxml2 ABI name expected by the IBM Db2 CLI driver. +add_ibm_libxml2_link() { + local libxml2 + if ! ldconfig -p 2>/dev/null | grep -q 'libxml2\.so\.2 '; then + libxml2=$(ldconfig -p 2>/dev/null | awk '$1 == "libxml2.so.16" {print $NF; exit}') + [ -n "$libxml2" ] && sudo ln -sfn "$libxml2" "$(dirname "$libxml2")/libxml2.so.2" + fi +} + # Function to install IBM Db2 CLI driver. add_cli_driver() { local os arch archive url tmp libs @@ -58,6 +67,7 @@ add_cli_driver() { if [ "$os" = "Linux" ]; then echo "$ibm_cli/lib" | sudo tee /etc/ld.so.conf.d/ibm_db2.conf >/dev/null sudo ldconfig + add_ibm_libxml2_link else libs='/usr/local/lib' sudo mkdir -p "$libs" @@ -78,6 +88,7 @@ add_ibm_helper() { else configure_flag="--with-pdo-ibm=$IBM_DB_HOME" fi + read -r "${ext}_CONFIGURE_PREFIX_OPTS" <<< "SED=sed" read -r "${ext}_CONFIGURE_OPTS" <<< "--with-php-config=$(command -v php-config) $configure_flag" patch_phpize add_extension_from_source "$ext" https://github.com php "pecl-database-$ext" master extension get diff --git a/src/scripts/extensions/oci.sh b/src/scripts/extensions/oci.sh index 929ffc2cd..a829b77f4 100644 --- a/src/scripts/extensions/oci.sh +++ b/src/scripts/extensions/oci.sh @@ -37,6 +37,10 @@ add_client() { for icdir in /opt/oracle/instantclient_*; do sudo mv "$icdir"/* "$oracle_client"/ done + if [ "$os" = "Linux" ]; then + client_library=$(find "$oracle_client" -maxdepth 1 -type f -name 'libclntsh.so.*.1' | sort -V | tail -n1) + [ -n "$client_library" ] && sudo ln -sfn "${client_library##*/}" "$oracle_client/libclntsh.so" + fi sudo mkdir -p "$libs" sudo ln -sf /opt/oracle/instantclient/*."$lib_ext"* "$libs" if [ "$os" = "Linux" ]; then @@ -49,7 +53,13 @@ add_client() { add_oci_helper() { if ! shared_extension "$ext"; then status='Installed and enabled' - read -r "${ext}_CONFIGURE_PREFIX_OPTS" <<< "CFLAGS=-Wno-incompatible-function-pointer-types" + local compatibility_flag + if [ "$os" = "Linux" ]; then + compatibility_flag='-Wno-error=incompatible-pointer-types' + else + compatibility_flag='-Wno-incompatible-function-pointer-types' + fi + read -r "${ext}_CONFIGURE_PREFIX_OPTS" <<< "SED=sed CFLAGS=$compatibility_flag" read -r "${ext}_LINUX_LIBS" <<< "libaio-dev" read -r "${ext}_CONFIGURE_OPTS" <<< "--with-php-config=$(command -v php-config) --with-${ext/_/-}=instantclient,$oracle_client" patch_phpize diff --git a/src/scripts/extensions/patches/couchbase.sh b/src/scripts/extensions/patches/couchbase.sh new file mode 100644 index 000000000..8629d8fc5 --- /dev/null +++ b/src/scripts/extensions/patches/couchbase.sh @@ -0,0 +1,12 @@ +patch_couchbase() { + local operation_queue query_index_manager + operation_queue=src/deps/couchbase-cxx-client/core/mcbp/operation_queue.cxx + query_index_manager=src/deps/couchbase-cxx-client/core/impl/query_index_manager.cxx + if [ -e "$operation_queue" ] && ! grep -q '^#include ' "$operation_queue"; then + sed -i.bak '/^#include /i#include ' "$operation_queue" + fi + if [ -e "$query_index_manager" ] && ! grep -q '^#include ' "$query_index_manager"; then + sed -i.bak '/^#include /i#include ' "$query_index_manager" + fi + rm -f "$operation_queue.bak" "$query_index_manager.bak" +} diff --git a/src/scripts/extensions/patches/geos.sh b/src/scripts/extensions/patches/geos.sh index 170e1f407..48a5ee173 100644 --- a/src/scripts/extensions/patches/geos.sh +++ b/src/scripts/extensions/patches/geos.sh @@ -2,8 +2,8 @@ patch_geos() { if [[ $(printf '%s\n%s\n' "${version:?}" "7.0" | sort -V | head -n1) == "7.0" ]]; then sed -i~ -e "s/, ce->name/, ZSTR_VAL(ce->name)/; s/ulong /zend_ulong /" geos.c fi - get -q -n /tmp/php8.patch https://git.remirepo.net/cgit/rpms/php/php-geos.git/plain/0003-add-all-arginfo-and-fix-build-with-PHP-8.patch - get -q -n /tmp/toString.patch https://git.remirepo.net/cgit/rpms/php/php-geos.git/plain/0006-fix-__toString-with-8.2.patch + get -q -n /tmp/php8.patch https://src.fedoraproject.org/rpms/php-geos/raw/2021845a362752948dd0338920f0a0e6b1031b4d/f/0003-add-all-arginfo-and-fix-build-with-PHP-8.patch + get -q -n /tmp/toString.patch https://src.fedoraproject.org/rpms/php-geos/raw/2021845a362752948dd0338920f0a0e6b1031b4d/f/0006-fix-__toString-with-8.2.patch patch -p1 < /tmp/php8.patch 2>/dev/null || true patch -p1 < /tmp/toString.patch 2>/dev/null || true } diff --git a/src/scripts/extensions/relay.sh b/src/scripts/extensions/relay.sh index 08f0abe6c..c8c27c269 100644 --- a/src/scripts/extensions/relay.sh +++ b/src/scripts/extensions/relay.sh @@ -35,7 +35,7 @@ get_openssl_suffix() { # Change library paths in relay binary. change_library_paths() { if [ "$os" = "Darwin" ]; then - otool -L "${ext_dir:?}"/relay.so | grep -q 'ssl.1' && openssl_version='1.1' || openssl_version='3' + otool -L "${ext_dir:?}"/relay.so | grep -q 'ssl.3.' && openssl_version='3' || openssl_version='1.1' [ -e "${brew_prefix:?}"/opt/openssl@"$openssl_version" ] || { safe_brew install --skip-link openssl@"$openssl_version" && brew link --overwrite --force openssl@"$openssl_version" @@ -63,6 +63,10 @@ add_relay_dependencies() { # Initialize relay extension ini configuration init_relay_ini() { + without_trace init_relay_ini_helper "$@" +} + +init_relay_ini_helper() { relay_ini=$1 if [ -e "$relay_ini" ]; then if [[ -n "$RELAY_KEY" ]]; then diff --git a/src/scripts/linux.sh b/src/scripts/linux.sh index 9276484d4..3187e6da8 100644 --- a/src/scripts/linux.sh +++ b/src/scripts/linux.sh @@ -226,7 +226,7 @@ update_php() { # Function to install PHP. add_php() { - if [ "${runner:?}" = "self-hosted" ] || [ "${use_package_cache:-true}" = "false" ]; then + if [ "${runner:?}" = "self-hosted" ] || [ "${use_builds_cache:-true}" = "false" ]; then if [[ "$version" =~ ${php_builder_versions:?} || "$ts" = "zts" ]]; then setup_php_builder else @@ -285,6 +285,9 @@ add_php_config() { # Function to Setup PHP setup_php() { step_log "Setup PHP" + if [ "${builds_cache_warning:-false}" = "true" ]; then + add_log "!" "PHP" "Cached PHP builds are experimental on this runner and may fail to install" + fi sudo mkdir -m 777 -p /var/run /run/php php_config="$(command -v php-config)" check_pre_installed diff --git a/src/scripts/tools/add_tools.ps1 b/src/scripts/tools/add_tools.ps1 index 918e59280..04aea38ff 100644 --- a/src/scripts/tools/add_tools.ps1 +++ b/src/scripts/tools/add_tools.ps1 @@ -87,36 +87,38 @@ Function Write-ComposerGhAuthNoOpWarning() { # Function to setup authentication in composer. Function Set-ComposerAuth() { - $token = if ($env:COMPOSER_TOKEN) { $env:COMPOSER_TOKEN } else { $env:GITHUB_TOKEN } - if(Test-Path env:COMPOSER_AUTH_JSON) { - if(Test-Json -JSON $env:COMPOSER_AUTH_JSON) { - Set-Content -Path $composer_home\auth.json -Value $env:COMPOSER_AUTH_JSON - } else { - Add-Log "$cross" "composer" "Could not parse COMPOSER_AUTH_JSON as valid JSON" + Invoke-WithoutTrace { + $token = if ($env:COMPOSER_TOKEN) { $env:COMPOSER_TOKEN } else { $env:GITHUB_TOKEN } + if(Test-Path env:COMPOSER_AUTH_JSON) { + if(Test-Json -JSON $env:COMPOSER_AUTH_JSON) { + Set-Content -Path $composer_home\auth.json -Value $env:COMPOSER_AUTH_JSON + } else { + Add-Log "$cross" "composer" "Could not parse COMPOSER_AUTH_JSON as valid JSON" + } } - } - if($skip_composer_github_auth) { - Write-ComposerGhAuthNoOpWarning - } - $composer_auth = @() - if(Test-Path env:PACKAGIST_TOKEN) { - $composer_auth += '"http-basic": {"repo.packagist.com": { "username": "token", "password": "' + $env:PACKAGIST_TOKEN + '"}}' - } - $write_token = $true - if ($token) { - if ($skip_composer_github_auth) { - $write_token = $false + if($skip_composer_github_auth) { + Write-ComposerGhAuthNoOpWarning } - if ($env:GITHUB_SERVER_URL -ne "https://github.com" -and -not(Test-GitHubPublicAccess $token)) { - $write_token = $false + $composer_auth = @() + if(Test-Path env:PACKAGIST_TOKEN) { + $composer_auth += '"http-basic": {"repo.packagist.com": { "username": "token", "password": "' + $env:PACKAGIST_TOKEN + '"}}' + } + $write_token = $true + if ($token) { + if ($skip_composer_github_auth) { + $write_token = $false + } + if ($env:GITHUB_SERVER_URL -ne "https://github.com" -and -not(Test-GitHubPublicAccess $token)) { + $write_token = $false + } + if($write_token) { + $composer_auth += '"github-oauth": {"github.com": "' + $token + '"}' + } } - if($write_token) { - $composer_auth += '"github-oauth": {"github.com": "' + $token + '"}' + if($composer_auth.length) { + Update-AuthJson $composer_auth } } - if($composer_auth.length) { - Update-AuthJson $composer_auth - } } # Function to set composer environment variables. @@ -144,6 +146,21 @@ Function Test-MutableToolUrl() { return ($Url -match $mutableUrlRegex) -or (($Url -match '\.phar([?#].*)?$') -and -not ($Url -match $versionLikeRegex)) } +# Function to verify the checksum of a file. +Function Test-ToolChecksum() { + Param( + [Parameter(Position = 0, Mandatory = $true)] + [string] + $Path, + [Parameter(Position = 1, Mandatory = $true)] + [string] + $Checksum + ) + $checksum_parts = $Checksum -split ':' + $actual_checksum = (Get-FileHash -Path $Path -Algorithm $checksum_parts[0]).Hash + return $actual_checksum -eq $checksum_parts[1] +} + # Function to extract tool version. Function Get-ToolVersion() { Param ( @@ -206,6 +223,9 @@ Function Add-ToolsHelper() { $extensions += @('dom', 'json', 'libxml', 'mbstring', 'xml', 'xmlwriter') } elseif($tool -eq "phpunit-bridge") { $extensions += @('dom', 'pdo', 'tokenizer', 'xmlwriter') + } elseif($tool -eq "cloud-cli") { + $extensions += @('fileinfo', 'sockets') + Copy-Item $env:cloud_cli_bin\cloud.bat -Destination $env:cloud_cli_bin\cloud-cli.bat } elseif($tool -eq "vapor-cli") { $extensions += @('fileinfo', 'json', 'mbstring', 'zip', 'simplexml') Copy-Item $env:vapor_cli_bin\vapor.bat -Destination $env:vapor_cli_bin\vapor-cli.bat @@ -229,8 +249,18 @@ Function Add-Tool() { [Parameter(Position = 2, Mandatory = $false)] $ver_param, [Parameter(Position = 3, Mandatory = $false)] - $skip_composer_github_auth + $skip_composer_github_auth, + [Parameter(Position = 4, Mandatory = $false)] + $checksum ) + $checksum_regex = '^sha(256|512):[0-9a-fA-F]+$' + if("$ver_param" -match $checksum_regex) { + $checksum = $ver_param + $ver_param = $null + } elseif("$skip_composer_github_auth" -match $checksum_regex) { + $checksum = $skip_composer_github_auth + $skip_composer_github_auth = $null + } if($tool -eq "composer") { $script:skip_composer_github_auth = $skip_composer_github_auth -eq 'true' } @@ -245,7 +275,12 @@ Function Add-Tool() { $use_cache = -not (Test-MutableToolUrl $urls[0]) $status_code = 200 if ($use_cache -and (Test-Path $cache_path -PathType Leaf)) { - Copy-Item $cache_path -Destination $tool_path -Force + if($checksum -and -not(Test-ToolChecksum $cache_path $checksum)) { + Remove-Item $cache_path -Force -ErrorAction SilentlyContinue + $status_code = 'checksum_mismatch' + } else { + Copy-Item $cache_path -Destination $tool_path -Force + } } else { $backup_path = "$tool_path.bak" if (Test-Path $tool_path) { Copy-Item $tool_path -Destination $backup_path -Force } @@ -265,18 +300,31 @@ Function Add-Tool() { } } if($status_code -eq 200 -and (Test-Path $tool_path)) { - if ($use_cache) { - Copy-Item $tool_path -Destination $cache_path -Force - } break } } + if($status_code -eq 200 -and (Test-Path $tool_path)) { + if($checksum -and -not(Test-ToolChecksum $tool_path $checksum)) { + Remove-Item @($tool_path, $cache_path) -Force -ErrorAction SilentlyContinue + $status_code = 'checksum_mismatch' + } elseif($use_cache) { + Copy-Item $tool_path -Destination $cache_path -Force + } + } if ($status_code -ne 200 -and (Test-Path $backup_path)) { Copy-Item $backup_path -Destination $tool_path -Force } Remove-Item $backup_path -Force -ErrorAction SilentlyContinue } + if($status_code -eq 'checksum_mismatch') { + if($tool -eq "composer") { + $env:fail_fast = 'true' + } + Add-Log $cross $tool "Checksum verification failed for $tool" + return + } + $escaped_tool = [regex]::Escape($tool) if (((Get-ChildItem -Path $bin_dir/* | Where-Object Name -Match "^$escaped_tool(\.exe|\.phar)?$").Count -gt 0)) { $bat_content = @() diff --git a/src/scripts/tools/add_tools.sh b/src/scripts/tools/add_tools.sh index d8deb299b..732caa529 100644 --- a/src/scripts/tools/add_tools.sh +++ b/src/scripts/tools/add_tools.sh @@ -85,6 +85,10 @@ composer_gh_auth_no_op() { # Function to setup authentication in composer. set_composer_auth() { + without_trace set_composer_auth_helper +} + +set_composer_auth_helper() { token="${COMPOSER_TOKEN:-$GITHUB_TOKEN}" if [ -n "${COMPOSER_AUTH_JSON:-}" ]; then if printf '%s' "$COMPOSER_AUTH_JSON" | jq -e . >/dev/null; then @@ -185,6 +189,9 @@ add_tools_helper() { if [ -e "$tool_path_dir"/phpunit ] && [ -d "$composer_bin" ]; then sudo cp "$tool_path_dir"/phpunit "$composer_bin" fi + elif [ "$tool" = "cloud-cli" ]; then + extensions+=(dom fileinfo iconv sockets tokenizer) + sudo ln -s "$scoped_dir"/vendor/bin/cloud "$scoped_dir"/vendor/bin/cloud-cli 2>/dev/null || true elif [ "$tool" = "vapor-cli" ]; then extensions+=(fileinfo json mbstring zip simplexml) sudo ln -s "$scoped_dir"/vendor/bin/vapor "$scoped_dir"/vendor/bin/vapor-cli 2>/dev/null || true @@ -201,8 +208,15 @@ add_tool() { url=$1 tool=$2 ver_param=$3 + checksum= + local arg + for arg in "$@"; do + [[ "$arg" =~ ^sha(256|512):[0-9a-fA-F]+$ ]] && checksum="$arg" + done + [[ "$ver_param" =~ ^sha(256|512): ]] && ver_param= if [ "$tool" = "composer" ]; then skip_composer_github_auth="${4:-false}" + [[ "$skip_composer_github_auth" =~ ^sha(256|512): ]] && skip_composer_github_auth=false fi tool_path="$tool_path_dir/$tool" if ! [ -d "$tool_path_dir" ]; then @@ -220,7 +234,12 @@ add_tool() { is_mutable_tool_url "${url[0]}" && use_cache=false status_code="200" if [ "$use_cache" = "true" ] && [ -f "$cache_path" ]; then - sudo cp -a "$cache_path" "$tool_path" + if [ -n "$checksum" ] && ! verify_checksum "$cache_path" "$checksum"; then + sudo rm -f "$cache_path" + status_code="checksum_mismatch" + else + sudo cp -a "$cache_path" "$tool_path" + fi else [ -f "$tool_path" ] && sudo cp -a "$tool_path" "$tool_path.bak" status_code=$(get -v -e "$tool_path" "${url[@]}") @@ -229,8 +248,14 @@ add_tool() { status_code=$(get -v -e "$tool_path" "${url[0]}") fi if [ "$status_code" = "200" ]; then - [ "$use_cache" = "true" ] && sudo cp -a "$tool_path" "$cache_path" - elif [ -f "$tool_path.bak" ]; then + if [ -n "$checksum" ] && ! verify_checksum "$tool_path" "$checksum"; then + sudo rm -f "$tool_path" "$cache_path" + status_code="checksum_mismatch" + elif [ "$use_cache" = "true" ]; then + sudo cp -a "$tool_path" "$cache_path" + fi + fi + if [ "$status_code" != "200" ] && [ -f "$tool_path.bak" ]; then sudo mv "$tool_path.bak" "$tool_path" fi sudo rm -f "$tool_path.bak" @@ -244,7 +269,9 @@ add_tool() { if [ "$tool" = "composer" ]; then export fail_fast=true fi - if [ "$status_code" = "404" ]; then + if [ "$status_code" = "checksum_mismatch" ]; then + add_log "$cross" "$tool" "Checksum verification failed for $tool" + elif [ "$status_code" = "404" ]; then add_log "$cross" "$tool" "Failed to download $tool from ${url[*]}" else add_log "$cross" "$tool" "Could not setup $tool" diff --git a/src/scripts/tools/blackfire.ps1 b/src/scripts/tools/blackfire.ps1 index 4427ef7d8..286bf111e 100644 --- a/src/scripts/tools/blackfire.ps1 +++ b/src/scripts/tools/blackfire.ps1 @@ -9,11 +9,13 @@ Function Add-Blackfire() { Get-File -Url $url -OutFile $bin_dir\blackfire.zip >$null 2>&1 Expand-Archive -Path $bin_dir\blackfire.zip -DestinationPath $bin_dir -Force >$null 2>&1 Add-ToProfile $current_profile 'blackfire' "New-Alias blackfire $bin_dir\blackfire.exe" - if ((Test-Path env:BLACKFIRE_SERVER_ID) -and (Test-Path env:BLACKFIRE_SERVER_TOKEN)) { - blackfire agent:config --server-id=$env:BLACKFIRE_SERVER_ID --server-token=$env:BLACKFIRE_SERVER_TOKEN >$null 2>&1 - } - if ((Test-Path env:BLACKFIRE_CLIENT_ID) -and (Test-Path env:BLACKFIRE_CLIENT_TOKEN)) { - blackfire client:config --client-id=$env:BLACKFIRE_CLIENT_ID --client-token=$env:BLACKFIRE_CLIENT_TOKEN --ca-cert=$php_dir\ssl\cacert.pem >$null 2>&1 + Invoke-WithoutTrace { + if ((Test-Path env:BLACKFIRE_SERVER_ID) -and (Test-Path env:BLACKFIRE_SERVER_TOKEN)) { + blackfire agent:config --server-id=$env:BLACKFIRE_SERVER_ID --server-token=$env:BLACKFIRE_SERVER_TOKEN >$null 2>&1 + } + if ((Test-Path env:BLACKFIRE_CLIENT_ID) -and (Test-Path env:BLACKFIRE_CLIENT_TOKEN)) { + blackfire client:config --client-id=$env:BLACKFIRE_CLIENT_ID --client-token=$env:BLACKFIRE_CLIENT_TOKEN --ca-cert=$php_dir\ssl\cacert.pem >$null 2>&1 + } } Add-Log $tick "blackfire" "Added blackfire $cli_version" } diff --git a/src/scripts/tools/blackfire.sh b/src/scripts/tools/blackfire.sh index b13c831d1..7bcfaa515 100644 --- a/src/scripts/tools/blackfire.sh +++ b/src/scripts/tools/blackfire.sh @@ -12,6 +12,10 @@ add_blackfire_darwin() { } blackfire_config() { + without_trace blackfire_config_helper +} + +blackfire_config_helper() { if [[ -n $BLACKFIRE_SERVER_ID ]] && [[ -n $BLACKFIRE_SERVER_TOKEN ]]; then blackfire agent:config --server-id="$BLACKFIRE_SERVER_ID" --server-token="$BLACKFIRE_SERVER_TOKEN" if [ "$os" = "Linux" ]; then diff --git a/src/scripts/tools/brew.sh b/src/scripts/tools/brew.sh index 6644ab9e3..b2677565e 100644 --- a/src/scripts/tools/brew.sh +++ b/src/scripts/tools/brew.sh @@ -55,25 +55,45 @@ get_file_mtime() { fi } -# Function to terminate a process and its direct children. -terminate_process_tree() { +# Function to list descendants before their parents, including separate sessions. +get_process_tree() { local pid=$1 local children child children=$(pgrep -P "$pid" 2>/dev/null || true) - kill -TERM "$pid" >/dev/null 2>&1 || true for child in $children; do - terminate_process_tree "$child" + get_process_tree "$child" + done + echo "$pid" +} + +# Function to detect Homebrew's source-build worker, even with buffered output. +is_brew_building_from_source() { + local pid + for pid in $(get_process_tree "$1"); do + if ps -ww -p "$pid" -o command= 2>/dev/null | grep -qE '/Homebrew/build[.]rb([[:space:]]|$)'; then + return 0 + fi + done + return 1 +} + +# Function to terminate the entire tree captured before any parents can exit. +terminate_process_tree() { + local pids pid + pids=$(get_process_tree "$1") + for pid in $pids; do + kill -TERM "$pid" >/dev/null 2>&1 || true done sleep 2 - kill -KILL "$pid" >/dev/null 2>&1 || true - for child in $children; do - terminate_process_tree "$child" + for pid in $pids; do + kill -KILL "$pid" >/dev/null 2>&1 || true done } # Function to run a command with an inactivity watchdog. run_with_inactivity_watchdog() { local timeout_secs="${SETUP_PHP_BREW_INACTIVITY_TIMEOUT:-180}" + local source_timeout_secs="${SETUP_PHP_BREW_SOURCE_INACTIVITY_TIMEOUT:-1800}" local poll_secs="${SETUP_PHP_BREW_WATCHDOG_POLL:-5}" local tmp_dir stdout_fifo stderr_fifo stdout_log stderr_log timeout_file local command_pid stdout_reader_pid stderr_reader_pid monitor_pid exit_code @@ -93,36 +113,39 @@ run_with_inactivity_watchdog() { ("$@" >"$stdout_fifo" 2>"$stderr_fifo") & command_pid=$! - ( - while IFS= read -r line || [ -n "$line" ]; do - printf '%s\n' "$line" - printf '%s\n' "$line" >>"$stdout_log" - done <"$stdout_fifo" - ) & + tee "$stdout_log" <"$stdout_fifo" & stdout_reader_pid=$! - ( - while IFS= read -r line || [ -n "$line" ]; do - printf '%s\n' "$line" >&2 - printf '%s\n' "$line" >>"$stderr_log" - done <"$stderr_fifo" - ) & + tee "$stderr_log" <"$stderr_fifo" >&2 & stderr_reader_pid=$! ( local last_activity current_activity current_err_activity now + local building_from_source=false was_building_from_source=false active_timeout_secs last_activity=$(get_file_mtime "$stdout_log") current_err_activity=$(get_file_mtime "$stderr_log") [ "$current_err_activity" -gt "$last_activity" ] && last_activity="$current_err_activity" while kill -0 "$command_pid" >/dev/null 2>&1; do sleep "$poll_secs" + kill -0 "$command_pid" >/dev/null 2>&1 || break + now=$(date +%s) + active_timeout_secs="$timeout_secs" + building_from_source=false + if is_brew_building_from_source "$command_pid"; then + building_from_source=true + active_timeout_secs="$source_timeout_secs" + fi + if [ "$building_from_source" != "$was_building_from_source" ]; then + last_activity="$now" + was_building_from_source="$building_from_source" + fi current_activity=$(get_file_mtime "$stdout_log") [ "$current_activity" -gt "$last_activity" ] && last_activity="$current_activity" current_err_activity=$(get_file_mtime "$stderr_log") [ "$current_err_activity" -gt "$last_activity" ] && last_activity="$current_err_activity" now=$(date +%s) - if [ $((now - last_activity)) -ge "$timeout_secs" ]; then - printf "\nsetup-php: brew produced no output for %ss; terminating and retrying...\n" "$timeout_secs" >&2 + if [ $((now - last_activity)) -ge "$active_timeout_secs" ]; then + printf "\nsetup-php: brew produced no output for %ss; terminating...\n" "$active_timeout_secs" >&2 : >"$timeout_file" terminate_process_tree "$command_pid" break @@ -131,12 +154,15 @@ run_with_inactivity_watchdog() { ) & monitor_pid=$! - wait "$command_pid" - exit_code=$? + exit_code=0 + wait "$command_pid" || exit_code=$? + # Let timeout cleanup finish killing source-build descendants before retrying. + if [ ! -e "$timeout_file" ]; then + kill "$monitor_pid" >/dev/null 2>&1 || true + fi + wait "$monitor_pid" 2>/dev/null || true wait "$stdout_reader_pid" 2>/dev/null || true wait "$stderr_reader_pid" 2>/dev/null || true - kill "$monitor_pid" >/dev/null 2>&1 || true - wait "$monitor_pid" 2>/dev/null || true if [ -e "$timeout_file" ]; then rm -rf "$tmp_dir" diff --git a/src/scripts/tools/ppa.sh b/src/scripts/tools/ppa.sh index 2fab78881..15813ede2 100644 --- a/src/scripts/tools/ppa.sh +++ b/src/scripts/tools/ppa.sh @@ -343,23 +343,32 @@ add_ppa_sp_mirror() { add_list sp/"$ppa_name" "$ppa_sp/$ppa/ubuntu" "$ppa_sp/$ppa/ubuntu/key.gpg" } +add_sury_list() { + ppa=${1:-ondrej/php} + [ "${debug:?}" = "debug" ] && add_list "$ppa" "$sury"/"${ppa##*/}"/ "$sury"/"${ppa##*/}"/apt.gpg "$VERSION_CODENAME" "main/debug" + add_list "$ppa" "$sury"/"${ppa##*/}"/ "$sury"/"${ppa##*/}"/apt.gpg +} + # Function to add a PPA. add_ppa() { set_base_version ppa=${1:-ondrej/php} if [[ "$ID" = "ubuntu" || "$ID_LIKE" =~ ubuntu ]] && [[ "$ppa" =~ "ondrej/" ]]; then - if is_ubuntu_ppa_up "$ppa" ; then - [ "${runner:?}" = "self-hosted" ] && find "$list_dir" -type f -name 'sp*' -exec grep -qF "${sp/https:\/\/}" {} \; -delete - [ "${debug:?}" = "debug" ] && add_list "$ppa" "$lpc_ppa/$ppa/ubuntu" "$lpc_ppa/$ppa/ubuntu" "$VERSION_CODENAME" "main/debug" - add_list "$ppa" - elif [ "$ppa" = "ondrej/php" ]; then - add_ppa_sp_mirror "$ppa" + if [ "$VERSION_ID" = "26.04" ]; then + add_sury_list else - add_log "${cross:?}" "$ppa" "PPA $ppa is not available" + if is_ubuntu_ppa_up "$ppa" ; then + [ "${runner:?}" = "self-hosted" ] && find "$list_dir" -type f -name 'sp*' -exec grep -qF "${sp/https:\/\/}" {} \; -delete + [ "${debug:?}" = "debug" ] && add_list "$ppa" "$lpc_ppa/$ppa/ubuntu" "$lpc_ppa/$ppa/ubuntu" "$VERSION_CODENAME" "main/debug" + add_list "$ppa" + elif [ "$ppa" = "ondrej/php" ]; then + add_ppa_sp_mirror "$ppa" + else + add_log "${cross:?}" "$ppa" "PPA $ppa is not available" + fi fi elif [[ "$ID" = "debian" || "$ID_LIKE" =~ debian ]] && [[ "$ppa" =~ "ondrej/" ]]; then - [ "${debug:?}" = "debug" ] && add_list "$ppa" "$sury"/"${ppa##*/}"/ "$sury"/"${ppa##*/}"/apt.gpg "$VERSION_CODENAME" "main/debug" - add_list "$ppa" "$sury"/"${ppa##*/}"/ "$sury"/"${ppa##*/}"/apt.gpg + add_sury_list else add_list "$ppa" fi diff --git a/src/scripts/unix.sh b/src/scripts/unix.sh index f0f45feab..e8a4e68a9 100644 --- a/src/scripts/unix.sh +++ b/src/scripts/unix.sh @@ -33,6 +33,8 @@ add_log() { local message=$3 if [ "$mark" = "$tick" ]; then printf "\033[32;1m%s \033[0m\033[34;1m%s \033[0m\033[90;1m%s\033[0m\n" "$mark" "$subject" "$message" + elif [ "$mark" = "!" ]; then + printf "\033[33;1m%s \033[0m\033[34;1m%s \033[0m\033[90;1m%s\033[0m\n" "$mark" "$subject" "$message" else printf "\033[31;1m%s \033[0m\033[34;1m%s \033[0m\033[90;1m%s\033[0m\n" "$mark" "$subject" "$message" [ "$fail_fast" = "true" ] && exit 1 @@ -48,16 +50,54 @@ set_output() { fi } +# Function to run sensitive code without tracing. Expand tokens inside the function, not its arguments. +without_trace() { + local setup_php_trace_flags=$- + set +x + "$@" + local setup_php_trace_status=$? + [[ "$setup_php_trace_flags" == *x* ]] && set -x + return "$setup_php_trace_status" +} + +# Function to check third-party runners eligible for the builds cache. +check_builds_cache_runner() { + local pid=$PPID executable + while [[ "$pid" =~ ^[0-9]+$ && "$pid" -gt 1 ]]; do + executable="$(readlink -f "/proc/$pid/exe")" || return 1 + if [[ "$executable" = */bin/Runner.Worker ]]; then + jq -e --arg name "${RUNNER_NAME:-}" \ + '.AgentName == $name and (.AgentName | test("^(blacksmith|depot)-"))' \ + "${executable%/bin/Runner.Worker}/.runner" >/dev/null 2>&1 + return $? + fi + pid="$(awk '$1 == "PPid:" {print $2}' "/proc/$pid/status")" || return 1 + done + return 1 +} + # Function to read env inputs. read_env() { + if [[ "${SETUP_PHP_TRACE:-0}" =~ ^[12]$ ]]; then + set -x + fi update="${update:-${UPDATE:-false}}" [ "${debug:-${DEBUG:-false}}" = "true" ] && debug=debug && update=true || debug=release [[ "${phpts:-${PHPTS:-nts}}" = "ts" || "${phpts:-${PHPTS:-nts}}" = "zts" ]] && ts=zts && update=true || ts=nts fail_fast="${fail_fast:-${FAIL_FAST:-false}}" + use_builds_cache="${use_builds_cache:-${use_package_cache:-}}" [[ ( -z "$ImageOS" && -z "$ImageVersion" ) || ( -n "$RUNNER_ENVIRONMENT" && "$RUNNER_ENVIRONMENT" = "self-hosted" ) || -n "$ACT" || -n "$CONTAINER" ]] && _runner=self-hosted || _runner=github runner="${runner:-${RUNNER:-$_runner}}" + if [[ $_runner = "self-hosted" && "${use_builds_cache:-false}" = "true" ]]; then + runner=github + if [[ "${ID:-}" = "ubuntu" && -z "$ACT" && -z "$CONTAINER" && + ( -n "${BLACKSMITH_VM_ID:-}" || "${RUNNER_NAME:-}" =~ ^(blacksmith|depot)- ) ]] && check_builds_cache_runner; then + _runner=github + builds_cache_warning=true + fi + fi tool_path_dir="${setup_php_tools_dir:-${SETUP_PHP_TOOLS_DIR:-/usr/local/bin}}" tool_cache_path_dir="${setup_php_tool_cache_dir:-${SETUP_PHP_TOOL_CACHE_DIR:-${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}/setup-php/tools}}" @@ -122,6 +162,25 @@ get_sha256() { fi } +# Function to verify the checksum of a file. +# checksum format: sha256: or sha512: +verify_checksum() { + local file_path=$1 + local checksum=$2 + local algo="${checksum%%:*}" + local expected="${checksum#*:}" + local actual= + local hash_command= + if hash_command="$(command -v "${algo}sum")"; then + actual="$(sudo "$hash_command" "$file_path" | cut -d' ' -f1)" + elif hash_command="$(command -v shasum)"; then + actual="$(sudo "$hash_command" -a "${algo#sha}" "$file_path" | cut -d' ' -f1)" + elif hash_command="$(command -v openssl)"; then + actual="$(sudo "$hash_command" dgst -"$algo" "$file_path" | awk '{print $NF}')" + fi + [ -n "$actual" ] && [ "$(echo "$actual" | tr '[:upper:]' '[:lower:]')" = "$(echo "$expected" | tr '[:upper:]' '[:lower:]')" ] +} + # Function to download a file using cURL. # mode: -s pipe to stdout, -v save file and return status code # execute: -e save file as executable diff --git a/src/scripts/win32.ps1 b/src/scripts/win32.ps1 index cfb6100cd..71a1f2ce1 100644 --- a/src/scripts/win32.ps1 +++ b/src/scripts/win32.ps1 @@ -28,6 +28,18 @@ Function Add-Log($mark, $subject, $message) { } } +# Function to run sensitive code without tracing. Expand tokens inside the script block. +Function Invoke-WithoutTrace([scriptblock]$Script) { + Set-PSDebug -Off + $previous_trace = $setup_php_trace + $setup_php_trace = 0 + try { + & $Script + } finally { + Set-PSDebug -Trace $previous_trace + } +} + # Function to set output on GitHub Actions. Function Set-Output() { param( @@ -167,6 +179,26 @@ Function Get-File { } } +# Function to get an asset name from the PHP builder release manifest. +Function Get-PhpReleaseAsset { + param ( + [ValidateSet('php', 'debug')] + [string]$Type, + [ValidateSet('stable', 'dev')] + [string]$Stability = 'stable' + ) + + if($null -eq $script:php_manifest) { + $script:php_manifest = Invoke-RestMethod "$php_builder/releases/download/php$version/manifest.json" + } + $thread_safety = if($ts) { 'ts' } else { 'nts' } + $asset = $script:php_manifest.$Stability.$Type.$thread_safety.$arch + if($null -eq $asset) { + throw "Asset not found in the php$version release manifest" + } + return $asset +} + # Function to make sure printf is in PATH. Function Add-Printf { if (-not(Test-Path "C:\Program Files\Git\usr\bin\printf.exe")) { @@ -258,51 +290,30 @@ Function Add-PhpConfig { Get-Content -Path $ini_files | Add-Content -Path $php_dir\php.ini } -# Function to get PHP from GitHub releases cache -Function Set-PhpCache { - try { - try { - $release = Invoke-RestMethod https://api.github.com/repos/shivammathur/php-builder-windows/releases/tags/php$version - $asset = $release.assets | ForEach-Object { - if($_.name -match "php-$version.[0-9]+$env:PHPTS-Win32-.*-$arch.zip") { - return $_.name - } - } | Select-Object -Last 1 - if($null -eq $asset) { - throw "Asset not found" - } - } catch { - $release = Get-File -Url $php_builder/releases/expanded_assets/php$version - $asset = $release.links.href | ForEach-Object { - if($_ -match "php-$version.[0-9]+$env:PHPTS-Win32-.*-$arch.zip") { - return $_.split('/')[-1] - } - } | Select-Object -Last 1 - } - Get-File -Url $php_builder/releases/download/php$version/$asset -OutFile $php_dir\$asset - Set-PhpDownloadCache -Path $php_dir CurrentUser - } catch { } +# Function to install PHP directly from the GitHub releases cache. +Function Install-PhpFromCache { + $asset = Get-PhpReleaseAsset -Type php + $url = "$php_builder/releases/download/php$version/$asset" + Get-File -Url $url -FallbackUrl $php_windows/releases/archives/$asset -OutFile $php_dir\$asset + Set-PhpDownloadCache -Path $php_dir CurrentUser + $php_manager = Get-Module PhpManager + & $php_manager { + param($url, $path) + $php_version = Get-PhpVersionFromUrl -Url $url -ReleaseState Release + Install-PhpFromUrl -Url $url -Path $path -PhpVersion $php_version -InstallVCRedist $true + } $url $php_dir + $ini_path = "$php_dir\php.ini" + Copy-Item -Path $php_dir\php.ini-production -Destination $ini_path -Force + Set-PhpIniKey -Key date.timezone -Value UTC -Path $ini_path + Set-PhpIniKey -Key default_charset -Value UTF-8 -Path $ini_path + Set-PhpIniKey -Key extension_dir -Value $ext_dir -Path $ini_path } # Function to add debug symbols to PHP. Function Add-DebugSymbols { - $dev = if ($version -match $nightly_versions) { '-dev' } else { '' } - try { - $release = Invoke-RestMethod https://api.github.com/repos/shivammathur/php-builder-windows/releases/tags/php$version - $asset = $release.assets | ForEach-Object { - if($_.name -match "php-debug-pack-$version.[0-9]+$dev$env:PHPTS-Win32-.*-$arch.zip") { - return $_.name - } - } | Select-Object -Last 1 - } catch { - $release = Get-File -Url $php_builder/releases/expanded_assets/php$version - $asset = $release.links.href | ForEach-Object { - if($_ -match "php-debug-pack-$version.[0-9]+$dev$env:PHPTS-Win32-.*-$arch.zip") { - return $_.split('/')[-1] - } - } | Select-Object -Last 1 - } - Get-File -Url $php_builder/releases/download/php$version/$asset -OutFile $php_dir\$asset + $stability = if ($version -match $nightly_versions) { 'dev' } else { 'stable' } + $asset = Get-PhpReleaseAsset -Type debug -Stability $stability + Get-File -Url $php_builder/releases/download/php$version/$asset -FallbackUrl $php_windows/releases/archives/$asset -OutFile $php_dir\$asset Expand-Archive -Path $php_dir\$asset -DestinationPath $php_dir -Force Get-ChildItem -Path $php_dir -Filter php_*.pdb | Move-Item -Destination $ext_dir } @@ -325,6 +336,8 @@ $ext_dir = "$php_dir\ext" $bin_dir = $php_dir $github = 'https://github.com' $php_builder = "$github/shivammathur/php-builder-windows" +$php_windows = 'https://downloads.php.net/~windows' +$php_manifest = $null $current_profile = "$env:TEMP\setup-php.ps1" $ProgressPreference = 'SilentlyContinue' $jit_versions = '8.[0-9]' @@ -332,6 +345,12 @@ $nightly_versions = '8.[6-9]' $xdebug3_versions = "7.[2-4]|8.[0-9]" $enable_extensions = ('openssl', 'curl', 'mbstring') +$setup_php_trace = 0 +if ($env:SETUP_PHP_TRACE -match '^[12]$') { + $setup_php_trace = [int]$env:SETUP_PHP_TRACE + Set-PSDebug -Trace $setup_php_trace +} + $arch = 'x64' if(-not([Environment]::Is64BitOperatingSystem) -or $version -lt '7.0') { $arch = 'x86' @@ -424,8 +443,11 @@ if ($null -eq $installed -or -not("$($installed.Version).".StartsWith(($version if ($version -match $nightly_versions) { $extra_version = Install-PhpNightly } else { - Set-PhpCache - Install-Php -Version $version -Architecture $arch -ThreadSafe $ts -InstallVC -Path $php_dir -TimeZone UTC -InitialPhpIni production -Force > $null 2>&1 + try { + Install-PhpFromCache > $null 2>&1 + } catch { + Install-Php -Version $version -Architecture $arch -ThreadSafe $ts -InstallVC -Path $php_dir -TimeZone UTC -InitialPhpIni production -Force > $null 2>&1 + } } Add-PhpConfig } catch { } diff --git a/src/tools.ts b/src/tools.ts index 443668a54..5d250090d 100644 --- a/src/tools.ts +++ b/src/tools.ts @@ -27,6 +27,7 @@ type ToolFunction = export interface ToolData { tool: string; version: string; + checksum?: string; os: string; php_version: string; github: string; @@ -73,6 +74,59 @@ interface ToolConfig { packagist?: string; } +/** + * Regex to match a checksum suffix in a tool release - tool:version@sha256: + */ +const checksum_suffix_regex = /@([a-z][a-z0-9-]*):([^@]*)$/i; +const checksum_like_suffix_regex = /@sha[^@]*$/i; + +/** + * Function to parse the checksum suffix in the tool release + * + * @param release + */ +export function extractChecksum(release: string): { + release: string; + checksum?: string; + error?: string; +} { + const matches = release.match(checksum_suffix_regex); + if (!matches) { + const checksum_like_matches = release.match(checksum_like_suffix_regex); + if (checksum_like_matches) { + return { + release: release.slice(0, -checksum_like_matches[0].length), + error: + 'Invalid checksum syntax, expected @sha256: or @sha512:' + }; + } + return {release}; + } + release = release.slice(0, -matches[0].length); + const algo = matches[1].toLowerCase(); + if (!['sha256', 'sha512'].includes(algo)) { + return { + release, + error: `Unsupported checksum algorithm ${algo}, expected sha256 or sha512` + }; + } + const hash = matches[2].toLowerCase(); + const hash_length = algo === 'sha256' ? 64 : 128; + if (!new RegExp(`^[a-f0-9]{${hash_length}}$`).test(hash)) { + return { + release, + error: `Invalid ${algo} checksum, expected ${hash_length} hexadecimal characters` + }; + } + if (!/^[^:]+:v?\d+\.\d+\.\d+(?:-[\w.-]+)?(?:\+[\w.-]+)?$/.test(release)) { + return { + release, + error: 'Checksum pinning requires a full version, for example tool:1.2.3' + }; + } + return {release, checksum: `${algo}:${hash}`}; +} + /** * GitHub reference object from API response */ @@ -260,9 +314,18 @@ export async function filterList(tools_list: string[]): Promise { const regex_any = /^composer($|:.*)/; const regex_valid = /^composer:?($|preview$|snapshot$|v?\d+(\.\d+)?$|v?\d+\.\d+\.\d+[\w-]*$)/; - const matches: string[] = tools_list.filter(tool => regex_valid.test(tool)); + const matches: string[] = tools_list.filter(tool => { + const parsed = extractChecksum(tool); + return ( + regex_valid.test(parsed.release) || + (regex_any.test(parsed.release) && + (parsed.checksum !== undefined || parsed.error !== undefined)) + ); + }); let composer = 'composer'; - tools_list = tools_list.filter(tool => !regex_any.test(tool)); + tools_list = tools_list.filter( + tool => !regex_any.test(extractChecksum(tool).release) + ); switch (true) { case matches[0] == undefined: break; @@ -335,7 +398,8 @@ export async function getPharUrl(data: ToolData): Promise { export async function addArchive(data: ToolData): Promise { return ( (await utils.getCommand(data.os, 'tool')) + - (await utils.joins(data.url, data.tool, data.version_parameter)) + (await utils.joins(data.url, data.tool, data.version_parameter)) + + (data.checksum ? ' ' + data.checksum : '') ); } @@ -427,7 +491,7 @@ export async function addComposer(data: ToolData): Promise { case /^1$/.test(channel): source_url = channel_source_url; break; - case /^\d+\.\d+\.\d+(?:-[\w-]+)?$/.test(data.version): + case /^\d+\.\d+\.\d+(?:-[\w.-]+)?(?:\+[\w.-]+)?$/.test(data.version): if (skipGitHubAuthForComposerVersion(data.version)) { cleanComposerAuthJson(); skip_composer_github_auth = ' true'; @@ -612,6 +676,8 @@ export async function getData( const json_file: string = fs.readFileSync(json_file_path, 'utf8'); const json_objects: Record = JSON.parse(json_file); release = release.replace(/\s+/g, ''); + const checksum_data = extractChecksum(release); + release = checksum_data.release; const parts: string[] = release.split(':'); const tool = parts[0]; const version = parts[1]; @@ -663,7 +729,10 @@ export async function getData( function: config.function, alias: config.alias }; + data.checksum = checksum_data.checksum; + data.error = checksum_data.error; data.release = await getRelease(release, data); + if (data.error !== undefined) return data; data.version = version ? await getVersion(version, data) : await getLatestVersion(data); @@ -688,6 +757,25 @@ export const functionRecord: Record< wp_cli: addWPCLI }; +/** + * Function to check if a tool supports checksum verification + * + * Only tools downloaded as archives via add_tool support it, so composer + * packages and tools set up using custom package scripts do not. + * + * @param data + */ +export async function supportsChecksum(data: ToolData): Promise { + switch (data.type) { + case 'phar': + return true; + case 'custom-function': + return !['pecl', 'dev_tools'].includes(data.function ?? ''); + default: + return false; + } +} + /** * Setup tools * @@ -714,6 +802,14 @@ export async function addTools( case data.error !== undefined: script += await utils.addLog('$cross', data.tool, data.error, data.os); break; + case data.checksum !== undefined && !(await supportsChecksum(data)): + script += await utils.addLog( + '$cross', + data.tool, + 'Checksum verification is not supported for ' + data.tool, + data.os + ); + break; case 'phar' === data.type: script += await addArchive(data); break; diff --git a/src/utils.ts b/src/utils.ts index 7323301f8..b55e71402 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -71,15 +71,13 @@ export async function parseVersion(version: string): Promise { for (const manifestURL of await getManifestURLS()) { const fetchResult = await fetch.fetch(manifestURL); if (fetchResult['data'] ?? false) { - const resolved: string | undefined = JSON.parse(fetchResult['data'])[ - version - ]; + const resolved: unknown = JSON.parse(fetchResult['data'])[version]; if (resolved === undefined) { throw new Error(`Invalid PHP version: ${version.slice(0, 20)}`); } - if (!/^\d+\.\d+$/.test(resolved)) { + if (typeof resolved !== 'string' || !/^\d+\.\d+$/.test(resolved)) { throw new Error( - `Invalid PHP version in manifest: ${resolved.slice(0, 10)}` + `Invalid PHP version in manifest: ${typeof resolved === 'string' ? resolved.slice(0, 10) : typeof resolved}` ); } return resolved; @@ -332,6 +330,47 @@ export async function suppressOutput(os: string): Promise { } } +/** + * Prepare verbose runtime scripts without changing the original sources. + */ +export async function addVerbose( + run_path: string, + os: string +): Promise { + const verbose = await readEnv('verbose'); + process.env['SETUP_PHP_TRACE'] = /^v{2,3}$/.test(verbose) + ? String(verbose.length - 1) + : '0'; + if (!/^(true|v{1,3})$/.test(verbose) && process.env['RUNNER_DEBUG'] !== '1') { + return run_path; + } + const extension = await scriptExtension(os); + const src = path.dirname(path.dirname(run_path)); + const dest = fs.mkdtempSync(src + '-verbose-'); + await fs.promises.cp(src, dest, {recursive: true, dereference: true}); + const scripts = path.join(dest, 'scripts'); + const verbose_run = path.join(scripts, path.basename(run_path)); + const pipe = />[ \t]*(?:\/dev\/null|\$null)[ \t]+2>&1/g; + for (const file of fs.readdirSync(scripts, { + recursive: true, + encoding: 'utf8' + })) { + if (!file.endsWith(extension)) continue; + const filename = path.join(scripts, file); + const original = fs.readFileSync(filename, 'utf8'); + // PowerShell's success stream also carries function return values. + let script = original.replace( + pipe, + os === 'win32' ? '2>&1 | Out-Host' : '' + ); + if (filename === verbose_run) { + script = script.replaceAll(src, dest); + } + if (script !== original) fs.writeFileSync(filename, script); + } + return verbose_run; +} + /** * Function to get script to log unsupported extensions. * @@ -473,10 +512,10 @@ export async function parseExtensionSource( const VERSION_INPUT_REGEX = /^(latest|lowest|highest|nightly|master|pre|pre-installed|\d+\.x|\d+(\.\d+){0,2})$/; -function validatePHPVersionInput(version: string, source: string): string { - if (!VERSION_INPUT_REGEX.test(version)) { +function validatePHPVersionInput(version: unknown, source: string): string { + if (typeof version !== 'string' || !VERSION_INPUT_REGEX.test(version)) { throw new Error( - `Invalid PHP version in ${source}: ${version.slice(0, 20)}` + `Invalid PHP version in ${source}: ${typeof version === 'string' ? version.slice(0, 20) : typeof version}` ); } return version; @@ -494,7 +533,9 @@ export async function readPHPVersion(): Promise { (await getInput('php-version-file', false)) || '.php-version'; if (fs.existsSync(versionFile)) { const contents: string = fs.readFileSync(versionFile, 'utf8'); - const match = contents.match(/^(?:php\s)?(\d+\.\d+\.\d+)$/m); + const match = contents.match( + /^[ \t]*(?:php[ \t]+)?([^\s#]+)[ \t]*(?:#.*)?$/m + ); return validatePHPVersionInput( match ? match[1] : contents.trim(), versionFile diff --git a/tsconfig.json b/tsconfig.json index 9f037c0df..2eb31efd8 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,17 +3,20 @@ "declaration": true, "esModuleInterop": true, "lib": [ - "ES2024" + "ES2025" ], - "module": "commonjs", - "moduleResolution": "node", + "module": "Node20", + "moduleResolution": "Node16", "noImplicitAny": true, "outDir": "./lib", "removeComments": true, "rootDir": "./src", "sourceMap": true, "strict": true, - "target": "ES2024" + "target": "ES2025", + "types": [ + "node" + ] }, "exclude": ["__tests__", "lib", "node_modules"] -} \ No newline at end of file +} diff --git a/tsconfig.test.json b/tsconfig.test.json new file mode 100644 index 000000000..6bfca1be9 --- /dev/null +++ b/tsconfig.test.json @@ -0,0 +1,14 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "isolatedModules": true, + "noEmit": true, + "rootDir": ".", + "types": [ + "jest", + "node" + ] + }, + "exclude": ["lib", "node_modules"], + "include": ["__tests__/**/*.ts", "src/**/*.ts"] +}