diff --git a/.eslintrc.json b/.eslintrc.json index 08f1b35bf..90e2c33c5 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -5,5 +5,6 @@ "error", {"argsIgnorePattern": "^_", "varsIgnorePattern": "^_$"} ] - } + }, + "root": true } diff --git a/.github/.OwlBot.lock.yaml b/.github/.OwlBot.lock.yaml index 748836981..fbf0659c3 100644 --- a/.github/.OwlBot.lock.yaml +++ b/.github/.OwlBot.lock.yaml @@ -1,4 +1,4 @@ -# Copyright 2022 Google LLC +# Copyright 2023 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -13,5 +13,5 @@ # limitations under the License. docker: image: gcr.io/cloud-devrel-public-resources/owlbot-nodejs:latest - digest: sha256:bb493bf01d28519e82ab61c490c20122c85a7119c03a978ad0c34b4239fbad15 -# created: 2022-08-23T18:40:55.597313991Z + digest: sha256:bfe4592953269bfa8d135200ca1b17809f106a337a885d7ecc12cd2a9998e98a +# created: 2023-11-15T20:00:24.246072277Z diff --git a/.github/release-please.yml b/.github/release-please.yml index b76f7986e..b025cc923 100644 --- a/.github/release-please.yml +++ b/.github/release-please.yml @@ -1,5 +1,5 @@ handleGHRelease: true -releaseType: node +manifest: true branches: - handleGHRelease: true releaseType: node diff --git a/.github/sync-repo-settings.yaml b/.github/sync-repo-settings.yaml index 1390363b7..2fe25bc41 100644 --- a/.github/sync-repo-settings.yaml +++ b/.github/sync-repo-settings.yaml @@ -11,8 +11,7 @@ branchProtectionRules: - cla/google - docs - lint - - test (14) - - test (16) + - test (18) - windows - pattern: 12.x isAdminEnforced: false diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 1dc3d9c6b..ef7807326 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -9,9 +9,9 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node: [14, 16] + node: [18, 20] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/setup-node@v3 with: node-version: ${{ matrix.node }} @@ -29,10 +29,10 @@ jobs: windows: runs-on: windows-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/setup-node@v3 with: - node-version: 14 + node-version: 18 - run: npm install - run: npm test env: @@ -40,21 +40,33 @@ jobs: lint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/setup-node@v3 with: - node-version: 14 + node-version: 18 - run: npm install - run: npm run lint docs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/setup-node@v3 with: - node-version: 14 + node-version: 18 - run: npm install - run: npm run docs - uses: JustinBeckwith/linkinator-action@v1 with: paths: docs/ + build-action: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + repository: google-github-actions/release-please-action + ref: main + - uses: actions/setup-node@v3 + with: + node-version: 18 + - run: npm install --save googleapis/release-please#${{ github.ref }} + - run: npm run build diff --git a/.kokoro/common.cfg b/.kokoro/common.cfg index 1c119ff0d..7c32ecb95 100644 --- a/.kokoro/common.cfg +++ b/.kokoro/common.cfg @@ -16,7 +16,7 @@ build_file: "release-please/.kokoro/trampoline_v2.sh" # Configure the docker image for kokoro-trampoline. env_vars: { key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-kokoro-resources/node:12-user" + value: "gcr.io/cloud-devrel-kokoro-resources/node:14-user" } env_vars: { key: "TRAMPOLINE_BUILD_FILE" diff --git a/.kokoro/continuous/node12/samples-test.cfg b/.kokoro/continuous/node12/samples-test.cfg index 74eab28af..6a5a4f4c9 100644 --- a/.kokoro/continuous/node12/samples-test.cfg +++ b/.kokoro/continuous/node12/samples-test.cfg @@ -5,3 +5,8 @@ env_vars: { key: "TRAMPOLINE_BUILD_FILE" value: "github/release-please/.kokoro/samples-test.sh" } + +env_vars: { + key: "SECRET_MANAGER_KEYS" + value: "long-door-651-kokoro-system-test-service-account" +} \ No newline at end of file diff --git a/.kokoro/continuous/node12/system-test.cfg b/.kokoro/continuous/node12/system-test.cfg index e5f9bd009..66c5eb95a 100644 --- a/.kokoro/continuous/node12/system-test.cfg +++ b/.kokoro/continuous/node12/system-test.cfg @@ -5,3 +5,8 @@ env_vars: { key: "TRAMPOLINE_BUILD_FILE" value: "github/release-please/.kokoro/system-test.sh" } + +env_vars: { + key: "SECRET_MANAGER_KEYS" + value: "long-door-651-kokoro-system-test-service-account" +} \ No newline at end of file diff --git a/.kokoro/continuous/node14/common.cfg b/.kokoro/continuous/node14/common.cfg new file mode 100644 index 000000000..7c32ecb95 --- /dev/null +++ b/.kokoro/continuous/node14/common.cfg @@ -0,0 +1,24 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Build logs will be here +action { + define_artifacts { + regex: "**/*sponge_log.xml" + } +} + +# Download trampoline resources. +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" + +# Use the trampoline script to run in docker. +build_file: "release-please/.kokoro/trampoline_v2.sh" + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/node:14-user" +} +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/release-please/.kokoro/test.sh" +} diff --git a/.kokoro/continuous/node14/lint.cfg b/.kokoro/continuous/node14/lint.cfg new file mode 100644 index 000000000..139008727 --- /dev/null +++ b/.kokoro/continuous/node14/lint.cfg @@ -0,0 +1,4 @@ +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/release-please/.kokoro/lint.sh" +} diff --git a/.kokoro/continuous/node14/samples-test.cfg b/.kokoro/continuous/node14/samples-test.cfg new file mode 100644 index 000000000..6a5a4f4c9 --- /dev/null +++ b/.kokoro/continuous/node14/samples-test.cfg @@ -0,0 +1,12 @@ +# Download resources for system tests (service account key, etc.) +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/google-cloud-nodejs" + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/release-please/.kokoro/samples-test.sh" +} + +env_vars: { + key: "SECRET_MANAGER_KEYS" + value: "long-door-651-kokoro-system-test-service-account" +} \ No newline at end of file diff --git a/.kokoro/continuous/node14/system-test.cfg b/.kokoro/continuous/node14/system-test.cfg new file mode 100644 index 000000000..66c5eb95a --- /dev/null +++ b/.kokoro/continuous/node14/system-test.cfg @@ -0,0 +1,12 @@ +# Download resources for system tests (service account key, etc.) +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/google-cloud-nodejs" + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/release-please/.kokoro/system-test.sh" +} + +env_vars: { + key: "SECRET_MANAGER_KEYS" + value: "long-door-651-kokoro-system-test-service-account" +} \ No newline at end of file diff --git a/.kokoro/continuous/node14/test.cfg b/.kokoro/continuous/node14/test.cfg new file mode 100644 index 000000000..e69de29bb diff --git a/.kokoro/presubmit/node12/samples-test.cfg b/.kokoro/presubmit/node12/samples-test.cfg index 74eab28af..6a5a4f4c9 100644 --- a/.kokoro/presubmit/node12/samples-test.cfg +++ b/.kokoro/presubmit/node12/samples-test.cfg @@ -5,3 +5,8 @@ env_vars: { key: "TRAMPOLINE_BUILD_FILE" value: "github/release-please/.kokoro/samples-test.sh" } + +env_vars: { + key: "SECRET_MANAGER_KEYS" + value: "long-door-651-kokoro-system-test-service-account" +} \ No newline at end of file diff --git a/.kokoro/presubmit/node12/system-test.cfg b/.kokoro/presubmit/node12/system-test.cfg index e5f9bd009..66c5eb95a 100644 --- a/.kokoro/presubmit/node12/system-test.cfg +++ b/.kokoro/presubmit/node12/system-test.cfg @@ -5,3 +5,8 @@ env_vars: { key: "TRAMPOLINE_BUILD_FILE" value: "github/release-please/.kokoro/system-test.sh" } + +env_vars: { + key: "SECRET_MANAGER_KEYS" + value: "long-door-651-kokoro-system-test-service-account" +} \ No newline at end of file diff --git a/.kokoro/presubmit/node14/common.cfg b/.kokoro/presubmit/node14/common.cfg new file mode 100644 index 000000000..7c32ecb95 --- /dev/null +++ b/.kokoro/presubmit/node14/common.cfg @@ -0,0 +1,24 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Build logs will be here +action { + define_artifacts { + regex: "**/*sponge_log.xml" + } +} + +# Download trampoline resources. +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" + +# Use the trampoline script to run in docker. +build_file: "release-please/.kokoro/trampoline_v2.sh" + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/node:14-user" +} +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/release-please/.kokoro/test.sh" +} diff --git a/.kokoro/presubmit/node14/samples-test.cfg b/.kokoro/presubmit/node14/samples-test.cfg new file mode 100644 index 000000000..6a5a4f4c9 --- /dev/null +++ b/.kokoro/presubmit/node14/samples-test.cfg @@ -0,0 +1,12 @@ +# Download resources for system tests (service account key, etc.) +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/google-cloud-nodejs" + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/release-please/.kokoro/samples-test.sh" +} + +env_vars: { + key: "SECRET_MANAGER_KEYS" + value: "long-door-651-kokoro-system-test-service-account" +} \ No newline at end of file diff --git a/.kokoro/presubmit/node14/system-test.cfg b/.kokoro/presubmit/node14/system-test.cfg new file mode 100644 index 000000000..66c5eb95a --- /dev/null +++ b/.kokoro/presubmit/node14/system-test.cfg @@ -0,0 +1,12 @@ +# Download resources for system tests (service account key, etc.) +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/google-cloud-nodejs" + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/release-please/.kokoro/system-test.sh" +} + +env_vars: { + key: "SECRET_MANAGER_KEYS" + value: "long-door-651-kokoro-system-test-service-account" +} \ No newline at end of file diff --git a/.kokoro/presubmit/node14/test.cfg b/.kokoro/presubmit/node14/test.cfg new file mode 100644 index 000000000..e69de29bb diff --git a/.kokoro/publish.sh b/.kokoro/publish.sh index 949e3e1d0..ca1d47af3 100755 --- a/.kokoro/publish.sh +++ b/.kokoro/publish.sh @@ -27,4 +27,16 @@ NPM_TOKEN=$(cat $KOKORO_KEYSTORE_DIR/73713_google-cloud-npm-token-1) echo "//wombat-dressing-room.appspot.com/:_authToken=${NPM_TOKEN}" > ~/.npmrc npm install -npm publish --access=public --registry=https://wombat-dressing-room.appspot.com +npm pack . +# npm provides no way to specify, observe, or predict the name of the tarball +# file it generates. We have to look in the current directory for the freshest +# .tgz file. +TARBALL=$(ls -1 -t *.tgz | head -1) + +npm publish --access=public --registry=https://wombat-dressing-room.appspot.com "$TARBALL" + +# Kokoro collects *.tgz and package-lock.json files and stores them in Placer +# so we can generate SBOMs and attestations. +# However, we *don't* want Kokoro to collect package-lock.json and *.tgz files +# that happened to be installed with dependencies. +find node_modules -name package-lock.json -o -name "*.tgz" | xargs rm -f \ No newline at end of file diff --git a/.kokoro/release/docs-devsite.sh b/.kokoro/release/docs-devsite.sh index 2198e67fe..81a89f6c1 100755 --- a/.kokoro/release/docs-devsite.sh +++ b/.kokoro/release/docs-devsite.sh @@ -25,5 +25,6 @@ if [[ -z "$CREDENTIALS" ]]; then fi npm install -npm install --no-save @google-cloud/cloud-rad@^0.2.5 -npx @google-cloud/cloud-rad \ No newline at end of file +npm install --no-save @google-cloud/cloud-rad@^0.4.0 +# publish docs to devsite +npx @google-cloud/cloud-rad . cloud-rad diff --git a/.kokoro/release/docs.cfg b/.kokoro/release/docs.cfg index 31f55cc79..8059cb930 100644 --- a/.kokoro/release/docs.cfg +++ b/.kokoro/release/docs.cfg @@ -11,7 +11,7 @@ before_action { # doc publications use a Python image. env_vars: { key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-kokoro-resources/node:12-user" + value: "gcr.io/cloud-devrel-kokoro-resources/node:14-user" } # Download trampoline resources. diff --git a/.kokoro/release/publish.cfg b/.kokoro/release/publish.cfg index 9c80b04e9..fa524b4d3 100644 --- a/.kokoro/release/publish.cfg +++ b/.kokoro/release/publish.cfg @@ -30,10 +30,22 @@ build_file: "release-please/.kokoro/trampoline_v2.sh" # Configure the docker image for kokoro-trampoline. env_vars: { key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-kokoro-resources/node:12-user" + value: "gcr.io/cloud-devrel-kokoro-resources/node:18-user" } env_vars: { key: "TRAMPOLINE_BUILD_FILE" value: "github/release-please/.kokoro/publish.sh" } + +# Store the packages we uploaded to npmjs.org and their corresponding +# package-lock.jsons in Placer. That way, we have a record of exactly +# what we published, and which version of which tools we used to publish +# it, which we can use to generate SBOMs and attestations. +action { + define_artifacts { + regex: "github/**/*.tgz" + regex: "github/**/package-lock.json" + strip_prefix: "github" + } +} diff --git a/.kokoro/samples-test.sh b/.kokoro/samples-test.sh index fbc058a4e..8c5d108cb 100755 --- a/.kokoro/samples-test.sh +++ b/.kokoro/samples-test.sh @@ -19,7 +19,7 @@ set -eo pipefail export NPM_CONFIG_PREFIX=${HOME}/.npm-global # Setup service account credentials. -export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/service-account.json +export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/secret_manager/long-door-651-kokoro-system-test-service-account export GCLOUD_PROJECT=long-door-651 cd $(dirname $0)/.. @@ -56,7 +56,7 @@ fi # codecov combines coverage across integration and unit tests. Include # the logic below for any environment you wish to collect coverage for: -COVERAGE_NODE=12 +COVERAGE_NODE=14 if npx check-node-version@3.3.0 --silent --node $COVERAGE_NODE; then NYC_BIN=./node_modules/nyc/bin/nyc.js if [ -f "$NYC_BIN" ]; then diff --git a/.kokoro/test.bat b/.kokoro/test.bat index ae59e59be..0bb124052 100644 --- a/.kokoro/test.bat +++ b/.kokoro/test.bat @@ -21,7 +21,7 @@ cd .. @rem we upgrade Node.js in the image: SET PATH=%PATH%;/cygdrive/c/Program Files/nodejs/npm -call nvm use v12.14.1 +call nvm use v14.17.3 call which node call npm install || goto :error diff --git a/.kokoro/test.sh b/.kokoro/test.sh index a5c7ac04c..862d478d3 100755 --- a/.kokoro/test.sh +++ b/.kokoro/test.sh @@ -39,7 +39,7 @@ npm test # codecov combines coverage across integration and unit tests. Include # the logic below for any environment you wish to collect coverage for: -COVERAGE_NODE=12 +COVERAGE_NODE=14 if npx check-node-version@3.3.0 --silent --node $COVERAGE_NODE; then NYC_BIN=./node_modules/nyc/bin/nyc.js if [ -f "$NYC_BIN" ]; then diff --git a/.release-please-manifest.json b/.release-please-manifest.json new file mode 100644 index 000000000..93c6490d1 --- /dev/null +++ b/.release-please-manifest.json @@ -0,0 +1,3 @@ +{ + ".": "16.8.0" +} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index f9f6aeeda..6fb57d660 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,423 @@ [1]: https://www.npmjs.com/package/release-please?activeTab=versions +## [16.8.0](https://github.com/googleapis/release-please/compare/v16.7.1...v16.8.0) (2024-01-26) + + +### Features + +* set 'version' of composer.json in RootComposerUpdatePackages ([#2201](https://github.com/googleapis/release-please/issues/2201)) ([00ae8d1](https://github.com/googleapis/release-please/commit/00ae8d1c83ef711156f8bac6bde08d1fb80276de)) + + +### Bug Fixes + +* **php-yoshi:** do not add version to root version map ([#2199](https://github.com/googleapis/release-please/issues/2199)) ([32a972a](https://github.com/googleapis/release-please/commit/32a972aa9ce02fae6ea0aa99c63fcbfb0e03191a)) + +## [16.7.1](https://github.com/googleapis/release-please/compare/v16.7.0...v16.7.1) (2024-01-25) + + +### Bug Fixes + +* **php-yoshi:** set "version" if it's in composer.json ([#2192](https://github.com/googleapis/release-please/issues/2192)) ([5e6186f](https://github.com/googleapis/release-please/commit/5e6186ff8c57435b293c64b84e63fd9a05c30f1c)) + +## [16.7.0](https://github.com/googleapis/release-please/compare/v16.6.0...v16.7.0) (2024-01-03) + + +### Features + +* **node-workspace:** add root package-lock.json ([#2162](https://github.com/googleapis/release-please/issues/2162)) ([8728d4a](https://github.com/googleapis/release-please/commit/8728d4ab53b46198b03e4f71875efee2e542d9af)) + +## [16.6.0](https://github.com/googleapis/release-please/compare/v16.5.1...v16.6.0) (2023-12-28) + + +### Features + +* **node-workspace:** use configured strategies to build new dependent version bumps ([#2112](https://github.com/googleapis/release-please/issues/2112)) ([de4088b](https://github.com/googleapis/release-please/commit/de4088b15374f76596d252136152263c37cfefef)) + +## [16.5.1](https://github.com/googleapis/release-please/compare/v16.5.0...v16.5.1) (2023-12-18) + + +### Bug Fixes + +* **deps:** update dependency @google-automations/git-file-utils to v2 ([#2081](https://github.com/googleapis/release-please/issues/2081)) ([9b745d5](https://github.com/googleapis/release-please/commit/9b745d572ebc2d125538df3b13ddd6a3983841bb)) +* **deps:** update dependency xpath to ^0.0.34 ([#2169](https://github.com/googleapis/release-please/issues/2169)) ([3f7045e](https://github.com/googleapis/release-please/commit/3f7045ebbd800870659ccd0ae330b5b8f8daf47d)) +* **node:** correctly detect >=, <= over >, < when replacing version ranges ([#2171](https://github.com/googleapis/release-please/issues/2171)) ([47fe582](https://github.com/googleapis/release-please/commit/47fe582a373eb62471e2c7f39b58a5d982c8e3a6)) + +## [16.5.0](https://github.com/googleapis/release-please/compare/v16.4.1...v16.5.0) (2023-12-11) + + +### Features + +* export current release-please version as VERSION constant ([#2159](https://github.com/googleapis/release-please/issues/2159)) ([264af84](https://github.com/googleapis/release-please/commit/264af8412faa20b818516efba0bb847720fc0d2a)) + +## [16.4.1](https://github.com/googleapis/release-please/compare/v16.4.0...v16.4.1) (2023-12-11) + + +### Bug Fixes + +* **node-workspace:** Add update-peer-dependencies option that also updates peer dependencies ([#2094](https://github.com/googleapis/release-please/issues/2094)) ([c84414a](https://github.com/googleapis/release-please/commit/c84414a3192cca65da4469c7559460624446c898)) +* pass pull request header and footer options to merge plugin ([#2143](https://github.com/googleapis/release-please/issues/2143)) ([e848100](https://github.com/googleapis/release-please/commit/e8481007981cf9fa3f476f65db4d3de807259e89)) + +## [16.4.0](https://github.com/googleapis/release-please/compare/v16.3.1...v16.4.0) (2023-12-05) + + +### Features + +* **types:** Export types exposed by Manifest for use downstream ([#2147](https://github.com/googleapis/release-please/issues/2147)) ([b259d70](https://github.com/googleapis/release-please/commit/b259d70270bd1c4358267aeff07de6aaaeddd9b9)) +* Update VERSION file in PHP repo if it exists ([#2153](https://github.com/googleapis/release-please/issues/2153)) ([a7d3b73](https://github.com/googleapis/release-please/commit/a7d3b73e605d0425b4a54a11ff2723a3075b4d3c)) + +## [16.3.1](https://github.com/googleapis/release-please/compare/v16.3.0...v16.3.1) (2023-11-27) + + +### Bug Fixes + +* Backfill files by commit for rebased PRs ([#2141](https://github.com/googleapis/release-please/issues/2141)) ([ee6d82f](https://github.com/googleapis/release-please/commit/ee6d82ffd27dd121fd0d73437456680d9d54dc98)) +* Pass prerelease to buildVersioningStrategy ([#2133](https://github.com/googleapis/release-please/issues/2133)) ([c9450df](https://github.com/googleapis/release-please/commit/c9450dffd7af3646a214d01a9b368ebab720be53)) + +## [16.3.0](https://github.com/googleapis/release-please/compare/v16.2.0...v16.3.0) (2023-11-10) + + +### Features + +* **deps:** Refactor node-workspace plugin to drop lerna-lite/core ([#2117](https://github.com/googleapis/release-please/issues/2117)) ([65fa72e](https://github.com/googleapis/release-please/commit/65fa72eb2f7931768d6aae5a45f04f037fe4f06a)) + +## [16.2.0](https://github.com/googleapis/release-please/compare/v16.1.0...v16.2.0) (2023-11-08) + + +### Features + +* Allow customizing PR body footer ([#2115](https://github.com/googleapis/release-please/issues/2115)) ([43014a1](https://github.com/googleapis/release-please/commit/43014a1f15d3640d67cb90cbf3047919facfa53e)) + + +### Bug Fixes + +* Correctly parse standalone prerelease PR body ([#2123](https://github.com/googleapis/release-please/issues/2123)) ([5ee9e3e](https://github.com/googleapis/release-please/commit/5ee9e3e9ae292dc4128717c3d5924da93b3bb670)) +* Set PR labels serially ([#2122](https://github.com/googleapis/release-please/issues/2122)) ([bf58911](https://github.com/googleapis/release-please/commit/bf58911d989f08abe3105309b6e6f918186e1125)) + +## [16.1.0](https://github.com/googleapis/release-please/compare/v16.0.0...v16.1.0) (2023-10-26) + + +### Features + +* Implement custom prerelease type ([#2083](https://github.com/googleapis/release-please/issues/2083)) ([97b0542](https://github.com/googleapis/release-please/commit/97b05421168316a23592897c8853893adf08d24c)) +* Update package-lock.json workspace entry versions ([#2088](https://github.com/googleapis/release-please/issues/2088)) ([dbb11bc](https://github.com/googleapis/release-please/commit/dbb11bc62d6c8135b5b168354e8f235398ffab03)), closes [#1993](https://github.com/googleapis/release-please/issues/1993) + + +### Bug Fixes + +* Releasable units should use version from pull-request body ([#2102](https://github.com/googleapis/release-please/issues/2102)) ([db035b7](https://github.com/googleapis/release-please/commit/db035b798f33c5ce0ddf2a43dcf2458c170c8fe3)), closes [#2101](https://github.com/googleapis/release-please/issues/2101) + +## [16.0.0](https://github.com/googleapis/release-please/compare/v15.13.0...v16.0.0) (2023-09-18) + + +### ⚠ BREAKING CHANGES + +* require node 18+ ([#2069](https://github.com/googleapis/release-please/issues/2069)) + +### Features + +* Fallback to root package version if package ignores github release ([#1935](https://github.com/googleapis/release-please/issues/1935)) ([0e11d4c](https://github.com/googleapis/release-please/commit/0e11d4c019f1e33cd713a237e037f31397d5371a)) +* Require node 18+ ([#2069](https://github.com/googleapis/release-please/issues/2069)) ([5a50247](https://github.com/googleapis/release-please/commit/5a5024727b93d0ba557b6f7ee5c6c1bab8d723d6)) +* Support pnpm workspaces ([#2058](https://github.com/googleapis/release-please/issues/2058)) ([13cba14](https://github.com/googleapis/release-please/commit/13cba14225cb836c74199d726a996f83122fab07)) +* Use default updaters based on file extension ([#2072](https://github.com/googleapis/release-please/issues/2072)) ([1ee162b](https://github.com/googleapis/release-please/commit/1ee162b3344e986afd09275f6762624e4a49faae)) + + +### Bug Fixes + +* **deps:** Bump semver dependency version ([#2068](https://github.com/googleapis/release-please/issues/2068)) ([cd0bd85](https://github.com/googleapis/release-please/commit/cd0bd853ac23087e5d5348c22f032fe0e533451d)) +* **deps:** Replace lerna dependency with lerna-lite ([13cba14](https://github.com/googleapis/release-please/commit/13cba14225cb836c74199d726a996f83122fab07)) +* **deps:** Upgrade http-proxy-agent to v7 ([#2071](https://github.com/googleapis/release-please/issues/2071)) ([cc50a34](https://github.com/googleapis/release-please/commit/cc50a34dee16115c07e574b05552678108f9e0c3)) +* **deps:** Upgrade https-proxy-agent to v7 ([cc50a34](https://github.com/googleapis/release-please/commit/cc50a34dee16115c07e574b05552678108f9e0c3)) + +## [15.13.0](https://github.com/googleapis/release-please/compare/v15.12.0...v15.13.0) (2023-08-18) + + +### Features + +* Adds metadata versioning for terraform modules ([#2041](https://github.com/googleapis/release-please/issues/2041)) ([49b33c7](https://github.com/googleapis/release-please/commit/49b33c73b2571699ad8362f8b6b934154a6ce375)) + +## [15.12.0](https://github.com/googleapis/release-please/compare/v15.11.2...v15.12.0) (2023-07-11) + + +### Features + +* Add PrereleaseVersioningStrategy ([#1981](https://github.com/googleapis/release-please/issues/1981)) ([b070888](https://github.com/googleapis/release-please/commit/b070888f25eff6e28c25014bcf67d6f9d47b9717)) + +## [15.11.2](https://github.com/googleapis/release-please/compare/v15.11.1...v15.11.2) (2023-07-10) + + +### Bug Fixes + +* **deps:** Update dependency conventional-changelog-conventionalcommits to v6 ([#1974](https://github.com/googleapis/release-please/issues/1974)) ([1998564](https://github.com/googleapis/release-please/commit/1998564555c472f4eb850cdcec99a009dd76f8ca)) +* **deps:** Update dependency conventional-changelog-writer to v6 ([#1975](https://github.com/googleapis/release-please/issues/1975)) ([a6aa293](https://github.com/googleapis/release-please/commit/a6aa293932200dd004024b8c8f6b458c2fa8f570)) + +## [15.11.1](https://github.com/googleapis/release-please/compare/v15.11.0...v15.11.1) (2023-07-10) + + +### Bug Fixes + +* **deps:** Update dependency conventional-commits-filter to v3 ([#1976](https://github.com/googleapis/release-please/issues/1976)) ([20b8f34](https://github.com/googleapis/release-please/commit/20b8f345624f2a7e639df1a50ebda2719f9c2423)) +* **python:** Warn on dynamic pyproject.toml versioning ([#1983](https://github.com/googleapis/release-please/issues/1983)) ([5ee5baa](https://github.com/googleapis/release-please/commit/5ee5baa0932d3435034b96183fed308eaf47ef73)) + +## [15.11.0](https://github.com/googleapis/release-please/compare/v15.10.5...v15.11.0) (2023-05-31) + + +### Features + +* **node:** Support package-lock.json version 3 ([#1940](https://github.com/googleapis/release-please/issues/1940)) ([77d80fb](https://github.com/googleapis/release-please/commit/77d80fb0c324cfadb91fd4a7ec656b2eb8eaeccb)), closes [#1939](https://github.com/googleapis/release-please/issues/1939) + + +### Bug Fixes + +* **helm:** Maintain any existing comments in Chart.yaml ([#1968](https://github.com/googleapis/release-please/issues/1968)) ([77de40e](https://github.com/googleapis/release-please/commit/77de40e6f8ceaac87d90948c0d7fa618dcd01163)) + +## [15.10.5](https://github.com/googleapis/release-please/compare/v15.10.4...v15.10.5) (2023-05-26) + + +### Bug Fixes + +* Allow configuring multiple, separate linked-versions plugins ([#1961](https://github.com/googleapis/release-please/issues/1961)) ([a3fac52](https://github.com/googleapis/release-please/commit/a3fac52b909bf62cfd934c48d139cc3cae9d37f1)) +* **php-yoshi:** Remove manifest.json, Version.php, and ServiceBuilder.php ([#1949](https://github.com/googleapis/release-please/issues/1949)) ([09fb84b](https://github.com/googleapis/release-please/commit/09fb84b9244649622b556a78a8b03f664213bcb7)) + +## [15.10.4](https://github.com/googleapis/release-please/compare/v15.10.3...v15.10.4) (2023-04-19) + + +### Bug Fixes + +* Add more trace logging when searching for latest release version ([#1922](https://github.com/googleapis/release-please/issues/1922)) ([c33cc81](https://github.com/googleapis/release-please/commit/c33cc8112fc366242182bcb3a28015c488f6140b)) + +## [15.10.3](https://github.com/googleapis/release-please/compare/v15.10.2...v15.10.3) (2023-04-11) + + +### Bug Fixes + +* NeedsBootstrap computation also considers tags ([#1915](https://github.com/googleapis/release-please/issues/1915)) ([2773b6e](https://github.com/googleapis/release-please/commit/2773b6e8ae6bf7bd98adb89ed0eb702a1705b27b)) + +## [15.10.2](https://github.com/googleapis/release-please/compare/v15.10.1...v15.10.2) (2023-04-11) + + +### Bug Fixes + +* **github-changelog-notes:** Prepend header to create parseable release notes ([#1912](https://github.com/googleapis/release-please/issues/1912)) ([3f53d40](https://github.com/googleapis/release-please/commit/3f53d40c8c3f927fffdf8973128e12450703a6e4)) + +## [15.10.1](https://github.com/googleapis/release-please/compare/v15.10.0...v15.10.1) (2023-04-10) + + +### Bug Fixes + +* **xml:** Preserve trailing newline if the xml file had one ([#1911](https://github.com/googleapis/release-please/issues/1911)) ([b899da6](https://github.com/googleapis/release-please/commit/b899da6637a5152fc13be5b89688c5f70c85563d)) + +## [15.10.0](https://github.com/googleapis/release-please/compare/v15.9.3...v15.10.0) (2023-04-10) + + +### Features + +* Allow excluding file paths to filter out commits ([#1875](https://github.com/googleapis/release-please/issues/1875)) ([a9bed82](https://github.com/googleapis/release-please/commit/a9bed8232ccaa192fb004953e34c49279d3c779f)) + +## [15.9.3](https://github.com/googleapis/release-please/compare/v15.9.2...v15.9.3) (2023-04-10) + + +### Bug Fixes + +* **python:** Handle large version numbers in setup.cfg ([#1906](https://github.com/googleapis/release-please/issues/1906)) ([9a7b11f](https://github.com/googleapis/release-please/commit/9a7b11f4d0797222fd65e871d4ba9f488a72d1d9)) + +## [15.9.2](https://github.com/googleapis/release-please/compare/v15.9.1...v15.9.2) (2023-03-28) + + +### Bug Fixes + +* **cargo-workspace:** Find workspace modules on the target branch ([#1889](https://github.com/googleapis/release-please/issues/1889)) ([9647941](https://github.com/googleapis/release-please/commit/96479413fd5fe9d1c546d829e70bfaf99b36661a)) + +## [15.9.1](https://github.com/googleapis/release-please/compare/v15.9.0...v15.9.1) (2023-03-14) + + +### Bug Fixes + +* **cargo-workspace:** Validate Cargo.toml version field ([#1877](https://github.com/googleapis/release-please/issues/1877)) ([0303e2e](https://github.com/googleapis/release-please/commit/0303e2eb9fb082bd9657baa117961d8567eba7e6)) + +## [15.9.0](https://github.com/googleapis/release-please/compare/v15.8.2...v15.9.0) (2023-03-14) + + +### Features + +* Support for "@" sign in component name ([#1873](https://github.com/googleapis/release-please/issues/1873)) ([d3b2f2f](https://github.com/googleapis/release-please/commit/d3b2f2f72c5aada66d3297d38b26d4aa3661177c)) + + +### Bug Fixes + +* Allow linked-versions to skip merging pull requests ([#1779](https://github.com/googleapis/release-please/issues/1779)) ([dc48b55](https://github.com/googleapis/release-please/commit/dc48b55b459754493513da30f68dc2588d3e30d4)) +* **refactor:** Rename Salesforce to sfdx ([#1829](https://github.com/googleapis/release-please/issues/1829)) ([122820d](https://github.com/googleapis/release-please/commit/122820d5a38a401e1bbdc4878b02f94cf405ad0e)) + +## [15.8.2](https://github.com/googleapis/release-please/compare/v15.8.1...v15.8.2) (2023-03-13) + + +### Bug Fixes + +* **cargo-workspaces:** Expand globs in crate paths ([#1852](https://github.com/googleapis/release-please/issues/1852)) ([0179f25](https://github.com/googleapis/release-please/commit/0179f25bf3bed7bca71c3cbdae6cc5a892954fe7)) + +## [15.8.1](https://github.com/googleapis/release-please/compare/v15.8.0...v15.8.1) (2023-03-07) + + +### Bug Fixes + +* **sequential-calls:** Use push instead of concat when returning releases ([#1865](https://github.com/googleapis/release-please/issues/1865)) ([1026c73](https://github.com/googleapis/release-please/commit/1026c7366a94b4dbfa567580613bcf31a991a516)) + +## [15.8.0](https://github.com/googleapis/release-please/compare/v15.7.0...v15.8.0) (2023-02-15) + + +### Features + +* Scan readme files in java-yoshi-mono-repo strategy ([#1853](https://github.com/googleapis/release-please/issues/1853)) ([635cc7d](https://github.com/googleapis/release-please/commit/635cc7d03820d539f470c151db410dd2a8d29eae)) + + +### Bug Fixes + +* Github issues link ([#1849](https://github.com/googleapis/release-please/issues/1849)) ([68e6759](https://github.com/googleapis/release-please/commit/68e67591bbae5db51ce0ce7591898a2adf49be96)) + +## [15.7.0](https://github.com/googleapis/release-please/compare/v15.6.0...v15.7.0) (2023-02-07) + + +### Features + +* **changelog.json:** Implement changelog.json for python ([#1841](https://github.com/googleapis/release-please/issues/1841)) ([52594b1](https://github.com/googleapis/release-please/commit/52594b194fdd0ae516776128e6511d5e4cd21518)) + +## [15.6.0](https://github.com/googleapis/release-please/compare/v15.5.1...v15.6.0) (2023-02-01) + + +### Features + +* **changelog.json:** Add pr suffix to issues array ([#1839](https://github.com/googleapis/release-please/issues/1839)) ([fdd75ef](https://github.com/googleapis/release-please/commit/fdd75efbc276d432f1d9d54f1790f4852a4aa3f7)) + +## [15.5.1](https://github.com/googleapis/release-please/compare/v15.5.0...v15.5.1) (2023-01-30) + + +### Bug Fixes + +* Support TOML up to v1.0.0-rc.1 spec. ([#1837](https://github.com/googleapis/release-please/issues/1837)) ([a3d94ee](https://github.com/googleapis/release-please/commit/a3d94eec209e00b6f513caa379096d082af7a72b)) + +## [15.5.0](https://github.com/googleapis/release-please/compare/v15.4.0...v15.5.0) (2023-01-27) + + +### Features + +* Add generic TOML updater ([#1833](https://github.com/googleapis/release-please/issues/1833)) ([2768a4c](https://github.com/googleapis/release-please/commit/2768a4cfe131ac8493447a8c7512c623c200df34)) +* Add toml generic updater option to extra-files schema ([#1835](https://github.com/googleapis/release-please/issues/1835)) ([9240f71](https://github.com/googleapis/release-please/commit/9240f71c21f077b240d2ce186456fb23b50dfd89)) + +## [15.4.0](https://github.com/googleapis/release-please/compare/v15.3.1...v15.4.0) (2023-01-26) + + +### Features + +* **changelog.json:** Include referenced issues/prs ([#1830](https://github.com/googleapis/release-please/issues/1830)) ([bacbbb5](https://github.com/googleapis/release-please/commit/bacbbb52ad802d42af1ffb40e8c616cc6c6601a6)) + +## [15.3.1](https://github.com/googleapis/release-please/compare/v15.3.0...v15.3.1) (2023-01-26) + + +### Bug Fixes + +* Filter changelog.json commits based on changelog sections ([#1827](https://github.com/googleapis/release-please/issues/1827)) ([844aacd](https://github.com/googleapis/release-please/commit/844aacd76434ae288ee3ac9b2061dd9406e99bd8)) + +## [15.3.0](https://github.com/googleapis/release-please/compare/v15.2.0...v15.3.0) (2023-01-25) + + +### Features + +* Add Salesforce strategy ([#1815](https://github.com/googleapis/release-please/issues/1815)) ([25b518f](https://github.com/googleapis/release-please/commit/25b518f4f34afcd749968d021f4eed99222a328a)) +* Add support for yarn workspace versions ([#1819](https://github.com/googleapis/release-please/issues/1819)) ([8b0cc7d](https://github.com/googleapis/release-please/commit/8b0cc7d7d203609c95e9e7cfbef4f0faedd3f46d)) +* **java-monorepo:** Switch to using .repo-metadata.json ([#1820](https://github.com/googleapis/release-please/issues/1820)) ([6cc85db](https://github.com/googleapis/release-please/commit/6cc85dbb95ade1c38c354a567a02b8a41d729a72)) +* **node:** Add support for changelog.json in Node ([#1823](https://github.com/googleapis/release-please/issues/1823)) ([d3e3bd3](https://github.com/googleapis/release-please/commit/d3e3bd3b102195befb051457f9a837ff47388157)) + +## [15.2.0](https://github.com/googleapis/release-please/compare/v15.1.2...v15.2.0) (2023-01-23) + + +### Features + +* **cli:** Add ability to dynamically load release-please plugin ([#1811](https://github.com/googleapis/release-please/issues/1811)) ([609383b](https://github.com/googleapis/release-please/commit/609383be5a05bb0107b489314b4bcd7615ddafd9)) +* Export Strategy interface so external packages can implement ([609383b](https://github.com/googleapis/release-please/commit/609383be5a05bb0107b489314b4bcd7615ddafd9)) +* Introduce ChangelogJson updater ([#1808](https://github.com/googleapis/release-please/issues/1808)) ([fe3a979](https://github.com/googleapis/release-please/commit/fe3a979a1c228610612aa2d6c303d408be956e2e)) +* Introduce JavaYoshiMonoRepo strategy ([#1810](https://github.com/googleapis/release-please/issues/1810)) ([2d14307](https://github.com/googleapis/release-please/commit/2d143077a545b92e1d9de923ab81ae1e12b7a468)) + +## [15.1.2](https://github.com/googleapis/release-please/compare/v15.1.1...v15.1.2) (2023-01-17) + + +### Bug Fixes + +* **ruby:** Gemfile.lock should not update when gem name is empty ([#1805](https://github.com/googleapis/release-please/issues/1805)) ([b54d499](https://github.com/googleapis/release-please/commit/b54d499a6b38e13175402fbd7eb7be75094d5014)) + +## [15.1.1](https://github.com/googleapis/release-please/compare/v15.1.0...v15.1.1) (2023-01-06) + + +### Bug Fixes + +* **deps:** Update @google-automations/git-file-utils to 1.2.5 ([89f363e](https://github.com/googleapis/release-please/commit/89f363e015bb3a5a7e738232352db70e4d336d86)) +* **deps:** Update code-suggester to 4.2.0 ([#1799](https://github.com/googleapis/release-please/issues/1799)) ([89f363e](https://github.com/googleapis/release-please/commit/89f363e015bb3a5a7e738232352db70e4d336d86)) + +## [15.1.0](https://github.com/googleapis/release-please/compare/v15.0.0...v15.1.0) (2023-01-05) + + +### Features + +* **ruby:** Add Gemfile.Lock updater ([#1790](https://github.com/googleapis/release-please/issues/1790)) ([9baf736](https://github.com/googleapis/release-please/commit/9baf736aa424bf3dcf0f05009e5cf8c9ef05fd69)) + + +### Bug Fixes + +* **java-yoshi:** Throw MissingRequiredFile error if no versions.txt found ([#1794](https://github.com/googleapis/release-please/issues/1794)) ([542d412](https://github.com/googleapis/release-please/commit/542d412307ea8d6350908aeb7efaf9db9e3d03f9)) + +## [15.0.0](https://github.com/googleapis/release-please/compare/v14.17.5...v15.0.0) (2022-12-12) + + +### ⚠ BREAKING CHANGES + +* Strategies can parse multiple releases from single release PR ([#1775](https://github.com/googleapis/release-please/issues/1775)) +* Parse conventional commits in manifest ([#1772](https://github.com/googleapis/release-please/issues/1772)) + +### Features + +* Strategies can parse multiple releases from single release PR ([#1775](https://github.com/googleapis/release-please/issues/1775)) ([b565f85](https://github.com/googleapis/release-please/commit/b565f85b64a431be1d62f8e682c183c4c1f1c631)) + + +### Code Refactoring + +* Parse conventional commits in manifest ([#1772](https://github.com/googleapis/release-please/issues/1772)) ([3391d3b](https://github.com/googleapis/release-please/commit/3391d3bc916ad07102bbb3873b93aeac6e13977c)) + +## [14.17.5](https://github.com/googleapis/release-please/compare/v14.17.4...v14.17.5) (2022-12-08) + + +### Bug Fixes + +* **expo:** Android version now correctly builds as a number ([#1770](https://github.com/googleapis/release-please/issues/1770)) ([d54483b](https://github.com/googleapis/release-please/commit/d54483be6d307aea75797f6a5bcfa6679b64088f)) + +## [14.17.4](https://github.com/googleapis/release-please/compare/v14.17.3...v14.17.4) (2022-12-01) + + +### Bug Fixes + +* Pass group-pull-request-title-pattern to strategies to parse releases ([#1760](https://github.com/googleapis/release-please/issues/1760)) ([f7601e4](https://github.com/googleapis/release-please/commit/f7601e423a267861fb86a441d1835ddf6da07a83)) + +## [14.17.3](https://github.com/googleapis/release-please/compare/v14.17.2...v14.17.3) (2022-11-26) + + +### Bug Fixes + +* Handle incrementing ruby patch versions larger than 1 digit ([#1762](https://github.com/googleapis/release-please/issues/1762)) ([7ad300e](https://github.com/googleapis/release-please/commit/7ad300e97a79acf4c3dbe0b9af8586eb32ab81cf)) + +## [14.17.2](https://github.com/googleapis/release-please/compare/v14.17.1...v14.17.2) (2022-11-22) + + +### Bug Fixes + +* Handle issue links in BREAKING_CHANGE notes section ([#1757](https://github.com/googleapis/release-please/issues/1757)) ([cd8c04b](https://github.com/googleapis/release-please/commit/cd8c04b4d7a67116b31baff60279fa6d719c73a0)) + +## [14.17.1](https://github.com/googleapis/release-please/compare/v14.17.0...v14.17.1) (2022-11-22) + + +### Bug Fixes + +* **dart:** Throw MissingRequiredFileError if pubspec.yaml is missing ([#1756](https://github.com/googleapis/release-please/issues/1756)) ([ada9fd6](https://github.com/googleapis/release-please/commit/ada9fd6db42aa6db0db52b8a81aa7f70b064e914)) +* **helm:** throw MissingRequiredFileError if Chart.yaml is missing ([ada9fd6](https://github.com/googleapis/release-please/commit/ada9fd6db42aa6db0db52b8a81aa7f70b064e914)) +* **node-workspace:** Maintain the dependency version prefix in newCandidate ([#1748](https://github.com/googleapis/release-please/issues/1748)) ([909d310](https://github.com/googleapis/release-please/commit/909d310defdf24adfd4858bbe1604668c14ef77f)) + ## [14.17.0](https://github.com/googleapis/release-please/compare/v14.16.0...v14.17.0) (2022-11-11) diff --git a/README.md b/README.md index a9b1c3908..84d0f3fba 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,26 @@ The most important prefixes you should have in mind are: * `feat!:`, or `fix!:`, `refactor!:`, etc., which represent a breaking change (indicated by the `!`) and will result in a SemVer major. +### Linear git commit history (use squash-merge) + +We **highly** recommend that you use squash-merges when merging pull requests. +A linear git history makes it much easier to: + +* Follow history - commits are sorted by merge date and are not mixed between + pull requests +* Find and revert bugs - `git bisect` is helpful for tracking down which + change introduced a bug +* Control the release-please changelog - when you merge a PR, you may have + commit messages that make sense within the scope of the PR, but don't + make sense when merged in the main branch. For example, you may have + `feat: introduce feature A` and then `fix: some bugfix introduced in + the first commit`. The `fix` commit is actually irrelevant to the release + notes as there was never a bug experienced in the main branch. +* Keep a clean main branch - if you use something like red/green development + (create a failing test in commit A, then fix in commit B) and merge (or + rebase-merge), then there will be points in time in your main branch where + tests do not pass. + ### What if my PR contains multiple fixes or features? Release Please allows you to represent multiple changes in a single commit, @@ -79,7 +99,7 @@ The above commit message will contain: that it's a breaking change. 3. an entry for the feature **"update encode to support unicode"**. -> :warning: **Important:** The additional messages must be added to the bottom of the commit. +:warning: **Important:** The additional messages must be added to the bottom of the commit. ## How do I change the version number? @@ -113,8 +133,14 @@ END_COMMIT_OVERRIDE The next time Release Please runs, it will use that override section as the commit message instead of the merged commit message. +:warning: **Important:** This feature will not work with plain merges because +release-please does not know which commit(s) to apply the override to. [We +recommend using squash-merge instead](#linear-git-commit-history-use-squash-merge). + ## Release Please bot does not create a release PR. Why? +### Step 1: Ensure releasable units are merged + Release Please creates a release pull request after it notices the default branch contains "releasable units" since the last release. A releasable unit is a commit to the branch with one of the following @@ -124,6 +150,26 @@ prefixes: "feat", "fix", and "deps". Some languages have their specific releasable unit configuration. For example, "docs" is a prefix for releasable units in Java and Python. +### Step 2: Ensure no `autorelease: pending` or `autorelease: triggered` label in an old PR + +Check existing pull requests labelled with `autorelease: pending` or +`autorelease: triggered` label. +Due to GitHub API failures, it's possible that the tag was not removed +correctly upon a previous release and Release Please thinks that the previous release is +still pending. +If you're certain that there's no pending release, remove the +`autorelease: pending` or `autorelease: triggered` label. + +For the GitHub application users, Release Please will not create a new pull request +if there's an existing pull request labeled as `autorelease: pending`. +To confirm this case, search for a pull request with the label. +(It's very likely it's the latest release pull request.) +If you find a release pull request with the label and it is not going to be released +(or already released), then remove the `autorelease: pending` label and re-run Release +Please. + +### Step 3: Rerun Release Please + If you think Release Please missed creating a release PR after a pull request with a releasable unit has been merged, please re-run `release-please`. If you are using the GitHub application, add `release-please:force-run` label to the merged pull request. If @@ -144,12 +190,13 @@ Release Please automates releases for the following flavors of repositories: | `krm-blueprint` | [A kpt package, with 1 or more KRM files and a CHANGELOG.md](https://github.com/GoogleCloudPlatform/blueprints/tree/main/catalog/project) | | `maven` | [Strategy for Maven projects, generates SNAPSHOT version after each release and updates `pom.xml` automatically](docs/java.md) | | `node` | [A Node.js repository, with a package.json and CHANGELOG.md](https://github.com/yargs/yargs) | -| `expo` | [An Expo based React Native repository, with a package.json, app.json and CHANGELOG.md](https://github.com/yargs/yargs) | +| `expo` | An Expo based React Native repository, with a package.json, app.json and CHANGELOG.md | | `ocaml` | [An OCaml repository, containing 1 or more opam or esy files and a CHANGELOG.md](https://github.com/grain-lang/binaryen.ml) | | `php` | A repository with a composer.json and a CHANGELOG.md | | `python` | [A Python repository, with a setup.py, setup.cfg, CHANGELOG.md](https://github.com/googleapis/python-storage) and optionally a pyproject.toml and a <project>/\_\_init\_\_.py | | `ruby` | A repository with a version.rb and a CHANGELOG.md | -| `rust` | A Rust repository, with a Cargo.toml (either as a crate or workspace) and a CHANGELOG.md | +| `rust` | A Rust repository, with a Cargo.toml (either as a crate or workspace, although note that workspaces require a [manifest driven release](https://github.com/googleapis/release-please/blob/main/docs/manifest-releaser.md) and the "cargo-workspace" plugin) and a CHANGELOG.md | +| `sfdx` | A repository with a [sfdx-project.json](https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_ws_config.htm) and a CHANGELOG.md | | `simple` | [A repository with a version.txt and a CHANGELOG.md](https://github.com/googleapis/gapic-generator) | | `terraform-module` | [A terraform module, with a version in the README.md, and a CHANGELOG.md](https://github.com/terraform-google-modules/terraform-google-project-factory) | diff --git a/__snapshots__/app-json.js b/__snapshots__/app-json.js index bdd5953e5..ccd886696 100644 --- a/__snapshots__/app-json.js +++ b/__snapshots__/app-json.js @@ -30,7 +30,7 @@ exports['AppJson updateContent updates the app versions 1'] = ` }, "android": { "package": "com.somedomain", - "versionCode": "440030201", + "versionCode": 440030201, "adaptiveIcon": { "foregroundImage": "./assets/icon-inverse.png", "backgroundColor": "#FFFFFF" diff --git a/__snapshots__/base.js b/__snapshots__/base.js index 77952a2b1..c34a5e7f9 100644 --- a/__snapshots__/base.js +++ b/__snapshots__/base.js @@ -8,7 +8,7 @@ exports['Strategy buildReleasePullRequest allows overriding initial version 1'] ### Miscellaneous Chores -* initial commit ([abc123](https://github.com/googleapis/base-test-repo/commit/abc123)) +* initial commit ([16d3754](https://github.com/googleapis/base-test-repo/commit/16d3754a2134a6d19ee19d2e5ba4dfbc)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). @@ -24,7 +24,7 @@ exports['Strategy buildReleasePullRequest allows overriding initial version in b ### Features -* initial commit ([abc123](https://github.com/googleapis/base-test-repo/commit/abc123)) +* initial commit ([a90fc00](https://github.com/googleapis/base-test-repo/commit/a90fc00ca62382346da72dd8f51078a7)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). @@ -40,7 +40,7 @@ exports['Strategy buildReleasePullRequest should pass changelogHost to default b ### Bug Fixes -* a bugfix ([abc5566](https://example.com/googleapis/base-test-repo/commit/abc5566)) +* a bugfix ([6c1715c](https://example.com/googleapis/base-test-repo/commit/6c1715c07438036db68bb939cf36fe6f)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). diff --git a/__snapshots__/cargo-workspace.js b/__snapshots__/cargo-workspace.js index fd9d682cc..b5a4477e8 100644 --- a/__snapshots__/cargo-workspace.js +++ b/__snapshots__/cargo-workspace.js @@ -140,6 +140,25 @@ Release notes for path: packages/rustA, releaseType: rust This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). ` +exports['CargoWorkspace plugin run handles glob paths 1'] = ` +:robot: I have created a release *beep* *boop* +--- + + +
@here/pkgA: 1.1.2 + +Release notes for path: packages/rustA, releaseType: rust +
+ +
@here/pkgD: 4.4.5 + +Release notes for path: packages/rustD, releaseType: rust +
+ +--- +This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). +` + exports['CargoWorkspace plugin run skips component if not touched 1'] = ` :robot: I have created a release *beep* *boop* --- diff --git a/__snapshots__/changelog-json.js b/__snapshots__/changelog-json.js new file mode 100644 index 000000000..febbf9754 --- /dev/null +++ b/__snapshots__/changelog-json.js @@ -0,0 +1,116 @@ +exports['changelog.json adds PR # suffix to issues array 1'] = ` +{ + "repository": "foo/bar", + "entries": [ + { + "changes": [ + { + "type": "feat", + "sha": "81228f3507ad6f742242474628ff58b2", + "message": "some feature", + "issues": [] + }, + { + "type": "fix", + "sha": "4e34bedd7131c9e6b0060038b0eba8cf", + "message": "Support TOML up to v1.0.0-rc.1 spec.", + "issues": [ + "1837" + ] + }, + { + "type": "docs", + "sha": "abbf5480ac552b33404be825a817df2a", + "message": "some documentation", + "issues": [] + } + ], + "version": "14.0.0", + "language": "JAVA", + "artifactName": "foo-artifact", + "id": "abc-123-efd-qwerty", + "createTime": "2023-01-05T16:42:33.446Z" + }, + {}, + {} + ], + "updateTime": "2023-01-05T16:42:33.446Z" +} +` + +exports['changelog.json prepends latest release to existing changelog 1'] = ` +{ + "repository": "foo/bar", + "entries": [ + { + "changes": [ + { + "type": "feat", + "sha": "81228f3507ad6f742242474628ff58b2", + "message": "some feature", + "issues": [] + }, + { + "type": "fix", + "sha": "26fff5655027c8e7b799cb450acca568", + "message": "some bugfix", + "issues": [] + }, + { + "type": "docs", + "sha": "abbf5480ac552b33404be825a817df2a", + "message": "some documentation", + "issues": [] + } + ], + "version": "14.0.0", + "language": "JAVA", + "artifactName": "foo-artifact", + "id": "abc-123-efd-qwerty", + "createTime": "2023-01-05T16:42:33.446Z" + }, + {}, + {} + ], + "updateTime": "2023-01-05T16:42:33.446Z" +} +` + +exports['changelog.json prepends new release to empty changelog 1'] = ` +{ + "repository": "foo/bar", + "entries": [ + { + "changes": [ + { + "type": "feat", + "sha": "81228f3507ad6f742242474628ff58b2", + "message": "some feature", + "issues": [] + }, + { + "type": "fix", + "sha": "05670cf2e850beffe53bb2691f8701c7", + "message": "some bugfix", + "issues": [], + "breakingChangeNote": "some bugfix" + }, + { + "type": "docs", + "sha": "e0a7c3eb307bdca5f9d4c991c82338da", + "message": "some documentation", + "issues": [], + "scope": "perf", + "breakingChangeNote": "some documentation" + } + ], + "version": "14.0.0", + "language": "JAVA", + "artifactName": "foo-artifact", + "id": "abc-123-efd-qwerty", + "createTime": "2023-01-05T16:42:33.446Z" + } + ], + "updateTime": "2023-01-05T16:42:33.446Z" +} +` diff --git a/__snapshots__/chart-yaml.js b/__snapshots__/chart-yaml.js index 6c31eeca8..e50f04df4 100644 --- a/__snapshots__/chart-yaml.js +++ b/__snapshots__/chart-yaml.js @@ -1,12 +1,27 @@ exports['ChartYaml updateContent updates version in Chart.yaml 1'] = ` +# Copyright 2021 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + name: helm-test-repo version: 1.1.0 apiVersion: v2 +# renovate: image=imageName appVersion: 2.0.0 dependencies: - name: another-repo version: 0.15.3 - repository: linkToHelmChartRepo + repository: "linkToHelmChartRepo" maintainers: - Abhinav Khanna diff --git a/__snapshots__/cli.js b/__snapshots__/cli.js index 2ce0e42ff..d30de7546 100644 --- a/__snapshots__/cli.js +++ b/__snapshots__/cli.js @@ -10,6 +10,8 @@ Options: debugging). [boolean] [default: false] --trace print extra verbose errors (use only for local debugging). [boolean] [default: false] + --plugin load plugin named release-please- + [array] [default: []] --token GitHub token with repo write permissions --api-url URL to use when making API requests [string] [default: "https://api.github.com"] @@ -29,6 +31,7 @@ Options: branches [boolean] [default: false] --pull-request-title-pattern Title pattern to make release PR [string] --pull-request-header Header for release PR [string] + --pull-request-footer Footer for release PR [string] --path release from path other than root directory [string] --component name of component release is being minted for @@ -39,8 +42,9 @@ Options: for? [choices: "dart", "dotnet-yoshi", "elixir", "expo", "go", "go-yoshi", "helm", "java", "java-backport", "java-bom", "java-lts", "java-yoshi", - "krm-blueprint", "maven", "node", "ocaml", "php", "php-yoshi", "python", - "ruby", "ruby-yoshi", "rust", "simple", "terraform-module"] + "java-yoshi-mono-repo", "krm-blueprint", "maven", "node", "ocaml", "php", + "php-yoshi", "python", "ruby", "ruby-yoshi", "rust", "salesforce", "sfdx", + "simple", "terraform-module"] --config-file where can the config file be found in the project? [default: "release-please-config.json"] --manifest-file where can the manifest file be found in the @@ -75,6 +79,8 @@ Options: [boolean] [default: false] --trace print extra verbose errors (use only for local debugging). [boolean] [default: false] + --plugin load plugin named release-please- + [array] [default: []] --token GitHub token with repo write permissions --api-url URL to use when making API requests [string] [default: "https://api.github.com"] @@ -114,6 +120,8 @@ Options: [boolean] [default: false] --trace print extra verbose errors (use only for local debugging). [boolean] [default: false] + --plugin load plugin named release-please- + [array] [default: []] --token GitHub token with repo write permissions --api-url URL to use when making API requests [string] [default: "https://api.github.com"] @@ -156,6 +164,9 @@ Options: debugging). [boolean] [default: false] --trace print extra verbose errors (use only for local debugging). [boolean] [default: false] + --plugin load plugin named + release-please- + [array] [default: []] --token GitHub token with repo write permissions --api-url URL to use when making API requests [string] [default: "https://api.github.com"] @@ -178,6 +189,7 @@ Options: the minor for non-breaking changes prior to the first major release [boolean] [default: false] + --prerelease-type type of the prerelease, e.g., alpha [string] --extra-files extra files for the strategy to consider [string] --version-file path to version file to update, e.g., @@ -186,7 +198,7 @@ Options: generated? [boolean] [default: false] --versioning-strategy strategy used for bumping versions [choices: "always-bump-major", "always-bump-minor", "always-bump-patch", - "default", "service-pack"] [default: "default"] + "default", "prerelease", "service-pack"] [default: "default"] --changelog-path where can the CHANGELOG be found in the project? [string] [default: "CHANGELOG.md"] --changelog-type type of changelog to build @@ -220,6 +232,7 @@ Options: branches [boolean] [default: false] --pull-request-title-pattern Title pattern to make release PR [string] --pull-request-header Header for release PR [string] + --pull-request-footer Footer for release PR [string] --path release from path other than root directory [string] --component name of component release is being minted @@ -230,8 +243,9 @@ Options: for? [choices: "dart", "dotnet-yoshi", "elixir", "expo", "go", "go-yoshi", "helm", "java", "java-backport", "java-bom", "java-lts", "java-yoshi", - "krm-blueprint", "maven", "node", "ocaml", "php", "php-yoshi", "python", - "ruby", "ruby-yoshi", "rust", "simple", "terraform-module"] + "java-yoshi-mono-repo", "krm-blueprint", "maven", "node", "ocaml", "php", + "php-yoshi", "python", "ruby", "ruby-yoshi", "rust", "salesforce", "sfdx", + "simple", "terraform-module"] --config-file where can the config file be found in the project? [default: "release-please-config.json"] diff --git a/__snapshots__/default-changelog-notes.js b/__snapshots__/default-changelog-notes.js index 623c6c5ff..1116f347e 100644 --- a/__snapshots__/default-changelog-notes.js +++ b/__snapshots__/default-changelog-notes.js @@ -109,6 +109,19 @@ exports['DefaultChangelogNotes buildNotes with commit parsing should handle a br * some bugfix ([05670cf](https://github.com/googleapis/java-asset/commit/05670cf2e850beffe53bb2691f8701c7)) ` +exports['DefaultChangelogNotes buildNotes with commit parsing should handle a breaking change with reference 1'] = ` +## [1.2.3](https://github.com/googleapis/java-asset/compare/v1.2.2...v1.2.3) (1983-10-10) + + +### ⚠ BREAKING CHANGES + +* some bugfix ([#1234](https://github.com/googleapis/java-asset/issues/1234)) + +### Bug Fixes + +* some bugfix ([#1234](https://github.com/googleapis/java-asset/issues/1234)) ([749cd8b](https://github.com/googleapis/java-asset/commit/749cd8b9edc6103a2f40a34ca45c31c5)) +` + exports['DefaultChangelogNotes buildNotes with commit parsing should handle bug links 1'] = ` ## [1.2.3](https://github.com/googleapis/java-asset/compare/v1.2.2...v1.2.3) (1983-10-10) @@ -140,6 +153,15 @@ exports['DefaultChangelogNotes buildNotes with commit parsing should handle html * render all imagesets as <picture> ([383fb14](https://github.com/googleapis/java-asset/commit/383fb14708ae91f7bb7e64bf0bacab38)) ` +exports['DefaultChangelogNotes buildNotes with commit parsing should handle inline bug links 1'] = ` +## [1.2.3](https://github.com/googleapis/java-asset/compare/v1.2.2...v1.2.3) (1983-10-10) + + +### Bug Fixes + +* some bugfix ([#1234](https://github.com/googleapis/java-asset/issues/1234)) ([6f2163b](https://github.com/googleapis/java-asset/commit/6f2163be093d8a8dd90232d06b45c07e)) +` + exports['DefaultChangelogNotes buildNotes with commit parsing should handle meta commits 1'] = ` ## [1.2.3](https://github.com/googleapis/java-asset/compare/v1.2.2...v1.2.3) (1983-10-10) diff --git a/__snapshots__/gemfile-lock.js b/__snapshots__/gemfile-lock.js new file mode 100644 index 000000000..b4629f8bd --- /dev/null +++ b/__snapshots__/gemfile-lock.js @@ -0,0 +1,191 @@ +exports['Gemfile.lock updateContent does not update anything if gem name is not provided 1'] = ` +PATH + remote: . + specs: + foo (0.1.0) + +GEM + remote: https://rubygems.org/ + specs: + ast (2.4.2) + foobar (1.0.1) + diff-lcs (1.5.0) + json (2.6.3) + parallel (1.22.1) + parser (3.1.3.0) + ast (~> 2.4.1) + rainbow (3.1.1) + rake (13.0.6) + regexp_parser (2.6.1) + rexml (3.2.5) + rspec (3.12.0) + rspec-core (~> 3.12.0) + rspec-expectations (~> 3.12.0) + rspec-mocks (~> 3.12.0) + rspec-core (3.12.0) + rspec-support (~> 3.12.0) + rspec-expectations (3.12.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.12.0) + rspec-mocks (3.12.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.12.0) + rspec-support (3.12.0) + rubocop (1.39.0) + json (~> 2.3) + parallel (~> 1.10) + parser (>= 3.1.2.1) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 1.8, < 3.0) + rexml (>= 3.2.5, < 4.0) + rubocop-ast (>= 1.23.0, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 1.4.0, < 3.0) + rubocop-ast (1.24.0) + parser (>= 3.1.1.0) + ruby-progressbar (1.11.0) + unicode-display_width (2.3.0) + +PLATFORMS + ruby + +DEPENDENCIES + bundler + foo! + foobar + rake + rspec + rubocop + +BUNDLED WITH + 2.3.26 + +` + +exports['Gemfile.lock updateContent updates prerelease in Gemfile.lock 1'] = ` +PATH + remote: . + specs: + foo (0.2.0.pre.alpha) + +GEM + remote: https://rubygems.org/ + specs: + ast (2.4.2) + foobar (1.0.1) + diff-lcs (1.5.0) + json (2.6.3) + parallel (1.22.1) + parser (3.1.3.0) + ast (~> 2.4.1) + rainbow (3.1.1) + rake (13.0.6) + regexp_parser (2.6.1) + rexml (3.2.5) + rspec (3.12.0) + rspec-core (~> 3.12.0) + rspec-expectations (~> 3.12.0) + rspec-mocks (~> 3.12.0) + rspec-core (3.12.0) + rspec-support (~> 3.12.0) + rspec-expectations (3.12.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.12.0) + rspec-mocks (3.12.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.12.0) + rspec-support (3.12.0) + rubocop (1.39.0) + json (~> 2.3) + parallel (~> 1.10) + parser (>= 3.1.2.1) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 1.8, < 3.0) + rexml (>= 3.2.5, < 4.0) + rubocop-ast (>= 1.23.0, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 1.4.0, < 3.0) + rubocop-ast (1.24.0) + parser (>= 3.1.1.0) + ruby-progressbar (1.11.0) + unicode-display_width (2.3.0) + +PLATFORMS + ruby + +DEPENDENCIES + bundler + foo! + foobar + rake + rspec + rubocop + +BUNDLED WITH + 2.3.26 + +` + +exports['Gemfile.lock updateContent updates version in Gemfile.lock 1'] = ` +PATH + remote: . + specs: + foo (0.2.0) + +GEM + remote: https://rubygems.org/ + specs: + ast (2.4.2) + foobar (1.0.1) + diff-lcs (1.5.0) + json (2.6.3) + parallel (1.22.1) + parser (3.1.3.0) + ast (~> 2.4.1) + rainbow (3.1.1) + rake (13.0.6) + regexp_parser (2.6.1) + rexml (3.2.5) + rspec (3.12.0) + rspec-core (~> 3.12.0) + rspec-expectations (~> 3.12.0) + rspec-mocks (~> 3.12.0) + rspec-core (3.12.0) + rspec-support (~> 3.12.0) + rspec-expectations (3.12.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.12.0) + rspec-mocks (3.12.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.12.0) + rspec-support (3.12.0) + rubocop (1.39.0) + json (~> 2.3) + parallel (~> 1.10) + parser (>= 3.1.2.1) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 1.8, < 3.0) + rexml (>= 3.2.5, < 4.0) + rubocop-ast (>= 1.23.0, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 1.4.0, < 3.0) + rubocop-ast (1.24.0) + parser (>= 3.1.1.0) + ruby-progressbar (1.11.0) + unicode-display_width (2.3.0) + +PLATFORMS + ruby + +DEPENDENCIES + bundler + foo! + foobar + rake + rspec + rubocop + +BUNDLED WITH + 2.3.26 + +` diff --git a/__snapshots__/generic-toml.js b/__snapshots__/generic-toml.js new file mode 100644 index 000000000..6bed582be --- /dev/null +++ b/__snapshots__/generic-toml.js @@ -0,0 +1,91 @@ +exports['GenericToml updateContent updates deep entry in toml 1'] = ` +[package] +name = "rust-test-repo" +version = "12.0.0" + +# To learn about other keys, check out Cargo's documentation + +[dependencies] +normal-dep = "1.2.3" + +[dev-dependencies] +dev-dep = { version = "2.3.4" } +dev-dep-2 = { path = "../dev-dep-2" } + +[build-dependencies] +# this is using a private registry +build-dep = { version = "1.2.3", registry = "private", path = ".." } # trailing comment + +[target.'cfg(windows)'.dev-dependencies] +windows-dep = { version = "1.2.3", registry = "private", path = ".." } + +[target.'cfg(unix)'.dependencies] +unix-dep = { version = "1.2.3", registry = "private", path = ".." } + +[target.'cfg(target_arch = "x86")'.dependencies] +x86-dep = { version = "1.2.3", registry = "private", path = ".." } + +[target.'cfg(target_arch = "x86_64")'.dependencies] +x86-64-dep = { version = "1.2.3", registry = "private", path = ".." } + +[target.'cfg(foobar)'.dependencies] +foobar-dep = "1.2.3" + +` + +exports['GenericToml updateContent updates matching entry 1'] = ` +[package] +name = "rust-test-repo" +version = "2.3.4" + +# To learn about other keys, check out Cargo's documentation + +[dependencies] +normal-dep = "1.2.3" + +[dev-dependencies] +dev-dep = { version = "1.2.3" } +dev-dep-2 = { path = "../dev-dep-2" } + +[build-dependencies] +# this is using a private registry +build-dep = { version = "1.2.3", registry = "private", path = ".." } # trailing comment + +[target.'cfg(windows)'.dev-dependencies] +windows-dep = { version = "1.2.3", registry = "private", path = ".." } + +[target.'cfg(unix)'.dependencies] +unix-dep = { version = "1.2.3", registry = "private", path = ".." } + +[target.'cfg(target_arch = "x86")'.dependencies] +x86-dep = { version = "1.2.3", registry = "private", path = ".." } + +[target.'cfg(target_arch = "x86_64")'.dependencies] +x86-64-dep = { version = "1.2.3", registry = "private", path = ".." } + +[target.'cfg(foobar)'.dependencies] +foobar-dep = "1.2.3" + +` + +exports['GenericToml updateContent updates matching entry with TOML v1.0.0 spec 1'] = ` +[package] +version = "2.3.4" + +[v1spec] +# taken from toml.io#Arrays examples +integers = [ 1, 2, 3 ] +colors = [ "red", "yellow", "green" ] +nested_arrays_of_ints = [ [ 1, 2 ], [3, 4, 5] ] +nested_mixed_array = [ [ 1, 2 ], ["a", "b", "c"] ] +string_array = [ "all", 'strings', """are the same""", '''type''' ] + +[heterogenous] +# Mixed-type arrays are allowed +numbers = [ 0.1, 0.2, 0.5, 1, 2, 5 ] +contributors = [ + "Foo Bar ", + { name = "Baz Qux", email = "bazqux@example.com", url = "https://example.com/bazqux" } +] + +` diff --git a/__snapshots__/github-changelog-notes.js b/__snapshots__/github-changelog-notes.js new file mode 100644 index 000000000..c99600410 --- /dev/null +++ b/__snapshots__/github-changelog-notes.js @@ -0,0 +1,5 @@ +exports['GitHubChangelogNotes buildNotes should build release notes from GitHub 1'] = ` +## 1.2.3 (1983-10-10) + +##Changes in Release v1.0.0 ... ##Contributors @monalisa +` diff --git a/__snapshots__/github.js b/__snapshots__/github.js index 9524e2afd..af1c14c8b 100644 --- a/__snapshots__/github.js +++ b/__snapshots__/github.js @@ -2,6 +2,43 @@ exports['GitHub commentOnIssue can create a comment 1'] = { "body": "This is a comment" } +exports['GitHub commitsSince backfills commit files for pull requests rebased and merged 1'] = [ + { + "sha": "b29149f890e6f76ee31ed128585744d4c598924c", + "message": "feat: feature-branch-rebase-merge commit 1", + "pullRequest": { + "sha": "b29149f890e6f76ee31ed128585744d4c598924c", + "number": 7, + "baseBranchName": "main", + "headBranchName": "feature-branch-rebase-merge", + "title": "feat: feature that will be rebase merged", + "body": "", + "labels": [], + "files": [] + }, + "files": [ + "abc" + ] + }, + { + "sha": "27d7d7232e2e312d1380e906984f0823f5decf61", + "message": "feat: feature-branch-rebase-merge commit 2", + "pullRequest": { + "sha": "27d7d7232e2e312d1380e906984f0823f5decf61", + "number": 7, + "baseBranchName": "main", + "headBranchName": "feature-branch-rebase-merge", + "title": "feat: feature that will be rebase merged", + "body": "", + "labels": [], + "files": [] + }, + "files": [ + "def" + ] + } +] + exports['GitHub commitsSince backfills commit files for pull requests with lots of files 1'] = [ { "sha": "e6daec403626c9987c7af0d97b34f324cd84320a", diff --git a/__snapshots__/java-yoshi-mono-repo.js b/__snapshots__/java-yoshi-mono-repo.js new file mode 100644 index 000000000..c0514c5e3 --- /dev/null +++ b/__snapshots__/java-yoshi-mono-repo.js @@ -0,0 +1,58 @@ +exports['JavaYoshiMonoRepo buildUpdates does not update changelog.json if no .repo-metadata.json is found 1'] = ` +{"entries":[]} +` + +exports['JavaYoshiMonoRepo buildUpdates omits non-breaking chores from changelog.json 1'] = ` +{ + "entries": [ + { + "changes": [ + { + "type": "fix", + "sha": "845db1381b3d5d20151cad2588f85feb", + "message": "update dependency com.google.cloud:google-cloud-storage to v1.120.0", + "issues": [], + "scope": "deps" + }, + { + "type": "chore", + "sha": "b3f8966b023b8f21ce127142aa91841c", + "message": "update a very important dep", + "issues": [], + "breakingChangeNote": "update a very important dep" + } + ], + "version": "0.1.0", + "language": "JAVA", + "artifactName": "cloud.google.com:foo", + "id": "abc-123-efd-qwerty", + "createTime": "2023-01-05T16:42:33.446Z" + } + ], + "updateTime": "2023-01-05T16:42:33.446Z" +} +` + +exports['JavaYoshiMonoRepo buildUpdates updates changelog.json 1'] = ` +{ + "entries": [ + { + "changes": [ + { + "type": "fix", + "sha": "845db1381b3d5d20151cad2588f85feb", + "message": "update dependency com.google.cloud:google-cloud-storage to v1.120.0", + "issues": [], + "scope": "deps" + } + ], + "version": "0.1.0", + "language": "JAVA", + "artifactName": "cloud.google.com:foo", + "id": "abc-123-efd-qwerty", + "createTime": "2023-01-05T16:42:33.446Z" + } + ], + "updateTime": "2023-01-05T16:42:33.446Z" +} +` diff --git a/__snapshots__/linked-versions-group-title.js b/__snapshots__/linked-versions-group-title.js new file mode 100644 index 000000000..e35e08b53 --- /dev/null +++ b/__snapshots__/linked-versions-group-title.js @@ -0,0 +1,28 @@ +exports['Plugin compatibility linked-versions and group-pull-request-title-pattern should find release to create 1'] = ` +:robot: I have created a release *beep* *boop* +--- + + +
primary: 1.1.0 + +## [1.1.0](https://github.com/fake-owner/fake-repo/compare/primary-v1.0.0...primary-v1.1.0) (1983-10-10) + + +### Features + +* some feature ([aaaaaa](https://github.com/fake-owner/fake-repo/commit/aaaaaa)) +
+ +
pkgA: 1.1.0 + +## [1.1.0](https://github.com/fake-owner/fake-repo/compare/pkgA-v1.0.0...pkgA-v1.1.0) (1983-10-10) + + +### Features + +* some feature ([aaaaaa](https://github.com/fake-owner/fake-repo/commit/aaaaaa)) +
+ +--- +This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). +` diff --git a/__snapshots__/linked-versions.js b/__snapshots__/linked-versions.js index 5e629f719..df70dece0 100644 --- a/__snapshots__/linked-versions.js +++ b/__snapshots__/linked-versions.js @@ -19,6 +19,67 @@ exports['LinkedVersions plugin can skip grouping pull requests 2'] = ` --- +## [0.2.4](https://github.com/fake-owner/fake-repo/compare/pkg2-v0.2.3...pkg2-v0.2.4) (1983-10-10) + + +### Bug Fixes + +* some bugfix ([bbbbbb](https://github.com/fake-owner/fake-repo/commit/bbbbbb)) + +--- +This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). +` + +exports['LinkedVersions plugin can skip grouping pull requests 3'] = ` +:robot: I have created a release *beep* *boop* +--- + + +## [0.2.4](https://github.com/fake-owner/fake-repo/compare/pkg3-v0.2.3...pkg3-v0.2.4) (1983-10-10) + + +### Miscellaneous Chores + +* **pkg3:** Synchronize group name versions + +--- +This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). +` + +exports['LinkedVersions plugin should allow multiple groups of linked versions 1'] = ` +:robot: I have created a release *beep* *boop* +--- + + +
pkg1: 1.0.1 + +## [1.0.1](https://github.com/fake-owner/fake-repo/compare/pkg1-v1.0.0...pkg1-v1.0.1) (1983-10-10) + + +### Bug Fixes + +* some bugfix ([aaaaaa](https://github.com/fake-owner/fake-repo/commit/aaaaaa)) +
+ +
pkg4: 1.0.1 + +## [1.0.1](https://github.com/fake-owner/fake-repo/compare/pkg4-v1.0.0...pkg4-v1.0.1) (1983-10-10) + + +### Miscellaneous Chores + +* **pkg4:** Synchronize second group name versions +
+ +--- +This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). +` + +exports['LinkedVersions plugin should allow multiple groups of linked versions 2'] = ` +:robot: I have created a release *beep* *boop* +--- + +
pkg2: 0.2.4 ## [0.2.4](https://github.com/fake-owner/fake-repo/compare/pkg2-v0.2.3...pkg2-v0.2.4) (1983-10-10) diff --git a/__snapshots__/manifest.js b/__snapshots__/manifest.js index 764742965..6c37ce136 100644 --- a/__snapshots__/manifest.js +++ b/__snapshots__/manifest.js @@ -117,7 +117,7 @@ exports['Manifest buildPullRequests should handle mixing componentless configs 1 This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). ` -exports['Manifest buildPullRequests should handle multiple package repository 1'] = ` +exports['Manifest buildPullRequests with multiple packages should handle multiple package repository 1'] = ` :robot: I have created a release *beep* *boop* --- diff --git a/__snapshots__/metadata.js b/__snapshots__/metadata.js new file mode 100644 index 000000000..96a6e215a --- /dev/null +++ b/__snapshots__/metadata.js @@ -0,0 +1,11 @@ +exports['metadata.yaml updateContent updates version in metadata.yaml 1'] = ` +apiVersion: blueprints.cloud.google.com/v1alpha1 +kind: BlueprintMetadata +metadata: + name: foo +spec: + info: + title: bar + version: 2.1.0 + +` diff --git a/__snapshots__/node-workspace.js b/__snapshots__/node-workspace.js index 6d359096f..56175e499 100644 --- a/__snapshots__/node-workspace.js +++ b/__snapshots__/node-workspace.js @@ -27,6 +27,15 @@ Release notes for path: node1, releaseType: node * @here/pkgB bumped from 2.2.2 to 2.2.3
+
@here/pkgE: 1.0.1 + +### Dependencies + +* The following workspace dependencies were updated + * dependencies + * @here/pkgA bumped to 3.3.4 +
+ --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). ` @@ -84,6 +93,37 @@ Release notes for path: ., releaseType: node This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). ` +exports['NodeWorkspace plugin run combines node packages 2'] = ` +{ + "name": "@here/root", + "version": "5.5.6", + "dependencies": { + "@here/pkgA": "^3.3.4", + "@here/pkgD": "^4.4.5" + } +} +` + +exports['NodeWorkspace plugin run combines node packages 3'] = ` +{ + "name": "@here/pkgA", + "version": "3.3.4", + "dependencies": { + "anotherExternal": "^4.3.1" + } +} +` + +exports['NodeWorkspace plugin run combines node packages 4'] = ` +{ + "name": "@here/pkgD", + "version": "4.4.5", + "dependencies": { + "anotherExternal": "^4.3.1" + } +} +` + exports['NodeWorkspace plugin run handles a single node package 1'] = ` :robot: I have created a release *beep* *boop* --- @@ -98,6 +138,82 @@ Release notes for path: node1, releaseType: node This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). ` +exports['NodeWorkspace plugin run includes headers for packages with configured strategies 1'] = ` +:robot: I have created a release *beep* *boop* +--- + + +
@here/pkgA: 3.3.4 + +Release notes for path: node1, releaseType: node +
+ +
pkgB: 2.2.3 + +## [2.2.3](https://github.com/googleapis/node-test-repo/compare/pkgB-v2.2.2...pkgB-v2.2.3) (1983-10-10) + + +### Dependencies + +* The following workspace dependencies were updated + * dependencies + * @here/pkgA bumped from 3.3.3 to 3.3.4 +
+ +
pkgC: 1.1.2 + +## 1.1.2 (1983-10-10) + + +### Dependencies + +* The following workspace dependencies were updated + * dependencies + * @here/pkgB bumped from 2.2.2 to 2.2.3 +
+ +
pkgE: 1.0.1 + +## 1.0.1 (1983-10-10) + + +### Dependencies + +* The following workspace dependencies were updated + * dependencies + * @here/pkgA bumped to 3.3.4 +
+ +--- +This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). +` + +exports['NodeWorkspace plugin run includes headers for packages with configured strategies 2'] = ` +other notes +` + +exports['NodeWorkspace plugin run includes headers for packages with configured strategies 3'] = ` +## [2.2.3](https://github.com/googleapis/node-test-repo/compare/pkgB-v2.2.2...pkgB-v2.2.3) (1983-10-10) + + +### Dependencies + +* The following workspace dependencies were updated + * dependencies + * @here/pkgA bumped from 3.3.3 to 3.3.4 +` + +exports['NodeWorkspace plugin run includes headers for packages with configured strategies 4'] = ` +## 1.1.2 (1983-10-10) + + +### Dependencies + +* The following workspace dependencies were updated + * dependencies + * @here/pkgB bumped from 2.2.2 to 2.2.3 +` + exports['NodeWorkspace plugin run respects version prefix 1'] = ` { "name": "@here/plugin1", @@ -155,6 +271,48 @@ Release notes for path: node1, releaseType: node Release notes for path: node4, releaseType: node +
@here/pkgE: 1.0.1 + +### Dependencies + +* The following workspace dependencies were updated + * dependencies + * @here/pkgA bumped to 3.3.4 +
+ +--- +This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). +` + +exports['NodeWorkspace plugin with updatePeerDependencies: true respects version prefix and updates peer dependencies 1'] = ` +{ + "name": "@here/plugin1", + "version": "4.4.4", + "peerDependencies": { + "@here/pkgA": "^2.2.2" + } +} +` + +exports['NodeWorkspace plugin with updatePeerDependencies: true should not ignore peer dependencies 1'] = ` +:robot: I have created a release *beep* *boop* +--- + + +
@here/pkgA: 3.3.4 + +Release notes for path: node1, releaseType: node +
+ +
@here/plugin1: 4.4.5 + +### Dependencies + +* The following workspace dependencies were updated + * peerDependencies + * @here/pkgA bumped from ^3.3.3 to ^3.3.4 +
+ --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). ` diff --git a/__snapshots__/node.js b/__snapshots__/node.js new file mode 100644 index 000000000..0497aeb83 --- /dev/null +++ b/__snapshots__/node.js @@ -0,0 +1,37 @@ +exports['Node buildReleasePullRequest updates changelog.json if present 1'] = ` +{ + "entries": [ + { + "changes": [ + { + "type": "fix", + "sha": "845db1381b3d5d20151cad2588f85feb", + "message": "update dependency com.google.cloud:google-cloud-storage to v1.120.0", + "issues": [], + "scope": "deps" + }, + { + "type": "chore", + "sha": "b3f8966b023b8f21ce127142aa91841c", + "message": "update a very important dep", + "issues": [], + "breakingChangeNote": "update a very important dep" + }, + { + "type": "fix", + "sha": "08ca01180a91c0a1ba8992b491db9212", + "message": "update dependency com.google.cloud:google-cloud-spanner to v1.50.0", + "issues": [], + "scope": "deps" + } + ], + "version": "1.0.0", + "language": "JAVASCRIPT", + "artifactName": "node-test-repo", + "id": "abc-123-efd-qwerty", + "createTime": "2023-01-05T16:42:33.446Z" + } + ], + "updateTime": "2023-01-05T16:42:33.446Z" +} +` diff --git a/__snapshots__/package-json.js b/__snapshots__/package-json.js index a0bac69de..3e01933d5 100644 --- a/__snapshots__/package-json.js +++ b/__snapshots__/package-json.js @@ -1,3 +1,59 @@ +exports['PackageJson updateContent updates dependency versions 1'] = ` +{ +\t"name": "yargs-parser", +\t"version": "14.0.0", +\t"description": "the mighty option parser used by yargs", +\t"main": "index.js", +\t"scripts": { +\t\t"test": "nyc mocha test/*.js", +\t\t"posttest": "standard", +\t\t"coverage": "nyc report --reporter=text-lcov | coveralls", +\t\t"release": "standard-version" +\t}, +\t"repository": { +\t\t"url": "git@github.com:yargs/yargs-parser.git" +\t}, +\t"keywords": [ +\t\t"argument", +\t\t"parser", +\t\t"yargs", +\t\t"command", +\t\t"cli", +\t\t"parsing", +\t\t"option", +\t\t"args", +\t\t"argument" +\t], +\t"author": "Ben Coe ", +\t"license": "ISC", +\t"devDependencies": { +\t\t"chai": "^4.2.1", +\t\t"coveralls": "^3.0.2", +\t\t"mocha": "^5.2.0", +\t\t"nyc": "^13.0.1", +\t\t"standard": "^12.0.1" +\t}, +\t"dependencies": { +\t\t"camelcase": "^6.0.0", +\t\t"decamelize": "^1.2.0" +\t}, +\t"optionalDependencies": { +\t\t"foo": "~0.1.0" +\t}, +\t"peerDependencies": { +\t\t"bar": ">=2.3.4" +\t}, +\t"files": [ +\t\t"lib", +\t\t"index.js" +\t], +\t"engine": { +\t\t"node": ">=6" +\t} +} + +` + exports['PackageJson updateContent updates the package version 1'] = ` { \t"name": "yargs-parser", diff --git a/__snapshots__/package-lock-json.js b/__snapshots__/package-lock-json.js index 088161d09..0c197f8a6 100644 --- a/__snapshots__/package-lock-json.js +++ b/__snapshots__/package-lock-json.js @@ -23,3 +23,54 @@ exports['PackageLockJson updateContent v2 updates the package version 1'] = ` } ` + +exports['PackageLockJson updateContent v3 monorepo updates the package version 1'] = ` +{ + "name": "release-please", + "version": "14.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "release-please", + "version": "14.0.0" + }, + "node_modules/release-please-foo": { + "resolved": "packages/foo", + "link": true + }, + "node_modules/release-please-bar": { + "resolved": "packages/bar", + "link": true + }, + "packages/foo": { + "name": "release-please-foo", + "version": "2.0.0", + "dependencies": { + "release-please-bar": "3.0.0" + } + }, + "packages/bar": { + "name": "release-please-bar", + "version": "3.0.0" + } + } +} + +` + +exports['PackageLockJson updateContent v3 updates the package version 1'] = ` +{ + "name": "release-please", + "version": "14.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "release-please", + "version": "14.0.0" + } + } +} + +` diff --git a/__snapshots__/php-composer-update-packages.js b/__snapshots__/php-composer-update-packages.js index aaa6053e1..d72b3eb13 100644 --- a/__snapshots__/php-composer-update-packages.js +++ b/__snapshots__/php-composer-update-packages.js @@ -1,17 +1,17 @@ exports['PHPComposer updateContent does not update a version when version is the same 1'] = ` -{"version":"1.0.0","replace":{"version":"1.0.0"}} +{"version":"1.0.0","replace":{"my/package":"1.0.0"}} ` exports['PHPComposer updateContent update all versions in composer.json 1'] = ` -{"version":"1.0.0","replace":{"version":"1.0.0"}} +{"version":"1.0.0","replace":{"my/package":"1.0.0"}} ` -exports['PHPComposer updateContent update replace version in composer.json when version is missing 1'] = ` -{"replace":{"version":"1.0.0"}} +exports['PHPComposer updateContent update replace package in composer.json when package is missing 1'] = ` +{"replace":{"my/package":"1.0.0"}} ` -exports['PHPComposer updateContent update replace version in composer.json when version is present 1'] = ` -{"replace":{"version":"1.0.0"}} +exports['PHPComposer updateContent update replace package in composer.json when package is set in version map 1'] = ` +{"replace":{"my/package":"1.0.0"}} ` exports['PHPComposer updateContent update root version in composer.json 1'] = ` diff --git a/__snapshots__/pom-xml.js b/__snapshots__/pom-xml.js index ea0287e73..121b3770c 100644 --- a/__snapshots__/pom-xml.js +++ b/__snapshots__/pom-xml.js @@ -1,3 +1,88 @@ +exports['PomXml updateContent preserves trailing newlines 1'] = ` + + + 4.0.0 + + + com.google.auth + google-auth-library-parent + 0.16.2 + ../pom.xml + + + com.google.auth + google-auth-library-appengine + 2.3.4 + Google Auth Library for Java - Google App Engine + + + + ossrh + https://oss.sonatype.org/content/repositories/snapshots + + + + + java + javatests + + + org.sonatype.plugins + nexus-staging-maven-plugin + + + org.apache.maven.plugins + maven-source-plugin + + + org.apache.maven.plugins + maven-javadoc-plugin + + + + + + + com.google.auth + google-auth-library-credentials + + + com.google.auth + google-auth-library-oauth2-http + + + com.google.http-client + google-http-client + + + com.google.http-client + google-http-client-jackson2 + + + com.google.appengine + appengine-api-1.0-sdk + provided + + + com.google.guava + guava + + + junit + junit + test + + + com.google.auth + google-auth-library-oauth2-http + test-jar + test + + + + +` + exports['PomXml updateContent updates dependencies 1'] = ` @@ -67,6 +152,7 @@ exports['PomXml updateContent updates project.parent.version 1'] = ` google-auth-library-appengine + ` exports['PomXml updateContent updates project.version 1'] = ` diff --git a/__snapshots__/python.js b/__snapshots__/python.js new file mode 100644 index 000000000..3db3ced56 --- /dev/null +++ b/__snapshots__/python.js @@ -0,0 +1,37 @@ +exports['Python buildUpdates updates changelog.json if present 1'] = ` +{ + "entries": [ + { + "changes": [ + { + "type": "fix", + "sha": "845db1381b3d5d20151cad2588f85feb", + "message": "update dependency com.google.cloud:google-cloud-storage to v1.120.0", + "issues": [], + "scope": "deps" + }, + { + "type": "chore", + "sha": "b3f8966b023b8f21ce127142aa91841c", + "message": "update a very important dep", + "issues": [], + "breakingChangeNote": "update a very important dep" + }, + { + "type": "fix", + "sha": "08ca01180a91c0a1ba8992b491db9212", + "message": "update dependency com.google.cloud:google-cloud-spanner to v1.50.0", + "issues": [], + "scope": "deps" + } + ], + "version": "0.1.0", + "language": "PYTHON", + "artifactName": "google-cloud-automl", + "id": "abc-123-efd-qwerty", + "createTime": "2023-01-05T16:42:33.446Z" + } + ], + "updateTime": "2023-01-05T16:42:33.446Z" +} +` diff --git a/__snapshots__/root-composer-update-packages.js b/__snapshots__/root-composer-update-packages.js index 6f933de3f..c8a210006 100644 --- a/__snapshots__/root-composer-update-packages.js +++ b/__snapshots__/root-composer-update-packages.js @@ -1,3 +1,7 @@ +exports['composer-update-package.json updateContent does not update version in composer if it does not exist 1'] = ` +{} +` + exports['composer-update-package.json updateContent updates all versions in root composer file 1'] = ` { "name": "google/cloud", @@ -256,3 +260,7 @@ exports['composer-update-package.json updateContent updates all versions in root } ` + +exports['composer-update-package.json updateContent updates version in composer if it exists 1'] = ` +{"version":"1.0.0"} +` diff --git a/__snapshots__/setup-cfg.js b/__snapshots__/setup-cfg.js index 418357205..778e17af2 100644 --- a/__snapshots__/setup-cfg.js +++ b/__snapshots__/setup-cfg.js @@ -1,3 +1,51 @@ +exports['setup.cfg updateContent updates big version in setup.cfg 1'] = ` +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +[metadata] +name = google-crc32c +version = 0.6.0 +description = A python wrapper of the C library 'Google CRC32C' +url = https://github.com/googleapis/python-crc32c +long_description = file: README.md +long_description_content_type = text/markdown +author = Google LLC +author_email = googleapis-packages@google.com + +license = Apache 2.0 +platforms = Posix, MacOS X, Windows +classifiers = + Development Status :: 4 - Beta + Intended Audience :: Developers + License :: OSI Approved :: Apache Software License + Operating System :: OS Independent + Programming Language :: Python :: 3 + Programming Language :: Python :: 3.5 + Programming Language :: Python :: 3.6 + Programming Language :: Python :: 3.7 + Programming Language :: Python :: 3.8 + +[options] +zip_safe = True +python_requires = >=3.5 + +[options.extras_require] +testing = pytest + + +` + exports['setup.cfg updateContent updates version in setup.cfg 1'] = ` # Copyright 2020 Google LLC # diff --git a/__snapshots__/sfdx-project-json.js b/__snapshots__/sfdx-project-json.js new file mode 100644 index 000000000..ffbaed788 --- /dev/null +++ b/__snapshots__/sfdx-project-json.js @@ -0,0 +1,12 @@ +exports['SfdxProjectJson updateContent updates version in sfdx-project.json 1'] = ` +{ + "packageDirectories": [ + { + "default": true, + "versionNumber": "2.3.4.NEXT" + } + ], + "name": "sfdx-test-repo" +} + +` diff --git a/__snapshots__/version-rb.js b/__snapshots__/version-rb.js index 39bf2c1f0..dddb8c3bd 100644 --- a/__snapshots__/version-rb.js +++ b/__snapshots__/version-rb.js @@ -24,6 +24,56 @@ end ` +exports['version.rb updateContent updates long patch versions in version.rb 1'] = ` +# Copyright 2019 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module Google + module Cloud + module Bigtable + VERSION = "0.6.11".freeze + end + end +end + +` + +exports['version.rb updateContent updates prerelease versions in version.rb 1'] = ` +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module Google + module Cloud + module Bigtable + VERSION = "10.0.0-alpha1".freeze + end + end +end + +` + exports['version.rb updateContent updates version in version.rb 1'] = ` # Copyright 2019 Google LLC # diff --git a/docs/cli.md b/docs/cli.md index cfbb5d80b..861a229e3 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -51,6 +51,7 @@ Extra options: | `--versioning-strategy` | [`VersioningStrategyType`](/docs/customizing.md#versioning-strategies) | Override method of determining SemVer version bumps based on commits. Defaults to `default` | | `--bump-minor-pre-major` | `boolean` | Configuration option for the versioning strategy. If set, will bump the minor version for breaking changes for versions < 1.0.0 | | `--bump-patch-for-minor-pre-major` | `boolean` | Configuration option for the versioning strategy. If set, will bump the patch version for features for versions < 1.0.0 | +| `--prerelease-type` | `string` | Configuration option for the prerelese versioning strategy. If prerelease strategy used and type set, will set the prerelese part of the version to the provided value in case prerelease part is not present. | | `--draft` | `boolean` | If set, create releases as drafts | | `--prerelease` | `boolean` | If set, create releases that are pre-major or pre-release version marked as pre-release on Github| | `--draft-pull-request` | `boolean` | If set, create pull requests as drafts | @@ -62,6 +63,7 @@ Extra options: | `--changelog-host` | `string` | Host for commit hyperlinks in the changelog. Defaults to `https://github.com` | | `--pull-request-title-pattern` | `string` | Override the pull request title pattern. Defaults to `chore${scope}: release${component} ${version}` | | `--pull-request-header` | `string` | Override the pull request header. Defaults to `:robot: I have created a release *beep* *boop*` | +| `--pull-request-footer` | `string` | Override the pull request footer. Defaults to `This PR was generated with Release Please. See documentation.` | | `--extra-files` | `string[]` | Extra file paths for the release strategy to consider | | `--version-file` | `string` | Ruby only. Path to the `version.rb` file | @@ -101,6 +103,7 @@ need to specify your release options: | `--versioning-strategy` | VersioningStrategy | Override method of determining SemVer version bumps based on commits. Defaults to `default` | | `--bump-minor-pre-major` | boolean | Configuration option for the versioning strategy. If set, will bump the minor version for breaking changes for versions < 1.0.0 | | `--bump-patch-for-minor-pre-major` | boolean | Configuration option for the versioning strategy. If set, will bump the patch version for features for versions < 1.0.0 | +| `--prerelease-type` | `string` | Configuration option for the prerelese versioning strategy. If prerelease strategy used and type set, will set the prerelese part of the version to the provided value in case prerelease part is not present. | | `--draft-pull-request` | boolean | If set, create pull requests as drafts | | `--label` | string | Comma-separated list of labels to apply to the release pull requests. Defaults to `autorelease: pending` |`autorelease: tagged` | | `--changelog-path` | `string` | Override the path to the managed CHANGELOG. Defaults to `CHANGELOG.md` | @@ -110,6 +113,7 @@ need to specify your release options: | `--monorepo-tags` | boolean | Add prefix to tags and branches, allowing multiple libraries to be released from the same repository | | `--pull-request-title-pattern` | `string` | Override the pull request title pattern. Defaults to `chore${scope}: release${component} ${version}` | | `--pull-request-header` | `string` | Override the pull request header. Defaults to `:robot: I have created a release *beep* *boop*` | +| `--pull-request-footer` | `string` | Override the pull request footer. Defaults to `This PR was generated with Release Please. See documentation.` | | `--signoff` | string | Add [`Signed-off-by`](https://git-scm.com/docs/git-commit#Documentation/git-commit.txt---signoff) line at the end of the commit log message using the user and email provided. (format "Name \") | | `--extra-files` | `string[]` | Extra file paths for the release strategy to consider | | `--version-file` | `string` | Ruby only. Path to the `version.rb` file | @@ -150,6 +154,7 @@ need to specify your release options: | `--monorepo-tags` | boolean | Add prefix to tags and branches, allowing multiple libraries to be released from the same repository | | `--pull-request-title-pattern` | `string` | Override the pull request title pattern. Defaults to `chore${scope}: release${component} ${version}` | | `--pull-request-header` | `string` | Override the pull request header. Defaults to `:robot: I have created a release *beep* *boop*` | +| `--pull-request-footer` | `string` | Override the pull request footer. Defaults to `This PR was generated with Release Please. See documentation.` | | `--draft` | `boolean` | If set, create releases as drafts | | `--prerelease` | `boolean` | If set, create releases that are pre-major or pre-release version marked as pre-release on Github| | `--label` | `string` | Comma-separated list of labels to apply to the release pull requests. Defaults to `autorelease: pending` | diff --git a/docs/customizing.md b/docs/customizing.md index 1f672c4d9..604d71d5f 100644 --- a/docs/customizing.md +++ b/docs/customizing.md @@ -23,6 +23,7 @@ Release Please automates releases for the following flavors of repositories: | `python` | [A Python repository, with a setup.py, setup.cfg, CHANGELOG.md](https://github.com/googleapis/python-storage) and optionally a pyproject.toml and a <project>/\_\_init\_\_.py | | `ruby` | A repository with a version.rb and a CHANGELOG.md | | `rust` | A Rust repository, with a Cargo.toml (either as a crate or workspace) and a CHANGELOG.md | +| `sfdx` | A repository with a [sfdx-project.json](https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_ws_config.htm) and a CHANGELOG.md | | `simple` | [A repository with a version.txt and a CHANGELOG.md](https://github.com/googleapis/gapic-generator) | | `terraform-module` | [A terraform module, with a version in the README.md, and a CHANGELOG.md](https://github.com/terraform-google-modules/terraform-google-project-factory) | @@ -43,6 +44,7 @@ version given a list of parsed commits. | `always-bump-minor` | Always bump minor version | | | `always-bump-major` | Always bump major version | | `service-pack` | Designed for Java backport fixes. Uses Maven's specification for service pack versions (e.g. 1.2.3-sp.1) | +| `prerelease` | Bumping prerelease number (eg. 1.2.0-beta01 to 1.2.0-beta02) or if prerelease type is set, using that in the prerelease part (eg. 1.2.1 to 1.3.0-beta) | ### Adding additional versioning strategy types @@ -62,12 +64,16 @@ To configure multiple components on different paths, configure a ## Changelog Types A changelog type's job is to build the CHANGELOG notes given a list -of parsed commits. +of parsed commits. This generated content is used in the release pull request body +and in release notes. By replacing the implementation, you can control how your +release notes appear. | Changelog Type | Description | | -------------- | ----------- | | `default` | Default CHANGELOG notes builder. Groups by commit type and links to pull requests and commits | -| `github` | Uses the GitHub API to generate notes | +| `github` | Uses the [GitHub API][release-notes-api] to generate notes | + +[release-notes-api]: https://docs.github.com/en/rest/releases/releases?apiVersion=2022-11-28#generate-release-notes-content-for-a-release ### Adding additional changelog types @@ -113,6 +119,15 @@ option in the manifest configuration. By default, the pull request header is: `:robot: I have created a release *beep* *boop*`. +### Pull Request Footer + +If you would like to customize the pull request footer, you can use the +`--pull-request-footer` CLI option or the `pull-request-footer` +option in the manifest configuration. + +By default, the pull request footer is: +`This PR was generated with Release Please. See documentation.`. + ## Release Lifecycle Labels By default, we open release pull requests with the `autorelease: pending` @@ -137,6 +152,14 @@ using the [Generic](/src/updaters/generic.ts) updater. You can specify a comma separated list of file paths with the `--extra-files` CLI option or the `extra-files` option in the manifest configuration. +```json +{ + "extra-files": [ + "path/to/file.md" + ] +} +``` + To mark versions needing an update in those files, you will add annotations (usually in comments). @@ -161,6 +184,8 @@ the block, we will attempt to replace version values. ## Updating arbitrary JSON files +For files with the `.xml` extension, the `version` property is updated. + For most release strategies, you can provide additional files to update using the [GenericJson](/src/updaters/generic-json.ts) updater. You can specify a configuration object in the `extra-files` option in the manifest @@ -184,6 +209,8 @@ informs release-please on which JSON field to update with the new version. ## Updating arbitrary XML files +For files with the `.xml` extension, the `version` element is updated. + For most release strategies, you can provide additional files to update using the [GenericXml](/src/updaters/generic-xml.ts) updater. You can specify a configuration object in the `extra-files` option in the manifest @@ -200,3 +227,46 @@ configuration. ] } ``` + +## Updating arbitrary YAML files + +For files with the `.yaml` or `.yml` extension, the `version` property is +updated. + +For most release strategies, you can provide additional files to update +using the [GenericYaml](/src/updaters/generic-yaml.ts) updater. You can +specify a configuration object in the `extra-files` option in the manifest +configuration. + +```json +{ + "extra-files": [ + { + "type": "yaml", + "path": "path/to/file.yaml", + "jsonpath": "$.json.path.to.field" + } + ] +} +``` + +## Updating arbitrary TOML files + +For files with the `.toml` extension, the `version` property is updated. + +For most release strategies, you can provide additional files to update +using the [GenericToml](/src/updaters/generic-toml.ts) updater. You can +specify a configuration object in the `extra-files` option in the manifest +configuration. + +```json +{ + "extra-files": [ + { + "type": "toml", + "path": "path/to/file.toml", + "jsonpath": "$.json.path.to.field" + } + ] +} +``` diff --git a/docs/manifest-releaser.md b/docs/manifest-releaser.md index 9fdec02a4..ce0b198a6 100644 --- a/docs/manifest-releaser.md +++ b/docs/manifest-releaser.md @@ -172,6 +172,9 @@ defaults (those are documented in comments) // absence defaults to false "bump-patch-for-minor-pre-major": true, + // setting the type of prerelease in case of prerelease strategy + "prerelease-type": "beta", + // set default conventional commit => changelog sections mapping/appearance. // absence defaults to https://git.io/JqCZL "changelog-sections": [...], @@ -239,7 +242,7 @@ defaults (those are documented in comments) // large numbers of packages at once. // absence defaults to false, causing calls to be issued concurrently. "sequential-calls": false, - + // per package configuration: at least one entry required. // the key is the relative path from the repo root to the folder that contains @@ -262,7 +265,10 @@ defaults (those are documented in comments) ".": { // overrides release-type for node "release-type": "node", + // exclude commits from that path from processing + "exclude-paths": ["path/to/myPyPkgA"] }, + // path segment should be relative to repository root "path/to/myJSPkgA": { // overrides release-type for node @@ -279,10 +285,10 @@ defaults (those are documented in comments) "release-as": "3.2.1" }, - "path/to/my-rust-crate", { + "path/to/my-rust-crate": { // override release-type for rust "release-type": "rust" - } + }, "path/to/myPyPkgA": { // when a default release-as is set, this is how you revert to using @@ -295,7 +301,8 @@ defaults (those are documented in comments) // our change log is located at path/to/myPyPkgA/docs/CHANGES.rst "changelog-path": "docs/CHANGES.rst" }, - "path/to/github-enterprise-package", { + + "path/to/github-enterprise-package": { // override changelog host for github enterprise package "changelog-host": "https://example.com" } @@ -304,6 +311,31 @@ defaults (those are documented in comments) } ``` +## Subsequent Versions + +release-please tries to determine the next release based on the previous tagged +release. The default search tag looks like: + +```sh +-v +``` + +In your specific tagging scheme, your tags could like `v`. And +this will result in an error like: + +```sh +❯ looking for tagName: -v +⚠ Expected 1 releases, only found 0 +``` + +To fix this, component can be removed from tagName being searched using the +`include-component-in-tag` property. Setting this to `false` will change the +tagName to: + +```sh +v +``` + ## Manifest At a minimum, a manifest file must exist at the tip of the `--target-branch`. @@ -333,6 +365,11 @@ on: push: branches: - main + +permissions: + contents: write + pull-requests: write + name: Run Release Please jobs: release-please: @@ -458,6 +495,23 @@ your update pull request. If you don't agree with this behavior and would only l your local dependencies bumped if they are within the SemVer range, you can set the `"always-link-local"` option to `false` in your manifest config. +#### Linking peer dependencies + +By default, the `node-workspace` plugin doesn't modify `peerDependencies` fields in +package.json. If you would like version bumps to be also linked in `peerDependencies` +fields, set `"updatePeerDependencies"` to `true` in your manifest plugin config. + +``` +{ + "plugins": [ + { + "type": "node-workspace", + "updatePeerDependencies": true + } + ] +} +``` + ### cargo-workspace The `cargo-workspace` plugin operates similarly to the `node-workspace` plugin, diff --git a/owlbot.py b/owlbot.py index a02c44cde..41058b856 100644 --- a/owlbot.py +++ b/owlbot.py @@ -12,24 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. - -import synthtool.languages.node as node - -node.owlbot_main(templates_excludes=[ - 'README.md', - 'CONTRIBUTING.md', - '.eslintignore', - '.eslintrc.json', - '.mocharc.js', - '.prettierignore', - '.prettierrc', - '.nycrc', - '.kokoro/presubmit/node10/system-test.cfg', - '.kokoro/continuous/node10/system-test.cfg', - '.kokoro/system-test.sh', - '.mocharc.js', - '.github/generated-files-bot.yml', - '.github/release-please.yml', - '.github/sync-repo-settings.yaml', - '.github/workflows/ci.yaml', -]) +# Intentionally left blank. This is a standalone node repo. diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 000000000..6b11577b5 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,10237 @@ +{ + "name": "release-please", + "version": "16.8.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "release-please", + "version": "16.8.0", + "license": "Apache-2.0", + "dependencies": { + "@conventional-commits/parser": "^0.4.1", + "@google-automations/git-file-utils": "^2.0.0", + "@iarna/toml": "^3.0.0", + "@octokit/graphql": "^5.0.0", + "@octokit/request": "^6.0.0", + "@octokit/request-error": "^3.0.0", + "@octokit/rest": "^19.0.0", + "@types/npm-package-arg": "^6.1.0", + "@xmldom/xmldom": "^0.8.4", + "chalk": "^4.0.0", + "code-suggester": "^4.2.0", + "conventional-changelog-conventionalcommits": "^6.0.0", + "conventional-changelog-writer": "^6.0.0", + "conventional-commits-filter": "^3.0.0", + "detect-indent": "^6.1.0", + "diff": "^5.0.0", + "figures": "^3.0.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "js-yaml": "^4.0.0", + "jsonpath": "^1.1.1", + "node-html-parser": "^6.0.0", + "parse-github-repo-url": "^1.4.1", + "semver": "^7.5.3", + "type-fest": "^3.0.0", + "typescript": "^4.6.4", + "unist-util-visit": "^2.0.3", + "unist-util-visit-parents": "^3.1.1", + "xpath": "^0.0.34", + "yaml": "^2.2.2", + "yargs": "^17.0.0" + }, + "bin": { + "release-please": "build/src/bin/release-please.js" + }, + "devDependencies": { + "@octokit/types": "^9.0.0", + "@types/chai": "^4.1.7", + "@types/diff": "^5.0.2", + "@types/iarna__toml": "^2.0.1", + "@types/inquirer": "^9.0.3", + "@types/js-yaml": "^4.0.0", + "@types/jsonpath": "^0.2.0", + "@types/mocha": "^9.0.0", + "@types/node": "^18.0.0", + "@types/npmlog": "^7.0.0", + "@types/pino": "^7.0.0", + "@types/semver": "^7.0.0", + "@types/sinon": "^10.0.0", + "@types/xmldom": "^0.1.31", + "@types/yargs": "^17.0.0", + "ajv": "^8.11.0", + "ajv-formats": "^2.1.1", + "c8": "^9.0.0", + "chai": "^4.2.0", + "config-chain": "^1.1.13", + "cross-env": "^7.0.0", + "gts": "^3.1.0", + "mocha": "^9.2.2", + "nock": "^13.0.0", + "sinon": "16.0.0", + "snap-shot-it": "^7.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dependencies": { + "@babel/highlight": "^7.10.4" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@bahmutov/data-driven": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@bahmutov/data-driven/-/data-driven-1.0.0.tgz", + "integrity": "sha512-YqW3hPS0RXriqjcCrLOTJj+LWe3c8JpwlL83k1ka1Q8U05ZjAKbGQZYeTzUd0NFEnnfPtsUiKGpFEBJG6kFuvg==", + "dev": true, + "dependencies": { + "check-more-types": "2.24.0", + "lazy-ass": "1.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "node_modules/@conventional-commits/parser": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@conventional-commits/parser/-/parser-0.4.1.tgz", + "integrity": "sha512-H2ZmUVt6q+KBccXfMBhbBF14NlANeqHTXL4qCL6QGbMzrc4HDXyzWuxPxPNbz71f/5UkR5DrycP5VO9u7crahg==", + "dependencies": { + "unist-util-visit": "^2.0.3", + "unist-util-visit-parents": "^3.1.1" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", + "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@eslint/eslintrc/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/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, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/@eslint/eslintrc/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@google-automations/git-file-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@google-automations/git-file-utils/-/git-file-utils-2.0.0.tgz", + "integrity": "sha512-F6h8npq7rt60fr3W+cil/zXbIiF9Hj8JzaN3LNh7uBIJpsWnjL9ObV84qW/345boMheDdo/n+cItmvCfsn0lLA==", + "dependencies": { + "@octokit/rest": "^19.0.7", + "@octokit/types": "^9.0.0", + "minimatch": "^5.1.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "node_modules/@iarna/toml": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-3.0.0.tgz", + "integrity": "sha512-td6ZUkz2oS3VeleBcN+m//Q6HlCFCPrnI0FZhrt/h4XqLEdOyYp2u21nd8MdsR+WJy5r9PTDaHTDDfhf4H4l6Q==" + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@octokit/auth-token": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.2.tgz", + "integrity": "sha512-pq7CwIMV1kmzkFTimdwjAINCXKTajZErLB4wMLYapR2nuB/Jpr66+05wOTZMSCBXP6n4DdDWT2W19Bm17vU69Q==", + "dependencies": { + "@octokit/types": "^8.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@octokit/auth-token/node_modules/@octokit/openapi-types": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-14.0.0.tgz", + "integrity": "sha512-HNWisMYlR8VCnNurDU6os2ikx0s0VyEjDYHNS/h4cgb8DeOxQ0n72HyinUtdDVxJhFy3FWLGl0DJhfEWk3P5Iw==" + }, + "node_modules/@octokit/auth-token/node_modules/@octokit/types": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-8.2.1.tgz", + "integrity": "sha512-8oWMUji8be66q2B9PmEIUyQm00VPDPun07umUWSaCwxmeaquFBro4Hcc3ruVoDo3zkQyZBlRvhIMEYS3pBhanw==", + "dependencies": { + "@octokit/openapi-types": "^14.0.0" + } + }, + "node_modules/@octokit/core": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.4.tgz", + "integrity": "sha512-rYKilwgzQ7/imScn3M9/pFfUf4I1AZEH3KhyJmtPdE2zfaXAn2mFfUy4FbKewzc2We5y/LlKLj36fWJLKC2SIQ==", + "dependencies": { + "@octokit/auth-token": "^3.0.0", + "@octokit/graphql": "^5.0.0", + "@octokit/request": "^6.0.0", + "@octokit/request-error": "^3.0.0", + "@octokit/types": "^9.0.0", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@octokit/endpoint": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.3.tgz", + "integrity": "sha512-57gRlb28bwTsdNXq+O3JTQ7ERmBTuik9+LelgcLIVfYwf235VHbN9QNo4kXExtp/h8T423cR5iJThKtFYxC7Lw==", + "dependencies": { + "@octokit/types": "^8.0.0", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@octokit/endpoint/node_modules/@octokit/openapi-types": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-14.0.0.tgz", + "integrity": "sha512-HNWisMYlR8VCnNurDU6os2ikx0s0VyEjDYHNS/h4cgb8DeOxQ0n72HyinUtdDVxJhFy3FWLGl0DJhfEWk3P5Iw==" + }, + "node_modules/@octokit/endpoint/node_modules/@octokit/types": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-8.2.1.tgz", + "integrity": "sha512-8oWMUji8be66q2B9PmEIUyQm00VPDPun07umUWSaCwxmeaquFBro4Hcc3ruVoDo3zkQyZBlRvhIMEYS3pBhanw==", + "dependencies": { + "@octokit/openapi-types": "^14.0.0" + } + }, + "node_modules/@octokit/graphql": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.4.tgz", + "integrity": "sha512-amO1M5QUQgYQo09aStR/XO7KAl13xpigcy/kI8/N1PnZYSS69fgte+xA4+c2DISKqUZfsh0wwjc2FaCt99L41A==", + "dependencies": { + "@octokit/request": "^6.0.0", + "@octokit/types": "^8.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@octokit/graphql/node_modules/@octokit/openapi-types": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-14.0.0.tgz", + "integrity": "sha512-HNWisMYlR8VCnNurDU6os2ikx0s0VyEjDYHNS/h4cgb8DeOxQ0n72HyinUtdDVxJhFy3FWLGl0DJhfEWk3P5Iw==" + }, + "node_modules/@octokit/graphql/node_modules/@octokit/types": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-8.2.1.tgz", + "integrity": "sha512-8oWMUji8be66q2B9PmEIUyQm00VPDPun07umUWSaCwxmeaquFBro4Hcc3ruVoDo3zkQyZBlRvhIMEYS3pBhanw==", + "dependencies": { + "@octokit/openapi-types": "^14.0.0" + } + }, + "node_modules/@octokit/openapi-types": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-16.0.0.tgz", + "integrity": "sha512-JbFWOqTJVLHZSUUoF4FzAZKYtqdxWu9Z5m2QQnOyEa04fOFljvyh7D3GYKbfuaSWisqehImiVIMG4eyJeP5VEA==" + }, + "node_modules/@octokit/plugin-paginate-rest": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.1.2.tgz", + "integrity": "sha512-qhrmtQeHU/IivxucOV1bbI/xZyC/iOBhclokv7Sut5vnejAIAEXVcGQeRpQlU39E0WwK9lNvJHphHri/DB6lbQ==", + "dependencies": { + "@octokit/tsconfig": "^1.0.2", + "@octokit/types": "^9.2.3" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "@octokit/core": ">=4" + } + }, + "node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/openapi-types": { + "version": "18.1.1", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-18.1.1.tgz", + "integrity": "sha512-VRaeH8nCDtF5aXWnjPuEMIYf1itK/s3JYyJcWFJT8X9pSNnBtriDf7wlEWsGuhPLl4QIH4xM8fqTXDwJ3Mu6sw==" + }, + "node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/types": { + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.3.2.tgz", + "integrity": "sha512-D4iHGTdAnEEVsB8fl95m1hiz7D5YiRdQ9b/OEb3BYRVwbLsGHcRVPz+u+BgRLNk0Q0/4iZCBqDN96j2XNxfXrA==", + "dependencies": { + "@octokit/openapi-types": "^18.0.0" + } + }, + "node_modules/@octokit/plugin-request-log": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz", + "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==", + "peerDependencies": { + "@octokit/core": ">=3" + } + }, + "node_modules/@octokit/plugin-rest-endpoint-methods": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-7.2.3.tgz", + "integrity": "sha512-I5Gml6kTAkzVlN7KCtjOM+Ruwe/rQppp0QU372K1GP7kNOYEKe8Xn5BW4sE62JAHdwpq95OQK/qGNyKQMUzVgA==", + "dependencies": { + "@octokit/types": "^10.0.0" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "@octokit/core": ">=3" + } + }, + "node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/openapi-types": { + "version": "18.1.1", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-18.1.1.tgz", + "integrity": "sha512-VRaeH8nCDtF5aXWnjPuEMIYf1itK/s3JYyJcWFJT8X9pSNnBtriDf7wlEWsGuhPLl4QIH4xM8fqTXDwJ3Mu6sw==" + }, + "node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/types": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-10.0.0.tgz", + "integrity": "sha512-Vm8IddVmhCgU1fxC1eyinpwqzXPEYu0NrYzD3YZjlGjyftdLBTeqNblRC0jmJmgxbJIsQlyogVeGnrNaaMVzIg==", + "dependencies": { + "@octokit/openapi-types": "^18.0.0" + } + }, + "node_modules/@octokit/request": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.2.tgz", + "integrity": "sha512-6VDqgj0HMc2FUX2awIs+sM6OwLgwHvAi4KCK3mT2H2IKRt6oH9d0fej5LluF5mck1lRR/rFWN0YIDSYXYSylbw==", + "dependencies": { + "@octokit/endpoint": "^7.0.0", + "@octokit/request-error": "^3.0.0", + "@octokit/types": "^8.0.0", + "is-plain-object": "^5.0.0", + "node-fetch": "^2.6.7", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@octokit/request-error": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-3.0.2.tgz", + "integrity": "sha512-WMNOFYrSaX8zXWoJg9u/pKgWPo94JXilMLb2VManNOby9EZxrQaBe/QSC4a1TzpAlpxofg2X/jMnCyZgL6y7eg==", + "dependencies": { + "@octokit/types": "^8.0.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@octokit/request-error/node_modules/@octokit/openapi-types": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-14.0.0.tgz", + "integrity": "sha512-HNWisMYlR8VCnNurDU6os2ikx0s0VyEjDYHNS/h4cgb8DeOxQ0n72HyinUtdDVxJhFy3FWLGl0DJhfEWk3P5Iw==" + }, + "node_modules/@octokit/request-error/node_modules/@octokit/types": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-8.2.1.tgz", + "integrity": "sha512-8oWMUji8be66q2B9PmEIUyQm00VPDPun07umUWSaCwxmeaquFBro4Hcc3ruVoDo3zkQyZBlRvhIMEYS3pBhanw==", + "dependencies": { + "@octokit/openapi-types": "^14.0.0" + } + }, + "node_modules/@octokit/request/node_modules/@octokit/openapi-types": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-14.0.0.tgz", + "integrity": "sha512-HNWisMYlR8VCnNurDU6os2ikx0s0VyEjDYHNS/h4cgb8DeOxQ0n72HyinUtdDVxJhFy3FWLGl0DJhfEWk3P5Iw==" + }, + "node_modules/@octokit/request/node_modules/@octokit/types": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-8.2.1.tgz", + "integrity": "sha512-8oWMUji8be66q2B9PmEIUyQm00VPDPun07umUWSaCwxmeaquFBro4Hcc3ruVoDo3zkQyZBlRvhIMEYS3pBhanw==", + "dependencies": { + "@octokit/openapi-types": "^14.0.0" + } + }, + "node_modules/@octokit/rest": { + "version": "19.0.13", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-19.0.13.tgz", + "integrity": "sha512-/EzVox5V9gYGdbAI+ovYj3nXQT1TtTHRT+0eZPcuC05UFSWO3mdO9UY1C0i2eLF9Un1ONJkAk+IEtYGAC+TahA==", + "dependencies": { + "@octokit/core": "^4.2.1", + "@octokit/plugin-paginate-rest": "^6.1.2", + "@octokit/plugin-request-log": "^1.0.4", + "@octokit/plugin-rest-endpoint-methods": "^7.1.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@octokit/tsconfig": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@octokit/tsconfig/-/tsconfig-1.0.2.tgz", + "integrity": "sha512-I0vDR0rdtP8p2lGMzvsJzbhdOWy405HcGovrspJ8RRibHnyRgggUSNO5AIox5LmqiwmatHKYsvj6VGFHkqS7lA==" + }, + "node_modules/@octokit/types": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.0.0.tgz", + "integrity": "sha512-LUewfj94xCMH2rbD5YJ+6AQ4AVjFYTgpp6rboWM5T7N3IsIF65SBEOVcYMGAEzO/kKNiNaW4LoWtoThOhH06gw==", + "dependencies": { + "@octokit/openapi-types": "^16.0.0" + } + }, + "node_modules/@sinonjs/commons": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } + }, + "node_modules/@sinonjs/fake-timers/node_modules/@sinonjs/commons": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", + "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/samsam": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.0.tgz", + "integrity": "sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^2.0.0", + "lodash.get": "^4.4.2", + "type-detect": "^4.0.8" + } + }, + "node_modules/@sinonjs/text-encoding": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", + "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", + "dev": true + }, + "node_modules/@types/chai": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.4.tgz", + "integrity": "sha512-KnRanxnpfpjUTqTCXslZSEdLfXExwgNxYPdiO2WGUj8+HDjFi8R3k5RVKPeSCzLjCcshCAtVO2QBbVuAV4kTnw==", + "dev": true + }, + "node_modules/@types/diff": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@types/diff/-/diff-5.0.2.tgz", + "integrity": "sha512-uw8eYMIReOwstQ0QKF0sICefSy8cNO/v7gOTiIy9SbwuHyEecJUm7qlgueOO5S1udZ5I/irVydHVwMchgzbKTg==", + "dev": true + }, + "node_modules/@types/iarna__toml": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/iarna__toml/-/iarna__toml-2.0.2.tgz", + "integrity": "sha512-Q3obxKhBLVVbEQ8zsAmsQVobAAZhi8dFFFjF0q5xKXiaHvH8IkSxcbM27e46M9feUMieR03SPpmp5CtaNzpdBg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/inquirer": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/@types/inquirer/-/inquirer-9.0.3.tgz", + "integrity": "sha512-CzNkWqQftcmk2jaCWdBTf9Sm7xSw4rkI1zpU/Udw3HX5//adEZUIm9STtoRP1qgWj0CWQtJ9UTvqmO2NNjhMJw==", + "dev": true, + "dependencies": { + "@types/through": "*", + "rxjs": "^7.2.0" + } + }, + "node_modules/@types/inquirer/node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@types/inquirer/node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", + "dev": true + }, + "node_modules/@types/js-yaml": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.5.tgz", + "integrity": "sha512-FhpRzf927MNQdRZP0J5DLIdTXhjLYzeUTmLAu69mnVksLH9CJY3IuSeEgbKUki7GQZm0WqDkGzyxju2EZGD2wA==", + "dev": true + }, + "node_modules/@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "dev": true + }, + "node_modules/@types/jsonpath": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@types/jsonpath/-/jsonpath-0.2.0.tgz", + "integrity": "sha512-v7qlPA0VpKUlEdhghbDqRoKMxFB3h3Ch688TApBJ6v+XLDdvWCGLJIYiPKGZnS6MAOie+IorCfNYVHOPIHSWwQ==", + "dev": true + }, + "node_modules/@types/minimist": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", + "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==" + }, + "node_modules/@types/mocha": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz", + "integrity": "sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==", + "dev": true + }, + "node_modules/@types/node": { + "version": "18.11.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz", + "integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==", + "dev": true + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", + "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==" + }, + "node_modules/@types/npm-package-arg": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/@types/npm-package-arg/-/npm-package-arg-6.1.1.tgz", + "integrity": "sha512-452/1Kp9IdM/oR10AyqAgZOxUt7eLbm+EMJ194L6oarMYdZNiFIFAOJ7IIr0OrZXTySgfHjJezh2oiyk2kc3ag==" + }, + "node_modules/@types/npmlog": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@types/npmlog/-/npmlog-7.0.0.tgz", + "integrity": "sha512-hJWbrKFvxKyWwSUXjZMYTINsSOY6IclhvGOZ97M8ac2tmR9hMwmTnYaMdpGhvju9ctWLTPhCS+eLfQNluiEjQQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/pino": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/@types/pino/-/pino-7.0.5.tgz", + "integrity": "sha512-wKoab31pknvILkxAF8ss+v9iNyhw5Iu/0jLtRkUD74cNfOOLJNnqfFKAv0r7wVaTQxRZtWrMpGfShwwBjOcgcg==", + "deprecated": "This is a stub types definition. pino provides its own type definitions, so you do not need this installed.", + "dev": true, + "dependencies": { + "pino": "*" + } + }, + "node_modules/@types/semver": { + "version": "7.3.13", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", + "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", + "dev": true + }, + "node_modules/@types/sinon": { + "version": "10.0.13", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.13.tgz", + "integrity": "sha512-UVjDqJblVNQYvVNUsj0PuYYw0ELRmgt1Nt5Vk0pT5f16ROGfcKJY8o1HVuMOJOpD727RrGB9EGvoaTQE5tgxZQ==", + "dev": true, + "dependencies": { + "@types/sinonjs__fake-timers": "*" + } + }, + "node_modules/@types/sinonjs__fake-timers": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.2.tgz", + "integrity": "sha512-9GcLXF0/v3t80caGs5p2rRfkB+a8VBGLJZVih6CNFkx8IZ994wiKKLSRs9nuFwk1HevWs/1mnUmkApGrSGsShA==", + "dev": true + }, + "node_modules/@types/through": { + "version": "0.0.30", + "resolved": "https://registry.npmjs.org/@types/through/-/through-0.0.30.tgz", + "integrity": "sha512-FvnCJljyxhPM3gkRgWmxmDZyAQSiBQQWLI0A0VFL0K7W1oRUrPJSqNO0NvTnLkBcotdlp3lKvaT0JrnyRDkzOg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/unist": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", + "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==" + }, + "node_modules/@types/xmldom": { + "version": "0.1.31", + "resolved": "https://registry.npmjs.org/@types/xmldom/-/xmldom-0.1.31.tgz", + "integrity": "sha512-bVy7s0nvaR5D1mT1a8ZkByHWNOGb6Vn4yi5TWhEdmyKlAG+08SA7Md6+jH+tYmMLueAwNeWvHHpeKrr6S4c4BA==", + "dev": true + }, + "node_modules/@types/yargs": { + "version": "17.0.20", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.20.tgz", + "integrity": "sha512-eknWrTHofQuPk2iuqDm1waA7V6xPlbgBoaaXEgYkClhLOnB0TtbW+srJaOToAgawPxPlHQzwypFA2bhZaUGP5A==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", + "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz", + "integrity": "sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==", + "dev": true, + "dependencies": { + "@typescript-eslint/experimental-utils": "4.33.0", + "@typescript-eslint/scope-manager": "4.33.0", + "debug": "^4.3.1", + "functional-red-black-tree": "^1.0.1", + "ignore": "^5.1.8", + "regexpp": "^3.1.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^4.0.0", + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/experimental-utils": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz", + "integrity": "sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.7", + "@typescript-eslint/scope-manager": "4.33.0", + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/typescript-estree": "4.33.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.33.0.tgz", + "integrity": "sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "4.33.0", + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/typescript-estree": "4.33.0", + "debug": "^4.3.1" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", + "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/visitor-keys": "4.33.0" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", + "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", + "dev": true, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", + "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/visitor-keys": "4.33.0", + "debug": "^4.3.1", + "globby": "^11.0.3", + "is-glob": "^4.0.1", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", + "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.33.0", + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, + "node_modules/@xmldom/xmldom": { + "version": "0.8.6", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.6.tgz", + "integrity": "sha512-uRjjusqpoqfmRkTaNuLJ2VohVr67Q5YwDATW3VU7PfzTj6IRaihGrYI7zckGZjxQPBIp63nfvJbM+Yu5ICh0Bg==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dev": true, + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", + "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/array-ify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", + "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==" + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/async-retry": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", + "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", + "dependencies": { + "retry": "0.13.1" + } + }, + "node_modules/atomic-sleep": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", + "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/before-after-hook": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", + "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==" + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/c8": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/c8/-/c8-9.0.0.tgz", + "integrity": "sha512-nFJhU2Cz6Frh2awk3IW7wwk3wx27/U2v8ojQCHGc1GWTCHS6aMu4lal327/ZnnYj7oSThGF1X3qUP1yzAJBcOQ==", + "dev": true, + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@istanbuljs/schema": "^0.1.3", + "find-up": "^5.0.0", + "foreground-child": "^3.1.1", + "istanbul-lib-coverage": "^3.2.0", + "istanbul-lib-report": "^3.0.1", + "istanbul-reports": "^3.1.6", + "test-exclude": "^6.0.0", + "v8-to-istanbul": "^9.0.0", + "yargs": "^17.7.2", + "yargs-parser": "^21.1.1" + }, + "bin": { + "c8": "bin/c8.js" + }, + "engines": { + "node": ">=14.14.0" + } + }, + "node_modules/c8/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "dependencies": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/chai": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz", + "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==", + "dev": true, + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^4.1.2", + "get-func-name": "^2.0.0", + "loupe": "^2.3.1", + "pathval": "^1.1.1", + "type-detect": "^4.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "node_modules/check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/check-more-types": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", + "integrity": "sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/code-suggester": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/code-suggester/-/code-suggester-4.2.0.tgz", + "integrity": "sha512-XqPYs9XOaLidTArPmKJnCU3aWiiiC+/i2mfLS/VPp07BJA1fptb0ZS+H6LnWSF4jV9tTYAjCmB8ru9uM5SiybA==", + "dependencies": { + "@octokit/rest": "^19.0.5", + "@types/yargs": "^16.0.0", + "async-retry": "^1.3.1", + "diff": "^5.0.0", + "glob": "^7.1.6", + "parse-diff": "^0.10.0", + "yargs": "^16.0.0" + }, + "bin": { + "code-suggester": "build/src/bin/code-suggester.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/code-suggester/node_modules/@types/yargs": { + "version": "16.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.5.tgz", + "integrity": "sha512-AxO/ADJOBFJScHbWhq2xAhlWP24rY4aCEG/NFaMvbT3X2MgRsLjhjQwsn0Zi5zn0LG9jUhCCZMeX9Dkuw6k+vQ==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/code-suggester/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/code-suggester/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/common-tags": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", + "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/compare-func": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", + "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", + "dependencies": { + "array-ify": "^1.0.0", + "dot-prop": "^5.1.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/config-chain": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "dev": true, + "dependencies": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "node_modules/conventional-changelog-conventionalcommits": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-6.1.0.tgz", + "integrity": "sha512-3cS3GEtR78zTfMzk0AizXKKIdN4OvSh7ibNz6/DPbhWWQu7LqE/8+/GqSodV+sywUR2gpJAdP/1JFf4XtN7Zpw==", + "dependencies": { + "compare-func": "^2.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/conventional-changelog-writer": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-6.0.1.tgz", + "integrity": "sha512-359t9aHorPw+U+nHzUXHS5ZnPBOizRxfQsWT5ZDHBfvfxQOAik+yfuhKXG66CN5LEWPpMNnIMHUTCKeYNprvHQ==", + "dependencies": { + "conventional-commits-filter": "^3.0.0", + "dateformat": "^3.0.3", + "handlebars": "^4.7.7", + "json-stringify-safe": "^5.0.1", + "meow": "^8.1.2", + "semver": "^7.0.0", + "split": "^1.0.1" + }, + "bin": { + "conventional-changelog-writer": "cli.js" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/conventional-commits-filter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-3.0.0.tgz", + "integrity": "sha512-1ymej8b5LouPx9Ox0Dw/qAO2dVdfpRFq28e5Y0jJEU8ZrLdy0vOSkkIInwmxErFGhg6SALro60ZrwYFVTUDo4Q==", + "dependencies": { + "lodash.ismatch": "^4.4.0", + "modify-values": "^1.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, + "node_modules/cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "bin": { + "cross-env": "src/bin/cross-env.js", + "cross-env-shell": "src/bin/cross-env-shell.js" + }, + "engines": { + "node": ">=10.14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/dateformat": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", + "engines": { + "node": "*" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", + "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", + "dependencies": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decamelize-keys/node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/deep-eql": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", + "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", + "dev": true, + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" + }, + "node_modules/deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==" + }, + "node_modules/detect-indent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", + "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/diff": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", + "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/disparity": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/disparity/-/disparity-3.0.0.tgz", + "integrity": "sha512-n94Rzbv2ambRaFzrnBf34IEiyOdIci7maRpMkoQWB6xFYGA7Nbs0Z5YQzMfTeyQeelv23nayqOcssBoc6rKrgw==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "diff": "^4.0.1" + }, + "bin": { + "disparity": "bin/disparity" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/disparity/node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz", + "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.1" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "optional": true, + "peer": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "optional": true, + "peer": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/entities": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", + "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-quotes": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/escape-quotes/-/escape-quotes-1.0.2.tgz", + "integrity": "sha512-JpLFzklNReeakCpyj59s78P5F72q0ZUpDnp2BuIk9TtTjj2HMsgiWBChw17BlZT8dRhMtmSb1jE2+pTP1iFYyw==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/escodegen": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=4.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/escodegen/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==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/escodegen/node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/eslint": { + "version": "7.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", + "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.3", + "@humanwhocodes/config-array": "^0.5.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-prettier": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-7.2.0.tgz", + "integrity": "sha512-rV4Qu0C3nfJKPOAhFujFxB7RMP+URFyQqqOZW9DMRD7ZDTFyjaIlETU3xzHELt++4ugC0+Jm084HQYkkJe+Ivg==", + "dev": true, + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-plugin-es": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", + "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "dev": true, + "dependencies": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + }, + "engines": { + "node": ">=8.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=4.19.1" + } + }, + "node_modules/eslint-plugin-es/node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/eslint-plugin-es/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-node": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", + "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", + "dev": true, + "dependencies": { + "eslint-plugin-es": "^3.0.0", + "eslint-utils": "^2.0.0", + "ignore": "^5.1.1", + "minimatch": "^3.0.4", + "resolve": "^1.10.1", + "semver": "^6.1.0" + }, + "engines": { + "node": ">=8.10.0" + }, + "peerDependencies": { + "eslint": ">=5.16.0" + } + }, + "node_modules/eslint-plugin-node/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-node/node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/eslint-plugin-node/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-node/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint-plugin-node/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-prettier": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.1.tgz", + "integrity": "sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g==", + "dev": true, + "dependencies": { + "prettier-linter-helpers": "^1.0.0" + }, + "engines": { + "node": ">=6.0.0" + }, + "peerDependencies": { + "eslint": ">=5.0.0", + "prettier": ">=1.13.0" + }, + "peerDependenciesMeta": { + "eslint-config-prettier": { + "optional": true + } + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/eslint/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/eslint/node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/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, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/eslint/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/eslint/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "dev": true, + "dependencies": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/esprima": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.2.2.tgz", + "integrity": "sha512-+JpPZam9w5DuJ3Q67SqsMGtiHKENSMRVoxvArfJZK01/BfLEObtZ6orJa/MtoGNR/rfMgp5837T41PAmTwAv/A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" + }, + "node_modules/fast-redact": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.1.2.tgz", + "integrity": "sha512-+0em+Iya9fKGfEQGcd62Yv6onjBmmhV1uh86XVfOU8VwAe6kaFdQCWI9s0/Nnugx5Vd9tdbZ7e6gE2tR9dzXdw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "dev": true + }, + "node_modules/folktale": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/folktale/-/folktale-2.3.2.tgz", + "integrity": "sha512-+8GbtQBwEqutP0v3uajDDoN64K2ehmHd0cjlghhxh0WpcfPzAIjPA03e1VvHlxL02FVGR0A6lwXsNQKn3H1RNQ==", + "dev": true + }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "dev": true + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/globals": { + "version": "13.19.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", + "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globals/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true, + "engines": { + "node": ">=4.x" + } + }, + "node_modules/gts": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/gts/-/gts-3.1.1.tgz", + "integrity": "sha512-Jw44aBbzMnd1vtZs7tZt3LMstKQukCBg7N4CKVGzviIQ45Cz5b9lxDJGXVKj/9ySuGv6TYEeijZJGbiiVcM27w==", + "dev": true, + "dependencies": { + "@typescript-eslint/eslint-plugin": "^4.2.0", + "@typescript-eslint/parser": "^4.2.0", + "chalk": "^4.1.0", + "eslint": "^7.10.0", + "eslint-config-prettier": "^7.0.0", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-prettier": "^3.1.4", + "execa": "^5.0.0", + "inquirer": "^7.3.3", + "json5": "^2.1.3", + "meow": "^9.0.0", + "ncp": "^2.0.0", + "prettier": "^2.1.2", + "rimraf": "^3.0.2", + "write-file-atomic": "^3.0.3" + }, + "bin": { + "gts": "build/src/cli.js" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "typescript": ">=3" + } + }, + "node_modules/gts/node_modules/meow": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", + "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==", + "dev": true, + "dependencies": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize": "^1.2.0", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gts/node_modules/type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/handlebars": { + "version": "4.7.7", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", + "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-ansi/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-only": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/has-only/-/has-only-1.1.1.tgz", + "integrity": "sha512-3GuFy9rDw0xvovCHb4SOKiRImbZ+a8boFBUyGNRPVd2mRyQOzYdau5G9nodUXC1ZKYN59hrHFkW1lgBQscYfTg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "bin": { + "he": "bin/he" + } + }, + "node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/http-proxy-agent": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz", + "integrity": "sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", + "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "node_modules/inquirer": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", + "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.19", + "mute-stream": "0.0.8", + "run-async": "^2.4.0", + "rxjs": "^6.6.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "dependencies": { + "ci-info": "^2.0.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", + "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/its-name": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/its-name/-/its-name-1.0.0.tgz", + "integrity": "sha512-GYUWFxViqxDvGzsNEItTEuOqqAQVx29Xl9Lh5YUqyJd6gPHTCMiIbjqcjjyUzsBUqEcgwIdRoydwgfFw1oYbhg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "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", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonpath": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/jsonpath/-/jsonpath-1.1.1.tgz", + "integrity": "sha512-l6Cg7jRpixfbgoWgkrl77dgEj8RPvND0wMH6TwQmi9Qs4TFfS9u5cUFnbeKTwj5ga5Y3BTGGNI28k117LJ009w==", + "dependencies": { + "esprima": "1.2.2", + "static-eval": "2.0.2", + "underscore": "1.12.1" + } + }, + "node_modules/just-extend": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", + "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", + "dev": true + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lazy-ass": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", + "integrity": "sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==", + "dev": true, + "engines": { + "node": "> 0.8" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", + "dev": true + }, + "node_modules/lodash.ismatch": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", + "integrity": "sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", + "dev": true + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/loupe": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", + "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.0" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", + "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", + "dependencies": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/minimist": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dependencies": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", + "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==", + "dev": true, + "dependencies": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.3", + "debug": "4.3.3", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.2.0", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "4.2.1", + "ms": "2.1.3", + "nanoid": "3.3.1", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "which": "2.0.2", + "workerpool": "6.2.0", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" + } + }, + "node_modules/mocha/node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/mocha/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/mocha/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/mocha/node_modules/debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/mocha/node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/mocha/node_modules/diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/mocha/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mocha/node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mocha/node_modules/minimatch": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", + "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/mocha/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha/node_modules/yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/modify-values": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", + "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", + "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/ncp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", + "integrity": "sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA==", + "dev": true, + "bin": { + "ncp": "bin/ncp" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" + }, + "node_modules/nise": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.4.tgz", + "integrity": "sha512-8+Ib8rRJ4L0o3kfmyVCL7gzrohyDe0cMFTBa2d364yIrEGMEoetznKJx899YxjybU6bL9SQkYPSBBs1gyYs8Xg==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^2.0.0", + "@sinonjs/fake-timers": "^10.0.2", + "@sinonjs/text-encoding": "^0.7.1", + "just-extend": "^4.0.2", + "path-to-regexp": "^1.7.0" + } + }, + "node_modules/nock": { + "version": "13.3.0", + "resolved": "https://registry.npmjs.org/nock/-/nock-13.3.0.tgz", + "integrity": "sha512-HHqYQ6mBeiMc+N038w8LkMpDCRquCHWeNmN3v6645P3NhN2+qXOBqvPqo7Rt1VyCMzKhJ733wZqw5B7cQVFNPg==", + "dev": true, + "dependencies": { + "debug": "^4.1.0", + "json-stringify-safe": "^5.0.1", + "lodash": "^4.17.21", + "propagate": "^2.0.0" + }, + "engines": { + "node": ">= 10.13" + } + }, + "node_modules/node-fetch": { + "version": "2.6.8", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.8.tgz", + "integrity": "sha512-RZ6dBYuj8dRSfxpUSu+NsdF1dpPpluJxwOp+6IoDp/sH2QNDSvurYsAa+F1WxY2RjA1iP93xhcsUoYbF2XBqVg==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-html-parser": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-6.1.4.tgz", + "integrity": "sha512-3muP9Uy/Pz7bQa9TNYVQzWJhNZMqyCx7xJle8kz2/y1UgzAUyXXShc1IcPaJy6u07CE3K5rQcRwlvHzmlySRjg==", + "dependencies": { + "css-select": "^5.1.0", + "he": "1.2.0" + } + }, + "node_modules/normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dependencies": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/on-exit-leak-free": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.0.tgz", + "integrity": "sha512-VuCaZZAjReZ3vUwgOB8LxAosIurDiAW0s13rI1YwmaP++jvcxP77AWoQvenZebpCA2m8WC1/EosPYPMjnRAp/w==", + "dev": true + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-diff": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/parse-diff/-/parse-diff-0.10.0.tgz", + "integrity": "sha512-7ZnB7HXPl2WdTtSGGzMFuCIzpmaxrDsLwKZp2AQRQVlmL9MUnCHESAmrbKKD5g+ItFJiCN2YPfPyMjWeJV/JoA==" + }, + "node_modules/parse-github-repo-url": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/parse-github-repo-url/-/parse-github-repo-url-1.4.1.tgz", + "integrity": "sha512-bSWyzBKqcSL4RrncTpGsEKoJ7H8a4L3++ifTAbTFeMHyq2wRV+42DGmQcHIrJIvdcacjIOxEuKH/w4tthF17gg==" + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "dev": true, + "dependencies": { + "isarray": "0.0.1" + } + }, + "node_modules/path-to-regexp/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "dev": true + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pino": { + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/pino/-/pino-8.8.0.tgz", + "integrity": "sha512-cF8iGYeu2ODg2gIwgAHcPrtR63ILJz3f7gkogaHC/TXVVXxZgInmNYiIpDYEwgEkxZti2Se6P2W2DxlBIZe6eQ==", + "dev": true, + "dependencies": { + "atomic-sleep": "^1.0.0", + "fast-redact": "^3.1.1", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "v1.0.0", + "pino-std-serializers": "^6.0.0", + "process-warning": "^2.0.0", + "quick-format-unescaped": "^4.0.3", + "real-require": "^0.2.0", + "safe-stable-stringify": "^2.3.1", + "sonic-boom": "^3.1.0", + "thread-stream": "^2.0.0" + }, + "bin": { + "pino": "bin.js" + } + }, + "node_modules/pino-abstract-transport": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.0.0.tgz", + "integrity": "sha512-c7vo5OpW4wIS42hUVcT5REsL8ZljsUfBjqV/e2sFxmFEFZiq1XLUp5EYLtuDH6PEHq9W1egWqRbnLUP5FuZmOA==", + "dev": true, + "dependencies": { + "readable-stream": "^4.0.0", + "split2": "^4.0.0" + } + }, + "node_modules/pino-abstract-transport/node_modules/readable-stream": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.3.0.tgz", + "integrity": "sha512-MuEnA0lbSi7JS8XM+WNJlWZkHAAdm7gETHdFK//Q/mChGyj2akEFtdLZh32jSdkWGbRwCW9pn6g3LWDdDeZnBQ==", + "dev": true, + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/pino-std-serializers": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-6.1.0.tgz", + "integrity": "sha512-KO0m2f1HkrPe9S0ldjx7za9BJjeHqBku5Ch8JyxETxT8dEFGz1PwgrHaOQupVYitpzbFSYm7nnljxD8dik2c+g==", + "dev": true + }, + "node_modules/pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.3.tgz", + "integrity": "sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-warning": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.1.0.tgz", + "integrity": "sha512-9C20RLxrZU/rFnxWncDkuF6O999NdIf3E1ws4B0ZeY3sRVPzWBMsYDE2lxjxhiXxg464cQTgKUGm8/i6y2YGXg==", + "dev": true + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/propagate": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", + "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", + "dev": true + }, + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/quick-format-unescaped": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", + "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==", + "dev": true + }, + "node_modules/quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "engines": { + "node": ">=8" + } + }, + "node_modules/quote": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/quote/-/quote-0.4.0.tgz", + "integrity": "sha512-KHp3y3xDjuBhRx+tYKOgzPnVHMRlgpn2rU450GcU4PL24r1H6ls/hfPrxDwX2pvYMlwODHI2l8WwgoV69x5rUQ==", + "dev": true + }, + "node_modules/ramda": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.28.0.tgz", + "integrity": "sha512-9QnLuG/kPVgWvMQ4aODhsBUFKOUmnbUnsSXACv+NCQZcHbeb+v8Lodp8OVxtRULN1/xOyYLLaL6npE6dMq5QTA==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==" + }, + "node_modules/read-pkg/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/read-pkg/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/real-require": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", + "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==", + "dev": true, + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dependencies": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safe-stable-stringify": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.2.tgz", + "integrity": "sha512-gMxvPJYhP0O9n2pvcfYfIuYgbledAOJFcqRThtPRmjscaipiwcwPPKLytpVzMkG2HAN87Qmo2d4PtGiri1dSLA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "devOptional": true + }, + "node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/sinon": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-16.0.0.tgz", + "integrity": "sha512-B8AaZZm9CT5pqe4l4uWJztfD/mOTa7dL8Qo0W4+s+t74xECOgSZDDQCBjNgIK3+n4kyxQrSTv2V5ul8K25qkiQ==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^3.0.0", + "@sinonjs/fake-timers": "^10.3.0", + "@sinonjs/samsam": "^8.0.0", + "diff": "^5.1.0", + "nise": "^5.1.4", + "supports-color": "^7.2.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/sinon" + } + }, + "node_modules/sinon/node_modules/@sinonjs/commons": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", + "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/snap-shot-compare": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/snap-shot-compare/-/snap-shot-compare-3.0.0.tgz", + "integrity": "sha512-bdwNOAGuKwPU+qsn0ASxTv+QfkXU+3VmkcDOkt965tes+JQQc8d6SfoLiEiRVhCey4v+ip2IjNUSbZm5nnkI9g==", + "dev": true, + "dependencies": { + "check-more-types": "2.24.0", + "debug": "4.1.1", + "disparity": "3.0.0", + "folktale": "2.3.2", + "lazy-ass": "1.6.0", + "strip-ansi": "5.2.0", + "variable-diff": "1.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/snap-shot-compare/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/snap-shot-compare/node_modules/debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/snap-shot-compare/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/snap-shot-core": { + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/snap-shot-core/-/snap-shot-core-10.2.4.tgz", + "integrity": "sha512-A7tkcfmvnRKge4VzFLAWA4UYMkvFY4TZKyL+D6hnHjI3HJ4pTepjG5DfR2ACeDKMzCSTQ5EwR2iOotI+Z37zsg==", + "dev": true, + "dependencies": { + "arg": "4.1.3", + "check-more-types": "2.24.0", + "common-tags": "1.8.0", + "debug": "4.3.1", + "escape-quotes": "1.0.2", + "folktale": "2.3.2", + "is-ci": "2.0.0", + "jsesc": "2.5.2", + "lazy-ass": "1.6.0", + "mkdirp": "1.0.4", + "pluralize": "8.0.0", + "quote": "0.4.0", + "ramda": "0.27.1" + }, + "bin": { + "resave-snapshots": "bin/resave-snapshots.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/snap-shot-core/node_modules/common-tags": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.0.tgz", + "integrity": "sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/snap-shot-core/node_modules/debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/snap-shot-core/node_modules/ramda": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.1.tgz", + "integrity": "sha512-PgIdVpn5y5Yns8vqb8FzBUEYn98V3xcPgawAkkgj0YJ0qDsnHCiNmZYfOGMgOvoB0eWFLpYbhxUR3mxfDIMvpw==", + "dev": true + }, + "node_modules/snap-shot-it": { + "version": "7.9.10", + "resolved": "https://registry.npmjs.org/snap-shot-it/-/snap-shot-it-7.9.10.tgz", + "integrity": "sha512-9USmsI2jc2kQslRhqkzFX+2K23o6v3VEzlQHwUNpZbbnEdU0ommReg2+Px7260sd+P/6CtaDx+LXadzt4caMVQ==", + "dev": true, + "dependencies": { + "@bahmutov/data-driven": "1.0.0", + "check-more-types": "2.24.0", + "common-tags": "1.8.2", + "debug": "4.3.4", + "has-only": "1.1.1", + "its-name": "1.0.0", + "lazy-ass": "1.6.0", + "pluralize": "8.0.0", + "ramda": "0.28.0", + "snap-shot-compare": "3.0.0", + "snap-shot-core": "10.2.4" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sonic-boom": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.2.1.tgz", + "integrity": "sha512-iITeTHxy3B9FGu8aVdiDXUVAcHMF9Ss0cCsAOo2HfCrmVGT3/DT5oYaeu0M/YKZDlKTvChEyPq0zI9Hf33EX6A==", + "dev": true, + "dependencies": { + "atomic-sleep": "^1.0.0" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz", + "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==" + }, + "node_modules/split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "dependencies": { + "through": "2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/split2": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.1.0.tgz", + "integrity": "sha512-VBiJxFkxiXRlUIeyMQi8s4hgvKCSjtknJv/LVYbrgALPwf5zSKmEwV9Lst25AkvMDnvxODugjdl6KZgwKM1WYQ==", + "dev": true, + "engines": { + "node": ">= 10.x" + } + }, + "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 + }, + "node_modules/static-eval": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.0.2.tgz", + "integrity": "sha512-N/D219Hcr2bPjLxPiV+TQE++Tsmrady7TqAJugLy7Xk1EumfDWS/f5dtBbkRCGE7wKKXuYockQoj8Rm2/pVKyg==", + "dependencies": { + "escodegen": "^1.8.1" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/table": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", + "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", + "dev": true, + "dependencies": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/test-exclude/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/test-exclude/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/thread-stream": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-2.3.0.tgz", + "integrity": "sha512-kaDqm1DET9pp3NXwR8382WHbnpXnRkN9xGN9dQt3B2+dmXiW8X1SOwmFOxAErEQ47ObhZ96J6yhZNXuyCOL7KA==", + "dev": true, + "dependencies": { + "real-require": "^0.2.0" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.5.3.tgz", + "integrity": "sha512-V2+og4j/rWReWvaFrse3s9g2xvUv/K9Azm/xo6CjIuq7oeGqsoimC7+9/A3tfvNcbQf8RPSVj/HV81fB4DJrjA==", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typescript": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", + "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/uglify-js": { + "version": "3.17.4", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", + "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/underscore": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", + "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==" + }, + "node_modules/unist-util-is": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", + "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", + "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz", + "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/universal-user-agent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", + "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==" + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "node_modules/v8-to-istanbul": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz", + "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/variable-diff": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/variable-diff/-/variable-diff-1.1.0.tgz", + "integrity": "sha512-0Jk/MsCNtL/fCuVIbsLxwXpABGZCzN57btcPbSsjOOAwkdHJ3Y58fo8BoUfG7jghnvglbwo+5Hk1KOJ2W2Ormw==", + "dev": true, + "dependencies": { + "chalk": "^1.1.1", + "object-assign": "^4.0.1" + } + }, + "node_modules/variable-diff/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/variable-diff/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/variable-diff/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/variable-diff/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/variable-diff/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz", + "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==" + }, + "node_modules/workerpool": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", + "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/xpath": { + "version": "0.0.34", + "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.34.tgz", + "integrity": "sha512-FxF6+rkr1rNSQrhUNYrAFJpRXNzlDoMxeXN5qI84939ylEv3qqPFKa85Oxr6tDaJKqwW6KKyo2v26TSv3k6LeA==", + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/yaml": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.1.tgz", + "integrity": "sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==", + "engines": { + "node": ">= 14" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs-unparser/node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs-unparser/node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "engines": { + "node": ">=12" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==" + }, + "@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "requires": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@bahmutov/data-driven": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@bahmutov/data-driven/-/data-driven-1.0.0.tgz", + "integrity": "sha512-YqW3hPS0RXriqjcCrLOTJj+LWe3c8JpwlL83k1ka1Q8U05ZjAKbGQZYeTzUd0NFEnnfPtsUiKGpFEBJG6kFuvg==", + "dev": true, + "requires": { + "check-more-types": "2.24.0", + "lazy-ass": "1.6.0" + } + }, + "@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "@conventional-commits/parser": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@conventional-commits/parser/-/parser-0.4.1.tgz", + "integrity": "sha512-H2ZmUVt6q+KBccXfMBhbBF14NlANeqHTXL4qCL6QGbMzrc4HDXyzWuxPxPNbz71f/5UkR5DrycP5VO9u7crahg==", + "requires": { + "unist-util-visit": "^2.0.3", + "unist-util-visit-parents": "^3.1.1" + } + }, + "@eslint/eslintrc": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", + "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "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 + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "@google-automations/git-file-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@google-automations/git-file-utils/-/git-file-utils-2.0.0.tgz", + "integrity": "sha512-F6h8npq7rt60fr3W+cil/zXbIiF9Hj8JzaN3LNh7uBIJpsWnjL9ObV84qW/345boMheDdo/n+cItmvCfsn0lLA==", + "requires": { + "@octokit/rest": "^19.0.7", + "@octokit/types": "^9.0.0", + "minimatch": "^5.1.0" + } + }, + "@humanwhocodes/config-array": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "@iarna/toml": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-3.0.0.tgz", + "integrity": "sha512-td6ZUkz2oS3VeleBcN+m//Q6HlCFCPrnI0FZhrt/h4XqLEdOyYp2u21nd8MdsR+WJy5r9PTDaHTDDfhf4H4l6Q==" + }, + "@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true + }, + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@octokit/auth-token": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.2.tgz", + "integrity": "sha512-pq7CwIMV1kmzkFTimdwjAINCXKTajZErLB4wMLYapR2nuB/Jpr66+05wOTZMSCBXP6n4DdDWT2W19Bm17vU69Q==", + "requires": { + "@octokit/types": "^8.0.0" + }, + "dependencies": { + "@octokit/openapi-types": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-14.0.0.tgz", + "integrity": "sha512-HNWisMYlR8VCnNurDU6os2ikx0s0VyEjDYHNS/h4cgb8DeOxQ0n72HyinUtdDVxJhFy3FWLGl0DJhfEWk3P5Iw==" + }, + "@octokit/types": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-8.2.1.tgz", + "integrity": "sha512-8oWMUji8be66q2B9PmEIUyQm00VPDPun07umUWSaCwxmeaquFBro4Hcc3ruVoDo3zkQyZBlRvhIMEYS3pBhanw==", + "requires": { + "@octokit/openapi-types": "^14.0.0" + } + } + } + }, + "@octokit/core": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.4.tgz", + "integrity": "sha512-rYKilwgzQ7/imScn3M9/pFfUf4I1AZEH3KhyJmtPdE2zfaXAn2mFfUy4FbKewzc2We5y/LlKLj36fWJLKC2SIQ==", + "requires": { + "@octokit/auth-token": "^3.0.0", + "@octokit/graphql": "^5.0.0", + "@octokit/request": "^6.0.0", + "@octokit/request-error": "^3.0.0", + "@octokit/types": "^9.0.0", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/endpoint": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.3.tgz", + "integrity": "sha512-57gRlb28bwTsdNXq+O3JTQ7ERmBTuik9+LelgcLIVfYwf235VHbN9QNo4kXExtp/h8T423cR5iJThKtFYxC7Lw==", + "requires": { + "@octokit/types": "^8.0.0", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + }, + "dependencies": { + "@octokit/openapi-types": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-14.0.0.tgz", + "integrity": "sha512-HNWisMYlR8VCnNurDU6os2ikx0s0VyEjDYHNS/h4cgb8DeOxQ0n72HyinUtdDVxJhFy3FWLGl0DJhfEWk3P5Iw==" + }, + "@octokit/types": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-8.2.1.tgz", + "integrity": "sha512-8oWMUji8be66q2B9PmEIUyQm00VPDPun07umUWSaCwxmeaquFBro4Hcc3ruVoDo3zkQyZBlRvhIMEYS3pBhanw==", + "requires": { + "@octokit/openapi-types": "^14.0.0" + } + } + } + }, + "@octokit/graphql": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.4.tgz", + "integrity": "sha512-amO1M5QUQgYQo09aStR/XO7KAl13xpigcy/kI8/N1PnZYSS69fgte+xA4+c2DISKqUZfsh0wwjc2FaCt99L41A==", + "requires": { + "@octokit/request": "^6.0.0", + "@octokit/types": "^8.0.0", + "universal-user-agent": "^6.0.0" + }, + "dependencies": { + "@octokit/openapi-types": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-14.0.0.tgz", + "integrity": "sha512-HNWisMYlR8VCnNurDU6os2ikx0s0VyEjDYHNS/h4cgb8DeOxQ0n72HyinUtdDVxJhFy3FWLGl0DJhfEWk3P5Iw==" + }, + "@octokit/types": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-8.2.1.tgz", + "integrity": "sha512-8oWMUji8be66q2B9PmEIUyQm00VPDPun07umUWSaCwxmeaquFBro4Hcc3ruVoDo3zkQyZBlRvhIMEYS3pBhanw==", + "requires": { + "@octokit/openapi-types": "^14.0.0" + } + } + } + }, + "@octokit/openapi-types": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-16.0.0.tgz", + "integrity": "sha512-JbFWOqTJVLHZSUUoF4FzAZKYtqdxWu9Z5m2QQnOyEa04fOFljvyh7D3GYKbfuaSWisqehImiVIMG4eyJeP5VEA==" + }, + "@octokit/plugin-paginate-rest": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.1.2.tgz", + "integrity": "sha512-qhrmtQeHU/IivxucOV1bbI/xZyC/iOBhclokv7Sut5vnejAIAEXVcGQeRpQlU39E0WwK9lNvJHphHri/DB6lbQ==", + "requires": { + "@octokit/tsconfig": "^1.0.2", + "@octokit/types": "^9.2.3" + }, + "dependencies": { + "@octokit/openapi-types": { + "version": "18.1.1", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-18.1.1.tgz", + "integrity": "sha512-VRaeH8nCDtF5aXWnjPuEMIYf1itK/s3JYyJcWFJT8X9pSNnBtriDf7wlEWsGuhPLl4QIH4xM8fqTXDwJ3Mu6sw==" + }, + "@octokit/types": { + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.3.2.tgz", + "integrity": "sha512-D4iHGTdAnEEVsB8fl95m1hiz7D5YiRdQ9b/OEb3BYRVwbLsGHcRVPz+u+BgRLNk0Q0/4iZCBqDN96j2XNxfXrA==", + "requires": { + "@octokit/openapi-types": "^18.0.0" + } + } + } + }, + "@octokit/plugin-request-log": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz", + "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==", + "requires": {} + }, + "@octokit/plugin-rest-endpoint-methods": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-7.2.3.tgz", + "integrity": "sha512-I5Gml6kTAkzVlN7KCtjOM+Ruwe/rQppp0QU372K1GP7kNOYEKe8Xn5BW4sE62JAHdwpq95OQK/qGNyKQMUzVgA==", + "requires": { + "@octokit/types": "^10.0.0" + }, + "dependencies": { + "@octokit/openapi-types": { + "version": "18.1.1", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-18.1.1.tgz", + "integrity": "sha512-VRaeH8nCDtF5aXWnjPuEMIYf1itK/s3JYyJcWFJT8X9pSNnBtriDf7wlEWsGuhPLl4QIH4xM8fqTXDwJ3Mu6sw==" + }, + "@octokit/types": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-10.0.0.tgz", + "integrity": "sha512-Vm8IddVmhCgU1fxC1eyinpwqzXPEYu0NrYzD3YZjlGjyftdLBTeqNblRC0jmJmgxbJIsQlyogVeGnrNaaMVzIg==", + "requires": { + "@octokit/openapi-types": "^18.0.0" + } + } + } + }, + "@octokit/request": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.2.tgz", + "integrity": "sha512-6VDqgj0HMc2FUX2awIs+sM6OwLgwHvAi4KCK3mT2H2IKRt6oH9d0fej5LluF5mck1lRR/rFWN0YIDSYXYSylbw==", + "requires": { + "@octokit/endpoint": "^7.0.0", + "@octokit/request-error": "^3.0.0", + "@octokit/types": "^8.0.0", + "is-plain-object": "^5.0.0", + "node-fetch": "^2.6.7", + "universal-user-agent": "^6.0.0" + }, + "dependencies": { + "@octokit/openapi-types": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-14.0.0.tgz", + "integrity": "sha512-HNWisMYlR8VCnNurDU6os2ikx0s0VyEjDYHNS/h4cgb8DeOxQ0n72HyinUtdDVxJhFy3FWLGl0DJhfEWk3P5Iw==" + }, + "@octokit/types": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-8.2.1.tgz", + "integrity": "sha512-8oWMUji8be66q2B9PmEIUyQm00VPDPun07umUWSaCwxmeaquFBro4Hcc3ruVoDo3zkQyZBlRvhIMEYS3pBhanw==", + "requires": { + "@octokit/openapi-types": "^14.0.0" + } + } + } + }, + "@octokit/request-error": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-3.0.2.tgz", + "integrity": "sha512-WMNOFYrSaX8zXWoJg9u/pKgWPo94JXilMLb2VManNOby9EZxrQaBe/QSC4a1TzpAlpxofg2X/jMnCyZgL6y7eg==", + "requires": { + "@octokit/types": "^8.0.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + }, + "dependencies": { + "@octokit/openapi-types": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-14.0.0.tgz", + "integrity": "sha512-HNWisMYlR8VCnNurDU6os2ikx0s0VyEjDYHNS/h4cgb8DeOxQ0n72HyinUtdDVxJhFy3FWLGl0DJhfEWk3P5Iw==" + }, + "@octokit/types": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-8.2.1.tgz", + "integrity": "sha512-8oWMUji8be66q2B9PmEIUyQm00VPDPun07umUWSaCwxmeaquFBro4Hcc3ruVoDo3zkQyZBlRvhIMEYS3pBhanw==", + "requires": { + "@octokit/openapi-types": "^14.0.0" + } + } + } + }, + "@octokit/rest": { + "version": "19.0.13", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-19.0.13.tgz", + "integrity": "sha512-/EzVox5V9gYGdbAI+ovYj3nXQT1TtTHRT+0eZPcuC05UFSWO3mdO9UY1C0i2eLF9Un1ONJkAk+IEtYGAC+TahA==", + "requires": { + "@octokit/core": "^4.2.1", + "@octokit/plugin-paginate-rest": "^6.1.2", + "@octokit/plugin-request-log": "^1.0.4", + "@octokit/plugin-rest-endpoint-methods": "^7.1.2" + } + }, + "@octokit/tsconfig": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@octokit/tsconfig/-/tsconfig-1.0.2.tgz", + "integrity": "sha512-I0vDR0rdtP8p2lGMzvsJzbhdOWy405HcGovrspJ8RRibHnyRgggUSNO5AIox5LmqiwmatHKYsvj6VGFHkqS7lA==" + }, + "@octokit/types": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.0.0.tgz", + "integrity": "sha512-LUewfj94xCMH2rbD5YJ+6AQ4AVjFYTgpp6rboWM5T7N3IsIF65SBEOVcYMGAEzO/kKNiNaW4LoWtoThOhH06gw==", + "requires": { + "@octokit/openapi-types": "^16.0.0" + } + }, + "@sinonjs/commons": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "dev": true, + "requires": { + "@sinonjs/commons": "^3.0.0" + }, + "dependencies": { + "@sinonjs/commons": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", + "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + } + } + }, + "@sinonjs/samsam": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.0.tgz", + "integrity": "sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==", + "dev": true, + "requires": { + "@sinonjs/commons": "^2.0.0", + "lodash.get": "^4.4.2", + "type-detect": "^4.0.8" + } + }, + "@sinonjs/text-encoding": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", + "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", + "dev": true + }, + "@types/chai": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.4.tgz", + "integrity": "sha512-KnRanxnpfpjUTqTCXslZSEdLfXExwgNxYPdiO2WGUj8+HDjFi8R3k5RVKPeSCzLjCcshCAtVO2QBbVuAV4kTnw==", + "dev": true + }, + "@types/diff": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@types/diff/-/diff-5.0.2.tgz", + "integrity": "sha512-uw8eYMIReOwstQ0QKF0sICefSy8cNO/v7gOTiIy9SbwuHyEecJUm7qlgueOO5S1udZ5I/irVydHVwMchgzbKTg==", + "dev": true + }, + "@types/iarna__toml": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/iarna__toml/-/iarna__toml-2.0.2.tgz", + "integrity": "sha512-Q3obxKhBLVVbEQ8zsAmsQVobAAZhi8dFFFjF0q5xKXiaHvH8IkSxcbM27e46M9feUMieR03SPpmp5CtaNzpdBg==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/inquirer": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/@types/inquirer/-/inquirer-9.0.3.tgz", + "integrity": "sha512-CzNkWqQftcmk2jaCWdBTf9Sm7xSw4rkI1zpU/Udw3HX5//adEZUIm9STtoRP1qgWj0CWQtJ9UTvqmO2NNjhMJw==", + "dev": true, + "requires": { + "@types/through": "*", + "rxjs": "^7.2.0" + }, + "dependencies": { + "rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "requires": { + "tslib": "^2.1.0" + } + }, + "tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true + } + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", + "dev": true + }, + "@types/js-yaml": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.5.tgz", + "integrity": "sha512-FhpRzf927MNQdRZP0J5DLIdTXhjLYzeUTmLAu69mnVksLH9CJY3IuSeEgbKUki7GQZm0WqDkGzyxju2EZGD2wA==", + "dev": true + }, + "@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "dev": true + }, + "@types/jsonpath": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@types/jsonpath/-/jsonpath-0.2.0.tgz", + "integrity": "sha512-v7qlPA0VpKUlEdhghbDqRoKMxFB3h3Ch688TApBJ6v+XLDdvWCGLJIYiPKGZnS6MAOie+IorCfNYVHOPIHSWwQ==", + "dev": true + }, + "@types/minimist": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", + "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==" + }, + "@types/mocha": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz", + "integrity": "sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==", + "dev": true + }, + "@types/node": { + "version": "18.11.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz", + "integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==", + "dev": true + }, + "@types/normalize-package-data": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", + "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==" + }, + "@types/npm-package-arg": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/@types/npm-package-arg/-/npm-package-arg-6.1.1.tgz", + "integrity": "sha512-452/1Kp9IdM/oR10AyqAgZOxUt7eLbm+EMJ194L6oarMYdZNiFIFAOJ7IIr0OrZXTySgfHjJezh2oiyk2kc3ag==" + }, + "@types/npmlog": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@types/npmlog/-/npmlog-7.0.0.tgz", + "integrity": "sha512-hJWbrKFvxKyWwSUXjZMYTINsSOY6IclhvGOZ97M8ac2tmR9hMwmTnYaMdpGhvju9ctWLTPhCS+eLfQNluiEjQQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/pino": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/@types/pino/-/pino-7.0.5.tgz", + "integrity": "sha512-wKoab31pknvILkxAF8ss+v9iNyhw5Iu/0jLtRkUD74cNfOOLJNnqfFKAv0r7wVaTQxRZtWrMpGfShwwBjOcgcg==", + "dev": true, + "requires": { + "pino": "*" + } + }, + "@types/semver": { + "version": "7.3.13", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", + "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", + "dev": true + }, + "@types/sinon": { + "version": "10.0.13", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.13.tgz", + "integrity": "sha512-UVjDqJblVNQYvVNUsj0PuYYw0ELRmgt1Nt5Vk0pT5f16ROGfcKJY8o1HVuMOJOpD727RrGB9EGvoaTQE5tgxZQ==", + "dev": true, + "requires": { + "@types/sinonjs__fake-timers": "*" + } + }, + "@types/sinonjs__fake-timers": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.2.tgz", + "integrity": "sha512-9GcLXF0/v3t80caGs5p2rRfkB+a8VBGLJZVih6CNFkx8IZ994wiKKLSRs9nuFwk1HevWs/1mnUmkApGrSGsShA==", + "dev": true + }, + "@types/through": { + "version": "0.0.30", + "resolved": "https://registry.npmjs.org/@types/through/-/through-0.0.30.tgz", + "integrity": "sha512-FvnCJljyxhPM3gkRgWmxmDZyAQSiBQQWLI0A0VFL0K7W1oRUrPJSqNO0NvTnLkBcotdlp3lKvaT0JrnyRDkzOg==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/unist": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", + "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==" + }, + "@types/xmldom": { + "version": "0.1.31", + "resolved": "https://registry.npmjs.org/@types/xmldom/-/xmldom-0.1.31.tgz", + "integrity": "sha512-bVy7s0nvaR5D1mT1a8ZkByHWNOGb6Vn4yi5TWhEdmyKlAG+08SA7Md6+jH+tYmMLueAwNeWvHHpeKrr6S4c4BA==", + "dev": true + }, + "@types/yargs": { + "version": "17.0.20", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.20.tgz", + "integrity": "sha512-eknWrTHofQuPk2iuqDm1waA7V6xPlbgBoaaXEgYkClhLOnB0TtbW+srJaOToAgawPxPlHQzwypFA2bhZaUGP5A==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", + "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==" + }, + "@typescript-eslint/eslint-plugin": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz", + "integrity": "sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "4.33.0", + "@typescript-eslint/scope-manager": "4.33.0", + "debug": "^4.3.1", + "functional-red-black-tree": "^1.0.1", + "ignore": "^5.1.8", + "regexpp": "^3.1.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/experimental-utils": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz", + "integrity": "sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.7", + "@typescript-eslint/scope-manager": "4.33.0", + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/typescript-estree": "4.33.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + } + }, + "@typescript-eslint/parser": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.33.0.tgz", + "integrity": "sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "4.33.0", + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/typescript-estree": "4.33.0", + "debug": "^4.3.1" + } + }, + "@typescript-eslint/scope-manager": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", + "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/visitor-keys": "4.33.0" + } + }, + "@typescript-eslint/types": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", + "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", + "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/visitor-keys": "4.33.0", + "debug": "^4.3.1", + "globby": "^11.0.3", + "is-glob": "^4.0.1", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", + "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.33.0", + "eslint-visitor-keys": "^2.0.0" + } + }, + "@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, + "@xmldom/xmldom": { + "version": "0.8.6", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.6.tgz", + "integrity": "sha512-uRjjusqpoqfmRkTaNuLJ2VohVr67Q5YwDATW3VU7PfzTj6IRaihGrYI7zckGZjxQPBIp63nfvJbM+Yu5ICh0Bg==" + }, + "abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dev": true, + "requires": { + "event-target-shim": "^5.0.0" + } + }, + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "requires": {} + }, + "agent-base": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", + "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "requires": { + "debug": "^4.3.4" + } + }, + "ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "requires": { + "ajv": "^8.0.0" + } + }, + "ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true + }, + "ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "requires": { + "type-fest": "^0.21.3" + }, + "dependencies": { + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true + } + } + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "array-ify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", + "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==" + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==" + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true + }, + "async-retry": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", + "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", + "requires": { + "retry": "0.13.1" + } + }, + "atomic-sleep": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", + "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==", + "dev": true + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true + }, + "before-after-hook": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", + "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==" + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" + }, + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "requires": { + "balanced-match": "^1.0.0" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "c8": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/c8/-/c8-9.0.0.tgz", + "integrity": "sha512-nFJhU2Cz6Frh2awk3IW7wwk3wx27/U2v8ojQCHGc1GWTCHS6aMu4lal327/ZnnYj7oSThGF1X3qUP1yzAJBcOQ==", + "dev": true, + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@istanbuljs/schema": "^0.1.3", + "find-up": "^5.0.0", + "foreground-child": "^3.1.1", + "istanbul-lib-coverage": "^3.2.0", + "istanbul-lib-report": "^3.0.1", + "istanbul-reports": "^3.1.6", + "test-exclude": "^6.0.0", + "v8-to-istanbul": "^9.0.0", + "yargs": "^17.7.2", + "yargs-parser": "^21.1.1" + }, + "dependencies": { + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true + } + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "requires": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + } + }, + "chai": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz", + "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^4.1.2", + "get-func-name": "^2.0.0", + "loupe": "^2.3.1", + "pathval": "^1.1.1", + "type-detect": "^4.0.5" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", + "dev": true + }, + "check-more-types": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", + "integrity": "sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA==", + "dev": true + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "dev": true + }, + "cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + } + }, + "code-suggester": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/code-suggester/-/code-suggester-4.2.0.tgz", + "integrity": "sha512-XqPYs9XOaLidTArPmKJnCU3aWiiiC+/i2mfLS/VPp07BJA1fptb0ZS+H6LnWSF4jV9tTYAjCmB8ru9uM5SiybA==", + "requires": { + "@octokit/rest": "^19.0.5", + "@types/yargs": "^16.0.0", + "async-retry": "^1.3.1", + "diff": "^5.0.0", + "glob": "^7.1.6", + "parse-diff": "^0.10.0", + "yargs": "^16.0.0" + }, + "dependencies": { + "@types/yargs": { + "version": "16.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.5.tgz", + "integrity": "sha512-AxO/ADJOBFJScHbWhq2xAhlWP24rY4aCEG/NFaMvbT3X2MgRsLjhjQwsn0Zi5zn0LG9jUhCCZMeX9Dkuw6k+vQ==", + "requires": { + "@types/yargs-parser": "*" + } + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + } + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "common-tags": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", + "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", + "dev": true + }, + "compare-func": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", + "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", + "requires": { + "array-ify": "^1.0.0", + "dot-prop": "^5.1.0" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "config-chain": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "dev": true, + "requires": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "conventional-changelog-conventionalcommits": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-6.1.0.tgz", + "integrity": "sha512-3cS3GEtR78zTfMzk0AizXKKIdN4OvSh7ibNz6/DPbhWWQu7LqE/8+/GqSodV+sywUR2gpJAdP/1JFf4XtN7Zpw==", + "requires": { + "compare-func": "^2.0.0" + } + }, + "conventional-changelog-writer": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-6.0.1.tgz", + "integrity": "sha512-359t9aHorPw+U+nHzUXHS5ZnPBOizRxfQsWT5ZDHBfvfxQOAik+yfuhKXG66CN5LEWPpMNnIMHUTCKeYNprvHQ==", + "requires": { + "conventional-commits-filter": "^3.0.0", + "dateformat": "^3.0.3", + "handlebars": "^4.7.7", + "json-stringify-safe": "^5.0.1", + "meow": "^8.1.2", + "semver": "^7.0.0", + "split": "^1.0.1" + } + }, + "conventional-commits-filter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-3.0.0.tgz", + "integrity": "sha512-1ymej8b5LouPx9Ox0Dw/qAO2dVdfpRFq28e5Y0jJEU8ZrLdy0vOSkkIInwmxErFGhg6SALro60ZrwYFVTUDo4Q==", + "requires": { + "lodash.ismatch": "^4.4.0", + "modify-values": "^1.0.1" + } + }, + "convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, + "cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.1" + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "requires": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + } + }, + "css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==" + }, + "dateformat": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==" + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==" + }, + "decamelize-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", + "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", + "requires": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "dependencies": { + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==" + } + } + }, + "deep-eql": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", + "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" + }, + "deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==" + }, + "detect-indent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", + "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==" + }, + "diff": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", + "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==" + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "disparity": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/disparity/-/disparity-3.0.0.tgz", + "integrity": "sha512-n94Rzbv2ambRaFzrnBf34IEiyOdIci7maRpMkoQWB6xFYGA7Nbs0Z5YQzMfTeyQeelv23nayqOcssBoc6rKrgw==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "diff": "^4.0.1" + }, + "dependencies": { + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + } + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "requires": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + } + }, + "domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==" + }, + "domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "requires": { + "domelementtype": "^2.3.0" + } + }, + "domutils": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz", + "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==", + "requires": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.1" + } + }, + "dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "requires": { + "is-obj": "^2.0.0" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "optional": true, + "peer": true, + "requires": { + "iconv-lite": "^0.6.2" + }, + "dependencies": { + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "optional": true, + "peer": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + } + } + }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + } + }, + "entities": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", + "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==" + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + }, + "escape-quotes": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/escape-quotes/-/escape-quotes-1.0.2.tgz", + "integrity": "sha512-JpLFzklNReeakCpyj59s78P5F72q0ZUpDnp2BuIk9TtTjj2HMsgiWBChw17BlZT8dRhMtmSb1jE2+pTP1iFYyw==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + }, + "escodegen": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "requires": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==" + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "requires": { + "prelude-ls": "~1.1.2" + } + } + } + }, + "eslint": { + "version": "7.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", + "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", + "dev": true, + "requires": { + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.3", + "@humanwhocodes/config-array": "^0.5.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "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 + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "eslint-config-prettier": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-7.2.0.tgz", + "integrity": "sha512-rV4Qu0C3nfJKPOAhFujFxB7RMP+URFyQqqOZW9DMRD7ZDTFyjaIlETU3xzHELt++4ugC0+Jm084HQYkkJe+Ivg==", + "dev": true, + "requires": {} + }, + "eslint-plugin-es": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", + "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "dev": true, + "requires": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + }, + "dependencies": { + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "eslint-plugin-node": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", + "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", + "dev": true, + "requires": { + "eslint-plugin-es": "^3.0.0", + "eslint-utils": "^2.0.0", + "ignore": "^5.1.1", + "minimatch": "^3.0.4", + "resolve": "^1.10.1", + "semver": "^6.1.0" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true + } + } + }, + "eslint-plugin-prettier": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.1.tgz", + "integrity": "sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g==", + "dev": true, + "requires": { + "prettier-linter-helpers": "^1.0.0" + } + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^2.0.0" + } + }, + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + }, + "espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "dev": true, + "requires": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "esprima": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.2.2.tgz", + "integrity": "sha512-+JpPZam9w5DuJ3Q67SqsMGtiHKENSMRVoxvArfJZK01/BfLEObtZ6orJa/MtoGNR/rfMgp5837T41PAmTwAv/A==" + }, + "esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + } + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "dev": true + }, + "events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true + }, + "execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + } + }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, + "fast-glob": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" + }, + "fast-redact": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.1.2.tgz", + "integrity": "sha512-+0em+Iya9fKGfEQGcd62Yv6onjBmmhV1uh86XVfOU8VwAe6kaFdQCWI9s0/Nnugx5Vd9tdbZ7e6gE2tR9dzXdw==", + "dev": true + }, + "fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true + }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "dev": true + }, + "folktale": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/folktale/-/folktale-2.3.2.tgz", + "integrity": "sha512-+8GbtQBwEqutP0v3uajDDoN64K2ehmHd0cjlghhxh0WpcfPzAIjPA03e1VvHlxL02FVGR0A6lwXsNQKn3H1RNQ==", + "dev": true + }, + "foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "dependencies": { + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true + } + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", + "dev": true + }, + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globals": { + "version": "13.19.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", + "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + }, + "dependencies": { + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + } + } + }, + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, + "gts": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/gts/-/gts-3.1.1.tgz", + "integrity": "sha512-Jw44aBbzMnd1vtZs7tZt3LMstKQukCBg7N4CKVGzviIQ45Cz5b9lxDJGXVKj/9ySuGv6TYEeijZJGbiiVcM27w==", + "dev": true, + "requires": { + "@typescript-eslint/eslint-plugin": "^4.2.0", + "@typescript-eslint/parser": "^4.2.0", + "chalk": "^4.1.0", + "eslint": "^7.10.0", + "eslint-config-prettier": "^7.0.0", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-prettier": "^3.1.4", + "execa": "^5.0.0", + "inquirer": "^7.3.3", + "json5": "^2.1.3", + "meow": "^9.0.0", + "ncp": "^2.0.0", + "prettier": "^2.1.2", + "rimraf": "^3.0.2", + "write-file-atomic": "^3.0.3" + }, + "dependencies": { + "meow": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", + "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==", + "dev": true, + "requires": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize": "^1.2.0", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + } + }, + "type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "dev": true + } + } + }, + "handlebars": { + "version": "4.7.7", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", + "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "requires": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4", + "wordwrap": "^1.0.0" + } + }, + "hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==" + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true + } + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "has-only": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/has-only/-/has-only-1.1.1.tgz", + "integrity": "sha512-3GuFy9rDw0xvovCHb4SOKiRImbZ+a8boFBUyGNRPVd2mRyQOzYdau5G9nodUXC1ZKYN59hrHFkW1lgBQscYfTg==", + "dev": true + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" + }, + "hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "http-proxy-agent": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz", + "integrity": "sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==", + "requires": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + } + }, + "https-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", + "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "requires": { + "agent-base": "^7.0.2", + "debug": "4" + } + }, + "human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true + }, + "ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "inquirer": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", + "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.19", + "mute-stream": "0.0.8", + "run-async": "^2.4.0", + "rxjs": "^6.6.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "requires": { + "has": "^1.0.3" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==" + }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==" + }, + "is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==" + }, + "is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true + }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "dev": true + }, + "istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + } + }, + "istanbul-reports": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", + "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "its-name": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/its-name/-/its-name-1.0.0.tgz", + "integrity": "sha512-GYUWFxViqxDvGzsNEItTEuOqqAQVx29Xl9Lh5YUqyJd6gPHTCMiIbjqcjjyUzsBUqEcgwIdRoydwgfFw1oYbhg==", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "requires": { + "argparse": "^2.0.1" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "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", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" + }, + "json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true + }, + "jsonpath": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/jsonpath/-/jsonpath-1.1.1.tgz", + "integrity": "sha512-l6Cg7jRpixfbgoWgkrl77dgEj8RPvND0wMH6TwQmi9Qs4TFfS9u5cUFnbeKTwj5ga5Y3BTGGNI28k117LJ009w==", + "requires": { + "esprima": "1.2.2", + "static-eval": "2.0.2", + "underscore": "1.12.1" + } + }, + "just-extend": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", + "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", + "dev": true + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + }, + "lazy-ass": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", + "integrity": "sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==", + "dev": true + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", + "dev": true + }, + "lodash.ismatch": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", + "integrity": "sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==" + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", + "dev": true + }, + "log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + } + }, + "loupe": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", + "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==", + "dev": true, + "requires": { + "get-func-name": "^2.0.0" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "requires": { + "semver": "^7.5.3" + } + }, + "map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==" + }, + "meow": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", + "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", + "requires": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + }, + "dependencies": { + "type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==" + } + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==" + }, + "minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "requires": { + "brace-expansion": "^2.0.1" + } + }, + "minimist": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==" + }, + "minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "requires": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, + "mocha": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", + "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==", + "dev": true, + "requires": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.3", + "debug": "4.3.3", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.2.0", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "4.2.1", + "ms": "2.1.3", + "nanoid": "3.3.1", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "which": "2.0.2", + "workerpool": "6.2.0", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "dependencies": { + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dev": true, + "requires": { + "ms": "2.1.2" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "dependencies": { + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "minimatch": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", + "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true + } + } + }, + "modify-values": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", + "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "nanoid": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", + "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "ncp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", + "integrity": "sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA==", + "dev": true + }, + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" + }, + "nise": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.4.tgz", + "integrity": "sha512-8+Ib8rRJ4L0o3kfmyVCL7gzrohyDe0cMFTBa2d364yIrEGMEoetznKJx899YxjybU6bL9SQkYPSBBs1gyYs8Xg==", + "dev": true, + "requires": { + "@sinonjs/commons": "^2.0.0", + "@sinonjs/fake-timers": "^10.0.2", + "@sinonjs/text-encoding": "^0.7.1", + "just-extend": "^4.0.2", + "path-to-regexp": "^1.7.0" + } + }, + "nock": { + "version": "13.3.0", + "resolved": "https://registry.npmjs.org/nock/-/nock-13.3.0.tgz", + "integrity": "sha512-HHqYQ6mBeiMc+N038w8LkMpDCRquCHWeNmN3v6645P3NhN2+qXOBqvPqo7Rt1VyCMzKhJ733wZqw5B7cQVFNPg==", + "dev": true, + "requires": { + "debug": "^4.1.0", + "json-stringify-safe": "^5.0.1", + "lodash": "^4.17.21", + "propagate": "^2.0.0" + } + }, + "node-fetch": { + "version": "2.6.8", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.8.tgz", + "integrity": "sha512-RZ6dBYuj8dRSfxpUSu+NsdF1dpPpluJxwOp+6IoDp/sH2QNDSvurYsAa+F1WxY2RjA1iP93xhcsUoYbF2XBqVg==", + "requires": { + "whatwg-url": "^5.0.0" + } + }, + "node-html-parser": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-6.1.4.tgz", + "integrity": "sha512-3muP9Uy/Pz7bQa9TNYVQzWJhNZMqyCx7xJle8kz2/y1UgzAUyXXShc1IcPaJy6u07CE3K5rQcRwlvHzmlySRjg==", + "requires": { + "css-select": "^5.1.0", + "he": "1.2.0" + } + }, + "normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "requires": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "requires": { + "boolbase": "^1.0.0" + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true + }, + "on-exit-leak-free": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.0.tgz", + "integrity": "sha512-VuCaZZAjReZ3vUwgOB8LxAosIurDiAW0s13rI1YwmaP++jvcxP77AWoQvenZebpCA2m8WC1/EosPYPMjnRAp/w==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-diff": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/parse-diff/-/parse-diff-0.10.0.tgz", + "integrity": "sha512-7ZnB7HXPl2WdTtSGGzMFuCIzpmaxrDsLwKZp2AQRQVlmL9MUnCHESAmrbKKD5g+ItFJiCN2YPfPyMjWeJV/JoA==" + }, + "parse-github-repo-url": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/parse-github-repo-url/-/parse-github-repo-url-1.4.1.tgz", + "integrity": "sha512-bSWyzBKqcSL4RrncTpGsEKoJ7H8a4L3++ifTAbTFeMHyq2wRV+42DGmQcHIrJIvdcacjIOxEuKH/w4tthF17gg==" + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "dev": true, + "requires": { + "isarray": "0.0.1" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "dev": true + } + } + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, + "pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "pino": { + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/pino/-/pino-8.8.0.tgz", + "integrity": "sha512-cF8iGYeu2ODg2gIwgAHcPrtR63ILJz3f7gkogaHC/TXVVXxZgInmNYiIpDYEwgEkxZti2Se6P2W2DxlBIZe6eQ==", + "dev": true, + "requires": { + "atomic-sleep": "^1.0.0", + "fast-redact": "^3.1.1", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "v1.0.0", + "pino-std-serializers": "^6.0.0", + "process-warning": "^2.0.0", + "quick-format-unescaped": "^4.0.3", + "real-require": "^0.2.0", + "safe-stable-stringify": "^2.3.1", + "sonic-boom": "^3.1.0", + "thread-stream": "^2.0.0" + } + }, + "pino-abstract-transport": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.0.0.tgz", + "integrity": "sha512-c7vo5OpW4wIS42hUVcT5REsL8ZljsUfBjqV/e2sFxmFEFZiq1XLUp5EYLtuDH6PEHq9W1egWqRbnLUP5FuZmOA==", + "dev": true, + "requires": { + "readable-stream": "^4.0.0", + "split2": "^4.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.3.0.tgz", + "integrity": "sha512-MuEnA0lbSi7JS8XM+WNJlWZkHAAdm7gETHdFK//Q/mChGyj2akEFtdLZh32jSdkWGbRwCW9pn6g3LWDdDeZnBQ==", + "dev": true, + "requires": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10" + } + } + } + }, + "pino-std-serializers": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-6.1.0.tgz", + "integrity": "sha512-KO0m2f1HkrPe9S0ldjx7za9BJjeHqBku5Ch8JyxETxT8dEFGz1PwgrHaOQupVYitpzbFSYm7nnljxD8dik2c+g==", + "dev": true + }, + "pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "prettier": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.3.tgz", + "integrity": "sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw==", + "dev": true + }, + "prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "requires": { + "fast-diff": "^1.1.2" + } + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "dev": true + }, + "process-warning": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.1.0.tgz", + "integrity": "sha512-9C20RLxrZU/rFnxWncDkuF6O999NdIf3E1ws4B0ZeY3sRVPzWBMsYDE2lxjxhiXxg464cQTgKUGm8/i6y2YGXg==", + "dev": true + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "propagate": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", + "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", + "dev": true + }, + "proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", + "dev": true + }, + "punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "dev": true + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, + "quick-format-unescaped": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", + "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==", + "dev": true + }, + "quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==" + }, + "quote": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/quote/-/quote-0.4.0.tgz", + "integrity": "sha512-KHp3y3xDjuBhRx+tYKOgzPnVHMRlgpn2rU450GcU4PL24r1H6ls/hfPrxDwX2pvYMlwODHI2l8WwgoV69x5rUQ==", + "dev": true + }, + "ramda": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.28.0.tgz", + "integrity": "sha512-9QnLuG/kPVgWvMQ4aODhsBUFKOUmnbUnsSXACv+NCQZcHbeb+v8Lodp8OVxtRULN1/xOyYLLaL6npE6dMq5QTA==", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==" + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==" + }, + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==" + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" + } + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "real-require": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", + "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==", + "dev": true + }, + "redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "requires": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + } + }, + "regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, + "resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "requires": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==" + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "safe-stable-stringify": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.2.tgz", + "integrity": "sha512-gMxvPJYhP0O9n2pvcfYfIuYgbledAOJFcqRThtPRmjscaipiwcwPPKLytpVzMkG2HAN87Qmo2d4PtGiri1dSLA==", + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "devOptional": true + }, + "semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "sinon": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-16.0.0.tgz", + "integrity": "sha512-B8AaZZm9CT5pqe4l4uWJztfD/mOTa7dL8Qo0W4+s+t74xECOgSZDDQCBjNgIK3+n4kyxQrSTv2V5ul8K25qkiQ==", + "dev": true, + "requires": { + "@sinonjs/commons": "^3.0.0", + "@sinonjs/fake-timers": "^10.3.0", + "@sinonjs/samsam": "^8.0.0", + "diff": "^5.1.0", + "nise": "^5.1.4", + "supports-color": "^7.2.0" + }, + "dependencies": { + "@sinonjs/commons": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", + "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + } + } + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + }, + "snap-shot-compare": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/snap-shot-compare/-/snap-shot-compare-3.0.0.tgz", + "integrity": "sha512-bdwNOAGuKwPU+qsn0ASxTv+QfkXU+3VmkcDOkt965tes+JQQc8d6SfoLiEiRVhCey4v+ip2IjNUSbZm5nnkI9g==", + "dev": true, + "requires": { + "check-more-types": "2.24.0", + "debug": "4.1.1", + "disparity": "3.0.0", + "folktale": "2.3.2", + "lazy-ass": "1.6.0", + "strip-ansi": "5.2.0", + "variable-diff": "1.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "snap-shot-core": { + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/snap-shot-core/-/snap-shot-core-10.2.4.tgz", + "integrity": "sha512-A7tkcfmvnRKge4VzFLAWA4UYMkvFY4TZKyL+D6hnHjI3HJ4pTepjG5DfR2ACeDKMzCSTQ5EwR2iOotI+Z37zsg==", + "dev": true, + "requires": { + "arg": "4.1.3", + "check-more-types": "2.24.0", + "common-tags": "1.8.0", + "debug": "4.3.1", + "escape-quotes": "1.0.2", + "folktale": "2.3.2", + "is-ci": "2.0.0", + "jsesc": "2.5.2", + "lazy-ass": "1.6.0", + "mkdirp": "1.0.4", + "pluralize": "8.0.0", + "quote": "0.4.0", + "ramda": "0.27.1" + }, + "dependencies": { + "common-tags": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.0.tgz", + "integrity": "sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==", + "dev": true + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ramda": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.1.tgz", + "integrity": "sha512-PgIdVpn5y5Yns8vqb8FzBUEYn98V3xcPgawAkkgj0YJ0qDsnHCiNmZYfOGMgOvoB0eWFLpYbhxUR3mxfDIMvpw==", + "dev": true + } + } + }, + "snap-shot-it": { + "version": "7.9.10", + "resolved": "https://registry.npmjs.org/snap-shot-it/-/snap-shot-it-7.9.10.tgz", + "integrity": "sha512-9USmsI2jc2kQslRhqkzFX+2K23o6v3VEzlQHwUNpZbbnEdU0ommReg2+Px7260sd+P/6CtaDx+LXadzt4caMVQ==", + "dev": true, + "requires": { + "@bahmutov/data-driven": "1.0.0", + "check-more-types": "2.24.0", + "common-tags": "1.8.2", + "debug": "4.3.4", + "has-only": "1.1.1", + "its-name": "1.0.0", + "lazy-ass": "1.6.0", + "pluralize": "8.0.0", + "ramda": "0.28.0", + "snap-shot-compare": "3.0.0", + "snap-shot-core": "10.2.4" + } + }, + "sonic-boom": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.2.1.tgz", + "integrity": "sha512-iITeTHxy3B9FGu8aVdiDXUVAcHMF9Ss0cCsAOo2HfCrmVGT3/DT5oYaeu0M/YKZDlKTvChEyPq0zI9Hf33EX6A==", + "dev": true, + "requires": { + "atomic-sleep": "^1.0.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==" + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz", + "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==" + }, + "split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "requires": { + "through": "2" + } + }, + "split2": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.1.0.tgz", + "integrity": "sha512-VBiJxFkxiXRlUIeyMQi8s4hgvKCSjtknJv/LVYbrgALPwf5zSKmEwV9Lst25AkvMDnvxODugjdl6KZgwKM1WYQ==", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "static-eval": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.0.2.tgz", + "integrity": "sha512-N/D219Hcr2bPjLxPiV+TQE++Tsmrady7TqAJugLy7Xk1EumfDWS/f5dtBbkRCGE7wKKXuYockQoj8Rm2/pVKyg==", + "requires": { + "escodegen": "^1.8.1" + } + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + }, + "strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "requires": { + "min-indent": "^1.0.0" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" + }, + "table": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", + "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", + "dev": true, + "requires": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + } + }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "thread-stream": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-2.3.0.tgz", + "integrity": "sha512-kaDqm1DET9pp3NXwR8382WHbnpXnRkN9xGN9dQt3B2+dmXiW8X1SOwmFOxAErEQ47ObhZ96J6yhZNXuyCOL7KA==", + "dev": true, + "requires": { + "real-require": "^0.2.0" + } + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==" + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "type-fest": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.5.3.tgz", + "integrity": "sha512-V2+og4j/rWReWvaFrse3s9g2xvUv/K9Azm/xo6CjIuq7oeGqsoimC7+9/A3tfvNcbQf8RPSVj/HV81fB4DJrjA==" + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "typescript": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", + "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==" + }, + "uglify-js": { + "version": "3.17.4", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", + "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", + "optional": true + }, + "underscore": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", + "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==" + }, + "unist-util-is": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", + "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==" + }, + "unist-util-visit": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", + "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz", + "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + }, + "universal-user-agent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", + "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==" + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "v8-to-istanbul": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz", + "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0" + } + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "variable-diff": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/variable-diff/-/variable-diff-1.1.0.tgz", + "integrity": "sha512-0Jk/MsCNtL/fCuVIbsLxwXpABGZCzN57btcPbSsjOOAwkdHJ3Y58fo8BoUfG7jghnvglbwo+5Hk1KOJ2W2Ormw==", + "dev": true, + "requires": { + "chalk": "^1.1.1", + "object-assign": "^4.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", + "dev": true + } + } + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "word-wrap": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz", + "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==" + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==" + }, + "workerpool": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", + "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", + "dev": true + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "xpath": { + "version": "0.0.34", + "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.34.tgz", + "integrity": "sha512-FxF6+rkr1rNSQrhUNYrAFJpRXNzlDoMxeXN5qI84939ylEv3qqPFKa85Oxr6tDaJKqwW6KKyo2v26TSv3k6LeA==" + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "yaml": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.1.tgz", + "integrity": "sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==" + }, + "yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "requires": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "dependencies": { + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==" + } + } + }, + "yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==" + }, + "yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "requires": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "dependencies": { + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true + }, + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true + }, + "is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true + } + } + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true + } + } +} diff --git a/package.json b/package.json index aced0b285..9231a2096 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,13 @@ { "name": "release-please", - "version": "14.17.0", + "version": "16.8.0", "description": "generate release PRs based on the conventionalcommits.org spec", "main": "./build/src/index.js", "bin": "./build/src/bin/release-please.js", "scripts": { - "test": "cross-env ENVIRONMENT=test LC_ALL=en c8 mocha --recursive --timeout=5000 build/test", + "test": "cross-env ENVIRONMENT=test LC_ALL=en c8 mocha --node-option no-experimental-fetch --recursive --timeout=5000 build/test", "docs": "echo add docs tests", - "test:snap": "SNAPSHOT_UPDATE=1 LC_ALL=en npm test", + "test:snap": "cross-env SNAPSHOT_UPDATE=1 LC_ALL=en npm test", "clean": "gts clean", "prepare": "npm run compile", "lint": "gts check", @@ -38,18 +38,16 @@ } }, "devDependencies": { - "@octokit/types": "^8.0.0", + "@octokit/types": "^9.0.0", "@types/chai": "^4.1.7", "@types/diff": "^5.0.2", "@types/iarna__toml": "^2.0.1", + "@types/inquirer": "^9.0.3", "@types/js-yaml": "^4.0.0", "@types/jsonpath": "^0.2.0", - "@types/lerna__collect-updates": "^5.0.0", - "@types/lerna__package": "^5.0.0", - "@types/lerna__package-graph": "^5.0.0", - "@types/lerna__run-topologically": "^5.0.0", "@types/mocha": "^9.0.0", "@types/node": "^18.0.0", + "@types/npmlog": "^7.0.0", "@types/pino": "^7.0.0", "@types/semver": "^7.0.0", "@types/sinon": "^10.0.0", @@ -57,23 +55,20 @@ "@types/yargs": "^17.0.0", "ajv": "^8.11.0", "ajv-formats": "^2.1.1", - "c8": "^7.0.0", + "c8": "^9.0.0", "chai": "^4.2.0", + "config-chain": "^1.1.13", "cross-env": "^7.0.0", "gts": "^3.1.0", "mocha": "^9.2.2", "nock": "^13.0.0", - "sinon": "14.0.2", + "sinon": "16.0.0", "snap-shot-it": "^7.0.0" }, "dependencies": { "@conventional-commits/parser": "^0.4.1", - "@google-automations/git-file-utils": "^1.2.0", - "@iarna/toml": "^2.2.5", - "@lerna/collect-updates": "^4.0.0", - "@lerna/package": "^4.0.0", - "@lerna/package-graph": "^4.0.0", - "@lerna/run-topologically": "^4.0.0", + "@google-automations/git-file-utils": "^2.0.0", + "@iarna/toml": "^3.0.0", "@octokit/graphql": "^5.0.0", "@octokit/request": "^6.0.0", "@octokit/request-error": "^3.0.0", @@ -81,28 +76,29 @@ "@types/npm-package-arg": "^6.1.0", "@xmldom/xmldom": "^0.8.4", "chalk": "^4.0.0", - "code-suggester": "^4.1.0", - "conventional-changelog-conventionalcommits": "^5.0.0", - "conventional-changelog-writer": "^5.0.0", - "conventional-commits-filter": "^2.0.2", + "code-suggester": "^4.2.0", + "conventional-changelog-conventionalcommits": "^6.0.0", + "conventional-changelog-writer": "^6.0.0", + "conventional-commits-filter": "^3.0.0", "detect-indent": "^6.1.0", "diff": "^5.0.0", "figures": "^3.0.0", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", "js-yaml": "^4.0.0", "jsonpath": "^1.1.1", "node-html-parser": "^6.0.0", "parse-github-repo-url": "^1.4.1", - "semver": "^7.0.0", + "semver": "^7.5.3", "type-fest": "^3.0.0", "typescript": "^4.6.4", "unist-util-visit": "^2.0.3", "unist-util-visit-parents": "^3.1.1", - "xpath": "^0.0.32", + "xpath": "^0.0.34", + "yaml": "^2.2.2", "yargs": "^17.0.0" }, "engines": { - "node": ">=14.0.0" + "node": ">=18.0.0" } } diff --git a/release-please-config.json b/release-please-config.json new file mode 100644 index 000000000..1d3d4638c --- /dev/null +++ b/release-please-config.json @@ -0,0 +1,12 @@ +{ + "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json", + "release-type": "node", + "include-component-in-tag": false, + "packages": { + ".": { + "extra-files": [ + "src/index.ts" + ] + } + } +} diff --git a/schemas/config.json b/schemas/config.json index 77adbe6fa..716d7daf8 100644 --- a/schemas/config.json +++ b/schemas/config.json @@ -20,6 +20,10 @@ "description": "Feature changes only bump semver patch if version < 1.0.0", "type": "boolean" }, + "prerelease-type": { + "description": "Configuration option for the prerelese versioning strategy. If prerelease strategy used and type set, will set the prerelese part of the version to the provided value in case prerelease part is not present.", + "type": "string" + }, "versioning": { "description": "Versioning strategy. Defaults to `default`", "type": "string" @@ -99,6 +103,10 @@ "description": "Customize the release pull request header.", "type": "string" }, + "pull-request-footer": { + "description": "Customize the release pull request footer.", + "type": "string" + }, "separate-pull-requests": { "description": "Open a separate release pull request for each component. Defaults to `false`.", "type": "boolean" @@ -117,12 +125,12 @@ "type": "string" }, { - "description": "An extra JSON on YAML file with a targeted update via jsonpath.", + "description": "An extra JSON, YAML, or TOML file with a targeted update via jsonpath.", "type": "object", "properties": { "type": { "description": "The file format type.", - "enum": ["json", "yaml"] + "enum": ["json", "toml", "yaml"] }, "path": { "description": "The path to the file.", @@ -184,6 +192,13 @@ ] } }, + "exclude-paths": { + "description": "Path of commits to be excluded from parsing. If all files from commit belong to one of the paths it will be skipped", + "type": "array", + "items": { + "type": "string" + } + }, "version-file": { "description": "Path to the specialize version file. Used by `ruby` and `simple` strategies.", "type": "string" @@ -283,7 +298,35 @@ "type": { "description": "The name of the plugin.", "type": "string", - "enum": ["cargo-workspace", "maven-workspace", "node-workspace"] + "enum": [ + "cargo-workspace", + "maven-workspace" + ] + }, + "updateAllPackages": { + "description": "Whether to force updating all packages regardless of the dependency tree. Defaults to `false`.", + "type": "boolean" + }, + "merge": { + "description": "Whether to merge in-scope pull requests into a combined release pull request. Defaults to `true`.", + "type": "boolean" + }, + "considerAllArtifacts": { + "description": "Whether to analyze all packages in the workspace for cross-component version bumping. This currently only works for the maven-workspace plugin. Defaults to `true`.", + "type": "boolean" + } + } + }, + { + "description": "Configuration for various `workspace` plugins.", + "type": "object", + "properties": { + "type": { + "description": "The name of the plugin.", + "type": "string", + "enum": [ + "node-workspace" + ] }, "updateAllPackages": { "description": "Whether to force updating all packages regardless of the dependency tree. Defaults to `false`.", @@ -296,6 +339,10 @@ "considerAllArtifacts": { "description": "Whether to analyze all packages in the workspace for cross-component version bumping. This currently only works for the maven-workspace plugin. Defaults to `true`.", "type": "boolean" + }, + "updatePeerDependencies": { + "description": "Also bump peer dependency versions if they are modified. Defaults to `false`.", + "type": "boolean" } } }, @@ -389,11 +436,13 @@ "changelog-path": true, "pull-request-title-pattern": true, "pull-request-header": true, + "pull-request-footer": true, "separate-pull-requests": true, "tag-separator": true, "extra-files": true, "version-file": true, "snapshot-label": true, - "initial-version": true + "initial-version": true, + "exclude-paths": true } } diff --git a/src/bin/release-please.ts b/src/bin/release-please.ts index 8353fc817..4baf2c626 100644 --- a/src/bin/release-please.ts +++ b/src/bin/release-please.ts @@ -63,6 +63,7 @@ interface ManifestArgs { interface VersioningArgs { bumpMinorPreMajor?: boolean; bumpPatchForMinorPreMajor?: boolean; + prereleaseType?: string; releaseAs?: string; // only for Ruby: TODO replace with generic bootstrap option @@ -114,6 +115,7 @@ interface TaggingArgs { monorepoTags?: boolean; pullRequestTitlePattern?: string; pullRequestHeader?: string; + pullRequestFooter?: string; } interface CreatePullRequestArgs @@ -275,6 +277,10 @@ function pullRequestStrategyOptions(yargs: yargs.Argv): yargs.Argv { default: false, type: 'boolean', }) + .option('prerelease-type', { + describe: 'type of the prerelease, e.g., alpha', + type: 'string', + }) .option('extra-files', { describe: 'extra files for the strategy to consider', type: 'string', @@ -414,6 +420,10 @@ function taggingOptions(yargs: yargs.Argv): yargs.Argv { .option('pull-request-header', { describe: 'Header for release PR', type: 'string', + }) + .option('pull-request-footer', { + describe: 'Footer for release PR', + type: 'string', }); } @@ -447,11 +457,13 @@ const createReleasePullRequestCommand: yargs.CommandModule< draftPullRequest: argv.draftPullRequest, bumpMinorPreMajor: argv.bumpMinorPreMajor, bumpPatchForMinorPreMajor: argv.bumpPatchForMinorPreMajor, + prereleaseType: argv.prereleaseType, changelogPath: argv.changelogPath, changelogType: argv.changelogType, changelogHost: argv.changelogHost, pullRequestTitlePattern: argv.pullRequestTitlePattern, pullRequestHeader: argv.pullRequestHeader, + pullRequestFooter: argv.pullRequestFooter, changelogSections: argv.changelogSections, releaseAs: argv.releaseAs, versioning: argv.versioningStrategy, @@ -711,6 +723,7 @@ const bootstrapCommand: yargs.CommandModule<{}, BootstrapArgs> = { draftPullRequest: argv.draftPullRequest, bumpMinorPreMajor: argv.bumpMinorPreMajor, bumpPatchForMinorPreMajor: argv.bumpPatchForMinorPreMajor, + prereleaseType: argv.prereleaseType, changelogPath: argv.changelogPath, changelogHost: argv.changelogHost, changelogSections: argv.changelogSections, @@ -820,6 +833,28 @@ export const parser = yargs setLogger(new CheckpointLogger(true)); } }) + .option('plugin', { + describe: 'load plugin named release-please-', + type: 'array', + default: [], + }) + .middleware(argv => { + for (const pluginName of argv.plugin) { + console.log(`requiring plugin: ${pluginName}`); + try { + const plugin = require(pluginName.toString()); + if (plugin?.init) { + console.log(`loading plugin: ${pluginName}`); + } else { + console.warn( + `plugin: ${pluginName} did not have an init() function.` + ); + } + } catch (e) { + console.warn(`failed to require plugin: ${pluginName}:`, e); + } + } + }) .demandCommand(1) .strict(true) .scriptName('release-please'); diff --git a/src/changelog-notes/default.ts b/src/changelog-notes/default.ts index 0404a5653..49405aa08 100644 --- a/src/changelog-notes/default.ts +++ b/src/changelog-notes/default.ts @@ -31,6 +31,11 @@ interface DefaultChangelogNotesOptions { mainTemplate?: string; } +interface Note { + title: string; + text: string; +} + export class DefaultChangelogNotes implements ChangelogNotes { // allow for customized commit template. private commitPartial?: string; @@ -68,14 +73,23 @@ export class DefaultChangelogNotes implements ChangelogNotes { this.headerPartial || preset.writerOpts.headerPartial; preset.writerOpts.mainTemplate = this.mainTemplate || preset.writerOpts.mainTemplate; - const changelogCommits = commits.map(commit => { + const notes = commit.notes + .filter(note => note.title === 'BREAKING CHANGE') + .map(note => + replaceIssueLink( + note, + context.host, + context.owner, + context.repository + ) + ); return { body: '', // commit.body, subject: htmlEscape(commit.bareMessage), type: commit.type, scope: commit.scope, - notes: commit.notes.filter(note => note.title === 'BREAKING CHANGE'), + notes, references: commit.references, mentions: [], merge: null, @@ -95,6 +109,19 @@ export class DefaultChangelogNotes implements ChangelogNotes { } } +function replaceIssueLink( + note: Note, + host: string, + owner: string, + repo: string +): Note { + note.text = note.text.replace( + /\(#(\d+)\)/, + `([#$1](${host}/${owner}/${repo}/issues/$1))` + ); + return note; +} + function htmlEscape(message: string): string { return message.replace('<', '<').replace('>', '>'); } diff --git a/src/changelog-notes/github.ts b/src/changelog-notes/github.ts index 2fd48cde7..a79ddeeab 100644 --- a/src/changelog-notes/github.ts +++ b/src/changelog-notes/github.ts @@ -25,10 +25,13 @@ export class GitHubChangelogNotes implements ChangelogNotes { _commits: ConventionalCommit[], options: BuildNotesOptions ): Promise { - return await this.github.generateReleaseNotes( + const body = await this.github.generateReleaseNotes( options.currentTag, options.targetBranch, options.previousTag ); + const date = new Date().toLocaleDateString('en-CA'); + const header = `## ${options.version} (${date})`; + return `${header}\n\n${body}`; } } diff --git a/src/factories/plugin-factory.ts b/src/factories/plugin-factory.ts index 60c01de00..242346853 100644 --- a/src/factories/plugin-factory.ts +++ b/src/factories/plugin-factory.ts @@ -41,6 +41,7 @@ export interface PluginFactoryOptions { // node options alwaysLinkLocal?: boolean; + updatePeerDependencies?: boolean; // workspace options updateAllPackages?: boolean; @@ -58,7 +59,11 @@ const pluginFactories: Record = { options.targetBranch, options.repositoryConfig, (options.type as LinkedVersionPluginConfig).groupName, - (options.type as LinkedVersionPluginConfig).components + (options.type as LinkedVersionPluginConfig).components, + { + ...options, + ...(options.type as WorkspacePluginOptions), + } ), 'cargo-workspace': options => new CargoWorkspace( diff --git a/src/factories/versioning-strategy-factory.ts b/src/factories/versioning-strategy-factory.ts index 3a12b2b18..ba69b0714 100644 --- a/src/factories/versioning-strategy-factory.ts +++ b/src/factories/versioning-strategy-factory.ts @@ -20,6 +20,7 @@ import {AlwaysBumpMajor} from '../versioning-strategies/always-bump-major'; import {ServicePackVersioningStrategy} from '../versioning-strategies/service-pack'; import {GitHub} from '../github'; import {ConfigurationError} from '../errors'; +import {PrereleaseVersioningStrategy} from '../versioning-strategies/prerelease'; export type VersioningStrategyType = string; @@ -27,6 +28,8 @@ export interface VersioningStrategyFactoryOptions { type?: VersioningStrategyType; bumpMinorPreMajor?: boolean; bumpPatchForMinorPreMajor?: boolean; + prereleaseType?: string; + prerelease?: boolean; github: GitHub; } @@ -40,6 +43,7 @@ const versioningTypes: Record = { 'always-bump-minor': options => new AlwaysBumpMinor(options), 'always-bump-major': options => new AlwaysBumpMajor(options), 'service-pack': options => new ServicePackVersioningStrategy(options), + prerelease: options => new PrereleaseVersioningStrategy(options), }; export function buildVersioningStrategy( diff --git a/src/factory.ts b/src/factory.ts index 58f30ad05..db5ae352f 100644 --- a/src/factory.ts +++ b/src/factory.ts @@ -16,6 +16,7 @@ import {Strategy} from './strategy'; import {Go} from './strategies/go'; import {GoYoshi} from './strategies/go-yoshi'; import {JavaYoshi} from './strategies/java-yoshi'; +import {JavaYoshiMonoRepo} from './strategies/java-yoshi-mono-repo'; import {KRMBlueprint} from './strategies/krm-blueprint'; import {OCaml} from './strategies/ocaml'; import {PHP} from './strategies/php'; @@ -24,6 +25,7 @@ import {Python} from './strategies/python'; import {Ruby} from './strategies/ruby'; import {RubyYoshi} from './strategies/ruby-yoshi'; import {Rust} from './strategies/rust'; +import {Sfdx} from './strategies/sfdx'; import {Simple} from './strategies/simple'; import {TerraformModule} from './strategies/terraform-module'; import {Helm} from './strategies/helm'; @@ -69,6 +71,7 @@ const releasers: Record = { java: options => new Java(options), maven: options => new Maven(options), 'java-yoshi': options => new JavaYoshi(options), + 'java-yoshi-mono-repo': options => new JavaYoshiMonoRepo(options), 'java-backport': options => new JavaYoshi({ ...options, @@ -97,6 +100,8 @@ const releasers: Record = { ruby: options => new Ruby(options), 'ruby-yoshi': options => new RubyYoshi(options), rust: options => new Rust(options), + salesforce: options => new Sfdx(options), + sfdx: options => new Sfdx(options), simple: options => new Simple(options), 'terraform-module': options => new TerraformModule(options), helm: options => new Helm(options), @@ -114,6 +119,8 @@ export async function buildStrategy( type: options.versioning, bumpMinorPreMajor: options.bumpMinorPreMajor, bumpPatchForMinorPreMajor: options.bumpPatchForMinorPreMajor, + prereleaseType: options.prereleaseType, + prerelease: options.prerelease, }); const changelogNotes = buildChangelogNotes({ type: options.changelogType || 'default', diff --git a/src/github.ts b/src/github.ts index 202a1bdc7..0b581b646 100644 --- a/src/github.ts +++ b/src/github.ts @@ -224,16 +224,11 @@ export class GitHub { } const {host, port} = defaultProxy; - - return new URL(baseUrl).protocol.replace(':', '') === 'http' - ? new HttpProxyAgent({ - host, - port, - }) - : new HttpsProxyAgent({ - host, - port, - }); + if (new URL(baseUrl).protocol.replace(':', '') === 'http') { + return new HttpProxyAgent(`http://${host}:${port}`); + } else { + return new HttpsProxyAgent(`https://${host}:${port}`); + } } /** @@ -474,17 +469,42 @@ export class GitHub { } const history = response.repository.ref.target.history; const commits = (history.nodes || []) as GraphQLCommit[]; + // Count the number of pull requests associated with each merge commit. This is + // used in the next step to make sure we only find pull requests with a + // merge commit that contain 1 merged commit. + const mergeCommitCount: Record = {}; + for (const commit of commits) { + for (const pr of commit.associatedPullRequests.nodes) { + if (pr.mergeCommit?.oid) { + mergeCommitCount[pr.mergeCommit.oid] ??= 0; + mergeCommitCount[pr.mergeCommit.oid]++; + } + } + } const commitData: Commit[] = []; for (const graphCommit of commits) { const commit: Commit = { sha: graphCommit.sha, message: graphCommit.message, }; - const pullRequest = graphCommit.associatedPullRequests.nodes.find(pr => { - return pr.mergeCommit && pr.mergeCommit.oid === graphCommit.sha; - }); + const mergePullRequest = graphCommit.associatedPullRequests.nodes.find( + pr => { + return ( + // Only match the pull request with a merge commit if there is a + // single merged commit in the PR. This means merge commits and squash + // merges will be matched, but rebase merged PRs will only be matched + // if they contain a single commit. This is so PRs that are rebased + // and merged will have ßSfiles backfilled from each commit instead of + // the whole PR. + pr.mergeCommit && + pr.mergeCommit.oid === graphCommit.sha && + mergeCommitCount[pr.mergeCommit.oid] === 1 + ); + } + ); + const pullRequest = + mergePullRequest || graphCommit.associatedPullRequests.nodes[0]; if (pullRequest) { - const files = (pullRequest.files?.nodes || []).map(node => node.path); commit.pullRequest = { sha: commit.sha, number: pullRequest.number, @@ -493,17 +513,24 @@ export class GitHub { title: pullRequest.title, body: pullRequest.body, labels: pullRequest.labels.nodes.map(node => node.name), - files, + files: (pullRequest.files?.nodes || []).map(node => node.path), }; - if (pullRequest.files?.pageInfo?.hasNextPage && options.backfillFiles) { + } + if (mergePullRequest) { + if ( + mergePullRequest.files?.pageInfo?.hasNextPage && + options.backfillFiles + ) { this.logger.info( - `PR #${pullRequest.number} has many files, backfilling` + `PR #${mergePullRequest.number} has many files, backfilling` ); commit.files = await this.getCommitFiles(graphCommit.sha); } else { // We cannot directly fetch files on commits via graphql, only provide file // information for commits with associated pull requests - commit.files = files; + commit.files = (mergePullRequest.files?.nodes || []).map( + node => node.path + ); } } else if (options.backfillFiles) { // In this case, there is no squashed merge commit. This could be a simple @@ -531,14 +558,16 @@ export class GitHub { this.logger.debug(`Backfilling file list for commit: ${sha}`); const files: string[] = []; for await (const resp of this.octokit.paginate.iterator( - this.octokit.repos.getCommit, + 'GET /repos/{owner}/{repo}/commits/{ref}', { owner: this.repository.owner, repo: this.repository.repo, ref: sha, } )) { - for (const f of resp.data.files || []) { + // Paginate plugin doesn't have types for listing files on a commit + const data = resp.data as any as {files: {filename: string}[]}; + for (const f of data.files || []) { if (f.filename) { files.push(f.filename); } @@ -675,7 +704,7 @@ export class GitHub { }; let results = 0; for await (const {data: pulls} of this.octokit.paginate.iterator( - this.octokit.rest.pulls.list, + 'GET /repos/{owner}/{repo}/pulls', { state: statusMap[status], owner: this.repository.owner, @@ -900,7 +929,7 @@ export class GitHub { const maxResults = options.maxResults || Number.MAX_SAFE_INTEGER; let results = 0; for await (const response of this.octokit.paginate.iterator( - this.octokit.rest.repos.listTags, + 'GET /repos/{owner}/{repo}/tags', { owner: this.repository.owner, repo: this.repository.repo, @@ -1401,7 +1430,7 @@ export class GitHub { commentOnIssue = wrapAsync( async (comment: string, number: number): Promise => { this.logger.debug( - `adding comment to https://github.com/${this.repository.owner}/${this.repository.repo}/issue/${number}` + `adding comment to https://github.com/${this.repository.owner}/${this.repository.repo}/issues/${number}` ); const resp = await this.octokit.issues.createComment({ owner: this.repository.owner, diff --git a/src/index.ts b/src/index.ts index 1f17ce93f..7e9226a48 100644 --- a/src/index.ts +++ b/src/index.ts @@ -18,8 +18,13 @@ export { ReleaserConfig, ManifestOptions, PluginType, + CandidateRelease, + CreatedRelease, } from './manifest'; +export {ReleasePullRequest} from './release-pull-request'; +export {PullRequest} from './pull-request'; export {Commit, ConventionalCommit} from './commit'; +export {Strategy} from './strategy'; export {BaseStrategyOptions, BuildUpdatesOptions} from './strategies/base'; export { ReleaseBuilder, @@ -56,3 +61,7 @@ export {Logger, setLogger} from './util/logger'; export {GitHub} from './github'; export const configSchema = require('../../schemas/config.json'); export const manifestSchema = require('../../schemas/manifest.json'); + +// x-release-please-start-version +export const VERSION = '16.8.0'; +// x-release-please-end diff --git a/src/manifest.ts b/src/manifest.ts index 21bb69935..b750cbf12 100644 --- a/src/manifest.ts +++ b/src/manifest.ts @@ -15,7 +15,7 @@ import {ChangelogSection} from './changelog-notes'; import {GitHub, GitHubRelease, GitHubTag} from './github'; import {Version, VersionsMap} from './version'; -import {Commit} from './commit'; +import {Commit, parseConventionalCommits} from './commit'; import {PullRequest} from './pull-request'; import {logger as defaultLogger, Logger} from './util/logger'; import {CommitSplit} from './util/commit-split'; @@ -33,7 +33,7 @@ import { } from './factory'; import {Release} from './release'; import {Strategy} from './strategy'; -import {Merge} from './plugins/merge'; +import {MergeOptions, Merge} from './plugins/merge'; import {ReleasePleaseManifest} from './updaters/release-please-manifest'; import { DuplicateReleaseError, @@ -46,6 +46,7 @@ import { FilePullRequestOverflowHandler, } from './util/pull-request-overflow-handler'; import {signoffCommitMessage} from './util/signoff-commit-message'; +import {CommitExclude} from './util/commit-exclude'; type ExtraJsonFile = { type: 'json'; @@ -70,12 +71,19 @@ type ExtraPomFile = { path: string; glob?: boolean; }; +type ExtraTomlFile = { + type: 'toml'; + path: string; + jsonpath: string; + glob?: boolean; +}; export type ExtraFile = | string | ExtraJsonFile | ExtraYamlFile | ExtraXmlFile - | ExtraPomFile; + | ExtraPomFile + | ExtraTomlFile; /** * These are configurations provided to each strategy per-path. */ @@ -86,6 +94,7 @@ export interface ReleaserConfig { versioning?: VersioningStrategyType; bumpMinorPreMajor?: boolean; bumpPatchForMinorPreMajor?: boolean; + prereleaseType?: string; // Strategy options releaseAs?: string; @@ -99,6 +108,7 @@ export interface ReleaserConfig { includeVInTag?: boolean; pullRequestTitlePattern?: string; pullRequestHeader?: string; + pullRequestFooter?: string; tagSeparator?: string; separatePullRequests?: boolean; labels?: string[]; @@ -118,6 +128,8 @@ export interface ReleaserConfig { extraFiles?: ExtraFile[]; snapshotLabels?: string[]; skipSnapshot?: boolean; + // Manifest only + excludePaths?: string[]; } export interface CandidateReleasePullRequest { @@ -138,6 +150,7 @@ interface ReleaserConfigJson { versioning?: VersioningStrategyType; 'bump-minor-pre-major'?: boolean; 'bump-patch-for-minor-pre-major'?: boolean; + 'prerelease-type'?: string; 'changelog-sections'?: ChangelogSection[]; 'release-as'?: string; 'skip-github-release'?: boolean; @@ -153,6 +166,7 @@ interface ReleaserConfigJson { 'changelog-host'?: string; 'pull-request-title-pattern'?: string; 'pull-request-header'?: string; + 'pull-request-footer'?: string; 'separate-pull-requests'?: boolean; 'tag-separator'?: string; 'extra-files'?: ExtraFile[]; @@ -160,6 +174,7 @@ interface ReleaserConfigJson { 'snapshot-label'?: string; // Java-only 'skip-snapshot'?: boolean; // Java-only 'initial-version'?: string; + 'exclude-paths'?: string[]; // manifest-only } export interface ManifestOptions { @@ -208,6 +223,9 @@ export interface WorkspacePluginConfig extends ConfigurablePluginType { merge?: boolean; considerAllArtifacts?: boolean; } +export interface NodeWorkspacePluginConfig extends WorkspacePluginConfig { + updatePeerDependencies?: boolean; +} export interface GroupPriorityPluginConfig extends ConfigurablePluginType { groups: string[]; } @@ -217,7 +235,8 @@ export type PluginType = | GroupPriorityPluginConfig | LinkedVersionPluginConfig | SentenceCasePluginConfig - | WorkspacePluginConfig; + | WorkspacePluginConfig + | NodeWorkspacePluginConfig; /** * This is the schema of the manifest config json @@ -251,7 +270,7 @@ const DEFAULT_COMMIT_SEARCH_DEPTH = 500; export const MANIFEST_PULL_REQUEST_TITLE_PATTERN = 'chore: release ${branch}'; -interface CreatedRelease extends GitHubRelease { +export interface CreatedRelease extends GitHubRelease { id: number; path: string; version: string; @@ -302,6 +321,8 @@ export class Manifest { * as the point to consider commits after * @param {boolean} manifestOptions.alwaysLinkLocal Option for the node-workspace * plugin + * @param {boolean} manifestOptions.updatePeerDependencies Option for the node-workspace + * plugin * @param {boolean} manifestOptions.separatePullRequests If true, create separate pull * requests instead of a single manifest release pull request * @param {PluginType[]} manifestOptions.plugins Any plugins to use for this repository @@ -417,6 +438,8 @@ export class Manifest { * as the point to consider commits after * @param {boolean} manifestOptions.alwaysLinkLocal Option for the node-workspace * plugin + * @param {boolean} manifestOptions.updatePeerDependencies Option for the node-workspace + * plugin * @param {boolean} manifestOptions.separatePullRequests If true, create separate pull * requests instead of a single manifest release pull request * @param {PluginType[]} manifestOptions.plugins Any plugins to use for this repository @@ -533,7 +556,6 @@ export class Manifest { } } - const needsBootstrap = releasesFound < expectedReleases; if (releasesFound < expectedReleases) { this.logger.warn( `Expected ${expectedReleases} releases, only found ${releasesFound}` @@ -553,6 +575,9 @@ export class Manifest { releasesFound++; } } + + const needsBootstrap = releasesFound < expectedReleases; + if (releasesFound < expectedReleases) { this.logger.warn( `Expected ${expectedReleases} releases, only found ${releasesFound}` @@ -631,13 +656,15 @@ export class Manifest { const splitCommits = cs.split(commits); // limit paths to ones since the last release - const commitsPerPath: Record = {}; + let commitsPerPath: Record = {}; for (const path in this.repositoryConfig) { commitsPerPath[path] = commitsAfterSha( path === ROOT_PROJECT_PATH ? commits : splitCommits[path], releaseShasByPath[path] ); } + const commitExclude = new CommitExclude(this.repositoryConfig); + commitsPerPath = commitExclude.excludeCommits(commitsPerPath); // backfill latest release tags from manifest for (const path in this.repositoryConfig) { @@ -678,7 +705,10 @@ export class Manifest { ); this.logger.debug(`type: ${config.releaseType}`); this.logger.debug(`targetBranch: ${this.targetBranch}`); - let pathCommits = commitsPerPath[path]; + let pathCommits = parseConventionalCommits( + commitsPerPath[path], + this.logger + ); // The processCommits hook can be implemented by plugins to // post-process commits. This can be used to perform cleanup, e.g,, sentence // casing all commit messages: @@ -728,12 +758,32 @@ export class Manifest { // Combine pull requests into 1 unless configured for separate // pull requests if (!this.separatePullRequests) { + const mergeOptions: MergeOptions = { + pullRequestTitlePattern: this.groupPullRequestTitlePattern, + }; + // Find the first repositoryConfig item that has a set value + // for the options that can be passed to the merge plugin + for (const path in this.repositoryConfig) { + const config = this.repositoryConfig[path]; + if ( + 'pullRequestHeader' in config && + !('pullRequestHeader' in mergeOptions) + ) { + mergeOptions.pullRequestHeader = config.pullRequestHeader; + } + if ( + 'pullRequestFooter' in config && + !('pullRequestFooter' in mergeOptions) + ) { + mergeOptions.pullRequestFooter = config.pullRequestFooter; + } + } this.plugins.push( new Merge( this.github, this.targetBranch, this.repositoryConfig, - this.groupPullRequestTitlePattern + mergeOptions ) ); } @@ -786,6 +836,34 @@ export class Manifest { sha: foundTag.sha, notes: '', }; + } else { + if ( + strategiesByPath[ROOT_PROJECT_PATH] && + this.repositoryConfig[path].skipGithubRelease + ) { + this.logger.debug('could not find release, checking root package'); + const rootComponent = await strategiesByPath[ + ROOT_PROJECT_PATH + ].getComponent(); + const rootTag = new TagName( + expectedVersion, + rootComponent, + this.repositoryConfig[ROOT_PROJECT_PATH].tagSeparator, + this.repositoryConfig[ROOT_PROJECT_PATH].includeVInTag + ); + const foundTag = allTags[rootTag.toString()]; + if (foundTag) { + this.logger.debug( + `found rootTag: ${foundTag.name} ${foundTag.sha}` + ); + releasesByPath[path] = { + name: foundTag.name, + tag: rootTag, + sha: foundTag.sha, + notes: '', + }; + } + } } } return releasesByPath; @@ -1061,7 +1139,7 @@ export class Manifest { // Find merged release pull requests const generator = await this.findMergedReleasePullRequests(); - const releases: CandidateRelease[] = []; + const candidateReleases: CandidateRelease[] = []; for await (const pullRequest of generator) { for (const path in this.repositoryConfig) { const config = this.repositoryConfig[path]; @@ -1069,9 +1147,11 @@ export class Manifest { this.logger.debug(`type: ${config.releaseType}`); this.logger.debug(`targetBranch: ${this.targetBranch}`); const strategy = strategiesByPath[path]; - const release = await strategy.buildRelease(pullRequest); - if (release) { - releases.push({ + const releases = await strategy.buildReleases(pullRequest, { + groupPullRequestTitlePattern: this.groupPullRequestTitlePattern, + }); + for (const release of releases) { + candidateReleases.push({ ...release, path, pullRequest, @@ -1081,13 +1161,11 @@ export class Manifest { (!!release.tag.version.preRelease || release.tag.version.major === 0), }); - } else { - this.logger.info(`No release necessary for path: ${path}`); } } } - return releases; + return candidateReleases; } /** @@ -1116,7 +1194,7 @@ export class Manifest { releasesByPullRequest[pullNumber], pullRequestsByNumber[pullNumber] ); - resultReleases.concat(releases); + resultReleases.push(...releases); } return resultReleases; } else { @@ -1163,10 +1241,11 @@ export class Manifest { ) { // we've either tagged all releases or they were duplicates: // adjust tags on pullRequest - await Promise.all([ - this.github.removeIssueLabels(this.labels, pullRequest.number), - this.github.addIssueLabels(this.releaseLabels, pullRequest.number), - ]); + await this.github.removeIssueLabels(this.labels, pullRequest.number); + await this.github.addIssueLabels( + this.releaseLabels, + pullRequest.number + ); } if (githubReleases.length === 0) { // If all releases were duplicate, throw a duplicate error @@ -1174,10 +1253,8 @@ export class Manifest { } } else { // adjust tags on pullRequest - await Promise.all([ - this.github.removeIssueLabels(this.labels, pullRequest.number), - this.github.addIssueLabels(this.releaseLabels, pullRequest.number), - ]); + await this.github.removeIssueLabels(this.labels, pullRequest.number); + await this.github.addIssueLabels(this.releaseLabels, pullRequest.number); } return githubReleases; @@ -1257,6 +1334,7 @@ function extractReleaserConfig( releaseType: config['release-type'], bumpMinorPreMajor: config['bump-minor-pre-major'], bumpPatchForMinorPreMajor: config['bump-patch-for-minor-pre-major'], + prereleaseType: config['prerelease-type'], versioning: config['versioning'], changelogSections: config['changelog-sections'], changelogPath: config['changelog-path'], @@ -1275,6 +1353,7 @@ function extractReleaserConfig( changelogType: config['changelog-type'], pullRequestTitlePattern: config['pull-request-title-pattern'], pullRequestHeader: config['pull-request-header'], + pullRequestFooter: config['pull-request-footer'], tagSeparator: config['tag-separator'], separatePullRequests: config['separate-pull-requests'], labels: config['label']?.split(','), @@ -1282,6 +1361,7 @@ function extractReleaserConfig( extraLabels: config['extra-label']?.split(','), skipSnapshot: config['skip-snapshot'], initialVersion: config['initial-version'], + excludePaths: config['exclude-paths'], }; } @@ -1481,6 +1561,9 @@ async function latestReleaseVersion( commitShas.add(commitWithPullRequest.sha); const mergedPullRequest = commitWithPullRequest.pullRequest; if (!mergedPullRequest) { + logger.trace( + `skipping commit: ${commitWithPullRequest.sha} missing merged pull request` + ); continue; } @@ -1489,12 +1572,20 @@ async function latestReleaseVersion( logger ); if (!branchName) { + logger.trace( + `skipping commit: ${commitWithPullRequest.sha} unrecognized branch name: ${mergedPullRequest.headBranchName}` + ); continue; } // If branchPrefix is specified, ensure it is found in the branch name. // If branchPrefix is not specified, component should also be undefined. if (branchName.getComponent() !== branchPrefix) { + logger.trace( + `skipping commit: ${ + commitWithPullRequest.sha + } branch component ${branchName.getComponent()} doesn't match expected prefix: ${branchPrefix}` + ); continue; } @@ -1504,6 +1595,9 @@ async function latestReleaseVersion( logger ); if (!pullRequestTitle) { + logger.trace( + `skipping commit: ${commitWithPullRequest.sha} couldn't parse pull request title: ${mergedPullRequest.title}` + ); continue; } @@ -1587,6 +1681,7 @@ function mergeReleaserConfig( bumpPatchForMinorPreMajor: pathConfig.bumpPatchForMinorPreMajor ?? defaultConfig.bumpPatchForMinorPreMajor, + prereleaseType: pathConfig.prereleaseType ?? defaultConfig.prereleaseType, versioning: pathConfig.versioning ?? defaultConfig.versioning, changelogSections: pathConfig.changelogSections ?? defaultConfig.changelogSections, @@ -1611,11 +1706,14 @@ function mergeReleaserConfig( defaultConfig.pullRequestTitlePattern, pullRequestHeader: pathConfig.pullRequestHeader ?? defaultConfig.pullRequestHeader, + pullRequestFooter: + pathConfig.pullRequestFooter ?? defaultConfig.pullRequestFooter, separatePullRequests: pathConfig.separatePullRequests ?? defaultConfig.separatePullRequests, skipSnapshot: pathConfig.skipSnapshot ?? defaultConfig.skipSnapshot, initialVersion: pathConfig.initialVersion ?? defaultConfig.initialVersion, extraLabels: pathConfig.extraLabels ?? defaultConfig.extraLabels, + excludePaths: pathConfig.excludePaths ?? defaultConfig.excludePaths, }; } diff --git a/src/plugin.ts b/src/plugin.ts index dd9276cf5..f7973626f 100644 --- a/src/plugin.ts +++ b/src/plugin.ts @@ -15,7 +15,7 @@ import {GitHub} from './github'; import {CandidateReleasePullRequest, RepositoryConfig} from './manifest'; import {Strategy} from './strategy'; -import {Commit} from './commit'; +import {Commit, ConventionalCommit} from './commit'; import {Release} from './release'; import {logger as defaultLogger, Logger} from './util/logger'; @@ -47,9 +47,7 @@ export abstract class ManifestPlugin { * @param {Commit[]} commits The set of commits that will feed into release pull request. * @returns {Commit[]} The modified commit objects. */ - // TODO: for next major version, let's run the default conventional commit parser earlier - // (outside of the strategy classes) and pass in the ConventionalCommit[] objects in. - processCommits(commits: Commit[]): Commit[] { + processCommits(commits: ConventionalCommit[]): ConventionalCommit[] { return commits; } diff --git a/src/plugins/cargo-workspace.ts b/src/plugins/cargo-workspace.ts index a324f9702..aa3f65784 100644 --- a/src/plugins/cargo-workspace.ts +++ b/src/plugins/cargo-workspace.ts @@ -37,6 +37,7 @@ import {PullRequestBody} from '../util/pull-request-body'; import {BranchName} from '../util/branch-name'; import {PatchVersionUpdate} from '../versioning-strategy'; import {CargoLock} from '../updaters/rust/cargo-lock'; +import {ConfigurationError} from '../errors'; interface CrateInfo { /** @@ -100,8 +101,16 @@ export class CargoWorkspace extends WorkspacePlugin { const allCrates: CrateInfo[] = []; const candidatesByPackage: Record = {}; - const members = cargoManifest.workspace.members; + + const members = ( + await Promise.all( + cargoManifest.workspace.members.map(member => + this.github.findFilesByGlobAndRef(member, this.targetBranch) + ) + ) + ).flat(); members.push(ROOT_PROJECT_PATH); + for (const path of members) { const manifestPath = addPath(path, 'Cargo.toml'); this.logger.info(`looking for candidate with path: ${path}`); @@ -129,8 +138,16 @@ export class CargoWorkspace extends WorkspacePlugin { const version = manifest.package?.version; if (!version) { - throw new Error( - `package manifest at ${manifestPath} is missing [package.version]` + throw new ConfigurationError( + `package manifest at ${manifestPath} is missing [package.version]`, + 'cargo-workspace', + `${this.github.repository.owner}/${this.github.repository.repo}` + ); + } else if (typeof version !== 'string') { + throw new ConfigurationError( + `package manifest at ${manifestPath} has an invalid [package.version]`, + 'cargo-workspace', + `${this.github.repository.owner}/${this.github.repository.repo}` ); } allCrates.push({ @@ -216,10 +233,10 @@ export class CargoWorkspace extends WorkspacePlugin { return existingCandidate; } - protected newCandidate( + protected async newCandidate( pkg: CrateInfo, updatedVersions: VersionsMap - ): CandidateReleasePullRequest { + ): Promise { const version = updatedVersions.get(pkg.name); if (!version) { throw new Error(`Didn't find updated version for ${pkg.name}`); diff --git a/src/plugins/linked-versions.ts b/src/plugins/linked-versions.ts index f13732df1..f3d059bf7 100644 --- a/src/plugins/linked-versions.ts +++ b/src/plugins/linked-versions.ts @@ -17,11 +17,12 @@ import {RepositoryConfig, CandidateReleasePullRequest} from '../manifest'; import {GitHub} from '../github'; import {Logger} from '../util/logger'; import {Strategy} from '../strategy'; -import {Commit} from '../commit'; +import {Commit, parseConventionalCommits} from '../commit'; import {Release} from '../release'; import {Version} from '../version'; import {buildStrategy} from '../factory'; import {Merge} from './merge'; +import {BranchName} from '../util/branch-name'; interface LinkedVersionsPluginOptions { merge?: boolean; @@ -87,7 +88,7 @@ export class LinkedVersions extends ManifestPlugin { const strategy = groupStrategies[path]; const latestRelease = releasesByPath[path]; const releasePullRequest = await strategy.buildReleasePullRequest( - commitsByPath[path], + parseConventionalCommits(commitsByPath[path], this.logger), latestRelease ); if (releasePullRequest?.version) { @@ -154,6 +155,7 @@ export class LinkedVersions extends ManifestPlugin { (collection, candidate) => { if (!candidate.pullRequest.version) { this.logger.warn('pull request missing version', candidate); + collection[1].push(candidate); return collection; } if (this.components.has(candidate.config.component || '')) { @@ -165,6 +167,9 @@ export class LinkedVersions extends ManifestPlugin { }, [[], []] as CandidateReleasePullRequest[][] ); + this.logger.info( + `found ${inScopeCandidates.length} linked-versions candidates` + ); // delegate to the merge plugin and add merged pull request if (inScopeCandidates.length > 0) { @@ -172,7 +177,14 @@ export class LinkedVersions extends ManifestPlugin { this.github, this.targetBranch, this.repositoryConfig, - `chore\${branch}: release ${this.groupName} libraries` + { + pullRequestTitlePattern: `chore\${scope}: release ${this.groupName} libraries`, + forceMerge: true, + headBranchName: BranchName.ofGroupTargetBranch( + this.groupName, + this.targetBranch + ).toString(), + } ); const merged = await merge.run(inScopeCandidates); outOfScopeCandidates.push(...merged); diff --git a/src/plugins/maven-workspace.ts b/src/plugins/maven-workspace.ts index 76486a7d0..0586ec2d6 100644 --- a/src/plugins/maven-workspace.ts +++ b/src/plugins/maven-workspace.ts @@ -58,7 +58,13 @@ interface MavenWorkspacePluginOptions extends WorkspacePluginOptions { considerAllArtifacts?: boolean; } -const JAVA_RELEASE_TYPES = new Set(['java', 'java-bom', 'java-yoshi', 'maven']); +const JAVA_RELEASE_TYPES = new Set([ + 'java', + 'java-bom', + 'java-yoshi', + 'java-yoshi-mono-repo', + 'maven', +]); const XPATH_PROJECT_GROUP = '/*[local-name()="project"]/*[local-name()="groupId"]'; const XPATH_PROJECT_ARTIFACT = @@ -388,10 +394,10 @@ export class MavenWorkspace extends WorkspacePlugin { } return existingCandidate; } - protected newCandidate( + protected async newCandidate( artifact: MavenArtifact, updatedVersions: VersionsMap - ): CandidateReleasePullRequest { + ): Promise { const version = updatedVersions.get(artifact.name); if (!version) { throw new Error(`Didn't find updated version for ${artifact.name}`); diff --git a/src/plugins/merge.ts b/src/plugins/merge.ts index f961ee2bc..493e02626 100644 --- a/src/plugins/merge.ts +++ b/src/plugins/merge.ts @@ -26,6 +26,14 @@ import {Update} from '../update'; import {mergeUpdates} from '../updaters/composite'; import {GitHub} from '../github'; +export interface MergeOptions { + pullRequestTitlePattern?: string; + pullRequestHeader?: string; + pullRequestFooter?: string; + headBranchName?: string; + forceMerge?: boolean; +} + /** * This plugin merges multiple pull requests into a single * release pull request. @@ -35,18 +43,23 @@ import {GitHub} from '../github'; export class Merge extends ManifestPlugin { private pullRequestTitlePattern?: string; private pullRequestHeader?: string; + private pullRequestFooter?: string; + private headBranchName?: string; + private forceMerge: boolean; constructor( github: GitHub, targetBranch: string, repositoryConfig: RepositoryConfig, - pullRequestTitlePattern?: string, - pullRequestHeader?: string + options: MergeOptions = {} ) { super(github, targetBranch, repositoryConfig); this.pullRequestTitlePattern = - pullRequestTitlePattern || MANIFEST_PULL_REQUEST_TITLE_PATTERN; - this.pullRequestHeader = pullRequestHeader; + options.pullRequestTitlePattern ?? MANIFEST_PULL_REQUEST_TITLE_PATTERN; + this.pullRequestHeader = options.pullRequestHeader; + this.pullRequestFooter = options.pullRequestFooter; + this.headBranchName = options.headBranchName; + this.forceMerge = options.forceMerge ?? false; } async run( @@ -61,7 +74,7 @@ export class Merge extends ManifestPlugin { Array> >( (collection, candidate) => { - if (candidate.config.separatePullRequests) { + if (candidate.config.separatePullRequests && !this.forceMerge) { collection[1].push(candidate); } else { collection[0].push(candidate); @@ -98,10 +111,13 @@ export class Merge extends ManifestPlugin { body: new PullRequestBody(releaseData, { useComponents: true, header: this.pullRequestHeader, + footer: this.pullRequestFooter, }), updates, labels: Array.from(labels), - headRefName: BranchName.ofTargetBranch(this.targetBranch).toString(), + headRefName: + this.headBranchName ?? + BranchName.ofTargetBranch(this.targetBranch).toString(), draft: !candidates.some(candidate => !candidate.pullRequest.draft), }; diff --git a/src/plugins/node-workspace.ts b/src/plugins/node-workspace.ts index 6b3b416df..1d309ebd9 100644 --- a/src/plugins/node-workspace.ts +++ b/src/plugins/node-workspace.ts @@ -12,20 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -import {PackageGraph} from '@lerna/package-graph'; -import { - Package as LernaPackage, - RawManifest as PackageJson, -} from '@lerna/package'; import {GitHub} from '../github'; import {CandidateReleasePullRequest, RepositoryConfig} from '../manifest'; +import {PackageLockJson} from '../updaters/node/package-lock-json'; import {Version, VersionsMap} from '../version'; -import {RawContent} from '../updaters/raw-content'; import {PullRequestTitle} from '../util/pull-request-title'; import {PullRequestBody} from '../util/pull-request-body'; import {ReleasePullRequest} from '../release-pull-request'; import {BranchName} from '../util/branch-name'; -import {jsonStringify} from '../util/json-stringify'; import {Changelog} from '../updaters/changelog'; import { WorkspacePlugin, @@ -36,23 +30,36 @@ import { addPath, } from './workspace'; import {PatchVersionUpdate} from '../versioning-strategy'; +import {Strategy} from '../strategy'; +import {Commit} from '../commit'; +import {Release} from '../release'; +import {CompositeUpdater} from '../updaters/composite'; +import {PackageJson, newVersionWithRange} from '../updaters/node/package-json'; +import {Logger} from '../util/logger'; -class Package extends LernaPackage { - constructor( - public readonly rawContent: string, - location: string, - pkg?: PackageJson - ) { - super(pkg ?? JSON.parse(rawContent), location); - } +interface ParsedPackageJson { + name: string; + version: string; + dependencies?: Record; + devDependencies?: Record; + peerDependencies?: Record; + optionalDependencies?: Record; +} - clone() { - return new Package(this.rawContent, this.location, this.toJSON()); - } +interface Package { + path: string; + name: string; + version: string; + dependencies: Record; + devDependencies: Record; + peerDependencies: Record; + optionalDependencies: Record; + jsonContent: string; } interface NodeWorkspaceOptions extends WorkspacePluginOptions { alwaysLinkLocal?: boolean; + updatePeerDependencies?: boolean; } /** @@ -64,7 +71,11 @@ interface NodeWorkspaceOptions extends WorkspacePluginOptions { */ export class NodeWorkspace extends WorkspacePlugin { private alwaysLinkLocal: boolean; - private packageGraph?: PackageGraph; + + private strategiesByPath: Record = {}; + private releasesByPath: Record = {}; + + readonly updatePeerDependencies: boolean; constructor( github: GitHub, targetBranch: string, @@ -72,7 +83,9 @@ export class NodeWorkspace extends WorkspacePlugin { options: NodeWorkspaceOptions = {} ) { super(github, targetBranch, repositoryConfig, options); + this.alwaysLinkLocal = options.alwaysLinkLocal === false ? false : true; + this.updatePeerDependencies = options.updatePeerDependencies === true; } protected async buildAllPackages( candidates: CandidateReleasePullRequest[] @@ -101,22 +114,28 @@ export class NodeWorkspace extends WorkspacePlugin { const packageUpdate = candidate.pullRequest.updates.find( update => update.path === packagePath ); - if (packageUpdate?.cachedFileContents) { - const pkg = new Package( - packageUpdate.cachedFileContents.parsedContent, - candidate.path - ); - packagesByPath.set(candidate.path, pkg); - candidatesByPackage[pkg.name] = candidate; - } else { - const contents = await this.github.getFileContentsOnBranch( + const contents = + packageUpdate?.cachedFileContents ?? + (await this.github.getFileContentsOnBranch( packagePath, this.targetBranch - ); - const pkg = new Package(contents.parsedContent, candidate.path); - packagesByPath.set(candidate.path, pkg); - candidatesByPackage[pkg.name] = candidate; - } + )); + const packageJson: ParsedPackageJson = JSON.parse( + contents.parsedContent + ); + const pkg: Package = { + name: packageJson.name, + path, + version: packageJson.version, + dependencies: packageJson.dependencies || {}, + devDependencies: packageJson.devDependencies || {}, + peerDependencies: packageJson.peerDependencies || {}, + optionalDependencies: packageJson.optionalDependencies || {}, + jsonContent: contents.parsedContent, + }; + packagesByPath.set(candidate.path, pkg); + candidatesByPackage[pkg.name] = candidate; + // } } else { const packagePath = addPath(path, 'package.json'); this.logger.debug( @@ -126,16 +145,23 @@ export class NodeWorkspace extends WorkspacePlugin { packagePath, this.targetBranch ); - packagesByPath.set(path, new Package(contents.parsedContent, path)); + const packageJson: ParsedPackageJson = JSON.parse( + contents.parsedContent + ); + const pkg: Package = { + name: packageJson.name, + path, + version: packageJson.version, + dependencies: packageJson.dependencies || {}, + devDependencies: packageJson.devDependencies || {}, + peerDependencies: packageJson.peerDependencies || {}, + optionalDependencies: packageJson.optionalDependencies || {}, + jsonContent: contents.parsedContent, + }; + packagesByPath.set(path, pkg); } } const allPackages = Array.from(packagesByPath.values()); - this.packageGraph = new PackageGraph( - allPackages, - 'allDependencies', - this.alwaysLinkLocal - ); - return { allPackages, candidatesByPackage, @@ -152,42 +178,38 @@ export class NodeWorkspace extends WorkspacePlugin { pkg: Package, updatedVersions: VersionsMap ): CandidateReleasePullRequest { - const graphPackage = this.packageGraph?.get(pkg.name); - if (!graphPackage) { - throw new Error(`Could not find graph package for ${pkg.name}`); - } - const updatedPackage = pkg.clone(); // Update version of the package - const newVersion = updatedVersions.get(updatedPackage.name); - if (newVersion) { - this.logger.info(`Updating ${updatedPackage.name} to ${newVersion}`); - updatedPackage.version = newVersion.toString(); - } - // Update dependency versions - for (const [depName, resolved] of graphPackage.localDependencies) { - const depVersion = updatedVersions.get(depName); - if (depVersion && resolved.type !== 'directory') { - const currentVersion = this.combineDeps(pkg)?.[depName]; - const prefix = currentVersion - ? this.detectRangePrefix(currentVersion) - : ''; - updatedPackage.updateLocalDependency( - resolved, - depVersion.toString(), - prefix - ); - this.logger.info( - `${pkg.name}.${depName} updated to ${prefix}${depVersion.toString()}` - ); - } + const newVersion = updatedVersions.get(pkg.name); + if (!newVersion) { + throw new Error(`Didn't find updated version for ${pkg.name}`); } - const dependencyNotes = getChangelogDepsNotes(pkg, updatedPackage); + const updatedPackage = { + ...pkg, + version: newVersion.toString(), + }; + + const updater = new PackageJson({ + version: newVersion, + versionsMap: updatedVersions, + }); + const dependencyNotes = getChangelogDepsNotes( + pkg, + updatedPackage, + updatedVersions, + this.logger + ); + existingCandidate.pullRequest.updates = existingCandidate.pullRequest.updates.map(update => { if (update.path === addPath(existingCandidate.path, 'package.json')) { - update.updater = new RawContent( - jsonStringify(updatedPackage.toJSON(), updatedPackage.rawContent) - ); + update.updater = new CompositeUpdater(update.updater, updater); + } else if ( + update.path === addPath(existingCandidate.path, 'package-lock.json') + ) { + update.updater = new PackageLockJson({ + version: newVersion, + versionsMap: updatedVersions, + }); } else if (update.updater instanceof Changelog) { if (dependencyNotes) { update.updater.changelogEntry = @@ -224,47 +246,56 @@ export class NodeWorkspace extends WorkspacePlugin { } return existingCandidate; } - protected newCandidate( + protected async newCandidate( pkg: Package, updatedVersions: VersionsMap - ): CandidateReleasePullRequest { - const graphPackage = this.packageGraph?.get(pkg.name); - if (!graphPackage) { - throw new Error(`Could not find graph package for ${pkg.name}`); - } - const updatedPackage = pkg.clone(); + ): Promise { // Update version of the package - const newVersion = updatedVersions.get(updatedPackage.name); - if (newVersion) { - this.logger.info(`Updating ${updatedPackage.name} to ${newVersion}`); - updatedPackage.version = newVersion.toString(); + const newVersion = updatedVersions.get(pkg.name); + if (!newVersion) { + throw new Error(`Didn't find updated version for ${pkg.name}`); } - for (const [depName, resolved] of graphPackage.localDependencies) { - const depVersion = updatedVersions.get(depName); - if (depVersion && resolved.type !== 'directory') { - const currentVersion = this.combineDeps(pkg)?.[depName]; - const prefix = currentVersion - ? this.detectRangePrefix(currentVersion) - : ''; - updatedPackage.updateLocalDependency( - resolved, - depVersion.toString(), - prefix - ); - this.logger.info( - `${pkg.name}.${depName} updated to ${prefix}${depVersion.toString()}` - ); - } + const updatedPackage = { + ...pkg, + version: newVersion.toString(), + }; + + const dependencyNotes = getChangelogDepsNotes( + pkg, + updatedPackage, + updatedVersions, + this.logger + ); + + const strategy = this.strategiesByPath[updatedPackage.path]; + const latestRelease = this.releasesByPath[updatedPackage.path]; + + const basePullRequest = strategy + ? await strategy.buildReleasePullRequest([], latestRelease, false, [], { + newVersion, + }) + : undefined; + + if (basePullRequest) { + return this.updateCandidate( + { + path: pkg.path, + pullRequest: basePullRequest, + config: { + releaseType: 'node', + }, + }, + pkg, + updatedVersions + ); } - const dependencyNotes = getChangelogDepsNotes(pkg, updatedPackage); - const packageJson = updatedPackage.toJSON() as PackageJson; - const version = Version.parse(packageJson.version); + const pullRequest: ReleasePullRequest = { title: PullRequestTitle.ofTargetBranch(this.targetBranch), body: new PullRequestBody([ { component: updatedPackage.name, - version, + version: newVersion, notes: appendDependenciesSectionToChangelog( '', dependencyNotes, @@ -274,17 +305,26 @@ export class NodeWorkspace extends WorkspacePlugin { ]), updates: [ { - path: addPath(updatedPackage.location, 'package.json'), + path: addPath(updatedPackage.path, 'package.json'), createIfMissing: false, - updater: new RawContent( - jsonStringify(packageJson, updatedPackage.rawContent) - ), + updater: new PackageJson({ + version: newVersion, + versionsMap: updatedVersions, + }), + }, + { + path: addPath(updatedPackage.path, 'package-lock.json'), + createIfMissing: false, + updater: new PackageJson({ + version: newVersion, + versionsMap: updatedVersions, + }), }, { - path: addPath(updatedPackage.location, 'CHANGELOG.md'), + path: addPath(updatedPackage.path, 'CHANGELOG.md'), createIfMissing: false, updater: new Changelog({ - version, + version: newVersion, changelogEntry: appendDependenciesSectionToChangelog( '', dependencyNotes, @@ -295,11 +335,11 @@ export class NodeWorkspace extends WorkspacePlugin { ], labels: [], headRefName: BranchName.ofTargetBranch(this.targetBranch).toString(), - version, + version: newVersion, draft: false, }; return { - path: updatedPackage.location, + path: updatedPackage.path, pullRequest, config: { releaseType: 'node', @@ -311,7 +351,39 @@ export class NodeWorkspace extends WorkspacePlugin { candidates: CandidateReleasePullRequest[], _updatedVersions: VersionsMap ): CandidateReleasePullRequest[] { - // NOP for node workspaces + if (candidates.length === 0) { + return candidates; + } + + const [candidate] = candidates; + + // check for root lock file in pull request + let hasRootLockFile: boolean | undefined; + for (let i = 0; i < candidate.pullRequest.updates.length; i++) { + if ( + candidate.pullRequest.updates[i].path === '.package-lock.json' || + candidate.pullRequest.updates[i].path === './package-lock.json' || + candidate.pullRequest.updates[i].path === 'package-lock.json' || + candidate.pullRequest.updates[i].path === '/package-lock.json' + ) { + hasRootLockFile = true; + break; + } + } + + // if there is a root lock file, then there is no additional pull request update necessary. + if (hasRootLockFile) { + return candidates; + } + + candidate.pullRequest.updates.push({ + path: 'package-lock.json', + createIfMissing: false, + updater: new PackageLockJson({ + versionsMap: _updatedVersions, + }), + }); + return candidates; } @@ -345,15 +417,7 @@ export class NodeWorkspace extends WorkspacePlugin { } protected pathFromPackage(pkg: Package): string { - return pkg.location; - } - - private detectRangePrefix(version: string): string { - return ( - Object.values(SUPPORTED_RANGE_PREFIXES).find(supportedRangePrefix => - version.startsWith(supportedRangePrefix) - ) || '' - ); + return pkg.path; } private combineDeps(packageJson: Package): Record { @@ -361,20 +425,31 @@ export class NodeWorkspace extends WorkspacePlugin { ...(packageJson.dependencies ?? {}), ...(packageJson.devDependencies ?? {}), ...(packageJson.optionalDependencies ?? {}), + ...(this.updatePeerDependencies + ? packageJson.peerDependencies ?? {} + : {}), }; } -} -enum SUPPORTED_RANGE_PREFIXES { - CARET = '^', - TILDE = '~', - GREATER_THAN = '>', - LESS_THAN = '<', - EQUAL_OR_GREATER_THAN = '>=', - EQUAL_OR_LESS_THAN = '<=', + async preconfigure( + strategiesByPath: Record, + _commitsByPath: Record, + _releasesByPath: Record + ): Promise> { + // Using preconfigure to siphon releases and strategies. + this.strategiesByPath = strategiesByPath; + this.releasesByPath = _releasesByPath; + + return strategiesByPath; + } } -function getChangelogDepsNotes(original: Package, updated: Package): string { +function getChangelogDepsNotes( + original: Package, + updated: Package, + updateVersions: VersionsMap, + logger: Logger +): string { let depUpdateNotes = ''; type DT = | 'dependencies' @@ -395,11 +470,20 @@ function getChangelogDepsNotes(original: Package, updated: Package): string { continue; } for (const [depName, currentDepVer] of Object.entries(pkgDepTypes)) { + const newVersion = updateVersions.get(depName); + if (!newVersion) { + logger.debug(`${depName} was not bumped, ignoring`); + continue; + } const origDepVer = original[depType]?.[depName]; - if (currentDepVer !== origDepVer) { + const newVersionString = newVersionWithRange(origDepVer, newVersion); + if (currentDepVer.startsWith('workspace:')) { + depUpdates.push(`\n * ${depName} bumped to ${newVersionString}`); + } else if (newVersionString !== origDepVer) { depUpdates.push( - `\n * ${depName} bumped from ${origDepVer} to ${currentDepVer}` + `\n * ${depName} bumped from ${origDepVer} to ${newVersionString}` ); + //handle case when "workspace:" version is used } } if (depUpdates.length > 0) { diff --git a/src/plugins/sentence-case.ts b/src/plugins/sentence-case.ts index d16483b6b..f257706cc 100644 --- a/src/plugins/sentence-case.ts +++ b/src/plugins/sentence-case.ts @@ -15,7 +15,7 @@ import {ManifestPlugin} from '../plugin'; import {GitHub} from '../github'; import {RepositoryConfig} from '../manifest'; -import {Commit} from '../commit'; +import {ConventionalCommit} from '../commit'; // A list of words that should not be converted to uppercase: const SPECIAL_WORDS = ['gRPC', 'npm']; @@ -43,9 +43,13 @@ export class SentenceCase extends ManifestPlugin { * @param {Commit[]} commits The set of commits that will feed into release pull request. * @returns {Commit[]} The modified commit objects. */ - processCommits(commits: Commit[]): Commit[] { + processCommits(commits: ConventionalCommit[]): ConventionalCommit[] { this.logger.info(`SentenceCase processing ${commits.length} commits`); for (const commit of commits) { + // The parsed conventional commit message, without the type: + console.info(commit.bareMessage); + commit.bareMessage = this.toUpperCase(commit.bareMessage); + // Check whether commit is in conventional commit format, if it is // we'll split the string by type and description: if (commit.message.includes(':')) { diff --git a/src/plugins/workspace.ts b/src/plugins/workspace.ts index 8f5b2b9c5..2386377dc 100644 --- a/src/plugins/workspace.ts +++ b/src/plugins/workspace.ts @@ -130,7 +130,7 @@ export abstract class WorkspacePlugin extends ManifestPlugin { if (existingCandidate) { // if already has an pull request, update the changelog and update this.logger.info( - `Updating exising candidate pull request for ${this.packageNameFromPackage( + `Updating existing candidate pull request for ${this.packageNameFromPackage( pkg )}, path: ${existingCandidate.path}` ); @@ -154,7 +154,7 @@ export abstract class WorkspacePlugin extends ManifestPlugin { pkg )}` ); - const newCandidate = this.newCandidate(pkg, updatedVersions); + const newCandidate = await this.newCandidate(pkg, updatedVersions); if (newCandidatePaths.has(newCandidate.path)) { this.logger.info( `Already created new candidate for path: ${newCandidate.path}` @@ -320,7 +320,7 @@ export abstract class WorkspacePlugin extends ManifestPlugin { protected abstract newCandidate( pkg: T, updatedVersions: VersionsMap - ): CandidateReleasePullRequest; + ): Promise; /** * Collect all packages being managed in this workspace. diff --git a/src/strategies/base.ts b/src/strategies/base.ts index c0a426a2c..02de0ce41 100644 --- a/src/strategies/base.ts +++ b/src/strategies/base.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -import {Strategy} from '../strategy'; +import {Strategy, BuildReleaseOptions, BumpReleaseOptions} from '../strategy'; import {GitHub} from '../github'; import {VersioningStrategy} from '../versioning-strategy'; import {Repository} from '../repository'; @@ -25,7 +25,7 @@ import { import {DefaultVersioningStrategy} from '../versioning-strategies/default'; import {DefaultChangelogNotes} from '../changelog-notes/default'; import {Update} from '../update'; -import {ConventionalCommit, Commit, parseConventionalCommits} from '../commit'; +import {ConventionalCommit, Commit} from '../commit'; import {Version, VersionsMap} from '../version'; import {TagName} from '../util/tag-name'; import {Release} from '../release'; @@ -35,17 +35,19 @@ import {PullRequestTitle} from '../util/pull-request-title'; import {BranchName} from '../util/branch-name'; import {PullRequestBody, ReleaseData} from '../util/pull-request-body'; import {PullRequest} from '../pull-request'; -import {mergeUpdates} from '../updaters/composite'; +import {CompositeUpdater, mergeUpdates} from '../updaters/composite'; import {Generic} from '../updaters/generic'; import {GenericJson} from '../updaters/generic-json'; import {GenericXml} from '../updaters/generic-xml'; import {PomXml} from '../updaters/java/pom-xml'; import {GenericYaml} from '../updaters/generic-yaml'; +import {GenericToml} from '../updaters/generic-toml'; const DEFAULT_CHANGELOG_PATH = 'CHANGELOG.md'; export interface BuildUpdatesOptions { changelogEntry: string; + commits?: ConventionalCommit[]; newVersion: Version; versionsMap: VersionsMap; latestVersion?: Version; @@ -73,6 +75,7 @@ export interface BaseStrategyOptions { includeVInTag?: boolean; pullRequestTitlePattern?: string; pullRequestHeader?: string; + pullRequestFooter?: string; extraFiles?: ExtraFile[]; versionFile?: string; snapshotLabels?: string[]; // Java-only @@ -105,6 +108,7 @@ export abstract class BaseStrategy implements Strategy { protected initialVersion?: string; readonly pullRequestTitlePattern?: string; readonly pullRequestHeader?: string; + readonly pullRequestFooter?: string; readonly extraFiles: ExtraFile[]; readonly extraLabels: string[]; @@ -137,6 +141,7 @@ export abstract class BaseStrategy implements Strategy { this.includeVInTag = options.includeVInTag ?? true; this.pullRequestTitlePattern = options.pullRequestTitlePattern; this.pullRequestHeader = options.pullRequestHeader; + this.pullRequestFooter = options.pullRequestFooter; this.extraFiles = options.extraFiles || []; this.initialVersion = options.initialVersion; this.extraLabels = options.extraLabels || []; @@ -220,7 +225,8 @@ export abstract class BaseStrategy implements Strategy { releaseNotesBody: string, _conventionalCommits: ConventionalCommit[], _latestRelease?: Release, - pullRequestHeader?: string + pullRequestHeader?: string, + pullRequestFooter?: string ): Promise { return new PullRequestBody( [ @@ -230,7 +236,10 @@ export abstract class BaseStrategy implements Strategy { notes: releaseNotesBody, }, ], - {header: pullRequestHeader} + { + header: pullRequestHeader, + footer: pullRequestFooter, + } ); } @@ -246,24 +255,22 @@ export abstract class BaseStrategy implements Strategy { * open a pull request. */ async buildReleasePullRequest( - commits: Commit[], + commits: ConventionalCommit[], latestRelease?: Release, draft?: boolean, - labels: string[] = [] + labels: string[] = [], + bumpOnlyOptions?: BumpReleaseOptions ): Promise { - const conventionalCommits = await this.postProcessCommits( - parseConventionalCommits(commits, this.logger) - ); + const conventionalCommits = await this.postProcessCommits(commits); this.logger.info(`Considering: ${conventionalCommits.length} commits`); - if (conventionalCommits.length === 0) { + if (!bumpOnlyOptions && conventionalCommits.length === 0) { this.logger.info(`No commits for path: ${this.path}, skipping`); return undefined; } - const newVersion = await this.buildNewVersion( - conventionalCommits, - latestRelease - ); + const newVersion = + bumpOnlyOptions?.newVersion ?? + (await this.buildNewVersion(conventionalCommits, latestRelease)); const versionsMap = await this.updateVersionsMap( await this.buildVersionsMap(conventionalCommits), conventionalCommits, @@ -299,7 +306,7 @@ export abstract class BaseStrategy implements Strategy { latestRelease, commits ); - if (this.changelogEmpty(releaseNotesBody)) { + if (!bumpOnlyOptions && this.changelogEmpty(releaseNotesBody)) { this.logger.info( `No user facing commits found since ${ latestRelease ? latestRelease.sha : 'beginning of time' @@ -312,6 +319,7 @@ export abstract class BaseStrategy implements Strategy { newVersion, versionsMap, latestVersion: latestRelease?.tag.version, + commits: conventionalCommits, }); const updatesWithExtras = mergeUpdates( updates.concat(...(await this.extraFileUpdates(newVersion, versionsMap))) @@ -322,7 +330,8 @@ export abstract class BaseStrategy implements Strategy { releaseNotesBody, conventionalCommits, latestRelease, - this.pullRequestHeader + this.pullRequestHeader, + this.pullRequestFooter ); return { @@ -395,6 +404,13 @@ export abstract class BaseStrategy implements Strategy { updater: new GenericYaml(extraFile.jsonpath, version), }); break; + case 'toml': + extraFileUpdates.push({ + path: this.addPath(path), + createIfMissing: false, + updater: new GenericToml(extraFile.jsonpath, version), + }); + break; case 'xml': extraFileUpdates.push({ path: this.addPath(path), @@ -417,6 +433,43 @@ export abstract class BaseStrategy implements Strategy { ); } } + } else if (extraFile.endsWith('.json')) { + extraFileUpdates.push({ + path: this.addPath(extraFile), + createIfMissing: false, + updater: new CompositeUpdater( + new GenericJson('$.version', version), + new Generic({version, versionsMap}) + ), + }); + } else if (extraFile.endsWith('.yaml') || extraFile.endsWith('.yml')) { + extraFileUpdates.push({ + path: this.addPath(extraFile), + createIfMissing: false, + updater: new CompositeUpdater( + new GenericYaml('$.version', version), + new Generic({version, versionsMap}) + ), + }); + } else if (extraFile.endsWith('.toml')) { + extraFileUpdates.push({ + path: this.addPath(extraFile), + createIfMissing: false, + updater: new CompositeUpdater( + new GenericToml('$.version', version), + new Generic({version, versionsMap}) + ), + }); + } else if (extraFile.endsWith('.xml')) { + extraFileUpdates.push({ + path: this.addPath(extraFile), + createIfMissing: false, + updater: new CompositeUpdater( + // Updates "version" element that is a child of the root element. + new GenericXml('/*/version', version), + new Generic({version, versionsMap}) + ), + }); } else { extraFileUpdates.push({ path: this.addPath(extraFile), @@ -495,9 +548,11 @@ export abstract class BaseStrategy implements Strategy { * Given a merged pull request, build the candidate release. * @param {PullRequest} mergedPullRequest The merged release pull request. * @returns {Release} The candidate release. + * @deprecated Use buildReleases() instead. */ async buildRelease( - mergedPullRequest: PullRequest + mergedPullRequest: PullRequest, + options?: BuildReleaseOptions ): Promise { if (this.skipGitHubRelease) { this.logger.info('Release skipped from strategy config'); @@ -507,6 +562,9 @@ export abstract class BaseStrategy implements Strategy { this.logger.error('Pull request should have been merged'); return; } + const mergedTitlePattern = + options?.groupPullRequestTitlePattern ?? + MANIFEST_PULL_REQUEST_TITLE_PATTERN; const pullRequestTitle = PullRequestTitle.parse( @@ -516,7 +574,7 @@ export abstract class BaseStrategy implements Strategy { ) || PullRequestTitle.parse( mergedPullRequest.title, - MANIFEST_PULL_REQUEST_TITLE_PATTERN, + mergedTitlePattern, this.logger ); if (!pullRequestTitle) { @@ -579,7 +637,15 @@ export abstract class BaseStrategy implements Strategy { if (notes === undefined) { this.logger.warn('Failed to find release notes'); } - const version = pullRequestTitle.getVersion() || releaseData?.version; + + let version: Version | undefined = pullRequestTitle.getVersion(); + if ( + !version || + (pullRequestBody.releaseData.length > 1 && releaseData?.version) + ) { + // prioritize pull-request body version for multi-component releases + version = releaseData?.version; + } if (!version) { this.logger.error('Pull request should have included version'); return; @@ -608,6 +674,22 @@ export abstract class BaseStrategy implements Strategy { }; } + /** + * Given a merged pull request, build the candidate releases. + * @param {PullRequest} mergedPullRequest The merged release pull request. + * @returns {Release} The candidate release. + */ + async buildReleases( + mergedPullRequest: PullRequest, + options?: BuildReleaseOptions + ): Promise { + const release = await this.buildRelease(mergedPullRequest, options); + if (release) { + return [release]; + } + return []; + } + isPublishedVersion(_version: Version): boolean { return true; } diff --git a/src/strategies/dart.ts b/src/strategies/dart.ts index 1401252e4..f21123e6b 100644 --- a/src/strategies/dart.ts +++ b/src/strategies/dart.ts @@ -21,6 +21,7 @@ import {PubspecYaml} from '../updaters/dart/pubspec-yaml'; import {BaseStrategy, BuildUpdatesOptions} from './base'; import {GitHubFileContents} from '@google-automations/git-file-utils'; import {Update} from '../update'; +import {FileNotFoundError, MissingRequiredFileError} from '../errors'; export class Dart extends BaseStrategy { private pubspecYmlContents?: GitHubFileContents; @@ -64,10 +65,21 @@ export class Dart extends BaseStrategy { private async getPubspecYmlContents(): Promise { if (!this.pubspecYmlContents) { - this.pubspecYmlContents = await this.github.getFileContentsOnBranch( - this.addPath('pubspec.yaml'), - this.targetBranch - ); + try { + this.pubspecYmlContents = await this.github.getFileContentsOnBranch( + this.addPath('pubspec.yaml'), + this.targetBranch + ); + } catch (e) { + if (e instanceof FileNotFoundError) { + throw new MissingRequiredFileError( + this.addPath('pubspec.yaml'), + Dart.name, + `${this.repository.owner}/${this.repository.repo}` + ); + } + throw e; + } } return this.pubspecYmlContents; } diff --git a/src/strategies/dotnet-yoshi.ts b/src/strategies/dotnet-yoshi.ts index 4d197af7d..a83dcee37 100644 --- a/src/strategies/dotnet-yoshi.ts +++ b/src/strategies/dotnet-yoshi.ts @@ -40,6 +40,8 @@ const DEFAULT_PULL_REQUEST_TITLE_PATTERN = 'Release${component} version ${version}'; const DEFAULT_PULL_REQUEST_HEADER = ':robot: I have created a release *beep* *boop*'; +const DEFAULT_PULL_REQUEST_FOOTER = + 'This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).'; const RELEASE_NOTES_HEADER_PATTERN = /#{2,3} \[?(\d+\.\d+\.\d+-?[^\]]*)\]?.* \((\d{4}-\d{2}-\d{2})\)/; @@ -61,6 +63,8 @@ export class DotnetYoshi extends BaseStrategy { options.pullRequestTitlePattern ?? DEFAULT_PULL_REQUEST_TITLE_PATTERN; options.pullRequestHeader = options.pullRequestHeader ?? DEFAULT_PULL_REQUEST_HEADER; + options.pullRequestFooter = + options.pullRequestFooter ?? DEFAULT_PULL_REQUEST_FOOTER; options.includeVInTag = options.includeVInTag ?? false; super(options); } diff --git a/src/strategies/helm.ts b/src/strategies/helm.ts index 82ff06406..fbc847566 100644 --- a/src/strategies/helm.ts +++ b/src/strategies/helm.ts @@ -21,6 +21,7 @@ import * as yaml from 'js-yaml'; import {ChartYaml} from '../updaters/helm/chart-yaml'; import {BaseStrategy, BuildUpdatesOptions} from './base'; import {Update} from '../update'; +import {FileNotFoundError, MissingRequiredFileError} from '../errors'; export class Helm extends BaseStrategy { private chartYmlContents?: GitHubFileContents; @@ -63,9 +64,20 @@ export class Helm extends BaseStrategy { private async getChartYmlContents(): Promise { if (!this.chartYmlContents) { - this.chartYmlContents = await this.github.getFileContents( - this.addPath('Chart.yaml') - ); + try { + this.chartYmlContents = await this.github.getFileContents( + this.addPath('Chart.yaml') + ); + } catch (e) { + if (e instanceof FileNotFoundError) { + throw new MissingRequiredFileError( + this.addPath('Chart.yaml'), + Helm.name, + `${this.repository.owner}/${this.repository.repo}` + ); + } + throw e; + } } return this.chartYmlContents; } diff --git a/src/strategies/java-yoshi-mono-repo.ts b/src/strategies/java-yoshi-mono-repo.ts new file mode 100644 index 000000000..eae2838ce --- /dev/null +++ b/src/strategies/java-yoshi-mono-repo.ts @@ -0,0 +1,351 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import {Update} from '../update'; +import {VersionsManifest} from '../updaters/java/versions-manifest'; +import {Version, VersionsMap} from '../version'; +import {Changelog} from '../updaters/changelog'; +import {ChangelogJson} from '../updaters/changelog-json'; +import {CommitSplit} from '../util/commit-split'; +import {CompositeUpdater} from '../updaters/composite'; +import {Updater} from '../update'; + +import {GitHubFileContents} from '@google-automations/git-file-utils'; +import { + FileNotFoundError, + GitHubAPIError, + MissingRequiredFileError, +} from '../errors'; +import {ConventionalCommit} from '../commit'; +import {Java, JavaBuildUpdatesOption} from './java'; +import {JavaUpdate} from '../updaters/java/java-update'; +import {filterCommits} from '../util/filter-commits'; + +export class JavaYoshiMonoRepo extends Java { + private versionsContent?: GitHubFileContents; + + /** + * Override this method to post process commits + * @param {ConventionalCommit[]} commits parsed commits + * @returns {ConventionalCommit[]} modified commits + */ + protected async postProcessCommits( + commits: ConventionalCommit[] + ): Promise { + if (commits.length === 0) { + // For Java commits, push a fake commit so we force a + // SNAPSHOT release + commits.push({ + type: 'fake', + bareMessage: 'fake commit', + message: 'fake commit', + breaking: false, + scope: null, + notes: [], + files: [], + references: [], + sha: 'fake', + }); + } + return commits; + } + + protected async needsSnapshot(): Promise { + return VersionsManifest.needsSnapshot( + (await this.getVersionsContent()).parsedContent + ); + } + + protected async buildVersionsMap(): Promise { + this.versionsContent = await this.getVersionsContent(); + return VersionsManifest.parseVersions(this.versionsContent.parsedContent); + } + + protected async getVersionsContent(): Promise { + if (!this.versionsContent) { + try { + this.versionsContent = await this.github.getFileContentsOnBranch( + this.addPath('versions.txt'), + this.targetBranch + ); + } catch (err) { + if (err instanceof GitHubAPIError) { + throw new MissingRequiredFileError( + this.addPath('versions.txt'), + JavaYoshiMonoRepo.name, + `${this.repository.owner}/${this.repository.repo}` + ); + } + throw err; + } + } + return this.versionsContent; + } + + protected async buildUpdates( + options: JavaBuildUpdatesOption + ): Promise { + const updates: Update[] = []; + const version = options.newVersion; + const versionsMap = options.versionsMap; + + updates.push({ + path: this.addPath('versions.txt'), + createIfMissing: false, + cachedFileContents: this.versionsContent, + updater: new VersionsManifest({ + version, + versionsMap, + }), + }); + + const pomFilesSearch = this.github.findFilesByFilenameAndRef( + 'pom.xml', + this.targetBranch, + this.path + ); + const buildFilesSearch = this.github.findFilesByFilenameAndRef( + 'build.gradle', + this.targetBranch, + this.path + ); + const dependenciesSearch = this.github.findFilesByFilenameAndRef( + 'dependencies.properties', + this.targetBranch, + this.path + ); + const readmeFilesSearch = this.github.findFilesByFilenameAndRef( + 'README.md', + this.targetBranch, + this.path + ); + + const pomFiles = await pomFilesSearch; + pomFiles.forEach(path => { + updates.push({ + path: this.addPath(path), + createIfMissing: false, + updater: new JavaUpdate({ + version, + versionsMap, + isSnapshot: options.isSnapshot, + }), + }); + }); + + const buildFiles = await buildFilesSearch; + buildFiles.forEach(path => { + updates.push({ + path: this.addPath(path), + createIfMissing: false, + updater: new JavaUpdate({ + version, + versionsMap, + isSnapshot: options.isSnapshot, + }), + }); + }); + + const dependenciesFiles = await dependenciesSearch; + dependenciesFiles.forEach(path => { + updates.push({ + path: this.addPath(path), + createIfMissing: false, + updater: new JavaUpdate({ + version, + versionsMap, + isSnapshot: options.isSnapshot, + }), + }); + }); + + const readmeFiles = await readmeFilesSearch; + readmeFiles.forEach(path => { + updates.push({ + path: this.addPath(path), + createIfMissing: false, + updater: new JavaUpdate({ + version, + versionsMap, + isSnapshot: options.isSnapshot, + }), + }); + }); + + this.extraFiles.forEach(extraFile => { + if (typeof extraFile === 'object') { + return; + } + updates.push({ + path: extraFile, + createIfMissing: false, + updater: new JavaUpdate({ + version, + versionsMap, + isSnapshot: options.isSnapshot, + }), + }); + }); + + if (!options.isSnapshot) { + updates.push({ + path: this.addPath(this.changelogPath), + createIfMissing: true, + updater: new Changelog({ + version, + changelogEntry: options.changelogEntry, + }), + }); + + // Bail early if the repository has no root changelog.json. + // This file is used to opt into machine readable commits. + const hasChangelogJson = await this.hasChangelogJson(); + if (hasChangelogJson && options.commits) { + const changelogUpdates: Array = []; + const cs = new CommitSplit({ + includeEmpty: false, + }); + const splitCommits = cs.split( + filterCommits(options.commits, this.changelogSections) + ); + for (const path of Object.keys(splitCommits)) { + const repoMetadata = await this.getRepoMetadata(path); + const artifactName = repoMetadata + ? repoMetadata['distribution_name'] + : null; + if (repoMetadata && artifactName) { + this.logger.info(`Found artifact ${artifactName} for ${path}`); + changelogUpdates.push( + new ChangelogJson({ + artifactName, + version, + // We filter out "chore:" commits, to reduce noise in the upstream + // release notes. We will only show a product release note entry + // if there has been a substantial change, such as a fix or feature. + commits: splitCommits[path], + language: 'JAVA', + }) + ); + } + } + updates.push({ + path: 'changelog.json', + createIfMissing: false, + updater: new CompositeUpdater(...changelogUpdates), + }); + } + } + + return updates; + } + + private async hasChangelogJson(): Promise { + try { + const content = await this.github.getFileContentsOnBranch( + 'changelog.json', + this.targetBranch + ); + return !!content; + } catch (e) { + if (e instanceof FileNotFoundError) return false; + else throw e; + } + } + + private async getRepoMetadata( + path: string + ): Promise | null> { + try { + const content = await this.github.getFileContentsOnBranch( + this.addPath(`${path}/.repo-metadata.json`), + this.targetBranch + ); + return content ? JSON.parse(content.parsedContent) : null; + } catch (e) { + if (e instanceof FileNotFoundError) return null; + else throw e; + } + } + + protected async updateVersionsMap( + versionsMap: VersionsMap, + conventionalCommits: ConventionalCommit[] + ): Promise { + let isPromotion = false; + const modifiedCommits: ConventionalCommit[] = []; + for (const commit of conventionalCommits) { + if (isPromotionCommit(commit)) { + isPromotion = true; + modifiedCommits.push({ + ...commit, + notes: commit.notes.filter(note => !isPromotionNote(note)), + }); + } else { + modifiedCommits.push(commit); + } + } + for (const versionKey of versionsMap.keys()) { + const version = versionsMap.get(versionKey); + if (!version) { + this.logger.warn(`didn't find version for ${versionKey}`); + continue; + } + if (isPromotion && isStableArtifact(versionKey)) { + versionsMap.set(versionKey, Version.parse('1.0.0')); + } else { + const newVersion = await this.versioningStrategy.bump( + version, + modifiedCommits + ); + versionsMap.set(versionKey, newVersion); + } + } + return versionsMap; + } + + protected initialReleaseVersion(): Version { + return Version.parse('0.1.0'); + } +} + +const VERSIONED_ARTIFACT_REGEX = /^.*-(v\d+[^-]*)$/; +const VERSION_REGEX = /^v\d+(.*)$/; + +/** + * Returns true if the artifact should be considered stable + * @param artifact name of the artifact to check + */ +function isStableArtifact(artifact: string): boolean { + const match = artifact.match(VERSIONED_ARTIFACT_REGEX); + if (!match) { + // The artifact does not have a version qualifier at the end + return true; + } + + const versionMatch = match[1].match(VERSION_REGEX); + if (versionMatch && versionMatch[1]) { + // The version is not stable (probably alpha/beta/rc) + return false; + } + + return true; +} + +function isPromotionCommit(commit: ConventionalCommit): boolean { + return commit.notes.some(isPromotionNote); +} + +function isPromotionNote(note: {title: string; text: string}): boolean { + return note.title === 'RELEASE AS' && note.text === '1.0.0'; +} diff --git a/src/strategies/java-yoshi.ts b/src/strategies/java-yoshi.ts index da0a13ccd..f1ecac822 100644 --- a/src/strategies/java-yoshi.ts +++ b/src/strategies/java-yoshi.ts @@ -17,7 +17,7 @@ import {VersionsManifest} from '../updaters/java/versions-manifest'; import {Version, VersionsMap} from '../version'; import {Changelog} from '../updaters/changelog'; import {GitHubFileContents} from '@google-automations/git-file-utils'; -import {GitHubAPIError, MissingRequiredFileError} from '../errors'; +import {MissingRequiredFileError, FileNotFoundError} from '../errors'; import {ConventionalCommit} from '../commit'; import {Java, JavaBuildUpdatesOption} from './java'; import {JavaUpdate} from '../updaters/java/java-update'; @@ -70,7 +70,7 @@ export class JavaYoshi extends Java { this.targetBranch ); } catch (err) { - if (err instanceof GitHubAPIError) { + if (err instanceof FileNotFoundError) { throw new MissingRequiredFileError( this.addPath('versions.txt'), JavaYoshi.name, diff --git a/src/strategies/java.ts b/src/strategies/java.ts index 5b1aa7e13..62ecc1b87 100644 --- a/src/strategies/java.ts +++ b/src/strategies/java.ts @@ -17,7 +17,7 @@ import {Version} from '../version'; import {BaseStrategy, BaseStrategyOptions, BuildUpdatesOptions} from './base'; import {Changelog} from '../updaters/changelog'; import {JavaSnapshot} from '../versioning-strategies/java-snapshot'; -import {Commit} from '../commit'; +import {ConventionalCommit} from '../commit'; import {Release} from '../release'; import {ReleasePullRequest} from '../release-pull-request'; import {PullRequestTitle} from '../util/pull-request-title'; @@ -30,6 +30,7 @@ import {DEFAULT_SNAPSHOT_LABELS} from '../manifest'; import {JavaReleased} from '../updaters/java/java-released'; import {mergeUpdates} from '../updaters/composite'; import {logger as defaultLogger} from '../util/logger'; +import {BumpReleaseOptions} from '../strategy'; const CHANGELOG_SECTIONS = [ {type: 'feat', section: 'Features'}, @@ -74,10 +75,11 @@ export class Java extends BaseStrategy { } async buildReleasePullRequest( - commits: Commit[], + commits: ConventionalCommit[], latestRelease?: Release, draft?: boolean, - labels: string[] = [] + labels: string[] = [], + _bumpOnlyOptions?: BumpReleaseOptions ): Promise { if (await this.needsSnapshot(commits, latestRelease)) { this.logger.info('Repository needs a snapshot bump.'); @@ -135,6 +137,7 @@ export class Java extends BaseStrategy { versionsMap, changelogEntry: notes, isSnapshot: true, + commits: [], }); const updatesWithExtras = mergeUpdates( updates.concat(...(await this.extraFileUpdates(newVersion, versionsMap))) @@ -156,7 +159,7 @@ export class Java extends BaseStrategy { } protected async needsSnapshot( - commits: Commit[], + commits: ConventionalCommit[], latestRelease?: Release ): Promise { if (this.skipSnapshot) { diff --git a/src/strategies/node.ts b/src/strategies/node.ts index e1628688c..52fc2c176 100644 --- a/src/strategies/node.ts +++ b/src/strategies/node.ts @@ -14,12 +14,14 @@ import {BaseStrategy, BuildUpdatesOptions} from './base'; import {Update} from '../update'; +import {ChangelogJson} from '../updaters/changelog-json'; import {PackageLockJson} from '../updaters/node/package-lock-json'; import {SamplesPackageJson} from '../updaters/node/samples-package-json'; import {Changelog} from '../updaters/changelog'; import {PackageJson} from '../updaters/node/package-json'; import {GitHubFileContents} from '@google-automations/git-file-utils'; import {FileNotFoundError, MissingRequiredFileError} from '../errors'; +import {filterCommits} from '../util/filter-commits'; export class Node extends BaseStrategy { private pkgJsonContents?: GitHubFileContents; @@ -29,6 +31,7 @@ export class Node extends BaseStrategy { ): Promise { const updates: Update[] = []; const version = options.newVersion; + const versionsMap = options.versionsMap; const packageName = (await this.getPackageName()) ?? ''; const lockFiles = ['package-lock.json', 'npm-shrinkwrap.json']; lockFiles.forEach(lockFile => { @@ -37,6 +40,7 @@ export class Node extends BaseStrategy { createIfMissing: false, updater: new PackageLockJson({ version, + versionsMap, }), }); }); @@ -68,6 +72,21 @@ export class Node extends BaseStrategy { }), }); + // If a machine readable changelog.json exists update it: + if (options.commits && packageName) { + const commits = filterCommits(options.commits, this.changelogSections); + updates.push({ + path: 'changelog.json', + createIfMissing: false, + updater: new ChangelogJson({ + artifactName: packageName, + version, + commits, + language: 'JAVASCRIPT', + }), + }); + } + return updates; } diff --git a/src/strategies/php-yoshi.ts b/src/strategies/php-yoshi.ts index 81b0877bc..67a675c92 100644 --- a/src/strategies/php-yoshi.ts +++ b/src/strategies/php-yoshi.ts @@ -16,7 +16,6 @@ import {BaseStrategy, BuildUpdatesOptions, BaseStrategyOptions} from './base'; import {Update} from '../update'; import {Changelog} from '../updaters/changelog'; import {RootComposerUpdatePackages} from '../updaters/php/root-composer-update-packages'; -import {PHPManifest} from '../updaters/php/php-manifest'; import {PHPClientVersion} from '../updaters/php/php-client-version'; import {VersionsMap, Version} from '../version'; import {Commit, parseConventionalCommits} from '../commit'; @@ -30,6 +29,7 @@ import {BranchName} from '../util/branch-name'; import {PullRequestBody} from '../util/pull-request-body'; import {GitHubFileContents} from '@google-automations/git-file-utils'; import {FileNotFoundError} from '../errors'; +import {BumpReleaseOptions} from '../strategy'; const CHANGELOG_SECTIONS = [ {type: 'feat', section: 'Features'}, @@ -69,12 +69,13 @@ export class PHPYoshi extends BaseStrategy { commits: Commit[], latestRelease?: Release, draft?: boolean, - labels: string[] = [] + labels: string[] = [], + bumpOnlyOptions?: BumpReleaseOptions ): Promise { const conventionalCommits = await this.postProcessCommits( parseConventionalCommits(commits, this.logger) ); - if (conventionalCommits.length === 0) { + if (!bumpOnlyOptions && conventionalCommits.length === 0) { this.logger.info(`No commits for path: ${this.path}, skipping`); return undefined; } @@ -154,6 +155,7 @@ export class PHPYoshi extends BaseStrategy { newVersion, versionsMap, latestVersion: latestRelease?.tag.version, + commits: conventionalCommits, // TODO(@bcoe): these commits will need to be divided into multiple changelog.json updates. }); for (const directory in directoryVersionContents) { const componentInfo = directoryVersionContents[directory]; @@ -170,6 +172,13 @@ export class PHPYoshi extends BaseStrategy { version, }), }); + updates.push({ + path: this.addPath(`${directory}/composer.json`), + createIfMissing: false, + updater: new RootComposerUpdatePackages({ + version, + }), + }); if (componentInfo.composer.extra?.component?.entry) { updates.push({ path: this.addPath( @@ -241,8 +250,7 @@ export class PHPYoshi extends BaseStrategy { }), }); - // update the aggregate package information in the root - // composer.json and manifest.json. + // update the aggregate package information in the root composer.json updates.push({ path: this.addPath('composer.json'), createIfMissing: false, @@ -252,33 +260,6 @@ export class PHPYoshi extends BaseStrategy { }), }); - updates.push({ - path: this.addPath('docs/manifest.json'), - createIfMissing: false, - updater: new PHPManifest({ - version, - versionsMap, - }), - }); - - updates.push({ - path: this.addPath('src/Version.php'), - createIfMissing: false, - updater: new PHPClientVersion({ - version, - versionsMap, - }), - }); - - updates.push({ - path: this.addPath('src/ServiceBuilder.php'), - createIfMissing: false, - updater: new PHPClientVersion({ - version, - versionsMap, - }), - }); - return updates; } } diff --git a/src/strategies/php.ts b/src/strategies/php.ts index 9136aa9a9..ccf46047f 100644 --- a/src/strategies/php.ts +++ b/src/strategies/php.ts @@ -17,6 +17,7 @@ import {Changelog} from '../updaters/changelog'; // PHP Specific. import {RootComposerUpdatePackages} from '../updaters/php/root-composer-update-packages'; import {BaseStrategy, BuildUpdatesOptions, BaseStrategyOptions} from './base'; +import {DefaultUpdater} from '../updaters/default'; import {Update} from '../update'; import {VersionsMap} from '../version'; @@ -46,7 +47,6 @@ export class PHP extends BaseStrategy { const updates: Update[] = []; const version = options.newVersion; const versionsMap: VersionsMap = new Map(); - versionsMap.set('version', version); updates.push({ path: this.addPath(this.changelogPath), @@ -67,6 +67,15 @@ export class PHP extends BaseStrategy { }), }); + // update VERSION file + updates.push({ + path: this.addPath('VERSION'), + createIfMissing: false, + updater: new DefaultUpdater({ + version, + }), + }); + return updates; } } diff --git a/src/strategies/python.ts b/src/strategies/python.ts index 8b7df84eb..5287b9451 100644 --- a/src/strategies/python.ts +++ b/src/strategies/python.ts @@ -15,6 +15,7 @@ import {BaseStrategy, BuildUpdatesOptions, BaseStrategyOptions} from './base'; import {Update} from '../update'; import {Changelog} from '../updaters/changelog'; +import {ChangelogJson} from '../updaters/changelog-json'; import {Version} from '../version'; import {SetupCfg} from '../updaters/python/setup-cfg'; import {SetupPy} from '../updaters/python/setup-py'; @@ -24,6 +25,8 @@ import { PyProjectToml, } from '../updaters/python/pyproject-toml'; import {PythonFileWithVersion} from '../updaters/python/python-file-with-version'; +import {FileNotFoundError} from '../errors'; +import {filterCommits} from '../util/filter-commits'; const CHANGELOG_SECTIONS = [ {type: 'feat', section: 'Features'}, @@ -133,6 +136,22 @@ export class Python extends BaseStrategy { }); }); + // If a machine readable changelog.json exists update it: + const artifactName = projectName ?? (await this.getNameFromSetupPy()); + if (options.commits && artifactName) { + const commits = filterCommits(options.commits, this.changelogSections); + updates.push({ + path: 'changelog.json', + createIfMissing: false, + updater: new ChangelogJson({ + artifactName, + version, + commits, + language: 'PYTHON', + }), + }); + } + return updates; } @@ -148,6 +167,35 @@ export class Python extends BaseStrategy { } } + protected async getNameFromSetupPy(): Promise { + const ARTIFACT_NAME_REGEX = /name *= *['"](?.*)['"](\r|\n|$)/; + const setupPyContents = await this.getSetupPyContents(); + if (setupPyContents) { + const match = setupPyContents.match(ARTIFACT_NAME_REGEX); + if (match && match?.groups?.name) { + return match.groups.name; + } + } + return null; + } + + protected async getSetupPyContents(): Promise { + try { + return ( + await this.github.getFileContentsOnBranch( + this.addPath('setup.py'), + this.targetBranch + ) + ).parsedContent; + } catch (e) { + if (e instanceof FileNotFoundError) { + return null; + } else { + throw e; + } + } + } + protected initialReleaseVersion(): Version { return Version.parse('0.1.0'); } diff --git a/src/strategies/ruby.ts b/src/strategies/ruby.ts index c08eaddbc..9b3581060 100644 --- a/src/strategies/ruby.ts +++ b/src/strategies/ruby.ts @@ -19,6 +19,7 @@ import {Changelog} from '../updaters/changelog'; // Ruby import {VersionRB} from '../updaters/ruby/version-rb'; +import {GemfileLock} from '../updaters/ruby/gemfile-lock'; import {BaseStrategy, BuildUpdatesOptions, BaseStrategyOptions} from './base'; import {ConventionalCommit} from '../commit'; import {Update} from '../update'; @@ -56,6 +57,16 @@ export class Ruby extends BaseStrategy { version, }), }); + + updates.push({ + path: this.addPath('Gemfile.lock'), + createIfMissing: false, + updater: new GemfileLock({ + version, + gemName: this.component || '', + }), + }); + return updates; } diff --git a/src/strategies/sfdx.ts b/src/strategies/sfdx.ts new file mode 100644 index 000000000..d1deb8616 --- /dev/null +++ b/src/strategies/sfdx.ts @@ -0,0 +1,81 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import {BaseStrategy, BuildUpdatesOptions} from './base'; +import {Update} from '../update'; +import {Changelog} from '../updaters/changelog'; +import {GitHubFileContents} from '@google-automations/git-file-utils'; +import {FileNotFoundError, MissingRequiredFileError} from '../errors'; +import {SfdxProjectJson} from '../updaters/sfdx/sfdx-project-json'; + +const sfdxProjectJsonFileName = 'sfdx-project.json'; + +export class Sfdx extends BaseStrategy { + private sfdxProjectJsonContents?: GitHubFileContents; + + protected async buildUpdates( + options: BuildUpdatesOptions + ): Promise { + const updates: Update[] = []; + const version = options.newVersion; + + updates.push({ + path: this.addPath(this.changelogPath), + createIfMissing: true, + updater: new Changelog({ + version, + changelogEntry: options.changelogEntry, + }), + }); + + updates.push({ + path: this.addPath(sfdxProjectJsonFileName), + createIfMissing: false, + cachedFileContents: this.sfdxProjectJsonContents, + updater: new SfdxProjectJson({ + version, + }), + }); + + return updates; + } + + async getDefaultPackageName(): Promise { + const pkgJsonContents = await this.getSfdxProjectJsonContents(); + const pkg = JSON.parse(pkgJsonContents.parsedContent); + return pkg.name; + } + + protected async getSfdxProjectJsonContents(): Promise { + if (!this.sfdxProjectJsonContents) { + try { + this.sfdxProjectJsonContents = + await this.github.getFileContentsOnBranch( + this.addPath(sfdxProjectJsonFileName), + this.targetBranch + ); + } catch (e) { + if (e instanceof FileNotFoundError) { + throw new MissingRequiredFileError( + this.addPath(sfdxProjectJsonFileName), + 'sfdx', + `${this.repository.owner}/${this.repository.repo}` + ); + } + throw e; + } + } + return this.sfdxProjectJsonContents; + } +} diff --git a/src/strategies/terraform-module.ts b/src/strategies/terraform-module.ts index e6d5be4b3..71287fcd2 100644 --- a/src/strategies/terraform-module.ts +++ b/src/strategies/terraform-module.ts @@ -17,6 +17,7 @@ import {Changelog} from '../updaters/changelog'; // Terraform specific. import {ReadMe} from '../updaters/terraform/readme'; import {ModuleVersion} from '../updaters/terraform/module-version'; +import {MetadataVersion} from '../updaters/terraform/metadata-version'; import {BaseStrategy, BuildUpdatesOptions} from './base'; import {Update} from '../update'; import {Version} from '../version'; @@ -88,6 +89,23 @@ export class TerraformModule extends BaseStrategy { }), }); }); + + // Update metadata.yaml to current candidate version. + const metadataFiles = await this.github.findFilesByFilenameAndRef( + 'metadata.yaml', + this.targetBranch, + this.path + ); + + metadataFiles.forEach(path => { + updates.push({ + path: this.addPath(path), + createIfMissing: false, + updater: new MetadataVersion({ + version, + }), + }); + }); return updates; } diff --git a/src/strategy.ts b/src/strategy.ts index 5108c2733..b4dd95606 100644 --- a/src/strategy.ts +++ b/src/strategy.ts @@ -20,6 +20,14 @@ import {VersioningStrategy} from './versioning-strategy'; import {ChangelogNotes} from './changelog-notes'; import {Version} from './version'; +export interface BuildReleaseOptions { + groupPullRequestTitlePattern?: string; +} + +export interface BumpReleaseOptions { + newVersion: Version; +} + /** * A strategy is responsible for determining which files are * necessary to update in a release pull request. @@ -35,6 +43,10 @@ export interface Strategy { * component if available. * @param {boolean} draft Optional. Whether or not to create the pull * request as a draft. Defaults to `false`. + * @param {BumpReleaseOptions} bumpOnlyOptions Optional. Options, that when + * present, indicate a release should be created even if there are no + * conventional commits. This is used when a release is required for + * a dependency update with a workspace plugin. * @returns {ReleasePullRequest | undefined} The release pull request to * open for this path/component. Returns undefined if we should not * open a pull request. @@ -43,15 +55,30 @@ export interface Strategy { commits: Commit[], latestRelease?: Release, draft?: boolean, - labels?: string[] + labels?: string[], + bumpOnlyOptions?: BumpReleaseOptions ): Promise; /** * Given a merged pull request, build the candidate release. * @param {PullRequest} mergedPullRequest The merged release pull request. * @returns {Release} The candidate release. + * @deprecated Use buildReleases() instead. + */ + buildRelease( + mergedPullRequest: PullRequest, + options?: BuildReleaseOptions + ): Promise; + + /** + * Given a merged pull request, build the candidate releases. + * @param {PullRequest} mergedPullRequest The merged release pull request. + * @returns {Release} The candidate release. */ - buildRelease(mergedPullRequest: PullRequest): Promise; + buildReleases( + mergedPullRequest: PullRequest, + options?: BuildReleaseOptions + ): Promise; /** * Return the component for this strategy. This may be a computed field. diff --git a/src/updaters/base-xml.ts b/src/updaters/base-xml.ts index f5fbad4e8..3930bbeec 100644 --- a/src/updaters/base-xml.ts +++ b/src/updaters/base-xml.ts @@ -29,7 +29,11 @@ export abstract class BaseXml implements Updater { const updated = this.updateDocument(document); if (updated) { - return new dom.XMLSerializer().serializeToString(document); + const newContent = new dom.XMLSerializer().serializeToString(document); + if (content.endsWith('\n') && !newContent.endsWith('\n')) { + return `${newContent}\n`; + } + return newContent; } else { return content; } diff --git a/src/updaters/changelog-json.ts b/src/updaters/changelog-json.ts new file mode 100644 index 000000000..f1c1711e5 --- /dev/null +++ b/src/updaters/changelog-json.ts @@ -0,0 +1,117 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import {ConventionalCommit} from '../commit'; +import {logger as defaultLogger, Logger} from '../util/logger'; +import {DefaultUpdater, UpdateOptions} from './default'; +import {randomUUID} from 'crypto'; + +const BREAKING_CHANGE_TITLE = 'BREAKING CHANGE'; +const COMMIT_PREFIX = /^[^:]+: ?/; +const PR_SUFFIX_REGEX = / ?\(#(?[0-9]+)\)$/; + +interface ChangelogJsonOptions extends UpdateOptions { + artifactName: string; + language: string; + commits: ConventionalCommit[]; +} + +interface Change { + type: string; + scope?: string; + sha: string; + issues: string[]; + message: string; + breakingChangeNote?: string; +} + +/** + * Maintians a machine readable CHANGELOG in chnagelog.json. + * See: https://gist.github.com/bcoe/50ef0a0024bbf107cd5bc0adbdc04758 + */ +export class ChangelogJson extends DefaultUpdater { + artifactName: string; + language: string; + commits: ConventionalCommit[]; + + /** + * Instantiate a new SamplesPackageJson updater + * @param options + */ + constructor(options: ChangelogJsonOptions) { + super(options); + this.language = options.language; + this.artifactName = options.artifactName; + this.commits = options.commits; + } + + /** + * Given initial file contents, return updated contents. + * @param {string} content The initial content + * @returns {string} The updated content + */ + updateContent(content: string, logger: Logger = defaultLogger): string { + const parsed = JSON.parse(content); + logger.info(`adding release ${this.version} for ${this.artifactName}`); + const changes = []; + for (const commit of this.commits) { + const issues = new Set(); + // The commit.message field contains the type/scope prefix. + let message = commit.message.replace(COMMIT_PREFIX, ''); + // When squashing commits, GitHub adds a suffix refrencing + // the # of the PR, e.g., chore(main): release 15.5.1 (#1838) + // this logic removes this suffix and prepends it to the + // issues array. + const match = message.match(PR_SUFFIX_REGEX); + if (match && match.groups?.pr) { + message = message.replace(match[0], ''); + issues.add(match.groups.pr); + } + // Array.from(someSet) will maintain elements in insertion + // order, given this we add references after the pr suffix. + for (const ref of commit.references) { + issues.add(ref.issue); + } + const change: Change = { + type: commit.type, + sha: commit.sha, + message: message, + issues: Array.from(issues), + }; + if (commit.scope) change.scope = commit.scope; + for (const note of commit.notes) { + if (note.title === BREAKING_CHANGE_TITLE) { + change.breakingChangeNote = note.text; + } + } + changes.push(change); + } + // If all commits were ignored, simply return the original changelog.json. + if (changes.length === 0) { + return content; + } + const time = new Date().toISOString(); + const release = { + changes, + version: this.version.toString(), + language: this.language, + artifactName: this.artifactName, + id: randomUUID(), + createTime: time, + }; + parsed.entries.unshift(release); + parsed.updateTime = time; + return JSON.stringify(parsed, null, 2); + } +} diff --git a/src/updaters/expo/app-json.ts b/src/updaters/expo/app-json.ts index 7df8308df..b8d0fae66 100644 --- a/src/updaters/expo/app-json.ts +++ b/src/updaters/expo/app-json.ts @@ -24,7 +24,7 @@ export interface AppJson { buildNumber?: string; }; android?: { - versionCode?: string; + versionCode?: number; }; }; } @@ -86,7 +86,7 @@ export class AppJson extends DefaultUpdater { logger.info( `updating Android version from ${parsed.expo.android.versionCode} to ${versionCode}` ); - parsed.expo.android.versionCode = versionCode.toString(); + parsed.expo.android.versionCode = versionCode; } return jsonStringify(parsed, content); diff --git a/src/updaters/generic-toml.ts b/src/updaters/generic-toml.ts new file mode 100644 index 000000000..eb94a9af6 --- /dev/null +++ b/src/updaters/generic-toml.ts @@ -0,0 +1,65 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import {Updater} from '../update'; +import {Version} from '../version'; +import * as jp from 'jsonpath'; +import {parseWith, replaceTomlValue} from '../util/toml-edit'; +import * as toml from '@iarna/toml'; +import {logger as defaultLogger, Logger} from '../util/logger'; + +/** + * Updates TOML document according to given JSONPath. + * + * Note that used parser does reformat the document and removes all comments, + * and converts everything to pure TOML. + * If you want to retain formatting, use generic updater with comment hints. + */ +export class GenericToml implements Updater { + readonly jsonpath: string; + readonly version: Version; + + constructor(jsonpath: string, version: Version) { + this.jsonpath = jsonpath; + this.version = version; + } + /** + * Given initial file contents, return updated contents. + * @param {string} content The initial content + * @returns {string} The updated content + */ + updateContent(content: string, logger: Logger = defaultLogger): string { + let data: toml.JsonMap; + try { + data = parseWith(content); + } catch (e) { + logger.warn('Invalid toml, cannot be parsed', e); + return content; + } + + const paths = jp.paths(data, this.jsonpath); + if (!paths || paths.length === 0) { + logger.warn(`No entries modified in ${this.jsonpath}`); + return content; + } + + let processed = content; + paths.forEach(path => { + if (path[0] === '$') path = path.slice(1); + processed = replaceTomlValue(processed, path, this.version.toString()); + }); + + return processed; + } +} diff --git a/src/updaters/helm/chart-yaml.ts b/src/updaters/helm/chart-yaml.ts index 32eb51149..7bc1591b2 100644 --- a/src/updaters/helm/chart-yaml.ts +++ b/src/updaters/helm/chart-yaml.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -import * as yaml from 'js-yaml'; +import * as yaml from 'yaml'; import {logger as defaultLogger, Logger} from '../../util/logger'; import {DefaultUpdater} from '../default'; @@ -26,13 +26,13 @@ export class ChartYaml extends DefaultUpdater { * @returns {string} The updated content */ updateContent(content: string, logger: Logger = defaultLogger): string { - const data = yaml.load(content, {json: true}); - if (data === null || data === undefined) { + const chart = yaml.parseDocument(content); + if (chart === null || chart === undefined) { return ''; } - const parsed = JSON.parse(JSON.stringify(data)); - logger.info(`updating from ${parsed.version} to ${this.version}`); - parsed.version = this.version.toString(); - return yaml.dump(parsed); + const oldVersion = chart.get('version'); + logger.info(`updating from ${oldVersion} to ${this.version}`); + chart.set('version', this.version.toString()); + return chart.toString(); } } diff --git a/src/updaters/node/package-json.ts b/src/updaters/node/package-json.ts index e01a6cafe..9eb5cf104 100644 --- a/src/updaters/node/package-json.ts +++ b/src/updaters/node/package-json.ts @@ -14,9 +14,19 @@ import {jsonStringify} from '../../util/json-stringify'; import {logger as defaultLogger, Logger} from '../../util/logger'; +import {Version, VersionsMap} from '../../version'; import {DefaultUpdater} from '../default'; -type LockFile = {version: string}; +export type PackageJsonDescriptor = { + name?: string; + resolved?: string; + link?: boolean; + version: string; + dependencies?: Record; + devDependencies?: Record; + peerDependencies?: Record; + optionalDependencies?: Record; +}; /** * This updates a Node.js package.json file's main version. @@ -25,12 +35,82 @@ export class PackageJson extends DefaultUpdater { /** * Given initial file contents, return updated contents. * @param {string} content The initial content + * @param logger * @returns {string} The updated content */ updateContent(content: string, logger: Logger = defaultLogger): string { - const parsed = JSON.parse(content) as LockFile; + const parsed = JSON.parse(content) as PackageJsonDescriptor; logger.info(`updating from ${parsed.version} to ${this.version}`); parsed.version = this.version.toString(); + + // If additional dependency versions specified, then update dependency versions + // while preserving any valid version range prefixes. + if (this.versionsMap) { + if (parsed.dependencies) { + updateDependencies(parsed.dependencies, this.versionsMap); + } + if (parsed.devDependencies) { + updateDependencies(parsed.devDependencies, this.versionsMap); + } + if (parsed.peerDependencies) { + updateDependencies(parsed.peerDependencies, this.versionsMap); + } + if (parsed.optionalDependencies) { + updateDependencies(parsed.optionalDependencies, this.versionsMap); + } + } + return jsonStringify(parsed, content); } } + +enum SUPPORTED_RANGE_PREFIXES { + CARET = '^', + TILDE = '~', + EQUAL_OR_GREATER_THAN = '>=', + EQUAL_OR_LESS_THAN = '<=', + GREATER_THAN = '>', + LESS_THAN = '<', +} +function detectRangePrefix(version: string): string { + return ( + Object.values(SUPPORTED_RANGE_PREFIXES).find(supportedRangePrefix => + version.startsWith(supportedRangePrefix) + ) || '' + ); +} +/** + * Helper to coerce a new version value into a version range that preserves the + * version range prefix of the original version. + * @param {string} oldVersion Old semver with range + * @param {Version} newVersion The new version to update with + */ +export function newVersionWithRange( + oldVersion: string, + newVersion: Version +): string { + const prefix = detectRangePrefix(oldVersion); + if (prefix) { + return `${prefix}${newVersion}`; + } + return newVersion.toString(); +} +/** + * Helper function to update dependency versions for all new versions specified + * in the updated versions map. Note that this mutates the existing input. + * @param {Record} dependencies Entries in package.json dependencies + * where the key is the dependency name and the value is the dependency range + * @param {VersionsMap} updatedVersions Map of new versions (without dependency range prefixes) + */ +export function updateDependencies( + dependencies: Record, + updatedVersions: VersionsMap +) { + for (const depName of Object.keys(dependencies)) { + const newVersion = updatedVersions.get(depName); + if (newVersion) { + const oldVersion = dependencies[depName]; + dependencies[depName] = newVersionWithRange(oldVersion, newVersion); + } + } +} diff --git a/src/updaters/node/package-lock-json.ts b/src/updaters/node/package-lock-json.ts index 5a1c7c188..b2c6cd7a0 100644 --- a/src/updaters/node/package-lock-json.ts +++ b/src/updaters/node/package-lock-json.ts @@ -12,28 +12,87 @@ // See the License for the specific language governing permissions and // limitations under the License. +import {Updater} from '../../update'; import {jsonStringify} from '../../util/json-stringify'; import {logger as defaultLogger, Logger} from '../../util/logger'; -import {DefaultUpdater} from '../default'; +import {Version, VersionsMap} from '../../version'; +import {UpdateOptions} from '../default'; +import {PackageJsonDescriptor, updateDependencies} from './package-json'; type LockFileV2 = { version: string; lockfileVersion?: number; - packages: Record; + packages: Record; }; /** * Updates a Node.js package-lock.json file's version and '' package * version (for a v2 lock file). */ -export class PackageLockJson extends DefaultUpdater { +export class PackageLockJson implements Updater { + version?: Version; + versionsMap?: VersionsMap; + constructor(options: Partial) { + this.version = options.version; + this.versionsMap = options.versionsMap; + } updateContent(content: string, logger: Logger = defaultLogger): string { const parsed = JSON.parse(content) as LockFileV2; - logger.info(`updating from ${parsed.version} to ${this.version}`); - parsed.version = this.version.toString(); - if (parsed.lockfileVersion === 2) { - parsed.packages[''].version = this.version.toString(); + if (this.version) { + logger.info(`updating from ${parsed.version} to ${this.version}`); + parsed.version = this.version.toString(); + } + + if (parsed.lockfileVersion === 2 || parsed.lockfileVersion === 3) { + if (this.version) { + parsed.packages[''].version = this.version.toString(); + } + + if (this.versionsMap) { + this.versionsMap.forEach((version, name) => { + let pkg = parsed.packages['node_modules/' + name]; + if (!pkg) { + return; + } + + // @see https://docs.npmjs.com/cli/v10/configuring-npm/package-lock-json#packages + if (pkg.link && pkg.resolved) { + pkg = parsed.packages[pkg.resolved]; + if (!pkg) { + return; + } + } + + pkg.version = version.toString(); + + if (pkg.dependencies) { + updateDependencies(pkg.dependencies, this.versionsMap!); + } + if (pkg.devDependencies) { + updateDependencies(pkg.devDependencies, this.versionsMap!); + } + if (pkg.peerDependencies) { + updateDependencies(pkg.peerDependencies, this.versionsMap!); + } + if (pkg.optionalDependencies) { + updateDependencies(pkg.optionalDependencies, this.versionsMap!); + } + }); + } } + if (this.versionsMap) { + for (const [, obj] of Object.entries(parsed.packages)) { + if (!obj.name) { + continue; + } + + const ver = this.versionsMap.get(obj.name); + if (ver) { + obj.version = ver.toString(); + } + } + } + return jsonStringify(parsed, content); } } diff --git a/src/updaters/php/root-composer-update-packages.ts b/src/updaters/php/root-composer-update-packages.ts index c30de2153..b39592dfc 100644 --- a/src/updaters/php/root-composer-update-packages.ts +++ b/src/updaters/php/root-composer-update-packages.ts @@ -26,11 +26,17 @@ export class RootComposerUpdatePackages extends DefaultUpdater { * @returns {string} The updated content */ updateContent(content: string, logger: Logger = defaultLogger): string { - if (!this.versionsMap || this.versionsMap.size === 0) { + if (!this.version && (!this.versionsMap || this.versionsMap.size === 0)) { logger.info('no updates necessary'); return content; } const parsed = JSON.parse(content); + if (parsed['version']) { + const fromVersion: string = parsed['version']; + const toVersion = this.version.toString() || '1.0.0'; + parsed['version'] = toVersion; + logger.info(`updating "version" from ${fromVersion} to ${toVersion}`); + } if (this.versionsMap) { for (const [key, version] of this.versionsMap.entries()) { const toVersion = version.toString() || '1.0.0'; diff --git a/src/updaters/python/pyproject-toml.ts b/src/updaters/python/pyproject-toml.ts index 06ae818ee..db1163fed 100644 --- a/src/updaters/python/pyproject-toml.ts +++ b/src/updaters/python/pyproject-toml.ts @@ -13,8 +13,8 @@ // limitations under the License. import * as TOML from '@iarna/toml'; -import {replaceTomlValue} from '../../util/toml-edit'; import {logger as defaultLogger, Logger} from '../../util/logger'; +import {replaceTomlValue} from '../../util/toml-edit'; import {DefaultUpdater} from '../default'; // TODO: remove support for `poetry.tool` when Poetry will use `project`. @@ -22,6 +22,7 @@ import {DefaultUpdater} from '../default'; interface PyProjectContent { name: string; version: string; + dynamic?: string[]; } /** @@ -52,6 +53,14 @@ export class PyProjectToml extends DefaultUpdater { const project = parsed.project || parsed.tool?.poetry; if (!project?.version) { + // Throw warning if the version is dynamically generated. + if (project?.dynamic && project.dynamic.includes('version')) { + const msg = + "dynamic version found in 'pyproject.toml'. Skipping update."; + logger.warn(msg); + return content; + } + const msg = 'invalid file'; logger.error(msg); throw new Error(msg); diff --git a/src/updaters/python/setup-cfg.ts b/src/updaters/python/setup-cfg.ts index fd4ff88ba..00c56f2ef 100644 --- a/src/updaters/python/setup-cfg.ts +++ b/src/updaters/python/setup-cfg.ts @@ -25,7 +25,7 @@ export class SetupCfg extends DefaultUpdater { */ updateContent(content: string): string { return content.replace( - /(version ?= ?)[0-9]+\.[0-9]+\.[0-9](?:-\w+)?/, + /(version ?= ?)[0-9]+\.[0-9]+\.[0-9]+(?:-\w+)?/, `$1${this.version}` ); } diff --git a/src/updaters/release-please-config.ts b/src/updaters/release-please-config.ts index a6cb1deab..feedfe1d5 100644 --- a/src/updaters/release-please-config.ts +++ b/src/updaters/release-please-config.ts @@ -75,6 +75,7 @@ function releaserConfigToJsonConfig( 'changelog-host': config.changelogHost, 'pull-request-title-pattern': config.pullRequestTitlePattern, 'pull-request-header': config.pullRequestHeader, + 'pull-request-footer': config.pullRequestFooter, 'separate-pull-requests': config.separatePullRequests, 'tag-separator': config.tagSeparator, 'extra-files': config.extraFiles, diff --git a/src/updaters/ruby/common.ts b/src/updaters/ruby/common.ts new file mode 100644 index 000000000..2ac0f4588 --- /dev/null +++ b/src/updaters/ruby/common.ts @@ -0,0 +1,52 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import {Version} from '../../version'; + +// Ruby gem semver strings using `.` seperator for prereleases rather then `-` +// See https://guides.rubygems.org/patterns/ + +export const RUBY_VERSION_REGEX = /((\d+).(\d)+.(\d+)(.\w+.*)?)/g; + +/** + * Stringify a version to a ruby compatible version string + * + * @param version The version to stringify + * @param useDotPrePreleaseSeperator Use a `.` seperator for prereleases rather then `-` + * @returns a ruby compatible version string + */ +export function stringifyRubyVersion( + version: Version, + useDotPrePreleaseSeperator = false +) { + if (!useDotPrePreleaseSeperator) { + return version.toString(); + } + + return `${version.major}.${version.minor}.${version.patch}${ + version.preRelease ? `.${version.preRelease}` : '' + }`; +} + +/** + * This function mimics Gem::Version parsing of version semver strings + * + * @param versionString The version string to resolve + * @returns A Gem::Version compatible version string + */ +export function resolveRubyGemfileLockVersion(versionString: string) { + // Replace `-` with `.pre.` as per ruby gem parsing + // See https://github.com/rubygems/rubygems/blob/master/lib/rubygems/version.rb#L229 + return versionString.replace(/-/g, '.pre.'); +} diff --git a/src/updaters/ruby/gemfile-lock.ts b/src/updaters/ruby/gemfile-lock.ts new file mode 100644 index 000000000..fec65e71a --- /dev/null +++ b/src/updaters/ruby/gemfile-lock.ts @@ -0,0 +1,64 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import {DefaultUpdater, UpdateOptions} from '../default'; +import {RUBY_VERSION_REGEX, resolveRubyGemfileLockVersion} from './common'; + +export interface GemfileLockOptions extends UpdateOptions { + gemName: string; +} + +/** + * Builds a regex matching a gem version in a Gemfile.lock file. + * @example + * rails (7.0.1) + * rails (7.0.1.alpha1) + */ +export function buildGemfileLockVersionRegex(gemName: string) { + return new RegExp(`s*${gemName} \\(${RUBY_VERSION_REGEX.source}\\)`); +} + +/** + * Updates a Gemfile.lock files which is expected to have a local path version string. + */ +export class GemfileLock extends DefaultUpdater { + gemName: string; + + constructor(options: GemfileLockOptions) { + super(options); + this.gemName = options.gemName; + } + + /** + * Given initial file contents, return updated contents. + * @param {string} content The initial content + * @returns {string} The updated content + */ + updateContent(content: string): string { + if (!this.gemName) { + return content; + } + + // Bundler will convert 1.0.0-alpha1 to 1.0.0.pre.alpha1, so we need to + // do the same here. + const versionString = resolveRubyGemfileLockVersion( + this.version.toString() + ); + + return content.replace( + buildGemfileLockVersionRegex(this.gemName), + `${this.gemName} (${versionString})` + ); + } +} diff --git a/src/updaters/ruby/version-rb.ts b/src/updaters/ruby/version-rb.ts index 96db08bb1..6e5535525 100644 --- a/src/updaters/ruby/version-rb.ts +++ b/src/updaters/ruby/version-rb.ts @@ -13,6 +13,11 @@ // limitations under the License. import {DefaultUpdater} from '../default'; +import {RUBY_VERSION_REGEX, stringifyRubyVersion} from './common'; + +const RUBY_VERSION_RB_REGEX = new RegExp( + `(["'])(${RUBY_VERSION_REGEX.source})(["'])` +); /** * Updates a versions.rb file which is expected to have a version string. @@ -25,8 +30,8 @@ export class VersionRB extends DefaultUpdater { */ updateContent(content: string): string { return content.replace( - /(["'])[0-9]+\.[0-9]+\.[0-9](-\w+)?["']/, - `$1${this.version}$1` + RUBY_VERSION_RB_REGEX, + `$1${stringifyRubyVersion(this.version)}$1` ); } } diff --git a/src/updaters/php/php-manifest.ts b/src/updaters/sfdx/sfdx-project-json.ts similarity index 53% rename from src/updaters/php/php-manifest.ts rename to src/updaters/sfdx/sfdx-project-json.ts index 737087c48..1c815a574 100644 --- a/src/updaters/php/php-manifest.ts +++ b/src/updaters/sfdx/sfdx-project-json.ts @@ -1,4 +1,4 @@ -// Copyright 2019 Google LLC +// Copyright 2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,47 +12,38 @@ // See the License for the specific language governing permissions and // limitations under the License. -import {logger as defaultLogger, Logger} from '../../util/logger'; import {jsonStringify} from '../../util/json-stringify'; +import {logger as defaultLogger, Logger} from '../../util/logger'; import {DefaultUpdater} from '../default'; -interface ManifestModule { +export type PackageDirectory = { + versionNumber: string; + default: boolean; +}; +export type SfdxProjectFile = { + packageDirectories: PackageDirectory[]; name: string; - versions: string[]; -} +}; /** - * Updates a manifest.json file. - * @see https://github.com/googleapis/google-cloud-php/blob/master/docs/manifest.json + * This updates a sfdx sfdx-project.json file's main version. */ -export class PHPManifest extends DefaultUpdater { +export class SfdxProjectJson extends DefaultUpdater { /** * Given initial file contents, return updated contents. * @param {string} content The initial content * @returns {string} The updated content */ updateContent(content: string, logger: Logger = defaultLogger): string { - if (!this.versionsMap || this.versionsMap.size === 0) { - logger.info('no updates necessary'); - return content; - } - const parsed = JSON.parse(content); - parsed.modules.forEach((module: ManifestModule) => { - if (!this.versionsMap) return; - for (const [key, version] of this.versionsMap) { - if (module.name === key) { - logger.info(`adding ${key}@${version} to manifest`); - module.versions.unshift(`v${version}`); - } + const parsed = JSON.parse(content) as SfdxProjectFile; + for (const packDir of parsed.packageDirectories) { + if (packDir.default) { + logger.info( + `updating from ${packDir.versionNumber} to ${this.version}` + ); + packDir.versionNumber = `${this.version.toString()}.NEXT`; } - - // the mono-repo's own API version should be added to the - // google/cloud key: - if (module.name === 'google/cloud') { - module.versions.unshift(`v${this.version}`); - } - }); - + } return jsonStringify(parsed, content); } } diff --git a/src/updaters/terraform/metadata-version.ts b/src/updaters/terraform/metadata-version.ts new file mode 100644 index 000000000..b75740bab --- /dev/null +++ b/src/updaters/terraform/metadata-version.ts @@ -0,0 +1,37 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import {logger as defaultLogger, Logger} from '../../util/logger'; +import {DefaultUpdater} from '../default'; + +/** + * Updates a Terraform metadata.yaml or metadata.display.yaml file(s). + */ +export class MetadataVersion extends DefaultUpdater { + /** + * Given initial file contents, return updated contents. + * @param {string} content The initial content + * @returns {string} The updated content + */ + updateContent(content: string, logger: Logger = defaultLogger): string { + const oldVersion = content.match(/version: [0-9]+\.[0-9]+\.[0-9]+(-\w+)?/); + if (oldVersion) { + logger.info(`updating from ${oldVersion} to v${this.version}`); + } + return content.replace( + /version: [0-9]+\.[0-9]+\.[0-9]+(-\w+)?/g, + `version: ${this.version}` + ); + } +} diff --git a/src/util/branch-name.ts b/src/util/branch-name.ts index d70709528..a914f0bf3 100644 --- a/src/util/branch-name.ts +++ b/src/util/branch-name.ts @@ -28,6 +28,7 @@ function getAllResourceNames(): BranchNameType[] { return [ AutoreleaseBranchName, ComponentBranchName, + GroupBranchName, DefaultBranchName, V12ComponentBranchName, V12DefaultBranchName, @@ -78,6 +79,13 @@ export class BranchName { `${RELEASE_PLEASE}--branches--${targetBranch}--components--${component}` ); } + static ofGroupTargetBranch(group: string, targetBranch: string): BranchName { + return new GroupBranchName( + `${RELEASE_PLEASE}--branches--${targetBranch}--groups--${safeBranchName( + group + )}` + ); + } constructor(_branchName: string) {} static matches(_branchName: string): boolean { @@ -211,3 +219,28 @@ class ComponentBranchName extends BranchName { return `${RELEASE_PLEASE}--branches--${this.targetBranch}--components--${this.component}`; } } + +const GROUP_PATTERN = `^${RELEASE_PLEASE}--branches--(?.+)--groups--(?.+)$`; +class GroupBranchName extends BranchName { + static matches(branchName: string): boolean { + return !!branchName.match(GROUP_PATTERN); + } + constructor(branchName: string) { + super(branchName); + const match = branchName.match(GROUP_PATTERN); + if (match?.groups) { + this.targetBranch = match.groups['branch']; + this.component = match.groups['group']; + } + } + toString(): string { + return `${RELEASE_PLEASE}--branches--${this.targetBranch}--groups--${this.component}`; + } +} + +function safeBranchName(branchName: string): string { + // convert disallowed characters in branch names, replacing them with '-'. + // replace multiple consecutive '-' with a single '-' to avoid interfering with + // our regexes for parsing the branch names + return branchName.replace(/[^\w\d]/g, '-').replace(/-+/g, '-'); +} diff --git a/src/util/commit-exclude.ts b/src/util/commit-exclude.ts new file mode 100644 index 000000000..60127950e --- /dev/null +++ b/src/util/commit-exclude.ts @@ -0,0 +1,63 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import {Commit} from '../commit'; +import {ReleaserConfig, ROOT_PROJECT_PATH} from '../manifest'; +import {normalizePaths} from './commit-utils'; + +export type CommitExcludeConfig = Pick; + +export class CommitExclude { + private excludePaths: Record = {}; + + constructor(config: Record) { + Object.entries(config).forEach(([path, releaseConfig]) => { + if (releaseConfig.excludePaths) { + this.excludePaths[path] = normalizePaths(releaseConfig.excludePaths); + } + }); + } + + excludeCommits( + commitsPerPath: Record + ): Record { + const filteredCommitsPerPath: Record = {}; + Object.entries(commitsPerPath).forEach(([path, commits]) => { + if (this.excludePaths[path]) { + commits = commits.filter(commit => + this.shouldInclude(commit, this.excludePaths[path], path) + ); + } + filteredCommitsPerPath[path] = commits; + }); + return filteredCommitsPerPath; + } + + private shouldInclude( + commit: Commit, + excludePaths: string[], + packagePath: string + ): boolean { + return ( + !commit.files || + !commit.files + .filter(file => this.isRelevant(file, packagePath)) + .every(file => excludePaths.some(path => this.isRelevant(file, path))) + ); + } + + private isRelevant(file: string, path: string) { + return path === ROOT_PROJECT_PATH || file.indexOf(`${path}/`) === 0; + } +} diff --git a/src/util/commit-split.ts b/src/util/commit-split.ts index 8565ce0c5..c8a2d5648 100644 --- a/src/util/commit-split.ts +++ b/src/util/commit-split.ts @@ -14,6 +14,7 @@ import {Commit} from '../commit'; import {ROOT_PROJECT_PATH} from '../manifest'; +import {normalizePaths} from './commit-utils'; export interface CommitSplitOptions { // Include empty git commits: each empty commit is included @@ -54,29 +55,14 @@ export class CommitSplit { opts = opts || {}; this.includeEmpty = !!opts.includeEmpty; if (opts.packagePaths) { - const paths: string[] = []; - for (let newPath of opts.packagePaths) { - // The special "." path, representing the root of the module, should be - // ignored by commit-split as it is assigned all commits in manifest.ts - if (newPath === ROOT_PROJECT_PATH) { - continue; - } - // normalize so that all paths have leading and trailing slashes for - // non-overlap validation. - // NOTE: GitHub API always returns paths using the `/` separator, - // regardless of what platform the client code is running on - newPath = newPath.replace(/\/$/, ''); - newPath = newPath.replace(/^\//, ''); - newPath = newPath.replace(/$/, '/'); - newPath = newPath.replace(/^/, '/'); - // store them with leading and trailing slashes removed. - newPath = newPath.replace(/\/$/, ''); - newPath = newPath.replace(/^\//, ''); - paths.push(newPath); - } - - // sort by longest paths first - this.packagePaths = paths.sort((a, b) => b.length - a.length); + const paths: string[] = normalizePaths(opts.packagePaths); + this.packagePaths = paths + .filter(path => { + // The special "." path, representing the root of the module, should be + // ignored by commit-split as it is assigned all commits in manifest.ts + return path !== ROOT_PROJECT_PATH; + }) + .sort((a, b) => b.length - a.length); // sort by longest paths first } } diff --git a/src/util/commit-utils.ts b/src/util/commit-utils.ts new file mode 100644 index 000000000..9e2842763 --- /dev/null +++ b/src/util/commit-utils.ts @@ -0,0 +1,30 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +export const normalizePaths = (paths: string[]) => { + return paths.map(path => { + // normalize so that all paths have leading and trailing slashes for + // non-overlap validation. + // NOTE: GitHub API always returns paths using the `/` separator, + // regardless of what platform the client code is running on + let newPath = path.replace(/\/$/, ''); + newPath = newPath.replace(/^\//, ''); + newPath = newPath.replace(/$/, '/'); + newPath = newPath.replace(/^/, '/'); + // store them with leading and trailing slashes removed. + newPath = newPath.replace(/\/$/, ''); + newPath = newPath.replace(/^\//, ''); + return newPath; + }); +}; diff --git a/src/util/filter-commits.ts b/src/util/filter-commits.ts new file mode 100644 index 000000000..5660ae13b --- /dev/null +++ b/src/util/filter-commits.ts @@ -0,0 +1,63 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import {ChangelogSection} from '../changelog-notes'; +import {ConventionalCommit} from '../commit'; + +const BREAKING_CHANGE_NOTE = 'BREAKING CHANGE'; + +const DEFAULT_CHANGELOG_SECTIONS = [ + {type: 'feat', section: 'Features'}, + {type: 'fix', section: 'Bug Fixes'}, + {type: 'perf', section: 'Performance Improvements'}, + {type: 'revert', section: 'Reverts'}, + {type: 'chore', section: 'Miscellaneous Chores', hidden: true}, + {type: 'docs', section: 'Documentation', hidden: true}, + {type: 'style', section: 'Styles', hidden: true}, + {type: 'refactor', section: 'Code Refactoring', hidden: true}, + {type: 'test', section: 'Tests', hidden: true}, + {type: 'build', section: 'Build System', hidden: true}, + {type: 'ci', section: 'Continuous Integration', hidden: true}, +]; + +/** + * Given a set of conventional commits and the configured + * changelog sections provided by the user, return the set + * of commits that should be displayed: + * + * @param commits + * @param changelogSections + * @returns ConventionalCommit[] + */ +export function filterCommits( + commits: ConventionalCommit[], + changelogSections?: ChangelogSection[] +): ConventionalCommit[] { + changelogSections = changelogSections ?? DEFAULT_CHANGELOG_SECTIONS; + const hiddenSections: Array = []; + const visibleSections: Array = []; + for (const section of changelogSections) { + if (!section.hidden) visibleSections.push(section.type); + else hiddenSections.push(section.type); + } + return commits.filter(commit => { + const isBreaking = commit.notes.find(note => { + return note.title === BREAKING_CHANGE_NOTE; + }); + return ( + visibleSections.includes(commit.type) || + (isBreaking && hiddenSections.includes(commit.type)) + ); + }); +} diff --git a/src/util/pull-request-body.ts b/src/util/pull-request-body.ts index 079343cbd..bf16e3ac4 100644 --- a/src/util/pull-request-body.ts +++ b/src/util/pull-request-body.ts @@ -152,7 +152,7 @@ function extractMultipleReleases(notes: string, logger: Logger): ReleaseData[] { } return data; } -const COMPARE_REGEX = /^#{2,} \[?(?\d+\.\d+\.\d+.*)\]?/; +const COMPARE_REGEX = /^#{2,} \[?(?\d+\.\d+\.\d+[^\]]*)\]?/; function extractSingleRelease(body: string, logger: Logger): ReleaseData[] { body = body.trim(); const match = body.match(COMPARE_REGEX); diff --git a/src/util/pull-request-title.ts b/src/util/pull-request-title.ts index 375a7eef9..c9df13721 100644 --- a/src/util/pull-request-title.ts +++ b/src/util/pull-request-title.ts @@ -47,7 +47,7 @@ export function generateMatchPattern( .replace('(', '\\(') .replace(')', '\\)') .replace('${scope}', '(\\((?[\\w-./]+)\\))?') - .replace('${component}', ' ?(?[\\w-./]*)?') + .replace('${component}', ' ?(?@?[\\w-./]*)?') .replace('${version}', 'v?(?[0-9].*)') .replace('${branch}', '(?[\\w-./]+)?')}$` ); diff --git a/src/util/toml-edit.ts b/src/util/toml-edit.ts index 4637d97df..5975c885e 100644 --- a/src/util/toml-edit.ts +++ b/src/util/toml-edit.ts @@ -86,7 +86,10 @@ class TaggedTOMLParser extends TOMLParser { * @param input A string * @param parserType The TOML parser to use (might be custom) */ -function parseWith(input: string, parserType: typeof TOMLParser): JsonMap { +export function parseWith( + input: string, + parserType: typeof TOMLParser = TaggedTOMLParser +): JsonMap { const parser = new parserType(); parser.parse(input); return parser.finish(); @@ -114,7 +117,7 @@ function isTaggedValue(x: unknown): x is TaggedValue { */ export function replaceTomlValue( input: string, - path: string[], + path: (string | number)[], newValue: string ) { // our pointer into the object "tree", initially points to the root. diff --git a/src/version.ts b/src/version.ts index b2c9658ae..e3bfcb145 100644 --- a/src/version.ts +++ b/src/version.ts @@ -82,6 +82,10 @@ export class Version { const buildPart = this.build ? `+${this.build}` : ''; return `${this.major}.${this.minor}.${this.patch}${preReleasePart}${buildPart}`; } + + get isPreMajor(): boolean { + return this.major < 1; + } } export type VersionsMap = Map; diff --git a/src/versioning-strategies/default.ts b/src/versioning-strategies/default.ts index 2db9c0303..6fdc0c97c 100644 --- a/src/versioning-strategies/default.ts +++ b/src/versioning-strategies/default.ts @@ -24,7 +24,7 @@ import {ConventionalCommit} from '../commit'; import {Version} from '../version'; import {logger as defaultLogger, Logger} from '../util/logger'; -interface DefaultVersioningStrategyOptions { +export interface DefaultVersioningStrategyOptions { bumpMinorPreMajor?: boolean; bumpPatchForMinorPreMajor?: boolean; logger?: Logger; @@ -89,13 +89,13 @@ export class DefaultVersioningStrategy implements VersioningStrategy { } if (breaking > 0) { - if (version.major < 1 && this.bumpMinorPreMajor) { + if (version.isPreMajor && this.bumpMinorPreMajor) { return new MinorVersionUpdate(); } else { return new MajorVersionUpdate(); } } else if (features > 0) { - if (version.major < 1 && this.bumpPatchForMinorPreMajor) { + if (version.isPreMajor && this.bumpPatchForMinorPreMajor) { return new PatchVersionUpdate(); } else { return new MinorVersionUpdate(); diff --git a/src/versioning-strategies/dependency-manifest.ts b/src/versioning-strategies/dependency-manifest.ts index 6e31b7842..fb5d606b0 100644 --- a/src/versioning-strategies/dependency-manifest.ts +++ b/src/versioning-strategies/dependency-manifest.ts @@ -57,13 +57,13 @@ export class DependencyManifest extends DefaultVersioningStrategy { let dependencyBump: VersionUpdater; if (breaking > 0) { - if (version.major < 1 && this.bumpMinorPreMajor) { + if (version.isPreMajor && this.bumpMinorPreMajor) { dependencyBump = new MinorVersionUpdate(); } else { dependencyBump = new MajorVersionUpdate(); } } else if (features > 0) { - if (version.major < 1 && this.bumpPatchForMinorPreMajor) { + if (version.isPreMajor && this.bumpPatchForMinorPreMajor) { dependencyBump = new PatchVersionUpdate(); } else { dependencyBump = new MinorVersionUpdate(); diff --git a/src/versioning-strategies/prerelease.ts b/src/versioning-strategies/prerelease.ts new file mode 100644 index 000000000..1fcbadf96 --- /dev/null +++ b/src/versioning-strategies/prerelease.ts @@ -0,0 +1,225 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { + DefaultVersioningStrategyOptions, + DefaultVersioningStrategy, +} from './default'; +import {Version} from '../version'; +import {ConventionalCommit} from '..'; +import { + VersionUpdater, + CustomVersionUpdate, + MinorVersionUpdate, + MajorVersionUpdate, +} from '../versioning-strategy'; + +interface PrereleaseVersioningStrategyOptions + extends DefaultVersioningStrategyOptions { + prereleaseType?: string; +} + +/** + * Regex to match the last set of numbers in a string + * Example: 1.2.3-beta01-01 -> 01 + */ +const PRERELEASE_NUMBER = /(?\d+)(?=\D*$)/; + +abstract class AbstractPrereleaseVersionUpdate implements VersionUpdater { + protected readonly prereleaseType?: string; + + constructor(prereleaseType?: string) { + this.prereleaseType = prereleaseType; + } + + /** + * Returns the new bumped prerelease version + * + * That is, if the current version is 1.2.3-beta01, the next prerelease version + * will be 1.2.3-beta02. If no number is found, the prerelease version will be + * 1.2.3-beta. If multiple numbers are found, the last set of numbers will be + * incremented, e.g. 1.2.3-beta01-01 -> 1.2.3-beta01-02. + * + * @param {prerelease} string The current version + * @returns {Version} The bumped version + */ + protected bumpPrerelease(prerelease: string): string { + const match = prerelease.match(PRERELEASE_NUMBER); + + let nextPrerelease = `${prerelease}.1`; + + if (match?.groups) { + const numberLength = match.groups.number.length; + const nextPrereleaseNumber = Number(match.groups.number) + 1; + const paddedNextPrereleaseNumber = `${nextPrereleaseNumber}`.padStart( + numberLength, + '0' + ); + nextPrerelease = prerelease.replace( + PRERELEASE_NUMBER, + paddedNextPrereleaseNumber + ); + } + return nextPrerelease; + } + + abstract bump(version: Version): Version; +} + +class PrereleasePatchVersionUpdate extends AbstractPrereleaseVersionUpdate { + /** + * Returns the new bumped version + * + * @param {Version} version The current version + * @returns {Version} The bumped version + */ + bump(version: Version): Version { + if (version.preRelease) { + const nextPrerelease = this.bumpPrerelease(version.preRelease); + return new Version( + version.major, + version.minor, + version.patch, + nextPrerelease, + version.build + ); + } + return new Version( + version.major, + version.minor, + version.patch + 1, + this.prereleaseType, + version.build + ); + } +} + +class PrereleaseMinorVersionUpdate extends AbstractPrereleaseVersionUpdate { + /** + * Returns the new bumped version + * + * @param {Version} version The current version + * @returns {Version} The bumped version + */ + bump(version: Version): Version { + if (version.preRelease) { + if (version.patch === 0) { + const nextPrerelease = this.bumpPrerelease(version.preRelease); + + return new Version( + version.major, + version.minor, + version.patch, + nextPrerelease, + version.build + ); + } + + return new MinorVersionUpdate().bump(version); + } + return new Version( + version.major, + version.minor + 1, + 0, + this.prereleaseType, + version.build + ); + } +} + +class PrereleaseMajorVersionUpdate extends AbstractPrereleaseVersionUpdate { + /** + * Returns the new bumped version + * + * @param {Version} version The current version + * @returns {Version} The bumped version + */ + bump(version: Version): Version { + if (version.preRelease) { + if (version.patch === 0 && version.minor === 0) { + const nextPrerelease = this.bumpPrerelease(version.preRelease); + return new Version( + version.major, + version.minor, + version.patch, + nextPrerelease, + version.build + ); + } + return new MajorVersionUpdate().bump(version); + } + return new Version( + version.major + 1, + 0, + 0, + this.prereleaseType, + version.build + ); + } +} + +/** + * This versioning strategy will increment the pre-release number for patch + * bumps if there is a pre-release number (preserving any leading 0s). + * Example: 1.2.3-beta01 -> 1.2.3-beta02. + */ +export class PrereleaseVersioningStrategy extends DefaultVersioningStrategy { + readonly prereleaseType?: string; + + constructor(options: PrereleaseVersioningStrategyOptions = {}) { + super(options); + this.prereleaseType = options.prereleaseType; + } + + determineReleaseType( + version: Version, + commits: ConventionalCommit[] + ): VersionUpdater { + // iterate through list of commits and find biggest commit type + let breaking = 0; + let features = 0; + for (const commit of commits) { + const releaseAs = commit.notes.find(note => note.title === 'RELEASE AS'); + if (releaseAs) { + // commits are handled newest to oldest, so take the first one (newest) found + this.logger.debug( + `found Release-As: ${releaseAs.text}, forcing version` + ); + return new CustomVersionUpdate( + Version.parse(releaseAs.text).toString() + ); + } + if (commit.breaking) { + breaking++; + } else if (commit.type === 'feat' || commit.type === 'feature') { + features++; + } + } + + if (breaking > 0) { + if (version.isPreMajor && this.bumpMinorPreMajor) { + return new PrereleaseMinorVersionUpdate(this.prereleaseType); + } else { + return new PrereleaseMajorVersionUpdate(this.prereleaseType); + } + } else if (features > 0) { + if (version.isPreMajor && this.bumpPatchForMinorPreMajor) { + return new PrereleasePatchVersionUpdate(this.prereleaseType); + } else { + return new PrereleaseMinorVersionUpdate(this.prereleaseType); + } + } + return new PrereleasePatchVersionUpdate(this.prereleaseType); + } +} diff --git a/test/changelog-notes/default-changelog-notes.ts b/test/changelog-notes/default-changelog-notes.ts index d88b4a68f..e78e48d10 100644 --- a/test/changelog-notes/default-changelog-notes.ts +++ b/test/changelog-notes/default-changelog-notes.ts @@ -21,6 +21,8 @@ import { } from '../helpers'; import {DefaultChangelogNotes} from '../../src/changelog-notes/default'; import {parseConventionalCommits} from '../../src/commit'; +import {PullRequestBody} from '../../src/util/pull-request-body'; +import {Version} from '../../src/version'; describe('DefaultChangelogNotes', () => { const commits = [ @@ -135,6 +137,16 @@ describe('DefaultChangelogNotes', () => { expect(notes).to.is.string; safeSnapshot(notes); }); + it('should handle a breaking change with reference', async () => { + const commits = [buildMockCommit('fix!: some bugfix (#1234)')]; + const changelogNotes = new DefaultChangelogNotes(); + const notes = await changelogNotes.buildNotes( + parseConventionalCommits(commits), + notesOptions + ); + expect(notes).to.is.string; + safeSnapshot(notes); + }); it('should parse multiple commit messages from a single commit', async () => { const commits = [buildCommitFromFixture('multiple-messages')]; const changelogNotes = new DefaultChangelogNotes(); @@ -165,6 +177,16 @@ describe('DefaultChangelogNotes', () => { expect(notes).to.is.string; safeSnapshot(notes); }); + it('should handle inline bug links', async () => { + const commits = [buildMockCommit('fix: some bugfix (#1234)')]; + const changelogNotes = new DefaultChangelogNotes(); + const notes = await changelogNotes.buildNotes( + parseConventionalCommits(commits), + notesOptions + ); + expect(notes).to.is.string; + safeSnapshot(notes); + }); it('should handle git trailers', async () => { const commits = [buildCommitFromFixture('git-trailers-with-breaking')]; const changelogNotes = new DefaultChangelogNotes(); @@ -263,4 +285,33 @@ describe('DefaultChangelogNotes', () => { // }); }); }); + describe('pull request compatibility', () => { + it('should build parseable notes', async () => { + const notesOptions = { + owner: 'googleapis', + repository: 'java-asset', + version: '1.2.3', + previousTag: 'v1.2.2', + currentTag: 'v1.2.3', + targetBranch: 'main', + }; + const changelogNotes = new DefaultChangelogNotes(); + const notes = await changelogNotes.buildNotes(commits, notesOptions); + const pullRequestBody = new PullRequestBody([ + { + version: Version.parse('1.2.3'), + notes, + }, + ]); + const pullRequestBodyContent = pullRequestBody.toString(); + const parsedPullRequestBody = PullRequestBody.parse( + pullRequestBodyContent + ); + expect(parsedPullRequestBody).to.not.be.undefined; + expect(parsedPullRequestBody!.releaseData).lengthOf(1); + expect(parsedPullRequestBody!.releaseData[0].version?.toString()).to.eql( + '1.2.3' + ); + }); + }); }); diff --git a/test/changelog-notes/github-changelog-notes.ts b/test/changelog-notes/github-changelog-notes.ts new file mode 100644 index 000000000..43a082dca --- /dev/null +++ b/test/changelog-notes/github-changelog-notes.ts @@ -0,0 +1,121 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import * as nock from 'nock'; +import {describe, it} from 'mocha'; +import {expect} from 'chai'; +import {safeSnapshot} from '../helpers'; +import {PullRequestBody} from '../../src/util/pull-request-body'; +import {Version} from '../../src/version'; +import {GitHubChangelogNotes} from '../../src/changelog-notes/github'; +import {GitHub} from '../../src/github'; + +nock.disableNetConnect(); + +describe('GitHubChangelogNotes', () => { + const commits = [ + { + sha: 'sha1', + message: 'feat: some feature', + files: ['path1/file1.txt'], + type: 'feat', + scope: null, + bareMessage: 'some feature', + notes: [], + references: [], + breaking: false, + }, + { + sha: 'sha2', + message: 'fix!: some bugfix', + files: ['path1/file1.rb'], + type: 'fix', + scope: null, + bareMessage: 'some bugfix', + notes: [{title: 'BREAKING CHANGE', text: 'some bugfix'}], + references: [], + breaking: true, + }, + { + sha: 'sha3', + message: 'docs: some documentation', + files: ['path1/file1.java'], + type: 'docs', + scope: null, + bareMessage: 'some documentation', + notes: [], + references: [], + breaking: false, + }, + ]; + describe('buildNotes', () => { + const notesOptions = { + owner: 'googleapis', + repository: 'java-asset', + version: '1.2.3', + previousTag: 'v1.2.2', + currentTag: 'v1.2.3', + targetBranch: 'main', + }; + let github: GitHub; + beforeEach(async () => { + github = await GitHub.create({ + owner: 'fake-owner', + repo: 'fake-repo', + defaultBranch: 'main', + token: 'fake-token', + }); + nock('https://api.github.com/') + .post('/repos/fake-owner/fake-repo/releases/generate-notes') + .reply(200, { + name: 'Release v1.0.0 is now available!', + body: '##Changes in Release v1.0.0 ... ##Contributors @monalisa', + }); + }); + it('should build release notes from GitHub', async () => { + const changelogNotes = new GitHubChangelogNotes(github); + const notes = await changelogNotes.buildNotes(commits, notesOptions); + expect(notes).to.is.string; + safeSnapshot(notes); + }); + + it('should build parseable notes', async () => { + const notesOptions = { + owner: 'googleapis', + repository: 'java-asset', + version: '1.2.3', + previousTag: 'v1.2.2', + currentTag: 'v1.2.3', + targetBranch: 'main', + }; + const changelogNotes = new GitHubChangelogNotes(github); + const notes = await changelogNotes.buildNotes(commits, notesOptions); + const pullRequestBody = new PullRequestBody([ + { + version: Version.parse('1.2.3'), + notes, + }, + ]); + const pullRequestBodyContent = pullRequestBody.toString(); + const parsedPullRequestBody = PullRequestBody.parse( + pullRequestBodyContent + ); + expect(parsedPullRequestBody).to.not.be.undefined; + expect(parsedPullRequestBody!.releaseData).lengthOf(1); + expect(parsedPullRequestBody!.releaseData[0].version?.toString()).to.eql( + '1.2.3' + ); + }); + }); +}); diff --git a/test/cli.ts b/test/cli.ts index 2b0635368..e1ba0cd1a 100644 --- a/test/cli.ts +++ b/test/cli.ts @@ -839,6 +839,32 @@ describe('CLI', () => { sinon.assert.calledOnce(createPullRequestsStub); }); + it('handles --prerelease-type', async () => { + await parser.parseAsync( + 'release-pr --repo-url=googleapis/release-please-cli --release-type=java-yoshi --prerelease-type=alpha' + ); + + sinon.assert.calledOnceWithExactly(gitHubCreateStub, { + owner: 'googleapis', + repo: 'release-please-cli', + token: undefined, + apiUrl: 'https://api.github.com', + graphqlUrl: 'https://api.github.com', + }); + sinon.assert.calledOnceWithExactly( + fromConfigStub, + fakeGitHub, + 'main', + sinon.match({ + releaseType: 'java-yoshi', + prereleaseType: 'alpha', + }), + sinon.match.any, + undefined + ); + sinon.assert.calledOnce(createPullRequestsStub); + }); + it('handles java --extra-files', async () => { await parser.parseAsync( 'release-pr --repo-url=googleapis/release-please-cli --release-type=java-yoshi --extra-files=foo/bar.java,asdf/qwer.java' diff --git a/test/factories/plugin-factory.ts b/test/factories/plugin-factory.ts index f08d11703..ef78222a4 100644 --- a/test/factories/plugin-factory.ts +++ b/test/factories/plugin-factory.ts @@ -25,6 +25,7 @@ import {LinkedVersions} from '../../src/plugins/linked-versions'; import {ManifestPlugin} from '../../src/plugin'; import {GitHub} from '../../src'; import {GroupPriority} from '../../src/plugins/group-priority'; +import {NodeWorkspace} from '../../src/plugins/node-workspace'; describe('PluginFactory', () => { let github: GitHub; @@ -97,6 +98,20 @@ describe('PluginFactory', () => { expect(plugin).to.not.be.undefined; expect(plugin).instanceof(GroupPriority); }); + it('should build workspace options', () => { + const plugin = buildPlugin({ + github, + type: { + type: 'node-workspace', + updatePeerDependencies: true, + }, + targetBranch: 'target-branch', + repositoryConfig, + manifestPath: '.manifest.json', + }); + expect(plugin).to.not.be.undefined; + expect(plugin).instanceof(NodeWorkspace); + }); }); describe('getPluginTypes', () => { it('should return default types', () => { diff --git a/test/factory.ts b/test/factory.ts index 2253518f0..1de07c1e4 100644 --- a/test/factory.ts +++ b/test/factory.ts @@ -32,6 +32,7 @@ import {DependencyManifest} from '../src/versioning-strategies/dependency-manife import {GitHubChangelogNotes} from '../src/changelog-notes/github'; import {DefaultChangelogNotes} from '../src/changelog-notes/default'; import {Java} from '../src/strategies/java'; +import {PrereleaseVersioningStrategy} from '../src/versioning-strategies/prerelease'; describe('factory', () => { let github: GitHub; @@ -74,6 +75,25 @@ describe('factory', () => { expect(versioningStrategy.bumpMinorPreMajor).to.be.true; expect(versioningStrategy.bumpPatchForMinorPreMajor).to.be.true; }); + it('should build with prerelease type', async () => { + const strategy = await buildStrategy({ + github, + releaseType: 'simple', + bumpMinorPreMajor: true, + bumpPatchForMinorPreMajor: true, + versioning: 'prerelease', + prereleaseType: 'alpha', + }); + expect(strategy).instanceof(Simple); + expect(strategy.versioningStrategy).instanceof( + PrereleaseVersioningStrategy + ); + const versioningStrategy = + strategy.versioningStrategy as PrereleaseVersioningStrategy; + expect(versioningStrategy.bumpMinorPreMajor).to.be.true; + expect(versioningStrategy.bumpPatchForMinorPreMajor).to.be.true; + expect(versioningStrategy.prereleaseType).to.eql('alpha'); + }); it('should throw for unknown type', async () => { try { await buildStrategy({ diff --git a/test/fixtures/commits-since-rebase.json b/test/fixtures/commits-since-rebase.json new file mode 100644 index 000000000..aa1c9091c --- /dev/null +++ b/test/fixtures/commits-since-rebase.json @@ -0,0 +1,88 @@ +{ + "repository": { + "ref": { + "target": { + "history": { + "nodes": [ + { + "associatedPullRequests": { + "nodes": [ + { + "number": 7, + "title": "feat: feature that will be rebase merged", + "baseRefName": "main", + "headRefName": "feature-branch-rebase-merge", + "labels": { + "nodes": [] + }, + "body": "", + "mergeCommit": { + "oid": "b29149f890e6f76ee31ed128585744d4c598924c" + }, + "files": { + "nodes": [] + } + } + ] + }, + "sha": "b29149f890e6f76ee31ed128585744d4c598924c", + "message": "feat: feature-branch-rebase-merge commit 1" + }, + { + "associatedPullRequests": { + "nodes": [ + { + "number": 7, + "title": "feat: feature that will be rebase merged", + "baseRefName": "main", + "headRefName": "feature-branch-rebase-merge", + "labels": { + "nodes": [] + }, + "body": "", + "mergeCommit": { + "oid": "b29149f890e6f76ee31ed128585744d4c598924c" + }, + "files": { + "nodes": [] + } + } + ] + }, + "sha": "27d7d7232e2e312d1380e906984f0823f5decf61", + "message": "feat: feature-branch-rebase-merge commit 2" + }, + { + "associatedPullRequests": { + "nodes": [ + { + "number": 6, + "title": "feat: other pr", + "baseRefName": "main", + "headRefName": "feature-branch-other", + "labels": { + "nodes": [] + }, + "body": "", + "mergeCommit": { + "oid": "2b4e0b3be2e231cd87cc44c411bd8f84b4587ab5" + }, + "files": { + "nodes": [] + } + } + ] + }, + "sha": "2b4e0b3be2e231cd87cc44c411bd8f84b4587ab5", + "message": "fix: feature-branch-other" + } + ], + "pageInfo": { + "hasNextPage": false, + "endCursor": "e6daec403626c9987c7af0d97b34f324cd84320a 12" + } + } + } + } + } +} diff --git a/test/fixtures/manifest/config/exclude-paths.json b/test/fixtures/manifest/config/exclude-paths.json new file mode 100644 index 000000000..0fbdfbc9c --- /dev/null +++ b/test/fixtures/manifest/config/exclude-paths.json @@ -0,0 +1,15 @@ +{ + "release-type": "simple", + "label": "custom: pending", + "release-label": "custom: tagged", + "exclude-paths": ["path-ignore"], + "packages": { + ".": { + "component": "root", + "exclude-paths": ["path-root-ignore"] + }, + "node-lib": { + "component": "node-lib" + } + } +} diff --git a/test/fixtures/manifest/config/node-workspace-plugins.json b/test/fixtures/manifest/config/node-workspace-plugins.json new file mode 100644 index 000000000..e282374db --- /dev/null +++ b/test/fixtures/manifest/config/node-workspace-plugins.json @@ -0,0 +1,21 @@ +{ + "release-type": "node", + "plugins": [ + { + "type": "node-workspace", + "considerAllArtifacts": true, + "updatePeerDependencies": true + } + ], + "packages": { + "pkg1": { + "component": "pkg1" + }, + "pkg2": { + "component": "pkg2" + }, + "pkg3": { + "component": "pkg3" + } + } +} diff --git a/test/fixtures/plugins/node-workspace/node5/package.json b/test/fixtures/plugins/node-workspace/node5/package.json new file mode 100644 index 000000000..ce053888b --- /dev/null +++ b/test/fixtures/plugins/node-workspace/node5/package.json @@ -0,0 +1,8 @@ +{ + "name": "@here/pkgE", + "version": "1.0.0", + "dependencies": { + "@here/pkgA": "workspace:^", + "anotherExternal": "^4.3.1" + } +} \ No newline at end of file diff --git a/test/fixtures/release-notes/multiple-with-root.txt b/test/fixtures/release-notes/multiple-with-root.txt new file mode 100644 index 000000000..a6386bbbd --- /dev/null +++ b/test/fixtures/release-notes/multiple-with-root.txt @@ -0,0 +1,44 @@ +:robot: I have created a release \*beep\* \*boop\* +--- +
3.3.0 + + +### Features + +* upgrade to upgrade to gcf-utils@12 ([#2262](https://www.github.com/googleapis/repo-automation-bots/issues/2262)) ([bd04376](https://www.github.com/googleapis/repo-automation-bots/commit/bd043767ae59a4eed450f1d18741111dc4c3f8e8)) +* **@google-automations/bot-config-utils:** upgrade to gcf-utils@12 ([#2262](https://www.github.com/googleapis/repo-automation-bots/issues/2262)) ([bd04376](https://www.github.com/googleapis/repo-automation-bots/commit/bd043767ae59a4eed450f1d18741111dc4c3f8e8)) +* **@google-automations/label-utils:** upgrade to gcf-utils@12 ([#2262](https://www.github.com/googleapis/repo-automation-bots/issues/2262)) ([bd04376](https://www.github.com/googleapis/repo-automation-bots/commit/bd043767ae59a4eed450f1d18741111dc4c3f8e8)) +* **@google-automations/object-selector:** upgrade to gcf-utils@12 ([#2262](https://www.github.com/googleapis/repo-automation-bots/issues/2262)) ([bd04376](https://www.github.com/googleapis/repo-automation-bots/commit/bd043767ae59a4eed450f1d18741111dc4c3f8e8)) +* **@google-automations/datastore-lock:** upgrade to gcf-utils@12 ([#2262](https://www.github.com/googleapis/repo-automation-bots/issues/2262)) ([bd04376](https://www.github.com/googleapis/repo-automation-bots/commit/bd043767ae59a4eed450f1d18741111dc4c3f8e8)) +
+
@google-automations/bot-config-utils: 3.2.0 + + +### Features + +* upgrade to gcf-utils@12 ([#2262](https://www.github.com/googleapis/repo-automation-bots/issues/2262)) ([bd04376](https://www.github.com/googleapis/repo-automation-bots/commit/bd043767ae59a4eed450f1d18741111dc4c3f8e8)) +
+
@google-automations/label-utils: 1.1.0 + + +### Features + +* upgrade to gcf-utils@12 ([#2262](https://www.github.com/googleapis/repo-automation-bots/issues/2262)) ([bd04376](https://www.github.com/googleapis/repo-automation-bots/commit/bd043767ae59a4eed450f1d18741111dc4c3f8e8)) +
+
@google-automations/object-selector: 1.1.0 + + +### Features + +* upgrade to gcf-utils@12 ([#2262](https://www.github.com/googleapis/repo-automation-bots/issues/2262)) ([bd04376](https://www.github.com/googleapis/repo-automation-bots/commit/bd043767ae59a4eed450f1d18741111dc4c3f8e8)) +
+
@google-automations/datastore-lock: 2.1.0 + + +### Features + +* upgrade to gcf-utils@12 ([#2262](https://www.github.com/googleapis/repo-automation-bots/issues/2262)) ([bd04376](https://www.github.com/googleapis/repo-automation-bots/commit/bd043767ae59a4eed450f1d18741111dc4c3f8e8)) +
+ + +This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). \ No newline at end of file diff --git a/test/fixtures/release-notes/single-prerelease.txt b/test/fixtures/release-notes/single-prerelease.txt new file mode 100644 index 000000000..aa57225bc --- /dev/null +++ b/test/fixtures/release-notes/single-prerelease.txt @@ -0,0 +1,20 @@ +:robot: I have created a release \*beep\* \*boop\* +--- +### [3.2.7-pre.0](https://www.github.com/googleapis/java-asset/compare/v3.2.6...v3.2.7-pre.0) (2021-10-20) + + +### Dependencies + +* update dependency com.google.api.grpc:proto-google-cloud-orgpolicy-v1 to v2.0.6 ([#980](https://www.github.com/googleapis/java-asset/issues/980)) ([710bb59](https://www.github.com/googleapis/java-asset/commit/710bb59c17da57f1104a84f8e44ada7c7fc9a59f)) +* update dependency com.google.api.grpc:proto-google-cloud-os-config-v1 to v2.2.2 ([#981](https://www.github.com/googleapis/java-asset/issues/981)) ([5495310](https://www.github.com/googleapis/java-asset/commit/5495310b7abf3a3dfa6878fc20e12ac3f268c93f)) +* update dependency com.google.api.grpc:proto-google-cloud-pubsub-v1 to v1.96.7 ([#982](https://www.github.com/googleapis/java-asset/issues/982)) ([c93a011](https://www.github.com/googleapis/java-asset/commit/c93a01135432ad2094550be6d03c05e7efde56ac)) +* update dependency com.google.api.grpc:proto-google-identity-accesscontextmanager-v1 to v1.2.3 ([#983](https://www.github.com/googleapis/java-asset/issues/983)) ([4eb1b14](https://www.github.com/googleapis/java-asset/commit/4eb1b14f1915ec22d2edb002341fa0eb361b70d8)) +* update dependency com.google.cloud:google-cloud-bigquery to v2.3.1 ([#984](https://www.github.com/googleapis/java-asset/issues/984)) ([5ba60b8](https://www.github.com/googleapis/java-asset/commit/5ba60b8916dfa066b76766bb650bf552ce05838b)) +* update dependency com.google.cloud:google-cloud-bigquery to v2.3.2 ([#991](https://www.github.com/googleapis/java-asset/issues/991)) ([cc6183e](https://www.github.com/googleapis/java-asset/commit/cc6183e49786e312a8af78026c7981f76f46fdd8)) +* update dependency com.google.cloud:google-cloud-core to v2.2.0 ([#988](https://www.github.com/googleapis/java-asset/issues/988)) ([2e07803](https://www.github.com/googleapis/java-asset/commit/2e0780320ed89e78f4c99b374469f2be9b828588)) +* update dependency com.google.cloud:google-cloud-shared-dependencies to v2.4.0 ([#989](https://www.github.com/googleapis/java-asset/issues/989)) ([0be3e21](https://www.github.com/googleapis/java-asset/commit/0be3e2170158450927075faf601f43a271a4443a)) +* update dependency com.google.cloud:google-cloud-storage to v2.1.9 ([#987](https://www.github.com/googleapis/java-asset/issues/987)) ([ea85100](https://www.github.com/googleapis/java-asset/commit/ea8510036db7990c47c7471f6d6ce899a83ec456)) +--- + + +This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). \ No newline at end of file diff --git a/test/fixtures/strategies/java-yoshi/.repo-metadata.json b/test/fixtures/strategies/java-yoshi/.repo-metadata.json new file mode 100644 index 000000000..45a20a0e5 --- /dev/null +++ b/test/fixtures/strategies/java-yoshi/.repo-metadata.json @@ -0,0 +1,17 @@ +{ + "api_shortname": "appengine", + "name_pretty": "App Engine Admin API", + "product_documentation": "https://cloud.google.com/appengine/docs/admin-api/", + "api_description": "you to manage your App Engine applications.", + "client_documentation": "https://cloud.google.com/java/docs/reference/google-cloud-appengine-admin/latest/overview", + "release_level": "stable", + "transport": "grpc", + "language": "java", + "repo": "googleapis/google-cloud-java", + "repo_short": "java-appengine-admin", + "distribution_name": "cloud.google.com:foo", + "api_id": "appengine.googleapis.com", + "library_type": "GAPIC_AUTO", + "requires_billing": true, + "codeowner_team": "@googleapis/aap-dpes" +} diff --git a/test/fixtures/strategies/java-yoshi/changelog.json b/test/fixtures/strategies/java-yoshi/changelog.json new file mode 100644 index 000000000..046955d4b --- /dev/null +++ b/test/fixtures/strategies/java-yoshi/changelog.json @@ -0,0 +1,3 @@ +{ + "entries": [] +} diff --git a/test/fixtures/strategies/node/changelog.json b/test/fixtures/strategies/node/changelog.json new file mode 100644 index 000000000..7e3bac35b --- /dev/null +++ b/test/fixtures/strategies/node/changelog.json @@ -0,0 +1,4 @@ +{ + "repository": "google-cloud-node", + "entries": [] +} diff --git a/test/fixtures/strategies/python/changelog.json b/test/fixtures/strategies/python/changelog.json new file mode 100644 index 000000000..32d6e21aa --- /dev/null +++ b/test/fixtures/strategies/python/changelog.json @@ -0,0 +1,4 @@ +{ + "repository": "google-cloud-foo", + "entries": [] +} diff --git a/test/fixtures/strategies/python/setup.py b/test/fixtures/strategies/python/setup.py new file mode 100644 index 000000000..cfe2b4b2e --- /dev/null +++ b/test/fixtures/strategies/python/setup.py @@ -0,0 +1,78 @@ +# Copyright 2018 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import io +import os + +import setuptools + +name = "google-cloud-automl" +description = "Cloud AutoML API client library" +version = "0.5.0" +release_status = "Development Status :: 3 - Alpha" +dependencies = [ + "google-api-core[grpc] >= 1.14.0, < 2.0.0dev", + 'enum34; python_version < "3.4"', +] +extras = { + "pandas": ["pandas>=0.24.0"], + "storage": ["google-cloud-storage >= 1.18.0, < 2.0.0dev"], +} + +package_root = os.path.abspath(os.path.dirname(__file__)) + +readme_filename = os.path.join(package_root, "README.rst") +with io.open(readme_filename, encoding="utf-8") as readme_file: + readme = readme_file.read() + +packages = [ + package for package in setuptools.find_packages() if package.startswith("google") +] + +namespaces = ["google"] +if "google.cloud" in packages: + namespaces.append("google.cloud") + +setuptools.setup( + name=name, + version=version, + description=description, + long_description=readme, + author="Google LLC", + author_email="googleapis-packages@oogle.com", + license="Apache 2.0", + url="https://github.com/GoogleCloudPlatform/google-cloud-python", + classifiers=[ + release_status, + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python", + "Programming Language :: Python :: 2", + "Programming Language :: Python :: 2.7", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Operating System :: OS Independent", + "Topic :: Internet", + ], + platforms="Posix; MacOS X; Windows", + packages=packages, + namespace_packages=namespaces, + install_requires=dependencies, + extras_require=extras, + python_requires=">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*", + include_package_data=True, + zip_safe=False, +) \ No newline at end of file diff --git a/test/fixtures/strategies/sfdx/sfdx-project.json b/test/fixtures/strategies/sfdx/sfdx-project.json new file mode 100644 index 000000000..6f2e8b638 --- /dev/null +++ b/test/fixtures/strategies/sfdx/sfdx-project.json @@ -0,0 +1,9 @@ +{ + "packageDirectories": [ + { + "default": true, + "versionNumber": "1.0.0.NEXT" + } + ], + "name": "sfdx-test-repo" +} diff --git a/test/github.ts b/test/github.ts index 35e6b1925..ef787852f 100644 --- a/test/github.ts +++ b/test/github.ts @@ -546,6 +546,39 @@ describe('GitHub', () => { snapshot(commitsSinceSha); req.done(); }); + + it('backfills commit files for pull requests rebased and merged', async () => { + const graphql = JSON.parse( + readFileSync(resolve(fixturesPath, 'commits-since-rebase.json'), 'utf8') + ); + req + .post('/graphql') + .reply(200, { + data: graphql, + }) + .get( + '/repos/fake/fake/commits/b29149f890e6f76ee31ed128585744d4c598924c' + ) + .reply(200, {files: [{filename: 'abc'}]}) + .get( + '/repos/fake/fake/commits/27d7d7232e2e312d1380e906984f0823f5decf61' + ) + .reply(200, {files: [{filename: 'def'}]}); + const targetBranch = 'main'; + const commitsSinceSha = await github.commitsSince( + targetBranch, + commit => { + // this commit is the 3rd most recent + return commit.sha === '2b4e0b3be2e231cd87cc44c411bd8f84b4587ab5'; + }, + {backfillFiles: true} + ); + expect(commitsSinceSha.length).to.eql(2); + expect(commitsSinceSha[0].files).to.eql(['abc']); + expect(commitsSinceSha[1].files).to.eql(['def']); + snapshot(commitsSinceSha); + req.done(); + }); }); describe('mergeCommitIterator', () => { @@ -670,13 +703,6 @@ describe('GitHub', () => { }); describe('createRelease', () => { - let githubCreateReleaseSpy: sinon.SinonSpy; - beforeEach(async () => { - githubCreateReleaseSpy = sandbox.spy( - github['octokit'].repos, - 'createRelease' - ); - }); it('should create a release with a package prefix', async () => { req .post('/repos/fake/fake/releases', body => { @@ -699,16 +725,6 @@ describe('GitHub', () => { notes: 'Some release notes', }); req.done(); - sinon.assert.calledOnceWithExactly(githubCreateReleaseSpy, { - name: undefined, - owner: 'fake', - repo: 'fake', - tag_name: 'v1.2.3', - body: 'Some release notes', - target_commitish: 'abc123', - draft: false, - prerelease: false, - }); expect(release).to.not.be.undefined; expect(release.id).to.eql(123456); expect(release.tagName).to.eql('v1.2.3'); @@ -804,16 +820,6 @@ describe('GitHub', () => { {draft: true} ); req.done(); - sinon.assert.calledOnceWithExactly(githubCreateReleaseSpy, { - name: undefined, - owner: 'fake', - repo: 'fake', - tag_name: 'v1.2.3', - body: 'Some release notes', - target_commitish: 'abc123', - draft: true, - prerelease: false, - }); expect(release).to.not.be.undefined; expect(release.tagName).to.eql('v1.2.3'); expect(release.sha).to.eql('abc123'); @@ -844,16 +850,6 @@ describe('GitHub', () => { {prerelease: true} ); req.done(); - sinon.assert.calledOnceWithExactly(githubCreateReleaseSpy, { - name: undefined, - owner: 'fake', - repo: 'fake', - tag_name: 'v1.2.3', - body: 'Some release notes', - target_commitish: 'abc123', - draft: false, - prerelease: true, - }); expect(release.id).to.eql(123456); expect(release.tagName).to.eql('v1.2.3'); expect(release.sha).to.eql('abc123'); diff --git a/test/helpers.ts b/test/helpers.ts index 5544ca12c..74ac886da 100644 --- a/test/helpers.ts +++ b/test/helpers.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -import {readFileSync, readdirSync, statSync} from 'fs'; +import {readFileSync, readdirSync, statSync, existsSync} from 'fs'; import {resolve, posix} from 'path'; import * as crypto from 'crypto'; import * as sinon from 'sinon'; @@ -20,7 +20,11 @@ import * as snapshot from 'snap-shot-it'; import * as suggester from 'code-suggester'; import {CreatePullRequestUserOptions} from 'code-suggester/build/src/types'; import {Octokit} from '@octokit/rest'; -import {Commit} from '../src/commit'; +import { + Commit, + ConventionalCommit, + parseConventionalCommits, +} from '../src/commit'; import {GitHub, GitHubTag, GitHubRelease} from '../src/github'; import {Update} from '../src/update'; import {expect} from 'chai'; @@ -110,6 +114,35 @@ export function readPOJO(name: string): object { return JSON.parse(content); } +/** + * Reads a fixture file as a string or returns empty string if the fixture + * does not exist. + */ +export function readFixture(fixturesPath: string, fixture: string): string { + const file = resolve(fixturesPath, fixture); + if (!existsSync(file)) { + return ''; + } + return readFileSync(resolve(fixturesPath, fixture), 'utf8'); +} + +export function buildMockConventionalCommit( + message: string, + files: string[] = [] +): ConventionalCommit[] { + return parseConventionalCommits([ + { + // Ensure SHA is same on Windows with replace: + sha: crypto + .createHash('md5') + .update(message.replace(/\r\n/g, '\n')) + .digest('hex'), + message, + files: files, + }, + ]); +} + export function buildMockCommit(message: string, files: string[] = []): Commit { return { // Ensure SHA is same on Windows with replace: @@ -121,6 +154,7 @@ export function buildMockCommit(message: string, files: string[] = []): Commit { files: files, }; } + export function buildGitHubFileContent( fixturesPath: string, fixture: string @@ -376,6 +410,19 @@ export function mockTags( return sandbox.stub(github, 'tagIterator').returns(fakeGenerator()); } +export function mockPullRequests( + sandbox: sinon.SinonSandbox, + github: GitHub, + pullRequests: PullRequest[] +): sinon.SinonStub { + async function* fakeGenerator() { + for (const pullRequest of pullRequests) { + yield pullRequest; + } + } + return sandbox.stub(github, 'pullRequestIterator').returns(fakeGenerator()); +} + export function mockReleaseData(count: number): ReleaseData[] { const releaseData: ReleaseData[] = []; const version = Version.parse('1.2.3'); diff --git a/test/manifest.ts b/test/manifest.ts index a5b8b6048..31beb2880 100644 --- a/test/manifest.ts +++ b/test/manifest.ts @@ -504,6 +504,37 @@ describe('Manifest', () => { 'lang: nodejs', ]); }); + it('should read exclude paths from manifest', async () => { + const getFileContentsStub = sandbox.stub( + github, + 'getFileContentsOnBranch' + ); + getFileContentsStub + .withArgs('release-please-config.json', 'main') + .resolves( + buildGitHubFileContent( + fixturesPath, + 'manifest/config/exclude-paths.json' + ) + ) + .withArgs('.release-please-manifest.json', 'main') + .resolves( + buildGitHubFileContent( + fixturesPath, + 'manifest/versions/versions.json' + ) + ); + const manifest = await Manifest.fromManifest( + github, + github.repository.defaultBranch + ); + expect(manifest.repositoryConfig['.'].excludePaths).to.deep.equal([ + 'path-root-ignore', + ]); + expect(manifest.repositoryConfig['node-lib'].excludePaths).to.deep.equal([ + 'path-ignore', + ]); + }); it('should build simple plugins from manifest', async () => { const getFileContentsStub = sandbox.stub( github, @@ -742,6 +773,36 @@ describe('Manifest', () => { ).to.eql('default'); }); + it('should read plugins from manifest', async () => { + const getFileContentsStub = sandbox.stub( + github, + 'getFileContentsOnBranch' + ); + getFileContentsStub + .withArgs('release-please-config.json', 'main') + .resolves( + buildGitHubFileContent( + fixturesPath, + 'manifest/config/node-workspace-plugins.json' + ) + ) + .withArgs('.release-please-manifest.json', 'main') + .resolves( + buildGitHubFileContent( + fixturesPath, + 'manifest/versions/versions.json' + ) + ); + const manifest = await Manifest.fromManifest( + github, + github.repository.defaultBranch + ); + expect(manifest.plugins).lengthOf(1); + expect(manifest.plugins[0]).instanceOf(NodeWorkspace); + const workspacePlugin = manifest.plugins[0] as NodeWorkspace; + expect(workspacePlugin.updatePeerDependencies).to.be.true; + }); + it('should throw a configuration error for a missing manifest config', async () => { const getFileContentsStub = sandbox.stub( github, @@ -1631,6 +1692,28 @@ describe('Manifest', () => { 'No beep boop for you' ); }); + + it('allows customizing pull request footer', async () => { + const manifest = new Manifest( + github, + 'main', + { + '.': { + releaseType: 'simple', + pullRequestFooter: 'No reminder for you', + }, + }, + { + '.': Version.parse('1.0.0'), + } + ); + const pullRequests = await manifest.buildPullRequests(); + expect(pullRequests).lengthOf(1); + const pullRequest = pullRequests[0]; + expect(pullRequest.body.footer.toString()).to.eql( + 'No reminder for you' + ); + }); }); it('should find the component from config', async () => { @@ -1697,90 +1780,123 @@ describe('Manifest', () => { ); }); - it('should handle multiple package repository', async () => { - mockReleases(sandbox, github, [ - { - id: 123456, - sha: 'abc123', - tagName: 'pkg1-v1.0.0', - url: 'https://github.com/fake-owner/fake-repo/releases/tag/pkg1-v1.0.0', - }, - { - id: 654321, - sha: 'def234', - tagName: 'pkg2-v0.2.3', - url: 'https://github.com/fake-owner/fake-repo/releases/tag/pkg2-v0.2.3', - }, - ]); - mockCommits(sandbox, github, [ - { - sha: 'aaaaaa', - message: 'fix: some bugfix', - files: ['path/a/foo'], - }, - { - sha: 'abc123', - message: 'chore: release main', - files: [], - pullRequest: { - headBranchName: 'release-please/branches/main', - baseBranchName: 'main', - number: 123, - title: 'chore: release main', - body: '', - labels: [], - files: [], + describe('with multiple packages', () => { + beforeEach(() => { + mockReleases(sandbox, github, [ + { + id: 123456, sha: 'abc123', + tagName: 'pkg1-v1.0.0', + url: 'https://github.com/fake-owner/fake-repo/releases/tag/pkg1-v1.0.0', }, - }, - { - sha: 'bbbbbb', - message: 'fix: some bugfix', - files: ['path/b/foo'], - }, - { - sha: 'cccccc', - message: 'fix: some bugfix', - files: ['path/a/foo'], - }, - { - sha: 'def234', - message: 'chore: release main', - files: [], - pullRequest: { - headBranchName: 'release-please/branches/main', - baseBranchName: 'main', - number: 123, - title: 'chore: release main', - body: '', - labels: [], + { + id: 654321, + sha: 'def234', + tagName: 'pkg2-v0.2.3', + url: 'https://github.com/fake-owner/fake-repo/releases/tag/pkg2-v0.2.3', + }, + ]); + mockCommits(sandbox, github, [ + { + sha: 'aaaaaa', + message: 'fix: some bugfix', + files: ['path/a/foo'], + }, + { + sha: 'abc123', + message: 'chore: release main', files: [], + pullRequest: { + headBranchName: 'release-please/branches/main', + baseBranchName: 'main', + number: 123, + title: 'chore: release main', + body: '', + labels: [], + files: [], + sha: 'abc123', + }, + }, + { + sha: 'bbbbbb', + message: 'fix: some bugfix', + files: ['path/b/foo'], + }, + { + sha: 'cccccc', + message: 'fix: some bugfix', + files: ['path/a/foo'], + }, + { sha: 'def234', + message: 'chore: release main', + files: [], + pullRequest: { + headBranchName: 'release-please/branches/main', + baseBranchName: 'main', + number: 123, + title: 'chore: release main', + body: '', + labels: [], + files: [], + sha: 'def234', + }, }, - }, - ]); - const manifest = new Manifest( - github, - 'main', - { - 'path/a': { - releaseType: 'simple', - component: 'pkg1', + ]); + }); + it('should handle multiple package repository', async () => { + const manifest = new Manifest( + github, + 'main', + { + 'path/a': { + releaseType: 'simple', + component: 'pkg1', + }, + 'path/b': { + releaseType: 'simple', + component: 'pkg2', + }, }, - 'path/b': { - releaseType: 'simple', - component: 'pkg2', + { + 'path/a': Version.parse('1.0.0'), + 'path/b': Version.parse('0.2.3'), + } + ); + const pullRequests = await manifest.buildPullRequests(); + expect(pullRequests).lengthOf(1); + expect(pullRequests[0].labels).to.eql(['autorelease: pending']); + snapshot(dateSafe(pullRequests[0].body.toString())); + }); + + it('should handle pull request header/footer with multiple packages', async () => { + const manifest = new Manifest( + github, + 'main', + { + 'path/a': { + releaseType: 'simple', + component: 'pkg1', + pullRequestHeader: 'Header from pkg1', + }, + 'path/b': { + releaseType: 'simple', + component: 'pkg2', + pullRequestHeader: 'Header from pkg2', + pullRequestFooter: 'Footer from pkg2', + }, }, - }, - { - 'path/a': Version.parse('1.0.0'), - 'path/b': Version.parse('0.2.3'), - } - ); - const pullRequests = await manifest.buildPullRequests(); - expect(pullRequests).lengthOf(1); - expect(pullRequests[0].labels).to.eql(['autorelease: pending']); - snapshot(dateSafe(pullRequests[0].body.toString())); + { + 'path/a': Version.parse('1.0.0'), + 'path/b': Version.parse('0.2.3'), + } + ); + const pullRequests = await manifest.buildPullRequests(); + expect(pullRequests).lengthOf(1); + const pullRequest = pullRequests[0]; + expect(pullRequest.body.header.toString()).to.eql('Header from pkg1'); + expect(pullRequest.body.footer.toString()).to.eql('Footer from pkg2'); + }); }); it('should allow creating multiple pull requests', async () => { @@ -2724,7 +2840,7 @@ describe('Manifest', () => { mockCommits(sandbox, github, [ { sha: 'aaaaaa', - message: 'fix: some bugfix', + message: 'fix: some bugfix\nfix:another fix', files: ['path/a/foo'], }, { @@ -2854,14 +2970,13 @@ describe('Manifest', () => { }); it('should apply plugin hook "processCommits"', async () => { - const mockPlugin = sandbox.createStubInstance(SentenceCase); - mockPlugin.run.returnsArg(0); - mockPlugin.preconfigure.returnsArg(0); - mockPlugin.processCommits.returnsArg(0); + const spyPlugin = sinon.spy(new SentenceCase(github, 'main', {})); sandbox .stub(pluginFactory, 'buildPlugin') .withArgs(sinon.match.has('type', 'sentence-case')) - .returns(mockPlugin); + // TS compiler is having issues with sinon.spy. + // eslint-disable-next-line @typescript-eslint/no-explicit-any + .returns(spyPlugin as any as InstanceType); const manifest = new Manifest( github, 'main', @@ -2881,7 +2996,34 @@ describe('Manifest', () => { ); const pullRequests = await manifest.buildPullRequests(); expect(pullRequests).not.empty; - sinon.assert.calledOnce(mockPlugin.processCommits); + // This assertion verifies that conventional commit parsing + // was applied before calling the processCommits plugin hook: + sinon.assert.calledWith(spyPlugin.processCommits, [ + { + sha: 'aaaaaa', + message: 'fix: Another fix', + files: ['path/a/foo'], + pullRequest: undefined, + type: 'fix', + scope: null, + bareMessage: 'Another fix', + notes: [], + references: [], + breaking: false, + }, + { + sha: 'aaaaaa', + message: 'fix: Some bugfix', + files: ['path/a/foo'], + pullRequest: undefined, + type: 'fix', + scope: null, + bareMessage: 'Some bugfix', + notes: [], + references: [], + breaking: false, + }, + ]); }); }); @@ -4996,6 +5138,139 @@ describe('Manifest', () => { expect(releases[0].path).to.eql('.'); }); + it('should handle customized group pull request title', async () => { + mockPullRequests( + github, + [], + [ + { + headBranchName: 'release-please/branches/main', + baseBranchName: 'main', + number: 1234, + title: 'chore: release v3.3.0', + body: pullRequestBody('release-notes/multiple-with-root.txt'), + labels: ['autorelease: pending'], + files: [ + 'package.json', + 'packages/bot-config-utils/package.json', + 'packages/label-utils/package.json', + 'packages/object-selector/package.json', + 'packages/datastore-lock/package.json', + ], + sha: 'abc123', + }, + ] + ); + const getFileContentsStub = sandbox.stub( + github, + 'getFileContentsOnBranch' + ); + getFileContentsStub + .withArgs('package.json', 'main') + .resolves( + buildGitHubFileRaw(JSON.stringify({name: '@google-automations/all'})) + ) + .withArgs('packages/bot-config-utils/package.json', 'main') + .resolves( + buildGitHubFileRaw( + JSON.stringify({name: '@google-automations/bot-config-utils'}) + ) + ) + .withArgs('packages/label-utils/package.json', 'main') + .resolves( + buildGitHubFileRaw( + JSON.stringify({name: '@google-automations/label-utils'}) + ) + ) + .withArgs('packages/object-selector/package.json', 'main') + .resolves( + buildGitHubFileRaw( + JSON.stringify({name: '@google-automations/object-selector'}) + ) + ) + .withArgs('packages/datastore-lock/package.json', 'main') + .resolves( + buildGitHubFileRaw( + JSON.stringify({name: '@google-automations/datastore-lock'}) + ) + ); + const manifest = new Manifest( + github, + 'main', + { + '.': { + releaseType: 'node', + component: '@google-automations/all', + includeComponentInTag: false, + }, + 'packages/bot-config-utils': { + releaseType: 'node', + }, + 'packages/label-utils': { + releaseType: 'node', + }, + 'packages/object-selector': { + releaseType: 'node', + }, + 'packages/datastore-lock': { + releaseType: 'node', + }, + }, + { + '.': Version.parse('3.2.0'), + 'packages/bot-config-utils': Version.parse('3.1.4'), + 'packages/label-utils': Version.parse('1.0.1'), + 'packages/object-selector': Version.parse('1.0.2'), + 'packages/datastore-lock': Version.parse('2.0.0'), + }, + { + groupPullRequestTitlePattern: 'chore: release v${version}', + } + ); + const releases = await manifest.buildReleases(); + expect(releases).lengthOf(5); + // 3.3.0 + expect(releases[0].tag.toString()).to.eql('v3.3.0'); + expect(releases[0].sha).to.eql('abc123'); + expect(releases[0].notes) + .to.be.a('string') + .and.satisfy((msg: string) => msg.startsWith('### Features')); + expect(releases[0].path).to.eql('.'); + expect(releases[0].name).to.eql('v3.3.0'); + // @google-automations/bot-config-utils: 3.2.0 + expect(releases[1].tag.toString()).to.eql('bot-config-utils-v3.2.0'); + expect(releases[1].sha).to.eql('abc123'); + expect(releases[1].notes) + .to.be.a('string') + .and.satisfy((msg: string) => msg.startsWith('### Features')); + expect(releases[1].path).to.eql('packages/bot-config-utils'); + expect(releases[1].name).to.eql('bot-config-utils: v3.2.0'); + // @google-automations/label-utils: 1.1.0 + expect(releases[2].tag.toString()).to.eql('label-utils-v1.1.0'); + expect(releases[2].sha).to.eql('abc123'); + expect(releases[2].notes) + .to.be.a('string') + .and.satisfy((msg: string) => msg.startsWith('### Features')); + expect(releases[2].path).to.eql('packages/label-utils'); + expect(releases[2].name).to.eql('label-utils: v1.1.0'); + // @google-automations/object-selector: 1.1.0 + expect(releases[3].tag.toString()).to.eql('object-selector-v1.1.0'); + expect(releases[3].sha).to.eql('abc123'); + expect(releases[3].notes) + .to.be.a('string') + .and.satisfy((msg: string) => msg.startsWith('### Features')); + expect(releases[3].path).to.eql('packages/object-selector'); + expect(releases[3].name).to.eql('object-selector: v1.1.0'); + // @google-automations/datastore-lock: 2.1.0 + expect(releases[4].tag.toString()).to.eql('datastore-lock-v2.1.0'); + expect(releases[4].sha).to.eql('abc123'); + expect(releases[4].notes) + .to.be.a('string') + .and.satisfy((msg: string) => msg.startsWith('### Features')); + expect(releases[4].path).to.eql('packages/datastore-lock'); + expect(releases[4].name).to.eql('datastore-lock: v2.1.0'); + }); + it('should skip component releases for non-component configs', async () => { mockPullRequests( github, @@ -5059,6 +5334,7 @@ describe('Manifest', () => { '[HOTFIX] - chore${scope}: release${component} ${version}', packageName: 'my-package-name', includeComponentInTag: false, + prerelease: undefined, }, }, { diff --git a/test/plugins/cargo-workspace.ts b/test/plugins/cargo-workspace.ts index 13333f976..65f46ad22 100644 --- a/test/plugins/cargo-workspace.ts +++ b/test/plugins/cargo-workspace.ts @@ -34,6 +34,8 @@ import snapshot = require('snap-shot-it'); import {RawContent} from '../../src/updaters/raw-content'; import {CargoToml} from '../../src/updaters/rust/cargo-toml'; import {parseCargoManifest} from '../../src/updaters/rust/common'; +import {ConfigurationError} from '../../src/errors'; +import assert = require('assert'); const sandbox = sinon.createSandbox(); const fixturesPath = './test/fixtures/plugins/cargo-workspace'; @@ -120,6 +122,10 @@ describe('CargoWorkspace plugin', () => { releaseType: 'rust', }, }); + sandbox + .stub(github, 'findFilesByGlobAndRef') + .withArgs('packages/rustA', 'main') + .resolves(['packages/rustA']); const newCandidates = await plugin.run(candidates); expect(newCandidates).lengthOf(2); const rustCandidate = newCandidates.find( @@ -166,6 +172,65 @@ describe('CargoWorkspace plugin', () => { ], ], }); + sandbox + .stub(github, 'findFilesByGlobAndRef') + .withArgs('packages/rustA', 'main') + .resolves(['packages/rustA']) + .withArgs('packages/rustD', 'main') + .resolves(['packages/rustD']); + plugin = new CargoWorkspace(github, 'main', { + 'packages/rustA': { + releaseType: 'rust', + }, + 'packages/rustD': { + releaseType: 'rust', + }, + }); + const newCandidates = await plugin.run(candidates); + expect(newCandidates).lengthOf(1); + const rustCandidate = newCandidates.find( + candidate => candidate.config.releaseType === 'rust' + ); + expect(rustCandidate).to.not.be.undefined; + const updates = rustCandidate!.pullRequest.updates; + assertHasUpdate(updates, 'packages/rustA/Cargo.toml'); + assertHasUpdate(updates, 'packages/rustD/Cargo.toml'); + snapshot(dateSafe(rustCandidate!.pullRequest.body.toString())); + }); + it('handles glob paths', async () => { + const candidates: CandidateReleasePullRequest[] = [ + buildMockCandidatePullRequest('packages/rustA', 'rust', '1.1.2', { + component: '@here/pkgA', + updates: [ + buildMockPackageUpdate( + 'packages/rustA/Cargo.toml', + 'packages/rustA/Cargo.toml' + ), + ], + }), + buildMockCandidatePullRequest('packages/rustD', 'rust', '4.4.5', { + component: '@here/pkgD', + updates: [ + buildMockPackageUpdate( + 'packages/rustD/Cargo.toml', + 'packages/rustD/Cargo.toml' + ), + ], + }), + ]; + stubFilesFromFixtures({ + sandbox, + github, + fixturePath: fixturesPath, + files: ['packages/rustA/Cargo.toml', 'packages/rustD/Cargo.toml'], + flatten: false, + targetBranch: 'main', + inlineFiles: [['Cargo.toml', '[workspace]\nmembers = ["packages/*"]']], + }); + sandbox + .stub(github, 'findFilesByGlobAndRef') + .withArgs('packages/*', 'main') + .resolves(['packages/rustA', 'packages/rustD']); plugin = new CargoWorkspace(github, 'main', { 'packages/rustA': { releaseType: 'rust', @@ -221,6 +286,18 @@ describe('CargoWorkspace plugin', () => { flatten: false, targetBranch: 'main', }); + sandbox + .stub(github, 'findFilesByGlobAndRef') + .withArgs('packages/rustA', 'main') + .resolves(['packages/rustA']) + .withArgs('packages/rustB', 'main') + .resolves(['packages/rustB']) + .withArgs('packages/rustC', 'main') + .resolves(['packages/rustC']) + .withArgs('packages/rustD', 'main') + .resolves(['packages/rustD']) + .withArgs('packages/rustE', 'main') + .resolves(['packages/rustE']); const newCandidates = await plugin.run(candidates); expect(newCandidates).lengthOf(1); const rustCandidate = newCandidates.find( @@ -272,6 +349,18 @@ describe('CargoWorkspace plugin', () => { flatten: false, targetBranch: 'main', }); + sandbox + .stub(github, 'findFilesByGlobAndRef') + .withArgs('packages/rustA', 'main') + .resolves(['packages/rustA']) + .withArgs('packages/rustB', 'main') + .resolves(['packages/rustB']) + .withArgs('packages/rustC', 'main') + .resolves(['packages/rustC']) + .withArgs('packages/rustD', 'main') + .resolves(['packages/rustD']) + .withArgs('packages/rustE', 'main') + .resolves(['packages/rustE']); plugin = new CargoWorkspace( github, 'main', @@ -332,6 +421,18 @@ describe('CargoWorkspace plugin', () => { flatten: false, targetBranch: 'main', }); + sandbox + .stub(github, 'findFilesByGlobAndRef') + .withArgs('packages/rustA', 'main') + .resolves(['packages/rustA']) + .withArgs('packages/rustB', 'main') + .resolves(['packages/rustB']) + .withArgs('packages/rustC', 'main') + .resolves(['packages/rustC']) + .withArgs('packages/rustD', 'main') + .resolves(['packages/rustD']) + .withArgs('packages/rustE', 'main') + .resolves(['packages/rustE']); const newCandidates = await plugin.run(candidates); expect(newCandidates).lengthOf(1); const rustCandidate = newCandidates.find( @@ -372,6 +473,18 @@ describe('CargoWorkspace plugin', () => { flatten: false, targetBranch: 'main', }); + sandbox + .stub(github, 'findFilesByGlobAndRef') + .withArgs('packages/rustA', 'main') + .resolves(['packages/rustA']) + .withArgs('packages/rustB', 'main') + .resolves(['packages/rustB']) + .withArgs('packages/rustC', 'main') + .resolves(['packages/rustC']) + .withArgs('packages/rustD', 'main') + .resolves(['packages/rustD']) + .withArgs('packages/rustE', 'main') + .resolves(['packages/rustE']); const newCandidates = await plugin.run(candidates); expect(newCandidates).lengthOf(1); const rustCandidate = newCandidates.find( @@ -385,5 +498,115 @@ describe('CargoWorkspace plugin', () => { assertHasUpdate(updates, 'packages/rustB/Cargo.toml', RawContent); snapshot(dateSafe(rustCandidate!.pullRequest.body.toString())); }); + it('handles packages without version', async () => { + const candidates: CandidateReleasePullRequest[] = [ + buildMockCandidatePullRequest('packages/rustA', 'rust', '1.1.2', { + component: '@here/pkgA', + updates: [ + buildMockPackageUpdate( + 'packages/rustA/Cargo.toml', + 'packages/rustA/Cargo.toml' + ), + ], + }), + ]; + stubFilesFromFixtures({ + sandbox, + github, + fixturePath: fixturesPath, + files: ['packages/rustA/Cargo.toml'], + flatten: false, + targetBranch: 'main', + inlineFiles: [ + [ + 'Cargo.toml', + '[workspace]\nmembers = ["packages/rustA", "packages/rustB"]', + ], + [ + 'packages/rustB/Cargo.toml', + '[package]\nname = "pkgB"\n\n[dependencies]\npkgA = { version = "1.1.1", path = "../pkgA" }', + ], + ], + }); + sandbox + .stub(github, 'findFilesByGlobAndRef') + .withArgs('packages/rustA', 'main') + .resolves(['packages/rustA']) + .withArgs('packages/rustB', 'main') + .resolves(['packages/rustB']); + plugin = new CargoWorkspace(github, 'main', { + 'packages/rustA': { + releaseType: 'rust', + }, + 'packages/rustB': { + releaseType: 'rust', + }, + }); + await assert.rejects( + async () => { + await plugin.run(candidates); + }, + err => { + return ( + err instanceof ConfigurationError && err.message.includes('missing') + ); + } + ); + }); + it('handles packages with invalid version', async () => { + const candidates: CandidateReleasePullRequest[] = [ + buildMockCandidatePullRequest('packages/rustA', 'rust', '1.1.2', { + component: '@here/pkgA', + updates: [ + buildMockPackageUpdate( + 'packages/rustA/Cargo.toml', + 'packages/rustA/Cargo.toml' + ), + ], + }), + ]; + stubFilesFromFixtures({ + sandbox, + github, + fixturePath: fixturesPath, + files: ['packages/rustA/Cargo.toml'], + flatten: false, + targetBranch: 'main', + inlineFiles: [ + [ + 'Cargo.toml', + '[workspace]\nmembers = ["packages/rustA", "packages/rustB"]', + ], + [ + 'packages/rustB/Cargo.toml', + '[package]\nname = "pkgB"\nversion = { major = 1, minor = 2, patch = 3 }\n\n[dependencies]\npkgA = { version = "1.1.1", path = "../pkgA" }', + ], + ], + }); + sandbox + .stub(github, 'findFilesByGlobAndRef') + .withArgs('packages/rustA', 'main') + .resolves(['packages/rustA']) + .withArgs('packages/rustB', 'main') + .resolves(['packages/rustB']); + plugin = new CargoWorkspace(github, 'main', { + 'packages/rustA': { + releaseType: 'rust', + }, + 'packages/rustB': { + releaseType: 'rust', + }, + }); + await assert.rejects( + async () => { + await plugin.run(candidates); + }, + err => { + return ( + err instanceof ConfigurationError && err.message.includes('invalid') + ); + } + ); + }); }); }); diff --git a/test/plugins/compatibility/linked-versions-group-title.ts b/test/plugins/compatibility/linked-versions-group-title.ts new file mode 100644 index 000000000..978fa2049 --- /dev/null +++ b/test/plugins/compatibility/linked-versions-group-title.ts @@ -0,0 +1,176 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import {describe, it, afterEach, beforeEach} from 'mocha'; +import * as sinon from 'sinon'; +import {GitHub} from '../../../src/github'; +import {Manifest} from '../../../src/manifest'; +import {Update} from '../../../src/update'; +import { + buildGitHubFileContent, + mockReleases, + mockCommits, + safeSnapshot, + stubFilesFromFixtures, + mockPullRequests, +} from '../../helpers'; +import {Version} from '../../../src/version'; +import {CargoToml} from '../../../src/updaters/rust/cargo-toml'; +import {parseCargoManifest} from '../../../src/updaters/rust/common'; +import {expect} from 'chai'; + +const sandbox = sinon.createSandbox(); +const fixturesPath = './test/fixtures/plugins/cargo-workspace'; + +export function buildMockPackageUpdate( + path: string, + fixtureName: string +): Update { + const cachedFileContents = buildGitHubFileContent(fixturesPath, fixtureName); + const manifest = parseCargoManifest(cachedFileContents.parsedContent); + return { + path, + createIfMissing: false, + cachedFileContents, + updater: new CargoToml({ + version: Version.parse(manifest.package?.version || 'FIXME'), + }), + }; +} + +describe('Plugin compatibility', () => { + let github: GitHub; + beforeEach(async () => { + github = await GitHub.create({ + owner: 'fake-owner', + repo: 'fake-repo', + defaultBranch: 'main', + }); + }); + afterEach(() => { + sandbox.restore(); + }); + describe('linked-versions and group-pull-request-title-pattern', () => { + it('should find release to create', async () => { + // Scenario: + // - package b depends on a + // - package a receives a new feature + // - package b version bumps its dependency on a + // - package a and b should both use a minor version bump + mockReleases(sandbox, github, [ + { + id: 123456, + sha: 'abc123', + tagName: 'primary-v1.0.0', + url: 'https://github.com/fake-owner/fake-repo/releases/tag/primary-v1.0.0', + }, + { + id: 654321, + sha: 'abc123', + tagName: 'pkgA-v1.0.0', + url: 'https://github.com/fake-owner/fake-repo/releases/tag/pkgA-v1.0.0', + }, + ]); + mockCommits(sandbox, github, [ + { + sha: 'aaaaaa', + message: 'feat: some feature', + files: ['packages/nodeA/foo'], + }, + { + sha: 'abc123', + message: 'chore: release main', + files: [], + pullRequest: { + headBranchName: 'release-please/branches/main', + baseBranchName: 'main', + number: 123, + title: 'chore: release main', + body: '', + labels: [], + files: [], + sha: 'abc123', + }, + }, + ]); + stubFilesFromFixtures({ + sandbox, + github, + fixturePath: fixturesPath, + files: [], + flatten: false, + targetBranch: 'main', + inlineFiles: [ + ['package.json', '{"name": "primary", "version": "1.0.0"}'], + [ + 'packages/nodeA/package.json', + '{"name": "pkgA", "version": "1.0.0"}', + ], + ], + }); + const manifest = new Manifest( + github, + 'main', + { + '.': { + releaseType: 'node', + component: 'primary', + }, + 'packages/nodeA': { + releaseType: 'node', + component: 'pkgA', + }, + }, + { + '.': Version.parse('1.0.0'), + 'packages/nodeA': Version.parse('1.0.0'), + }, + { + plugins: [ + { + type: 'linked-versions', + groupName: 'my group', + components: ['primary', 'pkgA'], + }, + ], + groupPullRequestTitlePattern: 'chore: Release${component} ${version}', + } + ); + const pullRequests = await manifest.buildPullRequests(); + expect(pullRequests).lengthOf(1); + const pullRequest = pullRequests[0]; + safeSnapshot(pullRequest.body.toString()); + expect(pullRequest.title.toString()).to.equal( + 'chore: Release primary 1.1.0' + ); + + console.log('-----------------------------------'); + + mockPullRequests(sandbox, github, [ + { + headBranchName: pullRequest.headRefName, + baseBranchName: 'main', + number: 1234, + title: pullRequest.title.toString(), + body: pullRequest.body.toString(), + labels: pullRequest.labels, + files: pullRequest.updates.map(update => update.path), + sha: 'cccccc', + }, + ]); + const releases = await manifest.buildReleases(); + expect(releases).lengthOf(2); + }); + }); +}); diff --git a/test/plugins/compatibility/linked-versions-workspace.ts b/test/plugins/compatibility/linked-versions-workspace.ts index 7f701a1ef..a7c57fae8 100644 --- a/test/plugins/compatibility/linked-versions-workspace.ts +++ b/test/plugins/compatibility/linked-versions-workspace.ts @@ -130,6 +130,12 @@ describe('Plugin compatibility', () => { ], ], }); + sandbox + .stub(github, 'findFilesByGlobAndRef') + .withArgs('packages/rustA', 'main') + .resolves(['packages/rustA']) + .withArgs('packages/rustB', 'main') + .resolves(['packages/rustB']); const manifest = new Manifest( github, 'main', diff --git a/test/plugins/linked-versions.ts b/test/plugins/linked-versions.ts index c591c0897..16f46c846 100644 --- a/test/plugins/linked-versions.ts +++ b/test/plugins/linked-versions.ts @@ -75,6 +75,12 @@ describe('LinkedVersions plugin', () => { tagName: 'pkg3-v0.2.3', url: 'https://github.com/fake-owner/fake-repo/releases/tag/pkg3-v0.2.3', }, + { + id: 4, + sha: 'abc123', + tagName: 'pkg4-v1.0.0', + url: 'https://github.com/fake-owner/fake-repo/releases/tag/pkg1-v1.0.0', + }, ]); mockCommits(sandbox, github, [ { @@ -265,4 +271,79 @@ describe('LinkedVersions plugin', () => { safeSnapshot(pullRequest.body.toString()); } }); + it('should allow multiple groups of linked versions', async () => { + const manifest = new Manifest( + github, + 'target-branch', + { + 'path/a': { + releaseType: 'simple', + component: 'pkg1', + }, + 'path/b': { + releaseType: 'simple', + component: 'pkg2', + }, + 'path/c': { + releaseType: 'simple', + component: 'pkg3', + }, + 'path/d': { + releaseType: 'simple', + component: 'pkg4', + }, + }, + { + 'path/a': Version.parse('1.0.0'), + 'path/b': Version.parse('0.2.3'), + 'path/c': Version.parse('0.2.3'), + 'path/d': Version.parse('1.0.0'), + }, + { + separatePullRequests: true, + plugins: [ + { + type: 'linked-versions', + groupName: 'group name', + components: ['pkg2', 'pkg3'], + }, + { + type: 'linked-versions', + groupName: 'second group name', + components: ['pkg1', 'pkg4'], + }, + ], + } + ); + const pullRequests = await manifest.buildPullRequests(); + expect(pullRequests).lengthOf(2); + const groupPullRequest1 = pullRequests[1]; + const packageData1 = groupPullRequest1.body.releaseData.find( + data => data.component === 'pkg1' + ); + expect(packageData1).to.not.be.undefined; + const packageData4 = groupPullRequest1.body.releaseData.find( + data => data.component === 'pkg4' + ); + expect(packageData4).to.not.be.undefined; + safeSnapshot(groupPullRequest1.body.toString()); + + const groupPullRequest2 = pullRequests[0]; + const packageData2 = groupPullRequest2.body.releaseData.find( + data => data.component === 'pkg2' + ); + expect(packageData2).to.not.be.undefined; + const packageData3 = groupPullRequest2.body.releaseData.find( + data => data.component === 'pkg3' + ); + expect(packageData3).to.not.be.undefined; + expect(packageData2?.version).to.eql(packageData3?.version); + safeSnapshot(groupPullRequest2.body.toString()); + + expect(groupPullRequest1.headRefName).not.to.eql( + groupPullRequest2.headRefName + ); + expect(groupPullRequest1.headRefName).to.not.include(' '); + expect(groupPullRequest2.headRefName).to.not.include(' '); + }); }); diff --git a/test/plugins/node-workspace.ts b/test/plugins/node-workspace.ts index 3125c6a29..b9a186acf 100644 --- a/test/plugins/node-workspace.ts +++ b/test/plugins/node-workspace.ts @@ -29,12 +29,15 @@ import { assertNoHasUpdate, buildMockCandidatePullRequest, buildGitHubFileRaw, + readFixture, } from '../helpers'; -import {RawContent} from '../../src/updaters/raw-content'; import snapshot = require('snap-shot-it'); import {ManifestPlugin} from '../../src/plugin'; import {Changelog} from '../../src/updaters/changelog'; import {ReleasePleaseManifest} from '../../src/updaters/release-please-manifest'; +import {Node} from '../../src/strategies/node'; +import {TagName} from '../../src/util/tag-name'; +import {Generic} from '../../src/updaters/generic'; const sandbox = sinon.createSandbox(); const fixturesPath = './test/fixtures/plugins/node-workspace'; @@ -73,13 +76,45 @@ function buildMockChangelogUpdate( }; } -function assertHasVersionUpdate(update: Update, expectedVersion: string) { - expect(update.updater).instanceof(RawContent); - const updater = update.updater as RawContent; - const data = JSON.parse(updater.rawContent); +/** + * Helper test to ensure that the file update exists and that + * the file is a json file with a .version equal to the provided + * version string. + * + * @param {Update[]} updates List of updates to search for + * @param {string} fixture Fixture name + * @param {string} expectedVersion Expected version string + */ +function assertHasVersionUpdate( + updates: Update[], + fixture: string, + expectedVersion: string +) { + const update = assertHasUpdate(updates, fixture); + const originalContent = readFixture(fixturesPath, fixture); + const content = update.updater.updateContent(originalContent); + const data = JSON.parse(content); expect(data.version).to.eql(expectedVersion); } +/** + * Helper test to snapshot the final contents of a file update. + * + * @param {Update[]} updates List of updates to search for + * @param {string} fixture Fixture name + */ +function snapshotUpdate( + updates: Update[], + file: string, + originalContent?: string +) { + if (!originalContent) { + originalContent = readFixture(fixturesPath, file); + } + const update = assertHasUpdate(updates, file); + snapshot(update.updater.updateContent(originalContent)); +} + describe('NodeWorkspace plugin', () => { let github: GitHub; let plugin: ManifestPlugin; @@ -102,6 +137,9 @@ describe('NodeWorkspace plugin', () => { node4: { releaseType: 'node', }, + node5: { + releaseType: 'node', + }, }); }); afterEach(() => { @@ -154,7 +192,7 @@ describe('NodeWorkspace plugin', () => { ), ], }), - buildMockCandidatePullRequest('node1', 'node', '2.2.2', { + buildMockCandidatePullRequest('node1', 'node', '3.3.3', { component: '@here/pkgA', updates: [ buildMockPackageUpdate('node1/package.json', 'node1/package.json'), @@ -173,14 +211,7 @@ describe('NodeWorkspace plugin', () => { expect(nodeCandidate).to.not.be.undefined; const updates = nodeCandidate!.pullRequest.updates; assertHasUpdate(updates, 'node1/package.json'); - - const update = assertHasUpdate( - updates, - 'plugin1/package.json', - RawContent - ); - const updater = update.updater as RawContent; - snapshot(updater.rawContent); + snapshotUpdate(updates, 'plugin1/package.json'); }); it('combines node packages', async () => { const candidates: CandidateReleasePullRequest[] = [ @@ -227,10 +258,10 @@ describe('NodeWorkspace plugin', () => { ); expect(nodeCandidate).to.not.be.undefined; const updates = nodeCandidate!.pullRequest.updates; - assertHasUpdate(updates, 'package.json'); - assertHasUpdate(updates, 'node1/package.json'); - assertHasUpdate(updates, 'node4/package.json'); snapshot(dateSafe(nodeCandidate!.pullRequest.body.toString())); + snapshotUpdate(updates, 'package.json'); + snapshotUpdate(updates, 'node1/package.json'); + snapshotUpdate(updates, 'node4/package.json'); }); it('walks dependency tree and updates previously untouched packages', async () => { const candidates: CandidateReleasePullRequest[] = [ @@ -256,6 +287,7 @@ describe('NodeWorkspace plugin', () => { 'node2/package.json', 'node3/package.json', 'node4/package.json', + 'node5/package.json', ], flatten: false, targetBranch: 'main', @@ -267,22 +299,11 @@ describe('NodeWorkspace plugin', () => { ); expect(nodeCandidate).to.not.be.undefined; const updates = nodeCandidate!.pullRequest.updates; - assertHasVersionUpdate( - assertHasUpdate(updates, 'node1/package.json', RawContent), - '3.3.4' - ); - assertHasVersionUpdate( - assertHasUpdate(updates, 'node2/package.json', RawContent), - '2.2.3' - ); - assertHasVersionUpdate( - assertHasUpdate(updates, 'node3/package.json', RawContent), - '1.1.2' - ); - assertHasVersionUpdate( - assertHasUpdate(updates, 'node4/package.json', RawContent), - '4.4.5' - ); + assertHasVersionUpdate(updates, 'node1/package.json', '3.3.4'); + assertHasVersionUpdate(updates, 'node2/package.json', '2.2.3'); + assertHasVersionUpdate(updates, 'node3/package.json', '1.1.2'); + assertHasVersionUpdate(updates, 'node4/package.json', '4.4.5'); + assertHasVersionUpdate(updates, 'node5/package.json', '1.0.1'); const updater = assertHasUpdate( updates, '.release-please-manifest.json', @@ -290,6 +311,7 @@ describe('NodeWorkspace plugin', () => { ).updater as ReleasePleaseManifest; expect(updater.versionsMap?.get('node2')?.toString()).to.eql('2.2.3'); expect(updater.versionsMap?.get('node3')?.toString()).to.eql('1.1.2'); + expect(updater.versionsMap?.get('node5')?.toString()).to.eql('1.0.1'); snapshot(dateSafe(nodeCandidate!.pullRequest.body.toString())); }); it('appends dependency notes to an updated module', async () => { @@ -313,7 +335,7 @@ describe('NodeWorkspace plugin', () => { buildMockPackageUpdate('node2/package.json', 'node2/package.json'), buildMockChangelogUpdate( 'node2/CHANGELOG.md', - '3.3.4', + '2.2.3', existingNotes ), ], @@ -329,6 +351,7 @@ describe('NodeWorkspace plugin', () => { 'node2/package.json', 'node3/package.json', 'node4/package.json', + 'node5/package.json', ], flatten: false, targetBranch: 'main', @@ -340,18 +363,9 @@ describe('NodeWorkspace plugin', () => { ); expect(nodeCandidate).to.not.be.undefined; const updates = nodeCandidate!.pullRequest.updates; - assertHasVersionUpdate( - assertHasUpdate(updates, 'node1/package.json', RawContent), - '3.3.4' - ); - assertHasVersionUpdate( - assertHasUpdate(updates, 'node2/package.json', RawContent), - '2.2.3' - ); - assertHasVersionUpdate( - assertHasUpdate(updates, 'node3/package.json', RawContent), - '1.1.2' - ); + assertHasVersionUpdate(updates, 'node1/package.json', '3.3.4'); + assertHasVersionUpdate(updates, 'node2/package.json', '2.2.3'); + assertHasVersionUpdate(updates, 'node3/package.json', '1.1.2'); assertNoHasUpdate(updates, 'node4/package.json'); snapshot(dateSafe(nodeCandidate!.pullRequest.body.toString())); const update = assertHasUpdate(updates, 'node1/CHANGELOG.md', Changelog); @@ -361,6 +375,169 @@ describe('NodeWorkspace plugin', () => { const update3 = assertHasUpdate(updates, 'node3/CHANGELOG.md', Changelog); snapshot((update3.updater as Changelog).changelogEntry); }); + it('includes headers for packages with configured strategies', async () => { + const candidates: CandidateReleasePullRequest[] = [ + buildMockCandidatePullRequest('node1', 'node', '3.3.4', { + component: '@here/pkgA', + updates: [ + buildMockPackageUpdate('node1/package.json', 'node1/package.json'), + buildMockChangelogUpdate( + 'node1/CHANGELOG.md', + '3.3.4', + 'other notes' + ), + ], + }), + ]; + stubFilesFromFixtures({ + sandbox, + github, + fixturePath: fixturesPath, + files: [ + 'node1/package.json', + 'node2/package.json', + 'node3/package.json', + 'node4/package.json', + 'node5/package.json', + ], + flatten: false, + targetBranch: 'main', + }); + await plugin.preconfigure( + { + node1: new Node({ + github, + targetBranch: 'main', + path: 'node1', + packageName: '@here/pkgA', + }), + node2: new Node({ + github, + targetBranch: 'main', + path: 'node2', + packageName: '@here/pkgB', + }), + node3: new Node({ + github, + targetBranch: 'main', + path: 'node3', + packageName: '@here/pkgC', + }), + node4: new Node({ + github, + targetBranch: 'main', + path: 'node4', + packageName: '@here/pkgD', + }), + node5: new Node({ + github, + targetBranch: 'main', + path: 'node5', + packageName: '@here/pkgE', + }), + }, + {}, + { + node2: { + tag: new TagName(new Version(2, 2, 2), 'pkgB'), + sha: '', + notes: '', + }, + } + ); + + const newCandidates = await plugin.run(candidates); + expect(newCandidates).lengthOf(1); + const nodeCandidate = newCandidates.find( + candidate => candidate.config.releaseType === 'node' + ); + expect(nodeCandidate).to.not.be.undefined; + const updates = nodeCandidate!.pullRequest.updates; + assertHasVersionUpdate(updates, 'node1/package.json', '3.3.4'); + assertHasVersionUpdate(updates, 'node2/package.json', '2.2.3'); + assertHasVersionUpdate(updates, 'node3/package.json', '1.1.2'); + snapshot(dateSafe(nodeCandidate!.pullRequest.body.toString())); + const update = assertHasUpdate(updates, 'node1/CHANGELOG.md', Changelog); + snapshot(dateSafe((update.updater as Changelog).changelogEntry)); + const changelogUpdaterNode2 = assertHasUpdate( + updates, + 'node2/CHANGELOG.md', + Changelog + ).updater as Changelog; + snapshot(dateSafe(changelogUpdaterNode2.changelogEntry)); + + const changelogUpdaterNode3 = assertHasUpdate( + updates, + 'node3/CHANGELOG.md', + Changelog + ).updater as Changelog; + + snapshot(dateSafe(changelogUpdaterNode3.changelogEntry)); + }); + it('incorporates extra-files from strategy', async () => { + const candidates: CandidateReleasePullRequest[] = [ + buildMockCandidatePullRequest('node1', 'node', '3.3.4', { + component: '@here/pkgA', + updates: [ + buildMockPackageUpdate('node1/package.json', 'node1/package.json'), + buildMockChangelogUpdate( + 'node1/CHANGELOG.md', + '3.3.4', + 'other notes' + ), + ], + }), + ]; + stubFilesFromFixtures({ + sandbox, + github, + fixturePath: fixturesPath, + files: [ + 'node1/package.json', + 'node2/package.json', + 'node3/package.json', + 'node4/package.json', + 'node5/package.json', + ], + flatten: false, + targetBranch: 'main', + }); + await plugin.preconfigure( + { + node1: new Node({ + github, + targetBranch: 'main', + path: 'node1', + packageName: '@here/pkgA', + }), + node2: new Node({ + github, + targetBranch: 'main', + path: 'node2', + packageName: '@here/pkgB', + extraFiles: ['my-file'], + }), + }, + {}, + { + node2: { + tag: new TagName(new Version(2, 2, 2), 'pkgB'), + sha: '', + notes: '', + }, + } + ); + + const newCandidates = await plugin.run(candidates); + expect(newCandidates).lengthOf(1); + const nodeCandidate = newCandidates.find( + candidate => candidate.config.releaseType === 'node' + ); + expect(nodeCandidate).to.not.be.undefined; + const updates = nodeCandidate!.pullRequest.updates; + + assertHasUpdate(updates, 'node2/my-file', Generic); + }); it('should ignore peer dependencies', async () => { const candidates: CandidateReleasePullRequest[] = [ buildMockCandidatePullRequest('node1', 'node', '3.3.4', { @@ -398,4 +575,86 @@ describe('NodeWorkspace plugin', () => { snapshot(dateSafe(nodeCandidate!.pullRequest.body.toString())); }); }); + describe('with updatePeerDependencies: true', () => { + const options = {updatePeerDependencies: true}; + it('should not ignore peer dependencies', async () => { + const candidates: CandidateReleasePullRequest[] = [ + buildMockCandidatePullRequest('node1', 'node', '3.3.4', { + component: '@here/pkgA', + updates: [ + buildMockPackageUpdate('node1/package.json', 'node1/package.json'), + ], + }), + ]; + stubFilesFromFixtures({ + sandbox, + github, + fixturePath: fixturesPath, + files: ['node1/package.json', 'plugin1/package.json'], + flatten: false, + targetBranch: 'main', + }); + plugin = new NodeWorkspace( + github, + 'main', + { + node1: { + releaseType: 'node', + }, + plugin1: { + releaseType: 'node', + }, + }, + options + ); + const newCandidates = await plugin.run(candidates); + expect(newCandidates).lengthOf(1); + const nodeCandidate = newCandidates.find( + candidate => candidate.config.releaseType === 'node' + ); + expect(nodeCandidate).to.not.be.undefined; + const updates = nodeCandidate!.pullRequest.updates; + assertHasUpdate(updates, 'node1/package.json'); + assertHasUpdate(updates, 'plugin1/package.json'); + snapshot(dateSafe(nodeCandidate!.pullRequest.body.toString())); + }); + + it('respects version prefix and updates peer dependencies', async () => { + const candidates: CandidateReleasePullRequest[] = [ + buildMockCandidatePullRequest('plugin1', 'node', '4.4.4', { + component: '@here/plugin1', + updates: [ + buildMockPackageUpdate( + 'plugin1/package.json', + 'plugin1/package.json' + ), + ], + }), + buildMockCandidatePullRequest('node1', 'node', '2.2.2', { + component: '@here/pkgA', + updates: [ + buildMockPackageUpdate('node1/package.json', 'node1/package.json'), + ], + }), + ]; + plugin = new NodeWorkspace( + github, + 'main', + { + plugin1: {releaseType: 'node'}, + node1: {releaseType: 'node'}, + }, + options + ); + const newCandidates = await plugin.run(candidates); + expect(newCandidates).lengthOf(1); + const nodeCandidate = newCandidates.find( + candidate => candidate.config.releaseType === 'node' + ); + expect(nodeCandidate).to.not.be.undefined; + const updates = nodeCandidate!.pullRequest.updates; + assertHasUpdate(updates, 'node1/package.json'); + snapshotUpdate(updates, 'plugin1/package.json'); + }); + }); }); diff --git a/test/plugins/sentence-case.ts b/test/plugins/sentence-case.ts index 5c35825c3..41a544795 100644 --- a/test/plugins/sentence-case.ts +++ b/test/plugins/sentence-case.ts @@ -16,6 +16,7 @@ import {SentenceCase} from '../../src/plugins/sentence-case'; import {expect} from 'chai'; import {GitHub} from '../../src/github'; +import {buildMockConventionalCommit} from '../helpers'; describe('SentenceCase Plugin', () => { let github: GitHub; @@ -30,14 +31,8 @@ describe('SentenceCase Plugin', () => { it('converts description to sentence case', async () => { const plugin = new SentenceCase(github, 'main', {}); const commits = await plugin.processCommits([ - { - sha: 'abc123', - message: 'fix: hello world', - }, - { - sha: 'abc123', - message: 'fix: Goodnight moon', - }, + ...buildMockConventionalCommit('fix: hello world'), + ...buildMockConventionalCommit('fix: Goodnight moon'), ]); expect(commits[0].message).to.equal('fix: Hello world'); expect(commits[1].message).to.equal('fix: Goodnight moon'); @@ -45,14 +40,8 @@ describe('SentenceCase Plugin', () => { it('leaves reserved words lowercase', async () => { const plugin = new SentenceCase(github, 'main', {}); const commits = await plugin.processCommits([ - { - sha: 'abc123', - message: 'feat: gRPC can now handle proxies', - }, - { - sha: 'abc123', - message: 'fix: npm now rocks', - }, + ...buildMockConventionalCommit('feat: gRPC can now handle proxies'), + ...buildMockConventionalCommit('fix: npm now rocks'), ]); expect(commits[0].message).to.equal('feat: gRPC can now handle proxies'); expect(commits[1].message).to.equal('fix: npm now rocks'); @@ -60,14 +49,8 @@ describe('SentenceCase Plugin', () => { it('handles sentences with now breaks', async () => { const plugin = new SentenceCase(github, 'main', {}); const commits = await plugin.processCommits([ - { - sha: 'abc123', - message: 'feat: beep-boop-hello', - }, - { - sha: 'abc123', - message: 'fix:log4j.foo.bar', - }, + ...buildMockConventionalCommit('feat: beep-boop-hello'), + ...buildMockConventionalCommit('fix:log4j.foo.bar'), ]); expect(commits[0].message).to.equal('feat: Beep-boop-hello'); expect(commits[1].message).to.equal('fix: Log4j.foo.bar'); @@ -76,14 +59,8 @@ describe('SentenceCase Plugin', () => { it('allows a custom list of specialWords to be provided', async () => { const plugin = new SentenceCase(github, 'main', {}, ['hello']); const commits = await plugin.processCommits([ - { - sha: 'abc123', - message: 'fix: hello world', - }, - { - sha: 'abc123', - message: 'fix: Goodnight moon', - }, + ...buildMockConventionalCommit('fix: hello world'), + ...buildMockConventionalCommit('fix: Goodnight moon'), ]); expect(commits[0].message).to.equal('fix: hello world'); expect(commits[1].message).to.equal('fix: Goodnight moon'); @@ -91,24 +68,20 @@ describe('SentenceCase Plugin', () => { it('handles subject with multiple : characters', async () => { const plugin = new SentenceCase(github, 'main', {}, []); const commits = await plugin.processCommits([ - { - sha: 'abc123', - message: 'fix: hello world:goodnight moon', - }, + ...buildMockConventionalCommit('abc123'), + ...buildMockConventionalCommit('fix: hello world:goodnight moon'), ]); expect(commits[0].message).to.equal('fix: Hello world:goodnight moon'); }); it('handles commit with no :', async () => { const plugin = new SentenceCase(github, 'main', {}, []); const commits = await plugin.processCommits([ - { - sha: 'abc123', - message: 'hello world goodnight moon', - }, + ...buildMockConventionalCommit('hello world goodnight moon'), ]); // Ensure there's no exception, a commit without a is not // a conventional commit, and will not show up in CHANGELOG. We // Do not bother sentence-casing: - expect(commits[0].message).to.equal('hello world goodnight moon'); + console.info(commits); + expect(commits.length).to.equal(0); }); }); diff --git a/test/strategies/base.ts b/test/strategies/base.ts index b32a1808c..4aa3d8a08 100644 --- a/test/strategies/base.ts +++ b/test/strategies/base.ts @@ -20,12 +20,18 @@ import {Update} from '../../src/update'; import {GitHub} from '../../src/github'; import {PullRequestBody} from '../../src/util/pull-request-body'; import snapshot = require('snap-shot-it'); -import {dateSafe, assertHasUpdate} from '../helpers'; +import { + dateSafe, + assertHasUpdate, + assertHasUpdates, + buildMockConventionalCommit, +} from '../helpers'; import {GenericJson} from '../../src/updaters/generic-json'; import {Generic} from '../../src/updaters/generic'; import {GenericXml} from '../../src/updaters/generic-xml'; import {PomXml} from '../../src/updaters/java/pom-xml'; import {GenericYaml} from '../../src/updaters/generic-yaml'; +import {GenericToml} from '../../src/updaters/generic-toml'; const sandbox = sinon.createSandbox(); @@ -63,12 +69,9 @@ describe('Strategy', () => { github, component: 'google-cloud-automl', }); - const commits = [ - { - sha: 'abc123', - message: 'chore: initial commit\n\nRelease-As: 2.3.4', - }, - ]; + const commits = buildMockConventionalCommit( + 'chore: initial commit\n\nRelease-As: 2.3.4' + ); const pullRequest = await strategy.buildReleasePullRequest(commits); expect(pullRequest).to.not.be.undefined; expect(pullRequest?.version?.toString()).to.eql('2.3.4'); @@ -81,12 +84,7 @@ describe('Strategy', () => { component: 'google-cloud-automl', initialVersion: '0.1.0', }); - const commits = [ - { - sha: 'abc123', - message: 'feat: initial commit', - }, - ]; + const commits = buildMockConventionalCommit('feat: initial commit'); const pullRequest = await strategy.buildReleasePullRequest(commits); expect(pullRequest).to.not.be.undefined; expect(pullRequest?.version?.toString()).to.eql('0.1.0'); @@ -100,7 +98,7 @@ describe('Strategy', () => { extraFiles: ['0', 'foo/1.~csv', 'foo/2.bak', 'foo/baz/bar/', '/3.java'], }); const pullRequest = await strategy.buildReleasePullRequest( - [{sha: 'aaa', message: 'fix: a bugfix'}], + buildMockConventionalCommit('fix: a bugfix'), undefined ); expect(pullRequest).to.exist; @@ -115,6 +113,70 @@ describe('Strategy', () => { ]) .and.not.include('foo/baz/bar/', 'expected file but got directory'); }); + it('updates extra JSON files with default', async () => { + const strategy = new TestStrategy({ + targetBranch: 'main', + github, + component: 'google-cloud-automl', + extraFiles: ['manifest.json'], + }); + const pullRequest = await strategy.buildReleasePullRequest( + buildMockConventionalCommit('fix: a bugfix'), + undefined + ); + expect(pullRequest).to.exist; + const updates = pullRequest?.updates; + expect(updates).to.be.an('array'); + assertHasUpdates(updates!, 'manifest.json', GenericJson, Generic); + }); + it('updates extra YAML files with default', async () => { + const strategy = new TestStrategy({ + targetBranch: 'main', + github, + component: 'google-cloud-automl', + extraFiles: ['pubspec.yaml'], + }); + const pullRequest = await strategy.buildReleasePullRequest( + buildMockConventionalCommit('fix: a bugfix'), + undefined + ); + expect(pullRequest).to.exist; + const updates = pullRequest?.updates; + expect(updates).to.be.an('array'); + assertHasUpdates(updates!, 'pubspec.yaml', GenericYaml, Generic); + }); + it('updates extra TOML files with default', async () => { + const strategy = new TestStrategy({ + targetBranch: 'main', + github, + component: 'google-cloud-automl', + extraFiles: ['foo.toml'], + }); + const pullRequest = await strategy.buildReleasePullRequest( + buildMockConventionalCommit('fix: a bugfix'), + undefined + ); + expect(pullRequest).to.exist; + const updates = pullRequest?.updates; + expect(updates).to.be.an('array'); + assertHasUpdates(updates!, 'foo.toml', GenericToml, Generic); + }); + it('updates extra Xml files with default', async () => { + const strategy = new TestStrategy({ + targetBranch: 'main', + github, + component: 'google-cloud-automl', + extraFiles: ['pom.xml'], + }); + const pullRequest = await strategy.buildReleasePullRequest( + buildMockConventionalCommit('fix: a bugfix'), + undefined + ); + expect(pullRequest).to.exist; + const updates = pullRequest?.updates; + expect(updates).to.be.an('array'); + assertHasUpdates(updates!, 'pom.xml', GenericXml, Generic); + }); it('updates extra JSON files', async () => { const strategy = new TestStrategy({ targetBranch: 'main', @@ -123,7 +185,7 @@ describe('Strategy', () => { extraFiles: ['0', {type: 'json', path: '/3.json', jsonpath: '$.foo'}], }); const pullRequest = await strategy.buildReleasePullRequest( - [{sha: 'aaa', message: 'fix: a bugfix'}], + buildMockConventionalCommit('fix: a bugfix'), undefined ); expect(pullRequest).to.exist; @@ -140,7 +202,7 @@ describe('Strategy', () => { extraFiles: ['0', {type: 'yaml', path: '/3.yaml', jsonpath: '$.foo'}], }); const pullRequest = await strategy.buildReleasePullRequest( - [{sha: 'aaa', message: 'fix: a bugfix'}], + buildMockConventionalCommit('fix: a bugfix'), undefined ); expect(pullRequest).to.exist; @@ -149,6 +211,23 @@ describe('Strategy', () => { assertHasUpdate(updates!, '0', Generic); assertHasUpdate(updates!, '3.yaml', GenericYaml); }); + it('updates extra TOML files', async () => { + const strategy = new TestStrategy({ + targetBranch: 'main', + github, + component: 'google-cloud-automl', + extraFiles: ['0', {type: 'toml', path: '/3.toml', jsonpath: '$.foo'}], + }); + const pullRequest = await strategy.buildReleasePullRequest( + buildMockConventionalCommit('fix: a bugfix'), + undefined + ); + expect(pullRequest).to.exist; + const updates = pullRequest?.updates; + expect(updates).to.be.an('array'); + assertHasUpdate(updates!, '0', Generic); + assertHasUpdate(updates!, '3.toml', GenericToml); + }); it('updates extra Xml files', async () => { const strategy = new TestStrategy({ targetBranch: 'main', @@ -157,7 +236,7 @@ describe('Strategy', () => { extraFiles: ['0', {type: 'xml', path: '/3.xml', xpath: '$.foo'}], }); const pullRequest = await strategy.buildReleasePullRequest( - [{sha: 'aaa', message: 'fix: a bugfix'}], + buildMockConventionalCommit('fix: a bugfix'), undefined ); expect(pullRequest).to.exist; @@ -174,7 +253,7 @@ describe('Strategy', () => { extraFiles: ['0', {type: 'pom', path: '/3.xml'}], }); const pullRequest = await strategy.buildReleasePullRequest( - [{sha: 'aaa', message: 'fix: a bugfix'}], + buildMockConventionalCommit('fix: a bugfix'), undefined ); expect(pullRequest).to.exist; @@ -202,7 +281,7 @@ describe('Strategy', () => { ], }); const pullRequest = await strategy.buildReleasePullRequest( - [{sha: 'aaa', message: 'fix: a bugfix'}], + buildMockConventionalCommit('fix: a bugfix'), undefined ); expect(pullRequest).to.exist; @@ -219,12 +298,7 @@ describe('Strategy', () => { component: 'google-cloud-automl', changelogHost: 'https://example.com', }); - const commits = [ - { - sha: 'abc5566', - message: 'fix: a bugfix', - }, - ]; + const commits = buildMockConventionalCommit('fix: a bugfix'); const pullRequest = await strategy.buildReleasePullRequest(commits); expect(pullRequest).to.exist; expect(pullRequest?.body.toString()).to.have.string( @@ -253,7 +327,7 @@ describe('Strategy', () => { extraFiles: [file], }); await strategy.buildReleasePullRequest( - [{sha: 'aaa', message: 'fix: a bugfix'}], + buildMockConventionalCommit('fix: a bugfix'), undefined ); expect.fail(`expected [addPath] to reject path: ${file}`); @@ -273,7 +347,7 @@ describe('Strategy', () => { extraLabels: ['foo', 'bar'], }); const pullRequest = await strategy.buildReleasePullRequest( - [{sha: 'aaa', message: 'fix: a bugfix'}], + buildMockConventionalCommit('fix: a bugfix'), undefined ); expect(pullRequest).to.exist; diff --git a/test/strategies/dart.ts b/test/strategies/dart.ts index 250b960fa..8ccaa2d85 100644 --- a/test/strategies/dart.ts +++ b/test/strategies/dart.ts @@ -15,7 +15,7 @@ import {describe, it, afterEach, beforeEach} from 'mocha'; import {Dart} from '../../src/strategies/dart'; import { - buildMockCommit, + buildMockConventionalCommit, buildGitHubFileContent, assertHasUpdate, } from '../helpers'; @@ -46,7 +46,7 @@ describe('Dart', () => { }); describe('buildReleasePullRequest', () => { const commits = [ - buildMockCommit( + ...buildMockConventionalCommit( 'fix(deps): update dependency com.google.cloud:google-cloud-storage to v1.120.0' ), ]; @@ -92,7 +92,7 @@ describe('Dart', () => { github, }); const commits = [ - buildMockCommit( + ...buildMockConventionalCommit( 'fix(deps): update dependency com.google.cloud:google-cloud-storage to v1.120.0' ), ]; @@ -124,7 +124,7 @@ describe('Dart', () => { packageName: 'some-dart-package', }); const commits = [ - buildMockCommit( + ...buildMockConventionalCommit( 'fix(deps): update dependency com.google.cloud:google-cloud-storage to v1.120.0' ), ]; diff --git a/test/strategies/dotnet-yoshi.ts b/test/strategies/dotnet-yoshi.ts index d1337416b..d8e88a4ff 100644 --- a/test/strategies/dotnet-yoshi.ts +++ b/test/strategies/dotnet-yoshi.ts @@ -23,7 +23,7 @@ import { buildGitHubFileContent, assertNoHasUpdate, } from '../helpers'; -import {buildMockCommit} from '../helpers'; +import {buildMockConventionalCommit} from '../helpers'; import {TagName} from '../../src/util/tag-name'; import {Changelog} from '../../src/updaters/changelog'; import {PullRequestBody} from '../../src/util/pull-request-body'; @@ -33,13 +33,13 @@ const sandbox = sinon.createSandbox(); const fixturesPath = './test/fixtures/strategies/dotnet-yoshi'; const COMMITS = [ - buildMockCommit( + ...buildMockConventionalCommit( 'fix(deps): update dependency com.google.cloud:google-cloud-storage to v1.120.0' ), - buildMockCommit( + ...buildMockConventionalCommit( 'fix(deps): update dependency com.google.cloud:google-cloud-spanner to v1.50.0' ), - buildMockCommit('chore: update common templates'), + ...buildMockConventionalCommit('chore: update common templates'), ]; describe('DotnetYoshi', () => { diff --git a/test/strategies/elixir.ts b/test/strategies/elixir.ts index 1a82e7021..9f72782f4 100644 --- a/test/strategies/elixir.ts +++ b/test/strategies/elixir.ts @@ -14,7 +14,7 @@ import {describe, it, afterEach, beforeEach} from 'mocha'; import {Elixir} from '../../src/strategies/elixir'; -import {buildMockCommit, assertHasUpdate} from '../helpers'; +import {buildMockConventionalCommit, assertHasUpdate} from '../helpers'; import * as nock from 'nock'; import * as sinon from 'sinon'; import {GitHub} from '../../src/github'; @@ -30,7 +30,7 @@ const sandbox = sinon.createSandbox(); describe('Elixir', () => { let github: GitHub; const commits = [ - buildMockCommit( + ...buildMockConventionalCommit( 'fix(deps): update dependency com.google.cloud:google-cloud-storage to v1.120.0' ), ]; diff --git a/test/strategies/expo.ts b/test/strategies/expo.ts index 707172d92..8c9578126 100644 --- a/test/strategies/expo.ts +++ b/test/strategies/expo.ts @@ -15,7 +15,7 @@ import {describe, it, afterEach, beforeEach} from 'mocha'; import {Expo} from '../../src/strategies/expo'; import { - buildMockCommit, + buildMockConventionalCommit, buildGitHubFileContent, assertHasUpdate, } from '../helpers'; @@ -38,7 +38,7 @@ const expoFixturesPath = './test/fixtures/strategies/expo'; describe('Expo', () => { let github: GitHub; const commits = [ - buildMockCommit( + ...buildMockConventionalCommit( 'fix(deps): update dependency com.google.cloud:google-cloud-storage to v1.120.0' ), ]; @@ -126,7 +126,7 @@ describe('Expo', () => { github, }); const commits = [ - buildMockCommit( + ...buildMockConventionalCommit( 'fix(deps): update dependency com.google.cloud:google-cloud-storage to v1.120.0' ), ]; @@ -159,7 +159,7 @@ describe('Expo', () => { component: 'abc-123', }); const commits = [ - buildMockCommit( + ...buildMockConventionalCommit( 'fix(deps): update dependency com.google.cloud:google-cloud-storage to v1.120.0' ), ]; diff --git a/test/strategies/go-yoshi.ts b/test/strategies/go-yoshi.ts index 589121f2c..4f682569e 100644 --- a/test/strategies/go-yoshi.ts +++ b/test/strategies/go-yoshi.ts @@ -18,7 +18,7 @@ import {GitHub} from '../../src/github'; import {GoYoshi} from '../../src/strategies/go-yoshi'; import * as sinon from 'sinon'; import {assertHasUpdate, dateSafe} from '../helpers'; -import {buildMockCommit} from '../helpers'; +import {buildMockConventionalCommit} from '../helpers'; import {TagName} from '../../src/util/tag-name'; import {Version} from '../../src/version'; import {Changelog} from '../../src/updaters/changelog'; @@ -28,11 +28,11 @@ import {VersionGo} from '../../src/updaters/go/version-go'; const sandbox = sinon.createSandbox(); const COMMITS = [ - buildMockCommit( + ...buildMockConventionalCommit( 'fix(iam): update dependency com.google.cloud:google-cloud-storage to v1.120.0', ['iam/foo.go'] ), - buildMockCommit('chore: update common templates'), + ...buildMockConventionalCommit('chore: update common templates'), ]; describe('GoYoshi', () => { @@ -110,10 +110,10 @@ describe('GoYoshi', () => { includeComponentInTag: false, }); const commits = [ - buildMockCommit('fix: some generic fix'), - buildMockCommit('fix(translate): some translate fix'), - buildMockCommit('fix(logging): some logging fix'), - buildMockCommit('feat: some generic feature'), + ...buildMockConventionalCommit('fix: some generic fix'), + ...buildMockConventionalCommit('fix(translate): some translate fix'), + ...buildMockConventionalCommit('fix(logging): some logging fix'), + ...buildMockConventionalCommit('feat: some generic feature'), ]; const pullRequest = await strategy.buildReleasePullRequest(commits); const pullRequestBody = pullRequest!.body.toString(); @@ -131,12 +131,12 @@ describe('GoYoshi', () => { includeComponentInTag: false, }); const commits = [ - buildMockCommit('fix: some generic fix'), - buildMockCommit('fix(iam/apiv1): some firestore fix', [ + ...buildMockConventionalCommit('fix: some generic fix'), + ...buildMockConventionalCommit('fix(iam/apiv1): some firestore fix', [ 'accessapproval/apiv1/access_approval_client.go', 'iam/apiv1/admin/firestore_admin_client.go', ]), - buildMockCommit('feat: some generic feature'), + ...buildMockConventionalCommit('feat: some generic feature'), ]; const pullRequest = await strategy.buildReleasePullRequest(commits); const pullRequestBody = pullRequest!.body.toString(); @@ -156,10 +156,18 @@ describe('GoYoshi', () => { github, }); const commits = [ - buildMockCommit('feat(all): auto-regenerate discovery clients (#1281)'), - buildMockCommit('feat(all): auto-regenerate discovery clients (#1280)'), - buildMockCommit('feat(all): auto-regenerate discovery clients (#1279)'), - buildMockCommit('feat(all): auto-regenerate discovery clients (#1278)'), + ...buildMockConventionalCommit( + 'feat(all): auto-regenerate discovery clients (#1281)' + ), + ...buildMockConventionalCommit( + 'feat(all): auto-regenerate discovery clients (#1280)' + ), + ...buildMockConventionalCommit( + 'feat(all): auto-regenerate discovery clients (#1279)' + ), + ...buildMockConventionalCommit( + 'feat(all): auto-regenerate discovery clients (#1278)' + ), ]; const pullRequest = await strategy.buildReleasePullRequest(commits); const pullRequestBody = pullRequest!.body.toString(); diff --git a/test/strategies/go.ts b/test/strategies/go.ts index ceec32f48..651e7a2c5 100644 --- a/test/strategies/go.ts +++ b/test/strategies/go.ts @@ -18,7 +18,7 @@ import {GitHub} from '../../src/github'; import {Go} from '../../src/strategies/go'; import * as sinon from 'sinon'; import {assertHasUpdate} from '../helpers'; -import {buildMockCommit} from '../helpers'; +import {buildMockConventionalCommit} from '../helpers'; import {TagName} from '../../src/util/tag-name'; import {Version} from '../../src/version'; import {Changelog} from '../../src/updaters/changelog'; @@ -26,13 +26,13 @@ import {Changelog} from '../../src/updaters/changelog'; const sandbox = sinon.createSandbox(); const COMMITS = [ - buildMockCommit( + ...buildMockConventionalCommit( 'fix(deps): update dependency com.google.cloud:google-cloud-storage to v1.120.0' ), - buildMockCommit( + ...buildMockConventionalCommit( 'fix(deps): update dependency com.google.cloud:google-cloud-spanner to v1.50.0' ), - buildMockCommit('chore: update common templates'), + ...buildMockConventionalCommit('chore: update common templates'), ]; describe('Go', () => { diff --git a/test/strategies/helm.ts b/test/strategies/helm.ts index 4df013014..d9b6c211c 100644 --- a/test/strategies/helm.ts +++ b/test/strategies/helm.ts @@ -15,7 +15,7 @@ import {describe, it, afterEach, beforeEach} from 'mocha'; import {Helm} from '../../src/strategies/helm'; import { - buildMockCommit, + buildMockConventionalCommit, buildGitHubFileContent, assertHasUpdate, } from '../helpers'; @@ -35,7 +35,7 @@ const fixturesPath = './test/fixtures/strategies/helm'; describe('Helm', () => { let github: GitHub; const commits = [ - buildMockCommit( + ...buildMockConventionalCommit( 'fix(deps): update dependency com.google.cloud:google-cloud-storage to v1.120.0' ), ]; diff --git a/test/strategies/java-yoshi-mono-repo.ts b/test/strategies/java-yoshi-mono-repo.ts new file mode 100644 index 000000000..0474b5e9f --- /dev/null +++ b/test/strategies/java-yoshi-mono-repo.ts @@ -0,0 +1,497 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import {describe, it, afterEach, beforeEach} from 'mocha'; +import {expect} from 'chai'; +import {GitHub} from '../../src/github'; +import {JavaYoshiMonoRepo} from '../../src/strategies/java-yoshi-mono-repo'; +import * as sinon from 'sinon'; +import { + buildGitHubFileContent, + assertHasUpdate, + assertNoHasUpdate, +} from '../helpers'; +import {buildMockConventionalCommit} from '../helpers'; +import {TagName} from '../../src/util/tag-name'; +import {Version} from '../../src/version'; +import {Changelog} from '../../src/updaters/changelog'; +import {JavaUpdate} from '../../src/updaters/java/java-update'; +import {VersionsManifest} from '../../src/updaters/java/versions-manifest'; +import {CompositeUpdater} from '../../src/updaters/composite'; + +import * as snapshot from 'snap-shot-it'; + +const sandbox = sinon.createSandbox(); +const fixturesPath = './test/fixtures/strategies/java-yoshi'; + +const COMMITS = [ + ...buildMockConventionalCommit( + 'fix(deps): update dependency com.google.cloud:google-cloud-storage to v1.120.0', + ['foo/bar/pom.xml'] + ), + ...buildMockConventionalCommit( + 'fix(deps): update dependency com.google.cloud:google-cloud-spanner to v1.50.0' + ), + ...buildMockConventionalCommit('chore: update common templates'), +]; + +const UUID_REGEX = + /[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}/g; +const ISO_DATE_REGEX = + /[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]+Z/g; // 2023-01-05T16:42:33.446Z + +describe('JavaYoshiMonoRepo', () => { + let github: GitHub; + beforeEach(async () => { + github = await GitHub.create({ + owner: 'googleapis', + repo: 'java-yoshi-test-repo', + defaultBranch: 'main', + }); + }); + afterEach(() => { + sandbox.restore(); + }); + describe('buildReleasePullRequest', () => { + it('returns release PR changes with defaultInitialVersion', async () => { + const expectedVersion = '0.1.0'; + const strategy = new JavaYoshiMonoRepo({ + targetBranch: 'main', + github, + component: 'google-cloud-automl', + }); + sandbox.stub(github, 'findFilesByFilenameAndRef').resolves([]); + const getFileContentsStub = sandbox.stub( + github, + 'getFileContentsOnBranch' + ); + getFileContentsStub + .withArgs('versions.txt', 'main') + .resolves(buildGitHubFileContent(fixturesPath, 'versions.txt')); + const latestRelease = undefined; + const release = await strategy.buildReleasePullRequest( + COMMITS, + latestRelease + ); + expect(release!.version?.toString()).to.eql(expectedVersion); + }); + it('returns release PR changes with semver patch bump', async () => { + const expectedVersion = '0.123.5'; + const strategy = new JavaYoshiMonoRepo({ + targetBranch: 'main', + github, + component: 'google-cloud-automl', + }); + sandbox.stub(github, 'findFilesByFilenameAndRef').resolves([]); + const getFileContentsStub = sandbox.stub( + github, + 'getFileContentsOnBranch' + ); + getFileContentsStub + .withArgs('versions.txt', 'main') + .resolves(buildGitHubFileContent(fixturesPath, 'versions.txt')); + const latestRelease = { + tag: new TagName(Version.parse('0.123.4'), 'google-cloud-automl'), + sha: 'abc123', + notes: 'some notes', + }; + const release = await strategy.buildReleasePullRequest( + COMMITS, + latestRelease + ); + expect(release!.version?.toString()).to.eql(expectedVersion); + }); + it('returns a snapshot bump PR', async () => { + const expectedVersion = '0.123.5-SNAPSHOT'; + const strategy = new JavaYoshiMonoRepo({ + targetBranch: 'main', + github, + component: 'google-cloud-automl', + }); + sandbox.stub(github, 'findFilesByFilenameAndRef').resolves([]); + const getFileContentsStub = sandbox.stub( + github, + 'getFileContentsOnBranch' + ); + getFileContentsStub + .withArgs('versions.txt', 'main') + .resolves( + buildGitHubFileContent(fixturesPath, 'versions-released.txt') + ); + const latestRelease = { + tag: new TagName(Version.parse('0.123.4'), 'google-cloud-automl'), + sha: 'abc123', + notes: 'some notes', + }; + const release = await strategy.buildReleasePullRequest( + COMMITS, + latestRelease + ); + expect(release!.version?.toString()).to.eql(expectedVersion); + }); + it('handles promotion to 1.0.0', async () => { + const commits = [ + ...buildMockConventionalCommit( + 'feat: promote to 1.0.0\n\nRelease-As: 1.0.0' + ), + ]; + const expectedVersion = '1.0.0'; + const strategy = new JavaYoshiMonoRepo({ + targetBranch: 'main', + github, + component: 'google-cloud-automl', + }); + sandbox.stub(github, 'findFilesByFilenameAndRef').resolves([]); + const getFileContentsStub = sandbox.stub( + github, + 'getFileContentsOnBranch' + ); + getFileContentsStub + .withArgs('versions.txt', 'main') + .resolves( + buildGitHubFileContent( + fixturesPath, + 'versions-with-beta-artifacts.txt' + ) + ); + const latestRelease = { + tag: new TagName(Version.parse('0.123.4'), 'google-cloud-automl'), + sha: 'abc123', + notes: 'some notes', + }; + const releasePullRequest = await strategy.buildReleasePullRequest( + commits, + latestRelease + ); + expect(releasePullRequest!.version?.toString()).to.eql(expectedVersion); + const update = assertHasUpdate( + releasePullRequest!.updates, + 'versions.txt', + VersionsManifest + ); + const versionsMap = (update.updater as VersionsManifest).versionsMap!; + expect(versionsMap.get('grpc-google-cloud-trace-v1')?.toString()).to.eql( + '1.0.0' + ); + expect( + versionsMap.get('grpc-google-cloud-trace-v1beta1')?.toString() + ).to.eql('0.74.0'); + }); + }); + describe('buildUpdates', () => { + it('builds common files', async () => { + const strategy = new JavaYoshiMonoRepo({ + targetBranch: 'main', + github, + component: 'google-cloud-automl', + }); + sandbox.stub(github, 'findFilesByFilenameAndRef').resolves([]); + const getFileContentsStub = sandbox.stub( + github, + 'getFileContentsOnBranch' + ); + getFileContentsStub + .withArgs('versions.txt', 'main') + .resolves(buildGitHubFileContent(fixturesPath, 'versions.txt')); + const latestRelease = undefined; + const release = await strategy.buildReleasePullRequest( + COMMITS, + latestRelease + ); + const updates = release!.updates; + assertHasUpdate(updates, 'CHANGELOG.md', Changelog); + assertHasUpdate(updates, 'versions.txt', VersionsManifest); + }); + + it('finds and updates standard files', async () => { + const strategy = new JavaYoshiMonoRepo({ + targetBranch: 'main', + github, + component: 'google-cloud-automl', + }); + const findFilesStub = sandbox.stub(github, 'findFilesByFilenameAndRef'); + findFilesStub + .withArgs('pom.xml', 'main', '.') + .resolves(['path1/pom.xml', 'path2/pom.xml']); + findFilesStub + .withArgs('build.gradle', 'main', '.') + .resolves(['path1/build.gradle', 'path2/build.gradle']); + findFilesStub + .withArgs('dependencies.properties', 'main', '.') + .resolves(['dependencies.properties']); + findFilesStub + .withArgs('README.md', 'main', '.') + .resolves(['path1/README.md', 'path2/README.md']); + const getFileContentsStub = sandbox.stub( + github, + 'getFileContentsOnBranch' + ); + getFileContentsStub + .withArgs('versions.txt', 'main') + .resolves(buildGitHubFileContent(fixturesPath, 'versions.txt')); + const latestRelease = undefined; + const release = await strategy.buildReleasePullRequest( + COMMITS, + latestRelease + ); + const updates = release!.updates; + assertHasUpdate(updates, 'CHANGELOG.md', Changelog); + const {updater} = assertHasUpdate(updates, 'path1/pom.xml', JavaUpdate); + const javaUpdater = updater as JavaUpdate; + expect(javaUpdater.isSnapshot).to.be.false; + expect( + javaUpdater.versionsMap?.get('google-cloud-trace')?.toString() + ).to.eql('0.108.1-beta'); + assertHasUpdate(updates, 'path2/pom.xml', JavaUpdate); + assertHasUpdate(updates, 'path1/build.gradle', JavaUpdate); + assertHasUpdate(updates, 'path1/build.gradle', JavaUpdate); + assertHasUpdate(updates, 'dependencies.properties', JavaUpdate); + assertHasUpdate(updates, 'versions.txt', VersionsManifest); + assertHasUpdate(updates, 'path1/README.md', JavaUpdate); + assertHasUpdate(updates, 'path2/README.md', JavaUpdate); + }); + + it('finds and updates extra files', async () => { + const strategy = new JavaYoshiMonoRepo({ + targetBranch: 'main', + github, + component: 'google-cloud-automl', + extraFiles: ['foo/bar.java', 'src/version.java'], + }); + sandbox.stub(github, 'findFilesByFilenameAndRef').resolves([]); + const getFileContentsStub = sandbox.stub( + github, + 'getFileContentsOnBranch' + ); + getFileContentsStub + .withArgs('versions.txt', 'main') + .resolves(buildGitHubFileContent(fixturesPath, 'versions.txt')); + const latestRelease = undefined; + const release = await strategy.buildReleasePullRequest( + COMMITS, + latestRelease + ); + const updates = release!.updates; + assertHasUpdate(updates, 'CHANGELOG.md', Changelog); + assertHasUpdate(updates, 'foo/bar.java', CompositeUpdater); + assertHasUpdate(updates, 'src/version.java', CompositeUpdater); + assertHasUpdate(updates, 'versions.txt', VersionsManifest); + }); + + it('updates all files for snapshots', async () => { + const strategy = new JavaYoshiMonoRepo({ + targetBranch: 'main', + github, + component: 'google-cloud-automl', + }); + const findFilesStub = sandbox.stub(github, 'findFilesByFilenameAndRef'); + findFilesStub + .withArgs('pom.xml', 'main', '.') + .resolves(['path1/pom.xml', 'path2/pom.xml']); + findFilesStub + .withArgs('build.gradle', 'main', '.') + .resolves(['path1/build.gradle', 'path2/build.gradle']); + findFilesStub + .withArgs('dependencies.properties', 'main', '.') + .resolves(['dependencies.properties']); + findFilesStub + .withArgs('README.md', 'main', '.') + .resolves(['path1/README.md', 'path2/README.md']); + const getFileContentsStub = sandbox.stub( + github, + 'getFileContentsOnBranch' + ); + getFileContentsStub + .withArgs('versions.txt', 'main') + .resolves( + buildGitHubFileContent(fixturesPath, 'versions-released.txt') + ); + const latestRelease = undefined; + const release = await strategy.buildReleasePullRequest( + COMMITS, + latestRelease + ); + const updates = release!.updates; + assertNoHasUpdate(updates, 'CHANGELOG.md'); + const {updater} = assertHasUpdate(updates, 'path1/pom.xml', JavaUpdate); + const javaUpdater = updater as JavaUpdate; + expect(javaUpdater.isSnapshot).to.be.true; + expect( + javaUpdater.versionsMap?.get('google-cloud-trace')?.toString() + ).to.eql('0.108.1-beta-SNAPSHOT'); + assertHasUpdate(updates, 'path2/pom.xml', JavaUpdate); + assertHasUpdate(updates, 'path1/build.gradle', JavaUpdate); + assertHasUpdate(updates, 'path1/build.gradle', JavaUpdate); + assertHasUpdate(updates, 'dependencies.properties', JavaUpdate); + assertHasUpdate(updates, 'versions.txt', VersionsManifest); + assertHasUpdate(updates, 'path1/README.md', JavaUpdate); + assertHasUpdate(updates, 'path2/README.md', JavaUpdate); + }); + + it('updates changelog.json', async () => { + const strategy = new JavaYoshiMonoRepo({ + targetBranch: 'main', + github, + component: 'google-cloud-automl', + }); + sandbox.stub(github, 'findFilesByFilenameAndRef').resolves([]); + const getFileContentsStub = sandbox.stub( + github, + 'getFileContentsOnBranch' + ); + getFileContentsStub + .withArgs('versions.txt', 'main') + .resolves(buildGitHubFileContent(fixturesPath, 'versions.txt')); + getFileContentsStub + .withArgs('foo/.repo-metadata.json', 'main') + .resolves(buildGitHubFileContent(fixturesPath, '.repo-metadata.json')); + getFileContentsStub + .withArgs('changelog.json', 'main') + .resolves(buildGitHubFileContent(fixturesPath, 'changelog.json')); + const latestRelease = undefined; + const release = await strategy.buildReleasePullRequest( + COMMITS, + latestRelease + ); + const updates = release!.updates; + assertHasUpdate(updates, 'CHANGELOG.md', Changelog); + assertHasUpdate(updates, 'versions.txt', VersionsManifest); + const update = assertHasUpdate( + updates, + 'changelog.json', + CompositeUpdater + ); + const newContent = update.updater.updateContent( + JSON.stringify({entries: []}) + ); + snapshot( + newContent + .replace(/\r\n/g, '\n') // make newline consistent regardless of OS. + .replace(UUID_REGEX, 'abc-123-efd-qwerty') + .replace(ISO_DATE_REGEX, '2023-01-05T16:42:33.446Z') + ); + }); + + it('omits non-breaking chores from changelog.json', async () => { + const COMMITS = [ + ...buildMockConventionalCommit( + 'fix(deps): update dependency com.google.cloud:google-cloud-storage to v1.120.0', + ['foo/bar/pom.xml'] + ), + ...buildMockConventionalCommit('chore: update deps', [ + 'foo/bar/pom.xml', + ]), + ...buildMockConventionalCommit('chore!: update a very important dep', [ + 'foo/bar/pom.xml', + ]), + ...buildMockConventionalCommit( + 'fix(deps): update dependency com.google.cloud:google-cloud-spanner to v1.50.0' + ), + ...buildMockConventionalCommit('chore: update common templates'), + ]; + const strategy = new JavaYoshiMonoRepo({ + targetBranch: 'main', + github, + component: 'google-cloud-automl', + }); + sandbox.stub(github, 'findFilesByFilenameAndRef').resolves([]); + const getFileContentsStub = sandbox.stub( + github, + 'getFileContentsOnBranch' + ); + getFileContentsStub + .withArgs('versions.txt', 'main') + .resolves(buildGitHubFileContent(fixturesPath, 'versions.txt')); + getFileContentsStub + .withArgs('foo/.repo-metadata.json', 'main') + .resolves(buildGitHubFileContent(fixturesPath, '.repo-metadata.json')); + getFileContentsStub + .withArgs('changelog.json', 'main') + .resolves(buildGitHubFileContent(fixturesPath, 'changelog.json')); + const latestRelease = undefined; + const release = await strategy.buildReleasePullRequest( + COMMITS, + latestRelease + ); + const updates = release!.updates; + assertHasUpdate(updates, 'CHANGELOG.md', Changelog); + assertHasUpdate(updates, 'versions.txt', VersionsManifest); + const update = assertHasUpdate( + updates, + 'changelog.json', + CompositeUpdater + ); + const newContent = update.updater.updateContent( + JSON.stringify({entries: []}) + ); + snapshot( + newContent + .replace(/\r\n/g, '\n') // make newline consistent regardless of OS. + .replace(UUID_REGEX, 'abc-123-efd-qwerty') + .replace(ISO_DATE_REGEX, '2023-01-05T16:42:33.446Z') + ); + }); + + it('does not update changelog.json if no .repo-metadata.json is found', async () => { + const COMMITS = [ + ...buildMockConventionalCommit( + 'fix(deps): update dependency com.google.cloud:google-cloud-storage to v1.120.0', + ['bar/bar/pom.xml'] + ), + ...buildMockConventionalCommit( + 'fix(deps): update dependency com.google.cloud:google-cloud-spanner to v1.50.0' + ), + ...buildMockConventionalCommit('chore: update common templates'), + ]; + const strategy = new JavaYoshiMonoRepo({ + targetBranch: 'main', + github, + component: 'google-cloud-automl', + }); + sandbox.stub(github, 'findFilesByFilenameAndRef').resolves([]); + const getFileContentsStub = sandbox.stub( + github, + 'getFileContentsOnBranch' + ); + getFileContentsStub + .withArgs('versions.txt', 'main') + .resolves(buildGitHubFileContent(fixturesPath, 'versions.txt')); + getFileContentsStub + .withArgs('changelog.json', 'main') + .resolves(buildGitHubFileContent(fixturesPath, 'changelog.json')); + const latestRelease = undefined; + const release = await strategy.buildReleasePullRequest( + COMMITS, + latestRelease + ); + const updates = release!.updates; + assertHasUpdate(updates, 'CHANGELOG.md', Changelog); + assertHasUpdate(updates, 'versions.txt', VersionsManifest); + const update = assertHasUpdate( + updates, + 'changelog.json', + CompositeUpdater + ); + const newContent = update.updater.updateContent( + JSON.stringify({entries: []}) + ); + snapshot( + newContent + .replace(/\r\n/g, '\n') // make newline consistent regardless of OS. + .replace(UUID_REGEX, 'abc-123-efd-qwerty') + .replace(ISO_DATE_REGEX, '2023-01-05T16:42:33.446Z') + ); + }); + }); +}); diff --git a/test/strategies/java-yoshi.ts b/test/strategies/java-yoshi.ts index b343ebbfc..84fcf87e1 100644 --- a/test/strategies/java-yoshi.ts +++ b/test/strategies/java-yoshi.ts @@ -22,25 +22,26 @@ import { assertHasUpdate, assertNoHasUpdate, } from '../helpers'; -import {buildMockCommit} from '../helpers'; +import {buildMockConventionalCommit} from '../helpers'; import {TagName} from '../../src/util/tag-name'; import {Version} from '../../src/version'; import {Changelog} from '../../src/updaters/changelog'; import {JavaUpdate} from '../../src/updaters/java/java-update'; import {VersionsManifest} from '../../src/updaters/java/versions-manifest'; import {CompositeUpdater} from '../../src/updaters/composite'; +import {FileNotFoundError, MissingRequiredFileError} from '../../src/errors'; const sandbox = sinon.createSandbox(); const fixturesPath = './test/fixtures/strategies/java-yoshi'; const COMMITS = [ - buildMockCommit( + ...buildMockConventionalCommit( 'fix(deps): update dependency com.google.cloud:google-cloud-storage to v1.120.0' ), - buildMockCommit( + ...buildMockConventionalCommit( 'fix(deps): update dependency com.google.cloud:google-cloud-spanner to v1.50.0' ), - buildMockCommit('chore: update common templates'), + ...buildMockConventionalCommit('chore: update common templates'), ]; describe('JavaYoshi', () => { @@ -134,7 +135,9 @@ describe('JavaYoshi', () => { }); it('handles promotion to 1.0.0', async () => { const commits = [ - buildMockCommit('feat: promote to 1.0.0\n\nRelease-As: 1.0.0'), + ...buildMockConventionalCommit( + 'feat: promote to 1.0.0\n\nRelease-As: 1.0.0' + ), ]; const expectedVersion = '1.0.0'; const strategy = new JavaYoshi({ @@ -178,6 +181,34 @@ describe('JavaYoshi', () => { versionsMap.get('grpc-google-cloud-trace-v1beta1')?.toString() ).to.eql('0.74.0'); }); + it('throws on missing required versions.txt', async () => { + const strategy = new JavaYoshi({ + targetBranch: 'main', + github, + component: 'google-cloud-automl', + }); + sandbox.stub(github, 'findFilesByFilenameAndRef').resolves([]); + const getFileContentsStub = sandbox.stub( + github, + 'getFileContentsOnBranch' + ); + getFileContentsStub + .withArgs('versions.txt', 'main') + .throws(new FileNotFoundError('versions.txt')); + const latestRelease = { + tag: new TagName(Version.parse('0.123.4'), 'google-cloud-automl'), + sha: 'abc123', + notes: 'some notes', + }; + let failed = false; + try { + await strategy.buildReleasePullRequest(COMMITS, latestRelease); + } catch (e) { + expect(e).instanceof(MissingRequiredFileError); + failed = true; + } + expect(failed).to.be.true; + }); }); describe('buildUpdates', () => { it('builds common files', async () => { diff --git a/test/strategies/java.ts b/test/strategies/java.ts index 1d0471839..63245b504 100644 --- a/test/strategies/java.ts +++ b/test/strategies/java.ts @@ -20,13 +20,14 @@ import { assertHasUpdate, assertHasUpdates, assertNoHasUpdate, - buildMockCommit, + buildMockConventionalCommit, } from '../helpers'; import {expect} from 'chai'; import {Version} from '../../src/version'; import {TagName} from '../../src/util/tag-name'; import {Changelog} from '../../src/updaters/changelog'; import {DEFAULT_LABELS, DEFAULT_SNAPSHOT_LABELS} from '../../src/manifest'; +import {CompositeUpdater} from '../../src/updaters/composite'; import {Generic} from '../../src/updaters/generic'; import {JavaReleased} from '../../src/updaters/java/java-released'; @@ -47,13 +48,13 @@ describe('Java', () => { describe('buildReleasePullRequest', () => { describe('for default component', () => { const COMMITS_NO_SNAPSHOT = [ - buildMockCommit('fix(deps): update dependency'), - buildMockCommit('fix(deps): update dependency'), - buildMockCommit('chore: update common templates'), + ...buildMockConventionalCommit('fix(deps): update dependency'), + ...buildMockConventionalCommit('fix(deps): update dependency'), + ...buildMockConventionalCommit('chore: update common templates'), ]; const COMMITS_WITH_SNAPSHOT = [ ...COMMITS_NO_SNAPSHOT, - buildMockCommit('chore(main): release 2.3.4-SNAPSHOT'), + ...buildMockConventionalCommit('chore(main): release 2.3.4-SNAPSHOT'), ]; it('returns release PR changes with defaultInitialVersion', async () => { @@ -192,7 +193,9 @@ describe('Java', () => { }; const release = await strategy.buildReleasePullRequest( [ - buildMockCommit('chore(main): release other 2.3.4-SNAPSHOT'), + ...buildMockConventionalCommit( + 'chore(main): release other 2.3.4-SNAPSHOT' + ), ...COMMITS_NO_SNAPSHOT, ], latestRelease @@ -260,7 +263,7 @@ describe('Java', () => { const updates = release!.updates; assertHasUpdate(updates, 'CHANGELOG.md', Changelog); - assertHasUpdates(updates, 'pom.xml', JavaReleased, Generic); + assertHasUpdates(updates, 'pom.xml', JavaReleased, CompositeUpdater); assertHasUpdates(updates, 'foo/bar.java', JavaReleased, Generic); }); @@ -284,20 +287,26 @@ describe('Java', () => { const updates = release!.updates; assertNoHasUpdate(updates, 'CHANGELOG.md'); assertHasUpdate(updates, 'foo/bar.java', Generic); - assertHasUpdate(updates, 'pom.xml', Generic); + assertHasUpdate(updates, 'pom.xml', CompositeUpdater); }); }); describe('with includeComponentInTag', () => { const COMMITS_NO_SNAPSHOT = [ - buildMockCommit('fix(deps): update dependency'), - buildMockCommit('fix(deps): update dependency'), - buildMockCommit('chore: update common templates'), - buildMockCommit('chore(main): release other-sample 13.3.5'), + ...buildMockConventionalCommit('fix(deps): update dependency'), + ...buildMockConventionalCommit('fix(deps): update dependency'), + ...buildMockConventionalCommit('chore: update common templates'), + ...buildMockConventionalCommit( + 'chore(main): release other-sample 13.3.5' + ), ]; const COMMITS_WITH_SNAPSHOT = COMMITS_NO_SNAPSHOT.concat( - buildMockCommit('chore(main): release other-sample 13.3.6-SNAPSHOT'), - buildMockCommit('chore(main): release test-sample 2.3.4-SNAPSHOT') + ...buildMockConventionalCommit( + 'chore(main): release other-sample 13.3.6-SNAPSHOT' + ), + ...buildMockConventionalCommit( + 'chore(main): release test-sample 2.3.4-SNAPSHOT' + ) ); it('returns release PR changes with defaultInitialVersion', async () => { diff --git a/test/strategies/krm-blueprint.ts b/test/strategies/krm-blueprint.ts index cdead8ef7..d32f295b2 100644 --- a/test/strategies/krm-blueprint.ts +++ b/test/strategies/krm-blueprint.ts @@ -15,7 +15,7 @@ import {describe, it, afterEach, beforeEach} from 'mocha'; import {KRMBlueprint} from '../../src/strategies/krm-blueprint'; import { - buildMockCommit, + buildMockConventionalCommit, stubFilesFromFixtures, assertHasUpdate, assertNoHasUpdate, @@ -36,7 +36,7 @@ const fixturesPath = './test/fixtures/strategies/krm-blueprint'; describe('KRMBlueprint', () => { let github: GitHub; const commits = [ - buildMockCommit( + ...buildMockConventionalCommit( 'fix(deps): update dependency com.google.cloud:google-cloud-storage to v1.120.0' ), ]; diff --git a/test/strategies/maven.ts b/test/strategies/maven.ts index a167e6dd4..78a71fff8 100644 --- a/test/strategies/maven.ts +++ b/test/strategies/maven.ts @@ -15,7 +15,11 @@ import {afterEach, beforeEach, describe, it} from 'mocha'; import {GitHub} from '../../src'; import * as sinon from 'sinon'; -import {assertHasUpdate, assertHasUpdates, buildMockCommit} from '../helpers'; +import { + assertHasUpdate, + assertHasUpdates, + buildMockConventionalCommit, +} from '../helpers'; import {Changelog} from '../../src/updaters/changelog'; import {Generic} from '../../src/updaters/generic'; import {JavaReleased} from '../../src/updaters/java/java-released'; @@ -28,8 +32,8 @@ import {expect} from 'chai'; const sandbox = sinon.createSandbox(); const COMMITS = [ - buildMockCommit('fix(deps): update dependency'), - buildMockCommit('chore: update common templates'), + ...buildMockConventionalCommit('fix(deps): update dependency'), + ...buildMockConventionalCommit('chore: update common templates'), ]; describe('Maven', () => { diff --git a/test/strategies/node.ts b/test/strategies/node.ts index 124e361b8..4579f57cb 100644 --- a/test/strategies/node.ts +++ b/test/strategies/node.ts @@ -15,7 +15,7 @@ import {describe, it, afterEach, beforeEach} from 'mocha'; import {Node} from '../../src/strategies/node'; import { - buildMockCommit, + buildMockConventionalCommit, buildGitHubFileContent, assertHasUpdate, } from '../helpers'; @@ -29,17 +29,24 @@ import {PackageLockJson} from '../../src/updaters/node/package-lock-json'; import {SamplesPackageJson} from '../../src/updaters/node/samples-package-json'; import {Changelog} from '../../src/updaters/changelog'; import {PackageJson} from '../../src/updaters/node/package-json'; +import {ChangelogJson} from '../../src/updaters/changelog-json'; import * as assert from 'assert'; import {MissingRequiredFileError, FileNotFoundError} from '../../src/errors'; +import * as snapshot from 'snap-shot-it'; nock.disableNetConnect(); const sandbox = sinon.createSandbox(); const fixturesPath = './test/fixtures/strategies/node'; +const UUID_REGEX = + /[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}/g; +const ISO_DATE_REGEX = + /[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]+Z/g; // 2023-01-05T16:42:33.446Z + describe('Node', () => { let github: GitHub; const commits = [ - buildMockCommit( + ...buildMockConventionalCommit( 'fix(deps): update dependency com.google.cloud:google-cloud-storage to v1.120.0' ), ]; @@ -95,7 +102,7 @@ describe('Node', () => { github, }); const commits = [ - buildMockCommit( + ...buildMockConventionalCommit( 'fix(deps): update dependency com.google.cloud:google-cloud-storage to v1.120.0' ), ]; @@ -125,7 +132,7 @@ describe('Node', () => { component: 'abc-123', }); const commits = [ - buildMockCommit( + ...buildMockConventionalCommit( 'fix(deps): update dependency com.google.cloud:google-cloud-storage to v1.120.0' ), ]; @@ -164,6 +171,52 @@ describe('Node', () => { await strategy.buildReleasePullRequest(commits, latestRelease); }, MissingRequiredFileError); }); + it('updates changelog.json if present', async () => { + const COMMITS = [ + ...buildMockConventionalCommit( + 'fix(deps): update dependency com.google.cloud:google-cloud-storage to v1.120.0' + ), + ...buildMockConventionalCommit('chore: update deps'), + ...buildMockConventionalCommit('chore!: update a very important dep'), + ...buildMockConventionalCommit( + 'fix(deps): update dependency com.google.cloud:google-cloud-spanner to v1.50.0' + ), + ...buildMockConventionalCommit('chore: update common templates'), + ]; + const strategy = new Node({ + targetBranch: 'main', + github, + component: 'google-cloud-node', + }); + sandbox.stub(github, 'findFilesByFilenameAndRef').resolves([]); + const getFileContentsStub = sandbox.stub( + github, + 'getFileContentsOnBranch' + ); + getFileContentsStub + .withArgs('changelog.json', 'main') + .resolves(buildGitHubFileContent(fixturesPath, 'changelog.json')); + getFileContentsStub + .withArgs('package.json', 'main') + .resolves(buildGitHubFileContent(fixturesPath, 'package.json')); + const latestRelease = undefined; + const release = await strategy.buildReleasePullRequest( + COMMITS, + latestRelease + ); + const updates = release!.updates; + assertHasUpdate(updates, 'CHANGELOG.md', Changelog); + const update = assertHasUpdate(updates, 'changelog.json', ChangelogJson); + const newContent = update.updater.updateContent( + JSON.stringify({entries: []}) + ); + snapshot( + newContent + .replace(/\r\n/g, '\n') // make newline consistent regardless of OS. + .replace(UUID_REGEX, 'abc-123-efd-qwerty') + .replace(ISO_DATE_REGEX, '2023-01-05T16:42:33.446Z') + ); + }); }); describe('buildUpdates', () => { it('builds common files', async () => { diff --git a/test/strategies/ocaml.ts b/test/strategies/ocaml.ts index 7c7fcd3ff..e73e73e2b 100644 --- a/test/strategies/ocaml.ts +++ b/test/strategies/ocaml.ts @@ -22,7 +22,7 @@ import { assertNoHasUpdate, stubFilesFromFixtures, } from '../helpers'; -import {buildMockCommit} from '../helpers'; +import {buildMockConventionalCommit} from '../helpers'; import {TagName} from '../../src/util/tag-name'; import {Version} from '../../src/version'; import {Changelog} from '../../src/updaters/changelog'; @@ -34,13 +34,13 @@ const sandbox = sinon.createSandbox(); const fixturesPath = './test/fixtures/strategies/ocaml'; const COMMITS = [ - buildMockCommit( + ...buildMockConventionalCommit( 'fix(deps): update dependency com.google.cloud:google-cloud-storage to v1.120.0' ), - buildMockCommit( + ...buildMockConventionalCommit( 'fix(deps): update dependency com.google.cloud:google-cloud-spanner to v1.50.0' ), - buildMockCommit('chore: update common templates'), + ...buildMockConventionalCommit('chore: update common templates'), ]; describe('OCaml', () => { diff --git a/test/strategies/php-yoshi.ts b/test/strategies/php-yoshi.ts index a997e1a3e..a494fe187 100644 --- a/test/strategies/php-yoshi.ts +++ b/test/strategies/php-yoshi.ts @@ -18,12 +18,11 @@ import {GitHub} from '../../src/github'; import {PHPYoshi} from '../../src/strategies/php-yoshi'; import * as sinon from 'sinon'; import {assertHasUpdate, buildGitHubFileRaw, dateSafe} from '../helpers'; -import {buildMockCommit} from '../helpers'; +import {buildMockConventionalCommit} from '../helpers'; import {TagName} from '../../src/util/tag-name'; import {Version} from '../../src/version'; import {Changelog} from '../../src/updaters/changelog'; import {RootComposerUpdatePackages} from '../../src/updaters/php/root-composer-update-packages'; -import {PHPManifest} from '../../src/updaters/php/php-manifest'; import {PHPClientVersion} from '../../src/updaters/php/php-client-version'; import {DefaultUpdater} from '../../src/updaters/default'; import snapshot = require('snap-shot-it'); @@ -37,15 +36,15 @@ describe('PHPYoshi', () => { let github: GitHub; let getFileStub: sinon.SinonStub; const commits = [ - buildMockCommit( + ...buildMockConventionalCommit( 'fix(deps): update dependency com.google.cloud:google-cloud-storage to v1.120.0', ['Client1/foo.php'] ), - buildMockCommit( + ...buildMockConventionalCommit( 'fix(deps): update dependency com.google.cloud:google-cloud-spanner to v1.50.0', ['Client2/foo.php', 'Client3/bar.php'] ), - buildMockCommit('misc: update common templates'), + ...buildMockConventionalCommit('misc: update common templates'), ]; beforeEach(async () => { github = await GitHub.create({ @@ -65,7 +64,9 @@ describe('PHPYoshi', () => { .resolves(buildGitHubFileRaw('0.1.2')); getFileStub .withArgs('Client1/composer.json', 'main') - .resolves(buildGitHubFileRaw('{"name": "google/client1"}')); + .resolves( + buildGitHubFileRaw('{"name": "google/client1", "version": "1.2.3"}') + ); getFileStub .withArgs('Client2/composer.json', 'main') .resolves(buildGitHubFileRaw('{"name": "google/client2"}')); @@ -152,9 +153,6 @@ describe('PHPYoshi', () => { const updates = release!.updates; assertHasUpdate(updates, 'CHANGELOG.md', Changelog); assertHasUpdate(updates, 'composer.json', RootComposerUpdatePackages); - assertHasUpdate(updates, 'docs/manifest.json', PHPManifest); - assertHasUpdate(updates, 'src/Version.php', PHPClientVersion); - assertHasUpdate(updates, 'src/ServiceBuilder.php', PHPClientVersion); }); it('finds touched components', async () => { const strategy = new PHPYoshi({ @@ -168,8 +166,15 @@ describe('PHPYoshi', () => { ); const updates = release!.updates; assertHasUpdate(updates, 'Client1/VERSION', DefaultUpdater); + assertHasUpdate( + updates, + 'Client1/composer.json', + RootComposerUpdatePackages + ); assertHasUpdate(updates, 'Client2/VERSION', DefaultUpdater); + assertHasUpdate(updates, 'Client2/composer.json'); assertHasUpdate(updates, 'Client3/VERSION', DefaultUpdater); + assertHasUpdate(updates, 'Client3/composer.json'); assertHasUpdate(updates, 'Client3/src/Entry.php', PHPClientVersion); }); it('ignores non client top level directories', async () => { @@ -179,15 +184,15 @@ describe('PHPYoshi', () => { }); const latestRelease = undefined; const commits = [ - buildMockCommit( + ...buildMockConventionalCommit( 'fix(deps): update dependency com.google.cloud:google-cloud-storage to v1.120.0', ['Client1/foo.php', '.git/release-please.yml'] ), - buildMockCommit( + ...buildMockConventionalCommit( 'fix(deps): update dependency com.google.cloud:google-cloud-spanner to v1.50.0', ['Client2/foo.php', 'Client3/bar.php'] ), - buildMockCommit('misc: update common templates'), + ...buildMockConventionalCommit('misc: update common templates'), ]; getFileStub .withArgs('.git/VERSION', 'main') @@ -198,10 +203,41 @@ describe('PHPYoshi', () => { ); const updates = release!.updates; assertHasUpdate(updates, 'Client1/VERSION', DefaultUpdater); + assertHasUpdate( + updates, + 'Client1/composer.json', + RootComposerUpdatePackages + ); assertHasUpdate(updates, 'Client2/VERSION', DefaultUpdater); + assertHasUpdate(updates, 'Client2/composer.json'); assertHasUpdate(updates, 'Client3/VERSION', DefaultUpdater); + assertHasUpdate(updates, 'Client3/composer.json'); assertHasUpdate(updates, 'Client3/src/Entry.php', PHPClientVersion); }); + it('updates component composer version', async () => { + const strategy = new PHPYoshi({ + targetBranch: 'main', + github, + }); + const latestRelease = undefined; + const release = await strategy.buildReleasePullRequest( + commits, + latestRelease + ); + const updates = release!.updates; + assertHasUpdate( + updates, + 'Client1/composer.json', + RootComposerUpdatePackages + ); + const client1Composer = updates.find(update => { + return update.path === 'Client1/composer.json'; + }); + const newContent = client1Composer!.updater.updateContent( + '{"name":"google/client1","version":"1.2.3"}' + ); + expect(newContent).to.eql('{"name":"google/client1","version":"1.2.4"}'); + }); }); describe('buildRelease', () => { it('parses the release notes', async () => { diff --git a/test/strategies/php.ts b/test/strategies/php.ts index a46adb44e..173f4c5d2 100644 --- a/test/strategies/php.ts +++ b/test/strategies/php.ts @@ -18,22 +18,23 @@ import {GitHub} from '../../src/github'; import {PHP} from '../../src/strategies/php'; import * as sinon from 'sinon'; import {assertHasUpdate} from '../helpers'; -import {buildMockCommit} from '../helpers'; +import {buildMockConventionalCommit} from '../helpers'; import {TagName} from '../../src/util/tag-name'; import {Version} from '../../src/version'; import {Changelog} from '../../src/updaters/changelog'; import {RootComposerUpdatePackages} from '../../src/updaters/php/root-composer-update-packages'; +import {DefaultUpdater} from '../../src/updaters/default'; const sandbox = sinon.createSandbox(); const COMMITS = [ - buildMockCommit( + ...buildMockConventionalCommit( 'fix(deps): update dependency com.google.cloud:google-cloud-storage to v1.120.0' ), - buildMockCommit( + ...buildMockConventionalCommit( 'fix(deps): update dependency com.google.cloud:google-cloud-spanner to v1.50.0' ), - buildMockCommit('chore: update common templates'), + ...buildMockConventionalCommit('chore: update common templates'), ]; describe('PHP', () => { @@ -95,9 +96,10 @@ describe('PHP', () => { latestRelease ); const updates = release!.updates; - expect(updates).lengthOf(2); + expect(updates).lengthOf(3); assertHasUpdate(updates, 'CHANGELOG.md', Changelog); assertHasUpdate(updates, 'composer.json', RootComposerUpdatePackages); + assertHasUpdate(updates, 'VERSION', DefaultUpdater); }); }); }); diff --git a/test/strategies/python.ts b/test/strategies/python.ts index 1061f326d..b304cca03 100644 --- a/test/strategies/python.ts +++ b/test/strategies/python.ts @@ -18,7 +18,7 @@ import {GitHub} from '../../src/github'; import {Python} from '../../src/strategies/python'; import * as sinon from 'sinon'; import {buildGitHubFileContent, assertHasUpdate} from '../helpers'; -import {buildMockCommit} from '../helpers'; +import {buildMockConventionalCommit} from '../helpers'; import {PythonFileWithVersion} from '../../src/updaters/python/python-file-with-version'; import {TagName} from '../../src/util/tag-name'; import {Version} from '../../src/version'; @@ -26,17 +26,25 @@ import {PyProjectToml} from '../../src/updaters/python/pyproject-toml'; import {SetupCfg} from '../../src/updaters/python/setup-cfg'; import {SetupPy} from '../../src/updaters/python/setup-py'; import {Changelog} from '../../src/updaters/changelog'; +import {ChangelogJson} from '../../src/updaters/changelog-json'; +import * as snapshot from 'snap-shot-it'; const sandbox = sinon.createSandbox(); +const fixturesPath = './test/fixtures/strategies/python'; + +const UUID_REGEX = + /[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}/g; +const ISO_DATE_REGEX = + /[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]+Z/g; // 2023-01-05T16:42:33.446Z const COMMITS = [ - buildMockCommit( + ...buildMockConventionalCommit( 'fix(deps): update dependency com.google.cloud:google-cloud-storage to v1.120.0' ), - buildMockCommit( + ...buildMockConventionalCommit( 'fix(deps): update dependency com.google.cloud:google-cloud-spanner to v1.50.0' ), - buildMockCommit('chore: update common templates'), + ...buildMockConventionalCommit('chore: update common templates'), ]; describe('Python', () => { @@ -59,6 +67,9 @@ describe('Python', () => { github, component: 'google-cloud-automl', }); + sandbox + .stub(github, 'getFileContentsOnBranch') + .resolves(buildGitHubFileContent(fixturesPath, 'setup.py')); sandbox.stub(github, 'findFilesByFilenameAndRef').resolves([]); const latestRelease = undefined; const release = await strategy.buildReleasePullRequest( @@ -74,6 +85,9 @@ describe('Python', () => { github, component: 'google-cloud-automl', }); + sandbox + .stub(github, 'getFileContentsOnBranch') + .resolves(buildGitHubFileContent(fixturesPath, 'setup.py')); sandbox.stub(github, 'findFilesByFilenameAndRef').resolves([]); const latestRelease = { tag: new TagName(Version.parse('0.123.4'), 'google-cloud-automl'), @@ -94,6 +108,9 @@ describe('Python', () => { github, component: 'google-cloud-automl', }); + sandbox + .stub(github, 'getFileContentsOnBranch') + .resolves(buildGitHubFileContent(fixturesPath, 'setup.py')); sandbox.stub(github, 'findFilesByFilenameAndRef').resolves([]); const latestRelease = undefined; const release = await strategy.buildReleasePullRequest( @@ -153,6 +170,9 @@ describe('Python', () => { github, component: 'google-cloud-automl', }); + sandbox + .stub(github, 'getFileContentsOnBranch') + .resolves(buildGitHubFileContent(fixturesPath, 'setup.py')); sandbox .stub(github, 'findFilesByFilenameAndRef') .resolves(['src/version.py']); @@ -164,5 +184,52 @@ describe('Python', () => { const updates = release!.updates; assertHasUpdate(updates, 'src/version.py', PythonFileWithVersion); }); + + it('updates changelog.json if present', async () => { + const COMMITS = [ + ...buildMockConventionalCommit( + 'fix(deps): update dependency com.google.cloud:google-cloud-storage to v1.120.0' + ), + ...buildMockConventionalCommit('chore: update deps'), + ...buildMockConventionalCommit('chore!: update a very important dep'), + ...buildMockConventionalCommit( + 'fix(deps): update dependency com.google.cloud:google-cloud-spanner to v1.50.0' + ), + ...buildMockConventionalCommit('chore: update common templates'), + ]; + const strategy = new Python({ + targetBranch: 'main', + github, + component: 'google-cloud-automl', + }); + sandbox.stub(github, 'findFilesByFilenameAndRef').resolves([]); + const getFileContentsStub = sandbox.stub( + github, + 'getFileContentsOnBranch' + ); + getFileContentsStub + .withArgs('changelog.json', 'main') + .resolves(buildGitHubFileContent(fixturesPath, 'changelog.json')); + getFileContentsStub + .withArgs('setup.py', 'main') + .resolves(buildGitHubFileContent(fixturesPath, 'setup.py')); + const latestRelease = undefined; + const release = await strategy.buildReleasePullRequest( + COMMITS, + latestRelease + ); + const updates = release!.updates; + assertHasUpdate(updates, 'CHANGELOG.md', Changelog); + const update = assertHasUpdate(updates, 'changelog.json', ChangelogJson); + const newContent = update.updater.updateContent( + JSON.stringify({entries: []}) + ); + snapshot( + newContent + .replace(/\r\n/g, '\n') // make newline consistent regardless of OS. + .replace(UUID_REGEX, 'abc-123-efd-qwerty') + .replace(ISO_DATE_REGEX, '2023-01-05T16:42:33.446Z') + ); + }); }); }); diff --git a/test/strategies/ruby-yoshi.ts b/test/strategies/ruby-yoshi.ts index 3d8101823..0e2501b42 100644 --- a/test/strategies/ruby-yoshi.ts +++ b/test/strategies/ruby-yoshi.ts @@ -18,7 +18,7 @@ import {GitHub} from '../../src/github'; import {RubyYoshi} from '../../src/strategies/ruby-yoshi'; import * as sinon from 'sinon'; import {assertHasUpdate, safeSnapshot} from '../helpers'; -import {buildMockCommit} from '../helpers'; +import {buildMockConventionalCommit} from '../helpers'; import {TagName} from '../../src/util/tag-name'; import {Version} from '../../src/version'; import {Changelog} from '../../src/updaters/changelog'; @@ -27,15 +27,15 @@ import {VersionRB} from '../../src/updaters/ruby/version-rb'; const sandbox = sinon.createSandbox(); const COMMITS = [ - buildMockCommit( + ...buildMockConventionalCommit( 'fix(deps): update dependency com.google.cloud:google-cloud-storage to v1.120.0 (#1234)', ['path1/foo.rb'] ), - buildMockCommit( + ...buildMockConventionalCommit( 'fix(deps): update dependency com.google.cloud:google-cloud-spanner to v1.50.0', ['path1/foo.rb', 'path2/bar.rb'] ), - buildMockCommit('chore: update common templates'), + ...buildMockConventionalCommit('chore: update common templates'), ]; describe('RubyYoshi', () => { diff --git a/test/strategies/ruby.ts b/test/strategies/ruby.ts index a5bd35d73..c10704ee6 100644 --- a/test/strategies/ruby.ts +++ b/test/strategies/ruby.ts @@ -18,23 +18,24 @@ import {GitHub} from '../../src/github'; import {Ruby} from '../../src/strategies/ruby'; import * as sinon from 'sinon'; import {assertHasUpdate} from '../helpers'; -import {buildMockCommit} from '../helpers'; +import {buildMockConventionalCommit} from '../helpers'; import {TagName} from '../../src/util/tag-name'; import {Version} from '../../src/version'; import {Changelog} from '../../src/updaters/changelog'; import {VersionRB} from '../../src/updaters/ruby/version-rb'; +import {GemfileLock} from '../../src/updaters/ruby/gemfile-lock'; import {PullRequestBody} from '../../src/util/pull-request-body'; const sandbox = sinon.createSandbox(); const COMMITS = [ - buildMockCommit( + ...buildMockConventionalCommit( 'fix(deps): update dependency com.google.cloud:google-cloud-storage to v1.120.0' ), - buildMockCommit( + ...buildMockConventionalCommit( 'fix(deps): update dependency com.google.cloud:google-cloud-spanner to v1.50.0' ), - buildMockCommit('chore: update common templates'), + ...buildMockConventionalCommit('chore: update common templates'), ]; describe('Ruby', () => { @@ -96,9 +97,10 @@ describe('Ruby', () => { latestRelease ); const updates = release!.updates; - expect(updates).lengthOf(2); + expect(updates).lengthOf(3); assertHasUpdate(updates, 'CHANGELOG.md', Changelog); assertHasUpdate(updates, 'lib/google/cloud/automl/version.rb', VersionRB); + assertHasUpdate(updates, 'Gemfile.lock', GemfileLock); }); it('allows overriding version file', async () => { const strategy = new Ruby({ @@ -113,9 +115,10 @@ describe('Ruby', () => { latestRelease ); const updates = release!.updates; - expect(updates).lengthOf(2); + expect(updates).lengthOf(3); assertHasUpdate(updates, 'CHANGELOG.md', Changelog); assertHasUpdate(updates, 'lib/foo/version.rb', VersionRB); + assertHasUpdate(updates, 'Gemfile.lock', GemfileLock); }); // TODO: add tests for tag separator // TODO: add tests for post-processing commit messages diff --git a/test/strategies/rust.ts b/test/strategies/rust.ts index b363439ed..c1fc8632a 100644 --- a/test/strategies/rust.ts +++ b/test/strategies/rust.ts @@ -18,7 +18,7 @@ import {GitHub} from '../../src/github'; import {Rust} from '../../src/strategies/rust'; import * as sinon from 'sinon'; import {buildGitHubFileContent, assertHasUpdate, dateSafe} from '../helpers'; -import {buildMockCommit} from '../helpers'; +import {buildMockConventionalCommit} from '../helpers'; import {TagName} from '../../src/util/tag-name'; import {Version} from '../../src/version'; import {Changelog} from '../../src/updaters/changelog'; @@ -29,13 +29,13 @@ import snapshot = require('snap-shot-it'); const sandbox = sinon.createSandbox(); const COMMITS = [ - buildMockCommit( + ...buildMockConventionalCommit( 'fix(deps): update dependency com.google.cloud:google-cloud-storage to v1.120.0' ), - buildMockCommit( + ...buildMockConventionalCommit( 'fix(deps): update dependency com.google.cloud:google-cloud-spanner to v1.50.0' ), - buildMockCommit('chore: update common templates'), + ...buildMockConventionalCommit('chore: update common templates'), ]; describe('Rust', () => { diff --git a/test/strategies/sfdx.ts b/test/strategies/sfdx.ts new file mode 100644 index 000000000..9231683c6 --- /dev/null +++ b/test/strategies/sfdx.ts @@ -0,0 +1,185 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import {describe, it, afterEach, beforeEach} from 'mocha'; +import {Sfdx} from '../../src/strategies/sfdx'; +import { + buildMockConventionalCommit, + buildGitHubFileContent, + assertHasUpdate, +} from '../helpers'; +import * as nock from 'nock'; +import * as sinon from 'sinon'; +import {GitHub} from '../../src/github'; +import {Version} from '../../src/version'; +import {TagName} from '../../src/util/tag-name'; +import {expect} from 'chai'; +import {Changelog} from '../../src/updaters/changelog'; +import {SfdxProjectJson} from '../../src/updaters/sfdx/sfdx-project-json'; +import * as assert from 'assert'; +import {MissingRequiredFileError, FileNotFoundError} from '../../src/errors'; + +nock.disableNetConnect(); +const sandbox = sinon.createSandbox(); +const fixturesPath = './test/fixtures/strategies/sfdx'; + +describe('Sfdx', () => { + let github: GitHub; + const commits = [ + ...buildMockConventionalCommit( + 'fix(deps): update dependency com.google.cloud:google-cloud-storage to v1.120.0' + ), + ]; + beforeEach(async () => { + github = await GitHub.create({ + owner: 'googleapis', + repo: 'sfdx-test-repo', + defaultBranch: 'main', + }); + }); + afterEach(() => { + sandbox.restore(); + }); + describe('buildReleasePullRequest', () => { + it('returns release PR changes with defaultInitialVersion', async () => { + const expectedVersion = '1.0.0'; + const strategy = new Sfdx({ + targetBranch: 'main', + github, + component: 'google-cloud-automl', + packageName: 'google-cloud-automl', + }); + const latestRelease = undefined; + const release = await strategy.buildReleasePullRequest( + commits, + latestRelease + ); + expect(release!.version?.toString()).to.eql(expectedVersion); + }); + it('builds a release pull request', async () => { + const expectedVersion = '0.123.5'; + const strategy = new Sfdx({ + targetBranch: 'main', + github, + component: 'some-sfdx-package', + packageName: 'some-sfdx-package', + }); + const latestRelease = { + tag: new TagName(Version.parse('0.123.4'), 'some-sfdx-package'), + sha: 'abc123', + notes: 'some notes', + }; + const pullRequest = await strategy.buildReleasePullRequest( + commits, + latestRelease + ); + expect(pullRequest!.version?.toString()).to.eql(expectedVersion); + }); + it('detects a default component', async () => { + const expectedVersion = '0.123.5'; + const strategy = new Sfdx({ + targetBranch: 'main', + github, + }); + const commits = [ + ...buildMockConventionalCommit( + 'fix(deps): update dependency com.google.cloud:google-cloud-storage to v1.120.0' + ), + ]; + const latestRelease = { + tag: new TagName(Version.parse('0.123.4'), 'sfdx-test-repo'), + sha: 'abc123', + notes: 'some notes', + }; + const getFileContentsStub = sandbox.stub( + github, + 'getFileContentsOnBranch' + ); + getFileContentsStub + .withArgs('sfdx-project.json', 'main') + .resolves(buildGitHubFileContent(fixturesPath, 'sfdx-project.json')); + const pullRequest = await strategy.buildReleasePullRequest( + commits, + latestRelease + ); + expect(pullRequest!.version?.toString()).to.eql(expectedVersion); + }); + it('detects a default packageName', async () => { + const expectedVersion = '0.123.5'; + const strategy = new Sfdx({ + targetBranch: 'main', + github, + component: 'abc-123', + }); + const commits = [ + ...buildMockConventionalCommit( + 'fix(deps): update dependency com.google.cloud:google-cloud-storage to v1.120.0' + ), + ]; + const latestRelease = { + tag: new TagName(Version.parse('0.123.4'), 'sfdx-test-repo'), + sha: 'abc123', + notes: 'some notes', + }; + const getFileContentsStub = sandbox.stub( + github, + 'getFileContentsOnBranch' + ); + getFileContentsStub + .withArgs('sfdx-project.json', 'main') + .resolves(buildGitHubFileContent(fixturesPath, 'sfdx-project.json')); + const pullRequest = await strategy.buildReleasePullRequest( + commits, + latestRelease + ); + expect(pullRequest!.version?.toString()).to.eql(expectedVersion); + }); + it('handles missing sfdx-project.json', async () => { + sandbox + .stub(github, 'getFileContentsOnBranch') + .rejects(new FileNotFoundError('stub/path')); + const strategy = new Sfdx({ + targetBranch: 'main', + github, + }); + const latestRelease = { + tag: new TagName(Version.parse('0.123.4'), 'some-sfdx-package'), + sha: 'abc123', + notes: 'some notes', + }; + assert.rejects(async () => { + await strategy.buildReleasePullRequest(commits, latestRelease); + }, MissingRequiredFileError); + }); + }); + describe('buildUpdates', () => { + it('builds common files', async () => { + const strategy = new Sfdx({ + targetBranch: 'main', + github, + component: 'google-cloud-automl', + packageName: 'google-cloud-automl-pkg', + }); + sandbox.stub(github, 'findFilesByFilenameAndRef').resolves([]); + const latestRelease = undefined; + const release = await strategy.buildReleasePullRequest( + commits, + latestRelease + ); + const updates = release!.updates; + assertHasUpdate(updates, 'CHANGELOG.md', Changelog); + assertHasUpdate(updates, 'sfdx-project.json', SfdxProjectJson); + }); + }); +}); diff --git a/test/strategies/simple.ts b/test/strategies/simple.ts index 75e46a5f8..808a3b6d8 100644 --- a/test/strategies/simple.ts +++ b/test/strategies/simple.ts @@ -18,7 +18,7 @@ import {GitHub} from '../../src/github'; import {Simple} from '../../src/strategies/simple'; import * as sinon from 'sinon'; import {assertHasUpdate} from '../helpers'; -import {buildMockCommit} from '../helpers'; +import {buildMockConventionalCommit} from '../helpers'; import {TagName} from '../../src/util/tag-name'; import {Version} from '../../src/version'; import {Changelog} from '../../src/updaters/changelog'; @@ -27,13 +27,13 @@ import {DefaultUpdater} from '../../src/updaters/default'; const sandbox = sinon.createSandbox(); const COMMITS = [ - buildMockCommit( + ...buildMockConventionalCommit( 'fix(deps): update dependency com.google.cloud:google-cloud-storage to v1.120.0' ), - buildMockCommit( + ...buildMockConventionalCommit( 'fix(deps): update dependency com.google.cloud:google-cloud-spanner to v1.50.0' ), - buildMockCommit('chore: update common templates'), + ...buildMockConventionalCommit('chore: update common templates'), ]; describe('Simple', () => { diff --git a/test/strategies/terraform-module.ts b/test/strategies/terraform-module.ts index 13a4a340e..e120d4bb9 100644 --- a/test/strategies/terraform-module.ts +++ b/test/strategies/terraform-module.ts @@ -17,23 +17,24 @@ import {expect} from 'chai'; import {GitHub} from '../../src/github'; import {TerraformModule} from '../../src/strategies/terraform-module'; import * as sinon from 'sinon'; -import {assertHasUpdate, buildMockCommit} from '../helpers'; +import {assertHasUpdate, buildMockConventionalCommit} from '../helpers'; import {TagName} from '../../src/util/tag-name'; import {Version} from '../../src/version'; import {Changelog} from '../../src/updaters/changelog'; import {ReadMe} from '../../src/updaters/terraform/readme'; import {ModuleVersion} from '../../src/updaters/terraform/module-version'; +import {MetadataVersion} from '../../src/updaters/terraform/metadata-version'; const sandbox = sinon.createSandbox(); const COMMITS = [ - buildMockCommit( + ...buildMockConventionalCommit( 'fix(deps): update dependency com.google.cloud:google-cloud-storage to v1.120.0' ), - buildMockCommit( + ...buildMockConventionalCommit( 'fix(deps): update dependency com.google.cloud:google-cloud-spanner to v1.50.0' ), - buildMockCommit('chore: update common templates'), + ...buildMockConventionalCommit('chore: update common templates'), ]; describe('TerraformModule', () => { @@ -120,6 +121,9 @@ describe('TerraformModule', () => { findFilesStub .withArgs('versions.tf.tmpl', 'main', '.') .resolves(['path1/versions.tf.tmpl', 'path2/versions.tf.tmpl']); + findFilesStub + .withArgs('metadata.yaml', 'main', '.') + .resolves(['path1/metadata.yaml', 'path2/metadata.yaml']); const latestRelease = undefined; const release = await strategy.buildReleasePullRequest( COMMITS, @@ -134,6 +138,8 @@ describe('TerraformModule', () => { assertHasUpdate(updates, 'path2/versions.tf', ModuleVersion); assertHasUpdate(updates, 'path1/versions.tf.tmpl', ModuleVersion); assertHasUpdate(updates, 'path2/versions.tf.tmpl', ModuleVersion); + assertHasUpdate(updates, 'path1/metadata.yaml', MetadataVersion); + assertHasUpdate(updates, 'path2/metadata.yaml', MetadataVersion); }); }); }); diff --git a/test/updaters/changelog-json.ts b/test/updaters/changelog-json.ts new file mode 100644 index 000000000..81a03ce84 --- /dev/null +++ b/test/updaters/changelog-json.ts @@ -0,0 +1,97 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import * as snapshot from 'snap-shot-it'; +import {describe, it} from 'mocha'; +import {ChangelogJson} from '../../src/updaters/changelog-json'; +import {Version} from '../../src/version'; +import {parseConventionalCommits} from '../../src/commit'; +import {buildMockCommit} from '../helpers'; + +const UUID_REGEX = + /[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}/g; +const ISO_DATE_REGEX = + /[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]+Z/g; // 2023-01-05T16:42:33.446Z + +describe('changelog.json', () => { + it('prepends new release to empty changelog', async () => { + const oldContent = '{"repository": "foo/bar", "entries": []}'; + const commits = [ + buildMockCommit('feat: some feature'), + buildMockCommit('fix!: some bugfix'), + buildMockCommit('docs(perf)!: some documentation'), + ]; + const conventionalCommits = parseConventionalCommits(commits); + const changelogJson = new ChangelogJson({ + version: Version.parse('14.0.0'), + artifactName: 'foo-artifact', + commits: conventionalCommits, + language: 'JAVA', + }); + const newContent = changelogJson.updateContent(oldContent); + snapshot( + newContent + .replace(/\r\n/g, '\n') // make newline consistent regardless of OS. + .replace(UUID_REGEX, 'abc-123-efd-qwerty') + .replace(ISO_DATE_REGEX, '2023-01-05T16:42:33.446Z') + ); + }); + it('prepends latest release to existing changelog', async () => { + const oldContent = '{"repository": "foo/bar", "entries": [{}, {}]}'; + const commits = [ + buildMockCommit('feat: some feature'), + buildMockCommit('fix: some bugfix'), + buildMockCommit('docs: some documentation'), + ]; + const conventionalCommits = parseConventionalCommits(commits); + const changelogJson = new ChangelogJson({ + version: Version.parse('14.0.0'), + artifactName: 'foo-artifact', + language: 'JAVA', + commits: conventionalCommits, + }); + const newContent = changelogJson.updateContent(oldContent); + snapshot( + newContent + .replace(/\r\n/g, '\n') // make newline consistent regardless of OS. + .replace(UUID_REGEX, 'abc-123-efd-qwerty') + .replace(ISO_DATE_REGEX, '2023-01-05T16:42:33.446Z') + ); + }); + // In discussion with downstream implementers, we decideed that it would + // make it easier to customize the CHANGELOG generated if we pre-parsed + // the PR # suffix that GitHub adds to squashed commits. + it('adds PR # suffix to issues array', async () => { + const oldContent = '{"repository": "foo/bar", "entries": [{}, {}]}'; + const commits = [ + buildMockCommit('feat: some feature'), + buildMockCommit('fix: Support TOML up to v1.0.0-rc.1 spec. (#1837)'), + buildMockCommit('docs: some documentation'), + ]; + const conventionalCommits = parseConventionalCommits(commits); + const changelogJson = new ChangelogJson({ + version: Version.parse('14.0.0'), + artifactName: 'foo-artifact', + language: 'JAVA', + commits: conventionalCommits, + }); + const newContent = changelogJson.updateContent(oldContent); + snapshot( + newContent + .replace(/\r\n/g, '\n') // make newline consistent regardless of OS. + .replace(UUID_REGEX, 'abc-123-efd-qwerty') + .replace(ISO_DATE_REGEX, '2023-01-05T16:42:33.446Z') + ); + }); +}); diff --git a/test/updaters/fixtures/Gemfile.lock b/test/updaters/fixtures/Gemfile.lock new file mode 100644 index 000000000..6a4703891 --- /dev/null +++ b/test/updaters/fixtures/Gemfile.lock @@ -0,0 +1,60 @@ +PATH + remote: . + specs: + foo (0.1.0) + +GEM + remote: https://rubygems.org/ + specs: + ast (2.4.2) + foobar (1.0.1) + diff-lcs (1.5.0) + json (2.6.3) + parallel (1.22.1) + parser (3.1.3.0) + ast (~> 2.4.1) + rainbow (3.1.1) + rake (13.0.6) + regexp_parser (2.6.1) + rexml (3.2.5) + rspec (3.12.0) + rspec-core (~> 3.12.0) + rspec-expectations (~> 3.12.0) + rspec-mocks (~> 3.12.0) + rspec-core (3.12.0) + rspec-support (~> 3.12.0) + rspec-expectations (3.12.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.12.0) + rspec-mocks (3.12.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.12.0) + rspec-support (3.12.0) + rubocop (1.39.0) + json (~> 2.3) + parallel (~> 1.10) + parser (>= 3.1.2.1) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 1.8, < 3.0) + rexml (>= 3.2.5, < 4.0) + rubocop-ast (>= 1.23.0, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 1.4.0, < 3.0) + rubocop-ast (1.24.0) + parser (>= 3.1.1.0) + ruby-progressbar (1.11.0) + unicode-display_width (2.3.0) + +PLATFORMS + ruby + +DEPENDENCIES + bundler + foo! + foobar + rake + rspec + rubocop + +BUNDLED WITH + 2.3.26 diff --git a/test/updaters/fixtures/helm/Chart.yaml b/test/updaters/fixtures/helm/Chart.yaml index a7e1686ad..458b38576 100644 --- a/test/updaters/fixtures/helm/Chart.yaml +++ b/test/updaters/fixtures/helm/Chart.yaml @@ -15,6 +15,7 @@ name: helm-test-repo version: 1.0.0 apiVersion: v2 +# renovate: image=imageName appVersion: 2.0.0 dependencies: - name: another-repo diff --git a/test/updaters/fixtures/metadata.yaml b/test/updaters/fixtures/metadata.yaml new file mode 100644 index 000000000..dccd8a5a3 --- /dev/null +++ b/test/updaters/fixtures/metadata.yaml @@ -0,0 +1,8 @@ +apiVersion: blueprints.cloud.google.com/v1alpha1 +kind: BlueprintMetadata +metadata: + name: foo +spec: + info: + title: bar + version: 2.0.0 diff --git a/test/updaters/fixtures/package-lock-v3-workspace.json b/test/updaters/fixtures/package-lock-v3-workspace.json new file mode 100644 index 000000000..061cac064 --- /dev/null +++ b/test/updaters/fixtures/package-lock-v3-workspace.json @@ -0,0 +1,31 @@ +{ + "name": "release-please", + "version": "11.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "release-please", + "version": "11.1.0" + }, + "node_modules/release-please-foo": { + "resolved": "packages/foo", + "link": true + }, + "node_modules/release-please-bar": { + "resolved": "packages/bar", + "link": true + }, + "packages/foo": { + "name": "release-please-foo", + "version": "1.0.0", + "dependencies": { + "release-please-bar": "1.0.0" + } + }, + "packages/bar": { + "name": "release-please-bar", + "version": "1.0.0" + } + } +} diff --git a/test/updaters/fixtures/package-lock-v3.json b/test/updaters/fixtures/package-lock-v3.json new file mode 100644 index 000000000..43f2ce1b4 --- /dev/null +++ b/test/updaters/fixtures/package-lock-v3.json @@ -0,0 +1,12 @@ +{ + "name": "release-please", + "version": "11.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "release-please", + "version": "11.1.0" + } + } +} diff --git a/test/updaters/fixtures/package-with-dependencies.json b/test/updaters/fixtures/package-with-dependencies.json new file mode 100644 index 000000000..c4b2ee977 --- /dev/null +++ b/test/updaters/fixtures/package-with-dependencies.json @@ -0,0 +1,52 @@ +{ + "name": "yargs-parser", + "version": "13.0.0", + "description": "the mighty option parser used by yargs", + "main": "index.js", + "scripts": { + "test": "nyc mocha test/*.js", + "posttest": "standard", + "coverage": "nyc report --reporter=text-lcov | coveralls", + "release": "standard-version" + }, + "repository": { + "url": "git@github.com:yargs/yargs-parser.git" + }, + "keywords": [ + "argument", + "parser", + "yargs", + "command", + "cli", + "parsing", + "option", + "args", + "argument" + ], + "author": "Ben Coe ", + "license": "ISC", + "devDependencies": { + "chai": "^4.2.0", + "coveralls": "^3.0.2", + "mocha": "^5.2.0", + "nyc": "^13.0.1", + "standard": "^12.0.1" + }, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "optionalDependencies": { + "foo": "~0.0.7" + }, + "peerDependencies": { + "bar": ">= 1.0.0" + }, + "files": [ + "lib", + "index.js" + ], + "engine": { + "node": ">=6" + } +} diff --git a/test/updaters/fixtures/php/manifest.json b/test/updaters/fixtures/php/manifest.json deleted file mode 100644 index 9524b7f98..000000000 --- a/test/updaters/fixtures/php/manifest.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "lang": "php", - "friendlyLang": "PHP", - "libraryTitle": "Google Cloud Client Library", - "moduleName": "google-cloud-php", - "markdown": "php", - "defaultModule": "google-cloud", - "modules": [ - { - "id": "google-cloud", - "name": "google/cloud", - "defaultService": "servicebuilder", - "versions": [ - "v0.7.1", - "v0.7.0", - "v0.6.0", - "v0.5.1", - "v0.5.0", - "v0.4.1", - "v0.4.0", - "v0.3.0", - "master" - ] - }, - { - "id": "access-context-manager", - "name": "google/access-context-manager", - "defaultService": "accesscontextmanager/readme", - "versions": [ - "v0.1.1", - "v0.1.0", - "master" - ] - }, - { - "id": "analytics-admin", - "name": "google/analytics-admin", - "defaultService": "analyticsadmin/readme", - "versions": [ - "v0.4.1", - "v0.4.0", - "v0.3.0", - "v0.2.0", - "v0.1.0", - "master" - ] - } - ], - "content": "json", - "home": "home.html", - "package": { - "title": "Packagist", - "href": "https://packagist.org/packages/google/cloud" - } -} \ No newline at end of file diff --git a/test/updaters/fixtures/pom-trailing-newline.xml b/test/updaters/fixtures/pom-trailing-newline.xml new file mode 100644 index 000000000..e8b4118b0 --- /dev/null +++ b/test/updaters/fixtures/pom-trailing-newline.xml @@ -0,0 +1,81 @@ + + + 4.0.0 + + + com.google.auth + google-auth-library-parent + 0.16.2 + ../pom.xml + + + com.google.auth + google-auth-library-appengine + 0.16.2 + Google Auth Library for Java - Google App Engine + + + + ossrh + https://oss.sonatype.org/content/repositories/snapshots + + + + + java + javatests + + + org.sonatype.plugins + nexus-staging-maven-plugin + + + org.apache.maven.plugins + maven-source-plugin + + + org.apache.maven.plugins + maven-javadoc-plugin + + + + + + + com.google.auth + google-auth-library-credentials + + + com.google.auth + google-auth-library-oauth2-http + + + com.google.http-client + google-http-client + + + com.google.http-client + google-http-client-jackson2 + + + com.google.appengine + appengine-api-1.0-sdk + provided + + + com.google.guava + guava + + + junit + junit + test + + + com.google.auth + google-auth-library-oauth2-http + test-jar + test + + + diff --git a/test/updaters/fixtures/setup-big-version.cfg b/test/updaters/fixtures/setup-big-version.cfg new file mode 100644 index 000000000..a78678a12 --- /dev/null +++ b/test/updaters/fixtures/setup-big-version.cfg @@ -0,0 +1,44 @@ +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +[metadata] +name = google-crc32c +version = 123.456.789 +description = A python wrapper of the C library 'Google CRC32C' +url = https://github.com/googleapis/python-crc32c +long_description = file: README.md +long_description_content_type = text/markdown +author = Google LLC +author_email = googleapis-packages@google.com + +license = Apache 2.0 +platforms = Posix, MacOS X, Windows +classifiers = + Development Status :: 4 - Beta + Intended Audience :: Developers + License :: OSI Approved :: Apache Software License + Operating System :: OS Independent + Programming Language :: Python :: 3 + Programming Language :: Python :: 3.5 + Programming Language :: Python :: 3.6 + Programming Language :: Python :: 3.7 + Programming Language :: Python :: 3.8 + +[options] +zip_safe = True +python_requires = >=3.5 + +[options.extras_require] +testing = pytest + diff --git a/test/updaters/fixtures/sfdx-project.json b/test/updaters/fixtures/sfdx-project.json new file mode 100644 index 000000000..6f2e8b638 --- /dev/null +++ b/test/updaters/fixtures/sfdx-project.json @@ -0,0 +1,9 @@ +{ + "packageDirectories": [ + { + "default": true, + "versionNumber": "1.0.0.NEXT" + } + ], + "name": "sfdx-test-repo" +} diff --git a/test/updaters/fixtures/toml/invalid.txt b/test/updaters/fixtures/toml/invalid.txt new file mode 100644 index 000000000..1acd2d2c2 --- /dev/null +++ b/test/updaters/fixtures/toml/invalid.txt @@ -0,0 +1 @@ +invalid = diff --git a/test/updaters/fixtures/toml/v1.0.0.toml b/test/updaters/fixtures/toml/v1.0.0.toml new file mode 100644 index 000000000..4f51715d5 --- /dev/null +++ b/test/updaters/fixtures/toml/v1.0.0.toml @@ -0,0 +1,18 @@ +[package] +version = '1.0.0' + +[v1spec] +# taken from toml.io#Arrays examples +integers = [ 1, 2, 3 ] +colors = [ "red", "yellow", "green" ] +nested_arrays_of_ints = [ [ 1, 2 ], [3, 4, 5] ] +nested_mixed_array = [ [ 1, 2 ], ["a", "b", "c"] ] +string_array = [ "all", 'strings', """are the same""", '''type''' ] + +[heterogenous] +# Mixed-type arrays are allowed +numbers = [ 0.1, 0.2, 0.5, 1, 2, 5 ] +contributors = [ + "Foo Bar ", + { name = "Baz Qux", email = "bazqux@example.com", url = "https://example.com/bazqux" } +] diff --git a/test/updaters/fixtures/version-with-long-patch.rb b/test/updaters/fixtures/version-with-long-patch.rb new file mode 100644 index 000000000..84c2070ca --- /dev/null +++ b/test/updaters/fixtures/version-with-long-patch.rb @@ -0,0 +1,21 @@ +# Copyright 2019 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module Google + module Cloud + module Bigtable + VERSION = "0.6.10".freeze + end + end +end diff --git a/test/updaters/fixtures/version-with-prerelease.rb b/test/updaters/fixtures/version-with-prerelease.rb new file mode 100644 index 000000000..014e71153 --- /dev/null +++ b/test/updaters/fixtures/version-with-prerelease.rb @@ -0,0 +1,21 @@ +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module Google + module Cloud + module Bigtable + VERSION = "10.0.0.alpha1".freeze + end + end +end diff --git a/test/updaters/gemfile-lock.ts b/test/updaters/gemfile-lock.ts new file mode 100644 index 000000000..3d1e7b322 --- /dev/null +++ b/test/updaters/gemfile-lock.ts @@ -0,0 +1,107 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import {readFileSync} from 'fs'; +import {resolve} from 'path'; +import * as snapshot from 'snap-shot-it'; +import {describe, it} from 'mocha'; +import {expect} from 'chai'; +import {GemfileLock} from '../../src/updaters/ruby/gemfile-lock'; +import {Version} from '../../src/version'; + +const fixturesPath = './test/updaters/fixtures'; + +describe('Gemfile.lock', () => { + describe('updateContent', () => { + // gemName, newVersion, existingContent, expected, shouldUpdate, description + // prettier-ignore + const testTable: [string, string, string, string, boolean, string][] = [ + ['foo', '0.2.0', 'foo (0.1.0)', 'foo (0.2.0)', true, 'minor'], + ['foo', '0.2.1', 'foo (0.2.0)', 'foo (0.2.1)', true, 'patch'], + ['foo', '0.2.11', 'foo (0.2.1)', 'foo (0.2.11)', true, 'long patch'], + ['foo', '0.3.0-alpha1', 'foo (0.2.0)', 'foo (0.3.0.pre.alpha1)', true, 'prerelease'], + ['foo', '0.3.0-alpha2', 'foo (0.3.0.pre.alpha1)', 'foo (0.3.0.pre.alpha2)', true, 'prerelease bump'], + ['foo', '1.0.0-beta', 'foo (0.3.0.pre.alpha2)', 'foo (1.0.0.pre.beta)', true, 'beta'], + ['foo', '1.0.0', 'foo (1.0.0.beta)', 'foo (1.0.0)', true, 'major'], + ['foo', '2.0.22', 'foo (1.0.0)', 'foo (2.0.22)', true, 'major bump with long patch'], + ['foo', '2.0.22', 'foo (1.0.0-alpha1)', 'foo (2.0.22)', true, 'update semantic version'], + ['foo', '1.0.0', 'something', 'something', false, 'text to ignore'], + ['foo', '1.0.0', 'foo 1.0.0', 'foo 1.0.0', false, 'no parantheses around version'], + ['foo', '1.0.0', 'barfoo (1.0.0)', 'barfoo (1.0.0)', false, 'prefixed gem name'], + ['foo', '1.0.0', 'foobar (0.1.0)', 'foobar (0.1.0)', false, 'suffixed gem name'], + ['', '1.0.0', 'foobar (0.1.0)', 'foobar (0.1.0)', false, 'empty gem name'], + ]; + + testTable.forEach( + ([ + gemName, + newVersion, + existingContent, + expected, + shouldUpdate, + description, + ]) => { + it(`should ${ + shouldUpdate ? 'update' : 'not update' + } for ${description}`, () => { + const version = new GemfileLock({ + version: Version.parse(newVersion), + gemName, + }); + const result = version.updateContent(existingContent); + expect(result).to.equal(expected); + }); + } + ); + + it('does not update anything if gem name is not provided', async () => { + const oldContent = readFileSync( + resolve(fixturesPath, './Gemfile.lock'), + 'utf8' + ).replace(/\r\n/g, '\n'); + const version = new GemfileLock({ + version: Version.parse('0.2.0'), + gemName: '', + }); + const newContent = version.updateContent(oldContent); + snapshot(newContent); + }); + + it('updates version in Gemfile.lock', async () => { + const oldContent = readFileSync( + resolve(fixturesPath, './Gemfile.lock'), + 'utf8' + ).replace(/\r\n/g, '\n'); + const version = new GemfileLock({ + version: Version.parse('0.2.0'), + gemName: 'foo', + }); + const newContent = version.updateContent(oldContent); + snapshot(newContent); + }); + + it('updates prerelease in Gemfile.lock', async () => { + const oldContent = readFileSync( + resolve(fixturesPath, './Gemfile.lock'), + 'utf8' + ).replace(/\r\n/g, '\n'); + const version = new GemfileLock({ + version: Version.parse('0.2.0-alpha'), + gemName: 'foo', + }); + const newContent = version.updateContent(oldContent); + snapshot(newContent); + }); + }); +}); diff --git a/test/updaters/generic-toml.ts b/test/updaters/generic-toml.ts new file mode 100644 index 000000000..dfb895ca7 --- /dev/null +++ b/test/updaters/generic-toml.ts @@ -0,0 +1,93 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import {readFileSync} from 'fs'; +import {resolve} from 'path'; +import * as snapshot from 'snap-shot-it'; +import {describe, it} from 'mocha'; +import {Version} from '../../src/version'; +import {expect, assert} from 'chai'; +import {GenericToml} from '../../src/updaters/generic-toml'; + +const fixturesPath = './test/updaters/fixtures'; + +describe('GenericToml', () => { + describe('updateContent', () => { + it('updates matching entry', async () => { + const oldContent = readFileSync( + resolve(fixturesPath, './Cargo.toml'), + 'utf8' + ).replace(/\r\n/g, '\n'); + const updater = new GenericToml( + '$.package.version', + Version.parse('v2.3.4') + ); + const newContent = updater.updateContent(oldContent); + snapshot(newContent); + }); + it('updates deep entry in toml', async () => { + const oldContent = readFileSync( + resolve(fixturesPath, './Cargo.toml'), + 'utf8' + ).replace(/\r\n/g, '\n'); + const updater = new GenericToml( + "$['dev-dependencies']..version", + Version.parse('v2.3.4') + ); + const newContent = updater.updateContent(oldContent); + snapshot(newContent); + }); + it('ignores non-matching entry', async () => { + const oldContent = readFileSync( + resolve(fixturesPath, './Cargo.toml'), + 'utf8' + ).replace(/\r\n/g, '\n'); + const updater = new GenericToml('$.nonExistent', Version.parse('v2.3.4')); + const newContent = updater.updateContent(oldContent); + expect(newContent).to.eql(oldContent); + }); + it('warns on invalid jsonpath', async () => { + const oldContent = readFileSync( + resolve(fixturesPath, './Cargo.toml'), + 'utf8' + ).replace(/\r\n/g, '\n'); + const updater = new GenericToml('bad jsonpath', Version.parse('v2.3.4')); + assert.throws(() => { + updater.updateContent(oldContent); + }); + }); + it('ignores invalid file', async () => { + const oldContent = readFileSync( + resolve(fixturesPath, './toml/invalid.txt'), + 'utf8' + ).replace(/\r\n/g, '\n'); + const updater = new GenericToml('$.boo', Version.parse('v2.3.4')); + const newContent = updater.updateContent(oldContent); + expect(newContent).to.eql(oldContent); + }); + it('updates matching entry with TOML v1.0.0 spec', async () => { + const oldContent = readFileSync( + resolve(fixturesPath, './toml/v1.0.0.toml'), + 'utf8' + ).replace(/\r\n/g, '\n'); + const updater = new GenericToml( + '$.package.version', + Version.parse('v2.3.4') + ); + const newContent = updater.updateContent(oldContent); + expect(newContent).not.to.eql(oldContent); + snapshot(newContent); + }); + }); +}); diff --git a/test/updaters/php-manifest.ts b/test/updaters/metadata.ts similarity index 61% rename from test/updaters/php-manifest.ts rename to test/updaters/metadata.ts index f66e9ffb5..f462844d8 100644 --- a/test/updaters/php-manifest.ts +++ b/test/updaters/metadata.ts @@ -1,4 +1,4 @@ -// Copyright 2021 Google LLC +// Copyright 2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,25 +16,22 @@ import {readFileSync} from 'fs'; import {resolve} from 'path'; import * as snapshot from 'snap-shot-it'; import {describe, it} from 'mocha'; -import {PHPManifest} from '../../src/updaters/php/php-manifest'; +import {MetadataVersion} from '../../src/updaters/terraform/metadata-version'; import {Version} from '../../src/version'; -const fixturesPath = './test/updaters/fixtures/php'; +const fixturesPath = './test/updaters/fixtures'; -describe('PHPManifest', () => { +describe('metadata.yaml', () => { describe('updateContent', () => { - it('update version in docs manifest', async () => { - const versions = new Map(); - versions.set('google/access-context-manager', Version.parse('0.2.0')); + it('updates version in metadata.yaml', async () => { const oldContent = readFileSync( - resolve(fixturesPath, './manifest.json'), + resolve(fixturesPath, './metadata.yaml'), 'utf8' ).replace(/\r\n/g, '\n'); - const composer = new PHPManifest({ - version: Version.parse('0.8.0'), - versionsMap: versions, + const version = new MetadataVersion({ + version: Version.parse('2.1.0'), }); - const newContent = composer.updateContent(oldContent); + const newContent = version.updateContent(oldContent); snapshot(newContent); }); }); diff --git a/test/updaters/package-json.ts b/test/updaters/package-json.ts index fd52cae8b..00a4861a9 100644 --- a/test/updaters/package-json.ts +++ b/test/updaters/package-json.ts @@ -17,7 +17,7 @@ import {resolve} from 'path'; import * as snapshot from 'snap-shot-it'; import {describe, it} from 'mocha'; import {PackageJson} from '../../src/updaters/node/package-json'; -import {Version} from '../../src/version'; +import {Version, VersionsMap} from '../../src/version'; const fixturesPath = './test/updaters/fixtures'; @@ -34,5 +34,23 @@ describe('PackageJson', () => { const newContent = packageJson.updateContent(oldContent); snapshot(newContent.replace(/\r\n/g, '\n')); }); + + it('updates dependency versions', async () => { + const oldContent = readFileSync( + resolve(fixturesPath, './package-with-dependencies.json'), + 'utf8' + ); + const versionsMap: VersionsMap = new Map(); + versionsMap.set('camelcase', Version.parse('6.0.0')); + versionsMap.set('chai', Version.parse('4.2.1')); + versionsMap.set('foo', Version.parse('0.1.0')); + versionsMap.set('bar', Version.parse('2.3.4')); + const packageJson = new PackageJson({ + version: Version.parse('14.0.0'), + versionsMap, + }); + const newContent = packageJson.updateContent(oldContent); + snapshot(newContent.replace(/\r\n/g, '\n')); + }); }); }); diff --git a/test/updaters/package-lock-json.ts b/test/updaters/package-lock-json.ts index 1c5a4cc30..71e087440 100644 --- a/test/updaters/package-lock-json.ts +++ b/test/updaters/package-lock-json.ts @@ -49,4 +49,36 @@ describe('PackageLockJson', () => { snapshot(newContent.replace(/\r\n/g, '\n')); }); }); + + describe('updateContent v3', () => { + it('updates the package version', async () => { + const oldContent = readFileSync( + resolve(fixturesPath, './package-lock-v3.json'), + 'utf8' + ); + const packageJson = new PackageLockJson({ + version: Version.parse('14.0.0'), + }); + const newContent = packageJson.updateContent(oldContent); + snapshot(newContent.replace(/\r\n/g, '\n')); + }); + }); + + describe('updateContent v3 monorepo', () => { + it('updates the package version', async () => { + const oldContent = readFileSync( + resolve(fixturesPath, './package-lock-v3-workspace.json'), + 'utf8' + ); + const versionsMap = new Map(); + versionsMap.set('release-please-foo', new Version(2, 0, 0)); + versionsMap.set('release-please-bar', new Version(3, 0, 0)); + const packageJson = new PackageLockJson({ + version: Version.parse('14.0.0'), + versionsMap, + }); + const newContent = packageJson.updateContent(oldContent); + snapshot(newContent.replace(/\r\n/g, '\n')); + }); + }); }); diff --git a/test/updaters/php-composer-update-packages.ts b/test/updaters/php-composer-update-packages.ts index 08059c1ae..7fc9c6369 100644 --- a/test/updaters/php-composer-update-packages.ts +++ b/test/updaters/php-composer-update-packages.ts @@ -21,32 +21,34 @@ import {Version, VersionsMap} from '../../src/version'; describe('PHPComposer', () => { describe('updateContent', () => { it('does not update a version when version is the same', async () => { - const oldContent = '{"version":"1.0.0","replace":{"version":"1.0.0"}}'; + const oldContent = '{"version":"1.0.0","replace":{"my/package":"1.0.0"}}'; const version = Version.parse('1.0.0'); const versionsMap: VersionsMap = new Map(); + versionsMap.set('my/package', version); + const newContent = new RootComposerUpdatePackages({ version, versionsMap, }).updateContent(oldContent); expect(newContent).to.eq( - '{"version":"1.0.0","replace":{"version":"1.0.0"}}' + '{"version":"1.0.0","replace":{"my/package":"1.0.0"}}' ); snapshot(newContent); }); it('update all versions in composer.json', async () => { - const oldContent = '{"version":"0.0.0","replace":{"version":"0.0.0"}}'; + const oldContent = '{"version":"0.0.0","replace":{"my/package":"0.0.0"}}'; const version = Version.parse('1.0.0'); const versionsMap: VersionsMap = new Map(); - versionsMap.set('version', version); + versionsMap.set('my/package', version); const newContent = new RootComposerUpdatePackages({ version, @@ -54,7 +56,7 @@ describe('PHPComposer', () => { }).updateContent(oldContent); expect(newContent).to.eq( - '{"version":"1.0.0","replace":{"version":"1.0.0"}}' + '{"version":"1.0.0","replace":{"my/package":"1.0.0"}}' ); snapshot(newContent); @@ -79,40 +81,40 @@ describe('PHPComposer', () => { snapshot(newContent); }); - it('update replace version in composer.json when version is present', async () => { - const oldContent = '{"replace":{"version":"0.0.0"}}'; + it('update replace package in composer.json when package is set in version map', async () => { + const oldContent = '{"replace":{"my/package":"0.0.0"}}'; const version = Version.parse('1.0.0'); const versionsMap: VersionsMap = new Map(); - versionsMap.set('version', version); + versionsMap.set('my/package', version); const newContent = new RootComposerUpdatePackages({ version, versionsMap, }).updateContent(oldContent); - expect(newContent).to.eq('{"replace":{"version":"1.0.0"}}'); + expect(newContent).to.eq('{"replace":{"my/package":"1.0.0"}}'); snapshot(newContent); }); - it('update replace version in composer.json when version is missing', async () => { + it('update replace package in composer.json when package is missing', async () => { const oldContent = '{"replace":{}}'; const version = Version.parse('1.0.0'); const versionsMap: VersionsMap = new Map(); - versionsMap.set('version', version); + versionsMap.set('my/package', version); const newContent = new RootComposerUpdatePackages({ version, versionsMap, }).updateContent(oldContent); - expect(newContent).to.eq('{"replace":{"version":"1.0.0"}}'); + expect(newContent).to.eq('{"replace":{"my/package":"1.0.0"}}'); snapshot(newContent); }); diff --git a/test/updaters/pom-xml.ts b/test/updaters/pom-xml.ts index e218dd856..32004f10c 100644 --- a/test/updaters/pom-xml.ts +++ b/test/updaters/pom-xml.ts @@ -59,5 +59,15 @@ describe('PomXml', () => { const newContent = updater.updateContent(oldContent); snapshot(newContent); }); + + it('preserves trailing newlines', async () => { + const oldContent = readFileSync( + resolve(fixturesPath, './pom-trailing-newline.xml'), + 'utf8' + ).replace(/\r\n/g, '\n'); + const updater = new PomXml(Version.parse('v2.3.4')); + const newContent = updater.updateContent(oldContent); + snapshot(newContent); + }); }); }); diff --git a/test/updaters/root-composer-update-packages.ts b/test/updaters/root-composer-update-packages.ts index dbf59f8ae..b87b1931c 100644 --- a/test/updaters/root-composer-update-packages.ts +++ b/test/updaters/root-composer-update-packages.ts @@ -16,6 +16,7 @@ import {readFileSync} from 'fs'; import {resolve} from 'path'; import * as snapshot from 'snap-shot-it'; import {describe, it} from 'mocha'; +import {expect} from 'chai'; import {RootComposerUpdatePackages} from '../../src/updaters/php/root-composer-update-packages'; import {Version} from '../../src/version'; @@ -38,5 +39,21 @@ describe('composer-update-package.json', () => { const newContent = composer.updateContent(oldContent); snapshot(newContent); }); + it('updates version in composer if it exists', async () => { + const composer = new RootComposerUpdatePackages({ + version: Version.parse('1.0.0'), + }); + const newContent = composer.updateContent('{"version": "0.8.0"}'); + expect(newContent).to.eql('{"version":"1.0.0"}'); + snapshot(newContent); + }); + it('does not update version in composer if it does not exist', async () => { + const composer = new RootComposerUpdatePackages({ + version: Version.parse('1.0.0'), + }); + const newContent = composer.updateContent('{}'); + expect(newContent).to.eql('{}'); + snapshot(newContent); + }); }); }); diff --git a/test/updaters/ruby/common.ts b/test/updaters/ruby/common.ts new file mode 100644 index 000000000..1ccaf4544 --- /dev/null +++ b/test/updaters/ruby/common.ts @@ -0,0 +1,115 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import {describe, it} from 'mocha'; +import {expect} from 'chai'; +import { + resolveRubyGemfileLockVersion, + stringifyRubyVersion, +} from '../../../src/updaters/ruby/common'; +import {Version} from '../../../src/version'; + +describe('ruby-common', () => { + describe('resolveRubyGemfileLockVersion', () => { + // input, expected + const testTable: [string, string][] = [ + ['0.0.0', '0.0.0'], + ['1.2.3', '1.2.3'], + ['15.10.22', '15.10.22'], + ['1.0.0-alpha', '1.0.0.pre.alpha'], + ['1.0.0-alpha1', '1.0.0.pre.alpha1'], + ['2.0.0-rc1', '2.0.0.pre.rc1'], + ]; + + testTable.forEach(([input, expected]) => { + it(`${input} should resolve to ${expected}`, () => { + expect( + resolveRubyGemfileLockVersion(Version.parse(input).toString()) + ).to.equal(expected); + }); + }); + }); + + describe('stringifyRubyVersion', () => { + // input, expected + const testTable: [string, string][] = [ + ['0.2.0', '0.2.0'], + ['1.2.3', '1.2.3'], + ['1.2.10', '1.2.10'], + ['15.10.22', '15.10.22'], + ['1.0.0-alpha', '1.0.0-alpha'], + ['1.0.0-alpha1', '1.0.0-alpha1'], + ['2.0.0-rc1', '2.0.0-rc1'], + ]; + + testTable.forEach(([input, expected]) => { + it(`${input} should equal ${expected}`, () => { + expect(stringifyRubyVersion(Version.parse(input))).to.equal(expected); + }); + }); + + describe('combined with resolve resolveRubyGemfileLockVersion', () => { + // input, expected + const testTable: [string, string][] = [ + ['0.2.0', '0.2.0'], + ['1.2.3', '1.2.3'], + ['1.2.10', '1.2.10'], + ['15.10.22', '15.10.22'], + ['1.0.0-alpha', '1.0.0.pre.alpha'], + ['1.0.0-alpha1', '1.0.0.pre.alpha1'], + ['2.0.0-rc1', '2.0.0.pre.rc1'], + ]; + + testTable.forEach(([input, expected]) => { + it(`${input} combined with resolveRubyGemfileLockVersion should equal ${expected}`, () => { + const versionString = stringifyRubyVersion(Version.parse(input)); + expect(resolveRubyGemfileLockVersion(versionString)).to.equal( + expected + ); + }); + }); + }); + + describe('with dot prelease seperator', () => { + const testTable: [string, string][] = [ + ['0.2.0', '0.2.0'], + ['1.2.3', '1.2.3'], + ['1.2.10', '1.2.10'], + ['15.10.22', '15.10.22'], + ['1.0.0-alpha', '1.0.0.alpha'], + ['1.0.0-alpha1', '1.0.0.alpha1'], + ['2.0.0-beta', '2.0.0.beta'], + ['2.0.0-rc1', '2.0.0.rc1'], + ]; + + testTable.forEach(([input, expected]) => { + it(`${input} should equal ${expected}`, () => { + expect(stringifyRubyVersion(Version.parse(input), true)).to.equal( + expected + ); + }); + + it(`${input} combined with resolveRubyGemfileLockVersion should equal ${expected}`, () => { + const versionString = stringifyRubyVersion( + Version.parse(input), + true + ); + expect(resolveRubyGemfileLockVersion(versionString)).to.equal( + expected + ); + }); + }); + }); + }); +}); diff --git a/test/updaters/setup-cfg.ts b/test/updaters/setup-cfg.ts index 6f2fa6b4f..8fca6e45e 100644 --- a/test/updaters/setup-cfg.ts +++ b/test/updaters/setup-cfg.ts @@ -34,5 +34,16 @@ describe('setup.cfg', () => { const newContent = version.updateContent(oldContent); snapshot(newContent); }); + it('updates big version in setup.cfg', async () => { + const oldContent = readFileSync( + resolve(fixturesPath, './setup-big-version.cfg'), + 'utf8' + ).replace(/\r\n/g, '\n'); + const version = new SetupCfg({ + version: Version.parse('0.6.0'), + }); + const newContent = version.updateContent(oldContent); + snapshot(newContent); + }); }); }); diff --git a/test/updaters/sfdx-project-json.ts b/test/updaters/sfdx-project-json.ts new file mode 100644 index 000000000..1678e4be2 --- /dev/null +++ b/test/updaters/sfdx-project-json.ts @@ -0,0 +1,48 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import {readFileSync} from 'fs'; +import {resolve} from 'path'; +import * as snapshot from 'snap-shot-it'; +import {describe, it} from 'mocha'; +import {Version} from '../../src/version'; +import { + SfdxProjectJson, + SfdxProjectFile, +} from '../../src/updaters/sfdx/sfdx-project-json'; +import {expect} from 'chai'; + +const fixturesPath = './test/updaters/fixtures/'; + +describe('SfdxProjectJson', () => { + describe('updateContent', () => { + it('updates version in sfdx-project.json', async () => { + const oldContent = readFileSync( + resolve(fixturesPath, 'sfdx-project.json'), + 'utf8' + ).replace(/\r\n/g, '\n'); + const versions = new Map(); + const pom = new SfdxProjectJson({ + versionsMap: versions, + version: Version.parse('v2.3.4'), + }); + const newContent = pom.updateContent(oldContent); + snapshot(newContent); + const parsedNewContent = JSON.parse(newContent) as SfdxProjectFile; + expect(parsedNewContent.packageDirectories[0].versionNumber).to.equal( + '2.3.4.NEXT' + ); + }); + }); +}); diff --git a/test/updaters/version-rb.ts b/test/updaters/version-rb.ts index d943920a2..ed5e87ec5 100644 --- a/test/updaters/version-rb.ts +++ b/test/updaters/version-rb.ts @@ -16,6 +16,7 @@ import {readFileSync} from 'fs'; import {resolve} from 'path'; import * as snapshot from 'snap-shot-it'; import {describe, it} from 'mocha'; +import {expect} from 'chai'; import {VersionRB} from '../../src/updaters/ruby/version-rb'; import {Version} from '../../src/version'; @@ -23,6 +24,37 @@ const fixturesPath = './test/updaters/fixtures'; describe('version.rb', () => { describe('updateContent', () => { + // newVersion, existingContent, expected, shouldUpdate, description + const testTable: [string, string, string, boolean, string][] = [ + ['0.2.0', "'0.1.0'", "'0.2.0'", true, 'single quotes'], + ['0.2.0', '"0.1.0"', '"0.2.0"', true, 'double quotes'], + ['0.2.0', '"0.1.0"', '"0.2.0"', true, 'minor'], + ['0.2.1', '"0.2.0"', '"0.2.1"', true, 'patch'], + ['0.2.11', '"0.2.10"', '"0.2.11"', true, 'long patch'], + ['1.0.0-alpha1', '"0.9.0"', '"1.0.0-alpha1"', true, 'prerelease'], + ['1.0.0-beta', '"1.0.0-alpha1"', '"1.0.0-beta"', true, 'prerelease bump'], + ['1.0.0', '"1.0.0.beta"', '"1.0.0"', true, 'major'], + ['1.0.1', '"1.0.0"', '"1.0.1"', true, 'major patch'], + ['1.0.0', '"1.0"', '"1.0"', false, 'ignored'], + ['1.0.0', 'something', 'something', false, 'random text'], + ['1.0.0', "'0.1'", "'0.1'", false, 'invalid version single quoted'], + ['1.0.0', '"0.1"', '"0.1"', false, 'invalid version double quoted'], + ]; + + testTable.forEach( + ([newVersion, existingContent, expected, shouldUpdate, description]) => { + it(`should ${ + shouldUpdate ? 'update' : 'not update' + } for ${description}`, () => { + const version = new VersionRB({ + version: Version.parse(newVersion), + }); + const result = version.updateContent(existingContent); + expect(result).to.equal(expected); + }); + } + ); + it('updates version in version.rb', async () => { const oldContent = readFileSync( resolve(fixturesPath, './version.rb'), @@ -48,5 +80,29 @@ describe('version.rb', () => { const newContent = version.updateContent(oldContent); snapshot(newContent); }); + + it('updates long patch versions in version.rb', async () => { + const oldContent = readFileSync( + resolve(fixturesPath, './version-with-long-patch.rb'), + 'utf8' + ).replace(/\r\n/g, '\n'); + const version = new VersionRB({ + version: Version.parse('0.6.11'), + }); + const newContent = version.updateContent(oldContent); + snapshot(newContent); + }); + + it('updates prerelease versions in version.rb', async () => { + const oldContent = readFileSync( + resolve(fixturesPath, './version-with-prerelease.rb'), + 'utf8' + ).replace(/\r\n/g, '\n'); + const version = new VersionRB({ + version: Version.parse('10.0.0-alpha1'), + }); + const newContent = version.updateContent(oldContent); + snapshot(newContent); + }); }); }); diff --git a/test/util/commit-exclude.ts b/test/util/commit-exclude.ts new file mode 100644 index 000000000..5f3f647ba --- /dev/null +++ b/test/util/commit-exclude.ts @@ -0,0 +1,137 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import {Commit} from '../../src'; +import { + CommitExclude, + CommitExcludeConfig, +} from '../../src/util/commit-exclude'; +import {expect} from 'chai'; + +describe('commit-exclude', () => { + const commitsPerPath: Record = { + '.': [ + { + sha: 'pack1Pack2', + message: 'commit pack1Pack2', + files: ['pkg1/foo.txt', 'pkg2/bar.txt'], + }, + { + sha: 'rootCommit', + message: 'commit root', + files: ['foo.txt'], + }, + { + sha: 'pack3', + message: 'commit pack3', + files: ['pkg3/bar/foo.txt'], + }, + ], + pkg1: [ + { + sha: 'pack1Pack2', + message: 'commit pack1Pack2', + files: ['pkg1/foo.txt', 'pkg2/bar.txt'], + }, + ], + pkg2: [ + { + sha: 'pack1Pack2', + message: 'commit pack1Pack2', + files: ['pkg1/foo.txt', 'pkg2/bar.txt'], + }, + ], + pkg3: [ + { + sha: 'pack3', + message: 'commit pack3', + files: ['pkg3/foo.txt'], + }, + { + sha: 'pack3sub', + message: 'commit pack3sub', + files: ['pkg3/bar/foo.txt'], + }, + ], + pkg4: [ + { + sha: 'pack3', + message: 'commit pack3', + files: ['pkg3/foo.txt'], + }, + { + sha: 'pack3sub', + message: 'commit pack3sub', + files: ['pkg3/bar/foo.txt'], + }, + ], + }; + + it('should not exclude anything if paths are empty', () => { + const config: Record = {}; + const commitExclude = new CommitExclude(config); + const newCommitsPerPath = commitExclude.excludeCommits(commitsPerPath); + expect(newCommitsPerPath['.'].length).to.equal(3); + expect(newCommitsPerPath['pkg1'].length).to.equal(1); + expect(newCommitsPerPath['pkg2'].length).to.equal(1); + expect(newCommitsPerPath['pkg3'].length).to.equal(2); + }); + + it('should not exclude only if all files are from excluded path', () => { + const config: Record = { + '.': {excludePaths: ['pkg3', 'pkg1']}, + pkg3: {excludePaths: ['pkg3/bar']}, + }; + const commitExclude = new CommitExclude(config); + const newCommitsPerPath = commitExclude.excludeCommits(commitsPerPath); + expect(newCommitsPerPath['.'].length).to.equal(2); + expect(newCommitsPerPath['pkg1'].length).to.equal(1); + expect(newCommitsPerPath['pkg2'].length).to.equal(1); + expect(newCommitsPerPath['pkg3'].length).to.equal(1); + }); + + it('should exclude if all files are from excluded path', () => { + const config: Record = { + '.': {excludePaths: ['pkg3', 'pkg1', 'pkg2']}, + }; + const commitExclude = new CommitExclude(config); + const newCommitsPerPath = commitExclude.excludeCommits(commitsPerPath); + expect(newCommitsPerPath['.'].length).to.equal(1); + expect(newCommitsPerPath['pkg1'].length).to.equal(1); + expect(newCommitsPerPath['pkg2'].length).to.equal(1); + expect(newCommitsPerPath['pkg3'].length).to.equal(2); + }); + + it('should make decision only on relevant files', () => { + const createCommit = (files: string[]) => { + const first = files[0]; + return { + sha: first.split('/')[0], + message: `commit ${first}`, + files, + }; + }; + const commits: Record = { + a: [createCommit(['a/b/c', 'd/e/f', 'd/e/g'])], + d: [createCommit(['a/b/c', 'd/e/f', 'd/e/g'])], + }; + const config: Record = { + d: {excludePaths: ['d/e']}, + }; + const commitExclude = new CommitExclude(config); + const newCommitsPerPath = commitExclude.excludeCommits(commits); + expect(newCommitsPerPath['a'].length).to.equal(1); + expect(newCommitsPerPath['d'].length).to.equal(0); + }); +}); diff --git a/test/util/filter-commits.ts b/test/util/filter-commits.ts new file mode 100644 index 000000000..7d0106e49 --- /dev/null +++ b/test/util/filter-commits.ts @@ -0,0 +1,92 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import {filterCommits} from '../../src/util/filter-commits'; +import {describe, it} from 'mocha'; +import {expect} from 'chai'; + +const BREAKING_CHANGE_NOTE = 'BREAKING CHANGE'; + +describe('filterCommits', () => { + it('removes unknown commit types', () => { + const commits = filterCommits([ + { + type: 'User-Name', + notes: [], + references: [], + bareMessage: '', + message: '', + scope: null, + breaking: false, + sha: 'deadbeef', + }, + ]); + expect(commits.length).to.equal(0); + }); + it('removes unknown commit type for breaking change', () => { + const commits = filterCommits([ + { + type: 'User-Name', + notes: [ + { + title: BREAKING_CHANGE_NOTE, + text: 'foo breaking change', + }, + ], + references: [], + bareMessage: '', + message: '', + scope: null, + breaking: false, + sha: 'deadbeef', + }, + ]); + expect(commits.length).to.equal(0); + }); + it('removes hidden commit types for non-breaking changes', () => { + const commits = filterCommits([ + { + type: 'chore', + notes: [], + references: [], + bareMessage: '', + message: '', + scope: null, + breaking: false, + sha: 'deadbeef', + }, + ]); + expect(commits.length).to.equal(0); + }); + it('includes hidden commit types for non-breaking changes', () => { + const commits = filterCommits([ + { + type: 'chore', + notes: [ + { + title: BREAKING_CHANGE_NOTE, + text: 'foo breaking change', + }, + ], + references: [], + bareMessage: '', + message: '', + scope: null, + breaking: false, + sha: 'deadbeef', + }, + ]); + expect(commits.length).to.equal(1); + }); +}); diff --git a/test/util/pull-request-body.ts b/test/util/pull-request-body.ts index 7145e5737..c7702a384 100644 --- a/test/util/pull-request-body.ts +++ b/test/util/pull-request-body.ts @@ -97,6 +97,19 @@ describe('PullRequestBody', () => { expect(releaseData[0].version?.toString()).to.eql('3.2.7'); expect(releaseData[0].notes).matches(/^### \[3\.2\.7\]/); }); + it('should parse standalone prerelease', () => { + const body = readFileSync( + resolve(fixturesPath, './single-prerelease.txt'), + 'utf8' + ); + const pullRequestBody = PullRequestBody.parse(body); + expect(pullRequestBody).to.not.be.undefined; + const releaseData = pullRequestBody!.releaseData; + expect(releaseData).lengthOf(1); + expect(releaseData[0].component).to.be.undefined; + expect(releaseData[0].version?.toString()).to.eql('3.2.7-pre.0'); + expect(releaseData[0].notes).matches(/^### \[3\.2\.7-pre\.0]/); + }); it('should parse legacy PHP body', () => { const body = readFileSync( resolve(fixturesPath, './legacy-php-yoshi.txt'), diff --git a/test/util/pull-request-title.ts b/test/util/pull-request-title.ts index 947b79d2b..c44447fbc 100644 --- a/test/util/pull-request-title.ts +++ b/test/util/pull-request-title.ts @@ -133,7 +133,7 @@ describe('PullRequestTitle', () => { it('return matchPattern with default Pattern', () => { const matchPattern = generateMatchPattern(); expect(matchPattern).to.eql( - /^chore(\((?[\w-./]+)\))?: release ?(?[\w-./]*)? v?(?[0-9].*)$/ + /^chore(\((?[\w-./]+)\))?: release ?(?@?[\w-./]*)? v?(?[0-9].*)$/ ); }); }); @@ -202,6 +202,16 @@ describe('PullRequestTitle with custom pullRequestTitlePattern', () => { expect(pullRequestTitle?.getVersion()?.toString()).to.eql('1.2.3'); }); + it('parses a component with @ sign prefix', () => { + const name = 'chore(main): 🔖 release @example/storage v1.2.3'; + const pullRequestTitle = PullRequestTitle.parse( + name, + 'chore${scope}: 🔖 release${component} ${version}' + ); + expect(pullRequestTitle).to.not.be.undefined; + expect(pullRequestTitle?.getComponent()).to.eql('@example/storage'); + }); + it('fails to parse', () => { const pullRequestTitle = PullRequestTitle.parse( 'release-foo', @@ -224,7 +234,7 @@ describe('PullRequestTitle with custom pullRequestTitlePattern', () => { it('parses a complex title and pattern', () => { const pullRequestTitle = PullRequestTitle.parse( - '[HOTFIX] - chore(hotfix/v3.1.0-bug): release 3.1.0-hotfix1 (storage)', + '[HOTFIX] - chore(hotfix/v3.1.0-bug): release 3.1.0-hotfix1 (@example/storage)', '[HOTFIX] - chore${scope}: release ${version} (${component})' ); expect(pullRequestTitle).to.not.be.undefined; @@ -232,7 +242,7 @@ describe('PullRequestTitle with custom pullRequestTitlePattern', () => { expect(pullRequestTitle?.getVersion()?.toString()).to.eql( '3.1.0-hotfix1' ); - expect(pullRequestTitle?.getComponent()).to.eql('storage'); + expect(pullRequestTitle?.getComponent()).to.eql('@example/storage'); }); }); describe('ofVersion', () => { @@ -287,7 +297,7 @@ describe('PullRequestTitle with custom pullRequestTitlePattern', () => { 'chore${scope}: 🔖 release${component} ${version}' ); expect(matchPattern).to.eql( - /^chore(\((?[\w-./]+)\))?: 🔖 release ?(?[\w-./]*)? v?(?[0-9].*)$/ + /^chore(\((?[\w-./]+)\))?: 🔖 release ?(?@?[\w-./]*)? v?(?[0-9].*)$/ ); }); diff --git a/test/version.ts b/test/version.ts index 2daaa965c..789de116e 100644 --- a/test/version.ts +++ b/test/version.ts @@ -150,4 +150,12 @@ describe('Version', () => { ]); }); }); + describe('isPreMajor', () => { + it('should return true for versions < 1.0.0', () => { + expect(Version.parse('0.1.0').isPreMajor).to.be.true; + }); + it('should return false for versions >= 1.0.0', () => { + expect(Version.parse('1.0.0').isPreMajor).to.be.false; + }); + }); }); diff --git a/test/versioning-strategies/prerelease.ts b/test/versioning-strategies/prerelease.ts new file mode 100644 index 000000000..41b1a6f30 --- /dev/null +++ b/test/versioning-strategies/prerelease.ts @@ -0,0 +1,415 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import {describe, it} from 'mocha'; + +import {expect} from 'chai'; +import {PrereleaseVersioningStrategy} from '../../src/versioning-strategies/prerelease'; +import {Version} from '../../src/version'; + +describe('PrereleaseVersioningStrategy', () => { + describe('with breaking change', () => { + const commits = [ + { + sha: 'sha1', + message: 'feat: some feature', + files: ['path1/file1.txt'], + type: 'feat', + scope: null, + bareMessage: 'some feature', + notes: [], + references: [], + breaking: false, + }, + { + sha: 'sha2', + message: 'fix!: some bugfix', + files: ['path1/file1.rb'], + type: 'fix', + scope: null, + bareMessage: 'some bugfix', + notes: [{title: 'BREAKING CHANGE', text: 'some bugfix'}], + references: [], + breaking: true, + }, + { + sha: 'sha3', + message: 'docs: some documentation', + files: ['path1/file1.java'], + type: 'docs', + scope: null, + bareMessage: 'some documentation', + notes: [], + references: [], + breaking: false, + }, + ]; + describe('without prerelease type', () => { + const expectedBumps: Record = { + '1.2.3': '2.0.0', + '0.1.2': '1.0.0', + '1.0.0-beta01': '1.0.0-beta02', + '2.0.0-beta01': '2.0.0-beta02', + '1.0.1-beta01': '2.0.0-beta01', + '1.1.0-beta01': '2.0.0-beta01', + '1.1.1-beta01': '2.0.0-beta01', + }; + for (const old in expectedBumps) { + const expected = expectedBumps[old]; + it(`can bump ${old} to ${expected}`, async () => { + const strategy = new PrereleaseVersioningStrategy(); + const oldVersion = Version.parse(old); + const newVersion = await strategy.bump(oldVersion, commits); + expect(newVersion.toString()).to.equal(expected); + }); + } + it('can bump a minor pre major for breaking change', async () => { + const strategy = new PrereleaseVersioningStrategy({ + bumpMinorPreMajor: true, + }); + const oldVersion = Version.parse('0.1.2'); + const newVersion = await strategy.bump(oldVersion, commits); + expect(newVersion.toString()).to.equal('0.2.0'); + }); + }); + + describe('with prerelease type', () => { + const expectedBumps: Record = { + '1.2.3': '2.0.0-beta', + '0.1.2': '1.0.0-beta', + '1.0.0-alpha': '1.0.0-alpha.1', + '1.0.0-beta': '1.0.0-beta.1', + '2.0.0-beta': '2.0.0-beta.1', + '1.0.1-beta': '2.0.0-beta', + '1.1.0-beta': '2.0.0-beta', + '1.1.1-beta': '2.0.0-beta', + '1.0.0-beta01': '1.0.0-beta02', + '2.0.0-beta01': '2.0.0-beta02', + '1.0.1-beta01': '2.0.0-beta01', + '1.1.0-beta01': '2.0.0-beta01', + '1.1.1-beta01': '2.0.0-beta01', + '1.0.0-beta2023.1': '1.0.0-beta2023.2', + '2.0.0-beta2023.1': '2.0.0-beta2023.2', + '1.0.1-beta2023.1': '2.0.0-beta2023.1', + '1.1.0-beta2023.1': '2.0.0-beta2023.1', + '1.1.1-beta2023.1': '2.0.0-beta2023.1', + }; + for (const old in expectedBumps) { + const expected = expectedBumps[old]; + it(`can bump ${old} to ${expected}`, async () => { + const strategy = new PrereleaseVersioningStrategy({ + prereleaseType: 'beta', + }); + const oldVersion = Version.parse(old); + const newVersion = await strategy.bump(oldVersion, commits); + expect(newVersion.toString()).to.equal(expected); + }); + } + it('can bump a minor pre major for breaking change', async () => { + const strategy = new PrereleaseVersioningStrategy({ + bumpMinorPreMajor: true, + prereleaseType: 'beta', + }); + const oldVersion = Version.parse('0.1.2'); + const newVersion = await strategy.bump(oldVersion, commits); + expect(newVersion.toString()).to.equal('0.2.0-beta'); + }); + }); + }); + + describe('with a feature', () => { + const commits = [ + { + sha: 'sha1', + message: 'feat: some feature', + files: ['path1/file1.txt'], + type: 'feat', + scope: null, + bareMessage: 'some feature', + notes: [], + references: [], + breaking: false, + }, + { + sha: 'sha2', + message: 'fix: some bugfix', + files: ['path1/file1.rb'], + type: 'fix', + scope: null, + bareMessage: 'some bugfix', + notes: [], + references: [], + breaking: false, + }, + { + sha: 'sha3', + message: 'docs: some documentation', + files: ['path1/file1.java'], + type: 'docs', + scope: null, + bareMessage: 'some documentation', + notes: [], + references: [], + breaking: false, + }, + ]; + describe('without prerelease type', () => { + const expectedBumps: Record = { + '1.2.3': '1.3.0', + '0.1.2': '0.2.0', + '1.0.0-beta01': '1.0.0-beta02', + '2.0.0-beta01': '2.0.0-beta02', + '1.0.1-beta01': '1.1.0-beta01', + '1.1.0-beta01': '1.1.0-beta02', + '1.1.1-beta01': '1.2.0-beta01', + }; + for (const old in expectedBumps) { + const expected = expectedBumps[old]; + it(`can bump ${old} to ${expected}`, async () => { + const strategy = new PrereleaseVersioningStrategy(); + const oldVersion = Version.parse(old); + const newVersion = await strategy.bump(oldVersion, commits); + expect(newVersion.toString()).to.equal(expected); + }); + } + it('can bump a patch pre-major', async () => { + const strategy = new PrereleaseVersioningStrategy({ + bumpPatchForMinorPreMajor: true, + }); + const oldVersion = Version.parse('0.1.2'); + const newVersion = await strategy.bump(oldVersion, commits); + expect(newVersion.toString()).to.equal('0.1.3'); + }); + }); + describe('with prerelease type', () => { + const expectedBumps: Record = { + '1.2.3': '1.3.0-beta', + '0.1.2': '0.2.0-beta', + '1.0.0-alpha': '1.0.0-alpha.1', + '1.0.0-beta': '1.0.0-beta.1', + '2.0.0-beta': '2.0.0-beta.1', + '1.0.1-beta': '1.1.0-beta', + '1.1.0-alpha': '1.1.0-alpha.1', + '1.1.0-beta': '1.1.0-beta.1', + '1.1.1-beta': '1.2.0-beta', + '1.0.0-beta01': '1.0.0-beta02', + '2.0.0-beta01': '2.0.0-beta02', + '1.0.1-beta01': '1.1.0-beta01', + '1.1.0-beta01': '1.1.0-beta02', + '1.1.1-beta01': '1.2.0-beta01', + '1.0.0-beta2023.1': '1.0.0-beta2023.2', + '2.0.0-beta2023.1': '2.0.0-beta2023.2', + '1.0.1-beta2023.1': '1.1.0-beta2023.1', + '1.1.0-beta2023.1': '1.1.0-beta2023.2', + '1.1.1-beta2023.1': '1.2.0-beta2023.1', + }; + for (const old in expectedBumps) { + const expected = expectedBumps[old]; + it(`can bump ${old} to ${expected}`, async () => { + const strategy = new PrereleaseVersioningStrategy({ + prereleaseType: 'beta', + }); + const oldVersion = Version.parse(old); + const newVersion = await strategy.bump(oldVersion, commits); + expect(newVersion.toString()).to.equal(expected); + }); + } + it('can bump a patch pre-major', async () => { + const strategy = new PrereleaseVersioningStrategy({ + bumpPatchForMinorPreMajor: true, + prereleaseType: 'beta', + }); + const oldVersion = Version.parse('0.1.2'); + const newVersion = await strategy.bump(oldVersion, commits); + expect(newVersion.toString()).to.equal('0.1.3-beta'); + }); + }); + }); + + describe('with a fix', () => { + const commits = [ + { + sha: 'sha2', + message: 'fix: some bugfix', + files: ['path1/file1.rb'], + type: 'fix', + scope: null, + bareMessage: 'some bugfix', + notes: [], + references: [], + breaking: false, + }, + { + sha: 'sha3', + message: 'docs: some documentation', + files: ['path1/file1.java'], + type: 'docs', + scope: null, + bareMessage: 'some documentation', + notes: [], + references: [], + breaking: false, + }, + ]; + describe('without prerelease type', () => { + const expectedBumps: Record = { + '1.2.3': '1.2.4', + '1.0.0-beta01': '1.0.0-beta02', + '2.0.0-beta01': '2.0.0-beta02', + '1.0.1-beta01': '1.0.1-beta02', + '1.1.0-beta01': '1.1.0-beta02', + '1.1.1-beta01': '1.1.1-beta02', + '1.0.0-beta1': '1.0.0-beta2', + '1.0.0-beta9': '1.0.0-beta10', // (although that would be unfortunate) + '1.0.0-beta09': '1.0.0-beta10', + }; + for (const old in expectedBumps) { + const expected = expectedBumps[old]; + it(`can bump ${old} to ${expected}`, async () => { + const strategy = new PrereleaseVersioningStrategy(); + const oldVersion = Version.parse(old); + const newVersion = await strategy.bump(oldVersion, commits); + expect(newVersion.toString()).to.equal(expected); + }); + } + }); + describe('with prerelease type', () => { + const expectedBumps: Record = { + '1.2.3': '1.2.4-beta', + '1.2.4-alpha': '1.2.4-alpha.1', + '1.2.4-beta': '1.2.4-beta.1', + '1.0.0-beta01': '1.0.0-beta02', + '2.0.0-beta01': '2.0.0-beta02', + '1.0.1-beta01': '1.0.1-beta02', + '1.1.0-beta01': '1.1.0-beta02', + '1.1.1-beta01': '1.1.1-beta02', + '1.0.0-beta1': '1.0.0-beta2', + '1.0.0-beta9': '1.0.0-beta10', // (although that would be unfortunate) + '1.0.0-beta09': '1.0.0-beta10', + '1.0.0-beta2023.1': '1.0.0-beta2023.2', + '2.0.0-beta2023.1': '2.0.0-beta2023.2', + '1.0.1-beta2023.1': '1.0.1-beta2023.2', + '1.1.0-beta2023.1': '1.1.0-beta2023.2', + '1.1.1-beta2023.1': '1.1.1-beta2023.2', + }; + for (const old in expectedBumps) { + const expected = expectedBumps[old]; + it(`can bump ${old} to ${expected}`, async () => { + const strategy = new PrereleaseVersioningStrategy({ + prereleaseType: 'beta', + }); + const oldVersion = Version.parse(old); + const newVersion = await strategy.bump(oldVersion, commits); + expect(newVersion.toString()).to.equal(expected); + }); + } + }); + }); + + describe('with release-as', () => { + it('sets the version', async () => { + const commits = [ + { + sha: 'sha1', + message: 'feat: some feature', + files: ['path1/file1.txt'], + type: 'feat', + scope: null, + bareMessage: 'some feature', + notes: [], + references: [], + breaking: false, + }, + { + sha: 'sha2', + message: 'fix!: some bugfix', + files: ['path1/file1.rb'], + type: 'fix', + scope: null, + bareMessage: 'some bugfix', + notes: [{title: 'RELEASE AS', text: '3.1.2'}], + references: [], + breaking: true, + }, + { + sha: 'sha3', + message: 'docs: some documentation', + files: ['path1/file1.java'], + type: 'docs', + scope: null, + bareMessage: 'some documentation', + notes: [], + references: [], + breaking: false, + }, + ]; + const strategy = new PrereleaseVersioningStrategy(); + const oldVersion = Version.parse('1.2.3'); + const newVersion = await strategy.bump(oldVersion, commits); + expect(newVersion.toString()).to.equal('3.1.2'); + }); + it('handles multiple release-as commits', async () => { + const commits = [ + { + sha: 'sha1', + message: 'feat: some feature', + files: ['path1/file1.txt'], + type: 'feat', + scope: null, + bareMessage: 'some feature', + notes: [], + references: [], + breaking: false, + }, + { + sha: 'sha2', + message: 'fix!: some bugfix', + files: ['path1/file1.rb'], + type: 'fix', + scope: null, + bareMessage: 'some bugfix', + notes: [{title: 'RELEASE AS', text: '3.1.2'}], + references: [], + breaking: true, + }, + { + sha: 'sha3', + message: 'docs: some documentation', + files: ['path1/file1.java'], + type: 'docs', + scope: null, + bareMessage: 'some documentation', + notes: [], + references: [], + breaking: false, + }, + { + sha: 'sha4', + message: 'fix!: some bugfix', + files: ['path1/file1.rb'], + type: 'fix', + scope: null, + bareMessage: 'some bugfix', + notes: [{title: 'RELEASE AS', text: '2.0.0'}], + references: [], + breaking: true, + }, + ]; + const strategy = new PrereleaseVersioningStrategy(); + const oldVersion = Version.parse('1.2.3'); + const newVersion = await strategy.bump(oldVersion, commits); + expect(newVersion.toString()).to.equal('3.1.2'); + }); + }); +}); diff --git a/typings/config-chain.d.ts b/typings/config-chain.d.ts new file mode 100644 index 000000000..20ddbcdfd --- /dev/null +++ b/typings/config-chain.d.ts @@ -0,0 +1,18 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// This files is needed because `lerna-lite` uses config-chain and there isn't a @types/config-chain available. +declare module 'config-chain' { + export class ConfigChain {} +}