diff --git a/.changeset/README.md b/.changeset/README.md new file mode 100644 index 0000000..e5b6d8d --- /dev/null +++ b/.changeset/README.md @@ -0,0 +1,8 @@ +# Changesets + +Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works +with multi-package repos, or single-package repos to help you version and publish your code. You can +find the full documentation for it [in our repository](https://github.com/changesets/changesets) + +We have a quick list of common questions to get you started engaging with this project in +[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) diff --git a/.changeset/config.json b/.changeset/config.json new file mode 100644 index 0000000..0500dbf --- /dev/null +++ b/.changeset/config.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@4.0.0/schema.json", + "changelog": ["@changesets/changelog-github", {"repo": "github/remote-input-element"}], + "commit": false, + "fixed": [], + "linked": [], + "access": "public", + "baseBranch": "main", + "updateInternalDependencies": "patch", + "ignore": [] +} diff --git a/.github/workflows/check-for-changeset.yml b/.github/workflows/check-for-changeset.yml new file mode 100644 index 0000000..abf83f8 --- /dev/null +++ b/.github/workflows/check-for-changeset.yml @@ -0,0 +1,38 @@ +name: Check for changeset + +on: + pull_request: + types: + - opened + - reopened + - synchronize + - labeled + - unlabeled + +permissions: + contents: read + pull-requests: read + +jobs: + check: + if: github.event.pull_request.user.login != 'dependabot[bot]' + runs-on: ubuntu-latest + steps: + - name: Check for changeset or skip label + env: + GH_TOKEN: ${{ github.token }} + PR_NUMBER: ${{ github.event.pull_request.number }} + run: | + if gh api "repos/${GITHUB_REPOSITORY}/issues/${PR_NUMBER}/labels" --paginate --jq '.[].name' | grep -qx 'skip changeset'; then + echo 'The "skip changeset" label is present.' + exit 0 + fi + + changesets=$(gh api "repos/${GITHUB_REPOSITORY}/pulls/${PR_NUMBER}/files" --paginate --jq '.[] | select(.status != "removed") | .filename' | grep -E '^\.changeset/[^/]+\.md$' | grep -Ev '^\.changeset/(README\.md|dependabot-[0-9]+\.md)$' || true) + if [ -n "$changesets" ]; then + echo 'The ".changeset/*.md" file pattern matched the changed files of the pull request.' + exit 0 + fi + + echo 'No changeset found. If these changes should not result in a new version, apply the "skip changeset" label to this pull request. If these changes should result in a version bump, run "npx changeset" and commit the generated file.' + exit 1 diff --git a/.github/workflows/dependabot-changeset.yml b/.github/workflows/dependabot-changeset.yml new file mode 100644 index 0000000..64b90ad --- /dev/null +++ b/.github/workflows/dependabot-changeset.yml @@ -0,0 +1,57 @@ +name: Dependabot changeset + +on: + pull_request_target: + types: + - opened + - reopened + - synchronize + +concurrency: + group: dependabot-changeset-${{ github.event.pull_request.number }} + cancel-in-progress: true +permissions: + contents: read + pull-requests: read + +jobs: + changeset: + if: github.event.pull_request.user.login == 'dependabot[bot]' + runs-on: ubuntu-latest + steps: + - name: Create GitHub App token + id: app-token + uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 + with: + app-id: ${{ vars.PRIMER_APP_ID_SHARED }} + private-key: ${{ secrets.PRIMER_APP_PRIVATE_KEY_SHARED }} + permission-contents: write + permission-pull-requests: read + permission-vulnerability-alerts: read + + - name: Fetch Dependabot metadata + id: metadata + uses: dependabot/fetch-metadata@08eff52bf64351f401fb50d4972fa95b9f2c2d1b + with: + github-token: ${{ steps.app-token.outputs.token }} + alert-lookup: true + + - name: Check out trusted base code + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.base.sha }} + persist-credentials: false + + - name: Set up Node + uses: actions/setup-node@v4 + with: + node-version: 22 + + - name: Apply Dependabot changeset policy + run: node scripts/dependabot-changeset.mjs + env: + GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} + DEPENDABOT_DEPENDENCY_NAMES: ${{ steps.metadata.outputs.dependency-names }} + DEPENDABOT_UPDATED_DEPENDENCIES_JSON: ${{ steps.metadata.outputs.updated-dependencies-json }} + DEPENDABOT_ALERT_STATE: ${{ steps.metadata.outputs.alert-state }} + DEPENDABOT_GHSA_ID: ${{ steps.metadata.outputs.ghsa-id }} diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index df048b1..ac74573 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -24,3 +24,5 @@ jobs: run: npm run build - name: Run test run: npm run test + - name: Run Dependabot changeset policy tests + run: npm run test:dependabot-changeset diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml deleted file mode 100644 index 855bc2b..0000000 --- a/.github/workflows/publish.yml +++ /dev/null @@ -1,27 +0,0 @@ -name: Publish - -on: - release: - types: [created] - -jobs: - publish-npm: - name: Publish to npm - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 - with: - node-version: 18 - registry-url: https://registry.npmjs.org/ - cache: npm - - run: npm install -g npm@latest - - run: npm ci - - run: npm test - - run: npm version ${TAG_NAME} --git-tag-version=false - env: - TAG_NAME: ${{ github.event.release.tag_name }} - - run: npm --ignore-scripts publish --provenance --access public diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..e64d30f --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,46 @@ +name: Release + +on: + push: + branches: + - main + workflow_dispatch: {} + +concurrency: ${{ github.workflow }}-${{ github.ref }} + +permissions: + contents: write + pull-requests: write + id-token: write + +jobs: + release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + # Full history and tags let Changesets generate GitHub changelogs + # with the correct commits. + fetch-depth: 0 + + - uses: actions/setup-node@v4 + with: + node-version: 22 + registry-url: https://registry.npmjs.org + + - name: Update npm for trusted publishing + run: npm install -g npm@latest + + - name: Install dependencies + run: npm ci + + - name: Run tests + run: npm test + + - name: Create release pull request or publish + uses: changesets/action@v2 + with: + pr-title: 'Release tracking' + publish-script: npm run release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/README.md b/README.md index d5e0699..2da1d9e 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,17 @@ npm install npm test ``` +## Releasing + +This project uses [Changesets](https://github.com/changesets/changesets) to manage versioning, changelogs, and publishing to npm. + +- **Human-authored pull requests**: For a user-facing change, run `npx changeset`, describe the change, and choose a `patch`, `minor`, or `major` bump. Commit the generated changeset with the change. If a pull request should not produce a release, apply the `skip changeset` label instead. +- **Dependabot pull requests**: Dependabot PRs are exempt from the human changeset check. A dedicated workflow adds one deterministic patch changeset when a Dependabot update resolves a security alert or changes the declared range of a direct production dependency in `package.json`. +- **Dependency updates without releases**: Direct development dependency updates, indirect dependency updates, and lockfile-only updates already permitted by the existing `package.json` range do not get changesets unless they resolve a Dependabot security alert. +- **Dependabot automation credentials**: The Dependabot changeset workflow uses the shared Primer GitHub App credentials (`PRIMER_APP_ID_SHARED` and `PRIMER_APP_PRIVATE_KEY_SHARED`). The App needs Contents write, Pull requests read, and Dependabot alerts read permissions so it can look up security-alert metadata and commit the generated changeset to the Dependabot branch without a personal access token. +- **Release pull request**: The [`release` workflow](.github/workflows/release.yml) opens or updates a **Release tracking** pull request using `changesets/action@v2`. Changesets owns release aggregation, versioning, changelog generation, and publishing. Merging that pull request publishes the package to npm and records the new version and changelog in the repository. +- **Manual runs**: Use the **Run workflow** button for the `Release` workflow (`workflow_dispatch`) to refresh release tracking without waiting for another push to `main`. + ## License Distributed under the MIT license. See LICENSE for details. diff --git a/package-lock.json b/package-lock.json index 3fdcf58..2f86f99 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,14 +1,16 @@ { "name": "@github/remote-input-element", - "version": "0.3.1", + "version": "0.4.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@github/remote-input-element", - "version": "0.3.1", + "version": "0.4.0", "license": "MIT", "devDependencies": { + "@changesets/changelog-github": "^1.0.0", + "@changesets/cli": "^3.0.1", "@typescript-eslint/parser": "^7.4.0", "chai": "^4.1.2", "eslint": "8.56.0", @@ -44,6 +46,332 @@ "node": ">=6.9.0" } }, + "node_modules/@changesets/apply-release-plan": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@changesets/apply-release-plan/-/apply-release-plan-8.0.0.tgz", + "integrity": "sha512-kUd2pbf1w5/AYmBMb0Tt+rkIPCjFJdT0SZMrkOjJT/WV/QbtmvkyB5jkV0oaNPheavprZk+SfUiozUti7TIL2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/config": "^4.0.0", + "@changesets/format": "^0.1.1", + "@changesets/git": "^4.0.0", + "@changesets/should-skip-package": "^1.0.0", + "@changesets/types": "^7.0.0", + "import-meta-resolve": "^4.2.0", + "jsonc-parser": "^3.3.1", + "semver": "^7.8.1" + }, + "engines": { + "node": "^22.11 || ^24 || >=26" + } + }, + "node_modules/@changesets/assemble-release-plan": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@changesets/assemble-release-plan/-/assemble-release-plan-7.0.0.tgz", + "integrity": "sha512-oEW8BxdA604kGGtDSCiHr5w9Tv4UWe9I2k61IBNZzCOE1kbYaJj4v+lFQNgcEZFkUc2pV/+hASErGDvpJOZCTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/errors": "^1.0.0", + "@changesets/get-dependents-graph": "^3.0.0", + "@changesets/should-skip-package": "^1.0.0", + "@changesets/types": "^7.0.0", + "semver": "^7.8.1" + }, + "engines": { + "node": "^22.11 || ^24 || >=26" + } + }, + "node_modules/@changesets/changelog-git": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@changesets/changelog-git/-/changelog-git-1.0.0.tgz", + "integrity": "sha512-3Dst2Ime2Op5nd4XmWJLPIgp11ZFqJqSkVug9izK6TDcIV4YlhPS4ECbEVR+eGI0bk0r1ItogD4j2Oli87bJrA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/types": "^7.0.0" + }, + "engines": { + "node": "^22.11 || ^24 || >=26" + } + }, + "node_modules/@changesets/changelog-github": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@changesets/changelog-github/-/changelog-github-1.0.0.tgz", + "integrity": "sha512-PNCSH5CGJrqOKxRjrMp2NLhceQv2QBs6HkjrLvYQqsEE2/ItN5R8GD/mskZZluoNWYvjPYFsY9T6swXfp5E0UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/get-github-info": "^1.0.0", + "@changesets/types": "^7.0.0" + }, + "engines": { + "node": "^22.11 || ^24 || >=26" + } + }, + "node_modules/@changesets/cli": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@changesets/cli/-/cli-3.0.1.tgz", + "integrity": "sha512-3IVpRSgiKDj2aRbBHKtWTXSRH2/iR3bWxau9iQUoEsZjDhRIj9nhl90k7FWMxZAJvLgJBbgMq8+qS0xQsenYsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/apply-release-plan": "^8.0.0", + "@changesets/assemble-release-plan": "^7.0.0", + "@changesets/changelog-git": "^1.0.0", + "@changesets/config": "^4.0.0", + "@changesets/errors": "^1.0.0", + "@changesets/get-dependents-graph": "^3.0.0", + "@changesets/git": "^4.0.0", + "@changesets/pre": "^3.0.0", + "@changesets/read": "^1.0.0", + "@changesets/should-skip-package": "^1.0.0", + "@changesets/types": "^7.0.0", + "@changesets/write": "^1.0.1", + "@clack/prompts": "^1.7.0", + "@manypkg/get-packages": "^3.1.0", + "@pnpm/deps.graph-sequencer": "^1100.0.1", + "cac": "^7.0.0", + "import-meta-resolve": "^4.2.0", + "launch-editor": "^2.14.1", + "package-manager-detector": "^1.6.0", + "semver": "^7.8.1", + "tinyexec": "^1.3.0" + }, + "bin": { + "changeset": "bin.js" + }, + "engines": { + "node": "^22.11 || ^24 || >=26", + "npm": ">=10.9.0", + "pnpm": ">=10.0.0", + "yarn": ">=4.5.2" + } + }, + "node_modules/@changesets/config": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@changesets/config/-/config-4.0.0.tgz", + "integrity": "sha512-mw95/YrkOuhZZxfnVAA4bSXOFUi+KlhzOBTM8C4x777NhUU6HWIl9Z+K+nME+E4PVsv5NQVQwTfiHihAS1A/ow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/get-dependents-graph": "^3.0.0", + "@changesets/should-skip-package": "^1.0.0", + "@changesets/types": "^7.0.0", + "@manypkg/get-packages": "^3.1.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": "^22.11 || ^24 || >=26" + } + }, + "node_modules/@changesets/config/node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/@changesets/errors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@changesets/errors/-/errors-1.0.0.tgz", + "integrity": "sha512-ElN/mEzn6zmETgjwf5MclCMa9ef59sAR0lfO8VSYIsiRvbC2FbLB/92EoYw10Sl0kGixxHFiJZUSv7dA+YpR8g==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^22.11 || ^24 || >=26" + } + }, + "node_modules/@changesets/format": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@changesets/format/-/format-0.1.2.tgz", + "integrity": "sha512-Caez5XtNXCFS/G5bwyav3wuXL0tMxVd2ZGbaumWbzN08tyzO21asCw7JZhNtVsAZDCvDRUzZN+Iit9SyRITSYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "package-manager-detector": "^1.8.0", + "tinyexec": "^1.3.0" + }, + "engines": { + "node": "^22.11 || ^24 || >=26" + } + }, + "node_modules/@changesets/get-dependents-graph": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@changesets/get-dependents-graph/-/get-dependents-graph-3.0.0.tgz", + "integrity": "sha512-ji/t5wFA1zREKXRUePE6Qi+Qu2UgxCeSSGQrphezwvQZrp49B7sJ+8+wvM0tA7zPeSxYKCojDy3WWgrl+s+awg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/types": "^7.0.0", + "semver": "^7.8.1" + }, + "engines": { + "node": "^22.11 || ^24 || >=26" + } + }, + "node_modules/@changesets/get-github-info": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@changesets/get-github-info/-/get-github-info-1.0.0.tgz", + "integrity": "sha512-nf5zPSqEKW0eXiJ4ltbjyIQ/srUHfxbghkLCjKdOLI3LehKXhiqxXcpja39eGPaj6qqGx2lFCrLJ7VWYUf9H2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "dataloader": "^2.2.3" + }, + "engines": { + "node": "^22.11 || ^24 || >=26" + } + }, + "node_modules/@changesets/git": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@changesets/git/-/git-4.0.0.tgz", + "integrity": "sha512-uIEswpPUgzBBqrC0qg13byNaPorzhf05LE2T+gRizEKCXvMsJC6NPJp5iNDSV/gYj4Viqh09UiOF5E7XWeH5lQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/errors": "^1.0.0", + "@changesets/types": "^7.0.0", + "@manypkg/get-packages": "^3.1.0", + "picomatch": "^4.0.4", + "tinyexec": "^1.3.0" + }, + "engines": { + "node": "^22.11 || ^24 || >=26" + } + }, + "node_modules/@changesets/git/node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/@changesets/parse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@changesets/parse/-/parse-1.0.0.tgz", + "integrity": "sha512-P0iaMb9p9CRYZiTgAllEIF9AUMQHIy1G72tKlcIqJp61icZSsKQNiOPdxAMZG8m/DvZwt/oz5xEbTpike//dWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/types": "^7.0.0", + "yaml": "^2.9.0" + }, + "engines": { + "node": "^22.11 || ^24 || >=26" + } + }, + "node_modules/@changesets/pre": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@changesets/pre/-/pre-3.0.0.tgz", + "integrity": "sha512-Zm/6YliV/a2oeWTqHJf6KxLrQwgcK1i/BRDl2m0EKZvbnxV5fG9QRhwJJGshjsZTUTS6dkfURQ2K6aAvgNw/3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/errors": "^1.0.0", + "@changesets/types": "^7.0.0", + "@manypkg/get-packages": "^3.1.0" + }, + "engines": { + "node": "^22.11 || ^24 || >=26" + } + }, + "node_modules/@changesets/read": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@changesets/read/-/read-1.0.0.tgz", + "integrity": "sha512-8TdE2PwG6yArPt5Ozej83Z6iHz1G8BDBKvIEKZ455MccR4K3GNbLR2XqjBxa+5yLFnEd3xAOPXYboBg1pt8stQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/git": "^4.0.0", + "@changesets/parse": "^1.0.0", + "@changesets/types": "^7.0.0" + }, + "engines": { + "node": "^22.11 || ^24 || >=26" + } + }, + "node_modules/@changesets/should-skip-package": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@changesets/should-skip-package/-/should-skip-package-1.0.0.tgz", + "integrity": "sha512-pwqoJmbONn1XgXmZXPEExgAaT+HdZLjALFTDgIm+PnS5KeO2nLtzA2/Q+4aMFY14kFMuXKG30MObhvDzWgzDgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/types": "^7.0.0" + }, + "engines": { + "node": "^22.11 || ^24 || >=26" + } + }, + "node_modules/@changesets/types": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@changesets/types/-/types-7.0.0.tgz", + "integrity": "sha512-c5GoiQyt3pxiXjrWSNoP8/GRf4kG+VnKzovx1OQM8dYYALlSwgedmkPmJ+ZqGxqwg9D3Bkj85Uo4KLd5BN3A0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^22.11 || ^24 || >=26" + } + }, + "node_modules/@changesets/write": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@changesets/write/-/write-1.0.1.tgz", + "integrity": "sha512-q/ThtP9gcnEP6xlv7LrY26C2mHqdGBti/MmOVngt/M/oIGYkssmQGxPK9WzBNt2juVcH/vml2WQ+ra8LXYOTaA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/format": "^0.1.1", + "@changesets/types": "^7.0.0", + "human-id": "^4.2.0" + }, + "engines": { + "node": "^22.11 || ^24 || >=26" + } + }, + "node_modules/@clack/core": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@clack/core/-/core-1.4.3.tgz", + "integrity": "sha512-/kr3UWNtdJfxZtPgDqUOmG2pvwlmcLGheex5yiZKdwbzZJxhV+HMNR9QNmyY5cGwTNV6LrR7Jtp+KjhUAP1qBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-wrap-ansi": "^0.2.0", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 20.12.0" + } + }, + "node_modules/@clack/prompts": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@clack/prompts/-/prompts-1.7.0.tgz", + "integrity": "sha512-y7/yvZ2TPAnR9+jnc00klvNNLkJiXFFrQA/hlLCcxA9a2A4zQIOimyFQ9XfwYKiGD1fb5GY8vbKIIgO8d5Tb2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@clack/core": "1.4.3", + "fast-string-width": "^3.0.2", + "fast-wrap-ansi": "^0.2.0", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 20.12.0" + } + }, "node_modules/@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", @@ -148,6 +476,48 @@ "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", "dev": true }, + "node_modules/@manypkg/find-root": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@manypkg/find-root/-/find-root-3.1.0.tgz", + "integrity": "sha512-BcSqCyKhBVZ5YkSzOiheMCV41kqAFptW6xGqYSTjkVTl9XQpr+pqHhwgGCOHQtjDCv7Is6EFyA14Sm5GVbVABA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@manypkg/tools": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@manypkg/get-packages": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@manypkg/get-packages/-/get-packages-3.1.0.tgz", + "integrity": "sha512-0TbBVyvPrP7xGYBI/cP8UP+yl/z+HtbTttAD7FMAJgn/kXOTwh5/60TsqP9ZYY710forNfyV0N8P/IE/ujGZJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@manypkg/find-root": "^3.1.0", + "@manypkg/tools": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@manypkg/tools": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@manypkg/tools/-/tools-2.1.2.tgz", + "integrity": "sha512-6QEf6yqFbETdwGITKq57aYoPfX/3K8XFNwsAlx0C1M7o8cb79sv1M3w+tWuWvIcSbNqrLF7OD7YpZMVVz335hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "jju": "^1.4.0", + "tinyglobby": "^0.2.13", + "yaml": "^2.9.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -195,6 +565,19 @@ "url": "https://opencollective.com/unts" } }, + "node_modules/@pnpm/deps.graph-sequencer": { + "version": "1100.0.1", + "resolved": "https://registry.npmjs.org/@pnpm/deps.graph-sequencer/-/deps.graph-sequencer-1100.0.1.tgz", + "integrity": "sha512-pOr5+q1fLYKwFN3LAJuGZEnfXDcQ73zqgDHMtGy+K+uIoUqyY+6MeDCWFwfu+4EFuq76I5EPFofoNAI+Bmmq4A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=22.13" + }, + "funding": { + "url": "https://opencollective.com/pnpm" + } + }, "node_modules/@socket.io/component-emitter": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", @@ -376,21 +759,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@typescript-eslint/visitor-keys": { "version": "7.4.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.4.0.tgz", @@ -828,6 +1196,16 @@ "node": ">= 0.8" } }, + "node_modules/cac": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cac/-/cac-7.0.0.tgz", + "integrity": "sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.19.0" + } + }, "node_modules/call-bind": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", @@ -1191,6 +1569,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/dataloader": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/dataloader/-/dataloader-2.2.3.tgz", + "integrity": "sha512-y2krtASINtPFS1rSDjacrFgn1dcUuoREVabwlOGOe4SdxenREqwjwjElAdwvbGM7kgZz9a3KVicWR7vcz8rnzA==", + "dev": true, + "license": "MIT" + }, "node_modules/date-format": { "version": "4.0.14", "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", @@ -1928,21 +2313,6 @@ "eslint": ">=7.0.0" } }, - "node_modules/eslint-plugin-github/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/eslint-plugin-i18n-text": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/eslint-plugin-i18n-text/-/eslint-plugin-i18n-text-1.0.1.tgz", @@ -2351,6 +2721,33 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, + "node_modules/fast-string-truncated-width": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fast-string-truncated-width/-/fast-string-truncated-width-3.0.3.tgz", + "integrity": "sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-string-width": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/fast-string-width/-/fast-string-width-3.0.2.tgz", + "integrity": "sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-string-truncated-width": "^3.0.2" + } + }, + "node_modules/fast-wrap-ansi": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/fast-wrap-ansi/-/fast-wrap-ansi-0.2.2.tgz", + "integrity": "sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-string-width": "^3.0.2" + } + }, "node_modules/fastq": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", @@ -2879,6 +3276,16 @@ "node": ">=8.0.0" } }, + "node_modules/human-id": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/human-id/-/human-id-4.2.1.tgz", + "integrity": "sha512-zPGsiS+dWoTZtZ4AtpA9Y+BdSFSNWvnouNlWNoUFyAM6xHOHmdCvqO3k8AIbdamCOv4gUFUVNPf6rJFfc4UiJw==", + "dev": true, + "license": "MIT", + "bin": { + "human-id": "dist/cli.js" + } + }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -2916,6 +3323,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/import-meta-resolve": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz", + "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -3374,6 +3792,13 @@ "set-function-name": "^2.0.1" } }, + "node_modules/jju": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", + "integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==", + "dev": true, + "license": "MIT" + }, "node_modules/js-yaml": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.1.tgz", @@ -3414,6 +3839,13 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, + "node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true, + "license": "MIT" + }, "node_modules/jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", @@ -3578,6 +4010,17 @@ "node": ">=0.10" } }, + "node_modules/launch-editor": { + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.14.1.tgz", + "integrity": "sha512-QWBrQsMpH7gPr965dsKD/3cKWiNoTjpATQf++Xq63N6sKRGMwlVXz41O1IZTMfZQgBctD/K5Zt06+/I6pP6+HA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picocolors": "^1.1.1", + "shell-quote": "^1.8.4" + } + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -3674,21 +4117,9 @@ "version": "2.3.7", "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", - "dev": true, - "dependencies": { - "get-func-name": "^2.0.1" - } - }, - "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==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" + "dev": true, + "dependencies": { + "get-func-name": "^2.0.1" } }, "node_modules/math-intrinsics": { @@ -4183,6 +4614,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/package-manager-detector": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.8.0.tgz", + "integrity": "sha512-yQA4H19AmPEoMUeavPMDIe1higySl/gH/yaQrkT/s07Qp+7pp2hYz30N3z2l5BkjVkF9Ow6o0wjJamm2y7Sn0A==", + "dev": true, + "license": "MIT" + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -4256,10 +4694,11 @@ } }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", @@ -4608,6 +5047,19 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, + "node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/serialize-javascript": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", @@ -4676,6 +5128,19 @@ "node": ">=8" } }, + "node_modules/shell-quote": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.10.0.tgz", + "integrity": "sha512-w1aiOKwKuRgtwAReIIj89puqg+I7GvX4IbLrvmhXbzQsj1+Zwi4VO3+fa6ZF91TWSjIxoEkKnMeHcLEODK5ZXA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/side-channel": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", @@ -4748,6 +5213,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true, + "license": "MIT" + }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -5037,6 +5509,64 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "node_modules/tinyexec": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.3.0.tgz", + "integrity": "sha512-QKAl9m8gWWGHV8jZcPeym6j+XULi6tOf1mT83WYJ4Lk2ytW/uwAWkrP0uFsdoYMdueVJ0qs26wZ+23xeB4ibNQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/tmp": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", @@ -5579,11 +6109,21 @@ "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==", - "dev": true + "node_modules/yaml": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", + "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } }, "node_modules/yargs": { "version": "16.2.0", @@ -5656,6 +6196,240 @@ "regenerator-runtime": "^0.14.0" } }, + "@changesets/apply-release-plan": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@changesets/apply-release-plan/-/apply-release-plan-8.0.0.tgz", + "integrity": "sha512-kUd2pbf1w5/AYmBMb0Tt+rkIPCjFJdT0SZMrkOjJT/WV/QbtmvkyB5jkV0oaNPheavprZk+SfUiozUti7TIL2w==", + "dev": true, + "requires": { + "@changesets/config": "^4.0.0", + "@changesets/format": "^0.1.1", + "@changesets/git": "^4.0.0", + "@changesets/should-skip-package": "^1.0.0", + "@changesets/types": "^7.0.0", + "import-meta-resolve": "^4.2.0", + "jsonc-parser": "^3.3.1", + "semver": "^7.8.1" + } + }, + "@changesets/assemble-release-plan": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@changesets/assemble-release-plan/-/assemble-release-plan-7.0.0.tgz", + "integrity": "sha512-oEW8BxdA604kGGtDSCiHr5w9Tv4UWe9I2k61IBNZzCOE1kbYaJj4v+lFQNgcEZFkUc2pV/+hASErGDvpJOZCTg==", + "dev": true, + "requires": { + "@changesets/errors": "^1.0.0", + "@changesets/get-dependents-graph": "^3.0.0", + "@changesets/should-skip-package": "^1.0.0", + "@changesets/types": "^7.0.0", + "semver": "^7.8.1" + } + }, + "@changesets/changelog-git": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@changesets/changelog-git/-/changelog-git-1.0.0.tgz", + "integrity": "sha512-3Dst2Ime2Op5nd4XmWJLPIgp11ZFqJqSkVug9izK6TDcIV4YlhPS4ECbEVR+eGI0bk0r1ItogD4j2Oli87bJrA==", + "dev": true, + "requires": { + "@changesets/types": "^7.0.0" + } + }, + "@changesets/changelog-github": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@changesets/changelog-github/-/changelog-github-1.0.0.tgz", + "integrity": "sha512-PNCSH5CGJrqOKxRjrMp2NLhceQv2QBs6HkjrLvYQqsEE2/ItN5R8GD/mskZZluoNWYvjPYFsY9T6swXfp5E0UA==", + "dev": true, + "requires": { + "@changesets/get-github-info": "^1.0.0", + "@changesets/types": "^7.0.0" + } + }, + "@changesets/cli": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@changesets/cli/-/cli-3.0.1.tgz", + "integrity": "sha512-3IVpRSgiKDj2aRbBHKtWTXSRH2/iR3bWxau9iQUoEsZjDhRIj9nhl90k7FWMxZAJvLgJBbgMq8+qS0xQsenYsQ==", + "dev": true, + "requires": { + "@changesets/apply-release-plan": "^8.0.0", + "@changesets/assemble-release-plan": "^7.0.0", + "@changesets/changelog-git": "^1.0.0", + "@changesets/config": "^4.0.0", + "@changesets/errors": "^1.0.0", + "@changesets/get-dependents-graph": "^3.0.0", + "@changesets/git": "^4.0.0", + "@changesets/pre": "^3.0.0", + "@changesets/read": "^1.0.0", + "@changesets/should-skip-package": "^1.0.0", + "@changesets/types": "^7.0.0", + "@changesets/write": "^1.0.1", + "@clack/prompts": "^1.7.0", + "@manypkg/get-packages": "^3.1.0", + "@pnpm/deps.graph-sequencer": "^1100.0.1", + "cac": "^7.0.0", + "import-meta-resolve": "^4.2.0", + "launch-editor": "^2.14.1", + "package-manager-detector": "^1.6.0", + "semver": "^7.8.1", + "tinyexec": "^1.3.0" + } + }, + "@changesets/config": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@changesets/config/-/config-4.0.0.tgz", + "integrity": "sha512-mw95/YrkOuhZZxfnVAA4bSXOFUi+KlhzOBTM8C4x777NhUU6HWIl9Z+K+nME+E4PVsv5NQVQwTfiHihAS1A/ow==", + "dev": true, + "requires": { + "@changesets/get-dependents-graph": "^3.0.0", + "@changesets/should-skip-package": "^1.0.0", + "@changesets/types": "^7.0.0", + "@manypkg/get-packages": "^3.1.0", + "picomatch": "^4.0.4" + }, + "dependencies": { + "picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true + } + } + }, + "@changesets/errors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@changesets/errors/-/errors-1.0.0.tgz", + "integrity": "sha512-ElN/mEzn6zmETgjwf5MclCMa9ef59sAR0lfO8VSYIsiRvbC2FbLB/92EoYw10Sl0kGixxHFiJZUSv7dA+YpR8g==", + "dev": true + }, + "@changesets/format": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@changesets/format/-/format-0.1.2.tgz", + "integrity": "sha512-Caez5XtNXCFS/G5bwyav3wuXL0tMxVd2ZGbaumWbzN08tyzO21asCw7JZhNtVsAZDCvDRUzZN+Iit9SyRITSYA==", + "dev": true, + "requires": { + "package-manager-detector": "^1.8.0", + "tinyexec": "^1.3.0" + } + }, + "@changesets/get-dependents-graph": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@changesets/get-dependents-graph/-/get-dependents-graph-3.0.0.tgz", + "integrity": "sha512-ji/t5wFA1zREKXRUePE6Qi+Qu2UgxCeSSGQrphezwvQZrp49B7sJ+8+wvM0tA7zPeSxYKCojDy3WWgrl+s+awg==", + "dev": true, + "requires": { + "@changesets/types": "^7.0.0", + "semver": "^7.8.1" + } + }, + "@changesets/get-github-info": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@changesets/get-github-info/-/get-github-info-1.0.0.tgz", + "integrity": "sha512-nf5zPSqEKW0eXiJ4ltbjyIQ/srUHfxbghkLCjKdOLI3LehKXhiqxXcpja39eGPaj6qqGx2lFCrLJ7VWYUf9H2w==", + "dev": true, + "requires": { + "dataloader": "^2.2.3" + } + }, + "@changesets/git": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@changesets/git/-/git-4.0.0.tgz", + "integrity": "sha512-uIEswpPUgzBBqrC0qg13byNaPorzhf05LE2T+gRizEKCXvMsJC6NPJp5iNDSV/gYj4Viqh09UiOF5E7XWeH5lQ==", + "dev": true, + "requires": { + "@changesets/errors": "^1.0.0", + "@changesets/types": "^7.0.0", + "@manypkg/get-packages": "^3.1.0", + "picomatch": "^4.0.4", + "tinyexec": "^1.3.0" + }, + "dependencies": { + "picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true + } + } + }, + "@changesets/parse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@changesets/parse/-/parse-1.0.0.tgz", + "integrity": "sha512-P0iaMb9p9CRYZiTgAllEIF9AUMQHIy1G72tKlcIqJp61icZSsKQNiOPdxAMZG8m/DvZwt/oz5xEbTpike//dWg==", + "dev": true, + "requires": { + "@changesets/types": "^7.0.0", + "yaml": "^2.9.0" + } + }, + "@changesets/pre": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@changesets/pre/-/pre-3.0.0.tgz", + "integrity": "sha512-Zm/6YliV/a2oeWTqHJf6KxLrQwgcK1i/BRDl2m0EKZvbnxV5fG9QRhwJJGshjsZTUTS6dkfURQ2K6aAvgNw/3Q==", + "dev": true, + "requires": { + "@changesets/errors": "^1.0.0", + "@changesets/types": "^7.0.0", + "@manypkg/get-packages": "^3.1.0" + } + }, + "@changesets/read": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@changesets/read/-/read-1.0.0.tgz", + "integrity": "sha512-8TdE2PwG6yArPt5Ozej83Z6iHz1G8BDBKvIEKZ455MccR4K3GNbLR2XqjBxa+5yLFnEd3xAOPXYboBg1pt8stQ==", + "dev": true, + "requires": { + "@changesets/git": "^4.0.0", + "@changesets/parse": "^1.0.0", + "@changesets/types": "^7.0.0" + } + }, + "@changesets/should-skip-package": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@changesets/should-skip-package/-/should-skip-package-1.0.0.tgz", + "integrity": "sha512-pwqoJmbONn1XgXmZXPEExgAaT+HdZLjALFTDgIm+PnS5KeO2nLtzA2/Q+4aMFY14kFMuXKG30MObhvDzWgzDgg==", + "dev": true, + "requires": { + "@changesets/types": "^7.0.0" + } + }, + "@changesets/types": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@changesets/types/-/types-7.0.0.tgz", + "integrity": "sha512-c5GoiQyt3pxiXjrWSNoP8/GRf4kG+VnKzovx1OQM8dYYALlSwgedmkPmJ+ZqGxqwg9D3Bkj85Uo4KLd5BN3A0w==", + "dev": true + }, + "@changesets/write": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@changesets/write/-/write-1.0.1.tgz", + "integrity": "sha512-q/ThtP9gcnEP6xlv7LrY26C2mHqdGBti/MmOVngt/M/oIGYkssmQGxPK9WzBNt2juVcH/vml2WQ+ra8LXYOTaA==", + "dev": true, + "requires": { + "@changesets/format": "^0.1.1", + "@changesets/types": "^7.0.0", + "human-id": "^4.2.0" + } + }, + "@clack/core": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@clack/core/-/core-1.4.3.tgz", + "integrity": "sha512-/kr3UWNtdJfxZtPgDqUOmG2pvwlmcLGheex5yiZKdwbzZJxhV+HMNR9QNmyY5cGwTNV6LrR7Jtp+KjhUAP1qBQ==", + "dev": true, + "requires": { + "fast-wrap-ansi": "^0.2.0", + "sisteransi": "^1.0.5" + } + }, + "@clack/prompts": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@clack/prompts/-/prompts-1.7.0.tgz", + "integrity": "sha512-y7/yvZ2TPAnR9+jnc00klvNNLkJiXFFrQA/hlLCcxA9a2A4zQIOimyFQ9XfwYKiGD1fb5GY8vbKIIgO8d5Tb2A==", + "dev": true, + "requires": { + "@clack/core": "1.4.3", + "fast-string-width": "^3.0.2", + "fast-wrap-ansi": "^0.2.0", + "sisteransi": "^1.0.5" + } + }, "@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", @@ -5729,6 +6503,36 @@ "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", "dev": true }, + "@manypkg/find-root": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@manypkg/find-root/-/find-root-3.1.0.tgz", + "integrity": "sha512-BcSqCyKhBVZ5YkSzOiheMCV41kqAFptW6xGqYSTjkVTl9XQpr+pqHhwgGCOHQtjDCv7Is6EFyA14Sm5GVbVABA==", + "dev": true, + "requires": { + "@manypkg/tools": "^2.1.0" + } + }, + "@manypkg/get-packages": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@manypkg/get-packages/-/get-packages-3.1.0.tgz", + "integrity": "sha512-0TbBVyvPrP7xGYBI/cP8UP+yl/z+HtbTttAD7FMAJgn/kXOTwh5/60TsqP9ZYY710forNfyV0N8P/IE/ujGZJg==", + "dev": true, + "requires": { + "@manypkg/find-root": "^3.1.0", + "@manypkg/tools": "^2.1.0" + } + }, + "@manypkg/tools": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@manypkg/tools/-/tools-2.1.2.tgz", + "integrity": "sha512-6QEf6yqFbETdwGITKq57aYoPfX/3K8XFNwsAlx0C1M7o8cb79sv1M3w+tWuWvIcSbNqrLF7OD7YpZMVVz335hQ==", + "dev": true, + "requires": { + "jju": "^1.4.0", + "tinyglobby": "^0.2.13", + "yaml": "^2.9.0" + } + }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -5761,6 +6565,12 @@ "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", "dev": true }, + "@pnpm/deps.graph-sequencer": { + "version": "1100.0.1", + "resolved": "https://registry.npmjs.org/@pnpm/deps.graph-sequencer/-/deps.graph-sequencer-1100.0.1.tgz", + "integrity": "sha512-pOr5+q1fLYKwFN3LAJuGZEnfXDcQ73zqgDHMtGy+K+uIoUqyY+6MeDCWFwfu+4EFuq76I5EPFofoNAI+Bmmq4A==", + "dev": true + }, "@socket.io/component-emitter": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", @@ -5888,15 +6698,6 @@ "requires": { "brace-expansion": "^2.0.1" } - }, - "semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } } } }, @@ -6215,6 +7016,12 @@ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "dev": true }, + "cac": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cac/-/cac-7.0.0.tgz", + "integrity": "sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==", + "dev": true + }, "call-bind": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", @@ -6484,6 +7291,12 @@ "is-data-view": "^1.0.1" } }, + "dataloader": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/dataloader/-/dataloader-2.2.3.tgz", + "integrity": "sha512-y2krtASINtPFS1rSDjacrFgn1dcUuoREVabwlOGOe4SdxenREqwjwjElAdwvbGM7kgZz9a3KVicWR7vcz8rnzA==", + "dev": true + }, "date-format": { "version": "4.0.14", "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", @@ -7117,15 +7930,6 @@ "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", "dev": true, "requires": {} - }, - "semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } } } }, @@ -7347,6 +8151,30 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, + "fast-string-truncated-width": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fast-string-truncated-width/-/fast-string-truncated-width-3.0.3.tgz", + "integrity": "sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==", + "dev": true + }, + "fast-string-width": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/fast-string-width/-/fast-string-width-3.0.2.tgz", + "integrity": "sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==", + "dev": true, + "requires": { + "fast-string-truncated-width": "^3.0.2" + } + }, + "fast-wrap-ansi": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/fast-wrap-ansi/-/fast-wrap-ansi-0.2.2.tgz", + "integrity": "sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==", + "dev": true, + "requires": { + "fast-string-width": "^3.0.2" + } + }, "fastq": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", @@ -7721,6 +8549,12 @@ "requires-port": "^1.0.0" } }, + "human-id": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/human-id/-/human-id-4.2.1.tgz", + "integrity": "sha512-zPGsiS+dWoTZtZ4AtpA9Y+BdSFSNWvnouNlWNoUFyAM6xHOHmdCvqO3k8AIbdamCOv4gUFUVNPf6rJFfc4UiJw==", + "dev": true + }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -7746,6 +8580,12 @@ "resolve-from": "^4.0.0" } }, + "import-meta-resolve": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz", + "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==", + "dev": true + }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -8045,6 +8885,12 @@ "set-function-name": "^2.0.1" } }, + "jju": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", + "integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==", + "dev": true + }, "js-yaml": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.1.tgz", @@ -8072,6 +8918,12 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, + "jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true + }, "jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", @@ -8210,6 +9062,16 @@ "language-subtag-registry": "^0.3.20" } }, + "launch-editor": { + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.14.1.tgz", + "integrity": "sha512-QWBrQsMpH7gPr965dsKD/3cKWiNoTjpATQf++Xq63N6sKRGMwlVXz41O1IZTMfZQgBctD/K5Zt06+/I6pP6+HA==", + "dev": true, + "requires": { + "picocolors": "^1.1.1", + "shell-quote": "^1.8.4" + } + }, "levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -8296,15 +9158,6 @@ "get-func-name": "^2.0.1" } }, - "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==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, "math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -8658,6 +9511,12 @@ "p-limit": "^3.0.2" } }, + "package-manager-detector": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.8.0.tgz", + "integrity": "sha512-yQA4H19AmPEoMUeavPMDIe1higySl/gH/yaQrkT/s07Qp+7pp2hYz30N3z2l5BkjVkF9Ow6o0wjJamm2y7Sn0A==", + "dev": true + }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -8710,9 +9569,9 @@ "dev": true }, "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "dev": true }, "picomatch": { @@ -8937,6 +9796,12 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, + "semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true + }, "serialize-javascript": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", @@ -8993,6 +9858,12 @@ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, + "shell-quote": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.10.0.tgz", + "integrity": "sha512-w1aiOKwKuRgtwAReIIj89puqg+I7GvX4IbLrvmhXbzQsj1+Zwi4VO3+fa6ZF91TWSjIxoEkKnMeHcLEODK5ZXA==", + "dev": true + }, "side-channel": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", @@ -9041,6 +9912,12 @@ "side-channel-map": "^1.0.1" } }, + "sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -9247,6 +10124,37 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "tinyexec": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.3.0.tgz", + "integrity": "sha512-QKAl9m8gWWGHV8jZcPeym6j+XULi6tOf1mT83WYJ4Lk2ytW/uwAWkrP0uFsdoYMdueVJ0qs26wZ+23xeB4ibNQ==", + "dev": true + }, + "tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "requires": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "dependencies": { + "fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "requires": {} + }, + "picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true + } + } + }, "tmp": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", @@ -9618,10 +10526,10 @@ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "yaml": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", + "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", "dev": true }, "yargs": { diff --git a/package.json b/package.json index 60f3e18..0619b6a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@github/remote-input-element", - "version": "0.3.1", + "version": "0.4.0", "description": "An input element that sends its value to a server endpoint and renders the response body.", "main": "dist/umd/index.js", "module": "dist/index.js", @@ -10,6 +10,10 @@ "files": [ "dist" ], + "publishConfig": { + "access": "public", + "provenance": true + }, "scripts": { "clean": "rm -rf dist", "lint": "eslint './src/**' './test/**.js'", @@ -17,10 +21,15 @@ "build": "tsc --outDir dist/umd --module umd && tsc", "pretest": "npm run build", "test": "karma start test/karma.config.js", + "test:dependabot-changeset": "node --test scripts/dependabot-changeset.test.mjs", + "changeset": "changeset", + "release": "npm_config_ignore_scripts=true changeset publish", "prepublishOnly": "npm run build", "postpublish": "npm publish --ignore-scripts --@github:registry='https://npm.pkg.github.com'" }, "devDependencies": { + "@changesets/changelog-github": "^1.0.0", + "@changesets/cli": "^3.0.1", "@typescript-eslint/parser": "^7.4.0", "chai": "^4.1.2", "eslint": "8.56.0", diff --git a/scripts/dependabot-changeset.mjs b/scripts/dependabot-changeset.mjs new file mode 100644 index 0000000..4ee6e55 --- /dev/null +++ b/scripts/dependabot-changeset.mjs @@ -0,0 +1,227 @@ +#!/usr/bin/env node +import {Buffer} from 'node:buffer' +import {readFileSync} from 'node:fs' + +export const CHANGESET_PREFIX = 'dependabot-' + +function parseList(value) { + if (!value) return [] + if (Array.isArray(value)) return value.flatMap(parseList) + + return String(value) + .split(/[\n,]+/) + .map(item => item.trim()) + .filter(Boolean) +} + +function unique(values) { + return [...new Set(values)] +} + +function getUpdatedDependencyNames(metadata) { + if (!metadata['updated-dependencies-json']) return [] + + try { + const dependencies = JSON.parse(metadata['updated-dependencies-json']) + if (!Array.isArray(dependencies)) return [] + + return dependencies + .map(dependency => dependency.dependencyName ?? dependency['dependency-name'] ?? dependency.name) + .filter(Boolean) + } catch { + return [] + } +} + +export function getDependencyNames(metadata) { + return unique([...getUpdatedDependencyNames(metadata), ...parseList(metadata['dependency-names'] ?? metadata['dependency-name'])]) +} + +export function isSecurityUpdate(metadata) { + let dependencies = [] + try { + const parsed = JSON.parse(metadata['updated-dependencies-json'] ?? '[]') + dependencies = Array.isArray(parsed) ? parsed : [] + } catch {} + + return [{alertState: metadata['alert-state'], ghsaId: metadata['ghsa-id']}, ...dependencies].some(dependency => { + const alertState = String(dependency.alertState ?? dependency['alert-state'] ?? '').trim().toLowerCase() + if (alertState === 'fixed') return true + if (alertState === 'dismissed') return false + return parseList(dependency.ghsaId ?? dependency['ghsa-id']).length > 0 + }) +} + +export function getProductionRangeChanges({basePackage, headPackage, dependencyNames}) { + const baseDependencies = basePackage.dependencies ?? {} + const headDependencies = headPackage.dependencies ?? {} + + return dependencyNames.filter(name => { + if (!(name in baseDependencies) && !(name in headDependencies)) return false + return baseDependencies[name] !== headDependencies[name] + }) +} + +export function evaluatePolicy({basePackage, headPackage, metadata}) { + const dependencyNames = getDependencyNames(metadata) + const securityUpdate = isSecurityUpdate(metadata) + const productionRangeChanges = getProductionRangeChanges({basePackage, headPackage, dependencyNames}) + + return { + dependencyNames, + qualifies: securityUpdate || productionRangeChanges.length > 0, + reasons: { + securityUpdate, + productionRangeChanges, + }, + } +} + +function formatList(items) { + if (items.length === 0) return 'dependencies' + if (items.length === 1) return `\`${items[0]}\`` + return `${items.slice(0, -1).map(item => `\`${item}\``).join(', ')} and \`${items.at(-1)}\`` +} + +export function renderChangeset({packageName, prNumber, policy}) { + const names = policy.dependencyNames + const reason = policy.reasons.securityUpdate + ? `Resolve Dependabot security alert(s) for ${formatList(names)}.` + : `Bump production dependency range(s) for ${formatList(policy.reasons.productionRangeChanges)}.` + + return `---\n"${packageName}": patch\n---\n\n${reason}\n\nGenerated for Dependabot PR #${prNumber}.\n` +} + +function encodePath(path) { + return path.split('/').map(encodeURIComponent).join('/') +} + +async function githubRequest(path, {method = 'GET', token, body, accept = 'application/vnd.github+json'} = {}) { + const response = await fetch(`https://api.github.com${path}`, { + method, + headers: { + accept, + authorization: 'Bearer ' + token, + 'content-type': 'application/json', + 'x-github-api-version': '2022-11-28', + }, + body: body === undefined ? undefined : JSON.stringify(body), + }) + + if (response.status === 404) return undefined + if (!response.ok) { + throw new Error(`${method} ${path} failed with ${response.status}: ${await response.text()}`) + } + + return response.json() +} + +async function readJsonContent({owner, repo, path, ref, token}) { + const content = await githubRequest(`/repos/${owner}/${repo}/contents/${encodePath(path)}?ref=${encodeURIComponent(ref)}`, { + token, + }) + if (!content?.content) throw new Error(`Unable to read ${path} at ${ref}`) + return JSON.parse(Buffer.from(content.content, 'base64').toString('utf8')) +} + +async function getContent({owner, repo, path, ref, token}) { + return githubRequest(`/repos/${owner}/${repo}/contents/${encodePath(path)}?ref=${encodeURIComponent(ref)}`, {token}) +} + +async function putContent({owner, repo, path, branch, content, token, message, sha}) { + await githubRequest(`/repos/${owner}/${repo}/contents/${encodePath(path)}`, { + method: 'PUT', + token, + body: { + message, + content: Buffer.from(content).toString('base64'), + branch, + sha, + }, + }) +} + +async function deleteContent({owner, repo, path, branch, token, message, sha}) { + await githubRequest(`/repos/${owner}/${repo}/contents/${encodePath(path)}`, { + method: 'DELETE', + token, + body: {message, branch, sha}, + }) +} + +export async function applyDependabotChangeset({event, metadata, token}) { + const pr = event.pull_request + if (!pr) throw new Error('This script must run for a pull request event.') + if (pr.user.login !== 'dependabot[bot]') throw new Error(`Refusing to modify PR authored by ${pr.user.login}.`) + if (pr.head.repo.full_name !== event.repository.full_name) { + throw new Error('Refusing to write to a pull request branch from a different repository.') + } + + const [owner, repo] = event.repository.full_name.split('/') + const basePackage = await readJsonContent({owner, repo, path: 'package.json', ref: pr.base.sha, token}) + const headPackage = await readJsonContent({owner, repo, path: 'package.json', ref: pr.head.sha, token}) + const policy = evaluatePolicy({basePackage, headPackage, metadata}) + const changesetPath = `.changeset/${CHANGESET_PREFIX}${pr.number}.md` + const existing = await getContent({owner, repo, path: changesetPath, ref: pr.head.ref, token}) + + if (!policy.qualifies) { + if (existing) { + await deleteContent({ + owner, + repo, + path: changesetPath, + branch: pr.head.ref, + token, + message: `Remove Dependabot changeset for #${pr.number}`, + sha: existing.sha, + }) + return {action: 'removed', path: changesetPath, policy} + } + + return {action: 'skipped', path: changesetPath, policy} + } + + const content = renderChangeset({packageName: headPackage.name, prNumber: pr.number, policy}) + if (existing && Buffer.from(existing.content, 'base64').toString('utf8') === content) { + return {action: 'unchanged', path: changesetPath, policy} + } + + await putContent({ + owner, + repo, + path: changesetPath, + branch: pr.head.ref, + token, + content, + message: `Add Dependabot changeset for #${pr.number}`, + sha: existing?.sha, + }) + + return {action: existing ? 'updated' : 'created', path: changesetPath, policy} +} + +function metadataFromEnv(env) { + return { + 'dependency-names': env.DEPENDABOT_DEPENDENCY_NAMES ?? '', + 'updated-dependencies-json': env.DEPENDABOT_UPDATED_DEPENDENCIES_JSON ?? '', + 'alert-state': env.DEPENDABOT_ALERT_STATE ?? '', + 'ghsa-id': env.DEPENDABOT_GHSA_ID ?? '', + } +} + +if (import.meta.url === `file://${process.argv[1]}`) { + const event = JSON.parse(process.env.GITHUB_EVENT_JSON ?? readFileSync(process.env.GITHUB_EVENT_PATH, 'utf8')) + const metadata = metadataFromEnv(process.env) + const token = process.env.GITHUB_TOKEN + if (!token) throw new Error('GITHUB_TOKEN is required.') + + applyDependabotChangeset({event, metadata, token}) + .then(result => { + console.log(`${result.action} ${result.path}`) + console.log(JSON.stringify(result.policy, null, 2)) + }) + .catch(error => { + console.error(error) + process.exitCode = 1 + }) +} diff --git a/scripts/dependabot-changeset.test.mjs b/scripts/dependabot-changeset.test.mjs new file mode 100644 index 0000000..8888477 --- /dev/null +++ b/scripts/dependabot-changeset.test.mjs @@ -0,0 +1,202 @@ +import assert from 'node:assert/strict' +import {Buffer} from 'node:buffer' +import {describe, test} from 'node:test' + +import {applyDependabotChangeset, evaluatePolicy, renderChangeset} from './dependabot-changeset.mjs' + +const basePackage = { + name: '@github/remote-input-element', + dependencies: { + '@github/auto-check-element': '^1.0.0', + 'remote-form': '^2.0.0', + }, + devDependencies: { + eslint: '^8.0.0', + }, +} + +function policy({headPackage = basePackage, metadata}) { + return evaluatePolicy({basePackage, headPackage, metadata}) +} + +describe('evaluatePolicy', () => { + test('adds a patch changeset for a direct production dependency with a changed manifest range', () => { + const result = policy({ + headPackage: { + ...basePackage, + dependencies: {...basePackage.dependencies, '@github/auto-check-element': '^2.0.0'}, + }, + metadata: {'dependency-names': '@github/auto-check-element', 'alert-state': ''}, + }) + + assert.equal(result.qualifies, true) + assert.deepEqual(result.reasons.productionRangeChanges, ['@github/auto-check-element']) + }) + + test('does not add a changeset for a direct development dependency', () => { + const result = policy({ + headPackage: { + ...basePackage, + devDependencies: {...basePackage.devDependencies, eslint: '^9.0.0'}, + }, + metadata: {'dependency-names': 'eslint', 'alert-state': ''}, + }) + + assert.equal(result.qualifies, false) + }) + + test('does not add a changeset for an indirect dependency', () => { + const result = policy({metadata: {'dependency-names': 'debug', 'alert-state': ''}}) + + assert.equal(result.qualifies, false) + }) + + test('does not add a changeset for an inclusive lockfile-only update', () => { + const result = policy({metadata: {'dependency-names': '@github/auto-check-element', 'alert-state': ''}}) + + assert.equal(result.qualifies, false) + }) + + test('adds a changeset for a security update to a development dependency', () => { + const result = policy({ + headPackage: { + ...basePackage, + devDependencies: {...basePackage.devDependencies, eslint: '^8.1.0'}, + }, + metadata: {'dependency-names': 'eslint', 'alert-state': 'fixed'}, + }) + + assert.equal(result.qualifies, true) + assert.equal(result.reasons.securityUpdate, true) + }) + + test('adds a changeset for a security update to an indirect dependency', () => { + const result = policy({metadata: {'dependency-names': 'debug', 'ghsa-id': 'GHSA-abcd-1234-efgh'}}) + + assert.equal(result.qualifies, true) + assert.equal(result.reasons.securityUpdate, true) + }) + + test('adds exactly one changeset for a grouped PR where any update qualifies', () => { + const result = policy({ + headPackage: { + ...basePackage, + dependencies: {...basePackage.dependencies, 'remote-form': '^3.0.0'}, + devDependencies: {...basePackage.devDependencies, eslint: '^9.0.0'}, + }, + metadata: { + 'updated-dependencies-json': JSON.stringify([ + {dependencyName: 'eslint'}, + {dependencyName: 'remote-form'}, + {dependencyName: 'debug'}, + ]), + 'alert-state': '', + }, + }) + + const changeset = renderChangeset({packageName: basePackage.name, prNumber: 54, policy: result}) + + assert.equal(result.qualifies, true) + assert.deepEqual(result.reasons.productionRangeChanges, ['remote-form']) + assert.equal((changeset.match(/---/g) ?? []).length, 2) + assert.match(changeset, /Generated for Dependabot PR #54\./) + }) + + test('repeated renders are idempotent', () => { + const result = policy({ + headPackage: { + ...basePackage, + dependencies: {...basePackage.dependencies, 'remote-form': '^3.0.0'}, + }, + metadata: {'dependency-names': 'remote-form', 'alert-state': ''}, + }) + + assert.equal( + renderChangeset({packageName: basePackage.name, prNumber: 54, policy: result}), + renderChangeset({packageName: basePackage.name, prNumber: 54, policy: result}), + ) + }) + + test('a previously generated changeset is removed when the PR no longer qualifies', () => { + const qualifying = policy({ + headPackage: { + ...basePackage, + dependencies: {...basePackage.dependencies, 'remote-form': '^3.0.0'}, + }, + metadata: {'dependency-names': 'remote-form', 'alert-state': ''}, + }) + const noLongerQualifying = policy({metadata: {'dependency-names': 'remote-form', 'alert-state': ''}}) + + assert.equal(qualifying.qualifies, true) + assert.equal(noLongerQualifying.qualifies, false) + }) +}) + +describe('applyDependabotChangeset', () => { + test('removes the existing changeset when the PR no longer qualifies', async t => { + const changesetPath = '.changeset/dependabot-54.md' + const existingSha = 'existing-sha' + const requests = [] + const originalFetch = globalThis.fetch + + globalThis.fetch = async (url, init = {}) => { + const {pathname, searchParams} = new URL(url) + requests.push({pathname, method: init.method ?? 'GET', body: init.body ? JSON.parse(init.body) : undefined}) + + if (pathname === '/repos/github/remote-input-element/contents/package.json') { + // Both `base.sha` and `head.sha` resolve to the same manifest so this PR no longer + // qualifies (a lockfile-only update), matching the scenario under test. + const ref = searchParams.get('ref') + const pkg = ref === 'base-sha' || ref === 'head-sha' ? basePackage : undefined + if (!pkg) throw new Error(`Unexpected ref ${ref}`) + + return { + ok: true, + status: 200, + json: async () => ({content: Buffer.from(JSON.stringify(pkg)).toString('base64')}), + } + } + + if (pathname === `/repos/github/remote-input-element/contents/${changesetPath}`) { + if ((init.method ?? 'GET') === 'DELETE') { + return {ok: true, status: 200, json: async () => ({})} + } + + return { + ok: true, + status: 200, + json: async () => ({sha: existingSha, content: Buffer.from('placeholder').toString('base64')}), + } + } + + throw new Error(`Unexpected request to ${url}`) + } + t.after(() => { + globalThis.fetch = originalFetch + }) + + const event = { + pull_request: { + number: 54, + user: {login: 'dependabot[bot]'}, + base: {sha: 'base-sha'}, + head: {sha: 'head-sha', ref: 'dependabot/npm_and_yarn/remote-form-2.0.1', repo: {full_name: 'github/remote-input-element'}}, + }, + repository: {full_name: 'github/remote-input-element'}, + } + + const result = await applyDependabotChangeset({ + event, + metadata: {'dependency-names': 'remote-form', 'alert-state': ''}, + token: 'test-token', + }) + + assert.equal(result.action, 'removed') + + const deleteRequest = requests.find(request => request.method === 'DELETE') + assert.ok(deleteRequest, 'expected a DELETE request for the changeset') + assert.equal(deleteRequest.pathname, `/repos/github/remote-input-element/contents/${changesetPath}`) + assert.equal(deleteRequest.body.branch, 'dependabot/npm_and_yarn/remote-form-2.0.1') + assert.equal(deleteRequest.body.sha, existingSha) + }) +})