diff --git a/.github/workflows/README.md b/.github/workflows/README.md new file mode 100644 index 000000000..0e6845059 --- /dev/null +++ b/.github/workflows/README.md @@ -0,0 +1,328 @@ +# GitHub Workflows Documentation + +This document explains the CI/CD system for the Asset Tokenization Studio (ATS) monorepo, including development workflow, release processes, and how to work with changesets. + +## Overview + +The repository uses **Changesets** for version management with independent release cycles for: + +- **ATS Project**: Asset Tokenization Studio (contracts, SDK, web app) +- **Mass Payout Project**: Mass payout functionality + +All development happens on the `develop` branch with automated testing, changeset validation, and manual release controls by authorized teams. + +## Developer Workflow + +### Daily Development Process + +```mermaid +sequenceDiagram + participant D as develop + participant F as feature/branch + participant M as main + participant F1 as feature/branch-main + + Note over D,M: Daily Development Pattern + + D->>F: Create feature branch + Note over F: Code changes + changeset + F->>D: PR with changeset (tests + validation) + Note over D: Accumulate features + + D->>F1: Create branch from develop + Note over F1: Same changes (no changeset needed) + F1->>M: PR to main (ready for release) + Note over M: Production-ready code +``` + +### Step-by-Step Guide + +1. **Create feature branch from develop**: + + ```bash + git checkout develop && git pull origin develop + git checkout -b feature/your-feature-name + ``` + +2. **Make your changes** to ATS or Mass Payout packages + +3. **Create changeset** (required for all PRs): + + ```bash + npm run changeset + ``` + + - Select affected packages + - Choose change type (patch/minor/major) + - Write clear description + +4. **Commit with DCO and Signature compliance**: + + ```bash + git add . + git commit --signoff -S -m "feat: your commit message" + git push origin feature/your-feature-name + ``` + +5. **Open PR to develop branch** - automated checks will run + +### Bypass Changeset Validation + +For non-feature changes, add these labels to skip changeset requirement: + +- `no-changeset`: Configuration or documentation changes +- `docs-only`: Documentation-only changes +- `chore`: Build system or dependency updates +- `hotfix`: Emergency fixes + +## Workflow Reference + +### Automated Workflows + +| Workflow | Trigger | Purpose | +| --------------------- | ---------------------------- | ------------------------------------- | +| **ATS Tests** | PR to main, ATS file changes | Run ATS contracts, SDK, and web tests | +| **Mass Payout Tests** | PR to main, MP file changes | Run Mass Payout package tests | +| **Changeset Check** | PR to develop | Validate changeset or bypass labels | + +### Manual Release Workflows + +| Workflow | Purpose | Authorized Teams | +| ----------------------- | ------------------------------------ | ------------------------------------------------------------ | +| **ATS Release** | Version ATS packages, create release | platform-ci, release-engineering-managers, iobuilders-hedera | +| **Mass Payout Release** | Version MP packages, create release | platform-ci, release-engineering-managers, iobuilders-hedera | + +### Automatic Publishing + +| Workflow | Trigger | Purpose | +| ----------------------- | ------------------- | --------------------------- | +| **ATS Publish** | Release tag `*-ats` | Publish ATS packages to npm | +| **Mass Payout Publish** | Release tag `*-mp` | Publish MP packages to npm | + +## Release Process + +The repository supports **two release approaches**: + +1. **Automated Release Workflows** (recommended for most releases) +2. **Manual Release Branches** (alternative for complex releases or when automation is unavailable) + +### Option 1: Automated Release Workflows + +#### ATS Release Flow + +```mermaid +sequenceDiagram + participant Dev as Developer + participant M as main + participant GH as GitHub Actions + participant NPM as NPM Registry + + Dev->>GH: Trigger ATS Release Workflow + GH->>GH: Validate ATS changesets exist + GH->>M: Run changeset version --ignore MP + GH->>M: Commit version changes to main + GH->>M: Create tag v1.16.0-ats + GH->>GH: Create GitHub release + GH->>NPM: Auto-trigger publish workflow + NPM->>NPM: Publish contracts & SDK +``` + +#### Mass Payout Release Flow + +```mermaid +sequenceDiagram + participant Dev as Developer + participant M as main + participant GH as GitHub Actions + participant NPM as NPM Registry + + Dev->>GH: Trigger MP Release Workflow + GH->>GH: Validate MP changesets exist + GH->>M: Run changeset version --ignore ATS + GH->>M: Commit version changes to main + GH->>M: Create tag v2.4.0-mp + GH->>GH: Create GitHub release + GH->>NPM: Auto-trigger publish workflow + NPM->>NPM: Publish MP packages +``` + +#### Release Options + +Both automated workflows support: + +- **Preview Mode**: Shows what would be released (dry-run) +- **Release Mode**: Actually creates releases and triggers publishing + +### Option 2: Manual Release Branches + +For complex releases or when automation is unavailable, you can use the traditional manual release branch approach: + +```mermaid +sequenceDiagram + participant M as main + participant D as develop + participant F as feat/example + participant F1 as feat/example-main + participant R as release/v1.22.2-ats + + Note over M,D: Initial state + + loop for each feature in sprint + D->>F: Create feature branch + Note over F: Feature development + changeset + F->>D: Merge PR with changeset + + D->>F1: Create branch from develop + F1->>M: Merge PR directly to main + end + + M->>R: Create release branch + Note over R: Run: npx changeset version + Note over R: Generate changelogs + version bump + R->>M: Merge version commit to main + + Note over M: Create tag v1.22.2-ats + Note over M: Manual GitHub release + Note over M: Automatic NPM publish via workflow + + M->>D: Merge main back to develop +``` + +#### Manual Release Steps + +1. **Create release branch from main**: + + ```bash + git checkout main && git pull origin main + git checkout -b release/v1.22.2-ats + ``` + +2. **Apply changesets and version packages**: + + ```bash + # For ATS release + npx changeset version --ignore "@hashgraph/mass-payout*" + + # For Mass Payout release + npx changeset version --ignore "@hashgraph/asset-tokenization-*" + ``` + +3. **Commit version changes**: + + ```bash + git add . + git commit --signoff -S -m "chore: release v1.22.2-ats" + git push origin release/v1.22.2-ats + ``` + +4. **Merge release branch to main**: + - Create PR from `release/v1.22.2-ats` to `main` + - Review and merge the version changes + +5. **Create GitHub release**: + - Create tag `v1.22.2-ats` on main branch + - Create GitHub release with generated changelog + - Publishing workflows trigger automatically + +6. **Sync main back to develop**: + ```bash + git checkout develop + git merge main + git push origin develop + ``` + +**Benefits of Manual Release Branches**: + +- ✅ Full control over version timing and content +- ✅ Ability to make additional changes during release process +- ✅ Works with existing automated publishing workflows +- ✅ Suitable for complex releases requiring manual intervention + +### Release Authorization + +Only these teams can trigger releases: + +- `platform-ci` +- `platform-ci-committers` +- `release-engineering-managers` +- `developer-advocates` +- `iobuilders-hedera` +- Users containing `hashgraph` + +## Workflow Interactions + +```mermaid +sequenceDiagram + participant D as develop + participant M as main + participant GH as GitHub Actions + participant NPM as NPM Registry + + Note over D,M: Workflow Overview + + loop Feature Development + Note over D: Features merge to develop + Note over D: Changesets accumulate + D->>M: Feature PRs to main + end + + Note over M: Ready for release + M->>GH: Manual release trigger + GH->>M: Version packages + create tag + GH->>GH: Create GitHub release + GH->>NPM: Auto-trigger publish + NPM->>NPM: Publish to NPM + + M->>D: Sync version changes back +``` + +## Troubleshooting + +### Common Issues + +**❌ Changeset check failed** + +- **Solution**: Create changeset with `npm run changeset` or add bypass label + +**❌ "No changesets found to be bumped"** + +- **Solution**: Ensure changesets exist for the project you're releasing +- Use `npm run changeset:status` to check pending changes + +**❌ Release workflow unauthorized** + +- **Solution**: Ensure you're member of authorized teams listed in CODEOWNERS + +**❌ Tests failing on PR** + +- **Solution**: Run `npm run ats:test` or `npm run mass-payout:test` locally +- Fix failing tests before requesting review + +**❌ DCO check failed** + +- **Solution**: Ensure all commits use `--signoff` flag: + ```bash + git commit --signoff -S -m "your message" + ``` + +### Getting Help + +- **Changesets documentation**: [Changesets Intro](https://github.com/changesets/changesets/blob/main/docs/intro-to-using-changesets.md) +- **Check pending releases**: `npm run changeset:status` +- **Preview releases**: `npm run release:preview` +- **Local development**: See `CLAUDE.md` for complete development setup + +## Quick Commands + +```bash +# Development +npm run changeset # Create changeset +npm run changeset:status # Check pending changes +npm run ats:test # Run ATS tests +npm run mass-payout:test # Run MP tests + +# Preview releases +npm run release:preview # Show all pending releases +npm run release:ats # Preview ATS release (local) +npm run release:mp # Preview MP release (local) +``` diff --git a/.github/workflows/ats.publish.yml b/.github/workflows/ats.publish.yml index faf929855..a9919e406 100644 --- a/.github/workflows/ats.publish.yml +++ b/.github/workflows/ats.publish.yml @@ -9,6 +9,11 @@ on: required: false type: boolean default: false + ref: + description: 'Branch/tag/commit to publish from' + required: false + type: string + default: 'main' # Release published trigger (GitHub release creation) - only for ATS releases (tags ending with -ats) release: @@ -27,8 +32,11 @@ jobs: contracts: name: Publish ATS Contracts runs-on: token-studio-linux-large - # Only run if manual trigger OR release tag contains '-ats-'/'-ATS-' - if: ${{ github.event_name == 'workflow_dispatch' || contains(github.ref_name, '-ats-') || contains(github.ref_name, '-ATS-') }} + # Only run if manual trigger OR release tag contains/ends with '-ats'/'-ATS' + if: ${{ github.event_name == 'workflow_dispatch' || contains(github.ref_name, '-ats-') || contains(github.ref_name, '-ATS-') || endsWith(github.ref_name, '-ats') || endsWith(github.ref_name, '-ATS') }} + permissions: + contents: read + id-token: write steps: - name: Harden Runner @@ -39,17 +47,18 @@ jobs: - name: Checkout repository uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: - ref: ${{ github.ref }} + ref: ${{ inputs.ref || github.ref }} fetch-depth: 0 - name: Setup NodeJS Environment uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: - node-version: 22.20.0 + node-version: 22.x registry-url: https://registry.npmjs.org - name: Create .npmrc file - working-directory: packages/ats/contracts + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} run: | cat << 'EOF' > .npmrc //registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN} @@ -65,26 +74,28 @@ jobs: env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} DRY_RUN: ${{ inputs.dry-run-enabled }} - working-directory: packages/ats/contracts run: | - PUBLISH_ARGS=("--access=restricted") + echo "DRY_RUN is set to: '${DRY_RUN}'" + + cd packages/ats/contracts + + PUBLISH_ARGS=("--access=public") if [[ "${DRY_RUN}" == "true" ]]; then PUBLISH_ARGS+=("--dry-run") echo "🔍 DRY RUN MODE: Would publish @hashgraph/asset-tokenization-contracts" fi - if ! npm publish "${PUBLISH_ARGS[@]}"; then - echo "❌ Failed to publish package: ${package_name}" - echo "📋 Package info:" && cat package.json | jq '.name, .version' - exit 1 - fi + npm publish "${PUBLISH_ARGS[@]}" sdk: name: Publish ATS SDK runs-on: token-studio-linux-large - # Only run if manual trigger OR release tag contains '-ats-'/'-ATS-' - if: ${{ github.event_name == 'workflow_dispatch' || contains(github.ref_name, '-ats-') || contains(github.ref_name, '-ATS-') }} + # Only run if manual trigger OR release tag contains/ends with '-ats'/'-ATS' + if: ${{ github.event_name == 'workflow_dispatch' || contains(github.ref_name, '-ats-') || contains(github.ref_name, '-ATS-') || endsWith(github.ref_name, '-ats') || endsWith(github.ref_name, '-ATS') }} # needs: contracts # Commented out for parallel execution + permissions: + contents: read + id-token: write steps: - name: Harden Runner @@ -95,17 +106,18 @@ jobs: - name: Checkout repository uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: - ref: ${{ github.ref }} + ref: ${{ inputs.ref || github.ref }} fetch-depth: 0 - name: Setup NodeJS Environment uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: - node-version: 22.20.0 + node-version: 22.x registry-url: https://registry.npmjs.org - name: Create .npmrc file - working-directory: packages/ats/sdk + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} run: | cat << 'EOF' > .npmrc //registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN} @@ -123,28 +135,25 @@ jobs: env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} DRY_RUN: ${{ inputs.dry-run-enabled }} - working-directory: packages/ats/sdk run: | - PUBLISH_ARGS=("--access=restricted") + echo "DRY_RUN is set to: '${DRY_RUN}'" + + cd packages/ats/sdk + + PUBLISH_ARGS=("--access=public") if [[ "${DRY_RUN}" == "true" ]]; then PUBLISH_ARGS+=("--dry-run") echo "🔍 DRY RUN MODE: Would publish @hashgraph/asset-tokenization-sdk" fi - if ! npm publish "${PUBLISH_ARGS[@]}"; then - echo "❌ Failed to publish package: ${package_name}" - echo "📋 Package info:" && cat package.json | jq '.name, .version' - exit 1 - fi + npm publish "${PUBLISH_ARGS[@]}" # Summary job to report results summary: name: Publish Summary runs-on: token-studio-linux-large - needs: - - contracts - - sdk - if: ${{ always() }} + needs: [contracts, sdk] + if: always() steps: - name: Harden the runner (Audit all outbound calls) uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1 @@ -153,13 +162,13 @@ jobs: - name: Report Results run: | - echo "## ATS Publish Results" >> "${GITHUB_STEP_SUMMARY}" - echo "| Package | Status |" >> "${GITHUB_STEP_SUMMARY}" - echo "| --- | --- |" >> "${GITHUB_STEP_SUMMARY}" - echo "| Contracts | ${{ needs.contracts.result }} |" >> "${GITHUB_STEP_SUMMARY}" - echo "| SDK | ${{ needs.sdk.result }} |" >> "${GITHUB_STEP_SUMMARY}" + echo "## ATS Publish Results" >> $GITHUB_STEP_SUMMARY + echo "| Package | Status |" >> $GITHUB_STEP_SUMMARY + echo "| --- | --- |" >> $GITHUB_STEP_SUMMARY + echo "| Contracts | ${{ needs.contracts.result }} |" >> $GITHUB_STEP_SUMMARY + echo "| SDK | ${{ needs.sdk.result }} |" >> $GITHUB_STEP_SUMMARY if [[ "${{ inputs.dry-run-enabled }}" == "true" ]]; then - echo "" >> "${GITHUB_STEP_SUMMARY}" - echo "🔍 **DRY RUN MODE** - No packages were actually published" >> "${GITHUB_STEP_SUMMARY}" + echo "" >> $GITHUB_STEP_SUMMARY + echo "🔍 **DRY RUN MODE** - No packages were actually published" >> $GITHUB_STEP_SUMMARY fi diff --git a/.github/workflows/ats.release.yml b/.github/workflows/ats.release.yml index 19ef010ee..bcc1d7548 100644 --- a/.github/workflows/ats.release.yml +++ b/.github/workflows/ats.release.yml @@ -25,6 +25,13 @@ jobs: ats-release: name: Create ATS Release runs-on: token-studio-linux-large + # Only allow authorized teams to trigger releases per CODEOWNERS + if: > + github.event_name == 'workflow_dispatch' && ( + contains(fromJSON('["platform-ci", "platform-ci-committers", "release-engineering-managers", "developer-advocates", "iobuilders-hedera"]'), + github.actor) || + contains(github.actor, 'hashgraph') + ) steps: - name: Harden Runner @@ -42,7 +49,7 @@ jobs: - name: Setup NodeJS Environment uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: - node-version: v22.20.0 + node-version: 22.x - name: Install dependencies run: npm ci @@ -50,27 +57,30 @@ jobs: - name: Validate ATS changesets exist id: validate run: | + # Use changeset status with JSON output to detect ATS packages with changes echo "📋 Getting changeset status..." npx changeset status --output=changeset-status.json + # Parse JSON to check if ATS packages have pending changes ATS_PACKAGES_TO_BUMP=$(jq -r '.releases[] | select(.name | test("@hashgraph/asset-tokenization-")) | .name' changeset-status.json | wc -l) - echo "ats-packages-to-bump=${ATS_PACKAGES_TO_BUMP}" >> "${GITHUB_OUTPUT}" + echo "ats-packages-to-bump=$ATS_PACKAGES_TO_BUMP" >> $GITHUB_OUTPUT - if [ "${ATS_PACKAGES_TO_BUMP}" -eq 0 ]; then + if [ "$ATS_PACKAGES_TO_BUMP" -eq 0 ]; then echo "❌ No ATS packages found to be bumped" echo "📋 Current changeset status:" npx changeset status exit 1 fi - echo "✅ Found ${ATS_PACKAGES_TO_BUMP} ATS package(s) ready for release" + echo "✅ Found $ATS_PACKAGES_TO_BUMP ATS package(s) ready for release" + # Show which packages will be bumped echo "📦 ATS packages to be released:" jq -r '.releases[] | select(.name | test("@hashgraph/asset-tokenization-")) | " - \(.name) (\(.oldVersion) → \(.newVersion))"' changeset-status.json - name: Preview ATS release - if: ${{ inputs.release-type == 'preview' }} + if: inputs.release-type == 'preview' run: | echo "🔍 PREVIEW MODE - What would be released for ATS packages:" echo "" @@ -83,12 +93,14 @@ jobs: echo "To proceed with actual release, run this workflow with 'release' option." - name: Version ATS packages - if: ${{ inputs.release-type == 'release' }} + if: inputs.release-type == 'release' run: | echo "🚀 Releasing ATS packages only (ignoring Mass Payout packages)" + # Run changeset version with ignore flag for Mass Payout packages npx changeset version --ignore "@hashgraph/mass-payout*" + # Check if any files were changed if [[ -n "$(git status --porcelain)" ]]; then echo "✅ Version bump completed for ATS packages" else @@ -97,59 +109,76 @@ jobs: fi - name: Commit version changes - if: ${{ inputs.release-type == 'release' }} + if: inputs.release-type == 'release' run: | + # GitHub Actions bot automatically handles git config for branch protection bypass + # When using GITHUB_TOKEN, GitHub automatically configures the correct identity + + # Add all changed files git add . - if git commit --signoff -S -m "chore: release ATS packages"; then + # Commit with DCO sign-off using GitHub Actions bot identity + if git commit --signoff -m "chore: release ATS packages"; then echo "✅ Version changes committed" else echo "ℹ️ No changes to commit" fi - name: Create ATS release - id: create-release-tag - if: ${{ inputs.release-type == 'release' }} - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + if: inputs.release-type == 'release' run: | + # Get the current ATS version (all ATS packages use fixed versioning) ATS_VERSION=$(node -p "require('./packages/ats/contracts/package.json').version") TAG_NAME="v${ATS_VERSION}-ats" - echo "📦 Creating ATS release tag: ${TAG_NAME}" + + echo "📦 Creating ATS release: $TAG_NAME" + + # Create and push tag git tag "${TAG_NAME}" git push origin "${TAG_NAME}" - echo "tag-name=${TAG_NAME}" >> "${GITHUB_OUTPUT}" - - - name: Create github release - if: ${{ inputs.release-type == 'release' }} - uses: step-security/release-action@03a57407052f15d1537fd5469a6fbbc536aba326 # v1.20.0 - with: - tag: ${{ steps.create-release-tag.outputs.tag-name }} - prerelease: false - draft: false - generateReleaseNotes: true - skipIfReleaseExists: true + # Generate release notes from ATS package changelogs + RELEASE_NOTES="" + for package in contracts sdk; do + CHANGELOG_FILE="packages/ats/${package}/CHANGELOG.md" + if [ -f "$CHANGELOG_FILE" ]; then + echo "📋 Including changelog from $package" + RELEASE_NOTES="$RELEASE_NOTES\n\n## @hashgraph/asset-tokenization-${package}\n" + # Get the latest version section from changelog + sed -n "/^## $ATS_VERSION/,/^## /p" "$CHANGELOG_FILE" | head -n -1 >> release-notes.md + fi + done + + # Create GitHub release + gh release create "$TAG_NAME" \ + --title "ATS Release v${ATS_VERSION}" \ + --notes-file release-notes.md \ + --target main + + echo "✅ GitHub release created: $TAG_NAME" + echo "🔗 Release URL: https://github.com/${{ github.repository }}/releases/tag/$TAG_NAME" + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Release Summary if: always() run: | if [ "${{ inputs.release-type }}" = "preview" ]; then - echo "## 🔍 ATS Release Preview Completed" >> "${GITHUB_STEP_SUMMARY}" - echo "Preview mode was selected. No actual release was created." >> "${GITHUB_STEP_SUMMARY}" + echo "## 🔍 ATS Release Preview Completed" >> $GITHUB_STEP_SUMMARY + echo "Preview mode was selected. No actual release was created." >> $GITHUB_STEP_SUMMARY elif [ "${{ job.status }}" = "success" ]; then ATS_VERSION=$(node -p "require('./packages/ats/contracts/package.json').version" 2>/dev/null || echo "unknown") - echo "## ✅ ATS Release v${ATS_VERSION} Completed Successfully" >> "${GITHUB_STEP_SUMMARY}" - echo "| Package | Status |" >> "${GITHUB_STEP_SUMMARY}" - echo "| --- | --- |" >> "${GITHUB_STEP_SUMMARY}" - echo "| ATS Contracts | ✅ Released |" >> "${GITHUB_STEP_SUMMARY}" - echo "| ATS SDK | ✅ Released |" >> "${GITHUB_STEP_SUMMARY}" - echo "| GitHub Release | ✅ Created |" >> "${GITHUB_STEP_SUMMARY}" - echo "" >> "${GITHUB_STEP_SUMMARY}" - echo "**Next Steps:**" >> "${GITHUB_STEP_SUMMARY}" - echo "- NPM publishing will be triggered automatically via ats.publish.yml" >> "${GITHUB_STEP_SUMMARY}" - echo "- Mass Payout packages were ignored and remain available for separate release" >> "${GITHUB_STEP_SUMMARY}" + echo "## ✅ ATS Release v${ATS_VERSION} Completed Successfully" >> $GITHUB_STEP_SUMMARY + echo "| Package | Status |" >> $GITHUB_STEP_SUMMARY + echo "| --- | --- |" >> $GITHUB_STEP_SUMMARY + echo "| ATS Contracts | ✅ Released |" >> $GITHUB_STEP_SUMMARY + echo "| ATS SDK | ✅ Released |" >> $GITHUB_STEP_SUMMARY + echo "| GitHub Release | ✅ Created |" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Next Steps:**" >> $GITHUB_STEP_SUMMARY + echo "- NPM publishing will be triggered automatically via ats.publish.yml" >> $GITHUB_STEP_SUMMARY + echo "- Mass Payout packages were ignored and remain available for separate release" >> $GITHUB_STEP_SUMMARY else - echo "## ❌ ATS Release Failed" >> "${GITHUB_STEP_SUMMARY}" - echo "Check the logs above for details on what went wrong." >> "${GITHUB_STEP_SUMMARY}" + echo "## ❌ ATS Release Failed" >> $GITHUB_STEP_SUMMARY + echo "Check the logs above for details on what went wrong." >> $GITHUB_STEP_SUMMARY fi diff --git a/.github/workflows/ats.test.yml b/.github/workflows/ats.test.yml index 5a3c7cdac..97e46c02b 100644 --- a/.github/workflows/ats.test.yml +++ b/.github/workflows/ats.test.yml @@ -59,7 +59,7 @@ jobs: - name: Setup NodeJS Environment uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: - node-version: 22.20.0 + node-version: 22.x - name: Install dependencies run: npm ci diff --git a/.github/workflows/changeset-check.yml b/.github/workflows/changeset-check.yml index b50461362..667a68980 100644 --- a/.github/workflows/changeset-check.yml +++ b/.github/workflows/changeset-check.yml @@ -35,50 +35,54 @@ jobs: - name: Fetch develop branch run: | + # Ensure we have the develop branch for changesets comparison git fetch origin develop:develop || git fetch origin main:develop || true git branch -a - name: Setup NodeJS Environment uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: - node-version: 22.20.0 + node-version: 22.x - name: Check for bypass labels id: bypass - env: - GH_TOKEN: ${{ github.token }} run: | + # Check if PR has bypass labels LABELS=$(gh pr view ${{ github.event.number }} --json labels --jq '.labels[].name' || echo "") - if echo "${LABELS}" | grep -E "(no-changeset|docs-only|hotfix|chore)" > /dev/null; then - echo "bypass=true" >> "${GITHUB_OUTPUT}" + + if echo "$LABELS" | grep -E "(no-changeset|docs-only|hotfix|chore)" > /dev/null; then + echo "bypass=true" >> $GITHUB_OUTPUT echo "✅ Found bypass label. Skipping changeset check." else - echo "bypass=false" >> "${GITHUB_OUTPUT}" + echo "bypass=false" >> $GITHUB_OUTPUT echo "🔍 No bypass labels found. Changeset check required." fi + env: + GH_TOKEN: ${{ github.token }} - name: Install dependencies - if: ${{ steps.bypass.outputs.bypass == 'false' }} + if: steps.bypass.outputs.bypass == 'false' run: npm ci - name: Check changeset status - if: ${{ steps.bypass.outputs.bypass == 'false' }} + if: steps.bypass.outputs.bypass == 'false' run: | echo "🔍 Checking for NEW changesets in this PR..." + # Get changeset files that are NEW in this PR (not in develop) NEW_CHANGESETS=$(git diff develop...HEAD --name-only --diff-filter=A | grep "^\.changeset/.*\.md$" | grep -v "README.md" || true) - NEW_CHANGESET_COUNT=$(echo "${NEW_CHANGESETS}" | grep -c "\.md$" || echo "0") + NEW_CHANGESET_COUNT=$(echo "$NEW_CHANGESETS" | grep -c "\.md$" || echo "0") echo "Files changed in PR:" git diff develop...HEAD --name-only --diff-filter=A | head -10 echo "" - echo "NEW changeset files in this PR: ${NEW_CHANGESET_COUNT}" - if [ -n "${NEW_CHANGESETS}" ]; then + echo "NEW changeset files in this PR: $NEW_CHANGESET_COUNT" + if [ -n "$NEW_CHANGESETS" ]; then echo "Found NEW changesets:" - echo "${NEW_CHANGESETS}" + echo "$NEW_CHANGESETS" fi - if [[ "${NEW_CHANGESET_COUNT}" -gt 0 ]]; then + if [ "$NEW_CHANGESET_COUNT" -gt 0 ]; then echo "✅ Changeset validation passed - found NEW changeset files in PR" else echo "" @@ -106,7 +110,7 @@ jobs: fi - name: Success summary - if: ${{ always() }} + if: always() run: | if [ "${{ steps.bypass.outputs.bypass }}" = "true" ]; then echo "✅ Changeset check bypassed due to label" diff --git a/.github/workflows/mp.publish.yml b/.github/workflows/mp.publish.yml index bbda2fc8d..1b9b0145b 100644 --- a/.github/workflows/mp.publish.yml +++ b/.github/workflows/mp.publish.yml @@ -9,6 +9,11 @@ on: required: false type: boolean default: false + ref: + description: 'Branch/tag/commit to publish from' + required: false + type: string + default: 'main' # Release published trigger (GitHub release creation) - only for Mass Payout releases (tags ending with -mp) release: @@ -28,7 +33,10 @@ jobs: name: Publish Mass Payout Packages runs-on: token-studio-linux-large # Only run if manual trigger OR release tag contains 'mp' - if: ${{ github.event_name == 'workflow_dispatch' || contains(github.ref_name, '-mp') }} + if: github.event_name == 'workflow_dispatch' || contains(github.ref_name, '-mp') + permissions: + contents: read + id-token: write steps: - name: Harden Runner @@ -39,16 +47,18 @@ jobs: - name: Checkout repository uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: - ref: ${{ github.ref }} + ref: ${{ inputs.ref || github.ref }} fetch-depth: 0 - name: Setup NodeJS Environment uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: - node-version: 22.20.0 + node-version: 22.x registry-url: https://registry.npmjs.org - name: Create .npmrc file + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} run: | cat << 'EOF' > .npmrc //registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN} @@ -57,9 +67,6 @@ jobs: - name: Install dependencies run: npm ci - - name: Install NestJS CLI globally - run: npm install -g @nestjs/cli - - name: Build Mass Payout packages run: npm run mass-payout:build @@ -68,13 +75,17 @@ jobs: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} DRY_RUN: ${{ inputs.dry-run-enabled }} run: | + echo "DRY_RUN is set to: '${DRY_RUN}'" + + # Find and publish all Mass Payout packages for package_dir in packages/mass-payout/*/; do - if [ -d "${package_dir}" ] && [ -f "${package_dir}package.json" ]; then - package_name=$(basename "${package_dir}") - echo "📦 Processing Mass Payout package: ${package_name}" + if [ -d "$package_dir" ] && [ -f "${package_dir}package.json" ]; then + package_name=$(basename "$package_dir") + echo "📦 Processing Mass Payout package: $package_name" - cd "${package_dir}" + cd "$package_dir" + # Check if package is publishable (not private) if ! node -p "require('./package.json').private || false" | grep -q "true"; then PUBLISH_ARGS=("--access=restricted") if [[ "${DRY_RUN}" == "true" ]]; then @@ -82,13 +93,9 @@ jobs: echo "🔍 DRY RUN MODE: Would publish @hashgraph/mass-payout-${package_name}" fi - if ! npm publish "${PUBLISH_ARGS[@]}"; then - echo "❌ Failed to publish package: ${package_name}" - echo "📋 Package info:" && cat package.json | jq '.name, .version' - exit 1 - fi + npm publish "${PUBLISH_ARGS[@]}" else - echo "⏭️ Skipping private package: ${package_name}" + echo "⏭️ Skipping private package: $package_name" fi cd - > /dev/null @@ -99,9 +106,8 @@ jobs: summary: name: Publish Summary runs-on: token-studio-linux-large - needs: - - mass-payout - if: ${{ always() }} + needs: [mass-payout] + if: always() steps: - name: Harden the runner (Audit all outbound calls) uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1 @@ -110,12 +116,12 @@ jobs: - name: Report Results run: | - echo "## Mass Payout Publish Results" >> "${GITHUB_STEP_SUMMARY}" - echo "| Package Type | Status |" >> "${GITHUB_STEP_SUMMARY}" - echo "| --- | --- |" >> "${GITHUB_STEP_SUMMARY}" - echo "| Mass Payout | ${{ needs.mass-payout.result }} |" >> "${GITHUB_STEP_SUMMARY}" + echo "## Mass Payout Publish Results" >> $GITHUB_STEP_SUMMARY + echo "| Package Type | Status |" >> $GITHUB_STEP_SUMMARY + echo "| --- | --- |" >> $GITHUB_STEP_SUMMARY + echo "| Mass Payout | ${{ needs.mass-payout.result }} |" >> $GITHUB_STEP_SUMMARY if [[ "${{ inputs.dry-run-enabled }}" == "true" ]]; then - echo "" >> "${GITHUB_STEP_SUMMARY}" - echo "🔍 **DRY RUN MODE** - No packages were actually published" >> "${GITHUB_STEP_SUMMARY}" + echo "" >> $GITHUB_STEP_SUMMARY + echo "🔍 **DRY RUN MODE** - No packages were actually published" >> $GITHUB_STEP_SUMMARY fi diff --git a/.github/workflows/mp.release.yml b/.github/workflows/mp.release.yml index 78942e87d..01c0141a5 100644 --- a/.github/workflows/mp.release.yml +++ b/.github/workflows/mp.release.yml @@ -25,6 +25,13 @@ jobs: mp-release: name: Create Mass Payout Release runs-on: token-studio-linux-large + # Only allow authorized teams to trigger releases per CODEOWNERS + if: > + github.event_name == 'workflow_dispatch' && ( + contains(fromJSON('["platform-ci", "platform-ci-committers", "release-engineering-managers", "developer-advocates", "iobuilders-hedera"]'), + github.actor) || + contains(github.actor, 'hashgraph') + ) steps: - name: Harden Runner @@ -42,7 +49,7 @@ jobs: - name: Setup NodeJS Environment uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: - node-version: 22.20.0 + node-version: 22.x - name: Install dependencies run: npm ci @@ -50,14 +57,16 @@ jobs: - name: Validate Mass Payout changesets exist id: validate run: | + # Use changeset status with JSON output to detect Mass Payout packages with changes echo "📋 Getting changeset status..." npx changeset status --output=changeset-status.json + # Parse JSON to check if Mass Payout packages have pending changes MP_PACKAGES_TO_BUMP=$(jq -r '.releases[] | select(.name | test("@hashgraph/mass-payout")) | .name' changeset-status.json | wc -l) - echo "mp-packages-to-bump=${MP_PACKAGES_TO_BUMP}" >> "${GITHUB_OUTPUT}" + echo "mp-packages-to-bump=$MP_PACKAGES_TO_BUMP" >> $GITHUB_OUTPUT - if [ "${MP_PACKAGES_TO_BUMP}" -eq 0 ]; then + if [ "$MP_PACKAGES_TO_BUMP" -eq 0 ]; then echo "❌ No Mass Payout packages found to be bumped" echo "📋 Current changeset status:" npx changeset status @@ -66,11 +75,12 @@ jobs: echo "✅ Found ${MP_PACKAGES_TO_BUMP} Mass Payout package(s) ready for release" + # Show which packages will be bumped echo "📦 Mass Payout packages to be released:" jq -r '.releases[] | select(.name | test("@hashgraph/mass-payout")) | " - \(.name) (\(.oldVersion) → \(.newVersion))"' changeset-status.json - name: Preview Mass Payout release - if: ${{ inputs.release-type == 'preview' }} + if: inputs.release-type == 'preview' run: | echo "🔍 PREVIEW MODE - What would be released for Mass Payout packages:" echo "" @@ -83,12 +93,14 @@ jobs: echo "To proceed with actual release, run this workflow with 'release' option." - name: Version Mass Payout packages - if: ${{ inputs.release-type == 'release' }} + if: inputs.release-type == 'release' run: | echo "🚀 Releasing Mass Payout packages only (ignoring ATS packages)" + # Run changeset version with ignore flag for ATS packages npx changeset version --ignore "@hashgraph/asset-tokenization-*" + # Check if any files were changed if [[ -n "$(git status --porcelain)" ]]; then echo "✅ Version bump completed for Mass Payout packages" else @@ -97,58 +109,85 @@ jobs: fi - name: Commit version changes - if: ${{ inputs.release-type == 'release' }} + if: inputs.release-type == 'release' run: | + # GitHub Actions bot automatically handles git config for branch protection bypass + # When using GITHUB_TOKEN, GitHub automatically configures the correct identity + + # Add all changed files git add . - if git commit --signoff -S -m "chore: release Mass Payout packages"; then + # Commit with DCO sign-off using GitHub Actions bot identity + if git commit --signoff -m "chore: release Mass Payout packages"; then echo "✅ Version changes committed" else echo "ℹ️ No changes to commit" fi - name: Create Mass Payout release - id: create-mp-release-tag - if: ${{ inputs.release-type == 'release' }} - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + if: inputs.release-type == 'release' run: | + # Get the current Mass Payout version MP_VERSION=$(node -p "require('./packages/mass-payout/core/package.json').version" 2>/dev/null || echo "1.0.0") TAG_NAME="v${MP_VERSION}-mp" - echo "📦 Creating Mass Payout release: ${TAG_NAME}" - git tag -s -a "${TAG_NAME}" -m "Creating Mass Payout Release with tag: ${TAG_NAME}" + + echo "📦 Creating Mass Payout release: $TAG_NAME" + + # Create and push tag + git tag "${TAG_NAME}" git push origin "${TAG_NAME}" - echo "release-tag=${TAG_NAME}" >> "${GITHUB_OUTPUT}" + # Generate release notes from Mass Payout package changelogs + RELEASE_NOTES="" + for package_dir in packages/mass-payout/*/; do + if [ -d "$package_dir" ]; then + package_name=$(basename "$package_dir") + CHANGELOG_FILE="${package_dir}CHANGELOG.md" + if [ -f "$CHANGELOG_FILE" ]; then + echo "📋 Including changelog from $package_name" + RELEASE_NOTES="$RELEASE_NOTES\n\n## @hashgraph/mass-payout-${package_name}\n" + # Get the latest version section from changelog + sed -n "/^## $MP_VERSION/,/^## /p" "$CHANGELOG_FILE" | head -n -1 >> release-notes.md + fi + fi + done + + # If no specific changelog found, create a basic release note + if [ ! -f release-notes.md ] || [ ! -s release-notes.md ]; then + echo "Mass Payout release v${MP_VERSION}" > release-notes.md + echo "" >> release-notes.md + echo "See individual package changelogs for detailed changes." >> release-notes.md + fi - - name: Create github release - if: ${{ inputs.release-type == 'release' }} - uses: step-security/release-action@03a57407052f15d1537fd5469a6fbbc536aba326 # v1.20.0 - with: - tag: ${{ steps.create-mp-release-tag.outputs.release-tag }} - prerelease: false - draft: false - generateReleaseNotes: true - skipIfReleaseExists: true + # Create GitHub release + gh release create "$TAG_NAME" \ + --title "Mass Payout Release v${MP_VERSION}" \ + --notes-file release-notes.md \ + --target main + + echo "✅ GitHub release created: $TAG_NAME" + echo "🔗 Release URL: https://github.com/${{ github.repository }}/releases/tag/$TAG_NAME" + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Release Summary - if: ${{ always() }} + if: always() run: | if [ "${{ inputs.release-type }}" = "preview" ]; then - echo "## 🔍 Mass Payout Release Preview Completed" >> "${GITHUB_STEP_SUMMARY}" - echo "Preview mode was selected. No actual release was created." >> "${GITHUB_STEP_SUMMARY}" + echo "## 🔍 Mass Payout Release Preview Completed" >> $GITHUB_STEP_SUMMARY + echo "Preview mode was selected. No actual release was created." >> $GITHUB_STEP_SUMMARY elif [ "${{ job.status }}" = "success" ]; then MP_VERSION=$(node -p "require('./packages/mass-payout/core/package.json').version" 2>/dev/null || echo "unknown") - echo "## ✅ Mass Payout Release v${MP_VERSION} Completed Successfully" >> "${GITHUB_STEP_SUMMARY}" - echo "| Package | Status |" >> "${GITHUB_STEP_SUMMARY}" - echo "| --- | --- |" >> "${GITHUB_STEP_SUMMARY}" - echo "| Mass Payout Packages | ✅ Released |" >> "${GITHUB_STEP_SUMMARY}" - echo "| GitHub Release | ✅ Created |" >> "${GITHUB_STEP_SUMMARY}" - echo "" >> "${GITHUB_STEP_SUMMARY}" - echo "**Next Steps:**" >> "${GITHUB_STEP_SUMMARY}" - echo "- NPM publishing will be triggered automatically via mp.publish.yml" >> "${GITHUB_STEP_SUMMARY}" - echo "- ATS packages were ignored and remain available for separate release" >> "${GITHUB_STEP_SUMMARY}" + echo "## ✅ Mass Payout Release v${MP_VERSION} Completed Successfully" >> $GITHUB_STEP_SUMMARY + echo "| Package | Status |" >> $GITHUB_STEP_SUMMARY + echo "| --- | --- |" >> $GITHUB_STEP_SUMMARY + echo "| Mass Payout Packages | ✅ Released |" >> $GITHUB_STEP_SUMMARY + echo "| GitHub Release | ✅ Created |" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Next Steps:**" >> $GITHUB_STEP_SUMMARY + echo "- NPM publishing will be triggered automatically via mp.publish.yml" >> $GITHUB_STEP_SUMMARY + echo "- ATS packages were ignored and remain available for separate release" >> $GITHUB_STEP_SUMMARY else - echo "## ❌ Mass Payout Release Failed" >> "${GITHUB_STEP_SUMMARY}" - echo "Check the logs above for details on what went wrong." >> "${GITHUB_STEP_SUMMARY}" + echo "## ❌ Mass Payout Release Failed" >> $GITHUB_STEP_SUMMARY + echo "Check the logs above for details on what went wrong." >> $GITHUB_STEP_SUMMARY fi diff --git a/.github/workflows/mp.test.yml b/.github/workflows/mp.test.yml index c80dae155..751be7f20 100644 --- a/.github/workflows/mp.test.yml +++ b/.github/workflows/mp.test.yml @@ -59,14 +59,11 @@ jobs: - name: Setup NodeJS Environment uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: - node-version: 22.20.0 + node-version: 22.x - name: Install dependencies run: npm ci - - name: Install NestJS CLI globally - run: npm install -g @nestjs/cli - - name: Build mass-payout run: npm run mass-payout:build diff --git a/.gitignore b/.gitignore index aab0693b1..19628de72 100644 --- a/.gitignore +++ b/.gitignore @@ -137,9 +137,3 @@ asset-tokenization-studio.iml .kiro/ .claude/ CLAUDE.md - -# Extracted methods from contracts -contracts/extracted-methods.txt - -# bin files -bin/ diff --git a/package-lock.json b/package-lock.json index 8672b4bb8..1499fa123 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4046,6 +4046,296 @@ "yarn": ">= 1.13.0" } }, + "node_modules/@angular-devkit/schematics-cli": { + "version": "17.1.2", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics-cli/-/schematics-cli-17.1.2.tgz", + "integrity": "sha512-bvXykYzSST05qFdlgIzUguNOb3z0hCa8HaTwtqdmQo9aFPf+P+/AC56I64t1iTchMjQtf3JrBQhYM25gUdcGbg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/core": "17.1.2", + "@angular-devkit/schematics": "17.1.2", + "ansi-colors": "4.1.3", + "inquirer": "9.2.12", + "symbol-observable": "4.0.0", + "yargs-parser": "21.1.1" + }, + "bin": { + "schematics": "bin/schematics.js" + }, + "engines": { + "node": "^18.13.0 || >=20.9.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-devkit/schematics-cli/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@angular-devkit/schematics-cli/node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/@angular-devkit/schematics-cli/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/@angular-devkit/schematics-cli/node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@angular-devkit/schematics-cli/node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 12" + } + }, + "node_modules/@angular-devkit/schematics-cli/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@angular-devkit/schematics-cli/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@angular-devkit/schematics-cli/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@angular-devkit/schematics-cli/node_modules/figures": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-5.0.0.tgz", + "integrity": "sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^5.0.0", + "is-unicode-supported": "^1.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@angular-devkit/schematics-cli/node_modules/figures/node_modules/is-unicode-supported": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", + "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@angular-devkit/schematics-cli/node_modules/inquirer": { + "version": "9.2.12", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-9.2.12.tgz", + "integrity": "sha512-mg3Fh9g2zfuVWJn6lhST0O7x4n03k7G8Tx5nvikJkbq8/CK47WDVm+UznF0G6s5Zi0KcyUisr6DU8T67N5U+1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ljharb/through": "^2.3.11", + "ansi-escapes": "^4.3.2", + "chalk": "^5.3.0", + "cli-cursor": "^3.1.0", + "cli-width": "^4.1.0", + "external-editor": "^3.1.0", + "figures": "^5.0.0", + "lodash": "^4.17.21", + "mute-stream": "1.0.0", + "ora": "^5.4.1", + "run-async": "^3.0.0", + "rxjs": "^7.8.1", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^6.2.0" + }, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/@angular-devkit/schematics-cli/node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@angular-devkit/schematics-cli/node_modules/mute-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", + "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@angular-devkit/schematics-cli/node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@angular-devkit/schematics-cli/node_modules/ora/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@angular-devkit/schematics-cli/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@angular-devkit/schematics-cli/node_modules/run-async": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz", + "integrity": "sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/@angular-devkit/schematics-cli/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/@angular-devkit/schematics/node_modules/bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -12203,6 +12493,321 @@ "integrity": "sha512-eMk0b9ReBbV23xXU693TAIrLyeO5iTgBZGSJfpqriG8UkYvr/hC9u9pyMlAakDNHWmbhMZCDs6KQO0jzKD8OTw==", "license": "MIT" }, + "node_modules/@nestjs/cli": { + "version": "10.3.2", + "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-10.3.2.tgz", + "integrity": "sha512-aWmD1GLluWrbuC4a1Iz/XBk5p74Uj6nIVZj6Ov03JbTfgtWqGFLtXuMetvzMiHxfrHehx/myt2iKAPRhKdZvTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/core": "17.1.2", + "@angular-devkit/schematics": "17.1.2", + "@angular-devkit/schematics-cli": "17.1.2", + "@nestjs/schematics": "^10.0.1", + "chalk": "4.1.2", + "chokidar": "3.6.0", + "cli-table3": "0.6.3", + "commander": "4.1.1", + "fork-ts-checker-webpack-plugin": "9.0.2", + "glob": "10.3.10", + "inquirer": "8.2.6", + "node-emoji": "1.11.0", + "ora": "5.4.1", + "rimraf": "4.4.1", + "shelljs": "0.8.5", + "source-map-support": "0.5.21", + "tree-kill": "1.2.2", + "tsconfig-paths": "4.2.0", + "tsconfig-paths-webpack-plugin": "4.1.0", + "typescript": "5.3.3", + "webpack": "5.90.1", + "webpack-node-externals": "3.0.0" + }, + "bin": { + "nest": "bin/nest.js" + }, + "engines": { + "node": ">= 16.14" + }, + "peerDependencies": { + "@swc/cli": "^0.1.62 || ^0.3.0", + "@swc/core": "^1.3.62" + }, + "peerDependenciesMeta": { + "@swc/cli": { + "optional": true + }, + "@swc/core": { + "optional": true + } + } + }, + "node_modules/@nestjs/cli/node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/@nestjs/cli/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@nestjs/cli/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/@nestjs/cli/node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/@nestjs/cli/node_modules/glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@nestjs/cli/node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@nestjs/cli/node_modules/jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/@nestjs/cli/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/@nestjs/cli/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@nestjs/cli/node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@nestjs/cli/node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@nestjs/cli/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@nestjs/cli/node_modules/rimraf": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.4.1.tgz", + "integrity": "sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^9.2.0" + }, + "bin": { + "rimraf": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@nestjs/cli/node_modules/rimraf/node_modules/glob": { + "version": "9.3.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz", + "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "minimatch": "^8.0.2", + "minipass": "^4.2.4", + "path-scurry": "^1.6.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@nestjs/cli/node_modules/rimraf/node_modules/minimatch": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz", + "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@nestjs/cli/node_modules/rimraf/node_modules/minipass": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", + "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/@nestjs/cli/node_modules/typescript": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/@nestjs/common": { "version": "10.3.3", "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-10.3.3.tgz", @@ -20722,7 +21327,6 @@ "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", "deprecated": "package has been renamed to acorn-import-attributes", "license": "MIT", - "peer": true, "peerDependencies": { "acorn": "^8" } @@ -42683,6 +43287,21 @@ "node": ">=6" } }, + "node_modules/tsconfig-paths-webpack-plugin": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-4.1.0.tgz", + "integrity": "sha512-xWFISjviPydmtmgeUAuXp4N1fky+VCtfhOkDUFIv5ea7p4wuTomI4QTrXvFBX2S4jZsmyTSrStQl+E+4w+RzxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "enhanced-resolve": "^5.7.0", + "tsconfig-paths": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/tsconfig-paths/node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -44904,7 +45523,6 @@ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.90.1.tgz", "integrity": "sha512-SstPdlAC5IvgFnhiRok8hqJo/+ArAbNv7rhU4fnWGHNVfN59HSQFaxZDSAL3IFG2YmqxuRs+IU33milSxbPlog==", "license": "MIT", - "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^1.0.5", @@ -44970,7 +45588,6 @@ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "license": "BSD-2-Clause", - "peer": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -44984,7 +45601,6 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "license": "BSD-2-Clause", - "peer": true, "engines": { "node": ">=4.0" } @@ -44994,7 +45610,6 @@ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "license": "MIT", - "peer": true, "engines": { "node": ">= 0.6" } @@ -45004,7 +45619,6 @@ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "license": "MIT", - "peer": true, "dependencies": { "mime-db": "1.52.0" }, @@ -46975,7 +47589,7 @@ "typechain": "8.3.2" }, "engines": { - "node": ">=22.16.0" + "node": "22.16.0" } }, "packages/mass-payout/contracts/node_modules/@adraffy/ens-normalize": { @@ -47655,6 +48269,7 @@ "rxjs": "7.8" }, "devDependencies": { + "@nestjs/cli": "10.3.2", "@nestjs/testing": "10.3.3", "@types/node": "20.11.24", "typescript": "5.3.3" diff --git a/packages/mass-payout/sdk/package.json b/packages/mass-payout/sdk/package.json index f62138020..9c85d8f78 100644 --- a/packages/mass-payout/sdk/package.json +++ b/packages/mass-payout/sdk/package.json @@ -33,6 +33,7 @@ "rxjs": "7.8" }, "devDependencies": { + "@nestjs/cli": "10.3.2", "@nestjs/testing": "10.3.3", "@types/node": "20.11.24", "typescript": "5.3.3"