From cd94aca4896828652cfd0857ce29a179326b0a6c Mon Sep 17 00:00:00 2001 From: Charles Hudson Date: Wed, 8 Jul 2026 15:43:26 +0200 Subject: [PATCH] feat(repo): new semantic versioning and CD process Replace the `commitizen`/`cz-vinyl` workflow with Commitlint-backed Conventional Commits. Commit messages now require scopes, local `commit-msg` validation, CI checks for PR titles and pushed `main` commits, and an interactive prompt for `pnpm commit` and plain interactive `git commit`. Add Release Please manifest mode as the source of truth for independent package releases. The manifest covers all public NPM packages plus Android and Swift, uses package-specific components and tags, and keeps one shared release PR titled `chore(repo): release packages`. Bootstrap the first semantic release away from the old alpha line. The initial generated releases are forced to `1.0.0` for GA NPM packages and `1.0.0-beta.0` for Android and Swift. Package-local `CHANGELOG.md` seeds make this PR touch every configured release path. Add a small Release Please runner with a `native-bridge-impact` plugin. Shared releasable runtime changes in the bridge/core path synthesize Android and Swift patch candidates. Real `android` and `swift` commits can still drive their own minor or major bumps. Update publishing to run only from released package tags. NPM publishing resolves package-specific Release Please tags, sorts released packages in workspace dependency order, rewrites package READMEs for their release tag, skips already-published versions, and publishes only to GitHub Packages. Android and Swift publishing now require `optimization-android-v*` and `optimization-swift-v*` tags. They derive versions from those tags and stamp native bridge builds with the released version. Add native `VERSION` files, Release Please config, package changelog seeds, release self-checks, and package-version build helpers so published bundles can fall back to `package.json` versions outside release-tag builds. Refresh `CONTRIBUTING.md` with the new contributor and maintainer flow: scoped commit expectations, squash-merge PR title rules, release impact guidance, Release Please ownership, publishing behavior, and troubleshooting notes. [[NT-3524](https://contentful.atlassian.net/browse/NT-3524)] --- .czrc | 3 - .github/workflows/commitlint.yaml | 45 + .github/workflows/main-pipeline.yaml | 2 +- .github/workflows/publish-android.yaml | 16 +- .github/workflows/publish-npm.yaml | 154 +- .github/workflows/publish-spm.yaml | 24 +- .github/workflows/release-please.yaml | 40 + .husky/commit-msg | 5 + .husky/prepare-commit-msg | 13 +- .release-please-manifest.json | 13 + CONTRIBUTING.md | 570 +++--- commitlint.config.cjs | 46 + lib/build-tools/src/index.ts | 2 +- lib/build-tools/src/package.test.ts | 42 +- lib/build-tools/src/package.ts | 46 +- package.json | 14 +- .../android/ContentfulOptimization/AGENTS.md | 5 +- .../ContentfulOptimization/CHANGELOG.md | 3 + .../android/ContentfulOptimization/VERSION | 1 + .../ContentfulOptimization/build.gradle.kts | 2 +- .../ios/ContentfulOptimization/CHANGELOG.md | 3 + packages/ios/ContentfulOptimization/VERSION | 1 + packages/node/node-sdk/CHANGELOG.md | 3 + packages/node/node-sdk/rslib.config.ts | 5 +- packages/react-native-sdk/CHANGELOG.md | 3 + packages/react-native-sdk/rslib.config.ts | 5 +- packages/universal/api-client/CHANGELOG.md | 3 + packages/universal/api-schemas/CHANGELOG.md | 3 + packages/universal/core-sdk/CHANGELOG.md | 3 + packages/universal/core-sdk/rslib.config.ts | 5 +- .../web/frameworks/nextjs-sdk/CHANGELOG.md | 3 + .../web/frameworks/nextjs-sdk/rslib.config.ts | 5 +- .../web/frameworks/react-web-sdk/CHANGELOG.md | 3 + .../frameworks/react-web-sdk/rslib.config.ts | 5 +- packages/web/preview-panel/CHANGELOG.md | 3 + packages/web/preview-panel/rslib.config.ts | 10 +- packages/web/web-sdk/CHANGELOG.md | 3 + packages/web/web-sdk/rslib.config.ts | 10 +- pnpm-lock.yaml | 1609 +++++++++++------ pnpm-workspace.yaml | 5 + release-please-config.json | 95 + scripts/list-npm-package-targets.ts | 164 +- scripts/prepare-commit-message.ts | 261 +++ scripts/release-please.ts | 334 ++++ 44 files changed, 2650 insertions(+), 940 deletions(-) delete mode 100644 .czrc create mode 100644 .github/workflows/commitlint.yaml create mode 100644 .github/workflows/release-please.yaml create mode 100644 .husky/commit-msg create mode 100644 .release-please-manifest.json create mode 100644 commitlint.config.cjs create mode 100644 packages/android/ContentfulOptimization/CHANGELOG.md create mode 100644 packages/android/ContentfulOptimization/VERSION create mode 100644 packages/ios/ContentfulOptimization/CHANGELOG.md create mode 100644 packages/ios/ContentfulOptimization/VERSION create mode 100644 packages/node/node-sdk/CHANGELOG.md create mode 100644 packages/react-native-sdk/CHANGELOG.md create mode 100644 packages/universal/api-client/CHANGELOG.md create mode 100644 packages/universal/api-schemas/CHANGELOG.md create mode 100644 packages/universal/core-sdk/CHANGELOG.md create mode 100644 packages/web/frameworks/nextjs-sdk/CHANGELOG.md create mode 100644 packages/web/frameworks/react-web-sdk/CHANGELOG.md create mode 100644 packages/web/preview-panel/CHANGELOG.md create mode 100644 packages/web/web-sdk/CHANGELOG.md create mode 100644 release-please-config.json create mode 100644 scripts/prepare-commit-message.ts create mode 100644 scripts/release-please.ts diff --git a/.czrc b/.czrc deleted file mode 100644 index 1ef3f835a..000000000 --- a/.czrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "path": "cz-vinyl" -} diff --git a/.github/workflows/commitlint.yaml b/.github/workflows/commitlint.yaml new file mode 100644 index 000000000..c5eec5158 --- /dev/null +++ b/.github/workflows/commitlint.yaml @@ -0,0 +1,45 @@ +name: Commitlint + +permissions: + contents: read + +on: + pull_request: + types: [opened, edited, reopened, synchronize, ready_for_review] + push: + branches: + - main + +jobs: + commitlint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 + + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version-file: '.nvmrc' + package-manager-cache: false + + - uses: pnpm/action-setup@903f9c1a6ebcba6cf41d87230be49611ac97822e # v6.0.3 + + - run: pnpm install --prefer-offline --frozen-lockfile + + - name: Lint pull request title + if: github.event_name == 'pull_request' + env: + PR_TITLE: ${{ github.event.pull_request.title }} + run: printf '%s\n' "$PR_TITLE" | pnpm exec commitlint + + - name: Lint pushed commits + if: github.event_name == 'push' + env: + COMMITLINT_FROM: ${{ github.event.before }} + run: | + if [[ "$COMMITLINT_FROM" =~ ^0+$ ]]; then + exit 0 + fi + + pnpm exec commitlint --from "$COMMITLINT_FROM" --to "$GITHUB_SHA" --verbose diff --git a/.github/workflows/main-pipeline.yaml b/.github/workflows/main-pipeline.yaml index cbb57028c..4793ddb69 100644 --- a/.github/workflows/main-pipeline.yaml +++ b/.github/workflows/main-pipeline.yaml @@ -45,7 +45,7 @@ jobs: # - Markdown plus docs/documentation changes do not trigger build, unit, native, or E2E jobs. # - Implementation E2E jobs run only for implementations relevant to changed paths. # - Skipped E2E jobs due to unmatched filters are expected behavior. - # - Keep this mapping aligned with CONTRIBUTING.md ("E2E Coverage and Environment"). + # - Keep this mapping aligned with CONTRIBUTING.md ("E2E jobs"). filters: | build: - '{lib/**,packages/**,implementations/**,package.json,pnpm-lock.yaml,pnpm-workspace.yaml,tsconfig*.json,.github/workflows/main-pipeline.yaml}' diff --git a/.github/workflows/publish-android.yaml b/.github/workflows/publish-android.yaml index 5d16e23ac..8c5c31059 100644 --- a/.github/workflows/publish-android.yaml +++ b/.github/workflows/publish-android.yaml @@ -9,7 +9,7 @@ on: workflow_dispatch: inputs: tag: - description: 'Existing release tag (e.g. v1.2.3)' + description: 'Existing Android release tag (e.g. optimization-android-v1.2.3)' required: true publish: description: 'Actually publish' @@ -18,6 +18,9 @@ on: jobs: publish: + if: + github.event_name == 'workflow_dispatch' || startsWith(github.event.release.tag_name, + 'optimization-android-v') runs-on: ubuntu-latest steps: - name: Derive release version @@ -27,8 +30,15 @@ jobs: else TAG='${{ inputs.tag }}' fi - echo "RELEASE_TAG=$TAG" >> "$GITHUB_ENV" - echo "RELEASE_VERSION=${TAG#v}" >> "$GITHUB_ENV" + case "$TAG" in + optimization-android-v*) ;; + *) + echo "Expected optimization-android-v* tag, got $TAG." >&2 + exit 1 + ;; + esac + echo "RELEASE_TAG=$TAG" >> "$GITHUB_ENV" + echo "RELEASE_VERSION=${TAG#optimization-android-v}" >> "$GITHUB_ENV" - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: diff --git a/.github/workflows/publish-npm.yaml b/.github/workflows/publish-npm.yaml index 3331fd144..bbf433fbb 100644 --- a/.github/workflows/publish-npm.yaml +++ b/.github/workflows/publish-npm.yaml @@ -5,13 +5,17 @@ permissions: id-token: write packages: write +concurrency: + group: publish-npm-${{ github.event.release.target_commitish || inputs.tag || github.run_id }} + cancel-in-progress: false + on: release: types: [published] workflow_dispatch: inputs: tag: - description: 'Existing release tag (e.g. v1.2.3)' + description: 'Existing package release tag (e.g. optimization-core-v1.2.3)' required: true publish: description: 'Actually publish' @@ -22,19 +26,8 @@ jobs: publish: runs-on: ubuntu-latest steps: - - name: Retrieve Secrets from Vault - if: github.event_name == 'release' || inputs.publish - id: vault - uses: hashicorp/vault-action@4c06c5ccf5c0761b6029f56cfb1dcf5565918a3b # v3.4.0 - with: - url: ${{ secrets.VAULT_URL }} - role: ${{ github.event.repository.name }}-github-action - method: jwt - path: github-actions - secrets: | - secret/data/github/github_packages_write GITHUB_PACKAGES_WRITE_TOKEN | GITHUB_PACKAGES_WRITE_TOKEN; - - - name: Derive release version + - name: Derive release tag + id: release_tag run: | if [ "${{ github.event_name }}" = "release" ]; then TAG='${{ github.event.release.tag_name }}' @@ -42,11 +35,12 @@ jobs: TAG='${{ inputs.tag }}' fi echo "RELEASE_TAG=$TAG" >> "$GITHUB_ENV" - echo "RELEASE_VERSION=${TAG#v}" >> "$GITHUB_ENV" + echo "release_tag=$TAG" >> "$GITHUB_OUTPUT" - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: - ref: ${{ github.event_name == 'release' && github.event.release.tag_name || inputs.tag }} + ref: ${{ steps.release_tag.outputs.release_tag }} + fetch-depth: 0 - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: @@ -61,32 +55,86 @@ jobs: - name: Resolve npm package targets id: npm_package_targets run: | - echo "pnpm_filters=$(./node_modules/.bin/tsx scripts/list-npm-package-targets.ts npm-pnpm-filters)" >> "$GITHUB_OUTPUT" + if [ "${{ github.event_name }}" = "release" ]; then + mapfile -t release_tags < <(git tag --points-at HEAD 'optimization-*-v*' | sort) + else + release_tags=("$RELEASE_TAG") + fi - - name: Bump package.json versions - run: | - pnpm -r ${{ steps.npm_package_targets.outputs.pnpm_filters }} exec \ - npm --no-git-tag-version --force version "$RELEASE_VERSION" - env: - RELEASE_VERSION: ${{ env.RELEASE_VERSION }} + release_targets="$(./node_modules/.bin/tsx scripts/list-npm-package-targets.ts released-npm-targets "${release_tags[@]}")" + pnpm_filters="$(./node_modules/.bin/tsx scripts/list-npm-package-targets.ts released-npm-pnpm-filters "${release_tags[@]}")" + + if [ -z "$release_targets" ]; then + echo "has_targets=false" >> "$GITHUB_OUTPUT" + exit 0 + fi + + IFS=$'\t' read -r package_name _package_dir _report_path _release_tag release_version <<< "$(printf '%s\n' "$release_targets" | head -n 1)" + + if [ -z "$package_name" ] || [ -z "$release_version" ]; then + echo "Invalid npm release target: $release_targets" >&2 + exit 1 + fi + + { + echo "has_targets=true" + echo "release_tags<> "$GITHUB_OUTPUT" + + - name: Retrieve Secrets from Vault + if: + steps.npm_package_targets.outputs.has_targets == 'true' && (github.event_name == 'release' + || inputs.publish) + id: vault + uses: hashicorp/vault-action@4c06c5ccf5c0761b6029f56cfb1dcf5565918a3b # v3.4.0 + with: + url: ${{ secrets.VAULT_URL }} + role: ${{ github.event.repository.name }}-github-action + method: jwt + path: github-actions + secrets: | + secret/data/github/github_packages_write GITHUB_PACKAGES_WRITE_TOKEN | GITHUB_PACKAGES_WRITE_TOKEN; - name: Build + if: steps.npm_package_targets.outputs.has_targets == 'true' run: pnpm build - env: - RELEASE_VERSION: ${{ env.RELEASE_VERSION }} - name: Generate npm third-party notices + if: steps.npm_package_targets.outputs.has_targets == 'true' run: pnpm notices:generate:npm - name: Prepare package READMEs for publish - run: | - pnpm -r ${{ steps.npm_package_targets.outputs.pnpm_filters }} exec build-tools rewrite-readme prepare + if: steps.npm_package_targets.outputs.has_targets == 'true' env: - RELEASE_TAG: ${{ env.RELEASE_TAG }} + RELEASE_TARGETS: ${{ steps.npm_package_targets.outputs.release_targets }} + run: | + while IFS= read -r target_info; do + if [ -z "$target_info" ]; then + continue + fi + + IFS=$'\t' read -r _package_name package_dir _report_path release_tag _release_version <<< "$target_info" + + if [ -z "$package_dir" ] || [ -z "$release_tag" ]; then + echo "Invalid npm README target: $target_info" >&2 + exit 1 + fi + + RELEASE_TAG="$release_tag" pnpm --dir "$package_dir" exec build-tools rewrite-readme prepare + done <<< "$RELEASE_TARGETS" - name: Stage third-party notices for publish + if: steps.npm_package_targets.outputs.has_targets == 'true' + env: + NOTICE_TARGETS: ${{ steps.npm_package_targets.outputs.release_targets }} run: | - notice_targets="$(./node_modules/.bin/tsx scripts/list-npm-package-targets.ts npm-targets)" + notice_targets="$NOTICE_TARGETS" if [ -z "$notice_targets" ]; then echo "No npm notice targets found." >&2 @@ -98,7 +146,7 @@ jobs: continue fi - IFS=$'\t' read -r package_name package_dir report_path <<< "$target_info" + IFS=$'\t' read -r package_name package_dir report_path _release_tag _release_version <<< "$target_info" if [ -z "$package_name" ] || [ -z "$package_dir" ] || [ -z "$report_path" ]; then echo "Invalid npm notice target: $target_info" >&2 @@ -119,12 +167,18 @@ jobs: done <<< "$notice_targets" - name: Create packages for troubleshooting - run: pnpm run pack:pkgs + if: steps.npm_package_targets.outputs.has_targets == 'true' + run: | + rm -rf pkgs + mkdir -p pkgs + pnpm pack ${{ steps.npm_package_targets.outputs.pnpm_filters }} --pack-destination pkgs - name: Verify packages include third-party notices + if: steps.npm_package_targets.outputs.has_targets == 'true' run: bash ./scripts/verify-npm-package-notices.sh pkgs - name: Upload packages for troubleshooting + if: steps.npm_package_targets.outputs.has_targets == 'true' uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: ci-optimization-sdk-packages @@ -133,16 +187,48 @@ jobs: retention-days: 3 - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 - if: github.event_name == 'release' || inputs.publish + if: + steps.npm_package_targets.outputs.has_targets == 'true' && (github.event_name == 'release' + || inputs.publish) with: node-version-file: '.nvmrc' registry-url: 'https://npm.pkg.github.com' scope: '@contentful' package-manager-cache: false + - name: Resolve unpublished targets + if: + steps.npm_package_targets.outputs.has_targets == 'true' && (github.event_name == 'release' + || inputs.publish) + id: unpublished_targets + env: + NODE_AUTH_TOKEN: ${{ steps.vault.outputs.GITHUB_PACKAGES_WRITE_TOKEN }} + RELEASE_TARGETS: ${{ steps.npm_package_targets.outputs.release_targets }} + run: | + publish_filters=() + + while IFS= read -r target_info; do + if [ -z "$target_info" ]; then + continue + fi + + IFS=$'\t' read -r package_name _package_dir _report_path _release_tag release_version <<< "$target_info" + + if npm view "$package_name@$release_version" version --registry=https://npm.pkg.github.com >/dev/null 2>&1; then + echo "$package_name@$release_version is already published; skipping." + continue + fi + + publish_filters+=(--filter "$package_name") + done <<< "$RELEASE_TARGETS" + + echo "pnpm_filters=${publish_filters[*]}" >> "$GITHUB_OUTPUT" + - name: Publish - if: github.event_name == 'release' || inputs.publish + if: + steps.unpublished_targets.outputs.pnpm_filters != '' && (github.event_name == 'release' || + inputs.publish) run: | - pnpm -r ${{ steps.npm_package_targets.outputs.pnpm_filters }} publish --access public --no-git-checks + pnpm -r ${{ steps.unpublished_targets.outputs.pnpm_filters }} publish --access public --no-git-checks env: NODE_AUTH_TOKEN: ${{ steps.vault.outputs.GITHUB_PACKAGES_WRITE_TOKEN }} diff --git a/.github/workflows/publish-spm.yaml b/.github/workflows/publish-spm.yaml index 4ea6309ce..a4d29a8fd 100644 --- a/.github/workflows/publish-spm.yaml +++ b/.github/workflows/publish-spm.yaml @@ -9,7 +9,7 @@ on: workflow_dispatch: inputs: tag: - description: 'Existing release tag (e.g. v1.2.3)' + description: 'Existing Swift release tag (e.g. optimization-swift-v1.2.3)' required: true publish: description: 'Actually publish' @@ -18,6 +18,9 @@ on: jobs: publish: + if: + github.event_name == 'workflow_dispatch' || startsWith(github.event.release.tag_name, + 'optimization-swift-v') runs-on: macos-latest steps: - name: Derive release version @@ -27,8 +30,17 @@ jobs: else TAG='${{ inputs.tag }}' fi - echo "RELEASE_TAG=$TAG" >> "$GITHUB_ENV" - echo "RELEASE_VERSION=${TAG#v}" >> "$GITHUB_ENV" + case "$TAG" in + optimization-swift-v*) ;; + *) + echo "Expected optimization-swift-v* tag, got $TAG." >&2 + exit 1 + ;; + esac + VERSION="${TAG#optimization-swift-v}" + echo "RELEASE_TAG=$TAG" >> "$GITHUB_ENV" + echo "RELEASE_VERSION=$VERSION" >> "$GITHUB_ENV" + echo "SPM_RELEASE_TAG=v$VERSION" >> "$GITHUB_ENV" - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -94,8 +106,8 @@ jobs: echo "No content changes since the last release commit; moving the tag only." else git -c user.name='contentful-ci' -c user.email='ci@contentful.com' \ - commit -m "Release $RELEASE_TAG (from contentful/optimization@${GITHUB_SHA:0:7})" + commit -m "Release $SPM_RELEASE_TAG (from contentful/optimization@${GITHUB_SHA:0:7})" git push origin HEAD:main fi - git tag --force "$RELEASE_TAG" - git push origin "refs/tags/$RELEASE_TAG" --force + git tag --force "$SPM_RELEASE_TAG" + git push origin "refs/tags/$SPM_RELEASE_TAG" --force diff --git a/.github/workflows/release-please.yaml b/.github/workflows/release-please.yaml new file mode 100644 index 000000000..a9d76453d --- /dev/null +++ b/.github/workflows/release-please.yaml @@ -0,0 +1,40 @@ +name: Release Please + +permissions: + contents: write + issues: write + pull-requests: write + +on: + push: + branches: + - main + workflow_dispatch: + +jobs: + release-please: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 + + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version-file: '.nvmrc' + package-manager-cache: false + + - uses: pnpm/action-setup@903f9c1a6ebcba6cf41d87230be49611ac97822e # v6.0.3 + + - run: pnpm install --prefer-offline --frozen-lockfile + + - name: Create GitHub releases + run: + pnpm release:please -- github-release --repo-url "$GITHUB_REPOSITORY" --target-branch main + env: + RELEASE_PLEASE_TOKEN: ${{ secrets.RELEASE_PLEASE_TOKEN }} + + - name: Create or update release PR + run: pnpm release:please -- release-pr --repo-url "$GITHUB_REPOSITORY" --target-branch main + env: + RELEASE_PLEASE_TOKEN: ${{ secrets.RELEASE_PLEASE_TOKEN }} diff --git a/.husky/commit-msg b/.husky/commit-msg new file mode 100644 index 000000000..3ed46473d --- /dev/null +++ b/.husky/commit-msg @@ -0,0 +1,5 @@ +#!/bin/bash + +set -e + +pnpm exec commitlint --edit "$1" diff --git a/.husky/prepare-commit-msg b/.husky/prepare-commit-msg index a273281a1..86c857ac1 100644 --- a/.husky/prepare-commit-msg +++ b/.husky/prepare-commit-msg @@ -1,11 +1,10 @@ #!/bin/bash -# Don't run cz if a message has been supplied -[ "$2" = "message" ] && exit 0 +set -e -# Don't run cz if we're amending the previous commit -[ "$2" = "commit" ] && [ "$3" = "HEAD" ] && exit 0 +# Only prompt for plain interactive `git commit`. +[ -n "$2" ] && exit 0 +[ -r /dev/tty ] || exit 0 -if [[ $COMMIT_MSG =~ ^$ ]]; then - exec -[Readme](./README.md) · [Reference](https://contentful.github.io/optimization) · -[Contributing](./CONTRIBUTING.md) +[Readme](./README.md) · +[Guides](https://contentful.github.io/optimization/documents/Documentation.Guides.html) · +[Reference](https://contentful.github.io/optimization) · [Contributing](./CONTRIBUTING.md) -We appreciate any community contributions to this project, whether in the form of issues or pull -requests. +> [!WARNING] +> +> The Optimization SDK Suite is pre-release (alpha). Breaking changes can be published at any time. + +We appreciate community contributions in the form of issues and pull requests. -This document explains how to set up the repository, how packages and reference implementations fit -together, which validation to run for common kinds of changes, and which local hooks and CI -behaviors to expect. +Use this guide when you change SDK packages, reference implementations, documentation, release +configuration, or repository tooling. It covers setup, the normal development flow, validation, pull +request expectations, and common troubleshooting. -Many subtrees also contain local `AGENTS.md` files. They are written for agent tooling, but they -also serve as concise local runbooks for humans. When you begin working in a package, -implementation, or `lib/` workspace, read the nearest `AGENTS.md` for subtree-specific commands and -gotchas. +Many subtrees include a local `AGENTS.md`. These files are written for agent tooling, but they also +serve as concise local runbooks for humans. Read the nearest `AGENTS.md` before working in a +package, implementation, or `lib/` workspace. -**Working on your first Pull Request?** You can learn how from this extensive -[list of resources for people who are new to contributing to Open Source](https://github.com/freeCodeCamp/how-to-contribute-to-open-source). +**Working on your first pull request?** See this +[list of resources for people who are new to contributing to open source](https://github.com/freeCodeCamp/how-to-contribute-to-open-source).
Table of Contents +- [Before you start](#before-you-start) - [Setup](#setup) - [Repository map](#repository-map) -- [Common commands](#common-commands) -- [Common workflows](#common-workflows) - - [Change a workspace package](#change-a-workspace-package) - - [Change an implementation](#change-an-implementation) - - [Run E2E for one implementation](#run-e2e-for-one-implementation) - - [Implementation helper usage](#implementation-helper-usage) -- [Validation matrix](#validation-matrix) -- [Code style and local hooks](#code-style-and-local-hooks) +- [Development flow](#development-flow) + - [Package changes](#package-changes) + - [Implementation changes](#implementation-changes) + - [E2E changes](#e2e-changes) +- [Commands](#commands) + - [Implementation helper](#implementation-helper) +- [Validation](#validation) +- [Pull requests and releases](#pull-requests-and-releases) + - [Commit scopes](#commit-scopes) + - [Release impact](#release-impact) + - [Contributor checklist](#contributor-checklist) + - [Maintainer checklist](#maintainer-checklist) - [Documentation](#documentation) - - [README depth and render targets](#readme-depth-and-render-targets) - [Local troubleshooting](#local-troubleshooting) -- [Troubleshooting CI issues](#troubleshooting-ci-issues) - - [E2E coverage and environment](#e2e-coverage-and-environment) - - [License check failure](#license-check-failure) +- [CI troubleshooting](#ci-troubleshooting) + - [E2E jobs](#e2e-jobs) + - [License checks](#license-checks)
-## Setup +## Before you start -The following software is required or strongly recommended for day-to-day development: +- Use `pnpm` for repository commands. +- Use the Node.js version from [`.nvmrc`](./.nvmrc). The pnpm workspace engine setting mirrors + `.nvmrc`. +- Use the pnpm version pinned in the root [`package.json`](./package.json). +- Change source-of-truth files, not generated output. Authored docs live in `documentation/`; + generated TypeDoc output lives in `docs/`. +- Treat reference implementations as maintained product artifacts, not disposable examples. +- Do not hand-edit `dist/`, `coverage/`, `docs/`, `pkgs/`, `.rslib/`, `.rsdoctor/`, `node_modules/`, + or local `.env` files unless the task explicitly targets them. -- [Node.js](https://nodejs.org/) (use [`.nvmrc`](./.nvmrc) when possible; the minimum supported - version is specified in [`package.json`](./package.json)) -- [pnpm](https://pnpm.io/installation) (the pinned version is recorded in the root - [`package.json`](./package.json)) -- [`jq`](https://jqlang.org/) for the local `pre-push` hook -- [Docker Desktop](https://www.docker.com/products/docker-desktop/) or any Docker-compatible - container manager when working on `implementations/web-sdk` -- An Android emulator when running React Native Detox flows in `implementations/react-native-sdk` +## Setup -> [!NOTE] -> -> Browser-based E2E flows also require Playwright browser binaries. The targeted -> `pnpm setup:e2e:` wrappers install them for browser implementations. +Install the day-to-day prerequisites: -After cloning the repository: +- [Node.js](https://nodejs.org/) through `nvm` or another tool that respects `.nvmrc`. +- [pnpm](https://pnpm.io/installation), using the version pinned in `package.json`. +- [`jq`](https://jqlang.org/) for the local `pre-push` hook. +- Playwright browser binaries for browser-based E2E. The targeted `setup:e2e` wrappers install them + for browser implementations. +- Native toolchains only when working on those surfaces: Android Studio or an Android emulator for + Android and React Native flows, and Xcode, XcodeGen, and an iOS simulator for iOS flows. + +After cloning the repository, run: ```sh nvm use @@ -85,67 +98,40 @@ pnpm version:pnpm ## Repository map -| Path | Purpose | -| -------------------- | ------------------------------------------------------------------------------------------ | -| `lib/` | Internal shared tooling and mock services, such as `build-tools` and `mocks` | -| `packages/` | Workspace packages, including the published SDKs and framework layers | -| `implementations/` | Reference applications used for integration testing, validation evidence, and E2E coverage | -| `pkgs/` | Generated tarballs created by `pnpm build:pkgs`; implementations install from these | -| `docs/` | Generated TypeDoc output | -| `dist/`, `coverage/` | Generated build and test artifacts inside individual workspaces | - -The most important repository-specific mechanic is this: +| Path | Purpose | +| -------------------- | ----------------------------------------------------------------------------------- | +| `lib/` | Internal shared tooling and mock services, such as `build-tools` and `mocks` | +| `packages/` | Workspace packages, including published SDKs and framework layers | +| `packages/android/` | Pre-release Android library | +| `packages/ios/` | Pre-release Swift package | +| `implementations/` | Reference apps used for integration testing, validation evidence, and E2E coverage | +| `documentation/` | Authored guides and concepts published with TypeDoc | +| `docs/` | Generated TypeDoc output | +| `pkgs/` | Generated tarballs created by `pnpm build:pkgs`; implementations install from these | +| `dist/`, `coverage/` | Generated build and test artifacts inside individual workspaces | +| `.github/workflows/` | CI, release, publish, and title-check workflows | + +The main repository-specific mechanic is package refresh: - Package changes do not automatically flow into reference implementations. -- If an implementation consumes a package you changed, rebuild tarballs with `pnpm build:pkgs` and - reinstall that implementation before trusting local results. -- The targeted `pnpm setup:e2e:` wrappers do this refresh for you as part of E2E - setup. - -## Common commands - -The root [`package.json`](./package.json) contains more scripts than are listed below. These are the -ones most contributors need regularly. - -| Command | When to use it | -| ------------------------------------------------- | ------------------------------------------------------------------------------ | -| `pnpm lint` | Lint `lib/` and `packages/` workspaces | -| `pnpm implementation:lint` | Lint `implementations/` | -| `pnpm implementation:install` | Refresh all implementations after rebuilding package tarballs | -| `pnpm typecheck` | Type-check all workspaces | -| `pnpm implementation:typecheck` | Type-check all implementations | -| `pnpm test:unit` | Run unit tests across workspace packages | -| `pnpm build` | Build all `@contentful/*` packages | -| `pnpm build:pkgs` | Build packages and create implementation-consumable tarballs in `pkgs/` | -| `pnpm size:check` | Validate bundle-size budgets for all built packages | -| `pnpm size:report` | Report bundle sizes without failing on budgets | -| `pnpm docs:generate` | Generate TypeDoc output | -| `pnpm format:check` | Check repository formatting | -| `pnpm setup:e2e:` | Prepare one implementation for E2E, including package refresh and local setup | -| `pnpm test:e2e:` | Run one implementation's full E2E flow | -| `pnpm implementation:run -- ...` | Run a specific helper action or package-local script inside one implementation | -| `pnpm playwright:install` | Install Playwright browsers across implementations | -| `pnpm playwright:install-deps` | Install Playwright system dependencies on Linux | -| `pnpm serve:mocks` | Run the shared mock services used by local flows | - -Most workspaces also define targeted local scripts such as `dev`, `build`, `test:unit`, and -`size:check`. Prefer targeted validation in the affected package or implementation instead of -running the whole repository when the change is narrow. - -Before running `pnpm implementation:lint` across the repository, run `pnpm implementation:install` -so the reference implementations have current local package tarballs installed. - -## Common workflows - -### Change a workspace package - -1. Read the nearest package or `lib/` `AGENTS.md`. -2. Make your change in the package source, tests, docs, or local harness. -3. Run targeted validation in that workspace. -4. If the package is consumed by an implementation you want to verify, rebuild tarballs and - reinstall the implementation before running local integration or E2E checks. - -Example: +- To test an implementation after changing a package, run `pnpm build:pkgs`, then reinstall the + affected implementation. +- The targeted `pnpm setup:e2e:` wrappers perform that refresh for E2E flows that + consume local tarballs. + +## Development flow + +1. Read the root `AGENTS.md`, then the nearest child `AGENTS.md` for the files you plan to edit. +2. Make the narrow source-of-truth change in the package, implementation, docs, or tooling layer + that owns the behavior. +3. Run the smallest meaningful validation for the changed surface. +4. If a package change is consumed by an implementation, rebuild tarballs and reinstall that + implementation before trusting local integration or E2E results. +5. Include the validation commands and any release impact in the pull request description. + +### Package changes + +Run root lint plus targeted package checks when the change is narrow: ```sh pnpm lint @@ -153,76 +139,109 @@ pnpm --filter @contentful/optimization-web typecheck pnpm --filter @contentful/optimization-web test:unit pnpm --filter @contentful/optimization-web build pnpm --filter @contentful/optimization-web size:check +``` + +If an implementation consumes the changed package, refresh it before testing: +```sh pnpm build:pkgs pnpm implementation:run -- web-sdk implementation:install ``` -If your next step is E2E rather than a narrow manual reinstall, prefer the targeted wrapper: +When E2E is the next step, use the targeted wrapper: ```sh pnpm setup:e2e:web-sdk pnpm test:e2e:web-sdk ``` -### Change an implementation +Broaden validation for public exports, shared runtime behavior, generated artifacts, mocks, +packaging, or behavior used by multiple SDKs. -1. Read the nearest implementation `AGENTS.md`. -2. If your change depends on freshly built local packages, run `pnpm build:pkgs` and reinstall the - implementation first. -3. Run targeted implementation validation. -4. Run the implementation's E2E flow for user-visible or integration-heavy changes. +### Implementation changes -Example: +Run the implementation checks that match the changed app: ```sh +pnpm implementation:lint pnpm implementation:run -- web-sdk_react typecheck pnpm implementation:run -- web-sdk_react build pnpm implementation:run -- web-sdk_react implementation:test:e2e:run ``` -### Run E2E for one implementation +If the implementation depends on freshly built local packages, run `pnpm build:pkgs` and reinstall +the implementation first. -1. Create a local `.env` from the implementation's `.env.example` if the implementation expects one - and you do not already have it. -2. Run the targeted setup wrapper. -3. Run the targeted E2E wrapper. +### E2E changes -Example: +Use root wrappers when they exist: ```sh -cp implementations/web-sdk/.env.example implementations/web-sdk/.env -pnpm setup:e2e:web-sdk -pnpm test:e2e:web-sdk +pnpm setup:e2e: +pnpm test:e2e: ``` -Environment notes: - -- `web-sdk` requires Docker because the app is served via nginx. -- Browser implementations require Playwright browser binaries. -- `react-native-sdk` requires an Android emulator for Detox flows. -- Several implementations use PM2-managed processes for local serving; stop only the relevant - implementation process rather than doing broad PM2 cleanup. - -### Implementation helper usage +The root wrappers cover `node-sdk`, `node-sdk+web-sdk`, `web-sdk`, `web-sdk_react`, +`web-sdk_angular`, `react-web-sdk`, `nextjs-sdk_app-router`, `nextjs-sdk_pages-router`, +`react-native-sdk`, and `ios-sdk`. -`implementation:run` is the shared helper used by the implementation scripts listed above. - -Run a helper action for all implementations: +Native Android uses implementation-local runners from the root: ```sh -pnpm implementation:run -- --all -- [args...] +pnpm implementation:run -- android-sdk test:e2e:compose +pnpm implementation:run -- android-sdk test:e2e:views +pnpm implementation:run -- android-sdk test:e2e ``` -Run a helper action for one implementation: +The Android, iOS, and React Native runners start or verify the required local services, devices, or +simulators where practical. Report the runner's concrete preflight failure if setup does not +complete. + +## Commands + +The root [`package.json`](./package.json) contains the full script list. These commands cover most +contributor workflows: + +| Command | When to use it | +| ------------------------------------------------- | ----------------------------------------------------------------------- | +| `pnpm lint` | Lint `lib/` and `packages/` workspaces | +| `pnpm implementation:lint` | Lint `implementations/` | +| `pnpm typecheck` | Type-check `lib/` and `packages/` workspaces | +| `pnpm implementation:typecheck` | Type-check all implementations | +| `pnpm test:unit` | Run unit tests across `lib/` and `packages/` | +| `pnpm build` | Build all `@contentful/*` packages | +| `pnpm build:pkgs` | Build packages and create implementation-consumable tarballs in `pkgs/` | +| `pnpm implementation:install` | Rebuild tarballs and refresh every implementation | +| `pnpm size:check` | Validate bundle-size budgets for all built packages | +| `pnpm size:report` | Report bundle sizes without failing on budgets | +| `pnpm docs:generate` | Generate TypeDoc output | +| `pnpm format:check` | Check repository formatting | +| `pnpm setup:e2e:` | Prepare one implementation for E2E | +| `pnpm test:e2e:` | Run one implementation's full E2E flow | +| `pnpm implementation:run -- ...` | Run a helper action or local script inside one implementation | +| `pnpm ios:test` | Build the JS bridge and run Swift package tests | +| `pnpm playwright:install` | Install Playwright browsers across implementations | +| `pnpm playwright:install-deps` | Install Playwright system dependencies on Linux | +| `pnpm serve:mocks` | Run the shared mock services used by local flows | + +Prefer targeted workspace commands when the change is narrow. Use aggregate commands when shared +behavior, exports, packaging, mocks, or generated artifacts cross workspace boundaries. + +### Implementation helper + +`implementation:run` runs helper actions or implementation-local scripts from the repository root: ```sh +pnpm implementation:run -- --all -- [args...] pnpm implementation:run -- [args...] ``` -- `` is a folder name under `implementations/` (for example: `web-sdk`, - `web-sdk_react`, `react-web-sdk`, `node-sdk`, `node-sdk+web-sdk`, `react-native-sdk`) -- `` can be one of these helper actions: +`` is a folder under `implementations/`, such as `web-sdk`, `web-sdk_react`, +`react-web-sdk`, `node-sdk`, `node-sdk+web-sdk`, `nextjs-sdk_app-router`, `nextjs-sdk_pages-router`, +`react-native-sdk`, `android-sdk`, or `ios-sdk`. + +Common helper actions include: + - `implementation:install` - `implementation:build:run` - `implementation:test:unit:run` @@ -230,181 +249,210 @@ pnpm implementation:run -- [args...] - `implementation:playwright:install-deps` - `implementation:setup:e2e` - `implementation:test:e2e:run` -- `` can also be any implementation-local script name (for example: `serve`, `serve:stop`, - `test:e2e:ui`) -- `[args...]` are forwarded to the target script/action (when supported by that action/script) + +You can also pass an implementation-local script name, such as `serve`, `build`, `typecheck`, +`test:e2e:ui`, `test:e2e:compose`, or `test:e2e:ios:build:release`. Examples: ```sh -# Install dependencies for every implementation pnpm implementation:run -- --all -- implementation:install - -# Run the implementation-level E2E command for all implementations -pnpm implementation:run -- --all -- implementation:test:e2e:run - -# Run one implementation's local script pnpm implementation:run -- web-sdk test:e2e:ui - -# Pass arguments through to the underlying E2E script +pnpm implementation:run -- android-sdk test:e2e:compose -- --flow preview-panel pnpm implementation:run -- node-sdk implementation:test:e2e:run -- --grep "homepage" ``` -Prefer the root wrapper scripts when they already match what you want to do. For example: - -- `pnpm implementation:install` -- `pnpm setup:e2e:` -- `pnpm test:e2e:` +## Validation -## Validation matrix - -Use the smallest meaningful validation set for the change. +Use the smallest meaningful validation set for the change: | Change type | Usually run | Notes | | ----------------------------------------------------------- | ----------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- | -| Docs-only or markdown-only | `pnpm format:check` | Also run `pnpm docs:generate` if public API docs or linked markdown changed | -| Package or `lib/` TypeScript change | Targeted `lint`, `typecheck`, `test:unit`, and `build` | Prefer `pnpm --filter ...` when the change is narrow | -| Built package runtime, export, dependency, or bundle change | Targeted `size:check` or root `pnpm size:check` | Bundle-size checks are contributor-run validation, not a dedicated CI job | -| Package change used by an implementation | `pnpm build:pkgs`, then reinstall the affected implementation | Use `pnpm setup:e2e:` if E2E is your next step | -| Implementation code change | `pnpm implementation:lint`, targeted implementation `typecheck`, and implementation-local tests | Some implementations have no meaningful unit tests; E2E matters more there | +| Docs-only or Markdown-only | `pnpm format:check` | Also run `pnpm docs:generate` if public API docs or linked Markdown changed | +| Package or `lib/` TypeScript change | Root `pnpm lint`, targeted `typecheck`, `test:unit`, and `build` | Prefer `pnpm --filter ...` when the change is narrow | +| Built package runtime, export, dependency, or bundle change | Targeted `size:check` or root `pnpm size:check` | Bundle-size checks validate evidence; budget changes need maintainer review | +| Package change used by an implementation | `pnpm build:pkgs`, then reinstall the affected implementation | Use `pnpm setup:e2e:` when E2E is the next step | +| Implementation code change | `pnpm implementation:lint`, targeted implementation `typecheck`, and implementation-local tests | Some implementations rely more on E2E than unit tests | +| Native Android change | Build both apps and run targeted Maestro | Use `test:e2e:compose`, `test:e2e:views`, or both when parity matters | +| Native iOS change | Targeted XCUITest or `pnpm test:e2e:ios-sdk` | Use `IOS_ONLY_TESTING` for focused release-run suites | | Shared build or packaging change | Broaden validation to downstream packages and at least one affected implementation | Examples: `lib/build-tools`, package exports, tarball/install flow | | User-visible integration or runtime behavior change | Targeted implementation E2E | Choose the implementation that exercises the changed surface | -When in doubt, start targeted and broaden only if the change crosses package or implementation -boundaries. +When an upstream package build fails, stop downstream validation. Stale downstream artifacts are not +evidence. -## Code style and local hooks +## Pull requests and releases -This project uses [ESLint](https://eslint.org/) and [Prettier](https://prettier.io/) to enforce -coding and formatting conventions. You can enable related editor plugins to get the same feedback -while working on Optimization SDKs. +This repository squash-merges pull requests. The pull request title becomes the commit header on +`main`, so the title must be a scoped Conventional Commit header. Release Please reads commits on +`main`, opens one shared release PR, and creates package-specific tags and GitHub releases after +that release PR merges. -Please review the following files to familiarize yourself with current configurations: +Release tags use package components: -- [eslint.config.ts](./eslint.config.ts) -- [.prettierrc](./.prettierrc) -- [.markdownlint.yaml](./.markdownlint.yaml) -- [.lintstagedrc.yaml](./.lintstagedrc.yaml) +| Artifact family | Release tag example | Publish target | +| --------------- | ------------------------------------ | ------------------------------------------------------------ | +| NPM packages | `optimization-web-v1.3.1` | GitHub Packages | +| Android | `optimization-android-v1.1.0-beta.0` | Maven Central | +| Swift | `optimization-swift-v1.1.0-beta.0` | `contentful/optimization.swift` with SPM tag `v1.1.0-beta.0` | -Local Git hooks installed by Husky: +### Commit scopes -- `pre-commit` runs `lint-staged` on staged files. -- `prepare-commit-msg` opens a Commitizen prompt when you do not supply a commit message and you are - not amending `HEAD`. -- `pre-push` runs targeted type checks and unit tests for changed workspaces and implementations. +Commitlint requires one of these scopes: -Practical implications: +```text +android, api-client, api-schemas, bridge, build-tools, ci, core, deps, +docs, implementations, nextjs, node, publish, react-native, react-web, +repo, swift, test, web, web-preview-panel +``` -- If you change TypeScript in a workspace package, expect targeted typecheck and unit-test work to - happen again on push. -- If you change an implementation, expect targeted implementation typecheck and implementation - `test:unit` work to run on push. -- Fix hook failures rather than bypassing them unless you have an explicit reviewed reason to skip - them. +Use the package or runtime scope for user-facing behavior. Use shared scopes such as `repo`, `ci`, +`docs`, `test`, `deps`, `build-tools`, `implementations`, or `publish` for maintenance-only work. -## Documentation +### Release impact + +| Change intent | Pull request title pattern | Release effect | +| ---------------------------------------- | ----------------------------------------------- | ------------------------------------------------------- | +| Bug fix or runtime correction | `fix(core): handle empty profile state` | Patch release for affected package paths | +| Performance fix | `perf(web): reduce client bundle work` | Patch release for affected package paths | +| Feature | `feat(web): support managed CDA client` | Minor release for affected package paths | +| Breaking change | `feat(web)!: remove legacy optimized entry API` | Major release for affected package paths | +| Docs, tests, CI, or internal maintenance | `docs(nextjs): clarify app router setup` | No package release unless paired with a breaking marker | -Code is documented using TSDoc, and reference documentation is generated using TypeDoc and published -automatically with each new version. +For breaking changes, include a footer in the pull request description and squash commit body: -- authored supporting docs belong in `documentation/`, while `docs/` remains generated output -- `pnpm docs:generate` generates documentation from TSDoc code comments, package README files, and - markdown files under `documentation/` -- `pnpm docs:watch` watches for file updates and rebuilds documentation output; useful while writing - and updating documentation +```text +BREAKING CHANGE: OptimizedEntry no longer accepts the legacy field shape. +``` -When changing public SDK behavior in this pre-release alpha period, update the same pull request to -keep these artifacts aligned: +Dependency updates follow the same rule as other changes. Use `fix(scope): ...` when a dependency +change affects published runtime behavior. Use `chore(deps): ...` for maintenance-only dependency +work. + +Release Please assigns releases by changed package paths and workspace dependency updates. Android +and Swift are configured as beta prerelease packages. The native bridge impact plugin also +synthesizes Android and Swift patch releases from releasable shared runtime commits that touch +`packages/universal/api-schemas`, `packages/universal/api-client`, `packages/universal/core-sdk`, or +`packages/universal/optimization-js-bridge`. When a change affects multiple packages, use the scope +that best describes the user-facing change and list the affected packages in the pull request +description. + +### Contributor checklist + +1. Keep the pull request focused on one coherent release intent. +2. Use `pnpm commit`, plain `git commit`, or a manual Conventional Commit message. +3. Set the pull request title to the Conventional Commit header that must land on `main`. +4. Run the validation listed in this document plus any local validation from the nearest + `AGENTS.md`. +5. Include validation commands and release impact in the pull request description. +6. Update the title before merge if review changes the release impact. + +Ask a maintainer before changing release policy, release budgets, publish workflows, or exact first +semantic versions. For an exact first semantic version, the maintainer must use a temporary +per-package `release-as` override before the release PR is created. + +### Maintainer checklist + +1. Review the change, validation evidence, and nearest `AGENTS.md` requirements. +2. Check that the pull request title is the Conventional Commit header that must land on `main`. +3. For breaking changes, keep the `BREAKING CHANGE:` footer in the squash commit body. +4. Squash-merge after required checks pass. +5. Let the `Release Please` workflow run on `main`. +6. Review the shared release PR named `chore(repo): release packages`. +7. Confirm the release PR updates the expected package versions, changelogs, internal workspace + dependency ranges, Android `VERSION`, and Swift `VERSION` files. +8. Merge the release PR when the release contents are correct. +9. Monitor package-specific GitHub releases and publish workflows: + - NPM publish uses GitHub Packages only and skips package versions that already exist. + - Android publish runs only for `optimization-android-v*` tags. + - Swift publish runs only for `optimization-swift-v*` tags and pushes `v` to + `contentful/optimization.swift`. + +Run `pnpm release:self-check` before changing Release Please config, native release synthesis, or +NPM target resolution. + +## Documentation -- TSDoc/JSDoc comments near changed API surfaces -- package READMEs that document those surfaces -- package-local development harnesses or example flows when they are meant to demonstrate the - changed behavior -- any replacement design, architecture, or specification artifacts that the repository adds for the - changed area +Follow [`STYLE_GUIDE.md`](./STYLE_GUIDE.md) for human-authored prose. -`documentation/` contains source markdown that TypeDoc publishes. `docs/` is generated output. Do -not hand-edit generated TypeDoc output. +Code reference documentation is generated with TypeDoc: -### README depth and render targets +- Authored supporting docs belong in `documentation/`. +- Generated TypeDoc output belongs in `docs/`; do not hand-edit it. +- `pnpm docs:generate` generates documentation from TSDoc comments, package README files, and + Markdown files under `documentation/`. +- `pnpm docs:watch` watches for file updates and rebuilds generated docs while writing. -READMEs are orientation surfaces, not the only place for every detail. Match depth to the README -category: +When public SDK behavior changes, keep the related documentation aligned in the same pull request: -- Application-facing package READMEs keep purpose, install, minimal setup, common options, critical - caveats, and links to guides, reference implementations, and generated API reference. -- Lower-level package READMEs explain the package's role in the SDK stack, who uses it directly, - common setup options where useful, and where exhaustive API details live. -- Reference implementation READMEs stay procedural: what the implementation validates, - prerequisites, setup, run/test commands, environment notes, and related package links. -- Internal and placeholder READMEs stay short, explicit, and status-oriented. +- TSDoc or JSDoc comments near changed API surfaces. +- Package READMEs that document those surfaces. +- Package-local harnesses or reference implementation flows that demonstrate the behavior. +- Guides, concepts, architecture notes, or specifications that explain the changed area. -Move step-by-step implementation material into the existing guide for that runtime when one exists. -Create a new guide only when no existing guide covers the reader goal. Keep exhaustive method -catalogs, callback payload shapes, and exported type details in TypeDoc. +READMEs are orientation surfaces. Keep package READMEs focused on purpose, installation, minimal +setup, common options, critical caveats, and links to guides, reference implementations, and +generated API reference. Keep reference implementation READMEs procedural. Package README links must work in GitHub source browsing, generated TypeDoc project documents, and -npmjs README rendering. Use canonical generated-doc URLs for shared header navigation and verify +npm README rendering. Use canonical generated-doc URLs for shared header navigation and verify repo-relative links before relying on package README publish rewriting. ## Local troubleshooting -- An implementation is not reflecting your package change: run `pnpm build:pkgs`, then reinstall the - affected implementation with `pnpm implementation:run -- implementation:install`. -- Playwright reports a missing browser: run `pnpm playwright:install`, or use the targeted - `pnpm setup:e2e:` wrapper. -- Playwright system dependencies are missing on Linux: run `pnpm playwright:install-deps`. -- `implementations/web-sdk` fails to serve locally: confirm Docker is running. -- React Native Detox cannot attach to a device: confirm an Android emulator is already running. -- An implementation behaves differently from expected local settings: compare its local `.env` with - its checked-in `.env.example`. -- A local port such as `3000`, `8000`, or `8081` is already in use: stop only the relevant local - process or implementation `serve` flow rather than using broad PM2 cleanup. +| Symptom | What to do | +| -------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | +| An implementation does not reflect a package change | Run `pnpm build:pkgs`, then `pnpm implementation:run -- implementation:install`. | +| Playwright reports a missing browser | Run `pnpm playwright:install`, or use the targeted `pnpm setup:e2e:` wrapper. | +| Playwright system dependencies are missing on Linux | Run `pnpm playwright:install-deps`. | +| `implementations/web-sdk` fails to serve locally | Check `implementations/web-sdk/.env` against `.env.example` and confirm port `3000` is free. | +| React Native Detox cannot attach to a device | Run the documented Detox runner; it can launch the configured emulator. Report the runner's actual failure if setup does not complete. | +| Android Maestro has no visible device before startup | Run the documented Android runner; it resolves or launches the pinned emulator when possible. | +| iOS XCUITest cannot find a simulator | Run the local iOS runner or root wrapper and report the concrete Xcode, simulator, XcodeGen, or signing preflight error. | +| An implementation uses unexpected local settings | Compare its local `.env` with its checked-in `.env.example`. | +| A port such as `3000`, `8000`, or `8081` is already used | Stop only the relevant local process or implementation `serve` flow instead of using broad PM2 cleanup. | +| Commitlint rejects a commit or pull request title | Add a supported scope. Example: use `fix(core): handle empty profile state`, not `fix: handle empty profile state`. | +| The pull request has the wrong release impact | Update the title before merge. For breaking changes, add `!` after the scope and include a `BREAKING CHANGE:` footer in the pull request body. | -## Troubleshooting CI issues +## CI troubleshooting -### E2E coverage and environment +`Main Pipeline` runs implementation E2E jobs when path filters request them for pull requests and +pushes to `main`. -`Main Pipeline` runs implementation E2E jobs when path filters request them for both: - -- pull requests -- pushes to `main` - -This is an intentional CI policy: +This is intentional CI policy: - E2E execution is path-filtered to reduce CI runtime and cost. -- CI E2E runs against local mock services via checked-in `.env.example` values to keep runs - deterministic and stable. -- Production/live-server E2E is a manual verification step when needed; it is intentionally not part - of default CI. - -The path filters do not watch only implementation directories. Shared package and root changes can -also trigger implementation E2E. At a high level: - -| Workflow filter -> job(s) | Also watches shared surfaces | -| ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `e2e_node_sdk` -> `e2e-node-sdk` | `lib/**`, `packages/node/node-sdk/**`, universal packages, root package/workflow files | -| `e2e_node_sdk_web_sdk` -> `e2e-node-sdk-web-sdk` | `lib/**`, `packages/node/node-sdk/**`, `packages/web/web-sdk/**`, `packages/web/preview-panel/**`, shared root files | -| `e2e_web_sdk` -> `e2e-web-sdk` | `lib/**`, `packages/web/web-sdk/**`, `packages/web/preview-panel/**`, universal packages, shared root files | -| `e2e_web_sdk_react` -> `e2e-web-sdk_react` | `lib/**`, `packages/web/web-sdk/**`, `packages/web/preview-panel/**`, universal packages, shared root files | -| `e2e_react_web_sdk` -> `e2e-react-web-sdk` | `lib/**`, `packages/web/frameworks/react-web-sdk/**`, `packages/web/web-sdk/**`, `packages/web/preview-panel/**`, universal packages, shared root files | -| `e2e_nextjs_sdk_app_router` -> `e2e-nextjs-sdk-app-router` | `lib/**`, `packages/web/frameworks/nextjs-sdk/**`, Node SDK, React Web SDK, Web SDK, universal packages, shared root files | -| `e2e_nextjs_sdk_pages_router` -> `e2e-nextjs-sdk-pages-router` | `lib/**`, `packages/web/frameworks/nextjs-sdk/**`, Node SDK, React Web SDK, Web SDK, preview panel, universal packages, shared root files | -| `e2e_react_native_android` -> `e2e-react-native-android-build`, `e2e-react-native-android` | `lib/**`, `packages/react-native-sdk/**`, universal packages, shared root files | +- CI E2E uses local mock services and checked-in `.env.example` values. +- Production or live-server E2E is manual verification when needed. +- E2E setup does not depend on repository secrets, so fork pull requests follow the same checked-in + setup path. + +### E2E jobs + +The path filters also watch shared package and root files that can affect the implementation: + +| Workflow filter | Job family | Also watches shared surfaces | +| ----------------------------- | --------------------------------------- | ------------------------------------------------------------ | +| `e2e_node_sdk` | `e2e-node-sdk` | `lib/**`, `packages/node/**`, `packages/universal/**` | +| `e2e_node_sdk_web_sdk` | `e2e-node-sdk-web-sdk` | Node, Web, Universal, and shared root files | +| `e2e_web_sdk` | `e2e-web-sdk` | `lib/**`, `packages/web/**`, `packages/universal/**` | +| `e2e_web_sdk_react` | `e2e-web-sdk_react` | `lib/**`, `packages/web/**`, `packages/universal/**` | +| `e2e_web_sdk_angular` | `e2e-web-sdk_angular` | `lib/**`, Node, Web, Universal, and shared root files | +| `e2e_react_web_sdk` | `e2e-react-web-sdk` | `lib/**`, `packages/web/**`, `packages/universal/**` | +| `e2e_nextjs_sdk_app_router` | `e2e-nextjs-sdk-app-router` | Node, Web, Universal, and shared root files | +| `e2e_nextjs_sdk_pages_router` | `e2e-nextjs-sdk-pages-router` | Node, Web, Universal, and shared root files | +| `e2e_react_native_android` | React Native Android build and E2E jobs | `packages/react-native-sdk/**`, Universal, and shared files | +| `e2e_android` | Android SDK build and Maestro jobs | `lib/mocks/**`, `packages/android/**`, Universal, root files | +| `e2e_ios` | iOS SDK build and XCUITest jobs | `lib/mocks/**`, `packages/ios/**`, Universal, root files | See [`.github/workflows/main-pipeline.yaml`](./.github/workflows/main-pipeline.yaml) for the exact authoritative filter list. -Skipping an implementation E2E job because its filter did not match is expected behavior, not a CI -coverage defect. - -If a change needs to trigger an implementation E2E job but does not match the current filters, -update the path filters in `.github/workflows/main-pipeline.yaml` in the same pull request. - -E2E setup does not depend on repository secrets. Each implementation creates `.env` from its own -checked-in `.env.example` file in CI, which keeps fork PR behavior aligned with internal PRs. +Skipping an implementation E2E job because its filter did not match is expected behavior. If a +change needs to trigger an implementation E2E job but does not match the current filters, update the +path filters in `.github/workflows/main-pipeline.yaml` in the same pull request. -### License check failure +### License checks Run `license-checker` locally: @@ -413,6 +461,6 @@ pnpx license-checker --summary pnpx license-checker > licenses.txt ``` -If the license for a package merely has a spelling or formatting difference from an existing entry -in the `license-check` GitHub workflow allow list, update the list and submit the change via pull -request. Otherwise, create an issue to receive further guidance from the maintainers. +If the license for a package has a spelling or formatting difference from an existing entry in the +`license-check` GitHub workflow allow list, update the list and submit the change via pull request. +Otherwise, create an issue for further guidance from the maintainers. diff --git a/commitlint.config.cjs b/commitlint.config.cjs new file mode 100644 index 000000000..8c0267da7 --- /dev/null +++ b/commitlint.config.cjs @@ -0,0 +1,46 @@ +const scopes = [ + 'android', + 'api-client', + 'api-schemas', + 'bridge', + 'build-tools', + 'ci', + 'core', + 'deps', + 'docs', + 'implementations', + 'nextjs', + 'node', + 'publish', + 'react-native', + 'react-web', + 'repo', + 'swift', + 'test', + 'web', + 'web-preview-panel', +] +const scopeEnum = Object.fromEntries( + scopes.map((scope) => [ + scope, + { + description: scope, + title: scope, + }, + ]), +) + +module.exports = { + extends: ['@commitlint/config-conventional'], + prompt: { + questions: { + scope: { + enum: scopeEnum, + }, + }, + }, + rules: { + 'scope-empty': [2, 'never'], + 'scope-enum': [2, 'always', scopes], + }, +} diff --git a/lib/build-tools/src/index.ts b/lib/build-tools/src/index.ts index 006e8a682..a29f47b39 100644 --- a/lib/build-tools/src/index.ts +++ b/lib/build-tools/src/index.ts @@ -11,6 +11,6 @@ export type { ClientBoundaryExportFailure, } from './clientBoundaryExports' export { emitDualDts } from './emitDualDts' -export { getPackageName, hasPackageName } from './package' +export { getPackageName, getPackageVersion, hasPackageName, hasPackageVersion } from './package' export { preparePublishReadme, rewriteReadmeForPublish } from './publishReadme' export { concatPolyfills, ensureUmdDefaultExport, maybeEnableRsDoctor } from './rslib' diff --git a/lib/build-tools/src/package.test.ts b/lib/build-tools/src/package.test.ts index 5dd1a0af0..8aab9f5bb 100644 --- a/lib/build-tools/src/package.test.ts +++ b/lib/build-tools/src/package.test.ts @@ -1,7 +1,7 @@ import { mkdtempSync, rmSync, writeFileSync } from 'node:fs' import { tmpdir } from 'node:os' import { join } from 'node:path' -import { getPackageName, hasPackageName } from './package' +import { getPackageName, getPackageVersion, hasPackageName, hasPackageVersion } from './package' describe('hasPackageName', () => { it('returns true when name is a string', () => { @@ -17,6 +17,20 @@ describe('hasPackageName', () => { }) }) +describe('hasPackageVersion', () => { + it('returns true when version is a string', () => { + expect(hasPackageVersion({ version: '1.2.3' })).toBe(true) + }) + + it('returns false when input is not an object with a string version', () => { + expect(hasPackageVersion(undefined)).toBe(false) + expect(hasPackageVersion(null)).toBe(false) + expect(hasPackageVersion('1.2.3')).toBe(false) + expect(hasPackageVersion({})).toBe(false) + expect(hasPackageVersion({ version: 123 })).toBe(false) + }) +}) + describe('getPackageName', () => { it('returns package name from package.json when present', () => { const packageDir = mkdtempSync(join(tmpdir(), 'build-tools-test-')) @@ -45,3 +59,29 @@ describe('getPackageName', () => { } }) }) + +describe('getPackageVersion', () => { + it('returns package version from package.json when present', () => { + const packageDir = mkdtempSync(join(tmpdir(), 'build-tools-test-')) + + try { + writeFileSync(join(packageDir, 'package.json'), JSON.stringify({ version: '1.2.3' })) + + expect(getPackageVersion(packageDir, '0.0.0')).toBe('1.2.3') + } finally { + rmSync(packageDir, { force: true, recursive: true }) + } + }) + + it('returns fallback when package.json has no valid string version', () => { + const packageDir = mkdtempSync(join(tmpdir(), 'build-tools-test-')) + + try { + writeFileSync(join(packageDir, 'package.json'), JSON.stringify({ version: 123 })) + + expect(getPackageVersion(packageDir, '0.0.0')).toBe('0.0.0') + } finally { + rmSync(packageDir, { force: true, recursive: true }) + } + }) +}) diff --git a/lib/build-tools/src/package.ts b/lib/build-tools/src/package.ts index e1db6bf46..ddee92cfa 100644 --- a/lib/build-tools/src/package.ts +++ b/lib/build-tools/src/package.ts @@ -28,6 +28,24 @@ export function hasPackageName( ) } +/** + * Type guard that checks whether a value is a `PackageJson` object with a `version` field. + * + * @param packageJson - The value to check. + * @returns `true` if the value is a `PackageJson` with a string `version` property. + * + * @public + */ +export function hasPackageVersion( + packageJson: unknown, +): packageJson is PackageJson & { version: string } { + return ( + typeof packageJson === 'object' && + packageJson !== null && + typeof Reflect.get(packageJson, 'version') === 'string' + ) +} + /** * Reads `package.json` from the given directory and returns its `name` field, * falling back to `fallbackName` when the name is absent. @@ -44,9 +62,7 @@ export function hasPackageName( * @public */ export function getPackageName(packageDir: string, fallbackName: string): string { - const packageJsonContent: unknown = JSON.parse( - readFileSync(resolve(packageDir, 'package.json'), 'utf-8'), - ) + const packageJsonContent = readPackageJson(packageDir) if (hasPackageName(packageJsonContent)) { return packageJsonContent.name @@ -54,3 +70,27 @@ export function getPackageName(packageDir: string, fallbackName: string): string return fallbackName } + +/** + * Reads `package.json` from the given directory and returns its `version` field, + * falling back to `fallbackVersion` when the version is absent. + * + * @param packageDir - Directory containing `package.json`. + * @param fallbackVersion - Value returned when the package has no `version` field. + * @returns The resolved package version. + * + * @public + */ +export function getPackageVersion(packageDir: string, fallbackVersion: string): string { + const packageJsonContent = readPackageJson(packageDir) + + if (hasPackageVersion(packageJsonContent)) { + return packageJsonContent.version + } + + return fallbackVersion +} + +function readPackageJson(packageDir: string): unknown { + return JSON.parse(readFileSync(resolve(packageDir, 'package.json'), 'utf-8')) +} diff --git a/package.json b/package.json index 7a9b98792..6effc6d4b 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "build:pkgs": "pnpm build && pnpm run pack:pkgs", "build:rsdoctor": "pnpm --filter './packages/**' --stream build:rsdoctor", "clean": "pnpm --filter './lib/*' --filter './packages/**' --parallel clean", + "commit": "tsx ./scripts/prepare-commit-message.ts --commit", "docs:generate": "typedoc", "docs:watch": "typedoc --watch", "format:check": "prettier . --check", @@ -45,6 +46,8 @@ "pm2:logs": "pm2 logs", "pm2:stop:all": "pm2 stop all", "prepare": "husky", + "release:please": "tsx ./scripts/release-please.ts", + "release:self-check": "pnpm exec tsx ./scripts/list-npm-package-targets.ts self-check && pnpm exec tsx ./scripts/release-please.ts self-check", "serve:mocks": "pnpm --dir lib/mocks serve", "setup:e2e": "pnpm run build:pkgs && pnpm run implementation:run -- --all -- implementation:install && pnpm run playwright:install && pnpm run playwright:install-deps", "setup:e2e:ios-sdk": "pnpm run implementation:ios-sdk -- xcodegen", @@ -81,21 +84,26 @@ }, "packageManager": "pnpm@11.10.0+sha512.0b7f8b98060031904c017e3a41eb187a16d40eeb829b95c4f8cb03681761fc4ab53dd219115b9b447f4dce1a05a214764461e7d3703392a9f32f9511ce8c86c8", "devDependencies": { - "@rstest/core": "catalog:", + "@commitlint/cli": "^21.2.1", + "@commitlint/config-conventional": "^21.2.0", + "@commitlint/prompt": "^21.2.0", + "@commitlint/prompt-cli": "^21.2.0", "@eslint/js": "^10.0.1", - "commitizen": "^4.3.1", - "cz-vinyl": "^2.5.4", + "@rstest/core": "catalog:", + "@types/inquirer": "^9.0.10", "eslint": "^10.0.0", "eslint-config-love": "^121.0.0", "eslint-config-prettier": "^10.1.8", "eslint-plugin-lit": "^2.2.1", "eslint-plugin-wc": "^3.1.0", "husky": "^9.1.7", + "inquirer": "^9.3.8", "jiti": "^2.6.1", "lint-staged": "^16.2.7", "pm2": "catalog:", "prettier": "^3.8.1", "prettier-plugin-organize-imports": "^4.3.0", + "release-please": "^17.10.2", "tsx": "catalog:", "typedoc": "^0.28.19", "typescript": "^5.9.3", diff --git a/packages/android/ContentfulOptimization/AGENTS.md b/packages/android/ContentfulOptimization/AGENTS.md index 84fdc6f9a..fb39bfeb6 100644 --- a/packages/android/ContentfulOptimization/AGENTS.md +++ b/packages/android/ContentfulOptimization/AGENTS.md @@ -35,8 +35,9 @@ assets. ## Releasing -- Maven Central publishing uses `.github/workflows/publish-android.yaml` on `v*` tags with group - `com.contentful.java` and artifact `optimization-android`. +- Maven Central publishing uses `.github/workflows/publish-android.yaml` on + `optimization-android-v*` tags with group `com.contentful.java` and artifact + `optimization-android`. - Published artifacts are generated; do not edit them by hand. - Android third-party notices are release assets. Debug/unit/local development must not depend on them. Release and publish flows that pass diff --git a/packages/android/ContentfulOptimization/CHANGELOG.md b/packages/android/ContentfulOptimization/CHANGELOG.md new file mode 100644 index 000000000..646dba88f --- /dev/null +++ b/packages/android/ContentfulOptimization/CHANGELOG.md @@ -0,0 +1,3 @@ +# Changelog + +Release notes are managed by Release Please. diff --git a/packages/android/ContentfulOptimization/VERSION b/packages/android/ContentfulOptimization/VERSION new file mode 100644 index 000000000..8efff9751 --- /dev/null +++ b/packages/android/ContentfulOptimization/VERSION @@ -0,0 +1 @@ +0.1.0-alpha17 diff --git a/packages/android/ContentfulOptimization/build.gradle.kts b/packages/android/ContentfulOptimization/build.gradle.kts index 731d12ed8..395653de7 100644 --- a/packages/android/ContentfulOptimization/build.gradle.kts +++ b/packages/android/ContentfulOptimization/build.gradle.kts @@ -24,7 +24,7 @@ plugins { // already-verified Maven Central namespace (com.contentful.java) rather than registering a new one. // The Android package namespace stays com.contentful.optimization (group != package, no conflict). // Version flows from the release tag in CI (-Pcontentful.optimization.version / RELEASE_VERSION), -// matching the npm and SPM release versions cut from the same tag. +// using the optimization-android-v* package release tag created by Release Please. group = "com.contentful.java" version = (project.findProperty("contentful.optimization.version") as String?) ?: System.getenv("RELEASE_VERSION") diff --git a/packages/ios/ContentfulOptimization/CHANGELOG.md b/packages/ios/ContentfulOptimization/CHANGELOG.md new file mode 100644 index 000000000..646dba88f --- /dev/null +++ b/packages/ios/ContentfulOptimization/CHANGELOG.md @@ -0,0 +1,3 @@ +# Changelog + +Release notes are managed by Release Please. diff --git a/packages/ios/ContentfulOptimization/VERSION b/packages/ios/ContentfulOptimization/VERSION new file mode 100644 index 000000000..8efff9751 --- /dev/null +++ b/packages/ios/ContentfulOptimization/VERSION @@ -0,0 +1 @@ +0.1.0-alpha17 diff --git a/packages/node/node-sdk/CHANGELOG.md b/packages/node/node-sdk/CHANGELOG.md new file mode 100644 index 000000000..646dba88f --- /dev/null +++ b/packages/node/node-sdk/CHANGELOG.md @@ -0,0 +1,3 @@ +# Changelog + +Release notes are managed by Release Please. diff --git a/packages/node/node-sdk/rslib.config.ts b/packages/node/node-sdk/rslib.config.ts index 2a535fca2..693a8ed7a 100644 --- a/packages/node/node-sdk/rslib.config.ts +++ b/packages/node/node-sdk/rslib.config.ts @@ -1,7 +1,8 @@ import { defineConfig } from '@rslib/core' -import { getPackageName, maybeEnableRsDoctor } from 'build-tools' +import { getPackageName, getPackageVersion, maybeEnableRsDoctor } from 'build-tools' const packageName = getPackageName(__dirname, '@contentful/optimization-node') +const packageVersion = getPackageVersion(__dirname, '0.0.0') const common = { bundle: true, @@ -27,7 +28,7 @@ export default defineConfig({ tsconfigPath: './tsconfig.build.json', decorators: { version: '2022-03' }, // stage-3 decorators define: { - __OPTIMIZATION_VERSION__: JSON.stringify(process.env.RELEASE_VERSION ?? '0.0.0'), + __OPTIMIZATION_VERSION__: JSON.stringify(process.env.RELEASE_VERSION ?? packageVersion), __OPTIMIZATION_PACKAGE_NAME__: JSON.stringify(packageName), }, }, diff --git a/packages/react-native-sdk/CHANGELOG.md b/packages/react-native-sdk/CHANGELOG.md new file mode 100644 index 000000000..646dba88f --- /dev/null +++ b/packages/react-native-sdk/CHANGELOG.md @@ -0,0 +1,3 @@ +# Changelog + +Release notes are managed by Release Please. diff --git a/packages/react-native-sdk/rslib.config.ts b/packages/react-native-sdk/rslib.config.ts index 24ad74372..4a393ca6c 100644 --- a/packages/react-native-sdk/rslib.config.ts +++ b/packages/react-native-sdk/rslib.config.ts @@ -1,8 +1,9 @@ import { defineConfig } from '@rslib/core' -import { getPackageName, maybeEnableRsDoctor } from 'build-tools' +import { getPackageName, getPackageVersion, maybeEnableRsDoctor } from 'build-tools' import path from 'node:path' const packageName = getPackageName(__dirname, '@contentful/optimization-react-native') +const packageVersion = getPackageVersion(__dirname, '0.0.0') const workspaceRoot = path.resolve(__dirname, '../../..') const browserUtilEntry = path.resolve(workspaceRoot, 'node_modules/.pnpm/node_modules/util/util.js') @@ -32,7 +33,7 @@ export default defineConfig({ tsconfigPath: './tsconfig.build.json', decorators: { version: '2022-03' }, // stage-3 decorators define: { - __OPTIMIZATION_VERSION__: JSON.stringify(process.env.RELEASE_VERSION ?? '0.0.0'), + __OPTIMIZATION_VERSION__: JSON.stringify(process.env.RELEASE_VERSION ?? packageVersion), __OPTIMIZATION_PACKAGE_NAME__: JSON.stringify(packageName), }, }, diff --git a/packages/universal/api-client/CHANGELOG.md b/packages/universal/api-client/CHANGELOG.md new file mode 100644 index 000000000..646dba88f --- /dev/null +++ b/packages/universal/api-client/CHANGELOG.md @@ -0,0 +1,3 @@ +# Changelog + +Release notes are managed by Release Please. diff --git a/packages/universal/api-schemas/CHANGELOG.md b/packages/universal/api-schemas/CHANGELOG.md new file mode 100644 index 000000000..646dba88f --- /dev/null +++ b/packages/universal/api-schemas/CHANGELOG.md @@ -0,0 +1,3 @@ +# Changelog + +Release notes are managed by Release Please. diff --git a/packages/universal/core-sdk/CHANGELOG.md b/packages/universal/core-sdk/CHANGELOG.md new file mode 100644 index 000000000..646dba88f --- /dev/null +++ b/packages/universal/core-sdk/CHANGELOG.md @@ -0,0 +1,3 @@ +# Changelog + +Release notes are managed by Release Please. diff --git a/packages/universal/core-sdk/rslib.config.ts b/packages/universal/core-sdk/rslib.config.ts index 7d90cb1ab..4d8f44e4e 100644 --- a/packages/universal/core-sdk/rslib.config.ts +++ b/packages/universal/core-sdk/rslib.config.ts @@ -1,7 +1,8 @@ import { defineConfig } from '@rslib/core' -import { getPackageName, maybeEnableRsDoctor } from 'build-tools' +import { getPackageName, getPackageVersion, maybeEnableRsDoctor } from 'build-tools' const packageName = getPackageName(__dirname, '@contentful/optimization-core') +const packageVersion = getPackageVersion(__dirname, '0.0.0') const common = { bundle: true, @@ -30,7 +31,7 @@ export default defineConfig({ tsconfigPath: './tsconfig.build.json', decorators: { version: '2022-03' }, // stage-3 decorators define: { - __OPTIMIZATION_VERSION__: JSON.stringify(process.env.RELEASE_VERSION ?? '0.0.0'), + __OPTIMIZATION_VERSION__: JSON.stringify(process.env.RELEASE_VERSION ?? packageVersion), __OPTIMIZATION_PACKAGE_NAME__: JSON.stringify(packageName), }, }, diff --git a/packages/web/frameworks/nextjs-sdk/CHANGELOG.md b/packages/web/frameworks/nextjs-sdk/CHANGELOG.md new file mode 100644 index 000000000..646dba88f --- /dev/null +++ b/packages/web/frameworks/nextjs-sdk/CHANGELOG.md @@ -0,0 +1,3 @@ +# Changelog + +Release notes are managed by Release Please. diff --git a/packages/web/frameworks/nextjs-sdk/rslib.config.ts b/packages/web/frameworks/nextjs-sdk/rslib.config.ts index beea4c1f7..51a024fcd 100644 --- a/packages/web/frameworks/nextjs-sdk/rslib.config.ts +++ b/packages/web/frameworks/nextjs-sdk/rslib.config.ts @@ -1,6 +1,6 @@ import { pluginReact } from '@rsbuild/plugin-react' import { defineConfig } from '@rslib/core' -import { getPackageName, maybeEnableRsDoctor } from 'build-tools' +import { getPackageName, getPackageVersion, maybeEnableRsDoctor } from 'build-tools' import path from 'node:path' import { fileURLToPath } from 'node:url' @@ -8,6 +8,7 @@ import { fileURLToPath } from 'node:url' const __filename = fileURLToPath(import.meta.url) const __dirname = path.dirname(__filename) const packageName = getPackageName(__dirname, '@contentful/optimization-nextjs') +const packageVersion = getPackageVersion(__dirname, '0.0.0') /* eslint-enable @typescript-eslint/naming-convention -- standardized var names */ const common = { @@ -64,7 +65,7 @@ export default defineConfig({ source: { tsconfigPath: './tsconfig.build.json', define: { - __OPTIMIZATION_VERSION__: JSON.stringify(process.env.RELEASE_VERSION ?? '0.0.0'), + __OPTIMIZATION_VERSION__: JSON.stringify(process.env.RELEASE_VERSION ?? packageVersion), __OPTIMIZATION_PACKAGE_NAME__: JSON.stringify(packageName), }, }, diff --git a/packages/web/frameworks/react-web-sdk/CHANGELOG.md b/packages/web/frameworks/react-web-sdk/CHANGELOG.md new file mode 100644 index 000000000..646dba88f --- /dev/null +++ b/packages/web/frameworks/react-web-sdk/CHANGELOG.md @@ -0,0 +1,3 @@ +# Changelog + +Release notes are managed by Release Please. diff --git a/packages/web/frameworks/react-web-sdk/rslib.config.ts b/packages/web/frameworks/react-web-sdk/rslib.config.ts index 5a49b5a24..09501b13e 100644 --- a/packages/web/frameworks/react-web-sdk/rslib.config.ts +++ b/packages/web/frameworks/react-web-sdk/rslib.config.ts @@ -1,6 +1,6 @@ import { pluginReact } from '@rsbuild/plugin-react' import { defineConfig } from '@rslib/core' -import { getPackageName, maybeEnableRsDoctor } from 'build-tools' +import { getPackageName, getPackageVersion, maybeEnableRsDoctor } from 'build-tools' import path from 'node:path' import { fileURLToPath } from 'node:url' @@ -8,6 +8,7 @@ import { fileURLToPath } from 'node:url' const __filename = fileURLToPath(import.meta.url) const __dirname = path.dirname(__filename) const packageName = getPackageName(__dirname, '@contentful/optimization-react-web') +const packageVersion = getPackageVersion(__dirname, '0.0.0') /* eslint-enable @typescript-eslint/naming-convention -- standardized var names */ const common = { @@ -64,7 +65,7 @@ export default defineConfig({ source: { tsconfigPath: './tsconfig.build.json', define: { - __OPTIMIZATION_VERSION__: JSON.stringify(process.env.RELEASE_VERSION ?? '0.0.0'), + __OPTIMIZATION_VERSION__: JSON.stringify(process.env.RELEASE_VERSION ?? packageVersion), __OPTIMIZATION_PACKAGE_NAME__: JSON.stringify(packageName), }, }, diff --git a/packages/web/preview-panel/CHANGELOG.md b/packages/web/preview-panel/CHANGELOG.md new file mode 100644 index 000000000..646dba88f --- /dev/null +++ b/packages/web/preview-panel/CHANGELOG.md @@ -0,0 +1,3 @@ +# Changelog + +Release notes are managed by Release Please. diff --git a/packages/web/preview-panel/rslib.config.ts b/packages/web/preview-panel/rslib.config.ts index 1561717e8..877326fa3 100644 --- a/packages/web/preview-panel/rslib.config.ts +++ b/packages/web/preview-panel/rslib.config.ts @@ -1,5 +1,10 @@ import { defineConfig } from '@rslib/core' -import { ensureUmdDefaultExport, getPackageName, maybeEnableRsDoctor } from 'build-tools' +import { + ensureUmdDefaultExport, + getPackageName, + getPackageVersion, + maybeEnableRsDoctor, +} from 'build-tools' import path from 'node:path' import { fileURLToPath } from 'node:url' @@ -7,6 +12,7 @@ import { fileURLToPath } from 'node:url' const __filename = fileURLToPath(import.meta.url) const __dirname = path.dirname(__filename) const packageName = getPackageName(__dirname, '@contentful/optimization-web-preview-panel') +const packageVersion = getPackageVersion(__dirname, '0.0.0') /* eslint-enable @typescript-eslint/naming-convention -- standardized var names */ const common = { @@ -24,7 +30,7 @@ export default defineConfig({ source: { tsconfigPath: './tsconfig.build.json', define: { - __OPTIMIZATION_VERSION__: JSON.stringify(process.env.RELEASE_VERSION ?? '0.0.0'), + __OPTIMIZATION_VERSION__: JSON.stringify(process.env.RELEASE_VERSION ?? packageVersion), __OPTIMIZATION_PACKAGE_NAME__: JSON.stringify(packageName), }, }, diff --git a/packages/web/web-sdk/CHANGELOG.md b/packages/web/web-sdk/CHANGELOG.md new file mode 100644 index 000000000..646dba88f --- /dev/null +++ b/packages/web/web-sdk/CHANGELOG.md @@ -0,0 +1,3 @@ +# Changelog + +Release notes are managed by Release Please. diff --git a/packages/web/web-sdk/rslib.config.ts b/packages/web/web-sdk/rslib.config.ts index ae83364b5..0633f572a 100644 --- a/packages/web/web-sdk/rslib.config.ts +++ b/packages/web/web-sdk/rslib.config.ts @@ -1,5 +1,10 @@ import { defineConfig } from '@rslib/core' -import { ensureUmdDefaultExport, getPackageName, maybeEnableRsDoctor } from 'build-tools' +import { + ensureUmdDefaultExport, + getPackageName, + getPackageVersion, + maybeEnableRsDoctor, +} from 'build-tools' import path from 'node:path' import { fileURLToPath } from 'node:url' @@ -7,6 +12,7 @@ import { fileURLToPath } from 'node:url' const __filename = fileURLToPath(import.meta.url) const __dirname = path.dirname(__filename) const packageName = getPackageName(__dirname, '@contentful/optimization-web') +const packageVersion = getPackageVersion(__dirname, '0.0.0') /* eslint-enable @typescript-eslint/naming-convention -- standardized var names */ const common = { @@ -24,7 +30,7 @@ export default defineConfig({ source: { tsconfigPath: './tsconfig.build.json', define: { - __OPTIMIZATION_VERSION__: JSON.stringify(process.env.RELEASE_VERSION ?? '0.0.0'), + __OPTIMIZATION_VERSION__: JSON.stringify(process.env.RELEASE_VERSION ?? packageVersion), __OPTIMIZATION_PACKAGE_NAME__: JSON.stringify(packageName), }, }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 803402252..29d04850c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -94,18 +94,27 @@ importers: .: devDependencies: + '@commitlint/cli': + specifier: ^21.2.1 + version: 21.2.1(@types/node@24.13.2)(conventional-commits-parser@7.0.1)(typescript@5.9.3) + '@commitlint/config-conventional': + specifier: ^21.2.0 + version: 21.2.0 + '@commitlint/prompt': + specifier: ^21.2.0 + version: 21.2.0(@types/node@24.13.2)(typescript@5.9.3) + '@commitlint/prompt-cli': + specifier: ^21.2.0 + version: 21.2.0(@types/node@24.13.2)(typescript@5.9.3) '@eslint/js': specifier: ^10.0.1 version: 10.0.1(eslint@10.0.0(jiti@2.6.1)) '@rstest/core': specifier: 'catalog:' version: 0.8.5(happy-dom@20.8.9) - commitizen: - specifier: ^4.3.1 - version: 4.3.1(@types/node@24.13.2)(typescript@5.9.3) - cz-vinyl: - specifier: ^2.5.4 - version: 2.5.4(@types/node@24.10.13)(inquirer@8.2.7(@types/node@24.13.2))(typescript@5.9.3) + '@types/inquirer': + specifier: ^9.0.10 + version: 9.0.10 eslint: specifier: ^10.0.0 version: 10.0.0(jiti@2.6.1) @@ -124,6 +133,9 @@ importers: husky: specifier: ^9.1.7 version: 9.1.7 + inquirer: + specifier: ^9.3.8 + version: 9.3.8(@types/node@24.13.2) jiti: specifier: ^2.6.1 version: 2.6.1 @@ -139,6 +151,9 @@ importers: prettier-plugin-organize-imports: specifier: ^4.3.0 version: 4.3.0(prettier@3.8.1)(typescript@5.9.3) + release-please: + specifier: ^17.10.2 + version: 17.10.2 tsx: specifier: 'catalog:' version: 4.21.0 @@ -1334,25 +1349,83 @@ packages: resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} engines: {node: '>=0.1.90'} - '@commitlint/config-validator@20.4.0': - resolution: {integrity: sha512-zShmKTF+sqyNOfAE0vKcqnpvVpG0YX8F9G/ZIQHI2CoKyK+PSdladXMSns400aZ5/QZs+0fN75B//3Q5CHw++w==} - engines: {node: '>=v18'} + '@commitlint/cli@21.2.1': + resolution: {integrity: sha512-blsZGe29hJ72VGEFVl72IVYX+1vsfINpjA9yWQA6i7OKD/McGEOXg08sKIRKjFk4JvzhV/9n0l3i6NooPLTNfg==} + engines: {node: '>=22.12.0'} + hasBin: true - '@commitlint/execute-rule@20.0.0': - resolution: {integrity: sha512-xyCoOShoPuPL44gVa+5EdZsBVao/pNzpQhkzq3RdtlFdKZtjWcLlUFQHSWBuhk5utKYykeJPSz2i8ABHQA+ZZw==} - engines: {node: '>=v18'} + '@commitlint/config-conventional@21.2.0': + resolution: {integrity: sha512-Qf8WRDVcyVd14if6VTWenebxFbKnVnbzPUJjlzjkyJGeHK2xCGd63Dr1XZzj0plXKQb9P0BfOxoc1HVeCo2BWQ==} + engines: {node: '>=22.12.0'} - '@commitlint/load@20.4.0': - resolution: {integrity: sha512-Dauup/GfjwffBXRJUdlX/YRKfSVXsXZLnINXKz0VZkXdKDcaEILAi9oflHGbfydonJnJAbXEbF3nXPm9rm3G6A==} - engines: {node: '>=v18'} + '@commitlint/config-validator@21.2.0': + resolution: {integrity: sha512-t7AzNHAKeIdo/3NRGwzpufKHsKkPHmFs/56N2Fnsh0/r0rGtnQzTxk6vnFgjaGr4hdSQKNB50/KAhR9Yk4LJKA==} + engines: {node: '>=22.12.0'} - '@commitlint/resolve-extends@20.4.0': - resolution: {integrity: sha512-ay1KM8q0t+/OnlpqXJ+7gEFQNlUtSU5Gxr8GEwnVf2TPN3+ywc5DzL3JCxmpucqxfHBTFwfRMXxPRRnR5Ki20g==} - engines: {node: '>=v18'} + '@commitlint/ensure@21.2.0': + resolution: {integrity: sha512-76IF9vDNS13lAzEEik9eKwzt8f9hYhWiwVXZ2AnyLCz5/f511FsEQ3pw1X3/zSQpdRLQU7i5qDMVKyXi1GWjSg==} + engines: {node: '>=22.12.0'} - '@commitlint/types@20.4.0': - resolution: {integrity: sha512-aO5l99BQJ0X34ft8b0h7QFkQlqxC6e7ZPVmBKz13xM9O8obDaM1Cld4sQlJDXXU/VFuUzQ30mVtHjVz74TuStw==} - engines: {node: '>=v18'} + '@commitlint/execute-rule@21.0.1': + resolution: {integrity: sha512-RifH+FmImozKBE6mozhF4K3r2RRKP7SMi/Q/zLCmExtp5e05lhHOUYqGBlFBAGNHaZxU/WYw1XuugYK9jQzqnA==} + engines: {node: '>=22.12.0'} + + '@commitlint/format@21.2.0': + resolution: {integrity: sha512-c4q64xaav2U83t7k7RyzJerBZurPer7FxUOY0RL5L/6CZijZ7K+s6HIBGIghj0ey1P2+seRX0J9XQYtDued6tg==} + engines: {node: '>=22.12.0'} + + '@commitlint/is-ignored@21.2.0': + resolution: {integrity: sha512-4/eB0vBN7L88O/oC4ajAEqi7j2ZfNgxl/+11RfAV9YosejZgDXhY2C9VcHnHJhOzPLoSy5P3Mg/46kqeyJfXKw==} + engines: {node: '>=22.12.0'} + + '@commitlint/lint@21.2.0': + resolution: {integrity: sha512-ceO5dp9pLjEZ6y6qbq/uXWXDPykqqlTsyzoQ0NzecpisSJhK3kTy9qzQoPeJuWG/IMNdV1lO0RgmzqoAlSi1uw==} + engines: {node: '>=22.12.0'} + + '@commitlint/load@21.2.0': + resolution: {integrity: sha512-RjlzWQqruRwIenJEfZtq7kG97co97nKoHpflE5YnF61tDLXxHPrdWImgzw6VL6MlFyaOcVlk74eBV8ZQmc3oIA==} + engines: {node: '>=22.12.0'} + + '@commitlint/message@21.2.0': + resolution: {integrity: sha512-YxGoiXD/HXNXLJPrQwE5poXa+XH0CBEm+mdvbHQP0g6MV/dmJyUFCzPNzZbxL93GvZ70TmtTK0Z0/IBpAqHv8g==} + engines: {node: '>=22.12.0'} + + '@commitlint/parse@21.2.0': + resolution: {integrity: sha512-QHWxG4d0PLTF634/AdyZ0MQS+CLn5YOuJlCFhMMlSGKFxzYGUetkHBj18xgBD+6fVzUrA2lrCdi/vlS2f/oYXg==} + engines: {node: '>=22.12.0'} + + '@commitlint/prompt-cli@21.2.0': + resolution: {integrity: sha512-rEgmjj/vDsz07siiRu3mJqsx85Rkit0qHE+jfz25ZFILISteZsKZdLXoN7AbUwqBMEGVd9ugd71ru50sx3fw1g==} + engines: {node: '>=22.12.0'} + hasBin: true + + '@commitlint/prompt@21.2.0': + resolution: {integrity: sha512-pF0ZNrWK5qjAUG/K8xtvOfwAoWjN1+aOgoi1y1eZCzoYRwv0Kmp4FlNp/UXhDCHl3crWNy40gdnX/HXO2SfmIQ==} + engines: {node: '>=22.12.0'} + + '@commitlint/read@21.2.1': + resolution: {integrity: sha512-hUW7EJQnNTL0vPOmVMNK4CrnrNBN0nN+JJHReFkdHO5y4iyHeEmTBwuC15OCqUTjxWo7idnH1LftfpWVIaPWIA==} + engines: {node: '>=22.12.0'} + + '@commitlint/resolve-extends@21.2.0': + resolution: {integrity: sha512-4O/1j51+79Wth9s/MGxt/5gs0XYLDgNlYpltQfhAvLE0itusLKs9zruxbiNg1oOkmkb9L9L4USYGjEj7n87NxA==} + engines: {node: '>=22.12.0'} + + '@commitlint/rules@21.2.0': + resolution: {integrity: sha512-C2yXMNpiB8ETZKfx5JD8+ExgF8vTU1VQMKPSUUYwqKpw9oJWQBrlXBpdU038mj2WPjof7o9UzFpmTyBeGMZwZg==} + engines: {node: '>=22.12.0'} + + '@commitlint/to-lines@21.0.1': + resolution: {integrity: sha512-bd1BFII7p1EQZre9Kaj+kKaMFP3cFCdt21K7DItVux9XP5WjLgJ0/Uy1pJJh9aPwVJ6SKg62PxqlZaHI8hQAXw==} + engines: {node: '>=22.12.0'} + + '@commitlint/top-level@21.2.0': + resolution: {integrity: sha512-Y5gmQ+KxzqCrBFJfLvFEPvvwD3LDiNZoTT2yeFBm96M8qhmqSzQc5DvX3rheAaAMjyIvMXOCLS/mWfdpONsjyQ==} + engines: {node: '>=22.12.0'} + + '@commitlint/types@21.2.0': + resolution: {integrity: sha512-7zVFCDB2reMvJH5dmbKnOQPjZEvjdJTH8jc0U/PIPU1r3/+vf5pD1HlfitV2MWsWXrvu7u39iY1lyLUPOaN0Gw==} + engines: {node: '>=22.12.0'} '@contentful/app-action-utils@1.4.1': resolution: {integrity: sha512-jsoA8832fgZj+KGl67k3GZKQDWCxY47p42nJuDpiAnaKRCvWXLo7zY+pQLWvS66OU4OyfwZnwZoBOZ6yu+Jr+w==} @@ -1373,6 +1446,25 @@ packages: resolution: {integrity: sha512-EA5vTfROZePoPmSlqLVd+luL/ev8CjnI20y6vWFVPlLRxQbv4XytXRzatydPE63CqfsPylF7NCn2z8rTLhnWfg==} engines: {node: '>=6.0.0'} + '@conventional-changelog/git-client@3.1.0': + resolution: {integrity: sha512-Tqa/gHco2WJWa740NRjOrfKVvzIqxkZpecb8bemaQ8sKM5PXb1UK4uTyTb/1wIqNuOVaDOFxyBdhTIQZn6gdjQ==} + engines: {node: '>=22'} + peerDependencies: + conventional-commits-filter: ^6.0.1 + conventional-commits-parser: ^7.0.1 + peerDependenciesMeta: + conventional-commits-filter: + optional: true + conventional-commits-parser: + optional: true + + '@conventional-changelog/template@1.2.1': + resolution: {integrity: sha512-TzlTVpKPjaqW6qOYjQcYUDuGsLCNsvFHVBXkYGTAnf5V37jCWrE5haKNXzz0WZUtVHjrpV76L1buANjwXMfT8w==} + engines: {node: '>=22'} + + '@conventional-commits/parser@0.4.1': + resolution: {integrity: sha512-H2ZmUVt6q+KBccXfMBhbBF14NlANeqHTXL4qCL6QGbMzrc4HDXyzWuxPxPNbz71f/5UkR5DrycP5VO9u7crahg==} + '@discoveryjs/json-ext@0.6.3': resolution: {integrity: sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ==} engines: {node: '>=14.17.0'} @@ -1598,6 +1690,10 @@ packages: '@gerrit0/mini-shiki@3.23.0': resolution: {integrity: sha512-bEMORlG0cqdjVyCEuU0cDQbORWX+kYCeo0kV1lbxF5bt4r7SID2l9bqsxJEM0zndaxpOUT7riCyIVEuqq/Ynxg==} + '@google-automations/git-file-utils@3.0.1': + resolution: {integrity: sha512-vlQZ8DlBcippB5zTY0M5Rib8tKT4yQ7oBKbs6kcWAzp70oyillKinXLZwlIgNTmfzzZx1J6cez3M0EmrpXFRcw==} + engines: {node: '>= 20'} + '@hapi/address@5.1.1': resolution: {integrity: sha512-A+po2d/dVoY7cYajycYI43ZbYMXukuopIsqCjh5QzsBCipDtdofHntljDlpccMjIfTy6UOkg+5KPriwYch2bXA==} engines: {node: '>=14.0.0'} @@ -1649,6 +1745,9 @@ packages: resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} engines: {node: '>=18.18'} + '@iarna/toml@3.0.0': + resolution: {integrity: sha512-td6ZUkz2oS3VeleBcN+m//Q6HlCFCPrnI0FZhrt/h4XqLEdOyYp2u21nd8MdsR+WJy5r9PTDaHTDDfhf4H4l6Q==} + '@img/colour@1.1.0': resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==} engines: {node: '>=18'} @@ -2019,6 +2118,18 @@ packages: '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + '@jsep-plugin/assignment@1.3.0': + resolution: {integrity: sha512-VVgV+CXrhbMI3aSusQyclHkenWSAm95WaiKrMxRFam3JSUiIaQjoMIw2sEs/OX4XifnqeQUN4DYbJjlA8EfktQ==} + engines: {node: '>= 10.16.0'} + peerDependencies: + jsep: ^0.4.0||^1.0.0 + + '@jsep-plugin/regex@1.0.4': + resolution: {integrity: sha512-q7qL4Mgjs1vByCaTnDFcBnV9HS7GVPJX5vyVoCgZHNSC9rjwIlmbXG5sUuorR5ndfHAIlJ8pVStxvjXHbNvtUg==} + engines: {node: '>= 10.16.0'} + peerDependencies: + jsep: ^0.4.0||^1.0.0 + '@leeoniya/ufuzzy@1.0.19': resolution: {integrity: sha512-0pikDeYt0IHEUPza5RTCDXc/17S1pTrYnReEMp8Aa6k1ovzw5QdZLwicW8TjljwEZRb6oYag0xmALohrcq/yOQ==} @@ -2164,6 +2275,58 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} + '@octokit/auth-token@4.0.0': + resolution: {integrity: sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==} + engines: {node: '>= 18'} + + '@octokit/core@5.2.2': + resolution: {integrity: sha512-/g2d4sW9nUDJOMz3mabVQvOGhVa4e/BN/Um7yca9Bb2XTzPPnfTWHWQg+IsEYO7M3Vx+EXvaM/I2pJWIMun1bg==} + engines: {node: '>= 18'} + + '@octokit/endpoint@9.0.6': + resolution: {integrity: sha512-H1fNTMA57HbkFESSt3Y9+FBICv+0jFceJFPWDePYlR/iMGrwM5ph+Dd4XRQs+8X+PUFURLQgX9ChPfhJ/1uNQw==} + engines: {node: '>= 18'} + + '@octokit/graphql@7.1.1': + resolution: {integrity: sha512-3mkDltSfcDUoa176nlGoA32RGjeWjl3K7F/BwHwRMJUW/IteSa4bnSV8p2ThNkcIcZU2umkZWxwETSSCJf2Q7g==} + engines: {node: '>= 18'} + + '@octokit/openapi-types@24.2.0': + resolution: {integrity: sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==} + + '@octokit/plugin-paginate-rest@11.4.4-cjs.2': + resolution: {integrity: sha512-2dK6z8fhs8lla5PaOTgqfCGBxgAv/le+EhPs27KklPhm1bKObpu6lXzwfUEQ16ajXzqNrKMujsFyo9K2eaoISw==} + engines: {node: '>= 18'} + peerDependencies: + '@octokit/core': '5' + + '@octokit/plugin-request-log@4.0.1': + resolution: {integrity: sha512-GihNqNpGHorUrO7Qa9JbAl0dbLnqJVrV8OXe2Zm5/Y4wFkZQDfTreBzVmiRfJVfE4mClXdihHnbpyyO9FSX4HA==} + engines: {node: '>= 18'} + peerDependencies: + '@octokit/core': '5' + + '@octokit/plugin-rest-endpoint-methods@13.3.2-cjs.1': + resolution: {integrity: sha512-VUjIjOOvF2oELQmiFpWA1aOPdawpyaCUqcEBc/UOUnj3Xp6DJGrJ1+bjUIIDzdHjnFNO6q57ODMfdEZnoBkCwQ==} + engines: {node: '>= 18'} + peerDependencies: + '@octokit/core': ^5 + + '@octokit/request-error@5.1.1': + resolution: {integrity: sha512-v9iyEQJH6ZntoENr9/yXxjuezh4My67CBSu9r6Ve/05Iu5gNgnisNWOsoJHTP6k0Rr0+HQIpnH+kyammu90q/g==} + engines: {node: '>= 18'} + + '@octokit/request@8.4.1': + resolution: {integrity: sha512-qnB2+SY3hkCmBxZsR/MPCybNmbJe4KAlfWErXq+rBKkQJlbjdJeS85VI9r8UqeLYLvnAenU8Q1okM/0MBsAGXw==} + engines: {node: '>= 18'} + + '@octokit/rest@20.1.2': + resolution: {integrity: sha512-GmYiltypkHHtihFwPRxlaorG5R9VAHuk/vbszVoRTGXnAsY60wYLkh/E2XiFmdZmqrisw+9FaazS1i5SbdWYgA==} + engines: {node: '>= 18'} + + '@octokit/types@13.10.0': + resolution: {integrity: sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==} + '@open-draft/deferred-promise@2.2.0': resolution: {integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==} @@ -2603,6 +2766,14 @@ packages: '@sideway/pinpoint@2.0.0': resolution: {integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==} + '@simple-libs/child-process-utils@2.0.0': + resolution: {integrity: sha512-dvNoRKLijXnD0XoJAz94pbNuB5GQgDr55UhpSPhffDkTT0Cmcqh9jSCOtwfT2d4H6MI9E7c4SgtMuJXZ6F3c6A==} + engines: {node: '>=22'} + + '@simple-libs/stream-utils@2.0.0': + resolution: {integrity: sha512-fCTuZK4QBa+39Oz9l4OGfJfz+GpwCp3AqO7Zch3to99xHPgstVsRFpeQ8LNd2o1Gv8raL2mCFwiaHh7bFSp5DQ==} + engines: {node: '>=22'} + '@sinclair/typebox@0.27.10': resolution: {integrity: sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA==} @@ -2733,6 +2904,9 @@ packages: '@types/http-errors@2.0.5': resolution: {integrity: sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==} + '@types/inquirer@9.0.10': + resolution: {integrity: sha512-vFW2WbXwO9eZpRT5GJGFJ/shgyMNnYozmnjakt9jCQSS1lvqX8pZEQMjJ9RdDPct/YxwciQ8+V8OYn9euIrZDA==} + '@types/istanbul-lib-coverage@2.0.6': resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} @@ -2751,8 +2925,8 @@ packages: '@types/jsonfile@6.1.4': resolution: {integrity: sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==} - '@types/node-fetch@2.6.13': - resolution: {integrity: sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==} + '@types/minimist@1.2.5': + resolution: {integrity: sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==} '@types/node@24.10.13': resolution: {integrity: sha512-oH72nZRfDv9lADUBSo104Aq7gPHpQZc4BTx38r9xf9pg5LfP6EzSyH2n7qFmmxRQXh7YlUXODcYsg6PuTDSxGg==} @@ -2760,6 +2934,12 @@ packages: '@types/node@24.13.2': resolution: {integrity: sha512-fRa09kZTgu8o71KFcDjUFuc7F+dEbZYZmkI0mg5YBTRs0yMKjYHsq/c0urDKeDb+D5qVgXOdFcuu+DZPKOITwA==} + '@types/normalize-package-data@2.4.4': + resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} + + '@types/npm-package-arg@6.1.4': + resolution: {integrity: sha512-vDgdbMy2QXHnAruzlv68pUtXCjmqUk3WrBAsRboRovsOmxbfn/WiYCjmecyKjGztnMps5dWp4Uq2prp+Ilo17Q==} + '@types/qs@6.14.0': resolution: {integrity: sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==} @@ -2792,9 +2972,15 @@ packages: '@types/tapable@2.2.7': resolution: {integrity: sha512-D6QzACV9vNX3r8HQQNTOnpG+Bv1rko+yEA82wKs3O9CQ5+XW7HI7TED17/UE7+5dIxyxZIWTxKbsBeF6uKFCwA==} + '@types/through@0.0.33': + resolution: {integrity: sha512-HsJ+z3QuETzP3cswwtzt2vEIiHBk/dCcHGhbmG5X3ecnwFD/lPrMpliGXxSCg03L9AhrdwA4Oz/qfspkDW+xGQ==} + '@types/trusted-types@2.0.7': resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + '@types/unist@2.0.11': + resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} + '@types/unist@3.0.3': resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} @@ -2982,6 +3168,10 @@ packages: '@vscode/sudo-prompt@9.3.2': resolution: {integrity: sha512-gcXoCN00METUNFeQOFJ+C9xUI0DKB+0EGMVg7wbVYRHBw2Eq3fKisDZOkRdOz3kqXRKOENMfShPOmypw1/8nOw==} + '@xmldom/xmldom@0.8.13': + resolution: {integrity: sha512-KRYzxepc14G/CEpEGc3Yn+JKaAeT63smlDr+vjB8jRfgTBBI9wRj/nkQEO+ucV8p8I9bfKLWp37uHgFrbntPvw==} + engines: {node: '>=10.0.0'} + abort-controller@3.0.0: resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} engines: {node: '>=6.5'} @@ -3026,10 +3216,6 @@ packages: resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} engines: {node: '>= 14'} - agentkeepalive@4.6.0: - resolution: {integrity: sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==} - engines: {node: '>= 8.0.0'} - aggregate-error@3.1.0: resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} engines: {node: '>=8'} @@ -3176,6 +3362,9 @@ packages: array-flatten@1.1.1: resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + array-ify@1.0.0: + resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==} + array-includes@3.1.9: resolution: {integrity: sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==} engines: {node: '>= 0.4'} @@ -3196,6 +3385,10 @@ packages: resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} engines: {node: '>= 0.4'} + arrify@1.0.1: + resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} + engines: {node: '>=0.10.0'} + asap@2.0.6: resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} @@ -3234,6 +3427,9 @@ packages: async-limiter@1.0.1: resolution: {integrity: sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==} + async-retry@1.3.3: + resolution: {integrity: sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==} + async@2.6.4: resolution: {integrity: sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==} @@ -3243,10 +3439,6 @@ packages: asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - at-least-node@1.0.0: - resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} - engines: {node: '>= 4.0.0'} - available-typed-arrays@1.0.7: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} @@ -3327,6 +3519,9 @@ packages: resolution: {integrity: sha512-bopVNp6ugyA150DDuZfPFdt1KZ5a94ZDiwX4hMgZDzF+GttD80lEy8kj98kbyhLXnPvhtIo93mdnLIjpCAeeOw==} engines: {node: '>=10.0.0'} + before-after-hook@2.2.3: + resolution: {integrity: sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==} + bfj@9.1.3: resolution: {integrity: sha512-1ythbcNNAd2UjTYW6M+MAHd9KM/m3g4mQ+3a4Vom16WgmUa4GsisdmXAYfpAjkObY5zdpgzaBh1ctZOEcJipuQ==} engines: {node: '>= 18.0.0'} @@ -3352,13 +3547,13 @@ packages: resolution: {integrity: sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==} engines: {node: '>=18'} + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + boxen@5.1.2: resolution: {integrity: sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==} engines: {node: '>=10'} - brace-expansion@1.1.12: - resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} - brace-expansion@1.1.15: resolution: {integrity: sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg==} @@ -3405,10 +3600,6 @@ packages: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} - cachedir@2.3.0: - resolution: {integrity: sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==} - engines: {node: '>=6'} - call-bind-apply-helpers@1.0.2: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} @@ -3429,6 +3620,10 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} + camelcase-keys@6.2.2: + resolution: {integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==} + engines: {node: '>=8'} + camelcase@5.3.1: resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} engines: {node: '>=6'} @@ -3471,12 +3666,6 @@ packages: resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} engines: {node: '>=10'} - chardet@0.4.2: - resolution: {integrity: sha512-j/Toj7f1z98Hh2cYo2BVr85EpIRWqUi7rtRSGxh/cqUjqrnJe9l9UE7IUGd2vQ2p+kSHLkSzObQPZPLUC6TQwg==} - - chardet@0.7.0: - resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} - chardet@2.1.1: resolution: {integrity: sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==} @@ -3666,10 +3855,8 @@ packages: resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} engines: {node: ^12.20.0 || >=14} - commitizen@4.3.1: - resolution: {integrity: sha512-gwAPAVTy/j5YcOOebcCRIijn+mSjWJC+IYKivTu6aG8Ei/scoXgfsMRnuAk6b0GRste2J4NGxVdMN3ZpfNaVaw==} - engines: {node: '>= 12'} - hasBin: true + compare-func@2.0.0: + resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==} compressible@2.0.18: resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} @@ -3749,12 +3936,30 @@ packages: resolution: {integrity: sha512-5VtIrJ7X6209Yn25PfFRSz51eAtKJtxXSMSYG8loNMYVd+1lfAFRcw+dMVgnOQLv/TmYRSh1KKjtbwxlzHBm4g==} engines: {node: '>=18'} - conventional-commit-types@3.0.0: - resolution: {integrity: sha512-SmmCYnOniSsAa9GqWOeLqc179lfr5TRu5b4QFDkbsrJ5TZjPJx85wtOr3zn+1dbeNiXDKGPbZ72IKbPhLXh/Lg==} + conventional-changelog-angular@9.2.1: + resolution: {integrity: sha512-oWSL6ZhnXbYraOFTK3PgRAQJ8fADDAEv5K6AdeyQPLvjFmhG8+ejL0jZZp/R7vTmGJaBvZEE+sE7dB4bCv7sAw==} + engines: {node: '>=22'} + + conventional-changelog-conventionalcommits@10.2.1: + resolution: {integrity: sha512-n4Kr1HFMTf3iMbES0TMxKIcYtUUv4rKqyQQp2JwfOEfFCOfGT3Tq4mCyJ8S9/YPyWhydjfKrrvnyl+gCjA+mJQ==} + engines: {node: '>=22'} - conventional-commits-parser@6.2.1: - resolution: {integrity: sha512-20pyHgnO40rvfI0NGF/xiEoFMkXDtkF8FwHvk5BokoFoCuTQRI8vrNCNFWUOfuolKJMm1tPCHc8GgYEtr1XRNA==} - engines: {node: '>=18'} + conventional-changelog-conventionalcommits@6.1.0: + resolution: {integrity: sha512-3cS3GEtR78zTfMzk0AizXKKIdN4OvSh7ibNz6/DPbhWWQu7LqE/8+/GqSodV+sywUR2gpJAdP/1JFf4XtN7Zpw==} + engines: {node: '>=14'} + + conventional-changelog-writer@6.0.1: + resolution: {integrity: sha512-359t9aHorPw+U+nHzUXHS5ZnPBOizRxfQsWT5ZDHBfvfxQOAik+yfuhKXG66CN5LEWPpMNnIMHUTCKeYNprvHQ==} + engines: {node: '>=14'} + hasBin: true + + conventional-commits-filter@3.0.0: + resolution: {integrity: sha512-1ymej8b5LouPx9Ox0Dw/qAO2dVdfpRFq28e5Y0jJEU8ZrLdy0vOSkkIInwmxErFGhg6SALro60ZrwYFVTUDo4Q==} + engines: {node: '>=14'} + + conventional-commits-parser@7.0.1: + resolution: {integrity: sha512-6VtskFpPsNkGVk/TY2RnV/MEdKfvCPBtQZN9x8jh9+k5RWBQ+tiaWn5UFCzTr0Dd88iKx7xghxbjBRp5uIzp3g==} + engines: {node: '>=22'} hasBin: true convert-source-map@2.0.0: @@ -3794,14 +3999,6 @@ packages: resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==} engines: {node: '>= 0.10'} - cosmiconfig-typescript-loader@5.0.0: - resolution: {integrity: sha512-+8cK7jRAReYkMwMiG+bxhcNKiHJDM6bR9FD/nGBXOWdMLuYawjF5cGrtLilJ+LGd3ZjCXnJjR5DkfWPoIVlqJA==} - engines: {node: '>=v16'} - peerDependencies: - '@types/node': ^24.0.13 - cosmiconfig: '>=8.2' - typescript: ^5.8.3 - cosmiconfig-typescript-loader@6.2.0: resolution: {integrity: sha512-GEN39v7TgdxgIoNcdkRE3uiAzQt3UXLyHbRHD6YoL048XAeOomyxaP+Hh/+2C6C2wYjxJ2onhJcsQp+L4YEkVQ==} engines: {node: '>=v18'} @@ -3819,6 +4016,15 @@ packages: typescript: optional: true + cosmiconfig@9.0.2: + resolution: {integrity: sha512-gtTZxTDau1wL7Y7zifc2dd8jHSK/k6BTx/2Xp/BpdlAdnlYWFVt7qhJqgwi7637yRwRQ3qL4ZidbB4I8tA5VOg==} + engines: {node: '>=14'} + peerDependencies: + typescript: ^5.8.3 + peerDependenciesMeta: + typescript: + optional: true + create-jest@29.7.0: resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -3831,20 +4037,19 @@ packages: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} + css-select@5.2.2: + resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} + + css-what@6.2.2: + resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} + engines: {node: '>= 6'} + csstype@3.2.3: resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} culvert@0.1.2: resolution: {integrity: sha512-yi1x3EAWKjQTreYWeSd98431AV+IEE0qoDyOoaHJ7KJ21gv6HtBXHVLX74opVSGqcR8/AbjJBHAHpcOy2bj5Gg==} - cz-conventional-changelog@3.3.0: - resolution: {integrity: sha512-U466fIzU5U22eES5lTNiNbZ+d8dfcHcssH4o7QsdWaCcRs/feIPCxKYSWkYBNs5mny7MvEfwpTLWjvbm94hecw==} - engines: {node: '>= 10'} - - cz-vinyl@2.5.4: - resolution: {integrity: sha512-XyAnDZx654hbUuUka+kuhOG0PztGgcRsPxaUzVHis3kGTvsuLgr3/efPhKyzDXR4r+J7ZVEgEwm5C24HKTRIwA==} - engines: {node: '>=14.16'} - data-uri-to-buffer@6.0.2: resolution: {integrity: sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==} engines: {node: '>= 14'} @@ -3871,6 +4076,9 @@ packages: date-fns@4.1.0: resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==} + dateformat@3.0.3: + resolution: {integrity: sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==} + dayjs@1.11.15: resolution: {integrity: sha512-MC+DfnSWiM9APs7fpiurHGCoeIx0Gdl6QZBy+5lu8MbYKN5FZEXqOgrundfibdfhGZ15o9hzmZ2xJjZnbvgKXQ==} @@ -3911,13 +4119,14 @@ packages: supports-color: optional: true + decamelize-keys@1.1.1: + resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==} + engines: {node: '>=0.10.0'} + decamelize@1.2.0: resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} engines: {node: '>=0.10.0'} - dedent@0.7.0: - resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==} - dedent@1.7.1: resolution: {integrity: sha512-9JmrhGZpOlEgOLdQgSm0zxFaYoQon408V1v49aqTWuXENVlnCuY9JBZcXZiCsZQWDjTm5Qf/nIvAy77mXDAjEg==} peerDependencies: @@ -3964,14 +4173,13 @@ packages: resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} engines: {node: '>= 0.8'} + deprecation@2.3.1: + resolution: {integrity: sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==} + destroy@1.2.0: resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - detect-file@1.0.0: - resolution: {integrity: sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==} - engines: {node: '>=0.10.0'} - detect-indent@6.1.0: resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} engines: {node: '>=8'} @@ -4017,6 +4225,10 @@ packages: domutils@3.2.2: resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} + dot-prop@5.3.0: + resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} + engines: {node: '>=8'} + dotenv@16.6.1: resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} engines: {node: '>=12'} @@ -4412,10 +4624,6 @@ packages: resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} engines: {node: '>= 0.8.0'} - expand-tilde@2.0.2: - resolution: {integrity: sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==} - engines: {node: '>=0.10.0'} - expect@29.7.0: resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -4447,14 +4655,6 @@ packages: external-editor@1.1.1: resolution: {integrity: sha512-0XYlP43jzxMgJjugDJ85Z0UDPnowkUbfFztNvsSGC9sJVIk97MZbGEb9WAhIVH0UgNxoLj/9ZQgB4CHJyz2GGQ==} - external-editor@2.2.0: - resolution: {integrity: sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==} - engines: {node: '>=0.12'} - - external-editor@3.1.0: - resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} - engines: {node: '>=4'} - extrareqp2@1.0.0: resolution: {integrity: sha512-Gum0g1QYb6wpPJCVypWP3bbIuaibcFiJcpuPM10YSXp/tzqi84x9PJageob+eN4xVRIOto4wjSGNLyMD54D2xA==} @@ -4562,12 +4762,6 @@ packages: resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==} engines: {node: '>= 18.0.0'} - find-node-modules@2.1.3: - resolution: {integrity: sha512-UC2I2+nx1ZuOBclWVNdcnbDR5dlrOdVb7xNjmT/lHE+LsgztWks3dG7boJ37yTS/venXw84B/mAW9uHVoC5QRg==} - - find-root@1.1.0: - resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==} - find-up@3.0.0: resolution: {integrity: sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==} engines: {node: '>=6'} @@ -4580,10 +4774,6 @@ packages: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} - findup-sync@4.0.0: - resolution: {integrity: sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ==} - engines: {node: '>= 8'} - flat-cache@3.2.0: resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} engines: {node: ^10.12.0 || >=12.0.0} @@ -4621,17 +4811,10 @@ packages: resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} engines: {node: '>=14'} - form-data-encoder@1.7.2: - resolution: {integrity: sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==} - form-data@4.0.5: resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} engines: {node: '>= 6'} - formdata-node@4.4.1: - resolution: {integrity: sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==} - engines: {node: '>= 12.20'} - forwarded@0.2.0: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} engines: {node: '>= 0.6'} @@ -4652,10 +4835,6 @@ packages: resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} engines: {node: '>=6 <7 || >=8'} - fs-extra@9.1.0: - resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} - engines: {node: '>=10'} - fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} @@ -4683,10 +4862,6 @@ packages: functions-have-names@1.2.3: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} - fuse.js@7.0.0: - resolution: {integrity: sha512-14F4hBIxqKvD4Zz/XjDc3y94mNZN6pRv3U13Udo0lNLCWRBUsrMv2xwcF/y/Z5sV6+FQW+/ow68cHpm4sunt8Q==} - engines: {node: '>=10'} - generator-function@2.0.1: resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==} engines: {node: '>= 0.4'} @@ -4772,17 +4947,9 @@ packages: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me - global-directory@4.0.1: - resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==} - engines: {node: '>=18'} - - global-modules@1.0.0: - resolution: {integrity: sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==} - engines: {node: '>=0.10.0'} - - global-prefix@1.0.2: - resolution: {integrity: sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==} - engines: {node: '>=0.10.0'} + global-directory@5.0.0: + resolution: {integrity: sha512-1pgFdhK3J2LeM+dVf2Pd424yHx2ou338lC0ErNP2hPx4j8eW1Sp0XqSjNxtk6Tc4Kr5wlWtSvz8cn2yb7/SG/w==} + engines: {node: '>=20'} globals@13.24.0: resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} @@ -4813,10 +4980,19 @@ packages: resolution: {integrity: sha512-DKKrynuQRne0PNpEbzuEdHlYOMksHSUI8Zc9Unei5gTsMNA2/vMpoMz/yKba50pejK56qj98qM0SjYxAKi13gQ==} engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} + handlebars@4.7.9: + resolution: {integrity: sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==} + engines: {node: '>=0.4.7'} + hasBin: true + happy-dom@20.8.9: resolution: {integrity: sha512-Tz23LR9T9jOGVZm2x1EPdXqwA37G/owYMxRwU0E4miurAtFsPMQ1d2Jc2okUaSjZqAFz2oEn3FLXC5a0a+siyA==} engines: {node: '>=20.0.0'} + hard-rejection@2.1.0: + resolution: {integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==} + engines: {node: '>=6'} + has-ansi@2.0.0: resolution: {integrity: sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==} engines: {node: '>=0.10.0'} @@ -4856,6 +5032,10 @@ packages: resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} engines: {node: '>= 0.4'} + he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + headers-polyfill@4.0.3: resolution: {integrity: sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==} @@ -4877,14 +5057,17 @@ packages: highlight.js@10.7.3: resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==} - homedir-polyfill@1.0.3: - resolution: {integrity: sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==} - engines: {node: '>=0.10.0'} - hoopy@0.1.4: resolution: {integrity: sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==} engines: {node: '>= 6.0.0'} + hosted-git-info@2.8.9: + resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} + + hosted-git-info@4.1.0: + resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==} + engines: {node: '>=10'} + html-entities@2.6.0: resolution: {integrity: sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==} @@ -4914,9 +5097,6 @@ packages: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} - humanize-ms@1.2.1: - resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} - husky@9.1.7: resolution: {integrity: sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==} engines: {node: '>=18'} @@ -4959,9 +5139,6 @@ packages: engines: {node: '>=8'} hasBin: true - import-meta-resolve@4.2.0: - resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==} - imurmurhash@0.1.4: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} @@ -4987,9 +5164,9 @@ packages: ini@1.3.8: resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} - ini@4.1.1: - resolution: {integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + ini@6.0.0: + resolution: {integrity: sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ==} + engines: {node: ^20.17.0 || >=22.9.0} inquirer-autocomplete-prompt@2.0.1: resolution: {integrity: sha512-jUHrH0btO7j5r8DTQgANf2CBkTZChoVySD8zF/wp5fZCOLIuUbleXhf4ZY5jNBOc1owA3gdfWtfZuppfYBhcUg==} @@ -4997,28 +5174,20 @@ packages: peerDependencies: inquirer: ^8.0.0 - inquirer-maxlength-input-prompt@1.0.2: - resolution: {integrity: sha512-bRs4PfQ7k+M3dDGadFo4//PlEYwWV/tKMNHV0m1jVHSGocyLvlRLuWrNgDuVAmXiEydM5QgfEEP7hbWNtgv0oA==} - engines: {node: '>=6.0.0'} - inquirer-select-directory@1.2.0: resolution: {integrity: sha512-G6D+//DozjVi+o3VwrHu2+RjQPAb0M78Vg4c8mellV8rehly/mJFLBgs9r4VrKz/afb+Gr2fqj24jH3gYUYawQ==} inquirer@2.0.0: resolution: {integrity: sha512-ClW/liBHCfUD57ciSoxoq7fS9F3t1rvxxO5gRzdsDzfcJdKTyeMsVgRBQZkzcr8Nd2f4NIA9rm0qDl4ZXYZRUA==} - inquirer@5.2.0: - resolution: {integrity: sha512-E9BmnJbAKLPGonz0HeWHtbKf+EeSP93paWO3ZYoUpq/aowXvYGjjCSuashhXPpzbArIjBbji39THkxTz9ZeEUQ==} - engines: {node: '>=6.0.0'} - - inquirer@8.2.5: - resolution: {integrity: sha512-QAgPDQMEgrDssk1XiwwHoOGYF9BAbUcc1+j+FhEvaOt8/cKRqyLn0U5qA6F74fGhTMGxf92pOvPBeh29jQJDTQ==} - engines: {node: '>=12.0.0'} - inquirer@8.2.7: resolution: {integrity: sha512-UjOaSel/iddGZJ5xP/Eixh6dY1XghiBw4XK13rCCIJcJfyhhoul/7KhLLUGtebEj6GDYM6Vnx/mVsjx2L/mFIA==} engines: {node: '>=12.0.0'} + inquirer@9.3.8: + resolution: {integrity: sha512-pFGGdaHrmRKMh4WoDDSowddgjT1Vkl90atobmTeSmcPGdYiwikch/m/Ef5wRaiamHejtw0cUUMMerzDUXCci2w==} + engines: {node: '>=18'} + internal-slot@1.1.0: resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} engines: {node: '>= 0.4'} @@ -5153,6 +5322,10 @@ packages: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} + is-obj@2.0.0: + resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} + engines: {node: '>=8'} + is-observable@1.1.0: resolution: {integrity: sha512-NqCa4Sa2d+u7BWc6CukaObG3Fh+CU9bvixbpcXYhy2VvYS7vVGIdAgnIS5Ks3A/cqk4rebLJ9s8zBstT2aKnIA==} engines: {node: '>=4'} @@ -5161,6 +5334,10 @@ packages: resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} engines: {node: '>=8'} + is-plain-obj@1.1.0: + resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} + engines: {node: '>=0.10.0'} + is-plain-obj@2.1.0: resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} engines: {node: '>=8'} @@ -5218,9 +5395,6 @@ packages: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} engines: {node: '>=10'} - is-utf8@0.2.1: - resolution: {integrity: sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==} - is-valid-element-name@1.0.0: resolution: {integrity: sha512-GZITEJY2LkSjQfaIPBha7eyZv+ge0PhBR7KITeCCWvy7VBQrCUdFkvpI+HrAPQjVtVjy1LvlEkqQTHckoszruw==} @@ -5236,10 +5410,6 @@ packages: resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} engines: {node: '>= 0.4'} - is-windows@1.0.2: - resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} - engines: {node: '>=0.10.0'} - is-wsl@1.1.0: resolution: {integrity: sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==} engines: {node: '>=4'} @@ -5493,10 +5663,6 @@ packages: node-notifier: optional: true - jiti@1.21.7: - resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} - hasBin: true - jiti@2.6.1: resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} hasBin: true @@ -5535,9 +5701,17 @@ packages: resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} hasBin: true + js-yaml@4.3.0: + resolution: {integrity: sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==} + hasBin: true + jsc-safe-url@0.2.4: resolution: {integrity: sha512-0wM3YBWtYePOjfyXQH5MWQ8H7sdk5EXSwZvmSLKk2RboVQ2Bu239jycHDz5J/8Blf3K0Qnoy2b6xD+z10MFB+Q==} + jsep@1.4.0: + resolution: {integrity: sha512-B7qPcEVE3NVkmSJbaYxvv4cHkVW7DQsZz13pUMrfS8z8Q/BuShN+gcTXrUlPiGqM2/t/EEaI030bpxMqY8gMlw==} + engines: {node: '>= 10.16.0'} + jsesc@3.1.0: resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} engines: {node: '>=6'} @@ -5582,6 +5756,11 @@ packages: jsonfile@6.2.0: resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} + jsonpath-plus@10.4.0: + resolution: {integrity: sha512-T92WWatJXmhBbKsgH/0hl+jxjdXrifi5IKeMY02DWggRxX0UElcbVzPlmgLTbvsPeW1PasQ6xE2Q75stkhGbsA==} + engines: {node: '>=18.0.0'} + hasBin: true + jsonwebtoken@9.0.3: resolution: {integrity: sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==} engines: {node: '>=12', npm: '>=6'} @@ -5704,18 +5883,15 @@ packages: lodash.includes@4.3.0: resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} - lodash.invoke@4.5.2: - resolution: {integrity: sha512-SC4Usc0XbIKuz3eH7oNwPqibKHfTJSGVZwO/6eGhdoPzqexOY7z43pKo8xz0M5zzXSRteADV6fW7cRf6Ru0+VA==} - lodash.isboolean@3.0.3: resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==} - lodash.isfunction@3.0.9: - resolution: {integrity: sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==} - lodash.isinteger@4.0.4: resolution: {integrity: sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==} + lodash.ismatch@4.4.0: + resolution: {integrity: sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==} + lodash.isnumber@3.0.3: resolution: {integrity: sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==} @@ -5725,30 +5901,18 @@ packages: lodash.isstring@4.0.1: resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==} - lodash.map@4.6.0: - resolution: {integrity: sha512-worNHGKLDetmcEYDvh2stPCrrQRkP20E4l0iIS7F8EvzMqBBi7ltvFN5m1HvTf1P7Jk1txKhvFcmYsCr8O2F1Q==} - lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - lodash.mergewith@4.6.2: - resolution: {integrity: sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==} - lodash.once@4.1.1: resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} - lodash.partialright@4.2.1: - resolution: {integrity: sha512-yebmPMQZH7i4El6SdJTW9rn8irWl8VTcsmiWqm/I4sY8/ZjbSo0Z512HL6soeAu3mh5rhx5uIIo6kYJOQXbCxw==} - lodash.startcase@4.4.0: resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} lodash.throttle@4.1.1: resolution: {integrity: sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==} - lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - lodash@4.17.23: resolution: {integrity: sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==} @@ -5779,10 +5943,6 @@ packages: resolution: {integrity: sha512-/3ER20CTTbahrCrpYfPn7Xavv9diBROZpoXGVZDWMw4b/X4uuUwAC0ki85tgsdMRONURyIJbcOvS94QsUBYPbQ==} hasBin: true - longest@2.0.1: - resolution: {integrity: sha512-Ajzxb8CM6WAnFjgiloPsI3bF+WCxcvhdIG3KNA2KN962+tdBsHcuQ4k4qX/EcS/2CRkcc0iAkR956Nib6aXU/Q==} - engines: {node: '>=0.10.0'} - loose-envify@1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true @@ -5815,6 +5975,14 @@ packages: makeerror@1.0.12: resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} + map-obj@1.0.1: + resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==} + engines: {node: '>=0.10.0'} + + map-obj@4.3.0: + resolution: {integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==} + engines: {node: '>=8'} + markdown-it@14.1.1: resolution: {integrity: sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA==} hasBin: true @@ -5845,9 +6013,13 @@ packages: memoize-one@5.2.1: resolution: {integrity: sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==} - meow@13.2.0: - resolution: {integrity: sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==} - engines: {node: '>=18'} + meow@14.1.0: + resolution: {integrity: sha512-EDYo6VlmtnumlcBCbh1gLJ//9jvM/ndXHfVXIFrZVr6fGcwTUyCTFNTLCKuY3ffbK8L/+3Mzqnd58RojiZqHVw==} + engines: {node: '>=20'} + + meow@8.1.2: + resolution: {integrity: sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==} + engines: {node: '>=10'} merge-descriptors@1.0.3: resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} @@ -5867,9 +6039,6 @@ packages: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} - merge@2.1.1: - resolution: {integrity: sha512-jz+Cfrg9GWOZbQAnDQ4hlVnQky+341Yk5ru8bZSe6sIDTCIg8n9i/u7hSQGSVOF3C7lH6mGtqjkiT9G4wFLL0w==} - methods@1.1.2: resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} engines: {node: '>= 0.6'} @@ -5994,9 +6163,6 @@ packages: resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} engines: {node: 18 || 20 || >=22} - minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - minimatch@3.1.5: resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} @@ -6008,8 +6174,9 @@ packages: resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} engines: {node: '>=16 || 14 >=14.17'} - minimist@1.2.7: - resolution: {integrity: sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==} + minimist-options@4.1.0: + resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==} + engines: {node: '>= 6'} minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} @@ -6037,6 +6204,10 @@ packages: engines: {node: '>=10'} hasBin: true + modify-values@1.0.1: + resolution: {integrity: sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==} + engines: {node: '>=0.10.0'} + module-details-from-path@1.0.4: resolution: {integrity: sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==} @@ -6062,12 +6233,13 @@ packages: mute-stream@0.0.6: resolution: {integrity: sha512-m0kBTDLF/0lgzCsPVmJSKM5xkLNX7ZAB0Q+n2DP37JMIRPVC2R4c3BdO6x++bXFKftbhvSfKgwxAexME+BRDRw==} - mute-stream@0.0.7: - resolution: {integrity: sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==} - mute-stream@0.0.8: resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} + mute-stream@1.0.0: + resolution: {integrity: sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + mute-stream@2.0.0: resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} engines: {node: ^18.17.0 || >=20.5.0} @@ -6109,6 +6281,9 @@ packages: resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} engines: {node: '>= 0.6'} + neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + netmask@2.0.2: resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==} engines: {node: '>= 0.4.0'} @@ -6138,23 +6313,12 @@ packages: resolution: {integrity: sha512-WDD0bdg9mbq6F4mRxEYcPWwfA1vxd0mrvKOyxI7Xj/atfRHVeutzuWByG//jfm4uPzp0y4Kj051EORCBSQMycw==} engines: {node: '>=12.0.0'} - node-domexception@1.0.0: - resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} - engines: {node: '>=10.5.0'} - deprecated: Use your platform's native DOMException instead - node-exports-info@1.6.0: resolution: {integrity: sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw==} engines: {node: '>= 0.4'} - node-fetch@2.7.0: - resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} - engines: {node: 4.x || >=6.0.0} - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true + node-html-parser@6.1.13: + resolution: {integrity: sha512-qIsTMOY4C/dAa5Q5vsobRpOOvPfC4pB61UVW2uSwZNUp0QU/jCekTal1vMmbO0DgdHeLUJpv/ARmDqErVxA3Sg==} node-int64@0.4.0: resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} @@ -6167,6 +6331,13 @@ packages: resolution: {integrity: sha512-LN4fydt9TqhZhThkZIVQnF9cwjU3qmUH9h78Mx/K7d3VvfRqqwthLwJEUOEL0QPZ0XQmNN7be5Ggit5+4dq3Bw==} engines: {node: '>=0.12.0'} + normalize-package-data@2.5.0: + resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} + + normalize-package-data@3.0.3: + resolution: {integrity: sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==} + engines: {node: '>=10'} + normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} @@ -6175,6 +6346,9 @@ packages: resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} engines: {node: '>=8'} + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + nullthrows@1.1.1: resolution: {integrity: sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==} @@ -6261,15 +6435,6 @@ packages: resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} engines: {node: '>=12'} - openai@4.65.0: - resolution: {integrity: sha512-LfA4KUBpH/8rA3vjCQ74LZtdK/8wx9W6Qxq8MHqEdImPsN1XPQ2ompIuJWkKS6kXt5Cs5i8Eb65IIo4M7U+yeQ==} - hasBin: true - peerDependencies: - zod: ^3.23.8 - peerDependenciesMeta: - zod: - optional: true - optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} @@ -6366,14 +6531,13 @@ packages: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} + parse-github-repo-url@1.4.1: + resolution: {integrity: sha512-bSWyzBKqcSL4RrncTpGsEKoJ7H8a4L3++ifTAbTFeMHyq2wRV+42DGmQcHIrJIvdcacjIOxEuKH/w4tthF17gg==} + parse-json@5.2.0: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} - parse-passwd@1.0.0: - resolution: {integrity: sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==} - engines: {node: '>=0.10.0'} - parse5-htmlparser2-tree-adapter@6.0.1: resolution: {integrity: sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==} @@ -6606,6 +6770,10 @@ packages: queue@6.0.2: resolution: {integrity: sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==} + quick-lru@4.0.1: + resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==} + engines: {node: '>=8'} + r-json@1.3.1: resolution: {integrity: sha512-5nhRFfjVMQdrwKUfUlRpDUCocdKtjSnYZ1R/86mpZDV3MfsZ3dYYNjSGuMX+mPBvFvQBhdzxSqxkuLPLv4uFGg==} @@ -6704,6 +6872,14 @@ packages: resolution: {integrity: sha512-llUJLzz1zTUBrskt2pwZgLq59AemifIftw4aB7JxOqf1HY2FDaGDxgwpAPVzHU1kdWabH7FauP4i1oEeer2WCA==} engines: {node: '>=0.10.0'} + read-pkg-up@7.0.1: + resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} + engines: {node: '>=8'} + + read-pkg@5.2.0: + resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} + engines: {node: '>=8'} + read@1.0.7: resolution: {integrity: sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==} engines: {node: '>=0.8'} @@ -6762,6 +6938,11 @@ packages: resolution: {integrity: sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==} hasBin: true + release-please@17.10.2: + resolution: {integrity: sha512-ucvCojdsq8wcc4LmQkIzVziuNSPLfP3WGO6+H5pET8LRECJms+dOe/FVMSi5QUybamGcaiCNguMYy9K3J/nPng==} + engines: {node: '>=22.0.0'} + hasBin: true + require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} @@ -6781,10 +6962,6 @@ packages: resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} engines: {node: '>=8'} - resolve-dir@1.0.1: - resolution: {integrity: sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==} - engines: {node: '>=0.10.0'} - resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -6826,6 +7003,10 @@ packages: resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} engines: {node: '>=18'} + retry@0.13.1: + resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} + engines: {node: '>= 4'} + rettime@0.10.1: resolution: {integrity: sha512-uyDrIlUEH37cinabq0AX4QbgV4HbFZ/gqoiunWQ1UqBtRvTTytwhNYjE++pO/MjPTZL5KQCf2bEoJ/BJNVQ5Kw==} @@ -6873,6 +7054,10 @@ packages: resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} engines: {node: '>=0.12.0'} + run-async@3.0.0: + resolution: {integrity: sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==} + engines: {node: '>=0.12.0'} + run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} @@ -6885,10 +7070,6 @@ packages: rx@4.1.0: resolution: {integrity: sha512-CiaiuN6gapkdl+cZUr67W6I8jquN4lkak3vtIsIWCl4XIPP8ffsoyN6/+PuGXnQy8Cu8W2y9Xxh31Rq4M6wUug==} - rxjs@5.5.12: - resolution: {integrity: sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw==} - engines: {npm: '>=2.0.0'} - rxjs@6.6.7: resolution: {integrity: sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==} engines: {npm: '>=2.0.0'} @@ -6928,6 +7109,10 @@ packages: scheduler@0.27.0: resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} + semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true @@ -7131,6 +7316,21 @@ packages: spawn-sync@1.0.15: resolution: {integrity: sha512-9DWBgrgYZzNghseho0JOuh+5fg9u6QWhAWa51QC7+U5rCheZ/j1DrEZnyE0RBBRqZ9uEXGPgSSM0nky6burpVw==} + spdx-correct@3.2.0: + resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + + spdx-exceptions@2.5.0: + resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} + + spdx-expression-parse@3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + + spdx-license-ids@3.0.23: + resolution: {integrity: sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==} + + split@1.0.1: + resolution: {integrity: sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==} + sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} @@ -7174,9 +7374,6 @@ packages: resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} engines: {node: '>=10'} - string-template@1.0.0: - resolution: {integrity: sha512-SLqR3GBUXuoPP5MmYtD7ompvXiG87QjT6lzOszyXjTM86Uu7At7vNnt2xgyTLq5o9T4IxTYFyGxcULqpsmsfdg==} - string-width@1.0.2: resolution: {integrity: sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==} engines: {node: '>=0.10.0'} @@ -7310,10 +7507,6 @@ packages: swc-plugin-coverage-instrument@0.0.32: resolution: {integrity: sha512-KsO1xNQdcVb331Rm98Op6uYf36/CYdF1kILQxOddmtCNlRLISpCUqHcnogu+QgELZvG48oie+w0fzS8uktjcEA==} - symbol-observable@1.0.1: - resolution: {integrity: sha512-Kb3PrPYz4HanVF1LVGuAdW6LoVgIwjUYJGzFe7NDrBLCN4lsV/5J0MFurV+ygS4bRVwrCEt2c7MQ1R2a72oJDw==} - engines: {node: '>=0.10.0'} - symbol-observable@1.2.0: resolution: {integrity: sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==} engines: {node: '>=0.10.0'} @@ -7376,6 +7569,10 @@ packages: tiny-invariant@1.3.3: resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + tinyexec@1.2.4: + resolution: {integrity: sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==} + engines: {node: '>=18'} + tinyglobby@0.2.15: resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} @@ -7395,10 +7592,6 @@ packages: resolution: {integrity: sha512-89PTqMWGDva+GqClOqBV9s3SMh7MA3Mq0pJUdAoHuF65YoE7O0LermaZkVfT5/Ngfo18H4eYiyG7zKOtnEbxsw==} engines: {node: '>=0.4.0'} - tmp@0.0.33: - resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} - engines: {node: '>=0.6.0'} - tmpl@1.0.5: resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} @@ -7417,13 +7610,14 @@ packages: resolution: {integrity: sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w==} engines: {node: '>=16'} - tr46@0.0.3: - resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - tree-kill@1.2.2: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} hasBin: true + trim-newlines@3.0.1: + resolution: {integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==} + engines: {node: '>=8'} + tryer@1.0.1: resolution: {integrity: sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==} @@ -7474,6 +7668,10 @@ packages: resolution: {integrity: sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==} engines: {node: '>=4'} + type-fest@0.18.1: + resolution: {integrity: sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==} + engines: {node: '>=10'} + type-fest@0.20.2: resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} engines: {node: '>=10'} @@ -7482,10 +7680,22 @@ packages: resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} engines: {node: '>=10'} + type-fest@0.6.0: + resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} + engines: {node: '>=8'} + type-fest@0.7.1: resolution: {integrity: sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==} engines: {node: '>=8'} + type-fest@0.8.1: + resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} + engines: {node: '>=8'} + + type-fest@3.13.1: + resolution: {integrity: sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==} + engines: {node: '>=14.16'} + type-fest@4.41.0: resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} engines: {node: '>=16'} @@ -7553,6 +7763,11 @@ packages: ucfirst@1.0.0: resolution: {integrity: sha512-xbB/CQ0GdkxqH4IElZqenn/dL/tnyx7DCDASWJPE92ePbFM21kKemXI2LBeYtEvblf1Ol98hyJJS43Wu5JMQSQ==} + uglify-js@3.19.3: + resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} + engines: {node: '>=0.8.0'} + hasBin: true + unbox-primitive@1.1.0: resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} engines: {node: '>= 0.4'} @@ -7579,6 +7794,18 @@ packages: resolution: {integrity: sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==} engines: {node: '>=4'} + unist-util-is@4.1.0: + resolution: {integrity: sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==} + + unist-util-visit-parents@3.1.1: + resolution: {integrity: sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==} + + unist-util-visit@2.0.3: + resolution: {integrity: sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==} + + universal-user-agent@6.0.1: + resolution: {integrity: sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==} + universalify@0.1.2: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} @@ -7639,6 +7866,9 @@ packages: resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} engines: {node: '>=10.12.0'} + validate-npm-package-license@3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + vary@1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} @@ -7659,13 +7889,6 @@ packages: wcwidth@1.0.1: resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} - web-streams-polyfill@4.0.0-beta.3: - resolution: {integrity: sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==} - engines: {node: '>= 14'} - - webidl-conversions@3.0.1: - resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} - whatwg-fetch@3.6.20: resolution: {integrity: sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==} @@ -7673,9 +7896,6 @@ packages: resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} engines: {node: '>=12'} - whatwg-url@5.0.0: - resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} - which-boxed-primitive@1.1.1: resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} engines: {node: '>= 0.4'} @@ -7699,10 +7919,6 @@ packages: resolution: {integrity: sha512-fvO4ExWMFsqyhG3AiPAObMuY1lxaqgYcxbc49CNdWDDECOJNgQyvsOWVwbZc+qf3rzRtxojBK+CMEv0Ld5CYpw==} engines: {node: '>= 0.4'} - which@1.3.1: - resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} - hasBin: true - which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} @@ -7716,6 +7932,9 @@ packages: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} + wordwrap@1.0.0: + resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} + wrap-ansi@3.0.1: resolution: {integrity: sha512-iXR3tDXpbnTpzjKSylUJRkLuOrEC7hwEB221cgn6wtF8wpmz28puFXAEfPT5zrjM3wahygB//VuWEr1vTkDcNQ==} engines: {node: '>=4'} @@ -7798,6 +8017,10 @@ packages: utf-8-validate: optional: true + xpath@0.0.34: + resolution: {integrity: sha512-FxF6+rkr1rNSQrhUNYrAFJpRXNzlDoMxeXN5qI84939ylEv3qqPFKa85Oxr6tDaJKqwW6KKyo2v26TSv3k6LeA==} + engines: {node: '>=0.6.0'} + y18n@4.0.3: resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} @@ -7871,9 +8094,6 @@ packages: resolution: {integrity: sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==} engines: {node: '>=18'} - zod@3.23.8: - resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} - zod@4.3.6: resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} @@ -8443,46 +8663,134 @@ snapshots: '@colors/colors@1.5.0': optional: true - '@commitlint/config-validator@20.4.0': + '@commitlint/cli@21.2.1(@types/node@24.13.2)(conventional-commits-parser@7.0.1)(typescript@5.9.3)': + dependencies: + '@commitlint/config-conventional': 21.2.0 + '@commitlint/format': 21.2.0 + '@commitlint/lint': 21.2.0 + '@commitlint/load': 21.2.0(@types/node@24.13.2)(typescript@5.9.3) + '@commitlint/read': 21.2.1(conventional-commits-parser@7.0.1) + '@commitlint/types': 21.2.0 + tinyexec: 1.2.4 + yargs: 18.0.0 + transitivePeerDependencies: + - '@types/node' + - conventional-commits-filter + - conventional-commits-parser + - typescript + + '@commitlint/config-conventional@21.2.0': + dependencies: + '@commitlint/types': 21.2.0 + conventional-changelog-conventionalcommits: 10.2.1 + + '@commitlint/config-validator@21.2.0': dependencies: - '@commitlint/types': 20.4.0 + '@commitlint/types': 21.2.0 ajv: 8.18.0 - optional: true - '@commitlint/execute-rule@20.0.0': - optional: true + '@commitlint/ensure@21.2.0': + dependencies: + '@commitlint/types': 21.2.0 + es-toolkit: 1.46.0 - '@commitlint/load@20.4.0(@types/node@24.10.13)(typescript@5.9.3)': + '@commitlint/execute-rule@21.0.1': {} + + '@commitlint/format@21.2.0': dependencies: - '@commitlint/config-validator': 20.4.0 - '@commitlint/execute-rule': 20.0.0 - '@commitlint/resolve-extends': 20.4.0 - '@commitlint/types': 20.4.0 - cosmiconfig: 9.0.0(typescript@5.9.3) - cosmiconfig-typescript-loader: 6.2.0(@types/node@24.10.13)(cosmiconfig@9.0.0(typescript@5.9.3))(typescript@5.9.3) + '@commitlint/types': 21.2.0 + picocolors: 1.1.1 + + '@commitlint/is-ignored@21.2.0': + dependencies: + '@commitlint/types': 21.2.0 + semver: 7.8.4 + + '@commitlint/lint@21.2.0': + dependencies: + '@commitlint/is-ignored': 21.2.0 + '@commitlint/parse': 21.2.0 + '@commitlint/rules': 21.2.0 + '@commitlint/types': 21.2.0 + + '@commitlint/load@21.2.0(@types/node@24.13.2)(typescript@5.9.3)': + dependencies: + '@commitlint/config-validator': 21.2.0 + '@commitlint/execute-rule': 21.0.1 + '@commitlint/resolve-extends': 21.2.0 + '@commitlint/types': 21.2.0 + cosmiconfig: 9.0.2(typescript@5.9.3) + cosmiconfig-typescript-loader: 6.2.0(@types/node@24.13.2)(cosmiconfig@9.0.2(typescript@5.9.3))(typescript@5.9.3) + es-toolkit: 1.46.0 is-plain-obj: 4.1.0 - lodash.mergewith: 4.6.2 picocolors: 1.1.1 transitivePeerDependencies: - '@types/node' - typescript - optional: true - '@commitlint/resolve-extends@20.4.0': + '@commitlint/message@21.2.0': {} + + '@commitlint/parse@21.2.0': + dependencies: + '@commitlint/types': 21.2.0 + conventional-changelog-angular: 9.2.1 + conventional-commits-parser: 7.0.1 + + '@commitlint/prompt-cli@21.2.0(@types/node@24.13.2)(typescript@5.9.3)': + dependencies: + '@commitlint/prompt': 21.2.0(@types/node@24.13.2)(typescript@5.9.3) + inquirer: 9.3.8(@types/node@24.13.2) + tinyexec: 1.2.4 + transitivePeerDependencies: + - '@types/node' + - typescript + + '@commitlint/prompt@21.2.0(@types/node@24.13.2)(typescript@5.9.3)': + dependencies: + '@commitlint/ensure': 21.2.0 + '@commitlint/load': 21.2.0(@types/node@24.13.2)(typescript@5.9.3) + '@commitlint/types': 21.2.0 + inquirer: 9.3.8(@types/node@24.13.2) + picocolors: 1.1.1 + transitivePeerDependencies: + - '@types/node' + - typescript + + '@commitlint/read@21.2.1(conventional-commits-parser@7.0.1)': + dependencies: + '@commitlint/top-level': 21.2.0 + '@commitlint/types': 21.2.0 + '@conventional-changelog/git-client': 3.1.0(conventional-commits-parser@7.0.1) + tinyexec: 1.2.4 + transitivePeerDependencies: + - conventional-commits-filter + - conventional-commits-parser + + '@commitlint/resolve-extends@21.2.0': dependencies: - '@commitlint/config-validator': 20.4.0 - '@commitlint/types': 20.4.0 - global-directory: 4.0.1 - import-meta-resolve: 4.2.0 - lodash.mergewith: 4.6.2 + '@commitlint/config-validator': 21.2.0 + '@commitlint/types': 21.2.0 + es-toolkit: 1.46.0 + global-directory: 5.0.0 resolve-from: 5.0.0 - optional: true - '@commitlint/types@20.4.0': + '@commitlint/rules@21.2.0': + dependencies: + '@commitlint/ensure': 21.2.0 + '@commitlint/message': 21.2.0 + '@commitlint/to-lines': 21.0.1 + '@commitlint/types': 21.2.0 + + '@commitlint/to-lines@21.0.1': {} + + '@commitlint/top-level@21.2.0': + dependencies: + escalade: 3.2.0 + + '@commitlint/types@21.2.0': dependencies: - conventional-commits-parser: 6.2.1 + conventional-commits-parser: 7.0.1 picocolors: 1.1.1 - optional: true '@contentful/app-action-utils@1.4.1': {} @@ -8509,6 +8817,21 @@ snapshots: - '@lingui/babel-plugin-lingui-macro' - babel-plugin-macros + '@conventional-changelog/git-client@3.1.0(conventional-commits-parser@7.0.1)': + dependencies: + '@simple-libs/child-process-utils': 2.0.0 + '@simple-libs/stream-utils': 2.0.0 + semver: 7.8.4 + optionalDependencies: + conventional-commits-parser: 7.0.1 + + '@conventional-changelog/template@1.2.1': {} + + '@conventional-commits/parser@0.4.1': + dependencies: + unist-util-visit: 2.0.3 + unist-util-visit-parents: 3.1.1 + '@discoveryjs/json-ext@0.6.3': {} '@emnapi/core@1.11.1': @@ -8679,6 +9002,13 @@ snapshots: '@shikijs/types': 3.23.0 '@shikijs/vscode-textmate': 10.0.2 + '@google-automations/git-file-utils@3.0.1': + dependencies: + '@octokit/rest': 20.1.2 + '@octokit/types': 13.10.0 + js-yaml: 4.1.1 + minimatch: 10.2.5 + '@hapi/address@5.1.1': dependencies: '@hapi/hoek': 11.0.7 @@ -8722,6 +9052,8 @@ snapshots: '@humanwhocodes/retry@0.4.3': {} + '@iarna/toml@3.0.0': {} + '@img/colour@1.1.0': optional: true @@ -9186,6 +9518,14 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 + '@jsep-plugin/assignment@1.3.0(jsep@1.4.0)': + dependencies: + jsep: 1.4.0 + + '@jsep-plugin/regex@1.0.4(jsep@1.4.0)': + dependencies: + jsep: 1.4.0 + '@leeoniya/ufuzzy@1.0.19': {} '@lingui/core@5.9.2': @@ -9371,6 +9711,69 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.20.1 + '@octokit/auth-token@4.0.0': {} + + '@octokit/core@5.2.2': + dependencies: + '@octokit/auth-token': 4.0.0 + '@octokit/graphql': 7.1.1 + '@octokit/request': 8.4.1 + '@octokit/request-error': 5.1.1 + '@octokit/types': 13.10.0 + before-after-hook: 2.2.3 + universal-user-agent: 6.0.1 + + '@octokit/endpoint@9.0.6': + dependencies: + '@octokit/types': 13.10.0 + universal-user-agent: 6.0.1 + + '@octokit/graphql@7.1.1': + dependencies: + '@octokit/request': 8.4.1 + '@octokit/types': 13.10.0 + universal-user-agent: 6.0.1 + + '@octokit/openapi-types@24.2.0': {} + + '@octokit/plugin-paginate-rest@11.4.4-cjs.2(@octokit/core@5.2.2)': + dependencies: + '@octokit/core': 5.2.2 + '@octokit/types': 13.10.0 + + '@octokit/plugin-request-log@4.0.1(@octokit/core@5.2.2)': + dependencies: + '@octokit/core': 5.2.2 + + '@octokit/plugin-rest-endpoint-methods@13.3.2-cjs.1(@octokit/core@5.2.2)': + dependencies: + '@octokit/core': 5.2.2 + '@octokit/types': 13.10.0 + + '@octokit/request-error@5.1.1': + dependencies: + '@octokit/types': 13.10.0 + deprecation: 2.3.1 + once: 1.4.0 + + '@octokit/request@8.4.1': + dependencies: + '@octokit/endpoint': 9.0.6 + '@octokit/request-error': 5.1.1 + '@octokit/types': 13.10.0 + universal-user-agent: 6.0.1 + + '@octokit/rest@20.1.2': + dependencies: + '@octokit/core': 5.2.2 + '@octokit/plugin-paginate-rest': 11.4.4-cjs.2(@octokit/core@5.2.2) + '@octokit/plugin-request-log': 4.0.1(@octokit/core@5.2.2) + '@octokit/plugin-rest-endpoint-methods': 13.3.2-cjs.1(@octokit/core@5.2.2) + + '@octokit/types@13.10.0': + dependencies: + '@octokit/openapi-types': 24.2.0 + '@open-draft/deferred-promise@2.2.0': {} '@open-draft/logger@0.3.0': @@ -10102,6 +10505,12 @@ snapshots: '@sideway/pinpoint@2.0.0': {} + '@simple-libs/child-process-utils@2.0.0': + dependencies: + '@simple-libs/stream-utils': 2.0.0 + + '@simple-libs/stream-utils@2.0.0': {} + '@sinclair/typebox@0.27.10': {} '@sinclair/typebox@0.34.48': {} @@ -10258,6 +10667,11 @@ snapshots: '@types/http-errors@2.0.5': {} + '@types/inquirer@9.0.10': + dependencies: + '@types/through': 0.0.33 + rxjs: 7.8.2 + '@types/istanbul-lib-coverage@2.0.6': {} '@types/istanbul-lib-report@3.0.3': @@ -10276,10 +10690,7 @@ snapshots: dependencies: '@types/node': 24.13.2 - '@types/node-fetch@2.6.13': - dependencies: - '@types/node': 24.13.2 - form-data: 4.0.5 + '@types/minimist@1.2.5': {} '@types/node@24.10.13': dependencies: @@ -10289,6 +10700,10 @@ snapshots: dependencies: undici-types: 7.18.2 + '@types/normalize-package-data@2.4.4': {} + + '@types/npm-package-arg@6.1.4': {} + '@types/qs@6.14.0': {} '@types/range-parser@1.2.7': {} @@ -10322,8 +10737,14 @@ snapshots: dependencies: tapable: 2.3.0 + '@types/through@0.0.33': + dependencies: + '@types/node': 24.13.2 + '@types/trusted-types@2.0.7': {} + '@types/unist@2.0.11': {} + '@types/unist@3.0.3': {} '@types/whatwg-mimetype@3.0.2': {} @@ -10494,6 +10915,8 @@ snapshots: '@vscode/sudo-prompt@9.3.2': {} + '@xmldom/xmldom@0.8.13': {} + abort-controller@3.0.0: dependencies: event-target-shim: 5.0.1 @@ -10536,10 +10959,6 @@ snapshots: agent-base@7.1.4: {} - agentkeepalive@4.6.0: - dependencies: - humanize-ms: 1.2.1 - aggregate-error@3.1.0: dependencies: clean-stack: 2.2.0 @@ -10660,6 +11079,8 @@ snapshots: array-flatten@1.1.1: {} + array-ify@1.0.0: {} + array-includes@3.1.9: dependencies: call-bind: 1.0.9 @@ -10705,6 +11126,8 @@ snapshots: get-intrinsic: 1.3.0 is-array-buffer: 3.0.5 + arrify@1.0.1: {} + asap@2.0.6: {} assertion-error@2.0.1: {} @@ -10731,6 +11154,10 @@ snapshots: async-limiter@1.0.1: {} + async-retry@1.3.3: + dependencies: + retry: 0.13.1 + async@2.6.4: dependencies: lodash: 4.18.1 @@ -10739,8 +11166,6 @@ snapshots: asynckit@0.4.0: {} - at-least-node@1.0.0: {} - available-typed-arrays@1.0.7: dependencies: possible-typed-array-names: 1.1.0 @@ -10868,6 +11293,8 @@ snapshots: basic-ftp@5.3.1: {} + before-after-hook@2.2.3: {} + bfj@9.1.3: dependencies: check-types: 11.2.3 @@ -10917,6 +11344,8 @@ snapshots: transitivePeerDependencies: - supports-color + boolbase@1.0.0: {} + boxen@5.1.2: dependencies: ansi-align: 3.0.1 @@ -10928,11 +11357,6 @@ snapshots: widest-line: 3.1.0 wrap-ansi: 7.0.0 - brace-expansion@1.1.12: - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - brace-expansion@1.1.15: dependencies: balanced-match: 1.0.2 @@ -10983,8 +11407,6 @@ snapshots: bytes@3.1.2: {} - cachedir@2.3.0: {} - call-bind-apply-helpers@1.0.2: dependencies: es-errors: 1.3.0 @@ -11011,6 +11433,12 @@ snapshots: callsites@3.1.0: {} + camelcase-keys@6.2.2: + dependencies: + camelcase: 5.3.1 + map-obj: 4.3.0 + quick-lru: 4.0.1 + camelcase@5.3.1: {} camelcase@6.3.0: {} @@ -11061,10 +11489,6 @@ snapshots: char-regex@1.0.2: {} - chardet@0.4.2: {} - - chardet@0.7.0: {} - chardet@2.1.1: {} charm@0.1.2: {} @@ -11253,25 +11677,10 @@ snapshots: commander@9.5.0: {} - commitizen@4.3.1(@types/node@24.13.2)(typescript@5.9.3): + compare-func@2.0.0: dependencies: - cachedir: 2.3.0 - cz-conventional-changelog: 3.3.0(@types/node@24.13.2)(typescript@5.9.3) - dedent: 0.7.0 - detect-indent: 6.1.0 - find-node-modules: 2.1.3 - find-root: 1.1.0 - fs-extra: 9.1.0 - glob: 7.2.3 - inquirer: 8.2.5 - is-utf8: 0.2.1 - lodash: 4.17.21 - minimist: 1.2.7 - strip-bom: 4.0.0 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - '@types/node' - - typescript + array-ify: 1.0.0 + dot-prop: 5.3.0 compressible@2.0.18: dependencies: @@ -11503,12 +11912,37 @@ snapshots: - debug - supports-color - conventional-commit-types@3.0.0: {} + conventional-changelog-angular@9.2.1: + dependencies: + '@conventional-changelog/template': 1.2.1 - conventional-commits-parser@6.2.1: + conventional-changelog-conventionalcommits@10.2.1: dependencies: - meow: 13.2.0 - optional: true + '@conventional-changelog/template': 1.2.1 + + conventional-changelog-conventionalcommits@6.1.0: + dependencies: + compare-func: 2.0.0 + + conventional-changelog-writer@6.0.1: + dependencies: + conventional-commits-filter: 3.0.0 + dateformat: 3.0.3 + handlebars: 4.7.9 + json-stringify-safe: 5.0.1 + meow: 8.1.2 + semver: 7.8.4 + split: 1.0.1 + + conventional-commits-filter@3.0.0: + dependencies: + lodash.ismatch: 4.4.0 + modify-values: 1.0.1 + + conventional-commits-parser@7.0.1: + dependencies: + '@simple-libs/stream-utils': 2.0.0 + meow: 14.1.0 convert-source-map@2.0.0: {} @@ -11537,22 +11971,23 @@ snapshots: object-assign: 4.1.1 vary: 1.1.2 - cosmiconfig-typescript-loader@5.0.0(@types/node@24.10.13)(cosmiconfig@9.0.0(typescript@5.9.3))(typescript@5.9.3): + cosmiconfig-typescript-loader@6.2.0(@types/node@24.13.2)(cosmiconfig@9.0.2(typescript@5.9.3))(typescript@5.9.3): dependencies: - '@types/node': 24.10.13 - cosmiconfig: 9.0.0(typescript@5.9.3) - jiti: 1.21.7 + '@types/node': 24.13.2 + cosmiconfig: 9.0.2(typescript@5.9.3) + jiti: 2.7.0 typescript: 5.9.3 - cosmiconfig-typescript-loader@6.2.0(@types/node@24.10.13)(cosmiconfig@9.0.0(typescript@5.9.3))(typescript@5.9.3): + cosmiconfig@9.0.0(typescript@5.9.3): dependencies: - '@types/node': 24.10.13 - cosmiconfig: 9.0.0(typescript@5.9.3) - jiti: 2.6.1 + env-paths: 2.2.1 + import-fresh: 3.3.1 + js-yaml: 4.1.1 + parse-json: 5.2.0 + optionalDependencies: typescript: 5.9.3 - optional: true - cosmiconfig@9.0.0(typescript@5.9.3): + cosmiconfig@9.0.2(typescript@5.9.3): dependencies: env-paths: 2.2.1 import-fresh: 3.3.1 @@ -11584,40 +12019,19 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 - csstype@3.2.3: {} + css-select@5.2.2: + dependencies: + boolbase: 1.0.0 + css-what: 6.2.2 + domhandler: 5.0.3 + domutils: 3.2.2 + nth-check: 2.1.1 - culvert@0.1.2: {} + css-what@6.2.2: {} - cz-conventional-changelog@3.3.0(@types/node@24.13.2)(typescript@5.9.3): - dependencies: - chalk: 2.4.2 - commitizen: 4.3.1(@types/node@24.13.2)(typescript@5.9.3) - conventional-commit-types: 3.0.0 - lodash.map: 4.6.0 - longest: 2.0.1 - word-wrap: 1.2.5 - optionalDependencies: - '@commitlint/load': 20.4.0(@types/node@24.10.13)(typescript@5.9.3) - transitivePeerDependencies: - - '@types/node' - - typescript + csstype@3.2.3: {} - cz-vinyl@2.5.4(@types/node@24.10.13)(inquirer@8.2.7(@types/node@24.13.2))(typescript@5.9.3): - dependencies: - cosmiconfig: 9.0.0(typescript@5.9.3) - cosmiconfig-typescript-loader: 5.0.0(@types/node@24.10.13)(cosmiconfig@9.0.0(typescript@5.9.3))(typescript@5.9.3) - fuse.js: 7.0.0 - inquirer-autocomplete-prompt: 2.0.1(inquirer@8.2.7(@types/node@24.13.2)) - inquirer-maxlength-input-prompt: 1.0.2 - openai: 4.65.0(zod@3.23.8) - string-template: 1.0.0 - word-wrap: 1.2.5 - zod: 3.23.8 - transitivePeerDependencies: - - '@types/node' - - encoding - - inquirer - - typescript + culvert@0.1.2: {} data-uri-to-buffer@6.0.2: {} @@ -11647,6 +12061,8 @@ snapshots: date-fns@4.1.0: {} + dateformat@3.0.3: {} + dayjs@1.11.15: {} dayjs@1.8.36: {} @@ -11667,9 +12083,12 @@ snapshots: dependencies: ms: 2.1.3 - decamelize@1.2.0: {} + decamelize-keys@1.1.1: + dependencies: + decamelize: 1.2.0 + map-obj: 1.0.1 - dedent@0.7.0: {} + decamelize@1.2.0: {} dedent@1.7.1: {} @@ -11709,9 +12128,9 @@ snapshots: depd@2.0.0: {} - destroy@1.2.0: {} + deprecation@2.3.1: {} - detect-file@1.0.0: {} + destroy@1.2.0: {} detect-indent@6.1.0: {} @@ -11756,6 +12175,10 @@ snapshots: domelementtype: 2.3.0 domhandler: 5.0.3 + dot-prop@5.3.0: + dependencies: + is-obj: 2.0.0 + dotenv@16.6.1: {} dotenv@17.3.1: {} @@ -12437,10 +12860,6 @@ snapshots: exit@0.1.2: {} - expand-tilde@2.0.2: - dependencies: - homedir-polyfill: 1.0.3 - expect@29.7.0: dependencies: '@jest/expect-utils': 29.7.0 @@ -12542,18 +12961,6 @@ snapshots: spawn-sync: 1.0.15 tmp: 0.0.29 - external-editor@2.2.0: - dependencies: - chardet: 0.4.2 - iconv-lite: 0.4.24 - tmp: 0.0.33 - - external-editor@3.1.0: - dependencies: - chardet: 0.7.0 - iconv-lite: 0.4.24 - tmp: 0.0.33 - extrareqp2@1.0.0(debug@4.3.7): dependencies: follow-redirects: 1.16.0(debug@4.3.7) @@ -12674,13 +13081,6 @@ snapshots: transitivePeerDependencies: - supports-color - find-node-modules@2.1.3: - dependencies: - findup-sync: 4.0.0 - merge: 2.1.1 - - find-root@1.1.0: {} - find-up@3.0.0: dependencies: locate-path: 3.0.0 @@ -12695,13 +13095,6 @@ snapshots: locate-path: 6.0.0 path-exists: 4.0.0 - findup-sync@4.0.0: - dependencies: - detect-file: 1.0.0 - is-glob: 4.0.3 - micromatch: 4.0.8 - resolve-dir: 1.0.1 - flat-cache@3.2.0: dependencies: flatted: 3.4.2 @@ -12734,8 +13127,6 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 - form-data-encoder@1.7.2: {} - form-data@4.0.5: dependencies: asynckit: 0.4.0 @@ -12744,11 +13135,6 @@ snapshots: hasown: 2.0.2 mime-types: 2.1.35 - formdata-node@4.4.1: - dependencies: - node-domexception: 1.0.0 - web-streams-polyfill: 4.0.0-beta.3 - forwarded@0.2.0: {} fresh@0.5.2: {} @@ -12767,13 +13153,6 @@ snapshots: jsonfile: 4.0.0 universalify: 0.1.2 - fs-extra@9.1.0: - dependencies: - at-least-node: 1.0.0 - graceful-fs: 4.2.11 - jsonfile: 6.2.0 - universalify: 2.0.1 - fs.realpath@1.0.0: {} fsevents@2.3.2: @@ -12807,8 +13186,6 @@ snapshots: functions-have-names@1.2.3: {} - fuse.js@7.0.0: {} - generator-function@2.0.1: {} gensync@1.0.0-beta.2: {} @@ -12899,28 +13276,13 @@ snapshots: fs.realpath: 1.0.0 inflight: 1.0.6 inherits: 2.0.4 - minimatch: 3.1.2 + minimatch: 3.1.5 once: 1.4.0 path-is-absolute: 1.0.1 - global-directory@4.0.1: + global-directory@5.0.0: dependencies: - ini: 4.1.1 - optional: true - - global-modules@1.0.0: - dependencies: - global-prefix: 1.0.2 - is-windows: 1.0.2 - resolve-dir: 1.0.1 - - global-prefix@1.0.2: - dependencies: - expand-tilde: 2.0.2 - homedir-polyfill: 1.0.3 - ini: 1.3.8 - is-windows: 1.0.2 - which: 1.3.1 + ini: 6.0.0 globals@13.24.0: dependencies: @@ -12943,6 +13305,15 @@ snapshots: graphql@16.12.0: {} + handlebars@4.7.9: + dependencies: + minimist: 1.2.8 + neo-async: 2.6.2 + source-map: 0.6.1 + wordwrap: 1.0.0 + optionalDependencies: + uglify-js: 3.19.3 + happy-dom@20.8.9: dependencies: '@types/node': 24.13.2 @@ -12955,6 +13326,8 @@ snapshots: - bufferutil - utf-8-validate + hard-rejection@2.1.0: {} + has-ansi@2.0.0: dependencies: ansi-regex: 2.1.1 @@ -12987,6 +13360,8 @@ snapshots: dependencies: function-bind: 1.1.2 + he@1.2.0: {} + headers-polyfill@4.0.3: {} hermes-compiler@250829098.0.9: {} @@ -13005,12 +13380,14 @@ snapshots: highlight.js@10.7.3: {} - homedir-polyfill@1.0.3: - dependencies: - parse-passwd: 1.0.0 - hoopy@0.1.4: {} + hosted-git-info@2.8.9: {} + + hosted-git-info@4.1.0: + dependencies: + lru-cache: 6.0.0 + html-entities@2.6.0: {} html-escaper@2.0.2: {} @@ -13053,10 +13430,6 @@ snapshots: human-signals@2.1.0: {} - humanize-ms@1.2.1: - dependencies: - ms: 2.1.3 - husky@9.1.7: {} iconv-lite@0.4.24: @@ -13089,9 +13462,6 @@ snapshots: pkg-dir: 4.2.0 resolve-cwd: 3.0.0 - import-meta-resolve@4.2.0: - optional: true - imurmurhash@0.1.4: {} indent-string@3.2.0: {} @@ -13109,8 +13479,7 @@ snapshots: ini@1.3.8: {} - ini@4.1.1: - optional: true + ini@6.0.0: {} inquirer-autocomplete-prompt@2.0.1(inquirer@8.2.7(@types/node@24.10.13)): dependencies: @@ -13121,23 +13490,6 @@ snapshots: run-async: 2.4.1 rxjs: 7.8.2 - inquirer-autocomplete-prompt@2.0.1(inquirer@8.2.7(@types/node@24.13.2)): - dependencies: - ansi-escapes: 4.3.2 - figures: 3.2.0 - inquirer: 8.2.7(@types/node@24.13.2) - picocolors: 1.1.1 - run-async: 2.4.1 - rxjs: 7.8.2 - - inquirer-maxlength-input-prompt@1.0.2: - dependencies: - chalk: 2.4.2 - inquirer: 5.2.0 - lodash.invoke: 4.5.2 - lodash.isfunction: 3.0.9 - lodash.partialright: 4.2.1 - inquirer-select-directory@1.2.0: dependencies: chalk: 1.1.1 @@ -13163,40 +13515,6 @@ snapshots: strip-ansi: 3.0.1 through: 2.3.8 - inquirer@5.2.0: - dependencies: - ansi-escapes: 3.2.0 - chalk: 2.4.2 - cli-cursor: 2.1.0 - cli-width: 2.2.1 - external-editor: 2.2.0 - figures: 2.0.0 - lodash: 4.18.1 - mute-stream: 0.0.7 - run-async: 2.4.1 - rxjs: 5.5.12 - string-width: 2.1.1 - strip-ansi: 4.0.0 - through: 2.3.8 - - inquirer@8.2.5: - dependencies: - ansi-escapes: 4.3.2 - chalk: 4.1.2 - cli-cursor: 3.1.0 - cli-width: 3.0.0 - external-editor: 3.1.0 - figures: 3.2.0 - lodash: 4.17.21 - mute-stream: 0.0.8 - ora: 5.4.1 - run-async: 2.4.1 - rxjs: 7.8.2 - string-width: 4.2.3 - strip-ansi: 6.0.1 - through: 2.3.8 - wrap-ansi: 7.0.0 - inquirer@8.2.7(@types/node@24.10.13): dependencies: '@inquirer/external-editor': 1.0.3(@types/node@24.10.13) @@ -13217,23 +13535,20 @@ snapshots: transitivePeerDependencies: - '@types/node' - inquirer@8.2.7(@types/node@24.13.2): + inquirer@9.3.8(@types/node@24.13.2): dependencies: '@inquirer/external-editor': 1.0.3(@types/node@24.13.2) + '@inquirer/figures': 1.0.15 ansi-escapes: 4.3.2 - chalk: 4.1.2 - cli-cursor: 3.1.0 - cli-width: 3.0.0 - figures: 3.2.0 - lodash: 4.18.1 - mute-stream: 0.0.8 + cli-width: 4.1.0 + mute-stream: 1.0.0 ora: 5.4.1 - run-async: 2.4.1 + run-async: 3.0.0 rxjs: 7.8.2 string-width: 4.2.3 strip-ansi: 6.0.1 - through: 2.3.8 wrap-ansi: 6.2.0 + yoctocolors-cjs: 2.1.3 transitivePeerDependencies: - '@types/node' @@ -13358,18 +13673,21 @@ snapshots: is-number@7.0.0: {} + is-obj@2.0.0: {} + is-observable@1.1.0: dependencies: symbol-observable: 1.2.0 is-path-inside@3.0.3: {} + is-plain-obj@1.1.0: {} + is-plain-obj@2.1.0: {} is-plain-obj@3.0.0: {} - is-plain-obj@4.1.0: - optional: true + is-plain-obj@4.1.0: {} is-potential-custom-element-name@1.0.1: {} @@ -13411,8 +13729,6 @@ snapshots: is-unicode-supported@0.1.0: {} - is-utf8@0.2.1: {} - is-valid-element-name@1.0.0: dependencies: is-potential-custom-element-name: 1.0.1 @@ -13428,8 +13744,6 @@ snapshots: call-bound: 1.0.4 get-intrinsic: 1.3.0 - is-windows@1.0.2: {} - is-wsl@1.1.0: {} is-wsl@2.2.0: @@ -14035,8 +14349,6 @@ snapshots: - supports-color - ts-node - jiti@1.21.7: {} - jiti@2.6.1: {} jiti@2.7.0: {} @@ -14083,8 +14395,14 @@ snapshots: dependencies: argparse: 2.0.1 + js-yaml@4.3.0: + dependencies: + argparse: 2.0.1 + jsc-safe-url@0.2.4: {} + jsep@1.4.0: {} + jsesc@3.1.0: {} json-buffer@3.0.1: {} @@ -14121,6 +14439,12 @@ snapshots: optionalDependencies: graceful-fs: 4.2.11 + jsonpath-plus@10.4.0: + dependencies: + '@jsep-plugin/assignment': 1.3.0(jsep@1.4.0) + '@jsep-plugin/regex': 1.0.4(jsep@1.4.0) + jsep: 1.4.0 + jsonwebtoken@9.0.3: dependencies: jws: 4.0.1 @@ -14297,37 +14621,26 @@ snapshots: lodash.includes@4.3.0: {} - lodash.invoke@4.5.2: {} - lodash.isboolean@3.0.3: {} - lodash.isfunction@3.0.9: {} - lodash.isinteger@4.0.4: {} + lodash.ismatch@4.4.0: {} + lodash.isnumber@3.0.3: {} lodash.isplainobject@4.0.6: {} lodash.isstring@4.0.1: {} - lodash.map@4.6.0: {} - lodash.merge@4.6.2: {} - lodash.mergewith@4.6.2: - optional: true - lodash.once@4.1.1: {} - lodash.partialright@4.2.1: {} - lodash.startcase@4.4.0: {} lodash.throttle@4.1.1: {} - lodash@4.17.21: {} - lodash@4.17.23: {} lodash@4.18.1: {} @@ -14368,8 +14681,6 @@ snapshots: dayjs: 1.11.15 yargs: 15.4.1 - longest@2.0.1: {} - loose-envify@1.4.0: dependencies: js-tokens: 4.0.0 @@ -14398,6 +14709,10 @@ snapshots: dependencies: tmpl: 1.0.5 + map-obj@1.0.1: {} + + map-obj@4.3.0: {} + markdown-it@14.1.1: dependencies: argparse: 2.0.1 @@ -14421,8 +14736,21 @@ snapshots: memoize-one@5.2.1: {} - meow@13.2.0: - optional: true + meow@14.1.0: {} + + meow@8.1.2: + dependencies: + '@types/minimist': 1.2.5 + camelcase-keys: 6.2.2 + decamelize-keys: 1.1.1 + hard-rejection: 2.1.0 + minimist-options: 4.1.0 + normalize-package-data: 3.0.3 + read-pkg-up: 7.0.1 + redent: 3.0.0 + trim-newlines: 3.0.1 + type-fest: 0.18.1 + yargs-parser: 20.2.9 merge-descriptors@1.0.3: {} @@ -14436,8 +14764,6 @@ snapshots: merge2@1.4.1: {} - merge@2.1.1: {} - methods@1.1.2: {} metro-babel-transformer@0.83.4: @@ -14659,10 +14985,6 @@ snapshots: dependencies: brace-expansion: 5.0.5 - minimatch@3.1.2: - dependencies: - brace-expansion: 1.1.12 - minimatch@3.1.5: dependencies: brace-expansion: 1.1.15 @@ -14675,7 +14997,11 @@ snapshots: dependencies: brace-expansion: 2.0.2 - minimist@1.2.7: {} + minimist-options@4.1.0: + dependencies: + arrify: 1.0.1 + is-plain-obj: 1.1.0 + kind-of: 6.0.3 minimist@1.2.8: {} @@ -14691,6 +15017,8 @@ snapshots: mkdirp@3.0.1: {} + modify-values@1.0.1: {} + module-details-from-path@1.0.4: {} moo@0.5.3: {} @@ -14726,10 +15054,10 @@ snapshots: mute-stream@0.0.6: {} - mute-stream@0.0.7: {} - mute-stream@0.0.8: {} + mute-stream@1.0.0: {} + mute-stream@2.0.0: {} mz@2.7.0: @@ -14760,6 +15088,8 @@ snapshots: negotiator@1.0.0: {} + neo-async@2.6.2: {} + netmask@2.0.2: {} next@16.2.6(@playwright/test@1.61.0)(react-dom@19.2.5(react@19.2.5))(react@19.2.5): @@ -14789,8 +15119,6 @@ snapshots: nocache@3.0.4: {} - node-domexception@1.0.0: {} - node-exports-info@1.6.0: dependencies: array.prototype.flatmap: 1.3.3 @@ -14798,9 +15126,10 @@ snapshots: object.entries: 1.1.9 semver: 6.3.1 - node-fetch@2.7.0: + node-html-parser@6.1.13: dependencies: - whatwg-url: 5.0.0 + css-select: 5.2.2 + he: 1.2.0 node-int64@0.4.0: {} @@ -14808,12 +15137,30 @@ snapshots: node-stream-zip@1.15.0: {} + normalize-package-data@2.5.0: + dependencies: + hosted-git-info: 2.8.9 + resolve: 1.22.11 + semver: 5.7.2 + validate-npm-package-license: 3.0.4 + + normalize-package-data@3.0.3: + dependencies: + hosted-git-info: 4.1.0 + is-core-module: 2.16.2 + semver: 7.8.4 + validate-npm-package-license: 3.0.4 + normalize-path@3.0.0: {} npm-run-path@4.0.1: dependencies: path-key: 3.1.1 + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + nullthrows@1.1.1: {} number-is-nan@1.0.1: {} @@ -14907,20 +15254,6 @@ snapshots: is-docker: 2.2.1 is-wsl: 2.2.0 - openai@4.65.0(zod@3.23.8): - dependencies: - '@types/node': 24.13.2 - '@types/node-fetch': 2.6.13 - abort-controller: 3.0.0 - agentkeepalive: 4.6.0 - form-data-encoder: 1.7.2 - formdata-node: 4.4.1 - node-fetch: 2.7.0 - optionalDependencies: - zod: 3.23.8 - transitivePeerDependencies: - - encoding - optionator@0.9.4: dependencies: deep-is: 0.1.4 @@ -15027,6 +15360,8 @@ snapshots: dependencies: callsites: 3.1.0 + parse-github-repo-url@1.4.1: {} + parse-json@5.2.0: dependencies: '@babel/code-frame': 7.29.7 @@ -15034,8 +15369,6 @@ snapshots: json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 - parse-passwd@1.0.0: {} - parse5-htmlparser2-tree-adapter@6.0.1: dependencies: parse5: 6.0.1 @@ -15283,6 +15616,8 @@ snapshots: dependencies: inherits: 2.0.4 + quick-lru@4.0.1: {} + r-json@1.3.1: dependencies: w-json: 1.3.10 @@ -15413,6 +15748,19 @@ snapshots: react@19.2.5: {} + read-pkg-up@7.0.1: + dependencies: + find-up: 4.1.0 + read-pkg: 5.2.0 + type-fest: 0.8.1 + + read-pkg@5.2.0: + dependencies: + '@types/normalize-package-data': 2.4.4 + normalize-package-data: 2.5.0 + parse-json: 5.2.0 + type-fest: 0.6.0 + read@1.0.7: dependencies: mute-stream: 0.0.8 @@ -15499,6 +15847,42 @@ snapshots: dependencies: jsesc: 3.1.0 + release-please@17.10.2: + dependencies: + '@conventional-commits/parser': 0.4.1 + '@google-automations/git-file-utils': 3.0.1 + '@iarna/toml': 3.0.0 + '@octokit/graphql': 7.1.1 + '@octokit/request': 8.4.1 + '@octokit/request-error': 5.1.1 + '@octokit/rest': 20.1.2 + '@types/npm-package-arg': 6.1.4 + '@xmldom/xmldom': 0.8.13 + async-retry: 1.3.3 + chalk: 4.1.2 + conventional-changelog-conventionalcommits: 6.1.0 + conventional-changelog-writer: 6.0.1 + conventional-commits-filter: 3.0.0 + detect-indent: 6.1.0 + diff: 8.0.3 + figures: 3.2.0 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + js-yaml: 4.3.0 + jsonpath-plus: 10.4.0 + node-html-parser: 6.1.13 + parse-github-repo-url: 1.4.1 + semver: 7.8.4 + type-fest: 3.13.1 + typescript: 5.9.3 + unist-util-visit: 2.0.3 + unist-util-visit-parents: 3.1.1 + xpath: 0.0.34 + yaml: 2.8.3 + yargs: 17.7.2 + transitivePeerDependencies: + - supports-color + require-directory@2.1.1: {} require-from-string@2.0.2: {} @@ -15517,11 +15901,6 @@ snapshots: dependencies: resolve-from: 5.0.0 - resolve-dir@1.0.1: - dependencies: - expand-tilde: 2.0.2 - global-modules: 1.0.0 - resolve-from@4.0.0: {} resolve-from@5.0.0: {} @@ -15565,6 +15944,8 @@ snapshots: onetime: 7.0.0 signal-exit: 4.1.0 + retry@0.13.1: {} + rettime@0.10.1: {} reusify@1.1.0: {} @@ -15610,6 +15991,8 @@ snapshots: run-async@2.4.1: {} + run-async@3.0.0: {} + run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 @@ -15620,10 +16003,6 @@ snapshots: rx@4.1.0: {} - rxjs@5.5.12: - dependencies: - symbol-observable: 1.0.1 - rxjs@6.6.7: dependencies: tslib: 1.14.1 @@ -15669,6 +16048,8 @@ snapshots: scheduler@0.27.0: {} + semver@5.7.2: {} + semver@6.3.1: {} semver@7.5.4: @@ -15946,6 +16327,24 @@ snapshots: concat-stream: 1.6.2 os-shim: 0.1.3 + spdx-correct@3.2.0: + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.23 + + spdx-exceptions@2.5.0: {} + + spdx-expression-parse@3.0.1: + dependencies: + spdx-exceptions: 2.5.0 + spdx-license-ids: 3.0.23 + + spdx-license-ids@3.0.23: {} + + split@1.0.1: + dependencies: + through: 2.3.8 + sprintf-js@1.0.3: {} sprintf-js@1.1.2: {} @@ -15980,8 +16379,6 @@ snapshots: char-regex: 1.0.2 strip-ansi: 6.0.1 - string-template@1.0.0: {} - string-width@1.0.2: dependencies: code-point-at: 1.1.0 @@ -16128,8 +16525,6 @@ snapshots: swc-plugin-coverage-instrument@0.0.32: {} - symbol-observable@1.0.1: {} - symbol-observable@1.2.0: {} synckit@0.11.12: @@ -16184,6 +16579,8 @@ snapshots: tiny-invariant@1.3.3: {} + tinyexec@1.2.4: {} + tinyglobby@0.2.15: dependencies: fdir: 6.5.0(picomatch@4.0.3) @@ -16201,10 +16598,6 @@ snapshots: dependencies: os-tmpdir: 1.0.2 - tmp@0.0.33: - dependencies: - os-tmpdir: 1.0.2 - tmpl@1.0.5: {} to-ast@1.0.0: @@ -16222,10 +16615,10 @@ snapshots: dependencies: tldts: 7.0.23 - tr46@0.0.3: {} - tree-kill@1.2.2: {} + trim-newlines@3.0.1: {} + tryer@1.0.1: {} ts-api-utils@2.4.0(typescript@5.9.3): @@ -16272,12 +16665,20 @@ snapshots: type-detect@4.1.0: {} + type-fest@0.18.1: {} + type-fest@0.20.2: {} type-fest@0.21.3: {} + type-fest@0.6.0: {} + type-fest@0.7.1: {} + type-fest@0.8.1: {} + + type-fest@3.13.1: {} + type-fest@4.41.0: {} type-fest@5.4.4: @@ -16369,6 +16770,9 @@ snapshots: ucfirst@1.0.0: {} + uglify-js@3.19.3: + optional: true + unbox-primitive@1.1.0: dependencies: call-bound: 1.0.4 @@ -16391,6 +16795,21 @@ snapshots: unicode-property-aliases-ecmascript@2.2.0: {} + unist-util-is@4.1.0: {} + + unist-util-visit-parents@3.1.1: + dependencies: + '@types/unist': 2.0.11 + unist-util-is: 4.1.0 + + unist-util-visit@2.0.3: + dependencies: + '@types/unist': 2.0.11 + unist-util-is: 4.1.0 + unist-util-visit-parents: 3.1.1 + + universal-user-agent@6.0.1: {} + universalify@0.1.2: {} universalify@2.0.1: {} @@ -16457,6 +16876,11 @@ snapshots: '@types/istanbul-lib-coverage': 2.0.6 convert-source-map: 2.0.0 + validate-npm-package-license@3.0.4: + dependencies: + spdx-correct: 3.2.0 + spdx-expression-parse: 3.0.1 + vary@1.1.2: {} vizion@2.2.1: @@ -16478,19 +16902,10 @@ snapshots: dependencies: defaults: 1.0.4 - web-streams-polyfill@4.0.0-beta.3: {} - - webidl-conversions@3.0.1: {} - whatwg-fetch@3.6.20: {} whatwg-mimetype@3.0.0: {} - whatwg-url@5.0.0: - dependencies: - tr46: 0.0.3 - webidl-conversions: 3.0.1 - which-boxed-primitive@1.1.1: dependencies: is-bigint: 1.1.0 @@ -16544,10 +16959,6 @@ snapshots: gopd: 1.2.0 has-tostringtag: 1.0.2 - which@1.3.1: - dependencies: - isexe: 2.0.0 - which@2.0.2: dependencies: isexe: 2.0.0 @@ -16558,6 +16969,8 @@ snapshots: word-wrap@1.2.5: {} + wordwrap@1.0.0: {} + wrap-ansi@3.0.1: dependencies: string-width: 2.1.1 @@ -16615,6 +17028,8 @@ snapshots: ws@8.21.0: {} + xpath@0.0.34: {} + y18n@4.0.3: {} y18n@5.0.8: {} @@ -16705,6 +17120,4 @@ snapshots: yoctocolors-cjs@2.1.3: {} - zod@3.23.8: {} - zod@4.3.6: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 335a236fc..6f19b2888 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -74,3 +74,8 @@ overrides: '@types/node': 'catalog:' typescript: 'catalog:' vitest: 'catalog:' + +minimumReleaseAgeExclude: + - '@commitlint/cli@21.2.1' + - '@commitlint/read@21.2.1' + - release-please@17.10.2 diff --git a/release-please-config.json b/release-please-config.json new file mode 100644 index 000000000..2cab7e9b5 --- /dev/null +++ b/release-please-config.json @@ -0,0 +1,95 @@ +{ + "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json", + "bootstrap-sha": "0508673176b924082be9a7c8579af09619336f4b", + "group-pull-request-title-pattern": "chore(repo): release packages", + "include-component-in-tag": true, + "include-v-in-tag": true, + "packages": { + "packages/universal/api-schemas": { + "component": "optimization-api-schemas", + "package-name": "@contentful/optimization-api-schemas", + "release-as": "1.0.0", + "release-type": "node" + }, + "packages/universal/api-client": { + "component": "optimization-api-client", + "package-name": "@contentful/optimization-api-client", + "release-as": "1.0.0", + "release-type": "node" + }, + "packages/universal/core-sdk": { + "component": "optimization-core", + "package-name": "@contentful/optimization-core", + "release-as": "1.0.0", + "release-type": "node" + }, + "packages/node/node-sdk": { + "component": "optimization-node", + "package-name": "@contentful/optimization-node", + "release-as": "1.0.0", + "release-type": "node" + }, + "packages/web/web-sdk": { + "component": "optimization-web", + "package-name": "@contentful/optimization-web", + "release-as": "1.0.0", + "release-type": "node" + }, + "packages/web/frameworks/react-web-sdk": { + "component": "optimization-react-web", + "package-name": "@contentful/optimization-react-web", + "release-as": "1.0.0", + "release-type": "node" + }, + "packages/web/frameworks/nextjs-sdk": { + "component": "optimization-nextjs", + "package-name": "@contentful/optimization-nextjs", + "release-as": "1.0.0", + "release-type": "node" + }, + "packages/web/preview-panel": { + "component": "optimization-web-preview-panel", + "package-name": "@contentful/optimization-web-preview-panel", + "release-as": "1.0.0", + "release-type": "node" + }, + "packages/react-native-sdk": { + "component": "optimization-react-native", + "package-name": "@contentful/optimization-react-native", + "release-as": "1.0.0-beta.0", + "release-type": "node", + "versioning": "prerelease", + "prerelease": true, + "prerelease-type": "beta" + }, + "packages/android/ContentfulOptimization": { + "component": "optimization-android", + "package-name": "optimization-android", + "release-as": "1.0.0-beta.0", + "release-type": "simple", + "version-file": "VERSION", + "versioning": "prerelease", + "prerelease": true, + "prerelease-type": "beta" + }, + "packages/ios/ContentfulOptimization": { + "component": "optimization-swift", + "package-name": "optimization-swift", + "release-as": "1.0.0-beta.0", + "release-type": "simple", + "version-file": "VERSION", + "versioning": "prerelease", + "prerelease": true, + "prerelease-type": "beta" + } + }, + "plugins": [ + { + "type": "native-bridge-impact", + "bootstrapSha": "0508673176b924082be9a7c8579af09619336f4b" + }, + { + "type": "node-workspace" + } + ] +} diff --git a/scripts/list-npm-package-targets.ts b/scripts/list-npm-package-targets.ts index 1e2e93922..945951883 100644 --- a/scripts/list-npm-package-targets.ts +++ b/scripts/list-npm-package-targets.ts @@ -1,5 +1,6 @@ /* eslint-disable no-console -- This CLI prints machine-readable records and errors. */ +import assert from 'node:assert/strict' import { spawnSync } from 'node:child_process' import { readFileSync } from 'node:fs' import path from 'node:path' @@ -11,6 +12,7 @@ interface PackageManifest { name: string optionalDependencies: Record private: boolean + version: string } interface WorkspacePackage { @@ -19,13 +21,19 @@ interface WorkspacePackage { path: string } +interface ReleasedNpmPublishTarget extends WorkspacePackage { + releaseTag: string + version: string +} + const rootDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..') const workspacePackages = readWorkspacePackages() const packageByName = new Map( workspacePackages.map((workspacePackage) => [workspacePackage.name, workspacePackage]), ) -const [command, packageName] = process.argv.slice(2) +const [command, ...args] = process.argv.slice(2) +const [packageName] = args if (command === 'npm-targets') { for (const target of getNpmPublishTargets()) { @@ -55,9 +63,30 @@ if (command === 'npm-targets') { .map((target) => `--filter=${target.name}`) .join(' '), ) +} else if (command === 'released-npm-targets') { + for (const target of getReleasedNpmPublishTargets(args)) { + console.log( + [ + target.name, + path.relative(rootDir, target.path), + npmNoticeReportPath(target.name), + target.releaseTag, + target.version, + ].join('\t'), + ) + } +} else if (command === 'released-npm-pnpm-filters') { + console.log( + getReleasedNpmPublishTargets(args) + .map((target) => `--filter=${target.name}`) + .join(' '), + ) +} else if (command === 'self-check') { + runSelfCheck() + console.log('list-npm-package-targets self-check passed.') } else { fail( - 'Usage: tsx scripts/list-npm-package-targets.ts npm-targets|npm-report-targets|report-target|npm-package-names|npm-pnpm-filters ', + 'Usage: tsx scripts/list-npm-package-targets.ts npm-targets|npm-report-targets|report-target|npm-package-names|npm-pnpm-filters|released-npm-targets|released-npm-pnpm-filters|self-check ', ) } @@ -147,7 +176,22 @@ function readPackageManifest(manifestPath: string): PackageManifest { name: manifest.name, optionalDependencies: readDependencyMap(manifest, 'optionalDependencies', manifestPath), private: manifest.private === true, + version: readPackageVersion(manifest, manifestPath), + } +} + +function readPackageVersion(manifest: Record, manifestPath: string): string { + const { version } = manifest + + if (version === undefined) { + return '0.0.0' + } + + if (typeof version !== 'string') { + fail(`Expected version to be a string in ${manifestPath}`) } + + return version } function readDependencyMap( @@ -230,6 +274,85 @@ function getProductionDependencies(workspacePackage: WorkspacePackage): Array<[s ] } +function getReleasedNpmPublishTargets(releaseTags: string[]): ReleasedNpmPublishTarget[] { + const targetsByName = new Map(getNpmPublishTargets().map((target) => [target.name, target])) + const releasedTargets = new Map() + + for (const releaseTag of releaseTags) { + const release = parseNpmReleaseTag(releaseTag) + + if (release === undefined) { + continue + } + + for (const target of targetsByName.values()) { + if (npmReleaseComponent(target.name) !== release.component) { + continue + } + + releasedTargets.set(target.name, { + ...target, + releaseTag, + version: release.version, + }) + } + } + + return sortNpmPublishTargets([...releasedTargets.values()]) +} + +function parseNpmReleaseTag( + releaseTag: string, +): { component: string; version: string } | undefined { + const match = /^(optimization-[a-z0-9-]+)-v(.+)$/u.exec(releaseTag) + + if (match === null) { + return undefined + } + + const [, component, version] = match + + if (component === undefined || version === undefined) { + return undefined + } + + return { component, version } +} + +function npmReleaseComponent(packageName: string): string { + return packageName.replace(/^@contentful\//u, '') +} + +function sortNpmPublishTargets(targets: ReleasedNpmPublishTarget[]): ReleasedNpmPublishTarget[] { + const targetsByName = new Map(targets.map((target) => [target.name, target])) + const sortedTargets: ReleasedNpmPublishTarget[] = [] + const visited = new Set() + + for (const target of targets) { + visit(target) + } + + return sortedTargets + + function visit(target: ReleasedNpmPublishTarget): void { + if (visited.has(target.name)) { + return + } + + visited.add(target.name) + + for (const [dependencyName, dependencyRange] of getProductionDependencies(target)) { + const dependencyTarget = targetsByName.get(dependencyName) + + if (dependencyTarget !== undefined && dependencyRange.startsWith('workspace:')) { + visit(dependencyTarget) + } + } + + sortedTargets.push(target) + } +} + function findDuplicates(values: string[]): string[] { const seen = new Set() const duplicates = new Set() @@ -245,6 +368,43 @@ function findDuplicates(values: string[]): string[] { return [...duplicates].sort((left, right) => left.localeCompare(right)) } +function runSelfCheck(): void { + const [coreTarget] = getReleasedNpmPublishTargets(['optimization-core-v1.2.3']) + assert.equal(coreTarget?.name, '@contentful/optimization-core') + assert.equal(coreTarget.version, '1.2.3') + + const sortedNames = getReleasedNpmPublishTargets([ + 'optimization-nextjs-v1.2.3', + 'optimization-react-web-v1.2.3', + 'optimization-web-v1.2.3', + 'optimization-node-v1.2.3', + 'optimization-core-v1.2.3', + 'optimization-api-client-v1.2.3', + 'optimization-api-schemas-v1.2.3', + ]).map((target) => target.name) + + assert( + sortedNames.indexOf('@contentful/optimization-api-schemas') < + sortedNames.indexOf('@contentful/optimization-api-client'), + ) + assert( + sortedNames.indexOf('@contentful/optimization-api-client') < + sortedNames.indexOf('@contentful/optimization-core'), + ) + assert( + sortedNames.indexOf('@contentful/optimization-core') < + sortedNames.indexOf('@contentful/optimization-web'), + ) + assert( + sortedNames.indexOf('@contentful/optimization-web') < + sortedNames.indexOf('@contentful/optimization-react-web'), + ) + assert( + sortedNames.indexOf('@contentful/optimization-react-web') < + sortedNames.indexOf('@contentful/optimization-nextjs'), + ) +} + function fail(message: string): never { console.error(message) process.exit(1) diff --git a/scripts/prepare-commit-message.ts b/scripts/prepare-commit-message.ts new file mode 100644 index 000000000..6842dfcc7 --- /dev/null +++ b/scripts/prepare-commit-message.ts @@ -0,0 +1,261 @@ +import { input } from '@commitlint/prompt/lib/input.js' +import InputCustomPrompt from '@commitlint/prompt/lib/inquirer/InputCustomPrompt.js' +import type { Answers, DistinctQuestion, PromptModule, QuestionCollection } from 'inquirer' +import inquirer from 'inquirer' +import assert from 'node:assert/strict' +import { spawnSync } from 'node:child_process' +import { writeFileSync } from 'node:fs' +import type { Key } from 'node:readline' + +const JIRA_BASE_URL = 'https://contentful.atlassian.net/browse' +const JIRA_FOOTER_REGEX = + /^\[\[[A-Z][A-Z0-9]+-\d+\]\(https:\/\/contentful\.atlassian\.net\/browse\/[A-Z][A-Z0-9]+-\d+\)\]$/imu +const JIRA_TICKET_REGEX = /(^|[^A-Z0-9])([A-Z][A-Z0-9]+-\d+)(?=$|[^A-Z0-9])/iu + +async function main(): Promise { + const [commandOrMessagePath] = process.argv.slice(2) + + if (commandOrMessagePath === 'self-check') { + runSelfCheck() + process.stdout.write('prepare-commit-message self-check passed.\n') + return + } + + if (commandOrMessagePath === '--commit') { + ensureStagedChanges() + commit(await readCommitMessage()) + return + } + + if (commandOrMessagePath === undefined) { + fail('Usage: tsx scripts/prepare-commit-message.ts |--commit|self-check') + } + + writeFileSync(commandOrMessagePath, `${await readCommitMessage()}\n`) +} + +async function readCommitMessage(): Promise { + const message = addJiraFooter(await input(promptWithoutFooter), readCurrentBranch()) + + if (message.trim() === '') { + fail('Commit message prompt returned an empty message.') + } + + return message +} + +const promptWithoutFooter = createPromptWithoutFooter() + +function createPromptWithoutFooter(): PromptModule { + const prompt = async ( + questions: QuestionCollection, + initialAnswers?: Partial, + ): Promise => await inquirer.prompt(filterFooterQuestion(questions), initialAnswers) + + const wrappedPrompt = Object.assign(prompt, { + prompts: inquirer.prompt.prompts, + registerPrompt(...args: Parameters) { + const [name, promptConstructor] = args + inquirer.prompt.registerPrompt( + name, + name === 'input-custom' ? SelectableInputPrompt : promptConstructor, + ) + return wrappedPrompt + }, + restoreDefaultPrompts() { + inquirer.prompt.restoreDefaultPrompts() + }, + }) + + return wrappedPrompt +} + +function filterFooterQuestion( + questions: QuestionCollection, +): QuestionCollection { + if (!Array.isArray(questions)) { + return questions + } + + const questionList = questions as ReadonlyArray> + + return questionList.filter((question) => question.name !== 'footer') +} + +interface KeyDescriptor { + key: Key + value: string +} + +interface SelectableInputQuestion extends DistinctQuestion { + tabCompletion?: Array<{ value: string }> +} + +class SelectableInputPrompt extends InputCustomPrompt { + private readonly choices: string[] + private selectedIndex = -1 + + constructor(...args: ConstructorParameters>) { + super(...args) + this.choices = readTabCompletionValues(args[0]) + } + + override onKeyPress2(event: KeyDescriptor): void { + if (event.key.name === 'up') { + this.selectChoice(-1) + return + } + + if (event.key.name === 'down') { + this.selectChoice(1) + return + } + + super.onKeyPress2(event) + } + + override render(error?: string): void { + const answered = this.status === 'answered' + let message = this.getQuestion() + + if (answered) { + message += String(this.answer) + } else { + message += this.rl.line + } + + const bottomContent = (error === undefined ? this.renderChoices() : `>> ${error}`) ?? '' + + this.screen.render(message, bottomContent) + } + + private selectChoice(delta: number): void { + if (this.choices.length === 0) { + return + } + + const lineIndex = this.choices.indexOf(this.rl.line.trim()) + const baseIndex = lineIndex === -1 ? this.selectedIndex : lineIndex + this.selectedIndex = getNextChoiceIndex(baseIndex, delta, this.choices.length) + + const selectedChoice = this.choices.at(this.selectedIndex) + + if (selectedChoice !== undefined) { + const { length } = selectedChoice + this.rl.line = selectedChoice + this.rl.cursor = length + } + + this.render() + } + + private renderChoices(): string | undefined { + if (this.choices.length === 0 || this.status === 'answered') { + return undefined + } + + const lineIndex = this.choices.indexOf(this.rl.line.trim()) + const selectedIndex = lineIndex === -1 ? this.selectedIndex : lineIndex + + return this.choices + .map((choice, index) => `${index === selectedIndex ? '>' : ' '} ${choice}`) + .join('\n') + } +} + +function readTabCompletionValues(question: SelectableInputQuestion): string[] { + return question.tabCompletion?.map((choice) => choice.value) ?? [] +} + +function getNextChoiceIndex(currentIndex: number, delta: number, length: number): number { + if (currentIndex === -1) { + return delta > 0 ? 0 : length - 1 + } + + return wrapIndex(currentIndex + delta, length) +} + +function wrapIndex(index: number, length: number): number { + return ((index % length) + length) % length +} + +function addJiraFooter(message: string, branchName: string | undefined): string { + const ticket = getJiraTicket(branchName) + + if (ticket === undefined || JIRA_FOOTER_REGEX.test(message)) { + return message + } + + return `${message.trimEnd()}\n\n[[${ticket}](${JIRA_BASE_URL}/${ticket})]` +} + +function getJiraTicket(branchName: string | undefined): string | undefined { + const match = branchName?.match(JIRA_TICKET_REGEX) + const [, , ticket] = match ?? [] + return ticket?.toUpperCase() +} + +function readCurrentBranch(): string | undefined { + const result = spawnSync('git', ['branch', '--show-current'], { encoding: 'utf8' }) + + if (result.status !== 0) { + return undefined + } + + return result.stdout.trim() +} + +function ensureStagedChanges(): void { + const result = spawnSync('git', ['diff', '--cached', '--quiet']) + + if (result.status === 0) { + fail('Nothing to commit. Stage your changes via "git add" and run "pnpm commit" again.') + } + + if (result.status !== 1) { + fail('Failed to inspect staged changes.') + } +} + +function commit(message: string): void { + const result = spawnSync('git', ['commit', '-m', message], { stdio: 'inherit' }) + + if (result.error !== undefined) { + fail(result.error.message) + } + + if (result.status !== 0) { + process.exit(result.status ?? 1) + } +} + +function runSelfCheck(): void { + const choiceCount = 3 + + assert.equal(typeof promptWithoutFooter, 'function') + assert.equal(getJiraTicket('NT-3524_semantic-versioning-continuous-deployment'), 'NT-3524') + assert.equal(getJiraTicket('feature/nt-3524-semantic-versioning'), 'NT-3524') + assert.equal(getJiraTicket('semantic-versioning'), undefined) + assert.deepEqual(filterFooterQuestion([{ name: 'type' }, { name: 'footer' }]), [{ name: 'type' }]) + assert.equal(getNextChoiceIndex(-1, 1, choiceCount), 0) + assert.equal(getNextChoiceIndex(-1, -1, choiceCount), choiceCount - 1) + assert.equal(getNextChoiceIndex(choiceCount - 1, 1, choiceCount), 0) + assert.equal( + addJiraFooter('feat(repo): add release flow', 'NT-3524-release'), + `feat(repo): add release flow\n\n[[NT-3524](${JIRA_BASE_URL}/NT-3524)]`, + ) + assert.equal( + addJiraFooter(`feat(repo): add release flow\n\n[[NT-1](${JIRA_BASE_URL}/NT-1)]`, 'NT-3524'), + `feat(repo): add release flow\n\n[[NT-1](${JIRA_BASE_URL}/NT-1)]`, + ) +} + +function fail(message: string): never { + process.stderr.write(`${message}\n`) + process.exit(1) +} + +main().catch((error: unknown) => { + const message = error instanceof Error ? error.message : String(error) + fail(message) +}) diff --git a/scripts/release-please.ts b/scripts/release-please.ts new file mode 100644 index 000000000..cfe184081 --- /dev/null +++ b/scripts/release-please.ts @@ -0,0 +1,334 @@ +import assert from 'node:assert/strict' +import { parseArgs } from 'node:util' +import { + GitHub, + Manifest, + registerPlugin, + type PluginFactoryOptions, + type Strategy, +} from 'release-please' +import { parseConventionalCommits, type Commit } from 'release-please/build/src/commit' +import { ManifestPlugin } from 'release-please/build/src/plugin' +import type { Release } from 'release-please/build/src/release' +import { isRecord } from './typeGuards' + +const DEFAULT_CONFIG_FILE = 'release-please-config.json' +const DEFAULT_MANIFEST_FILE = '.release-please-manifest.json' +const DEFAULT_TARGET_BRANCH = 'main' +const ANDROID_RELEASE_PATH = 'packages/android/ContentfulOptimization' +const SWIFT_RELEASE_PATH = 'packages/ios/ContentfulOptimization' + +const SHARED_RUNTIME_PATHS = [ + 'packages/universal/api-schemas', + 'packages/universal/api-client', + 'packages/universal/core-sdk', + 'packages/universal/optimization-js-bridge', +] as const + +const NATIVE_TARGETS = [ + { path: ANDROID_RELEASE_PATH, scope: 'android' }, + { path: SWIFT_RELEASE_PATH, scope: 'swift' }, +] as const + +const RELEASE_COMMANDS = ['release-pr', 'github-release', 'self-check'] as const +const RELEASABLE_TYPES = new Set(['feat', 'fix', 'perf']) + +type ReleaseCommand = (typeof RELEASE_COMMANDS)[number] +type NativeTarget = (typeof NATIVE_TARGETS)[number] +type ParsedOptions = ReturnType['values'] + +registerPlugin( + 'native-bridge-impact', + (options: PluginFactoryOptions) => new NativeBridgeImpactPlugin(options), +) + +class NativeBridgeImpactPlugin extends ManifestPlugin { + private readonly bootstrapSha: string | undefined + + constructor(options: PluginFactoryOptions) { + super(options.github, options.targetBranch, options.repositoryConfig, options.logger) + this.bootstrapSha = readNativeImpactBootstrapSha(options) + } + + override async preconfigure( + strategiesByPath: Record, + commitsByPath: Record, + _releasesByPath: Record, + ): Promise> { + const configuredNativeTargets = NATIVE_TARGETS.filter( + (target) => this.repositoryConfig[target.path] !== undefined, + ) + + for (const target of configuredNativeTargets) { + if (strategiesByPath[target.path] === undefined) { + continue + } + + const sharedCommits = await this.getSharedRuntimeCommitsSinceLatestNativeRelease( + target, + _releasesByPath, + ) + + if (sharedCommits.length === 0) { + continue + } + + commitsByPath[target.path] = [ + createSyntheticNativeImpactCommit(target, sharedCommits), + ...(commitsByPath[target.path] ?? []), + ] + } + + return strategiesByPath + } + + private async getSharedRuntimeCommitsSinceLatestNativeRelease( + target: NativeTarget, + releasesByPath: Record, + ): Promise { + const releaseSha = releasesByPath[target.path]?.sha + const baseSha = releaseSha === '' ? this.bootstrapSha : (releaseSha ?? this.bootstrapSha) + + if (baseSha === undefined || baseSha === '') { + return [] + } + + const commits = await this.github.commitsSince( + this.targetBranch, + (commit) => commit.sha === baseSha, + { backfillFiles: true }, + ) + + return getReleasableSharedCommits(commits) + } +} + +function readNativeImpactBootstrapSha(options: PluginFactoryOptions): string | undefined { + const { type } = options + + if (!isRecord(type)) { + return undefined + } + + const { bootstrapSha } = type + + if (typeof bootstrapSha === 'string') { + return bootstrapSha + } + + return undefined +} + +async function main(): Promise { + const { values, positionals } = parseReleasePleaseArgs() + const command = readCommand(positionals[0]) + + if (command === 'self-check') { + runSelfCheck() + process.stdout.write('release-please self-check passed.\n') + return + } + + await runReleasePleaseCommand(command, values) +} + +function parseReleasePleaseArgs(): ReturnType { + return parseArgs({ + allowPositionals: true, + options: { + 'config-file': { type: 'string' }, + 'dry-run': { type: 'boolean' }, + 'manifest-file': { type: 'string' }, + 'repo-url': { type: 'string' }, + token: { type: 'string' }, + 'target-branch': { type: 'string' }, + }, + }) +} + +async function runReleasePleaseCommand( + command: ReleaseCommand, + values: ParsedOptions, +): Promise { + const { owner, repo, token } = readGitHubOptions(values) + + const github = await GitHub.create({ owner, repo, token }) + const targetBranch = readStringOption(values, 'target-branch') ?? DEFAULT_TARGET_BRANCH + const manifest = await Manifest.fromManifest( + github, + targetBranch, + readStringOption(values, 'config-file') ?? DEFAULT_CONFIG_FILE, + readStringOption(values, 'manifest-file') ?? DEFAULT_MANIFEST_FILE, + ) + + await runManifestCommand(command, manifest, values['dry-run'] === true) +} + +function readGitHubOptions(values: ParsedOptions): { owner: string; repo: string; token: string } { + const token = + readStringOption(values, 'token') ?? + process.env.RELEASE_PLEASE_TOKEN ?? + process.env.GITHUB_TOKEN + const repoUrl = readStringOption(values, 'repo-url') ?? process.env.GITHUB_REPOSITORY + + if (token === undefined || token === '') { + fail('Set RELEASE_PLEASE_TOKEN or pass --token.') + } + + if (repoUrl === undefined || repoUrl === '') { + fail('Pass --repo-url or set GITHUB_REPOSITORY.') + } + + return { ...parseRepoUrl(repoUrl), token } +} + +function parseRepoUrl(repoUrl: string): { owner: string; repo: string } { + const match = /^([^/]+)\/([^/]+)$/u.exec(repoUrl) + + if (match === null) { + fail(`Expected repo URL in owner/repo form, got ${repoUrl}.`) + } + + const [, owner, repo] = match + + if (owner === undefined || repo === undefined) { + fail(`Expected repo URL in owner/repo form, got ${repoUrl}.`) + } + + return { owner, repo } +} + +function readStringOption(values: ParsedOptions, name: string): string | undefined { + const { [name]: value } = values + + if (typeof value === 'string') { + return value + } + + return undefined +} + +async function runManifestCommand( + command: ReleaseCommand, + manifest: Manifest, + isDryRun: boolean, +): Promise { + if (command === 'release-pr' && isDryRun) { + const pullRequests = await manifest.buildPullRequests() + process.stdout.write(`Would create or update ${pullRequests.length} release PR(s).\n`) + return + } + + if (command === 'release-pr') { + await manifest.createPullRequests() + return + } + + if (isDryRun) { + const releases = await manifest.buildReleases() + process.stdout.write(`Would create ${releases.length} GitHub release(s).\n`) + return + } + + await manifest.createReleases() +} + +function readCommand(command: string | undefined): ReleaseCommand { + const selectedCommand = command ?? 'release-pr' + + if (isReleaseCommand(selectedCommand)) { + return selectedCommand + } + + fail(`Usage: pnpm release:please -- ${RELEASE_COMMANDS.join('|')} [options]`) +} + +function isReleaseCommand(command: string): command is ReleaseCommand { + switch (command) { + case 'release-pr': + case 'github-release': + case 'self-check': + return true + default: + return false + } +} + +function getReleasableSharedCommits(commits: Commit[]): Commit[] { + const commitsBySha = new Map() + + for (const commit of commits) { + if ( + commitsBySha.has(commit.sha) || + !touchesSharedRuntime(commit) || + !isReleasableCommit(commit) + ) { + continue + } + + commitsBySha.set(commit.sha, commit) + } + + return [...commitsBySha.values()] +} + +function touchesSharedRuntime(commit: Commit): boolean { + return ( + commit.files?.some((file) => + SHARED_RUNTIME_PATHS.some( + (sharedPath) => file === sharedPath || file.startsWith(`${sharedPath}/`), + ), + ) ?? false + ) +} + +function isReleasableCommit(commit: Commit): boolean { + return parseConventionalCommits([commit]).some( + (conventionalCommit) => + conventionalCommit.breaking || RELEASABLE_TYPES.has(conventionalCommit.type), + ) +} + +function createSyntheticNativeImpactCommit(target: NativeTarget, sharedCommits: Commit[]): Commit { + const [sourceCommit] = sharedCommits + + assert(sourceCommit !== undefined) + + return { + author: sourceCommit.author, + files: [target.path], + message: `fix(${target.scope}): refresh shared native runtime`, + pullRequest: sourceCommit.pullRequest, + sha: sourceCommit.sha, + } +} + +function runSelfCheck(): void { + const releasableSharedCommit = { + files: ['packages/universal/optimization-js-bridge/src/index.ts'], + message: 'fix(bridge): refresh bridge payload', + sha: 'abc123', + } + const docsOnlyCommit = { + files: ['packages/universal/core-sdk/README.md'], + message: 'docs(core): clarify setup', + sha: 'def456', + } + const sharedCommits = getReleasableSharedCommits([docsOnlyCommit, releasableSharedCommit]) + assert.equal(sharedCommits.length, 1) + + const [androidTarget] = NATIVE_TARGETS + const syntheticCommit = createSyntheticNativeImpactCommit(androidTarget, sharedCommits) + assert.equal(syntheticCommit.message, 'fix(android): refresh shared native runtime') + assert.equal(syntheticCommit.sha, releasableSharedCommit.sha) +} + +function fail(message: string): never { + process.stderr.write(`${message}\n`) + process.exit(1) +} + +main().catch((error: unknown) => { + const message = error instanceof Error ? (error.stack ?? error.message) : String(error) + fail(message) +})