diff --git a/.github/workflows/release-beta.yml b/.github/workflows/release-beta.yml new file mode 100644 index 0000000000..5d58810a50 --- /dev/null +++ b/.github/workflows/release-beta.yml @@ -0,0 +1,368 @@ +name: Release CLI Plugins (Beta) + +on: + push: + branches: [v2-beta] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v4 + with: + version: 7 + - uses: actions/setup-node@v4 + with: + node-version: '22.x' + + - name: Enable Corepack + run: corepack enable + + - name: Install pnpm + run: corepack prepare pnpm@7 --activate + + - name: Install root dependencies + run: pnpm install + + - name: Reading Configuration + id: release_config + uses: rgarcia-phi/json-to-variables@v1.1.0 + with: + filename: .github/config/release.json + prefix: release + + # Dev Dependencies + - name: Installing dependencies of dev dependencies + id: dev-dependencies-installation + if: ${{env.release_releaseAll == 'true' || env.release_plugins_dev-dependencies == 'true'}} + working-directory: ./packages/contentstack-dev-dependencies + run: npm install + - name: Compiling dev dependencies + if: ${{ steps.dev-dependencies-installation.conclusion == 'success' }} + working-directory: ./packages/contentstack-dev-dependencies + run: npm run prepack + - name: Publishing dev dependencies (Beta) + uses: JS-DevTools/npm-publish@v3 + if: ${{ steps.dev-dependencies-installation.conclusion == 'success' }} + with: + token: ${{ secrets.NPM_TOKEN }} + package: ./packages/contentstack-dev-dependencies/package.json + tag: beta + + # Utilities + - name: Installing dependencies of utilities + id: utilities-installation + if: ${{env.release_releaseAll == 'true' || env.release_plugins_utilities == 'true'}} + working-directory: ./packages/contentstack-utilities + run: npm install + - name: Compiling utilities + if: ${{ steps.utilities-installation.conclusion == 'success' }} + working-directory: ./packages/contentstack-utilities + run: npm run prepack + - name: Publishing utilities (Beta) + uses: JS-DevTools/npm-publish@v3 + if: ${{ steps.utilities-installation.conclusion == 'success' }} + with: + token: ${{ secrets.NPM_TOKEN }} + package: ./packages/contentstack-utilities/package.json + tag: beta + + # Variants + - name: Installing dependencies of variants + id: variants-installation + if: ${{env.release_releaseAll == 'true' || env.release_plugins_utilities == 'true'}} + working-directory: ./packages/contentstack-variants + run: npm install + - name: Compiling variants + if: ${{ steps.variants-installation.conclusion == 'success' }} + working-directory: ./packages/contentstack-variants + run: npm run prepack + - name: Publishing variants (Beta) + uses: JS-DevTools/npm-publish@v3 + if: ${{ steps.variants-installation.conclusion == 'success' }} + with: + token: ${{ secrets.NPM_TOKEN }} + package: ./packages/contentstack-variants/package.json + access: public + tag: beta + + # Command + - name: Installing dependencies of command + id: command-installation + if: ${{env.release_releaseAll == 'true' || env.release_plugins_command == 'true'}} + working-directory: ./packages/contentstack-command + run: npm install + - name: Compiling command + if: ${{ steps.command-installation.conclusion == 'success' }} + working-directory: ./packages/contentstack-command + run: npm run prepack + - name: Publishing command (Beta) + uses: JS-DevTools/npm-publish@v3 + if: ${{ steps.command-installation.conclusion == 'success' }} + with: + token: ${{ secrets.NPM_TOKEN }} + package: ./packages/contentstack-command/package.json + tag: beta + + # Config + - name: Installing dependencies of config + id: config-installation + if: ${{env.release_releaseAll == 'true' || env.release_plugins_config == 'true'}} + working-directory: ./packages/contentstack-config + run: npm install + - name: Compiling config + if: ${{ steps.config-installation.conclusion == 'success' }} + working-directory: ./packages/contentstack-config + run: npm run prepack + - name: Publishing config (Beta) + uses: JS-DevTools/npm-publish@v3 + if: ${{ steps.config-installation.conclusion == 'success' }} + with: + token: ${{ secrets.NPM_TOKEN }} + package: ./packages/contentstack-config/package.json + tag: beta + + # Auth + - name: Installing dependencies of auth + id: auth-installation + if: ${{env.release_releaseAll == 'true' || env.release_plugins_auth == 'true'}} + working-directory: ./packages/contentstack-auth + run: npm install + - name: Compiling auth + if: ${{ steps.auth-installation.conclusion == 'success' }} + working-directory: ./packages/contentstack-auth + run: npm run prepack + - name: Publishing auth (Beta) + uses: JS-DevTools/npm-publish@v3 + if: ${{ steps.auth-installation.conclusion == 'success' }} + with: + token: ${{ secrets.NPM_TOKEN }} + package: ./packages/contentstack-auth/package.json + tag: beta + + # Export + - name: Installing dependencies of export + id: export-installation + if: ${{ env.release_releaseAll == 'true' || env.release_plugins_export == 'true'}} + working-directory: ./packages/contentstack-export + run: npm install + - name: Compiling export + if: ${{ steps.export-installation.conclusion == 'success' }} + working-directory: ./packages/contentstack-export + run: npm run prepack + - name: Publishing export (Beta) + uses: JS-DevTools/npm-publish@v3 + if: ${{ steps.export-installation.conclusion == 'success' }} + with: + token: ${{ secrets.NPM_TOKEN }} + package: ./packages/contentstack-export/package.json + tag: beta + + # Audit + - name: Installing dependencies of audit + id: audit-installation + if: ${{env.release_releaseAll == 'true' || env.release_plugins_audit == 'true'}} + working-directory: ./packages/contentstack-audit + run: npm install + - name: Compiling audit + if: ${{ steps.audit-installation.conclusion == 'success' }} + working-directory: ./packages/contentstack-audit + run: npm run prepack + - name: Publishing audit (Beta) + uses: JS-DevTools/npm-publish@v3 + if: ${{ steps.audit-installation.conclusion == 'success' }} + with: + token: ${{ secrets.NPM_TOKEN }} + package: ./packages/contentstack-audit/package.json + access: public + tag: beta + + # Import + - name: Installing dependencies of import + id: import-installation + if: ${{env.release_releaseAll == 'true' || env.release_plugins_import == 'true'}} + working-directory: ./packages/contentstack-import + run: npm install + - name: Compiling import + if: ${{ steps.import-installation.conclusion == 'success' }} + working-directory: ./packages/contentstack-import + run: npm run prepack + - name: Publishing import (Beta) + uses: JS-DevTools/npm-publish@v3 + if: ${{ steps.import-installation.conclusion == 'success' }} + with: + token: ${{ secrets.NPM_TOKEN }} + package: ./packages/contentstack-import/package.json + tag: beta + + # Clone + - name: Installing dependencies of clone + id: clone-installation + if: ${{env.release_releaseAll == 'true' || env.release_plugins_clone == 'true'}} + working-directory: ./packages/contentstack-clone + run: npm install + - name: Publishing clone (Beta) + uses: JS-DevTools/npm-publish@v3 + if: ${{ steps.clone-installation.conclusion == 'success' }} + with: + token: ${{ secrets.NPM_TOKEN }} + package: ./packages/contentstack-clone/package.json + tag: beta + + # Import Setup + - name: Installing dependencies of import-setup + id: import-setup-installation + if: ${{env.release_releaseAll == 'true' || env.release_plugins_import_setup == 'true'}} + working-directory: ./packages/contentstack-import-setup + run: npm install + - name: Compiling import-setup + if: ${{ steps.import-setup-installation.conclusion == 'success' }} + working-directory: ./packages/contentstack-import-setup + run: npm run prepack + - name: Publishing import-setup (Beta) + uses: JS-DevTools/npm-publish@v3 + if: ${{ steps.import-setup-installation.conclusion == 'success' }} + with: + token: ${{ secrets.NPM_TOKEN }} + package: ./packages/contentstack-import-setup/package.json + access: public + tag: beta + + # Export to CSV + - name: Installing dependencies of export to csv + id: export-to-csv-installation + if: ${{env.release_releaseAll == 'true' || env.release_plugins_export-to-csv == 'true'}} + working-directory: ./packages/contentstack-export-to-csv + run: npm install + - name: Publishing export to csv (Beta) + uses: JS-DevTools/npm-publish@v3 + if: ${{ steps.export-to-csv-installation.conclusion == 'success' }} + with: + token: ${{ secrets.NPM_TOKEN }} + package: ./packages/contentstack-export-to-csv/package.json + tag: beta + + # Migrate RTE + - name: Installing dependencies of migrate rte + id: migrate-rte-installation + if: ${{env.release_releaseAll == 'true' || env.release_plugins_migrate-rte == 'true'}} + working-directory: ./packages/contentstack-migrate-rte + run: npm install + - name: Publishing migrate rte (Beta) + uses: JS-DevTools/npm-publish@v3 + if: ${{ steps.migrate-rte-installation.conclusion == 'success' }} + with: + token: ${{ secrets.NPM_TOKEN }} + package: ./packages/contentstack-migrate-rte/package.json + tag: beta + + # Migration + - name: Installing dependencies of migration + id: migration-installation + if: ${{env.release_releaseAll == 'true' || env.release_plugins_migration == 'true'}} + working-directory: ./packages/contentstack-migration + run: npm install + - name: Publishing migration (Beta) + uses: JS-DevTools/npm-publish@v3 + if: ${{ steps.migration-installation.conclusion == 'success' }} + with: + token: ${{ secrets.NPM_TOKEN }} + package: ./packages/contentstack-migration/package.json + tag: beta + + # Seed + - name: Installing dependencies of seed + id: seed-installation + if: ${{env.release_releaseAll == 'true' || env.release_plugins_seed == 'true'}} + working-directory: ./packages/contentstack-seed + run: npm install + - name: Compiling seed + if: ${{ steps.seed-installation.conclusion == 'success' }} + working-directory: ./packages/contentstack-seed + run: npm run prepack + - name: Publishing seed (Beta) + uses: JS-DevTools/npm-publish@v3 + if: ${{ steps.seed-installation.conclusion == 'success' }} + with: + token: ${{ secrets.NPM_TOKEN }} + package: ./packages/contentstack-seed/package.json + tag: beta + + # Bootstrap + - name: Installing dependencies of bootstrap + id: bootstrap-installation + if: ${{env.release_releaseAll == 'true' || env.release_plugins_bootstrap == 'true'}} + working-directory: ./packages/contentstack-bootstrap + run: npm install + - name: Compiling bootstrap + if: ${{ steps.bootstrap-installation.conclusion == 'success' }} + working-directory: ./packages/contentstack-bootstrap + run: npm run prepack + - name: Publishing bootstrap (Beta) + uses: JS-DevTools/npm-publish@v3 + if: ${{ steps.bootstrap-installation.conclusion == 'success' }} + with: + token: ${{ secrets.NPM_TOKEN }} + package: ./packages/contentstack-bootstrap/package.json + tag: beta + + # Bulk Publish + - name: Installing dependencies of bulk publish + id: bulk-publish-installation + if: ${{env.release_releaseAll == 'true' || env.release_plugins_bulk-publish == 'true'}} + working-directory: ./packages/contentstack-bulk-publish + run: npm install + - name: Publishing bulk publish (Beta) + uses: JS-DevTools/npm-publish@v3 + if: ${{ steps.bulk-publish-installation.conclusion == 'success' }} + with: + token: ${{ secrets.NPM_TOKEN }} + package: ./packages/contentstack-bulk-publish/package.json + tag: beta + + # Branches + - name: Installing dependencies of branches + id: branches-installation + if: ${{env.release_releaseAll == 'true' || env.release_plugins_branches == 'true'}} + working-directory: ./packages/contentstack-branches + run: npm install + - name: Compiling branches + if: ${{ steps.branches-installation.conclusion == 'success' }} + working-directory: ./packages/contentstack-branches + run: npm run prepack + - name: Publishing branches (Beta) + uses: JS-DevTools/npm-publish@v3 + if: ${{ steps.branches-installation.conclusion == 'success' }} + with: + token: ${{ secrets.NPM_TOKEN }} + package: ./packages/contentstack-branches/package.json + access: public + tag: beta + + # Core CLI + - name: Installing dependencies of core + id: core-installation + if: ${{env.release_releaseAll == 'true' || env.release_plugins_core == 'true'}} + working-directory: ./packages/contentstack + run: npm install + - name: Compiling core + if: ${{ steps.core-installation.conclusion == 'success' }} + working-directory: ./packages/contentstack + run: npm run prepack + - name: Publishing core (Beta) + id: publish-core + uses: JS-DevTools/npm-publish@v3 + if: ${{ steps.core-installation.conclusion == 'success' }} + with: + token: ${{ secrets.NPM_TOKEN }} + package: ./packages/contentstack/package.json + tag: beta + + - name: Create Beta Release + if: ${{ steps.publish-core.conclusion == 'success' }} + id: create_release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + VERSION: ${{ steps.publish-core.outputs.version }} + run: gh release create v"$VERSION"-beta --title "Beta Release $VERSION" --generate-notes --prerelease diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 83384fe848..accc815e98 100755 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,6 +31,7 @@ jobs: with: filename: .github/config/release.json prefix: release + # Dev Dependencies - name: Installing dependencies of dev dependencies id: dev-dependencies-installation if: ${{env.release_releaseAll == 'true' || env.release_plugins_dev-dependencies == 'true'}} @@ -46,6 +47,8 @@ jobs: with: token: ${{ secrets.NPM_TOKEN }} package: ./packages/contentstack-dev-dependencies/package.json + + # Utilities - name: Installing dependencies of utilities id: utilities-installation if: ${{env.release_releaseAll == 'true' || env.release_plugins_utilities == 'true'}} @@ -61,6 +64,8 @@ jobs: with: token: ${{ secrets.NPM_TOKEN }} package: ./packages/contentstack-utilities/package.json + + # Variants - name: Installing dependencies of variants id: variants-installation if: ${{env.release_releaseAll == 'true' || env.release_plugins_utilities == 'true'}} @@ -77,6 +82,8 @@ jobs: token: ${{ secrets.NPM_TOKEN }} package: ./packages/contentstack-variants/package.json access: public + + # Command - name: Installing dependencies of command id: command-installation if: ${{env.release_releaseAll == 'true' || env.release_plugins_command == 'true'}} @@ -92,6 +99,8 @@ jobs: with: token: ${{ secrets.NPM_TOKEN }} package: ./packages/contentstack-command/package.json + + # Config - name: Installing dependencies of config id: config-installation if: ${{env.release_releaseAll == 'true' || env.release_plugins_config == 'true'}} @@ -107,6 +116,8 @@ jobs: with: token: ${{ secrets.NPM_TOKEN }} package: ./packages/contentstack-config/package.json + + # Auth - name: Installing dependencies of auth id: auth-installation if: ${{env.release_releaseAll == 'true' || env.release_plugins_auth == 'true'}} @@ -122,6 +133,8 @@ jobs: with: token: ${{ secrets.NPM_TOKEN }} package: ./packages/contentstack-auth/package.json + + # Export - name: Installing dependencies of export id: export-installation if: ${{ env.release_releaseAll == 'true' || env.release_plugins_export == 'true'}} @@ -137,6 +150,8 @@ jobs: with: token: ${{ secrets.NPM_TOKEN }} package: ./packages/contentstack-export/package.json + + # Audit - name: Installing dependencies of audit id: audit-installation if: ${{env.release_releaseAll == 'true' || env.release_plugins_audit == 'true'}} @@ -153,6 +168,8 @@ jobs: token: ${{ secrets.NPM_TOKEN }} package: ./packages/contentstack-audit/package.json access: public + + # Import - name: Installing dependencies of import id: import-installation if: ${{env.release_releaseAll == 'true' || env.release_plugins_import == 'true'}} @@ -168,6 +185,8 @@ jobs: with: token: ${{ secrets.NPM_TOKEN }} package: ./packages/contentstack-import/package.json + + # Clone - name: Installing dependencies of clone id: clone-installation if: ${{env.release_releaseAll == 'true' || env.release_plugins_clone == 'true'}} @@ -179,6 +198,8 @@ jobs: with: token: ${{ secrets.NPM_TOKEN }} package: ./packages/contentstack-clone/package.json + + # Import Setup - name: Installing dependencies of import-setup id: import-setup-installation if: ${{env.release_releaseAll == 'true' || env.release_plugins_import_setup == 'true'}} @@ -195,6 +216,8 @@ jobs: token: ${{ secrets.NPM_TOKEN }} package: ./packages/contentstack-import-setup/package.json access: public + + # Export to CSV - name: Installing dependencies of export to csv id: export-to-csv-installation if: ${{env.release_releaseAll == 'true' || env.release_plugins_export-to-csv == 'true'}} @@ -206,6 +229,8 @@ jobs: with: token: ${{ secrets.NPM_TOKEN }} package: ./packages/contentstack-export-to-csv/package.json + + # Migrate RTE - name: Installing dependencies of migrate rte id: migrate-rte-installation if: ${{env.release_releaseAll == 'true' || env.release_plugins_migrate-rte == 'true'}} @@ -217,6 +242,8 @@ jobs: with: token: ${{ secrets.NPM_TOKEN }} package: ./packages/contentstack-migrate-rte/package.json + + # Migration - name: Installing dependencies of migration id: migration-installation if: ${{env.release_releaseAll == 'true' || env.release_plugins_migration == 'true'}} @@ -228,6 +255,8 @@ jobs: with: token: ${{ secrets.NPM_TOKEN }} package: ./packages/contentstack-migration/package.json + + # Seed - name: Installing dependencies of seed id: seed-installation if: ${{env.release_releaseAll == 'true' || env.release_plugins_seed == 'true'}} @@ -243,6 +272,8 @@ jobs: with: token: ${{ secrets.NPM_TOKEN }} package: ./packages/contentstack-seed/package.json + + # Bootstrap - name: Installing dependencies of bootstrap id: bootstrap-installation if: ${{env.release_releaseAll == 'true' || env.release_plugins_bootstrap == 'true'}} @@ -258,6 +289,8 @@ jobs: with: token: ${{ secrets.NPM_TOKEN }} package: ./packages/contentstack-bootstrap/package.json + + # Bulk Publish - name: Installing dependencies of bulk publish id: bulk-publish-installation if: ${{env.release_releaseAll == 'true' || env.release_plugins_bulk-publish == 'true'}} @@ -269,6 +302,8 @@ jobs: with: token: ${{ secrets.NPM_TOKEN }} package: ./packages/contentstack-bulk-publish/package.json + + # Branches - name: Installing dependencies of branches id: branches-installation if: ${{env.release_releaseAll == 'true' || env.release_plugins_branches == 'true'}} diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index 78ad39d4b1..afaf557e46 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -18,7 +18,7 @@ jobs: - name: Install dependencies for all plugins run: | - npm run setup-repo-old + NODE_ENV=PREPACK_MODE npm run setup-repo-old - name: Run tests for Contentstack Command working-directory: ./packages/contentstack-command diff --git a/.talismanrc b/.talismanrc index ea2220a8f7..c8169b6b48 100644 --- a/.talismanrc +++ b/.talismanrc @@ -1,8 +1,8 @@ fileignoreconfig: - filename: package-lock.json - checksum: b07cb236b78aa3149b89e2ed18851ee005db8ef735062f91e0e91b2adf013c12 + checksum: 1625bf05fa92826c389d702552d5027df7632a96bac74a970f78f866bbb59e7e - filename: pnpm-lock.yaml - checksum: 577582ed82062ad359d8bc2bc0a309ab4d344a2a4122573d8cf77aeb481268f2 + checksum: 87a6d67aa28e2675ac544cebd0cad703382b799fb46abfe96398c96522374624 - filename: packages/contentstack-import-setup/test/unit/backup-handler.test.ts checksum: 0582d62b88834554cf12951c8690a73ef3ddbb78b82d2804d994cf4148e1ef93 - filename: packages/contentstack-import-setup/test/config.json @@ -32,7 +32,7 @@ fileignoreconfig: - filename: packages/contentstack-import-setup/test/unit/login-handler.test.ts checksum: e549f9ca3a9aae0d93b7284f7e771d55c0610725ddcb4333612df2f215e92769 - filename: packages/contentstack/README.md - checksum: f46084b199b3b0d7986b363c86a657570def71e5da29b948cc343eaf94ec7e97 + checksum: 97b2fd7499f21eb330e66b712dc1a9b9bb315db8d8614b46ae0c6966024d5895 - filename: packages/contentstack-import-setup/test/unit/modules/assets.test.ts checksum: 449a5e3383631a6f78d1291aa3c28c91681879289398f0a933158fba5c5d5acf - filename: packages/contentstack-auth/env.example @@ -58,7 +58,7 @@ fileignoreconfig: - filename: packages/contentstack-auth/test/utils/mfa-handler.test.ts checksum: b067f93cf0185d794e8419cc41e8fac96ed790dea8fc48dc083ee242ccacbd4d - filename: packages/contentstack-import/src/import/module-importer.ts - checksum: 93fac2407e20070aa393f783e5a21093e99424e5fd2873aabc2099ac3ea02b27 + checksum: f0ec2d9205aab0571cabef092e1933f840e8bcdb34bf519c662c34519c233155 - filename: packages/contentstack-import/src/utils/import-config-handler.ts checksum: bb8093633dc7de888541990623c3e02a482b7e6f5db0ba396bedc20c4c74b782 - filename: packages/contentstack-import/src/utils/setup-branch.ts @@ -68,7 +68,7 @@ fileignoreconfig: - filename: packages/contentstack-import/src/import/modules/entries.ts checksum: 2fd4e8ecf75e077632a6408d09997f0921d2a3508f9f2cb8f47fe79a28592300 - filename: packages/contentstack-utilities/src/logger/logger.ts - checksum: 76429bc87e279624b386f00e7eb3f4ec25621ace7056289f812b9a076d6e184e + checksum: 0a5d7f66e1a207691787f856456b18b62366f8711a5a8b13eb8a052920be2e87 - filename: packages/contentstack-bootstrap/src/bootstrap/utils.ts checksum: e66a08cb3cd444071688fbad1e14da309f8504f584cfaed85499d32b623e29e8 - filename: packages/contentstack-bootstrap/messages/index.json @@ -81,10 +81,32 @@ fileignoreconfig: checksum: 7024f22a6ed3908d7cf074bbd8e7107e2d9f43bbcc42939b28d360c89d44cc29 - filename: packages/contentstack-bulk-publish/src/util/generate-bulk-publish-url.js checksum: 5f7c1e2fac3e7fab21e861d609c54ca7191ee09fd076dd0adc66604043bf7a43 +- filename: packages/contentstack-import/src/commands/cm/stacks/import.ts + checksum: 0dbf0a6bc447206260b8acd41b85781d60ca50c948bb3ca62f444f97d64d1fb2 +- filename: packages/contentstack-utilities/src/interfaces/index.ts + checksum: d0b0042e643ce0c0489b86f15f3b64f60a837c2ae928b6275028e5e0184b0a7a +- filename: packages/contentstack-variants/src/import/attribute.ts + checksum: 03e764ee2032c44d9493f2be194f91a2337026b7fd8037df90240327e6bcaabb +- filename: packages/contentstack-variants/src/import/audiences.ts + checksum: f24697ef86e928bb4d16f93c021b647639cc344a7f02463d79d69f9434ebed56 +- filename: packages/contentstack-variants/src/import/events.ts + checksum: 88256a99c8ff8d6904df2e3767b39f4761d35ce680b3cabd712c33889bd02fca +- filename: packages/contentstack-import/src/import/modules/personalize.ts + checksum: 1311a613177160637e21b3983b281b384c2cb15837d001a398b67afef30a393a +- filename: packages/contentstack-export/src/export/modules/environments.ts + checksum: fd33318628321583dbeedd70ba7ba97f1e167d364dd26847771d745db295b16f +- filename: packages/contentstack-import/src/import/modules/environments.ts + checksum: 25ec3da4b218c5bbabcfa1af59f26d62e99110bf361a77aab30bfa3ab402da05 +- filename: packages/contentstack-variants/src/utils/constants.ts + checksum: 0ceef8ec8489a05d8ecf07cfa7e92575b0da7d5a6c0ed65b64f46d23aab7074d +- filename: packages/contentstack-export/src/utils/marketplace-app-helper.ts + checksum: fcd17c120a0359baeb61b7bd0f8d1ace2662f7f7293d355867f578312fe3a1a0 +- filename: packages/contentstack-variants/src/import/variant-entries.ts + checksum: 6e645a3d95903058f32306d306912353272e86e60571919a34125a9cd7b69a59 - filename: packages/contentstack-import/src/utils/interactive.ts checksum: b401a6166313c184712ff623ea8d95a5548fb3d8b8229c053ae44a1850b54a72 - filename: packages/contentstack-import-setup/src/utils/backup-handler.ts checksum: 7db02c6f2627400b28fc96d505bf074d477080a45ba13943709d4845b6ca0908 - filename: packages/contentstack-import/src/utils/backup-handler.ts checksum: 0a9accdafce01837166223ed00cd801e2ebb39a4ef952231f67232859a5beea8 -version: "1.0" +version: "1.0" \ No newline at end of file diff --git a/MIGRATION.md b/MIGRATION.md new file mode 100644 index 0000000000..34667b7adb --- /dev/null +++ b/MIGRATION.md @@ -0,0 +1,167 @@ +# Contentstack CLI Migration Guide: 1.x.x to 2.x.x-beta + +## Overview + +This guide helps you migrate from Contentstack CLI 1.x.x to the new 2.x.x-beta version. The new version introduces significant improvements in performance, user experience, and functionality. + +## Major Changes + +### 1. 🚀 TypeScript Module Support (Default) + +**What Changed:** +- Removed `export-info.json` support +- TypeScript modules are now the default for export and import operations +- Improved performance and reliability + +**Before (1.x.x):** +```bash +csdx cm:stacks:export -d "./export-data" -k bltxxxxxx +``` +The CLI generated an export-info.json file containing a contentVersion field: +contentVersion: 2 for TypeScript modules +contentVersion: 1 for JavaScript modules (default) +This version indicator helped the import process select the appropriate module structure, as TypeScript and JavaScript modules have different structures for assets, entries, and other components. + +**After (2.x.x-beta):** +```bash +csdx cm:stacks:export -d "./export-data" -k bltxxxxxx +``` +No export-info.json file is generated +TypeScript modules are used by default for all operations +Simplified export structure with consistent module formatting + +**Migration Action:** Remove `export-info.json` file generation logic from export plugin. + +### 2. 🌿 Main Branch Export (Default) + +**What Changed:** +- By default, only the main branch content is exported +- Consistent behavior with import operations +- Faster exports for most use cases + +**Before (1.x.x):** +- Exported all branches by default + +**After (2.x.x-beta):** +- Exports main branch by default +- Specify `--branch` for specific branch export + +**Examples:** + +```bash +# Export main branch (default behavior) +csdx cm:stacks:export -d "./export-data" -k bltxxxxxx + +# Export specific branch +csdx cm:stacks:export --branch feature-branch -d "./export-data" -k bltxxxxxx + +# Export using branch alias +csdx cm:stacks:export --branch-alias production -d "./export-data" -k bltxxxxxx +``` + +**Migration Action:** To export specific branches, add the `--branch` flag to your commands. + +### 3. 📊 Progress Manager UI (Default) + +**What Changed:** +- Visual Progress Manager is now the default UI for export, import, clone & seed operations +- Enhanced user experience with real-time progress tracking +- Console logs are available as an optional mode + +## New Progress Manager Interface + +### Default Mode: Visual Progress Manager + +When you run the export or import commands, a visual progress interface appears. + +``` +STACK: + ├─ Settings |████████████████████████████████████████| 100% | 1/1 | ✓ Complete (1/1) + ├─ Locale |████████████████████████████████████████| 100% | 1/1 | ✓ Complete (1/1) + +LOCALES: + └─ Locales |████████████████████████████████████████| 100% | 2/2 | ✓ Complete (2/2) + +CONTENT TYPES: + └─ Content types |████████████████████████████████████████| 100% | 6/6 | ✓ Complete (6/6) + +ENTRIES: + ├─ Entries |████████████████████████████████████████| 100% | 12/12 | ✓ Complete (12/12) +``` + +### Optional Mode: Console Logs + +For debugging or detailed logging, switch to console log mode: + +**Enable Console Logs:** +```bash +csdx config:set:log --show-console-logs +``` + +**Disable Console Logs (back to Progress Manager):** +```bash +csdx config:set:log --no-show-console-logs +``` + +**Console Log Output Example:** +``` +[2025-08-22 16:12:23] INFO: Exporting content from branch main +[2025-08-22 16:12:23] INFO: Started to export content, version is 2 +[2025-08-22 16:12:23] INFO: Exporting module: stack +[2025-08-22 16:12:24] INFO: Exporting stack settings +[2025-08-22 16:12:25] SUCCESS: Exported stack settings successfully! +``` + +## Troubleshooting + +### Common Issues + +**1. Command not found errors:** +- Ensure you have installed the 2.x.x-beta version +- Clear npm cache: `npm cache clean --force` + +**2. Missing branch content:** +- Check if you need to specify the `--branch` flag for non-main branches +- Verify the branch exists in your stack + +**3. Progress display issues:** +- Try switching between console logs and progress manager modes +- Check terminal compatibility for progress bars + +**4. Performance differences:** +- The 2.x.x-beta version should be faster due to TypeScript modules +- If you are experiencing issues, switch to console log mode for debugging + +### Getting Help + +**Documentation:** +- [CLI Documentation](https://www.contentstack.com/docs/developers/cli) +- [API Reference](https://www.contentstack.com/docs/developers/apis) + +**Support:** +- [GitHub Issues](https://github.com/contentstack/cli/issues) + +## Benefits of 2.x.x-beta + +### 🚀 **Performance Improvements** +- Faster export/import operations with TypeScript modules +- Optimized branch handling +- Reduced memory usage + +### 🎯 **Better User Experience** +- Visual Progress Manager with real-time updates +- Cleaner command syntax +- More intuitive default behaviors + +### 🔧 **Enhanced Reliability** +- Improved error handling +- Better progress tracking +- More consistent behavior across commands + +### 📊 **Better Observability** +- Detailed progress information +- Clear success/failure indicators +- Optional detailed logging for debugging +--- + +**Need help with migration?** Contact our support team or visit our community forum for assistance. diff --git a/README.md b/README.md index 60eca7d5e3..6b922e41eb 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,18 @@ npm install -g @contentstack/cli To verify the installation, run `csdx` in the command window. +## Migration Guide + +If you're upgrading from CLI 1.x to 2.x.x-beta, please refer to our comprehensive [Migration Guide](./MIGRATION.md) for: + +- **Breaking changes** and new default behaviors +- **Step-by-step migration instructions** +- **New features** like TypeScript module support and Progress Manager UI +- **Command syntax updates** and configuration changes +- **Troubleshooting tips** for common migration issues + +📖 **[View Migration Guide →](./MIGRATION.md)** + ## Usage After the successful installation of CLI, use the `--help` parameter to display the help section of the CLI. You can even combine this parameter with a specific command to get the help section of that command. diff --git a/package-lock.json b/package-lock.json index 2c28133c9d..340f5f8e77 100644 --- a/package-lock.json +++ b/package-lock.json @@ -280,53 +280,53 @@ } }, "node_modules/@aws-sdk/client-cloudfront": { - "version": "3.890.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudfront/-/client-cloudfront-3.890.0.tgz", - "integrity": "sha512-xe1RA5OtH3CbF25TDidEiXhrvZAMKqPEnaw6YaHYnelES+7OHcIjI29by88nD5L0P49GpCCudJJ3Qp2gbkY5Xg==", + "version": "3.901.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudfront/-/client-cloudfront-3.901.0.tgz", + "integrity": "sha512-1JjAc4/JU7nPCTg3sXClw0HL7ITrH/VxdRbEN1lvW2QDM0Hd93IRzttDcig+4IrDNqdLQcUJ8s7oj4iYSz3atg==", "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.890.0", - "@aws-sdk/credential-provider-node": "3.890.0", - "@aws-sdk/middleware-host-header": "3.887.0", - "@aws-sdk/middleware-logger": "3.887.0", - "@aws-sdk/middleware-recursion-detection": "3.887.0", - "@aws-sdk/middleware-user-agent": "3.890.0", - "@aws-sdk/region-config-resolver": "3.890.0", - "@aws-sdk/types": "3.887.0", - "@aws-sdk/util-endpoints": "3.890.0", - "@aws-sdk/util-user-agent-browser": "3.887.0", - "@aws-sdk/util-user-agent-node": "3.890.0", - "@aws-sdk/xml-builder": "3.887.0", - "@smithy/config-resolver": "^4.2.2", - "@smithy/core": "^3.11.0", - "@smithy/fetch-http-handler": "^5.2.1", - "@smithy/hash-node": "^4.1.1", - "@smithy/invalid-dependency": "^4.1.1", - "@smithy/middleware-content-length": "^4.1.1", - "@smithy/middleware-endpoint": "^4.2.2", - "@smithy/middleware-retry": "^4.2.2", - "@smithy/middleware-serde": "^4.1.1", - "@smithy/middleware-stack": "^4.1.1", - "@smithy/node-config-provider": "^4.2.2", - "@smithy/node-http-handler": "^4.2.1", - "@smithy/protocol-http": "^5.2.1", - "@smithy/smithy-client": "^4.6.2", - "@smithy/types": "^4.5.0", - "@smithy/url-parser": "^4.1.1", - "@smithy/util-base64": "^4.1.0", - "@smithy/util-body-length-browser": "^4.1.0", - "@smithy/util-body-length-node": "^4.1.0", - "@smithy/util-defaults-mode-browser": "^4.1.2", - "@smithy/util-defaults-mode-node": "^4.1.2", - "@smithy/util-endpoints": "^3.1.2", - "@smithy/util-middleware": "^4.1.1", - "@smithy/util-retry": "^4.1.1", - "@smithy/util-stream": "^4.3.1", - "@smithy/util-utf8": "^4.1.0", - "@smithy/util-waiter": "^4.1.1", + "@aws-sdk/core": "3.901.0", + "@aws-sdk/credential-provider-node": "3.901.0", + "@aws-sdk/middleware-host-header": "3.901.0", + "@aws-sdk/middleware-logger": "3.901.0", + "@aws-sdk/middleware-recursion-detection": "3.901.0", + "@aws-sdk/middleware-user-agent": "3.901.0", + "@aws-sdk/region-config-resolver": "3.901.0", + "@aws-sdk/types": "3.901.0", + "@aws-sdk/util-endpoints": "3.901.0", + "@aws-sdk/util-user-agent-browser": "3.901.0", + "@aws-sdk/util-user-agent-node": "3.901.0", + "@aws-sdk/xml-builder": "3.901.0", + "@smithy/config-resolver": "^4.3.0", + "@smithy/core": "^3.14.0", + "@smithy/fetch-http-handler": "^5.3.0", + "@smithy/hash-node": "^4.2.0", + "@smithy/invalid-dependency": "^4.2.0", + "@smithy/middleware-content-length": "^4.2.0", + "@smithy/middleware-endpoint": "^4.3.0", + "@smithy/middleware-retry": "^4.4.0", + "@smithy/middleware-serde": "^4.2.0", + "@smithy/middleware-stack": "^4.2.0", + "@smithy/node-config-provider": "^4.3.0", + "@smithy/node-http-handler": "^4.3.0", + "@smithy/protocol-http": "^5.3.0", + "@smithy/smithy-client": "^4.7.0", + "@smithy/types": "^4.6.0", + "@smithy/url-parser": "^4.2.0", + "@smithy/util-base64": "^4.2.0", + "@smithy/util-body-length-browser": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.0", + "@smithy/util-defaults-mode-browser": "^4.2.0", + "@smithy/util-defaults-mode-node": "^4.2.0", + "@smithy/util-endpoints": "^3.2.0", + "@smithy/util-middleware": "^4.2.0", + "@smithy/util-retry": "^4.2.0", + "@smithy/util-stream": "^4.4.0", + "@smithy/util-utf8": "^4.2.0", + "@smithy/util-waiter": "^4.2.0", "tslib": "^2.6.2" }, "engines": { @@ -334,119 +334,118 @@ } }, "node_modules/@aws-sdk/client-s3": { - "version": "3.890.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.890.0.tgz", - "integrity": "sha512-yByS+gXYe0KALEEGz9vqIapSKAJ/bGgevOMzPDHZfxQXP1DQxOnPQCbsCC7GDpYpy7Q2Wx54fgU5bqyMd7cfpA==", + "version": "3.901.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.901.0.tgz", + "integrity": "sha512-wyKhZ51ur1tFuguZ6PgrUsot9KopqD0Tmxw8O8P/N3suQDxFPr0Yo7Y77ezDRDZQ95Ml3C0jlvx79HCo8VxdWA==", "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha1-browser": "5.2.0", "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.890.0", - "@aws-sdk/credential-provider-node": "3.890.0", - "@aws-sdk/middleware-bucket-endpoint": "3.890.0", - "@aws-sdk/middleware-expect-continue": "3.887.0", - "@aws-sdk/middleware-flexible-checksums": "3.890.0", - "@aws-sdk/middleware-host-header": "3.887.0", - "@aws-sdk/middleware-location-constraint": "3.887.0", - "@aws-sdk/middleware-logger": "3.887.0", - "@aws-sdk/middleware-recursion-detection": "3.887.0", - "@aws-sdk/middleware-sdk-s3": "3.890.0", - "@aws-sdk/middleware-ssec": "3.887.0", - "@aws-sdk/middleware-user-agent": "3.890.0", - "@aws-sdk/region-config-resolver": "3.890.0", - "@aws-sdk/signature-v4-multi-region": "3.890.0", - "@aws-sdk/types": "3.887.0", - "@aws-sdk/util-endpoints": "3.890.0", - "@aws-sdk/util-user-agent-browser": "3.887.0", - "@aws-sdk/util-user-agent-node": "3.890.0", - "@aws-sdk/xml-builder": "3.887.0", - "@smithy/config-resolver": "^4.2.2", - "@smithy/core": "^3.11.0", - "@smithy/eventstream-serde-browser": "^4.1.1", - "@smithy/eventstream-serde-config-resolver": "^4.2.1", - "@smithy/eventstream-serde-node": "^4.1.1", - "@smithy/fetch-http-handler": "^5.2.1", - "@smithy/hash-blob-browser": "^4.1.1", - "@smithy/hash-node": "^4.1.1", - "@smithy/hash-stream-node": "^4.1.1", - "@smithy/invalid-dependency": "^4.1.1", - "@smithy/md5-js": "^4.1.1", - "@smithy/middleware-content-length": "^4.1.1", - "@smithy/middleware-endpoint": "^4.2.2", - "@smithy/middleware-retry": "^4.2.2", - "@smithy/middleware-serde": "^4.1.1", - "@smithy/middleware-stack": "^4.1.1", - "@smithy/node-config-provider": "^4.2.2", - "@smithy/node-http-handler": "^4.2.1", - "@smithy/protocol-http": "^5.2.1", - "@smithy/smithy-client": "^4.6.2", - "@smithy/types": "^4.5.0", - "@smithy/url-parser": "^4.1.1", - "@smithy/util-base64": "^4.1.0", - "@smithy/util-body-length-browser": "^4.1.0", - "@smithy/util-body-length-node": "^4.1.0", - "@smithy/util-defaults-mode-browser": "^4.1.2", - "@smithy/util-defaults-mode-node": "^4.1.2", - "@smithy/util-endpoints": "^3.1.2", - "@smithy/util-middleware": "^4.1.1", - "@smithy/util-retry": "^4.1.1", - "@smithy/util-stream": "^4.3.1", - "@smithy/util-utf8": "^4.1.0", - "@smithy/util-waiter": "^4.1.1", - "@types/uuid": "^9.0.1", - "tslib": "^2.6.2", - "uuid": "^9.0.1" + "@aws-sdk/core": "3.901.0", + "@aws-sdk/credential-provider-node": "3.901.0", + "@aws-sdk/middleware-bucket-endpoint": "3.901.0", + "@aws-sdk/middleware-expect-continue": "3.901.0", + "@aws-sdk/middleware-flexible-checksums": "3.901.0", + "@aws-sdk/middleware-host-header": "3.901.0", + "@aws-sdk/middleware-location-constraint": "3.901.0", + "@aws-sdk/middleware-logger": "3.901.0", + "@aws-sdk/middleware-recursion-detection": "3.901.0", + "@aws-sdk/middleware-sdk-s3": "3.901.0", + "@aws-sdk/middleware-ssec": "3.901.0", + "@aws-sdk/middleware-user-agent": "3.901.0", + "@aws-sdk/region-config-resolver": "3.901.0", + "@aws-sdk/signature-v4-multi-region": "3.901.0", + "@aws-sdk/types": "3.901.0", + "@aws-sdk/util-endpoints": "3.901.0", + "@aws-sdk/util-user-agent-browser": "3.901.0", + "@aws-sdk/util-user-agent-node": "3.901.0", + "@aws-sdk/xml-builder": "3.901.0", + "@smithy/config-resolver": "^4.3.0", + "@smithy/core": "^3.14.0", + "@smithy/eventstream-serde-browser": "^4.2.0", + "@smithy/eventstream-serde-config-resolver": "^4.3.0", + "@smithy/eventstream-serde-node": "^4.2.0", + "@smithy/fetch-http-handler": "^5.3.0", + "@smithy/hash-blob-browser": "^4.2.0", + "@smithy/hash-node": "^4.2.0", + "@smithy/hash-stream-node": "^4.2.0", + "@smithy/invalid-dependency": "^4.2.0", + "@smithy/md5-js": "^4.2.0", + "@smithy/middleware-content-length": "^4.2.0", + "@smithy/middleware-endpoint": "^4.3.0", + "@smithy/middleware-retry": "^4.4.0", + "@smithy/middleware-serde": "^4.2.0", + "@smithy/middleware-stack": "^4.2.0", + "@smithy/node-config-provider": "^4.3.0", + "@smithy/node-http-handler": "^4.3.0", + "@smithy/protocol-http": "^5.3.0", + "@smithy/smithy-client": "^4.7.0", + "@smithy/types": "^4.6.0", + "@smithy/url-parser": "^4.2.0", + "@smithy/util-base64": "^4.2.0", + "@smithy/util-body-length-browser": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.0", + "@smithy/util-defaults-mode-browser": "^4.2.0", + "@smithy/util-defaults-mode-node": "^4.2.0", + "@smithy/util-endpoints": "^3.2.0", + "@smithy/util-middleware": "^4.2.0", + "@smithy/util-retry": "^4.2.0", + "@smithy/util-stream": "^4.4.0", + "@smithy/util-utf8": "^4.2.0", + "@smithy/util-waiter": "^4.2.0", + "@smithy/uuid": "^1.1.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=18.0.0" } }, "node_modules/@aws-sdk/client-sso": { - "version": "3.890.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.890.0.tgz", - "integrity": "sha512-vefYNwh/K5V5YiJpFJfoMPNqsoiRTqD7ZnkvR0cjJdwhOIwFnSKN1vz0OMjySTQmVMcG4JKGVul82ou7ErtOhQ==", + "version": "3.901.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.901.0.tgz", + "integrity": "sha512-sGyDjjkJ7ppaE+bAKL/Q5IvVCxtoyBIzN+7+hWTS/mUxWJ9EOq9238IqmVIIK6sYNIzEf9yhobfMARasPYVTNg==", "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.890.0", - "@aws-sdk/middleware-host-header": "3.887.0", - "@aws-sdk/middleware-logger": "3.887.0", - "@aws-sdk/middleware-recursion-detection": "3.887.0", - "@aws-sdk/middleware-user-agent": "3.890.0", - "@aws-sdk/region-config-resolver": "3.890.0", - "@aws-sdk/types": "3.887.0", - "@aws-sdk/util-endpoints": "3.890.0", - "@aws-sdk/util-user-agent-browser": "3.887.0", - "@aws-sdk/util-user-agent-node": "3.890.0", - "@smithy/config-resolver": "^4.2.2", - "@smithy/core": "^3.11.0", - "@smithy/fetch-http-handler": "^5.2.1", - "@smithy/hash-node": "^4.1.1", - "@smithy/invalid-dependency": "^4.1.1", - "@smithy/middleware-content-length": "^4.1.1", - "@smithy/middleware-endpoint": "^4.2.2", - "@smithy/middleware-retry": "^4.2.2", - "@smithy/middleware-serde": "^4.1.1", - "@smithy/middleware-stack": "^4.1.1", - "@smithy/node-config-provider": "^4.2.2", - "@smithy/node-http-handler": "^4.2.1", - "@smithy/protocol-http": "^5.2.1", - "@smithy/smithy-client": "^4.6.2", - "@smithy/types": "^4.5.0", - "@smithy/url-parser": "^4.1.1", - "@smithy/util-base64": "^4.1.0", - "@smithy/util-body-length-browser": "^4.1.0", - "@smithy/util-body-length-node": "^4.1.0", - "@smithy/util-defaults-mode-browser": "^4.1.2", - "@smithy/util-defaults-mode-node": "^4.1.2", - "@smithy/util-endpoints": "^3.1.2", - "@smithy/util-middleware": "^4.1.1", - "@smithy/util-retry": "^4.1.1", - "@smithy/util-utf8": "^4.1.0", + "@aws-sdk/core": "3.901.0", + "@aws-sdk/middleware-host-header": "3.901.0", + "@aws-sdk/middleware-logger": "3.901.0", + "@aws-sdk/middleware-recursion-detection": "3.901.0", + "@aws-sdk/middleware-user-agent": "3.901.0", + "@aws-sdk/region-config-resolver": "3.901.0", + "@aws-sdk/types": "3.901.0", + "@aws-sdk/util-endpoints": "3.901.0", + "@aws-sdk/util-user-agent-browser": "3.901.0", + "@aws-sdk/util-user-agent-node": "3.901.0", + "@smithy/config-resolver": "^4.3.0", + "@smithy/core": "^3.14.0", + "@smithy/fetch-http-handler": "^5.3.0", + "@smithy/hash-node": "^4.2.0", + "@smithy/invalid-dependency": "^4.2.0", + "@smithy/middleware-content-length": "^4.2.0", + "@smithy/middleware-endpoint": "^4.3.0", + "@smithy/middleware-retry": "^4.4.0", + "@smithy/middleware-serde": "^4.2.0", + "@smithy/middleware-stack": "^4.2.0", + "@smithy/node-config-provider": "^4.3.0", + "@smithy/node-http-handler": "^4.3.0", + "@smithy/protocol-http": "^5.3.0", + "@smithy/smithy-client": "^4.7.0", + "@smithy/types": "^4.6.0", + "@smithy/url-parser": "^4.2.0", + "@smithy/util-base64": "^4.2.0", + "@smithy/util-body-length-browser": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.0", + "@smithy/util-defaults-mode-browser": "^4.2.0", + "@smithy/util-defaults-mode-node": "^4.2.0", + "@smithy/util-endpoints": "^3.2.0", + "@smithy/util-middleware": "^4.2.0", + "@smithy/util-retry": "^4.2.0", + "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" }, "engines": { @@ -454,26 +453,24 @@ } }, "node_modules/@aws-sdk/core": { - "version": "3.890.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.890.0.tgz", - "integrity": "sha512-CT+yjhytHdyKvV3Nh/fqBjnZ8+UiQZVz4NMm4LrPATgVSOdfygXHqrWxrPTVgiBtuJWkotg06DF7+pTd5ekLBw==", + "version": "3.901.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.901.0.tgz", + "integrity": "sha512-brKAc3y64tdhyuEf+OPIUln86bRTqkLgb9xkd6kUdIeA5+qmp/N6amItQz+RN4k4O3kqkCPYnAd3LonTKluobw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.887.0", - "@aws-sdk/xml-builder": "3.887.0", - "@smithy/core": "^3.11.0", - "@smithy/node-config-provider": "^4.2.2", - "@smithy/property-provider": "^4.1.1", - "@smithy/protocol-http": "^5.2.1", - "@smithy/signature-v4": "^5.2.1", - "@smithy/smithy-client": "^4.6.2", - "@smithy/types": "^4.5.0", - "@smithy/util-base64": "^4.1.0", - "@smithy/util-body-length-browser": "^4.1.0", - "@smithy/util-middleware": "^4.1.1", - "@smithy/util-utf8": "^4.1.0", - "fast-xml-parser": "5.2.5", + "@aws-sdk/types": "3.901.0", + "@aws-sdk/xml-builder": "3.901.0", + "@smithy/core": "^3.14.0", + "@smithy/node-config-provider": "^4.3.0", + "@smithy/property-provider": "^4.2.0", + "@smithy/protocol-http": "^5.3.0", + "@smithy/signature-v4": "^5.3.0", + "@smithy/smithy-client": "^4.7.0", + "@smithy/types": "^4.6.0", + "@smithy/util-base64": "^4.2.0", + "@smithy/util-middleware": "^4.2.0", + "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" }, "engines": { @@ -481,16 +478,16 @@ } }, "node_modules/@aws-sdk/credential-provider-env": { - "version": "3.890.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.890.0.tgz", - "integrity": "sha512-BtsUa2y0Rs8phmB2ScZ5RuPqZVmxJJXjGfeiXctmLFTxTwoayIK1DdNzOWx6SRMPVc3s2RBGN4vO7T1TwN+ajA==", + "version": "3.901.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.901.0.tgz", + "integrity": "sha512-5hAdVl3tBuARh3zX5MLJ1P/d+Kr5kXtDU3xm1pxUEF4xt2XkEEpwiX5fbkNkz2rbh3BCt2gOHsAbh6b3M7n+DA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.890.0", - "@aws-sdk/types": "3.887.0", - "@smithy/property-provider": "^4.1.1", - "@smithy/types": "^4.5.0", + "@aws-sdk/core": "3.901.0", + "@aws-sdk/types": "3.901.0", + "@smithy/property-provider": "^4.2.0", + "@smithy/types": "^4.6.0", "tslib": "^2.6.2" }, "engines": { @@ -498,21 +495,21 @@ } }, "node_modules/@aws-sdk/credential-provider-http": { - "version": "3.890.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.890.0.tgz", - "integrity": "sha512-0sru3LVwsuGYyzbD90EC/d5HnCZ9PL4O9BA2LYT6b9XceC005Oj86uzE47LXb+mDhTAt3T6ZO0+ZcVQe0DDi8w==", + "version": "3.901.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.901.0.tgz", + "integrity": "sha512-Ggr7+0M6QZEsrqRkK7iyJLf4LkIAacAxHz9c4dm9hnDdU7vqrlJm6g73IxMJXWN1bIV7IxfpzB11DsRrB/oNjQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.890.0", - "@aws-sdk/types": "3.887.0", - "@smithy/fetch-http-handler": "^5.2.1", - "@smithy/node-http-handler": "^4.2.1", - "@smithy/property-provider": "^4.1.1", - "@smithy/protocol-http": "^5.2.1", - "@smithy/smithy-client": "^4.6.2", - "@smithy/types": "^4.5.0", - "@smithy/util-stream": "^4.3.1", + "@aws-sdk/core": "3.901.0", + "@aws-sdk/types": "3.901.0", + "@smithy/fetch-http-handler": "^5.3.0", + "@smithy/node-http-handler": "^4.3.0", + "@smithy/property-provider": "^4.2.0", + "@smithy/protocol-http": "^5.3.0", + "@smithy/smithy-client": "^4.7.0", + "@smithy/types": "^4.6.0", + "@smithy/util-stream": "^4.4.0", "tslib": "^2.6.2" }, "engines": { @@ -520,24 +517,24 @@ } }, "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.890.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.890.0.tgz", - "integrity": "sha512-Mxv7ByftHKH7dE6YXu9gQ6ODXwO1iSO32t8tBrZLS3g8K1knWADIqDFv3yErQtJ8hp27IDxbAbVH/1RQdSkmhA==", + "version": "3.901.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.901.0.tgz", + "integrity": "sha512-zxadcDS0hNJgv8n4hFYJNOXyfjaNE1vvqIiF/JzZSQpSSYXzCd+WxXef5bQh+W3giDtRUmkvP5JLbamEFjZKyw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.890.0", - "@aws-sdk/credential-provider-env": "3.890.0", - "@aws-sdk/credential-provider-http": "3.890.0", - "@aws-sdk/credential-provider-process": "3.890.0", - "@aws-sdk/credential-provider-sso": "3.890.0", - "@aws-sdk/credential-provider-web-identity": "3.890.0", - "@aws-sdk/nested-clients": "3.890.0", - "@aws-sdk/types": "3.887.0", - "@smithy/credential-provider-imds": "^4.1.2", - "@smithy/property-provider": "^4.1.1", - "@smithy/shared-ini-file-loader": "^4.2.0", - "@smithy/types": "^4.5.0", + "@aws-sdk/core": "3.901.0", + "@aws-sdk/credential-provider-env": "3.901.0", + "@aws-sdk/credential-provider-http": "3.901.0", + "@aws-sdk/credential-provider-process": "3.901.0", + "@aws-sdk/credential-provider-sso": "3.901.0", + "@aws-sdk/credential-provider-web-identity": "3.901.0", + "@aws-sdk/nested-clients": "3.901.0", + "@aws-sdk/types": "3.901.0", + "@smithy/credential-provider-imds": "^4.2.0", + "@smithy/property-provider": "^4.2.0", + "@smithy/shared-ini-file-loader": "^4.3.0", + "@smithy/types": "^4.6.0", "tslib": "^2.6.2" }, "engines": { @@ -545,23 +542,23 @@ } }, "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.890.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.890.0.tgz", - "integrity": "sha512-zbPz3mUtaBdch0KoH8/LouRDcYSzyT2ecyCOo5OAFVil7AxT1jvsn4vX78FlnSVpZ4mLuHY8pHTVGi235XiyBA==", + "version": "3.901.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.901.0.tgz", + "integrity": "sha512-dPuFzMF7L1s/lQyT3wDxqLe82PyTH+5o1jdfseTEln64LJMl0ZMWaKX/C1UFNDxaTd35Cgt1bDbjjAWHMiKSFQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/credential-provider-env": "3.890.0", - "@aws-sdk/credential-provider-http": "3.890.0", - "@aws-sdk/credential-provider-ini": "3.890.0", - "@aws-sdk/credential-provider-process": "3.890.0", - "@aws-sdk/credential-provider-sso": "3.890.0", - "@aws-sdk/credential-provider-web-identity": "3.890.0", - "@aws-sdk/types": "3.887.0", - "@smithy/credential-provider-imds": "^4.1.2", - "@smithy/property-provider": "^4.1.1", - "@smithy/shared-ini-file-loader": "^4.2.0", - "@smithy/types": "^4.5.0", + "@aws-sdk/credential-provider-env": "3.901.0", + "@aws-sdk/credential-provider-http": "3.901.0", + "@aws-sdk/credential-provider-ini": "3.901.0", + "@aws-sdk/credential-provider-process": "3.901.0", + "@aws-sdk/credential-provider-sso": "3.901.0", + "@aws-sdk/credential-provider-web-identity": "3.901.0", + "@aws-sdk/types": "3.901.0", + "@smithy/credential-provider-imds": "^4.2.0", + "@smithy/property-provider": "^4.2.0", + "@smithy/shared-ini-file-loader": "^4.3.0", + "@smithy/types": "^4.6.0", "tslib": "^2.6.2" }, "engines": { @@ -569,17 +566,17 @@ } }, "node_modules/@aws-sdk/credential-provider-process": { - "version": "3.890.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.890.0.tgz", - "integrity": "sha512-dWZ54TI1Q+UerF5YOqGiCzY+x2YfHsSQvkyM3T4QDNTJpb/zjiVv327VbSOULOlI7gHKWY/G3tMz0D9nWI7YbA==", + "version": "3.901.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.901.0.tgz", + "integrity": "sha512-/IWgmgM3Cl1wTdJA5HqKMAojxLkYchh5kDuphApxKhupLu6Pu0JBOHU8A5GGeFvOycyaVwosod6zDduINZxe+A==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.890.0", - "@aws-sdk/types": "3.887.0", - "@smithy/property-provider": "^4.1.1", - "@smithy/shared-ini-file-loader": "^4.2.0", - "@smithy/types": "^4.5.0", + "@aws-sdk/core": "3.901.0", + "@aws-sdk/types": "3.901.0", + "@smithy/property-provider": "^4.2.0", + "@smithy/shared-ini-file-loader": "^4.3.0", + "@smithy/types": "^4.6.0", "tslib": "^2.6.2" }, "engines": { @@ -587,19 +584,19 @@ } }, "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.890.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.890.0.tgz", - "integrity": "sha512-ajYCZ6f2+98w8zG/IXcQ+NhWYoI5qPUDovw+gMqMWX/jL1cmZ9PFAwj2Vyq9cbjum5RNWwPLArWytTCgJex4AQ==", + "version": "3.901.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.901.0.tgz", + "integrity": "sha512-SjmqZQHmqFSET7+6xcZgtH7yEyh5q53LN87GqwYlJZ6KJ5oNw11acUNEhUOL1xTSJEvaWqwTIkS2zqrzLcM9bw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/client-sso": "3.890.0", - "@aws-sdk/core": "3.890.0", - "@aws-sdk/token-providers": "3.890.0", - "@aws-sdk/types": "3.887.0", - "@smithy/property-provider": "^4.1.1", - "@smithy/shared-ini-file-loader": "^4.2.0", - "@smithy/types": "^4.5.0", + "@aws-sdk/client-sso": "3.901.0", + "@aws-sdk/core": "3.901.0", + "@aws-sdk/token-providers": "3.901.0", + "@aws-sdk/types": "3.901.0", + "@smithy/property-provider": "^4.2.0", + "@smithy/shared-ini-file-loader": "^4.3.0", + "@smithy/types": "^4.6.0", "tslib": "^2.6.2" }, "engines": { @@ -607,18 +604,18 @@ } }, "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.890.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.890.0.tgz", - "integrity": "sha512-qZ2Mx7BeYR1s0F/H6wePI0MAmkFswmBgrpgMCOt2S4b2IpQPnUa2JbxY3GwW2WqX3nV0KjPW08ctSLMmlq/tKA==", + "version": "3.901.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.901.0.tgz", + "integrity": "sha512-NYjy/6NLxH9m01+pfpB4ql8QgAorJcu8tw69kzHwUd/ql6wUDTbC7HcXqtKlIwWjzjgj2BKL7j6SyFapgCuafA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.890.0", - "@aws-sdk/nested-clients": "3.890.0", - "@aws-sdk/types": "3.887.0", - "@smithy/property-provider": "^4.1.1", - "@smithy/shared-ini-file-loader": "^4.2.0", - "@smithy/types": "^4.5.0", + "@aws-sdk/core": "3.901.0", + "@aws-sdk/nested-clients": "3.901.0", + "@aws-sdk/types": "3.901.0", + "@smithy/property-provider": "^4.2.0", + "@smithy/shared-ini-file-loader": "^4.3.0", + "@smithy/types": "^4.6.0", "tslib": "^2.6.2" }, "engines": { @@ -626,18 +623,18 @@ } }, "node_modules/@aws-sdk/middleware-bucket-endpoint": { - "version": "3.890.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.890.0.tgz", - "integrity": "sha512-X/td72r18uLsB1Hv70uK9cFzvc5Xyd8fde1FR7aU9COzw2ncNFgG2TJkxHBjdkby/T6SL5R4kY49KjVT3KHnzA==", + "version": "3.901.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.901.0.tgz", + "integrity": "sha512-mPF3N6eZlVs9G8aBSzvtoxR1RZqMo1aIwR+X8BAZSkhfj55fVF2no4IfPXfdFO3I66N+zEQ8nKoB0uTATWrogQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.887.0", - "@aws-sdk/util-arn-parser": "3.873.0", - "@smithy/node-config-provider": "^4.2.2", - "@smithy/protocol-http": "^5.2.1", - "@smithy/types": "^4.5.0", - "@smithy/util-config-provider": "^4.1.0", + "@aws-sdk/types": "3.901.0", + "@aws-sdk/util-arn-parser": "3.893.0", + "@smithy/node-config-provider": "^4.3.0", + "@smithy/protocol-http": "^5.3.0", + "@smithy/types": "^4.6.0", + "@smithy/util-config-provider": "^4.2.0", "tslib": "^2.6.2" }, "engines": { @@ -645,15 +642,15 @@ } }, "node_modules/@aws-sdk/middleware-expect-continue": { - "version": "3.887.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.887.0.tgz", - "integrity": "sha512-AlrTZZScDTG9SYeT82BC5cK/6Q4N0miN5xqMW/pbBqP3fNXlsdJOWKB+EKD3V6DV41EV5GVKHKe/1065xKSQ4w==", + "version": "3.901.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.901.0.tgz", + "integrity": "sha512-bwq9nj6MH38hlJwOY9QXIDwa6lI48UsaZpaXbdD71BljEIRlxDzfB4JaYb+ZNNK7RIAdzsP/K05mJty6KJAQHw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.887.0", - "@smithy/protocol-http": "^5.2.1", - "@smithy/types": "^4.5.0", + "@aws-sdk/types": "3.901.0", + "@smithy/protocol-http": "^5.3.0", + "@smithy/types": "^4.6.0", "tslib": "^2.6.2" }, "engines": { @@ -661,24 +658,24 @@ } }, "node_modules/@aws-sdk/middleware-flexible-checksums": { - "version": "3.890.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.890.0.tgz", - "integrity": "sha512-l2HHqI8qtwve1vXWE/cMzi0v53rSz6PNj4aas4K+OR8rvaS4O8OuVdcTC1vQB+0sFSjWNNRFtZnIqixah0XDxw==", + "version": "3.901.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.901.0.tgz", + "integrity": "sha512-63lcKfggVUFyXhE4SsFXShCTCyh7ZHEqXLyYEL4DwX+VWtxutf9t9m3fF0TNUYDE8eEGWiRXhegj8l4FjuW+wA==", "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/crc32": "5.2.0", "@aws-crypto/crc32c": "5.2.0", "@aws-crypto/util": "5.2.0", - "@aws-sdk/core": "3.890.0", - "@aws-sdk/types": "3.887.0", - "@smithy/is-array-buffer": "^4.1.0", - "@smithy/node-config-provider": "^4.2.2", - "@smithy/protocol-http": "^5.2.1", - "@smithy/types": "^4.5.0", - "@smithy/util-middleware": "^4.1.1", - "@smithy/util-stream": "^4.3.1", - "@smithy/util-utf8": "^4.1.0", + "@aws-sdk/core": "3.901.0", + "@aws-sdk/types": "3.901.0", + "@smithy/is-array-buffer": "^4.2.0", + "@smithy/node-config-provider": "^4.3.0", + "@smithy/protocol-http": "^5.3.0", + "@smithy/types": "^4.6.0", + "@smithy/util-middleware": "^4.2.0", + "@smithy/util-stream": "^4.4.0", + "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" }, "engines": { @@ -686,15 +683,15 @@ } }, "node_modules/@aws-sdk/middleware-host-header": { - "version": "3.887.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.887.0.tgz", - "integrity": "sha512-ulzqXv6NNqdu/kr0sgBYupWmahISHY+azpJidtK6ZwQIC+vBUk9NdZeqQpy7KVhIk2xd4+5Oq9rxapPwPI21CA==", + "version": "3.901.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.901.0.tgz", + "integrity": "sha512-yWX7GvRmqBtbNnUW7qbre3GvZmyYwU0WHefpZzDTYDoNgatuYq6LgUIQ+z5C04/kCRoFkAFrHag8a3BXqFzq5A==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.887.0", - "@smithy/protocol-http": "^5.2.1", - "@smithy/types": "^4.5.0", + "@aws-sdk/types": "3.901.0", + "@smithy/protocol-http": "^5.3.0", + "@smithy/types": "^4.6.0", "tslib": "^2.6.2" }, "engines": { @@ -702,14 +699,14 @@ } }, "node_modules/@aws-sdk/middleware-location-constraint": { - "version": "3.887.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.887.0.tgz", - "integrity": "sha512-eU/9Cq4gg2sS32bOomxdx2YF43kb+o70pMhnEBBnVVeqzE8co78SO5FQdWfRTfhNJgTyQ6Vgosx//CNMPIfZPg==", + "version": "3.901.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.901.0.tgz", + "integrity": "sha512-MuCS5R2ngNoYifkVt05CTULvYVWX0dvRT0/Md4jE3a0u0yMygYy31C1zorwfE/SUgAQXyLmUx8ATmPp9PppImQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.887.0", - "@smithy/types": "^4.5.0", + "@aws-sdk/types": "3.901.0", + "@smithy/types": "^4.6.0", "tslib": "^2.6.2" }, "engines": { @@ -717,14 +714,14 @@ } }, "node_modules/@aws-sdk/middleware-logger": { - "version": "3.887.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.887.0.tgz", - "integrity": "sha512-YbbgLI6jKp2qSoAcHnXrQ5jcuc5EYAmGLVFgMVdk8dfCfJLfGGSaOLxF4CXC7QYhO50s+mPPkhBYejCik02Kug==", + "version": "3.901.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.901.0.tgz", + "integrity": "sha512-UoHebjE7el/tfRo8/CQTj91oNUm+5Heus5/a4ECdmWaSCHCS/hXTsU3PTTHAY67oAQR8wBLFPfp3mMvXjB+L2A==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.887.0", - "@smithy/types": "^4.5.0", + "@aws-sdk/types": "3.901.0", + "@smithy/types": "^4.6.0", "tslib": "^2.6.2" }, "engines": { @@ -732,16 +729,16 @@ } }, "node_modules/@aws-sdk/middleware-recursion-detection": { - "version": "3.887.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.887.0.tgz", - "integrity": "sha512-tjrUXFtQnFLo+qwMveq5faxP5MQakoLArXtqieHphSqZTXm21wDJM73hgT4/PQQGTwgYjDKqnqsE1hvk0hcfDw==", + "version": "3.901.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.901.0.tgz", + "integrity": "sha512-Wd2t8qa/4OL0v/oDpCHHYkgsXJr8/ttCxrvCKAt0H1zZe2LlRhY9gpDVKqdertfHrHDj786fOvEQA28G1L75Dg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.887.0", + "@aws-sdk/types": "3.901.0", "@aws/lambda-invoke-store": "^0.0.1", - "@smithy/protocol-http": "^5.2.1", - "@smithy/types": "^4.5.0", + "@smithy/protocol-http": "^5.3.0", + "@smithy/types": "^4.6.0", "tslib": "^2.6.2" }, "engines": { @@ -749,25 +746,25 @@ } }, "node_modules/@aws-sdk/middleware-sdk-s3": { - "version": "3.890.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.890.0.tgz", - "integrity": "sha512-58P1lrE606zpp29xH9Keh3j2BWfa2ciGBtygJTpulRMlqPL3U1gFfU2g5nDYJbjKgRtCgNIBqfmtkL4eikCb9w==", + "version": "3.901.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.901.0.tgz", + "integrity": "sha512-prgjVC3fDT2VIlmQPiw/cLee8r4frTam9GILRUVQyDdNtshNwV3MiaSCLzzQJjKJlLgnBLNUHJCSmvUVtg+3iA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.890.0", - "@aws-sdk/types": "3.887.0", - "@aws-sdk/util-arn-parser": "3.873.0", - "@smithy/core": "^3.11.0", - "@smithy/node-config-provider": "^4.2.2", - "@smithy/protocol-http": "^5.2.1", - "@smithy/signature-v4": "^5.2.1", - "@smithy/smithy-client": "^4.6.2", - "@smithy/types": "^4.5.0", - "@smithy/util-config-provider": "^4.1.0", - "@smithy/util-middleware": "^4.1.1", - "@smithy/util-stream": "^4.3.1", - "@smithy/util-utf8": "^4.1.0", + "@aws-sdk/core": "3.901.0", + "@aws-sdk/types": "3.901.0", + "@aws-sdk/util-arn-parser": "3.893.0", + "@smithy/core": "^3.14.0", + "@smithy/node-config-provider": "^4.3.0", + "@smithy/protocol-http": "^5.3.0", + "@smithy/signature-v4": "^5.3.0", + "@smithy/smithy-client": "^4.7.0", + "@smithy/types": "^4.6.0", + "@smithy/util-config-provider": "^4.2.0", + "@smithy/util-middleware": "^4.2.0", + "@smithy/util-stream": "^4.4.0", + "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" }, "engines": { @@ -775,14 +772,14 @@ } }, "node_modules/@aws-sdk/middleware-ssec": { - "version": "3.887.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.887.0.tgz", - "integrity": "sha512-1ixZks0IDkdac1hjPe4vdLSuD9HznkhblCEb4T0wNyw3Ee1fdXg+MlcPWywzG5zkPXLcIrULUzJg/OSYfaDXcQ==", + "version": "3.901.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.901.0.tgz", + "integrity": "sha512-YiLLJmA3RvjL38mFLuu8fhTTGWtp2qT24VqpucgfoyziYcTgIQkJJmKi90Xp6R6/3VcArqilyRgM1+x8i/em+Q==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.887.0", - "@smithy/types": "^4.5.0", + "@aws-sdk/types": "3.901.0", + "@smithy/types": "^4.6.0", "tslib": "^2.6.2" }, "engines": { @@ -790,18 +787,18 @@ } }, "node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.890.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.890.0.tgz", - "integrity": "sha512-x4+gLrOFGN7PnfxCaQbs3QEF8bMQE4CVxcOp066UEJqr2Pn4yB12Q3O+YntOtESK5NcTxIh7JlhGss95EHzNng==", + "version": "3.901.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.901.0.tgz", + "integrity": "sha512-Zby4F03fvD9xAgXGPywyk4bC1jCbnyubMEYChLYohD+x20ULQCf+AimF/Btn7YL+hBpzh1+RmqmvZcx+RgwgNQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.890.0", - "@aws-sdk/types": "3.887.0", - "@aws-sdk/util-endpoints": "3.890.0", - "@smithy/core": "^3.11.0", - "@smithy/protocol-http": "^5.2.1", - "@smithy/types": "^4.5.0", + "@aws-sdk/core": "3.901.0", + "@aws-sdk/types": "3.901.0", + "@aws-sdk/util-endpoints": "3.901.0", + "@smithy/core": "^3.14.0", + "@smithy/protocol-http": "^5.3.0", + "@smithy/types": "^4.6.0", "tslib": "^2.6.2" }, "engines": { @@ -809,49 +806,49 @@ } }, "node_modules/@aws-sdk/nested-clients": { - "version": "3.890.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.890.0.tgz", - "integrity": "sha512-D5qVNd+qlqdL8duJShzffAqPllGRA4tG7n/GEpL13eNfHChPvGkkUFBMrxSgCAETaTna13G6kq+dMO+SAdbm1A==", + "version": "3.901.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.901.0.tgz", + "integrity": "sha512-feAAAMsVwctk2Tms40ONybvpfJPLCmSdI+G+OTrNpizkGLNl6ik2Ng2RzxY6UqOfN8abqKP/DOUj1qYDRDG8ag==", "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.890.0", - "@aws-sdk/middleware-host-header": "3.887.0", - "@aws-sdk/middleware-logger": "3.887.0", - "@aws-sdk/middleware-recursion-detection": "3.887.0", - "@aws-sdk/middleware-user-agent": "3.890.0", - "@aws-sdk/region-config-resolver": "3.890.0", - "@aws-sdk/types": "3.887.0", - "@aws-sdk/util-endpoints": "3.890.0", - "@aws-sdk/util-user-agent-browser": "3.887.0", - "@aws-sdk/util-user-agent-node": "3.890.0", - "@smithy/config-resolver": "^4.2.2", - "@smithy/core": "^3.11.0", - "@smithy/fetch-http-handler": "^5.2.1", - "@smithy/hash-node": "^4.1.1", - "@smithy/invalid-dependency": "^4.1.1", - "@smithy/middleware-content-length": "^4.1.1", - "@smithy/middleware-endpoint": "^4.2.2", - "@smithy/middleware-retry": "^4.2.2", - "@smithy/middleware-serde": "^4.1.1", - "@smithy/middleware-stack": "^4.1.1", - "@smithy/node-config-provider": "^4.2.2", - "@smithy/node-http-handler": "^4.2.1", - "@smithy/protocol-http": "^5.2.1", - "@smithy/smithy-client": "^4.6.2", - "@smithy/types": "^4.5.0", - "@smithy/url-parser": "^4.1.1", - "@smithy/util-base64": "^4.1.0", - "@smithy/util-body-length-browser": "^4.1.0", - "@smithy/util-body-length-node": "^4.1.0", - "@smithy/util-defaults-mode-browser": "^4.1.2", - "@smithy/util-defaults-mode-node": "^4.1.2", - "@smithy/util-endpoints": "^3.1.2", - "@smithy/util-middleware": "^4.1.1", - "@smithy/util-retry": "^4.1.1", - "@smithy/util-utf8": "^4.1.0", + "@aws-sdk/core": "3.901.0", + "@aws-sdk/middleware-host-header": "3.901.0", + "@aws-sdk/middleware-logger": "3.901.0", + "@aws-sdk/middleware-recursion-detection": "3.901.0", + "@aws-sdk/middleware-user-agent": "3.901.0", + "@aws-sdk/region-config-resolver": "3.901.0", + "@aws-sdk/types": "3.901.0", + "@aws-sdk/util-endpoints": "3.901.0", + "@aws-sdk/util-user-agent-browser": "3.901.0", + "@aws-sdk/util-user-agent-node": "3.901.0", + "@smithy/config-resolver": "^4.3.0", + "@smithy/core": "^3.14.0", + "@smithy/fetch-http-handler": "^5.3.0", + "@smithy/hash-node": "^4.2.0", + "@smithy/invalid-dependency": "^4.2.0", + "@smithy/middleware-content-length": "^4.2.0", + "@smithy/middleware-endpoint": "^4.3.0", + "@smithy/middleware-retry": "^4.4.0", + "@smithy/middleware-serde": "^4.2.0", + "@smithy/middleware-stack": "^4.2.0", + "@smithy/node-config-provider": "^4.3.0", + "@smithy/node-http-handler": "^4.3.0", + "@smithy/protocol-http": "^5.3.0", + "@smithy/smithy-client": "^4.7.0", + "@smithy/types": "^4.6.0", + "@smithy/url-parser": "^4.2.0", + "@smithy/util-base64": "^4.2.0", + "@smithy/util-body-length-browser": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.0", + "@smithy/util-defaults-mode-browser": "^4.2.0", + "@smithy/util-defaults-mode-node": "^4.2.0", + "@smithy/util-endpoints": "^3.2.0", + "@smithy/util-middleware": "^4.2.0", + "@smithy/util-retry": "^4.2.0", + "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" }, "engines": { @@ -859,17 +856,17 @@ } }, "node_modules/@aws-sdk/region-config-resolver": { - "version": "3.890.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.890.0.tgz", - "integrity": "sha512-VfdT+tkF9groRYNzKvQCsCGDbOQdeBdzyB1d6hWiq22u13UafMIoskJ1ec0i0H1X29oT6mjTitfnvPq1UiKwzQ==", + "version": "3.901.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.901.0.tgz", + "integrity": "sha512-7F0N888qVLHo4CSQOsnkZ4QAp8uHLKJ4v3u09Ly5k4AEStrSlFpckTPyUx6elwGL+fxGjNE2aakK8vEgzzCV0A==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.887.0", - "@smithy/node-config-provider": "^4.2.2", - "@smithy/types": "^4.5.0", - "@smithy/util-config-provider": "^4.1.0", - "@smithy/util-middleware": "^4.1.1", + "@aws-sdk/types": "3.901.0", + "@smithy/node-config-provider": "^4.3.0", + "@smithy/types": "^4.6.0", + "@smithy/util-config-provider": "^4.2.0", + "@smithy/util-middleware": "^4.2.0", "tslib": "^2.6.2" }, "engines": { @@ -877,17 +874,17 @@ } }, "node_modules/@aws-sdk/signature-v4-multi-region": { - "version": "3.890.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.890.0.tgz", - "integrity": "sha512-il8kb2/wDLXhemN3p7v4MvbvqoMuo7Ug3ihuIUIhPtSVjcnn+BISJU0S+5YTl8TXf6qxML9VrfxL0pmuhO3BsA==", + "version": "3.901.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.901.0.tgz", + "integrity": "sha512-2IWxbll/pRucp1WQkHi2W5E2SVPGBvk4Is923H7gpNksbVFws18ItjMM8ZpGm44cJEoy1zR5gjhLFklatpuoOw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/middleware-sdk-s3": "3.890.0", - "@aws-sdk/types": "3.887.0", - "@smithy/protocol-http": "^5.2.1", - "@smithy/signature-v4": "^5.2.1", - "@smithy/types": "^4.5.0", + "@aws-sdk/middleware-sdk-s3": "3.901.0", + "@aws-sdk/types": "3.901.0", + "@smithy/protocol-http": "^5.3.0", + "@smithy/signature-v4": "^5.3.0", + "@smithy/types": "^4.6.0", "tslib": "^2.6.2" }, "engines": { @@ -895,18 +892,18 @@ } }, "node_modules/@aws-sdk/token-providers": { - "version": "3.890.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.890.0.tgz", - "integrity": "sha512-+pK/0iQEpPmnztbAw0NNmb+B5pPy8VLu+Ab4SJLgVp41RE9NO13VQtrzUbh61TTAVMrzqWlLQ2qmAl2Fk4VNgw==", + "version": "3.901.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.901.0.tgz", + "integrity": "sha512-pJEr1Ggbc/uVTDqp9IbNu9hdr0eQf3yZix3s4Nnyvmg4xmJSGAlbPC9LrNr5u3CDZoc8Z9CuLrvbP4MwYquNpQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.890.0", - "@aws-sdk/nested-clients": "3.890.0", - "@aws-sdk/types": "3.887.0", - "@smithy/property-provider": "^4.1.1", - "@smithy/shared-ini-file-loader": "^4.2.0", - "@smithy/types": "^4.5.0", + "@aws-sdk/core": "3.901.0", + "@aws-sdk/nested-clients": "3.901.0", + "@aws-sdk/types": "3.901.0", + "@smithy/property-provider": "^4.2.0", + "@smithy/shared-ini-file-loader": "^4.3.0", + "@smithy/types": "^4.6.0", "tslib": "^2.6.2" }, "engines": { @@ -914,13 +911,13 @@ } }, "node_modules/@aws-sdk/types": { - "version": "3.887.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.887.0.tgz", - "integrity": "sha512-fmTEJpUhsPsovQ12vZSpVTEP/IaRoJAMBGQXlQNjtCpkBp6Iq3KQDa/HDaPINE+3xxo6XvTdtibsNOd5zJLV9A==", + "version": "3.901.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.901.0.tgz", + "integrity": "sha512-FfEM25hLEs4LoXsLXQ/q6X6L4JmKkKkbVFpKD4mwfVHtRVQG6QxJiCPcrkcPISquiy6esbwK2eh64TWbiD60cg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.5.0", + "@smithy/types": "^4.6.0", "tslib": "^2.6.2" }, "engines": { @@ -928,9 +925,9 @@ } }, "node_modules/@aws-sdk/util-arn-parser": { - "version": "3.873.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-arn-parser/-/util-arn-parser-3.873.0.tgz", - "integrity": "sha512-qag+VTqnJWDn8zTAXX4wiVioa0hZDQMtbZcGRERVnLar4/3/VIKBhxX2XibNQXFu1ufgcRn4YntT/XEPecFWcg==", + "version": "3.893.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-arn-parser/-/util-arn-parser-3.893.0.tgz", + "integrity": "sha512-u8H4f2Zsi19DGnwj5FSZzDMhytYF/bCh37vAtBsn3cNDL3YG578X5oc+wSX54pM3tOxS+NY7tvOAo52SW7koUA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -941,16 +938,16 @@ } }, "node_modules/@aws-sdk/util-endpoints": { - "version": "3.890.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.890.0.tgz", - "integrity": "sha512-nJ8v1x9ZQKzMRK4dS4oefOMIHqb6cguctTcx1RB9iTaFOR5pP7bvq+D4mvNZ6vBxiHg1dQGBUUgl5XJmdR7atQ==", + "version": "3.901.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.901.0.tgz", + "integrity": "sha512-5nZP3hGA8FHEtKvEQf4Aww5QZOkjLW1Z+NixSd+0XKfHvA39Ah5sZboScjLx0C9kti/K3OGW1RCx5K9Zc3bZqg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.887.0", - "@smithy/types": "^4.5.0", - "@smithy/url-parser": "^4.1.1", - "@smithy/util-endpoints": "^3.1.2", + "@aws-sdk/types": "3.901.0", + "@smithy/types": "^4.6.0", + "@smithy/url-parser": "^4.2.0", + "@smithy/util-endpoints": "^3.2.0", "tslib": "^2.6.2" }, "engines": { @@ -958,9 +955,9 @@ } }, "node_modules/@aws-sdk/util-locate-window": { - "version": "3.873.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.873.0.tgz", - "integrity": "sha512-xcVhZF6svjM5Rj89T1WzkjQmrTF6dpR2UvIHPMTnSZoNe6CixejPZ6f0JJ2kAhO8H+dUHwNBlsUgOTIKiK/Syg==", + "version": "3.893.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.893.0.tgz", + "integrity": "sha512-T89pFfgat6c8nMmpI8eKjBcDcgJq36+m9oiXbcUzeU55MP9ZuGgBomGjGnHaEyF36jenW9gmg3NfZDm0AO2XPg==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -971,29 +968,29 @@ } }, "node_modules/@aws-sdk/util-user-agent-browser": { - "version": "3.887.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.887.0.tgz", - "integrity": "sha512-X71UmVsYc6ZTH4KU6hA5urOzYowSXc3qvroagJNLJYU1ilgZ529lP4J9XOYfEvTXkLR1hPFSRxa43SrwgelMjA==", + "version": "3.901.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.901.0.tgz", + "integrity": "sha512-Ntb6V/WFI21Ed4PDgL/8NSfoZQQf9xzrwNgiwvnxgAl/KvAvRBgQtqj5gHsDX8Nj2YmJuVoHfH9BGjL9VQ4WNg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.887.0", - "@smithy/types": "^4.5.0", + "@aws-sdk/types": "3.901.0", + "@smithy/types": "^4.6.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.890.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.890.0.tgz", - "integrity": "sha512-s85NkCxKoAlUvx7UP7OelxLqwTi27Tps9/Q+4N+9rEUjThxEnDsqJSStJ1XiYhddz1xc/vxMvPjYN0qX6EKPtA==", + "version": "3.901.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.901.0.tgz", + "integrity": "sha512-l59KQP5TY7vPVUfEURc7P5BJKuNg1RSsAKBQW7LHLECXjLqDUbo2SMLrexLBEoArSt6E8QOrIN0C8z/0Xk0jYw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@aws-sdk/middleware-user-agent": "3.890.0", - "@aws-sdk/types": "3.887.0", - "@smithy/node-config-provider": "^4.2.2", - "@smithy/types": "^4.5.0", + "@aws-sdk/middleware-user-agent": "3.901.0", + "@aws-sdk/types": "3.901.0", + "@smithy/node-config-provider": "^4.3.0", + "@smithy/types": "^4.6.0", "tslib": "^2.6.2" }, "engines": { @@ -1009,13 +1006,14 @@ } }, "node_modules/@aws-sdk/xml-builder": { - "version": "3.887.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.887.0.tgz", - "integrity": "sha512-lMwgWK1kNgUhHGfBvO/5uLe7TKhycwOn3eRCqsKPT9aPCx/HWuTlpcQp8oW2pCRGLS7qzcxqpQulcD+bbUL7XQ==", + "version": "3.901.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.901.0.tgz", + "integrity": "sha512-pxFCkuAP7Q94wMTNPAwi6hEtNrp/BdFf+HOrIEeFQsk4EoOmpKY3I6S+u6A9Wg295J80Kh74LqDWM22ux3z6Aw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.5.0", + "@smithy/types": "^4.6.0", + "fast-xml-parser": "5.2.5", "tslib": "^2.6.2" }, "engines": { @@ -1823,9 +1821,9 @@ } }, "node_modules/@contentstack/utils": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@contentstack/utils/-/utils-1.4.2.tgz", - "integrity": "sha512-OGRYPws6ceM9Qf+s9CPh5OeG+ujBSchqvuAL0lvxMnoFm5pM9bZkxP42e/fVGOZSP96eoSfUzqZyBZgLupxedg==", + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/@contentstack/utils/-/utils-1.4.4.tgz", + "integrity": "sha512-Lk+7WxhBc8SdpRACnCjPg0RTzObT02o+4sZjcW2b5GxTzkVt1vsGwAU16mVxD6UkpLOYuoas7nmZX7Jjce3UEg==", "license": "MIT" }, "node_modules/@cspotcode/source-map-support": { @@ -1853,12 +1851,12 @@ } }, "node_modules/@dabh/diagnostics": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", - "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.8.tgz", + "integrity": "sha512-R4MSXTVnuMzGD7bzHdW2ZhhdPC/igELENcq5IjEverBvq5hn1SXCWcsi6eSsdWP0/Ur+SItRRjAktmdoX/8R/Q==", "license": "MIT", "dependencies": { - "colorspace": "1.1.x", + "@so-ric/colorspace": "^1.1.6", "enabled": "2.0.x", "kuler": "^2.0.0" } @@ -1915,9 +1913,9 @@ } }, "node_modules/@es-joy/jsdoccomment/node_modules/@typescript-eslint/types": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.44.0.tgz", - "integrity": "sha512-ZSl2efn44VsYM0MfDQe68RKzBz75NPgLQXuGypmym6QVOWL5kegTZuZ02xRAT9T+onqvM6T8CdQk0OwYMB6ZvA==", + "version": "8.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.45.0.tgz", + "integrity": "sha512-WugXLuOIq67BMgQInIxxnsSyRLFxdkJEJu8r4ngLR56q/4Q5LrbfkFRH27vMTjxEK8Pyz7QfzuZe/G15qQnVRA==", "dev": true, "license": "MIT", "engines": { @@ -2400,11 +2398,14 @@ } }, "node_modules/@eslint/compat": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@eslint/compat/-/compat-1.3.2.tgz", - "integrity": "sha512-jRNwzTbd6p2Rw4sZ1CgWRS8YMtqG15YyZf7zvb6gY2rB2u6n+2Z+ELW0GtL0fQgyl0pr4Y/BzBfng/BdsereRA==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@eslint/compat/-/compat-1.4.0.tgz", + "integrity": "sha512-DEzm5dKeDBPm3r08Ixli/0cmxr8LkRdwxMRUIJBlSCpAwSrvFEJpVBzV+66JhDxiaqKxnRzCXhtiMiczF7Hglg==", "dev": true, "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.16.0" + }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -2460,20 +2461,23 @@ } }, "node_modules/@eslint/config-helpers": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.1.tgz", - "integrity": "sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.0.tgz", + "integrity": "sha512-WUFvV4WoIwW8Bv0KeKCIIEgdSiFOsulyN0xrMu+7z43q/hkOLXjvb5u7UC9jDxvRzcrbEmuZBX5yJZz1741jog==", "dev": true, "license": "Apache-2.0", "peer": true, + "dependencies": { + "@eslint/core": "^0.16.0" + }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@eslint/core": { - "version": "0.15.2", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.2.tgz", - "integrity": "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==", + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.16.0.tgz", + "integrity": "sha512-nmC8/totwobIiFcGkDza3GIKfAw1+hLiYVrh3I1nIomQ8PEr5cxg34jnkmGawul/ep52wGRAcyeDCNtWKSOj4Q==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -2525,6 +2529,33 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@eslint/css/node_modules/@eslint/plugin-kit": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.5.tgz", + "integrity": "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.15.2", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/css/node_modules/@eslint/plugin-kit/node_modules/@eslint/core": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.2.tgz", + "integrity": "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@eslint/eslintrc": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", @@ -2623,6 +2654,33 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@eslint/json/node_modules/@eslint/core": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.2.tgz", + "integrity": "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/json/node_modules/@eslint/plugin-kit": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.5.tgz", + "integrity": "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.15.2", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@eslint/object-schema": { "version": "2.1.6", "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", @@ -2635,13 +2693,14 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.5.tgz", - "integrity": "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.0.tgz", + "integrity": "sha512-sB5uyeq+dwCWyPi31B2gQlVlo+j5brPlWx4yZBrEaRo/nhdDE8Xke1gsGgtiBdaBTxuTkceLVuVt/pclrasb0A==", "dev": true, "license": "Apache-2.0", + "peer": true, "dependencies": { - "@eslint/core": "^0.15.2", + "@eslint/core": "^0.16.0", "levn": "^0.4.1" }, "engines": { @@ -2870,9 +2929,9 @@ } }, "node_modules/@inquirer/core/node_modules/@types/node": { - "version": "22.18.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.18.5.tgz", - "integrity": "sha512-g9BpPfJvxYBXUWI9bV37j6d6LTMNQ88hPwdWWUeYZnMhlo66FIg9gCc1/DZb15QylJSKwOZjwrckvOTWpOiChg==", + "version": "22.18.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.18.8.tgz", + "integrity": "sha512-pAZSHMiagDR7cARo/cch1f3rXy0AEXwsVsVH09FcyeJVAzCnGgmYis7P3JidtTUjyadhTeSo8TgRPswstghDaw==", "dev": true, "license": "MIT", "dependencies": { @@ -3670,16 +3729,16 @@ } }, "node_modules/@oclif/core": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/@oclif/core/-/core-4.5.3.tgz", - "integrity": "sha512-ISoFlfmsuxJvNKXhabCO4/KqNXDQdLHchZdTPfZbtqAsQbqTw5IKitLVZq9Sz1LWizN37HILp4u0350B8scBjg==", + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/@oclif/core/-/core-4.5.4.tgz", + "integrity": "sha512-78YYJls8+KG96tReyUsesKKIKqC0qbFSY1peUSrt0P2uGsrgAuU9axQ0iBQdhAlIwZDcTyaj+XXVQkz2kl/O0w==", "license": "MIT", "dependencies": { "ansi-escapes": "^4.3.2", "ansis": "^3.17.0", "clean-stack": "^3.0.1", "cli-spinners": "^2.9.2", - "debug": "^4.4.0", + "debug": "^4.4.3", "ejs": "^3.1.10", "get-package-type": "^0.1.0", "indent-string": "^4.0.0", @@ -4042,14 +4101,14 @@ } }, "node_modules/@oclif/plugin-not-found/node_modules/@types/node": { - "version": "24.5.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.5.1.tgz", - "integrity": "sha512-/SQdmUP2xa+1rdx7VwB9yPq8PaKej8TD5cQ+XfKDPWWC+VDJU4rvVVagXqKUzhKjtFoNA8rXDJAkCxQPAe00+Q==", + "version": "24.7.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.7.0.tgz", + "integrity": "sha512-IbKooQVqUBrlzWTi79E8Fw78l8k1RNtlDDNWsFZs7XonuQSJ8oNYfEeclhprUldXISRMLzBpILuKgPlIxm+/Yw==", "license": "MIT", "optional": true, "peer": true, "dependencies": { - "undici-types": "~7.12.0" + "undici-types": "~7.14.0" } }, "node_modules/@oclif/plugin-not-found/node_modules/chardet": { @@ -4105,9 +4164,9 @@ } }, "node_modules/@oclif/plugin-not-found/node_modules/undici-types": { - "version": "7.12.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.12.0.tgz", - "integrity": "sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ==", + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.14.0.tgz", + "integrity": "sha512-QQiYxHuyZ9gQUIrmPo3IA+hUl4KYk8uSA7cHrcKd/l3p1OTpZcM0Tbp9x7FAtXdAYhlasd60ncPpgu6ihG6TOA==", "license": "MIT", "optional": true, "peer": true @@ -4127,15 +4186,15 @@ } }, "node_modules/@oclif/plugin-plugins": { - "version": "5.4.47", - "resolved": "https://registry.npmjs.org/@oclif/plugin-plugins/-/plugin-plugins-5.4.47.tgz", - "integrity": "sha512-eUWNbyYwKPbH+Ca98eI2OBZ6IioWM1aJ6SGp9TrVGRu2qNeDtG/qnqemv3v5qcHzPK211CPSvHJBFYef3J9rBg==", + "version": "5.4.49", + "resolved": "https://registry.npmjs.org/@oclif/plugin-plugins/-/plugin-plugins-5.4.49.tgz", + "integrity": "sha512-OeDLxEjbfEj5AN/wEKXzSY4VC+svBVdjrlHjxm4/e1ZnK3ZuSe1MeABmJc4mXmWwG/zagtNtSAKmTOWhe+WmmA==", "license": "MIT", "dependencies": { - "@oclif/core": "^4.5.3", + "@oclif/core": "^4.5.4", "ansis": "^3.17.0", "debug": "^4.4.0", - "npm": "^10.9.3", + "npm": "^10.9.4", "npm-package-arg": "^11.0.3", "npm-run-path": "^5.3.0", "object-treeify": "^4.0.1", @@ -4331,9 +4390,9 @@ } }, "node_modules/@rollup/plugin-node-resolve": { - "version": "16.0.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-16.0.1.tgz", - "integrity": "sha512-tk5YCxJWIG81umIvNkSod2qK5KyQW19qcBF/B78n1bjtOON6gzKoVeSzAE8yHCZEDmqkHKkxplExA8KzdJLJpA==", + "version": "16.0.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-16.0.2.tgz", + "integrity": "sha512-tCtHJ2BlhSoK4cCs25NMXfV7EALKr0jyasmqVCq3y9cBrKdmJhtsy1iTz36Xhk/O+pDJbzawxF4K6ZblqCnITQ==", "license": "MIT", "dependencies": { "@rollup/pluginutils": "^5.0.1", @@ -4403,9 +4462,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.50.2.tgz", - "integrity": "sha512-uLN8NAiFVIRKX9ZQha8wy6UUs06UNSZ32xj6giK/rmMXAgKahwExvK6SsmgU5/brh4w/nSgj8e0k3c1HBQpa0A==", + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.4.tgz", + "integrity": "sha512-BTm2qKNnWIQ5auf4deoetINJm2JzvihvGb9R6K/ETwKLql/Bb3Eg2H1FBp1gUb4YGbydMA3jcmQTR73q7J+GAA==", "cpu": [ "arm" ], @@ -4416,9 +4475,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.50.2.tgz", - "integrity": "sha512-oEouqQk2/zxxj22PNcGSskya+3kV0ZKH+nQxuCCOGJ4oTXBdNTbv+f/E3c74cNLeMO1S5wVWacSws10TTSB77g==", + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.4.tgz", + "integrity": "sha512-P9LDQiC5vpgGFgz7GSM6dKPCiqR3XYN1WwJKA4/BUVDjHpYsf3iBEmVz62uyq20NGYbiGPR5cNHI7T1HqxNs2w==", "cpu": [ "arm64" ], @@ -4429,9 +4488,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.50.2.tgz", - "integrity": "sha512-OZuTVTpj3CDSIxmPgGH8en/XtirV5nfljHZ3wrNwvgkT5DQLhIKAeuFSiwtbMto6oVexV0k1F1zqURPKf5rI1Q==", + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.4.tgz", + "integrity": "sha512-QRWSW+bVccAvZF6cbNZBJwAehmvG9NwfWHwMy4GbWi/BQIA/laTIktebT2ipVjNncqE6GLPxOok5hsECgAxGZg==", "cpu": [ "arm64" ], @@ -4442,9 +4501,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.50.2.tgz", - "integrity": "sha512-Wa/Wn8RFkIkr1vy1k1PB//VYhLnlnn5eaJkfTQKivirOvzu5uVd2It01ukeQstMursuz7S1bU+8WW+1UPXpa8A==", + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.4.tgz", + "integrity": "sha512-hZgP05pResAkRJxL1b+7yxCnXPGsXU0fG9Yfd6dUaoGk+FhdPKCJ5L1Sumyxn8kvw8Qi5PvQ8ulenUbRjzeCTw==", "cpu": [ "x64" ], @@ -4455,9 +4514,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.50.2.tgz", - "integrity": "sha512-QkzxvH3kYN9J1w7D1A+yIMdI1pPekD+pWx7G5rXgnIlQ1TVYVC6hLl7SOV9pi5q9uIDF9AuIGkuzcbF7+fAhow==", + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.4.tgz", + "integrity": "sha512-xmc30VshuBNUd58Xk4TKAEcRZHaXlV+tCxIXELiE9sQuK3kG8ZFgSPi57UBJt8/ogfhAF5Oz4ZSUBN77weM+mQ==", "cpu": [ "arm64" ], @@ -4468,9 +4527,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.50.2.tgz", - "integrity": "sha512-dkYXB0c2XAS3a3jmyDkX4Jk0m7gWLFzq1C3qUnJJ38AyxIF5G/dyS4N9B30nvFseCfgtCEdbYFhk0ChoCGxPog==", + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.4.tgz", + "integrity": "sha512-WdSLpZFjOEqNZGmHflxyifolwAiZmDQzuOzIq9L27ButpCVpD7KzTRtEG1I0wMPFyiyUdOO+4t8GvrnBLQSwpw==", "cpu": [ "x64" ], @@ -4481,9 +4540,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.50.2.tgz", - "integrity": "sha512-9VlPY/BN3AgbukfVHAB8zNFWB/lKEuvzRo1NKev0Po8sYFKx0i+AQlCYftgEjcL43F2h9Ui1ZSdVBc4En/sP2w==", + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.4.tgz", + "integrity": "sha512-xRiOu9Of1FZ4SxVbB0iEDXc4ddIcjCv2aj03dmW8UrZIW7aIQ9jVJdLBIhxBI+MaTnGAKyvMwPwQnoOEvP7FgQ==", "cpu": [ "arm" ], @@ -4494,9 +4553,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.50.2.tgz", - "integrity": "sha512-+GdKWOvsifaYNlIVf07QYan1J5F141+vGm5/Y8b9uCZnG/nxoGqgCmR24mv0koIWWuqvFYnbURRqw1lv7IBINw==", + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.4.tgz", + "integrity": "sha512-FbhM2p9TJAmEIEhIgzR4soUcsW49e9veAQCziwbR+XWB2zqJ12b4i/+hel9yLiD8pLncDH4fKIPIbt5238341Q==", "cpu": [ "arm" ], @@ -4507,9 +4566,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.50.2.tgz", - "integrity": "sha512-df0Eou14ojtUdLQdPFnymEQteENwSJAdLf5KCDrmZNsy1c3YaCNaJvYsEUHnrg+/DLBH612/R0xd3dD03uz2dg==", + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.4.tgz", + "integrity": "sha512-4n4gVwhPHR9q/g8lKCyz0yuaD0MvDf7dV4f9tHt0C73Mp8h38UCtSCSE6R9iBlTbXlmA8CjpsZoujhszefqueg==", "cpu": [ "arm64" ], @@ -4520,9 +4579,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.50.2.tgz", - "integrity": "sha512-iPeouV0UIDtz8j1YFR4OJ/zf7evjauqv7jQ/EFs0ClIyL+by++hiaDAfFipjOgyz6y6xbDvJuiU4HwpVMpRFDQ==", + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.4.tgz", + "integrity": "sha512-u0n17nGA0nvi/11gcZKsjkLj1QIpAuPFQbR48Subo7SmZJnGxDpspyw2kbpuoQnyK+9pwf3pAoEXerJs/8Mi9g==", "cpu": [ "arm64" ], @@ -4533,9 +4592,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.50.2.tgz", - "integrity": "sha512-OL6KaNvBopLlj5fTa5D5bau4W82f+1TyTZRr2BdnfsrnQnmdxh4okMxR2DcDkJuh4KeoQZVuvHvzuD/lyLn2Kw==", + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.4.tgz", + "integrity": "sha512-0G2c2lpYtbTuXo8KEJkDkClE/+/2AFPdPAbmaHoE870foRFs4pBrDehilMcrSScrN/fB/1HTaWO4bqw+ewBzMQ==", "cpu": [ "loong64" ], @@ -4546,9 +4605,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.50.2.tgz", - "integrity": "sha512-I21VJl1w6z/K5OTRl6aS9DDsqezEZ/yKpbqlvfHbW0CEF5IL8ATBMuUx6/mp683rKTK8thjs/0BaNrZLXetLag==", + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.4.tgz", + "integrity": "sha512-teSACug1GyZHmPDv14VNbvZFX779UqWTsd7KtTM9JIZRDI5NUwYSIS30kzI8m06gOPB//jtpqlhmraQ68b5X2g==", "cpu": [ "ppc64" ], @@ -4559,9 +4618,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.50.2.tgz", - "integrity": "sha512-Hq6aQJT/qFFHrYMjS20nV+9SKrXL2lvFBENZoKfoTH2kKDOJqff5OSJr4x72ZaG/uUn+XmBnGhfr4lwMRrmqCQ==", + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.4.tgz", + "integrity": "sha512-/MOEW3aHjjs1p4Pw1Xk4+3egRevx8Ji9N6HUIA1Ifh8Q+cg9dremvFCUbOX2Zebz80BwJIgCBUemjqhU5XI5Eg==", "cpu": [ "riscv64" ], @@ -4572,9 +4631,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.50.2.tgz", - "integrity": "sha512-82rBSEXRv5qtKyr0xZ/YMF531oj2AIpLZkeNYxmKNN6I2sVE9PGegN99tYDLK2fYHJITL1P2Lgb4ZXnv0PjQvw==", + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.4.tgz", + "integrity": "sha512-1HHmsRyh845QDpEWzOFtMCph5Ts+9+yllCrREuBR/vg2RogAQGGBRC8lDPrPOMnrdOJ+mt1WLMOC2Kao/UwcvA==", "cpu": [ "riscv64" ], @@ -4585,9 +4644,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.50.2.tgz", - "integrity": "sha512-4Q3S3Hy7pC6uaRo9gtXUTJ+EKo9AKs3BXKc2jYypEcMQ49gDPFU2P1ariX9SEtBzE5egIX6fSUmbmGazwBVF9w==", + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.4.tgz", + "integrity": "sha512-seoeZp4L/6D1MUyjWkOMRU6/iLmCU2EjbMTyAG4oIOs1/I82Y5lTeaxW0KBfkUdHAWN7j25bpkt0rjnOgAcQcA==", "cpu": [ "s390x" ], @@ -4598,9 +4657,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.50.2.tgz", - "integrity": "sha512-9Jie/At6qk70dNIcopcL4p+1UirusEtznpNtcq/u/C5cC4HBX7qSGsYIcG6bdxj15EYWhHiu02YvmdPzylIZlA==", + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.4.tgz", + "integrity": "sha512-Wi6AXf0k0L7E2gteNsNHUs7UMwCIhsCTs6+tqQ5GPwVRWMaflqGec4Sd8n6+FNFDw9vGcReqk2KzBDhCa1DLYg==", "cpu": [ "x64" ], @@ -4611,9 +4670,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.50.2.tgz", - "integrity": "sha512-HPNJwxPL3EmhzeAnsWQCM3DcoqOz3/IC6de9rWfGR8ZCuEHETi9km66bH/wG3YH0V3nyzyFEGUZeL5PKyy4xvw==", + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.4.tgz", + "integrity": "sha512-dtBZYjDmCQ9hW+WgEkaffvRRCKm767wWhxsFW3Lw86VXz/uJRuD438/XvbZT//B96Vs8oTA8Q4A0AfHbrxP9zw==", "cpu": [ "x64" ], @@ -4624,9 +4683,9 @@ ] }, "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.50.2.tgz", - "integrity": "sha512-nMKvq6FRHSzYfKLHZ+cChowlEkR2lj/V0jYj9JnGUVPL2/mIeFGmVM2mLaFeNa5Jev7W7TovXqXIG2d39y1KYA==", + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.4.tgz", + "integrity": "sha512-1ox+GqgRWqaB1RnyZXL8PD6E5f7YyRUJYnCqKpNzxzP0TkaUh112NDrR9Tt+C8rJ4x5G9Mk8PQR3o7Ku2RKqKA==", "cpu": [ "arm64" ], @@ -4637,9 +4696,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.50.2.tgz", - "integrity": "sha512-eFUvvnTYEKeTyHEijQKz81bLrUQOXKZqECeiWH6tb8eXXbZk+CXSG2aFrig2BQ/pjiVRj36zysjgILkqarS2YA==", + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.4.tgz", + "integrity": "sha512-8GKr640PdFNXwzIE0IrkMWUNUomILLkfeHjXBi/nUvFlpZP+FA8BKGKpacjW6OUUHaNI6sUURxR2U2g78FOHWQ==", "cpu": [ "arm64" ], @@ -4650,9 +4709,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.50.2.tgz", - "integrity": "sha512-cBaWmXqyfRhH8zmUxK3d3sAhEWLrtMjWBRwdMMHJIXSjvjLKvv49adxiEz+FJ8AP90apSDDBx2Tyd/WylV6ikA==", + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.4.tgz", + "integrity": "sha512-AIy/jdJ7WtJ/F6EcfOb2GjR9UweO0n43jNObQMb6oGxkYTfLcnN7vYYpG+CN3lLxrQkzWnMOoNSHTW54pgbVxw==", "cpu": [ "ia32" ], @@ -4662,10 +4721,23 @@ "win32" ] }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.4.tgz", + "integrity": "sha512-UF9KfsH9yEam0UjTwAgdK0anlQ7c8/pWPU2yVjyWcF1I1thABt6WXE47cI71pGiZ8wGvxohBoLnxM04L/wj8mQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.50.2.tgz", - "integrity": "sha512-APwKy6YUhvZaEoHyM+9xqmTpviEI+9eL7LoCH+aLcvWYHJ663qG5zx7WzWZY+a9qkg5JtzcMyJ9z0WtQBMDmgA==", + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.4.tgz", + "integrity": "sha512-bf9PtUa0u8IXDVxzRToFQKsNCRz9qLYfR/MpECxl4mRoWYjAeFjgxj1XdZr2M/GNVpT05p+LgQOHopYDlUu6/w==", "cpu": [ "x64" ], @@ -4767,13 +4839,13 @@ "license": "(Unlicense OR Apache-2.0)" }, "node_modules/@smithy/abort-controller": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.1.1.tgz", - "integrity": "sha512-vkzula+IwRvPR6oKQhMYioM3A/oX/lFCZiwuxkQbRhqJS2S4YRY2k7k/SyR2jMf3607HLtbEwlRxi0ndXHMjRg==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.2.0.tgz", + "integrity": "sha512-PLUYa+SUKOEZtXFURBu/CNxlsxfaFGxSBPcStL13KpVeVWIfdezWyDqkz7iDLmwnxojXD0s5KzuB5HGHvt4Aeg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.5.0", + "@smithy/types": "^4.6.0", "tslib": "^2.6.2" }, "engines": { @@ -4781,9 +4853,9 @@ } }, "node_modules/@smithy/chunked-blob-reader": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader/-/chunked-blob-reader-5.1.0.tgz", - "integrity": "sha512-a36AtR7Q7XOhRPt6F/7HENmTWcB8kN7mDJcOFM/+FuKO6x88w8MQJfYCufMWh4fGyVkPjUh3Rrz/dnqFQdo6OQ==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader/-/chunked-blob-reader-5.2.0.tgz", + "integrity": "sha512-WmU0TnhEAJLWvfSeMxBNe5xtbselEO8+4wG0NtZeL8oR21WgH1xiO37El+/Y+H/Ie4SCwBy3MxYWmOYaGgZueA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -4794,13 +4866,13 @@ } }, "node_modules/@smithy/chunked-blob-reader-native": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader-native/-/chunked-blob-reader-native-4.1.0.tgz", - "integrity": "sha512-Bnv0B3nSlfB2mPO0WgM49I/prl7+kamF042rrf3ezJ3Z4C7csPYvyYgZfXTGXwXfj1mAwDWjE/ybIf49PzFzvA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader-native/-/chunked-blob-reader-native-4.2.0.tgz", + "integrity": "sha512-HNbGWdyTfSM1nfrZKQjYTvD8k086+M8s1EYkBUdGC++lhxegUp2HgNf5RIt6oOGVvsC26hBCW/11tv8KbwLn/Q==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/util-base64": "^4.1.0", + "@smithy/util-base64": "^4.2.0", "tslib": "^2.6.2" }, "engines": { @@ -4808,16 +4880,16 @@ } }, "node_modules/@smithy/config-resolver": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.2.2.tgz", - "integrity": "sha512-IT6MatgBWagLybZl1xQcURXRICvqz1z3APSCAI9IqdvfCkrA7RaQIEfgC6G/KvfxnDfQUDqFV+ZlixcuFznGBQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.3.0.tgz", + "integrity": "sha512-9oH+n8AVNiLPK/iK/agOsoWfrKZ3FGP3502tkksd6SRsKMYiu7AFX0YXo6YBADdsAj7C+G/aLKdsafIJHxuCkQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.2.2", - "@smithy/types": "^4.5.0", - "@smithy/util-config-provider": "^4.1.0", - "@smithy/util-middleware": "^4.1.1", + "@smithy/node-config-provider": "^4.3.0", + "@smithy/types": "^4.6.0", + "@smithy/util-config-provider": "^4.2.0", + "@smithy/util-middleware": "^4.2.0", "tslib": "^2.6.2" }, "engines": { @@ -4825,39 +4897,38 @@ } }, "node_modules/@smithy/core": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.11.0.tgz", - "integrity": "sha512-Abs5rdP1o8/OINtE49wwNeWuynCu0kme1r4RI3VXVrHr4odVDG7h7mTnw1WXXfN5Il+c25QOnrdL2y56USfxkA==", + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.14.0.tgz", + "integrity": "sha512-XJ4z5FxvY/t0Dibms/+gLJrI5niRoY0BCmE02fwmPcRYFPI4KI876xaE79YGWIKnEslMbuQPsIEsoU/DXa0DoA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/middleware-serde": "^4.1.1", - "@smithy/protocol-http": "^5.2.1", - "@smithy/types": "^4.5.0", - "@smithy/util-base64": "^4.1.0", - "@smithy/util-body-length-browser": "^4.1.0", - "@smithy/util-middleware": "^4.1.1", - "@smithy/util-stream": "^4.3.1", - "@smithy/util-utf8": "^4.1.0", - "@types/uuid": "^9.0.1", - "tslib": "^2.6.2", - "uuid": "^9.0.1" + "@smithy/middleware-serde": "^4.2.0", + "@smithy/protocol-http": "^5.3.0", + "@smithy/types": "^4.6.0", + "@smithy/util-base64": "^4.2.0", + "@smithy/util-body-length-browser": "^4.2.0", + "@smithy/util-middleware": "^4.2.0", + "@smithy/util-stream": "^4.4.0", + "@smithy/util-utf8": "^4.2.0", + "@smithy/uuid": "^1.1.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=18.0.0" } }, "node_modules/@smithy/credential-provider-imds": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.1.2.tgz", - "integrity": "sha512-JlYNq8TShnqCLg0h+afqe2wLAwZpuoSgOyzhYvTgbiKBWRov+uUve+vrZEQO6lkdLOWPh7gK5dtb9dS+KGendg==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.2.0.tgz", + "integrity": "sha512-SOhFVvFH4D5HJZytb0bLKxCrSnwcqPiNlrw+S4ZXjMnsC+o9JcUQzbZOEQcA8yv9wJFNhfsUiIUKiEnYL68Big==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.2.2", - "@smithy/property-provider": "^4.1.1", - "@smithy/types": "^4.5.0", - "@smithy/url-parser": "^4.1.1", + "@smithy/node-config-provider": "^4.3.0", + "@smithy/property-provider": "^4.2.0", + "@smithy/types": "^4.6.0", + "@smithy/url-parser": "^4.2.0", "tslib": "^2.6.2" }, "engines": { @@ -4865,15 +4936,15 @@ } }, "node_modules/@smithy/eventstream-codec": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-4.1.1.tgz", - "integrity": "sha512-PwkQw1hZwHTQB6X5hSUWz2OSeuj5Z6enWuAqke7DgWoP3t6vg3ktPpqPz3Erkn6w+tmsl8Oss6nrgyezoea2Iw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-4.2.0.tgz", + "integrity": "sha512-XE7CtKfyxYiNZ5vz7OvyTf1osrdbJfmUy+rbh+NLQmZumMGvY0mT0Cq1qKSfhrvLtRYzMsOBuRpi10dyI0EBPg==", "dev": true, "license": "Apache-2.0", "dependencies": { "@aws-crypto/crc32": "5.2.0", - "@smithy/types": "^4.5.0", - "@smithy/util-hex-encoding": "^4.1.0", + "@smithy/types": "^4.6.0", + "@smithy/util-hex-encoding": "^4.2.0", "tslib": "^2.6.2" }, "engines": { @@ -4881,14 +4952,14 @@ } }, "node_modules/@smithy/eventstream-serde-browser": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-4.1.1.tgz", - "integrity": "sha512-Q9QWdAzRaIuVkefupRPRFAasaG/droBqn1feiMnmLa+LLEUG45pqX1+FurHFmlqiCfobB3nUlgoJfeXZsr7MPA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-4.2.0.tgz", + "integrity": "sha512-U53p7fcrk27k8irLhOwUu+UYnBqsXNLKl1XevOpsxK3y1Lndk8R7CSiZV6FN3fYFuTPuJy5pP6qa/bjDzEkRvA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/eventstream-serde-universal": "^4.1.1", - "@smithy/types": "^4.5.0", + "@smithy/eventstream-serde-universal": "^4.2.0", + "@smithy/types": "^4.6.0", "tslib": "^2.6.2" }, "engines": { @@ -4896,13 +4967,13 @@ } }, "node_modules/@smithy/eventstream-serde-config-resolver": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-4.2.1.tgz", - "integrity": "sha512-oSUkF9zDN9zcOUBMtxp8RewJlh71E9NoHWU8jE3hU9JMYCsmW4assVTpgic/iS3/dM317j6hO5x18cc3XrfvEw==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-4.3.0.tgz", + "integrity": "sha512-uwx54t8W2Yo9Jr3nVF5cNnkAAnMCJ8Wrm+wDlQY6rY/IrEgZS3OqagtCu/9ceIcZFQ1zVW/zbN9dxb5esuojfA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.5.0", + "@smithy/types": "^4.6.0", "tslib": "^2.6.2" }, "engines": { @@ -4910,14 +4981,14 @@ } }, "node_modules/@smithy/eventstream-serde-node": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-4.1.1.tgz", - "integrity": "sha512-tn6vulwf/ScY0vjhzptSJuDJJqlhNtUjkxJ4wiv9E3SPoEqTEKbaq6bfqRO7nvhTG29ALICRcvfFheOUPl8KNA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-4.2.0.tgz", + "integrity": "sha512-yjM2L6QGmWgJjVu/IgYd6hMzwm/tf4VFX0lm8/SvGbGBwc+aFl3hOzvO/e9IJ2XI+22Tx1Zg3vRpFRs04SWFcg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/eventstream-serde-universal": "^4.1.1", - "@smithy/types": "^4.5.0", + "@smithy/eventstream-serde-universal": "^4.2.0", + "@smithy/types": "^4.6.0", "tslib": "^2.6.2" }, "engines": { @@ -4925,14 +4996,14 @@ } }, "node_modules/@smithy/eventstream-serde-universal": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-4.1.1.tgz", - "integrity": "sha512-uLOAiM/Dmgh2CbEXQx+6/ssK7fbzFhd+LjdyFxXid5ZBCbLHTFHLdD/QbXw5aEDsLxQhgzDxLLsZhsftAYwHJA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-4.2.0.tgz", + "integrity": "sha512-C3jxz6GeRzNyGKhU7oV656ZbuHY93mrfkT12rmjDdZch142ykjn8do+VOkeRNjSGKw01p4g+hdalPYPhmMwk1g==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/eventstream-codec": "^4.1.1", - "@smithy/types": "^4.5.0", + "@smithy/eventstream-codec": "^4.2.0", + "@smithy/types": "^4.6.0", "tslib": "^2.6.2" }, "engines": { @@ -4940,16 +5011,16 @@ } }, "node_modules/@smithy/fetch-http-handler": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.2.1.tgz", - "integrity": "sha512-5/3wxKNtV3wO/hk1is+CZUhL8a1yy/U+9u9LKQ9kZTkMsHaQjJhc3stFfiujtMnkITjzWfndGA2f7g9Uh9vKng==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.3.0.tgz", + "integrity": "sha512-BG3KSmsx9A//KyIfw+sqNmWFr1YBUr+TwpxFT7yPqAk0yyDh7oSNgzfNH7pS6OC099EGx2ltOULvumCFe8bcgw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/protocol-http": "^5.2.1", - "@smithy/querystring-builder": "^4.1.1", - "@smithy/types": "^4.5.0", - "@smithy/util-base64": "^4.1.0", + "@smithy/protocol-http": "^5.3.0", + "@smithy/querystring-builder": "^4.2.0", + "@smithy/types": "^4.6.0", + "@smithy/util-base64": "^4.2.0", "tslib": "^2.6.2" }, "engines": { @@ -4957,15 +5028,15 @@ } }, "node_modules/@smithy/hash-blob-browser": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@smithy/hash-blob-browser/-/hash-blob-browser-4.1.1.tgz", - "integrity": "sha512-avAtk++s1e/1VODf+rg7c9R2pB5G9y8yaJaGY4lPZI2+UIqVyuSDMikWjeWfBVmFZ3O7NpDxBbUCyGhThVUKWQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/hash-blob-browser/-/hash-blob-browser-4.2.0.tgz", + "integrity": "sha512-MWmrRTPqVKpN8NmxmJPTeQuhewTt8Chf+waB38LXHZoA02+BeWYVQ9ViAwHjug8m7lQb1UWuGqp3JoGDOWvvuA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/chunked-blob-reader": "^5.1.0", - "@smithy/chunked-blob-reader-native": "^4.1.0", - "@smithy/types": "^4.5.0", + "@smithy/chunked-blob-reader": "^5.2.0", + "@smithy/chunked-blob-reader-native": "^4.2.0", + "@smithy/types": "^4.6.0", "tslib": "^2.6.2" }, "engines": { @@ -4973,15 +5044,15 @@ } }, "node_modules/@smithy/hash-node": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.1.1.tgz", - "integrity": "sha512-H9DIU9WBLhYrvPs9v4sYvnZ1PiAI0oc8CgNQUJ1rpN3pP7QADbTOUjchI2FB764Ub0DstH5xbTqcMJu1pnVqxA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.2.0.tgz", + "integrity": "sha512-ugv93gOhZGysTctZh9qdgng8B+xO0cj+zN0qAZ+Sgh7qTQGPOJbMdIuyP89KNfUyfAqFSNh5tMvC+h2uCpmTtA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.5.0", - "@smithy/util-buffer-from": "^4.1.0", - "@smithy/util-utf8": "^4.1.0", + "@smithy/types": "^4.6.0", + "@smithy/util-buffer-from": "^4.2.0", + "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" }, "engines": { @@ -4989,14 +5060,14 @@ } }, "node_modules/@smithy/hash-stream-node": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@smithy/hash-stream-node/-/hash-stream-node-4.1.1.tgz", - "integrity": "sha512-3ztT4pV0Moazs3JAYFdfKk11kYFDo4b/3R3+xVjIm6wY9YpJf+xfz+ocEnNKcWAdcmSMqi168i2EMaKmJHbJMA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/hash-stream-node/-/hash-stream-node-4.2.0.tgz", + "integrity": "sha512-8dELAuGv+UEjtzrpMeNBZc1sJhO8GxFVV/Yh21wE35oX4lOE697+lsMHBoUIFAUuYkTMIeu0EuJSEsH7/8Y+UQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.5.0", - "@smithy/util-utf8": "^4.1.0", + "@smithy/types": "^4.6.0", + "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" }, "engines": { @@ -5004,13 +5075,13 @@ } }, "node_modules/@smithy/invalid-dependency": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.1.1.tgz", - "integrity": "sha512-1AqLyFlfrrDkyES8uhINRlJXmHA2FkG+3DY8X+rmLSqmFwk3DJnvhyGzyByPyewh2jbmV+TYQBEfngQax8IFGg==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.2.0.tgz", + "integrity": "sha512-ZmK5X5fUPAbtvRcUPtk28aqIClVhbfcmfoS4M7UQBTnDdrNxhsrxYVv0ZEl5NaPSyExsPWqL4GsPlRvtlwg+2A==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.5.0", + "@smithy/types": "^4.6.0", "tslib": "^2.6.2" }, "engines": { @@ -5018,9 +5089,9 @@ } }, "node_modules/@smithy/is-array-buffer": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.1.0.tgz", - "integrity": "sha512-ePTYUOV54wMogio+he4pBybe8fwg4sDvEVDBU8ZlHOZXbXK3/C0XfJgUCu6qAZcawv05ZhZzODGUerFBPsPUDQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.2.0.tgz", + "integrity": "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -5031,14 +5102,14 @@ } }, "node_modules/@smithy/md5-js": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@smithy/md5-js/-/md5-js-4.1.1.tgz", - "integrity": "sha512-MvWXKK743BuHjr/hnWuT6uStdKEaoqxHAQUvbKJPPZM5ZojTNFI5D+47BoQfBE5RgGlRRty05EbWA+NXDv+hIA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/md5-js/-/md5-js-4.2.0.tgz", + "integrity": "sha512-LFEPniXGKRQArFmDQ3MgArXlClFJMsXDteuQQY8WG1/zzv6gVSo96+qpkuu1oJp4MZsKrwchY0cuAoPKzEbaNA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.5.0", - "@smithy/util-utf8": "^4.1.0", + "@smithy/types": "^4.6.0", + "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" }, "engines": { @@ -5046,14 +5117,14 @@ } }, "node_modules/@smithy/middleware-content-length": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.1.1.tgz", - "integrity": "sha512-9wlfBBgTsRvC2JxLJxv4xDGNBrZuio3AgSl0lSFX7fneW2cGskXTYpFxCdRYD2+5yzmsiTuaAJD1Wp7gWt9y9w==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.2.0.tgz", + "integrity": "sha512-6ZAnwrXFecrA4kIDOcz6aLBhU5ih2is2NdcZtobBDSdSHtE9a+MThB5uqyK4XXesdOCvOcbCm2IGB95birTSOQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/protocol-http": "^5.2.1", - "@smithy/types": "^4.5.0", + "@smithy/protocol-http": "^5.3.0", + "@smithy/types": "^4.6.0", "tslib": "^2.6.2" }, "engines": { @@ -5061,19 +5132,19 @@ } }, "node_modules/@smithy/middleware-endpoint": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.2.2.tgz", - "integrity": "sha512-M51KcwD+UeSOFtpALGf5OijWt915aQT5eJhqnMKJt7ZTfDfNcvg2UZgIgTZUoiORawb6o5lk4n3rv7vnzQXgsA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.3.0.tgz", + "integrity": "sha512-jFVjuQeV8TkxaRlcCNg0GFVgg98tscsmIrIwRFeC74TIUyLE3jmY9xgc1WXrPQYRjQNK3aRoaIk6fhFRGOIoGw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/core": "^3.11.0", - "@smithy/middleware-serde": "^4.1.1", - "@smithy/node-config-provider": "^4.2.2", - "@smithy/shared-ini-file-loader": "^4.2.0", - "@smithy/types": "^4.5.0", - "@smithy/url-parser": "^4.1.1", - "@smithy/util-middleware": "^4.1.1", + "@smithy/core": "^3.14.0", + "@smithy/middleware-serde": "^4.2.0", + "@smithy/node-config-provider": "^4.3.0", + "@smithy/shared-ini-file-loader": "^4.3.0", + "@smithy/types": "^4.6.0", + "@smithy/url-parser": "^4.2.0", + "@smithy/util-middleware": "^4.2.0", "tslib": "^2.6.2" }, "engines": { @@ -5081,36 +5152,35 @@ } }, "node_modules/@smithy/middleware-retry": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.2.3.tgz", - "integrity": "sha512-am6wR0kKGCuQfaGc0f3UKdl9AmbSe3DacScw8It5aHDFNXwgXSHNbAoFrf37qZn4Br6Ap7+LI6lWaBT3LJtv7g==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.4.0.tgz", + "integrity": "sha512-yaVBR0vQnOnzex45zZ8ZrPzUnX73eUC8kVFaAAbn04+6V7lPtxn56vZEBBAhgS/eqD6Zm86o6sJs6FuQVoX5qg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.2.2", - "@smithy/protocol-http": "^5.2.1", - "@smithy/service-error-classification": "^4.1.2", - "@smithy/smithy-client": "^4.6.2", - "@smithy/types": "^4.5.0", - "@smithy/util-middleware": "^4.1.1", - "@smithy/util-retry": "^4.1.2", - "@types/uuid": "^9.0.1", - "tslib": "^2.6.2", - "uuid": "^9.0.1" + "@smithy/node-config-provider": "^4.3.0", + "@smithy/protocol-http": "^5.3.0", + "@smithy/service-error-classification": "^4.2.0", + "@smithy/smithy-client": "^4.7.0", + "@smithy/types": "^4.6.0", + "@smithy/util-middleware": "^4.2.0", + "@smithy/util-retry": "^4.2.0", + "@smithy/uuid": "^1.1.0", + "tslib": "^2.6.2" }, "engines": { "node": ">=18.0.0" } }, "node_modules/@smithy/middleware-serde": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.1.1.tgz", - "integrity": "sha512-lh48uQdbCoj619kRouev5XbWhCwRKLmphAif16c4J6JgJ4uXjub1PI6RL38d3BLliUvSso6klyB/LTNpWSNIyg==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.2.0.tgz", + "integrity": "sha512-rpTQ7D65/EAbC6VydXlxjvbifTf4IH+sADKg6JmAvhkflJO2NvDeyU9qsWUNBelJiQFcXKejUHWRSdmpJmEmiw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/protocol-http": "^5.2.1", - "@smithy/types": "^4.5.0", + "@smithy/protocol-http": "^5.3.0", + "@smithy/types": "^4.6.0", "tslib": "^2.6.2" }, "engines": { @@ -5118,13 +5188,13 @@ } }, "node_modules/@smithy/middleware-stack": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.1.1.tgz", - "integrity": "sha512-ygRnniqNcDhHzs6QAPIdia26M7e7z9gpkIMUe/pK0RsrQ7i5MblwxY8078/QCnGq6AmlUUWgljK2HlelsKIb/A==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.2.0.tgz", + "integrity": "sha512-G5CJ//eqRd9OARrQu9MK1H8fNm2sMtqFh6j8/rPozhEL+Dokpvi1Og+aCixTuwDAGZUkJPk6hJT5jchbk/WCyg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.5.0", + "@smithy/types": "^4.6.0", "tslib": "^2.6.2" }, "engines": { @@ -5132,15 +5202,15 @@ } }, "node_modules/@smithy/node-config-provider": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.2.2.tgz", - "integrity": "sha512-SYGTKyPvyCfEzIN5rD8q/bYaOPZprYUPD2f5g9M7OjaYupWOoQFYJ5ho+0wvxIRf471i2SR4GoiZ2r94Jq9h6A==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.3.0.tgz", + "integrity": "sha512-5QgHNuWdT9j9GwMPPJCKxy2KDxZ3E5l4M3/5TatSZrqYVoEiqQrDfAq8I6KWZw7RZOHtVtCzEPdYz7rHZixwcA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/property-provider": "^4.1.1", - "@smithy/shared-ini-file-loader": "^4.2.0", - "@smithy/types": "^4.5.0", + "@smithy/property-provider": "^4.2.0", + "@smithy/shared-ini-file-loader": "^4.3.0", + "@smithy/types": "^4.6.0", "tslib": "^2.6.2" }, "engines": { @@ -5148,16 +5218,16 @@ } }, "node_modules/@smithy/node-http-handler": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.2.1.tgz", - "integrity": "sha512-REyybygHlxo3TJICPF89N2pMQSf+p+tBJqpVe1+77Cfi9HBPReNjTgtZ1Vg73exq24vkqJskKDpfF74reXjxfw==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.3.0.tgz", + "integrity": "sha512-RHZ/uWCmSNZ8cneoWEVsVwMZBKy/8123hEpm57vgGXA3Irf/Ja4v9TVshHK2ML5/IqzAZn0WhINHOP9xl+Qy6Q==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/abort-controller": "^4.1.1", - "@smithy/protocol-http": "^5.2.1", - "@smithy/querystring-builder": "^4.1.1", - "@smithy/types": "^4.5.0", + "@smithy/abort-controller": "^4.2.0", + "@smithy/protocol-http": "^5.3.0", + "@smithy/querystring-builder": "^4.2.0", + "@smithy/types": "^4.6.0", "tslib": "^2.6.2" }, "engines": { @@ -5165,13 +5235,13 @@ } }, "node_modules/@smithy/property-provider": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.1.1.tgz", - "integrity": "sha512-gm3ZS7DHxUbzC2wr8MUCsAabyiXY0gaj3ROWnhSx/9sPMc6eYLMM4rX81w1zsMaObj2Lq3PZtNCC1J6lpEY7zg==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.2.0.tgz", + "integrity": "sha512-rV6wFre0BU6n/tx2Ztn5LdvEdNZ2FasQbPQmDOPfV9QQyDmsCkOAB0osQjotRCQg+nSKFmINhyda0D3AnjSBJw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.5.0", + "@smithy/types": "^4.6.0", "tslib": "^2.6.2" }, "engines": { @@ -5179,13 +5249,13 @@ } }, "node_modules/@smithy/protocol-http": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.2.1.tgz", - "integrity": "sha512-T8SlkLYCwfT/6m33SIU/JOVGNwoelkrvGjFKDSDtVvAXj/9gOT78JVJEas5a+ETjOu4SVvpCstKgd0PxSu/aHw==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.0.tgz", + "integrity": "sha512-6POSYlmDnsLKb7r1D3SVm7RaYW6H1vcNcTWGWrF7s9+2noNYvUsm7E4tz5ZQ9HXPmKn6Hb67pBDRIjrT4w/d7Q==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.5.0", + "@smithy/types": "^4.6.0", "tslib": "^2.6.2" }, "engines": { @@ -5193,14 +5263,14 @@ } }, "node_modules/@smithy/querystring-builder": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.1.1.tgz", - "integrity": "sha512-J9b55bfimP4z/Jg1gNo+AT84hr90p716/nvxDkPGCD4W70MPms0h8KF50RDRgBGZeL83/u59DWNqJv6tEP/DHA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.2.0.tgz", + "integrity": "sha512-Q4oFD0ZmI8yJkiPPeGUITZj++4HHYCW3pYBYfIobUCkYpI6mbkzmG1MAQQ3lJYYWj3iNqfzOenUZu+jqdPQ16A==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.5.0", - "@smithy/util-uri-escape": "^4.1.0", + "@smithy/types": "^4.6.0", + "@smithy/util-uri-escape": "^4.2.0", "tslib": "^2.6.2" }, "engines": { @@ -5208,13 +5278,13 @@ } }, "node_modules/@smithy/querystring-parser": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.1.1.tgz", - "integrity": "sha512-63TEp92YFz0oQ7Pj9IuI3IgnprP92LrZtRAkE3c6wLWJxfy/yOPRt39IOKerVr0JS770olzl0kGafXlAXZ1vng==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.2.0.tgz", + "integrity": "sha512-BjATSNNyvVbQxOOlKse0b0pSezTWGMvA87SvoFoFlkRsKXVsN3bEtjCxvsNXJXfnAzlWFPaT9DmhWy1vn0sNEA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.5.0", + "@smithy/types": "^4.6.0", "tslib": "^2.6.2" }, "engines": { @@ -5222,26 +5292,26 @@ } }, "node_modules/@smithy/service-error-classification": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.1.2.tgz", - "integrity": "sha512-Kqd8wyfmBWHZNppZSMfrQFpc3M9Y/kjyN8n8P4DqJJtuwgK1H914R471HTw7+RL+T7+kI1f1gOnL7Vb5z9+NgQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.2.0.tgz", + "integrity": "sha512-Ylv1ttUeKatpR0wEOMnHf1hXMktPUMObDClSWl2TpCVT4DwtJhCeighLzSLbgH3jr5pBNM0LDXT5yYxUvZ9WpA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.5.0" + "@smithy/types": "^4.6.0" }, "engines": { "node": ">=18.0.0" } }, "node_modules/@smithy/shared-ini-file-loader": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.2.0.tgz", - "integrity": "sha512-OQTfmIEp2LLuWdxa8nEEPhZmiOREO6bcB6pjs0AySf4yiZhl6kMOfqmcwcY8BaBPX+0Tb+tG7/Ia/6mwpoZ7Pw==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.3.0.tgz", + "integrity": "sha512-VCUPPtNs+rKWlqqntX0CbVvWyjhmX30JCtzO+s5dlzzxrvSfRh5SY0yxnkirvc1c80vdKQttahL71a9EsdolSQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.5.0", + "@smithy/types": "^4.6.0", "tslib": "^2.6.2" }, "engines": { @@ -5249,19 +5319,19 @@ } }, "node_modules/@smithy/signature-v4": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.2.1.tgz", - "integrity": "sha512-M9rZhWQLjlQVCCR37cSjHfhriGRN+FQ8UfgrYNufv66TJgk+acaggShl3KS5U/ssxivvZLlnj7QH2CUOKlxPyA==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.3.0.tgz", + "integrity": "sha512-MKNyhXEs99xAZaFhm88h+3/V+tCRDQ+PrDzRqL0xdDpq4gjxcMmf5rBA3YXgqZqMZ/XwemZEurCBQMfxZOWq/g==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/is-array-buffer": "^4.1.0", - "@smithy/protocol-http": "^5.2.1", - "@smithy/types": "^4.5.0", - "@smithy/util-hex-encoding": "^4.1.0", - "@smithy/util-middleware": "^4.1.1", - "@smithy/util-uri-escape": "^4.1.0", - "@smithy/util-utf8": "^4.1.0", + "@smithy/is-array-buffer": "^4.2.0", + "@smithy/protocol-http": "^5.3.0", + "@smithy/types": "^4.6.0", + "@smithy/util-hex-encoding": "^4.2.0", + "@smithy/util-middleware": "^4.2.0", + "@smithy/util-uri-escape": "^4.2.0", + "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" }, "engines": { @@ -5269,18 +5339,18 @@ } }, "node_modules/@smithy/smithy-client": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.6.2.tgz", - "integrity": "sha512-u82cjh/x7MlMat76Z38TRmEcG6JtrrxN4N2CSNG5o2v2S3hfLAxRgSgFqf0FKM3dglH41Evknt/HOX+7nfzZ3g==", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.7.0.tgz", + "integrity": "sha512-3BDx/aCCPf+kkinYf5QQhdQ9UAGihgOVqI3QO5xQfSaIWvUE4KYLtiGRWsNe1SR7ijXC0QEPqofVp5Sb0zC8xQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/core": "^3.11.0", - "@smithy/middleware-endpoint": "^4.2.2", - "@smithy/middleware-stack": "^4.1.1", - "@smithy/protocol-http": "^5.2.1", - "@smithy/types": "^4.5.0", - "@smithy/util-stream": "^4.3.1", + "@smithy/core": "^3.14.0", + "@smithy/middleware-endpoint": "^4.3.0", + "@smithy/middleware-stack": "^4.2.0", + "@smithy/protocol-http": "^5.3.0", + "@smithy/types": "^4.6.0", + "@smithy/util-stream": "^4.4.0", "tslib": "^2.6.2" }, "engines": { @@ -5288,9 +5358,9 @@ } }, "node_modules/@smithy/types": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.5.0.tgz", - "integrity": "sha512-RkUpIOsVlAwUIZXO1dsz8Zm+N72LClFfsNqf173catVlvRZiwPy0x2u0JLEA4byreOPKDZPGjmPDylMoP8ZJRg==", + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.6.0.tgz", + "integrity": "sha512-4lI9C8NzRPOv66FaY1LL1O/0v0aLVrq/mXP/keUa9mJOApEeae43LsLd2kZRUJw91gxOQfLIrV3OvqPgWz1YsA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -5301,14 +5371,14 @@ } }, "node_modules/@smithy/url-parser": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.1.1.tgz", - "integrity": "sha512-bx32FUpkhcaKlEoOMbScvc93isaSiRM75pQ5IgIBaMkT7qMlIibpPRONyx/0CvrXHzJLpOn/u6YiDX2hcvs7Dg==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.2.0.tgz", + "integrity": "sha512-AlBmD6Idav2ugmoAL6UtR6ItS7jU5h5RNqLMZC7QrLCoITA9NzIN3nx9GWi8g4z1pfWh2r9r96SX/jHiNwPJ9A==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/querystring-parser": "^4.1.1", - "@smithy/types": "^4.5.0", + "@smithy/querystring-parser": "^4.2.0", + "@smithy/types": "^4.6.0", "tslib": "^2.6.2" }, "engines": { @@ -5316,14 +5386,14 @@ } }, "node_modules/@smithy/util-base64": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-4.1.0.tgz", - "integrity": "sha512-RUGd4wNb8GeW7xk+AY5ghGnIwM96V0l2uzvs/uVHf+tIuVX2WSvynk5CxNoBCsM2rQRSZElAo9rt3G5mJ/gktQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-4.2.0.tgz", + "integrity": "sha512-+erInz8WDv5KPe7xCsJCp+1WCjSbah9gWcmUXc9NqmhyPx59tf7jqFz+za1tRG1Y5KM1Cy1rWCcGypylFp4mvA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/util-buffer-from": "^4.1.0", - "@smithy/util-utf8": "^4.1.0", + "@smithy/util-buffer-from": "^4.2.0", + "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" }, "engines": { @@ -5331,9 +5401,9 @@ } }, "node_modules/@smithy/util-body-length-browser": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-4.1.0.tgz", - "integrity": "sha512-V2E2Iez+bo6bUMOTENPr6eEmepdY8Hbs+Uc1vkDKgKNA/brTJqOW/ai3JO1BGj9GbCeLqw90pbbH7HFQyFotGQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-4.2.0.tgz", + "integrity": "sha512-Fkoh/I76szMKJnBXWPdFkQJl2r9SjPt3cMzLdOB6eJ4Pnpas8hVoWPYemX/peO0yrrvldgCUVJqOAjUrOLjbxg==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -5344,9 +5414,9 @@ } }, "node_modules/@smithy/util-body-length-node": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-4.1.0.tgz", - "integrity": "sha512-BOI5dYjheZdgR9XiEM3HJcEMCXSoqbzu7CzIgYrx0UtmvtC3tC2iDGpJLsSRFffUpy8ymsg2ARMP5fR8mtuUQQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-4.2.0.tgz", + "integrity": "sha512-U8q1WsSZFjXijlD7a4wsDQOvOwV+72iHSfq1q7VD+V75xP/pdtm0WIGuaFJ3gcADDOKj2MIBn4+zisi140HEnQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -5357,13 +5427,13 @@ } }, "node_modules/@smithy/util-buffer-from": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.1.0.tgz", - "integrity": "sha512-N6yXcjfe/E+xKEccWEKzK6M+crMrlwaCepKja0pNnlSkm6SjAeLKKA++er5Ba0I17gvKfN/ThV+ZOx/CntKTVw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.2.0.tgz", + "integrity": "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/is-array-buffer": "^4.1.0", + "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" }, "engines": { @@ -5371,9 +5441,9 @@ } }, "node_modules/@smithy/util-config-provider": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-4.1.0.tgz", - "integrity": "sha512-swXz2vMjrP1ZusZWVTB/ai5gK+J8U0BWvP10v9fpcFvg+Xi/87LHvHfst2IgCs1i0v4qFZfGwCmeD/KNCdJZbQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-4.2.0.tgz", + "integrity": "sha512-YEjpl6XJ36FTKmD+kRJJWYvrHeUvm5ykaUS5xK+6oXffQPHeEM4/nXlZPe+Wu0lsgRUcNZiliYNh/y7q9c2y6Q==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -5384,15 +5454,15 @@ } }, "node_modules/@smithy/util-defaults-mode-browser": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.1.2.tgz", - "integrity": "sha512-QKrOw01DvNHKgY+3p4r9Ut4u6EHLVZ01u6SkOMe6V6v5C+nRPXJeWh72qCT1HgwU3O7sxAIu23nNh+FOpYVZKA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.2.0.tgz", + "integrity": "sha512-qzHp7ZDk1Ba4LDwQVCNp90xPGqSu7kmL7y5toBpccuhi3AH7dcVBIT/pUxYcInK4jOy6FikrcTGq5wxcka8UaQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/property-provider": "^4.1.1", - "@smithy/smithy-client": "^4.6.2", - "@smithy/types": "^4.5.0", + "@smithy/property-provider": "^4.2.0", + "@smithy/smithy-client": "^4.7.0", + "@smithy/types": "^4.6.0", "bowser": "^2.11.0", "tslib": "^2.6.2" }, @@ -5401,18 +5471,18 @@ } }, "node_modules/@smithy/util-defaults-mode-node": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.1.2.tgz", - "integrity": "sha512-l2yRmSfx5haYHswPxMmCR6jGwgPs5LjHLuBwlj9U7nNBMS43YV/eevj+Xq1869UYdiynnMrCKtoOYQcwtb6lKg==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.2.0.tgz", + "integrity": "sha512-FxUHS3WXgx3bTWR6yQHNHHkQHZm/XKIi/CchTnKvBulN6obWpcbzJ6lDToXn+Wp0QlVKd7uYAz2/CTw1j7m+Kg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/config-resolver": "^4.2.2", - "@smithy/credential-provider-imds": "^4.1.2", - "@smithy/node-config-provider": "^4.2.2", - "@smithy/property-provider": "^4.1.1", - "@smithy/smithy-client": "^4.6.2", - "@smithy/types": "^4.5.0", + "@smithy/config-resolver": "^4.3.0", + "@smithy/credential-provider-imds": "^4.2.0", + "@smithy/node-config-provider": "^4.3.0", + "@smithy/property-provider": "^4.2.0", + "@smithy/smithy-client": "^4.7.0", + "@smithy/types": "^4.6.0", "tslib": "^2.6.2" }, "engines": { @@ -5420,14 +5490,14 @@ } }, "node_modules/@smithy/util-endpoints": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.1.2.tgz", - "integrity": "sha512-+AJsaaEGb5ySvf1SKMRrPZdYHRYSzMkCoK16jWnIMpREAnflVspMIDeCVSZJuj+5muZfgGpNpijE3mUNtjv01Q==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.2.0.tgz", + "integrity": "sha512-TXeCn22D56vvWr/5xPqALc9oO+LN+QpFjrSM7peG/ckqEPoI3zaKZFp+bFwfmiHhn5MGWPaLCqDOJPPIixk9Wg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.2.2", - "@smithy/types": "^4.5.0", + "@smithy/node-config-provider": "^4.3.0", + "@smithy/types": "^4.6.0", "tslib": "^2.6.2" }, "engines": { @@ -5435,9 +5505,9 @@ } }, "node_modules/@smithy/util-hex-encoding": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-4.1.0.tgz", - "integrity": "sha512-1LcueNN5GYC4tr8mo14yVYbh/Ur8jHhWOxniZXii+1+ePiIbsLZ5fEI0QQGtbRRP5mOhmooos+rLmVASGGoq5w==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-4.2.0.tgz", + "integrity": "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -5448,13 +5518,13 @@ } }, "node_modules/@smithy/util-middleware": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.1.1.tgz", - "integrity": "sha512-CGmZ72mL29VMfESz7S6dekqzCh8ZISj3B+w0g1hZFXaOjGTVaSqfAEFAq8EGp8fUL+Q2l8aqNmt8U1tglTikeg==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.2.0.tgz", + "integrity": "sha512-u9OOfDa43MjagtJZ8AapJcmimP+K2Z7szXn8xbty4aza+7P1wjFmy2ewjSbhEiYQoW1unTlOAIV165weYAaowA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.5.0", + "@smithy/types": "^4.6.0", "tslib": "^2.6.2" }, "engines": { @@ -5462,14 +5532,14 @@ } }, "node_modules/@smithy/util-retry": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.1.2.tgz", - "integrity": "sha512-NCgr1d0/EdeP6U5PSZ9Uv5SMR5XRRYoVr1kRVtKZxWL3tixEL3UatrPIMFZSKwHlCcp2zPLDvMubVDULRqeunA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.2.0.tgz", + "integrity": "sha512-BWSiuGbwRnEE2SFfaAZEX0TqaxtvtSYPM/J73PFVm+A29Fg1HTPiYFb8TmX1DXp4hgcdyJcNQmprfd5foeORsg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/service-error-classification": "^4.1.2", - "@smithy/types": "^4.5.0", + "@smithy/service-error-classification": "^4.2.0", + "@smithy/types": "^4.6.0", "tslib": "^2.6.2" }, "engines": { @@ -5477,19 +5547,19 @@ } }, "node_modules/@smithy/util-stream": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.3.1.tgz", - "integrity": "sha512-khKkW/Jqkgh6caxMWbMuox9+YfGlsk9OnHOYCGVEdYQb/XVzcORXHLYUubHmmda0pubEDncofUrPNniS9d+uAA==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.4.0.tgz", + "integrity": "sha512-vtO7ktbixEcrVzMRmpQDnw/Ehr9UWjBvSJ9fyAbadKkC4w5Cm/4lMO8cHz8Ysb8uflvQUNRcuux/oNHKPXkffg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/fetch-http-handler": "^5.2.1", - "@smithy/node-http-handler": "^4.2.1", - "@smithy/types": "^4.5.0", - "@smithy/util-base64": "^4.1.0", - "@smithy/util-buffer-from": "^4.1.0", - "@smithy/util-hex-encoding": "^4.1.0", - "@smithy/util-utf8": "^4.1.0", + "@smithy/fetch-http-handler": "^5.3.0", + "@smithy/node-http-handler": "^4.3.0", + "@smithy/types": "^4.6.0", + "@smithy/util-base64": "^4.2.0", + "@smithy/util-buffer-from": "^4.2.0", + "@smithy/util-hex-encoding": "^4.2.0", + "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" }, "engines": { @@ -5497,9 +5567,9 @@ } }, "node_modules/@smithy/util-uri-escape": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-4.1.0.tgz", - "integrity": "sha512-b0EFQkq35K5NHUYxU72JuoheM6+pytEVUGlTwiFxWFpmddA+Bpz3LgsPRIpBk8lnPE47yT7AF2Egc3jVnKLuPg==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-4.2.0.tgz", + "integrity": "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -5510,13 +5580,13 @@ } }, "node_modules/@smithy/util-utf8": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.1.0.tgz", - "integrity": "sha512-mEu1/UIXAdNYuBcyEPbjScKi/+MQVXNIuY/7Cm5XLIWe319kDrT5SizBE95jqtmEXoDbGoZxKLCMttdZdqTZKQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.0.tgz", + "integrity": "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/util-buffer-from": "^4.1.0", + "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" }, "engines": { @@ -5524,20 +5594,43 @@ } }, "node_modules/@smithy/util-waiter": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-4.1.1.tgz", - "integrity": "sha512-PJBmyayrlfxM7nbqjomF4YcT1sApQwZio0NHSsT0EzhJqljRmvhzqZua43TyEs80nJk2Cn2FGPg/N8phH6KeCQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-4.2.0.tgz", + "integrity": "sha512-0Z+nxUU4/4T+SL8BCNN4ztKdQjToNvUYmkF1kXO5T7Yz3Gafzh0HeIG6mrkN8Fz3gn9hSyxuAT+6h4vM+iQSBQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/abort-controller": "^4.2.0", + "@smithy/types": "^4.6.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/uuid": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@smithy/uuid/-/uuid-1.1.0.tgz", + "integrity": "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/abort-controller": "^4.1.1", - "@smithy/types": "^4.5.0", "tslib": "^2.6.2" }, "engines": { "node": ">=18.0.0" } }, + "node_modules/@so-ric/colorspace": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@so-ric/colorspace/-/colorspace-1.1.6.tgz", + "integrity": "sha512-/KiKkpHNOBgkFJwu9sh48LkHSMYGyuTcSFK/qMBdnOAlrRJzRSXAOFB5qwzaVQuDl8wAvHVMkaASQDReTahxuw==", + "license": "MIT", + "dependencies": { + "color": "^5.0.2", + "text-hex": "1.0.x" + } + }, "node_modules/@stylistic/eslint-plugin": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-3.1.0.tgz", @@ -5559,14 +5652,14 @@ } }, "node_modules/@stylistic/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.44.0.tgz", - "integrity": "sha512-87Jv3E+al8wpD+rIdVJm/ItDBe/Im09zXIjFoipOjr5gHUhJmTzfFLuTJ/nPTMc2Srsroy4IBXwcTCHyRR7KzA==", + "version": "8.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.45.0.tgz", + "integrity": "sha512-clmm8XSNj/1dGvJeO6VGH7EUSeA0FMs+5au/u3lrA3KfG8iJ4u8ym9/j2tTEoacAffdW1TVUzXO30W1JTJS7dA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.44.0", - "@typescript-eslint/visitor-keys": "8.44.0" + "@typescript-eslint/types": "8.45.0", + "@typescript-eslint/visitor-keys": "8.45.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5577,9 +5670,9 @@ } }, "node_modules/@stylistic/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.44.0.tgz", - "integrity": "sha512-ZSl2efn44VsYM0MfDQe68RKzBz75NPgLQXuGypmym6QVOWL5kegTZuZ02xRAT9T+onqvM6T8CdQk0OwYMB6ZvA==", + "version": "8.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.45.0.tgz", + "integrity": "sha512-WugXLuOIq67BMgQInIxxnsSyRLFxdkJEJu8r4ngLR56q/4Q5LrbfkFRH27vMTjxEK8Pyz7QfzuZe/G15qQnVRA==", "dev": true, "license": "MIT", "engines": { @@ -5591,16 +5684,16 @@ } }, "node_modules/@stylistic/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.44.0.tgz", - "integrity": "sha512-lqNj6SgnGcQZwL4/SBJ3xdPEfcBuhCG8zdcwCPgYcmiPLgokiNDKlbPzCwEwu7m279J/lBYWtDYL+87OEfn8Jw==", + "version": "8.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.45.0.tgz", + "integrity": "sha512-GfE1NfVbLam6XQ0LcERKwdTTPlLvHvXXhOeUGC1OXi4eQBoyy1iVsW+uzJ/J9jtCz6/7GCQ9MtrQ0fml/jWCnA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.44.0", - "@typescript-eslint/tsconfig-utils": "8.44.0", - "@typescript-eslint/types": "8.44.0", - "@typescript-eslint/visitor-keys": "8.44.0", + "@typescript-eslint/project-service": "8.45.0", + "@typescript-eslint/tsconfig-utils": "8.45.0", + "@typescript-eslint/types": "8.45.0", + "@typescript-eslint/visitor-keys": "8.45.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -5620,16 +5713,16 @@ } }, "node_modules/@stylistic/eslint-plugin/node_modules/@typescript-eslint/utils": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.44.0.tgz", - "integrity": "sha512-nktOlVcg3ALo0mYlV+L7sWUD58KG4CMj1rb2HUVOO4aL3K/6wcD+NERqd0rrA5Vg06b42YhF6cFxeixsp9Riqg==", + "version": "8.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.45.0.tgz", + "integrity": "sha512-bxi1ht+tLYg4+XV2knz/F7RVhU0k6VrSMc9sb8DQ6fyCTrGQLHfo7lDtN0QJjZjKkLA2ThrKuCdHEvLReqtIGg==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.44.0", - "@typescript-eslint/types": "8.44.0", - "@typescript-eslint/typescript-estree": "8.44.0" + "@typescript-eslint/scope-manager": "8.45.0", + "@typescript-eslint/types": "8.45.0", + "@typescript-eslint/typescript-estree": "8.45.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5644,13 +5737,13 @@ } }, "node_modules/@stylistic/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.44.0.tgz", - "integrity": "sha512-zaz9u8EJ4GBmnehlrpoKvj/E3dNbuQ7q0ucyZImm3cLqJ8INTc970B1qEqDX/Rzq65r3TvVTN7kHWPBoyW7DWw==", + "version": "8.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.45.0.tgz", + "integrity": "sha512-qsaFBA3e09MIDAGFUrTk+dzqtfv1XPVz8t8d1f0ybTzrCY7BKiMC5cjrl1O/P7UmHsNyW90EYSkU/ZWpmXelag==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.44.0", + "@typescript-eslint/types": "8.45.0", "eslint-visitor-keys": "^4.2.1" }, "engines": { @@ -6132,24 +6225,33 @@ "license": "MIT" }, "node_modules/@types/send": { - "version": "0.17.5", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.5.tgz", - "integrity": "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@types/send/-/send-1.2.0.tgz", + "integrity": "sha512-zBF6vZJn1IaMpg3xUF25VK3gd3l8zwE0ZLRX7dsQyQi+jp4E8mMDJNGDYnYse+bQhYwWERTxVwHpi3dMOq7RKQ==", "license": "MIT", "dependencies": { - "@types/mime": "^1", "@types/node": "*" } }, "node_modules/@types/serve-static": { - "version": "1.15.8", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.8.tgz", - "integrity": "sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==", + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.9.tgz", + "integrity": "sha512-dOTIuqpWLyl3BBXU3maNQsS4A3zuuoYRNIvYSxxhebPfXg2mzWQEPne/nlJ37yOse6uGgR386uTpdsx4D0QZWA==", "license": "MIT", "dependencies": { "@types/http-errors": "*", "@types/node": "*", - "@types/send": "*" + "@types/send": "<1" + } + }, + "node_modules/@types/serve-static/node_modules/@types/send": { + "version": "0.17.5", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.5.tgz", + "integrity": "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==", + "license": "MIT", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" } }, "node_modules/@types/sinon": { @@ -6311,14 +6413,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.44.0.tgz", - "integrity": "sha512-ZeaGNraRsq10GuEohKTo4295Z/SuGcSq2LzfGlqiuEvfArzo/VRrT0ZaJsVPuKZ55lVbNk8U6FcL+ZMH8CoyVA==", + "version": "8.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.45.0.tgz", + "integrity": "sha512-3pcVHwMG/iA8afdGLMuTibGR7pDsn9RjDev6CCB+naRsSYs2pns5QbinF4Xqw6YC/Sj3lMrm/Im0eMfaa61WUg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.44.0", - "@typescript-eslint/types": "^8.44.0", + "@typescript-eslint/tsconfig-utils": "^8.45.0", + "@typescript-eslint/types": "^8.45.0", "debug": "^4.3.4" }, "engines": { @@ -6333,9 +6435,9 @@ } }, "node_modules/@typescript-eslint/project-service/node_modules/@typescript-eslint/types": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.44.0.tgz", - "integrity": "sha512-ZSl2efn44VsYM0MfDQe68RKzBz75NPgLQXuGypmym6QVOWL5kegTZuZ02xRAT9T+onqvM6T8CdQk0OwYMB6ZvA==", + "version": "8.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.45.0.tgz", + "integrity": "sha512-WugXLuOIq67BMgQInIxxnsSyRLFxdkJEJu8r4ngLR56q/4Q5LrbfkFRH27vMTjxEK8Pyz7QfzuZe/G15qQnVRA==", "dev": true, "license": "MIT", "engines": { @@ -6365,9 +6467,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.44.0.tgz", - "integrity": "sha512-x5Y0+AuEPqAInc6yd0n5DAcvtoQ/vyaGwuX5HE9n6qAefk1GaedqrLQF8kQGylLUb9pnZyLf+iEiL9fr8APDtQ==", + "version": "8.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.45.0.tgz", + "integrity": "sha512-aFdr+c37sc+jqNMGhH+ajxPXwjv9UtFZk79k8pLoJ6p4y0snmYpPA52GuWHgt2ZF4gRRW6odsEj41uZLojDt5w==", "dev": true, "license": "MIT", "engines": { @@ -7570,9 +7672,9 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.5.tgz", - "integrity": "sha512-TiU4qUT9jdCuh4aVOG7H1QozyeI2sZRqoRPdqBIaslfNt4WUSanRBueAwl2x5jt4rXBMim3lIN2x6yT8PDi24Q==", + "version": "2.8.12", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.12.tgz", + "integrity": "sha512-vAPMQdnyKCBtkmQA6FMCBvU9qFIppS3nzyXnEM+Lo2IAhG4Mpjv9cCxMudhgV3YdNNJv6TNqXy97dfRVL2LmaQ==", "dev": true, "license": "Apache-2.0", "bin": { @@ -7753,9 +7855,9 @@ "license": "ISC" }, "node_modules/browserslist": { - "version": "4.26.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.26.2.tgz", - "integrity": "sha512-ECFzp6uFOSB+dcZ5BK/IBaGWssbSYBHvuMeMt3MMFyhI0Z8SqGgEkBLARgpRH3hutIgPVsALcMwbDrJqPxQ65A==", + "version": "4.26.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.26.3.tgz", + "integrity": "sha512-lAUU+02RFBuCKQPj/P6NgjlbCnLBMp4UtgTx7vNHd3XSIJF87s9a5rA3aH2yw3GS9DqZAUbOtZdCCiZeVRqt0w==", "dev": true, "funding": [ { @@ -7773,9 +7875,9 @@ ], "license": "MIT", "dependencies": { - "baseline-browser-mapping": "^2.8.3", - "caniuse-lite": "^1.0.30001741", - "electron-to-chromium": "^1.5.218", + "baseline-browser-mapping": "^2.8.9", + "caniuse-lite": "^1.0.30001746", + "electron-to-chromium": "^1.5.227", "node-releases": "^2.0.21", "update-browserslist-db": "^1.1.3" }, @@ -8057,9 +8159,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001743", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001743.tgz", - "integrity": "sha512-e6Ojr7RV14Un7dz6ASD0aZDmQPT/A+eZU+nuTNfjqmRrmkmQlnTNWH0SKmqagx9PeW87UVqapSurtAXifmtdmw==", + "version": "1.0.30001748", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001748.tgz", + "integrity": "sha512-5P5UgAr0+aBmNiplks08JLw+AW/XG/SurlgZLgB1dDLfAw7EfRGxIwzPHxdSCGY/BTKDqIVyJL87cCN6s0ZR0w==", "dev": true, "funding": [ { @@ -8260,9 +8362,9 @@ } }, "node_modules/ci-info": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.0.tgz", - "integrity": "sha512-l+2bNRMiQgcfILUi33labAZYIWlH1kWDp+ecNo5iisRKrbm0xcRyCww71/YU0Fkw0mAFpz9bJayXPjey6vkmaQ==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", + "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==", "dev": true, "funding": [ { @@ -8511,13 +8613,16 @@ "license": "MIT" }, "node_modules/color": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", - "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/color/-/color-5.0.2.tgz", + "integrity": "sha512-e2hz5BzbUPcYlIRHo8ieAhYgoajrJr+hWoceg6E345TPsATMUKqDgzt8fSXZJJbxfpiPzkWyphz8yn8At7q3fA==", "license": "MIT", "dependencies": { - "color-convert": "^1.9.3", - "color-string": "^1.6.0" + "color-convert": "^3.0.1", + "color-string": "^2.0.0" + }, + "engines": { + "node": ">=18" } }, "node_modules/color-convert": { @@ -8539,29 +8644,46 @@ "license": "MIT" }, "node_modules/color-string": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", - "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-2.1.2.tgz", + "integrity": "sha512-RxmjYxbWemV9gKu4zPgiZagUxbH3RQpEIO77XoSSX0ivgABDZ+h8Zuash/EMFLTI4N9QgFPOJ6JQpPZKFxa+dA==", "license": "MIT", "dependencies": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" + "color-name": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/color-string/node_modules/color-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.2.tgz", + "integrity": "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A==", + "license": "MIT", + "engines": { + "node": ">=12.20" } }, "node_modules/color/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-3.1.2.tgz", + "integrity": "sha512-UNqkvCDXstVck3kdowtOTWROIJQwafjOfXSmddoDrXo4cewMKmusCeF22Q24zvjR8nwWib/3S/dfyzPItPEiJg==", "license": "MIT", "dependencies": { - "color-name": "1.1.3" + "color-name": "^2.0.0" + }, + "engines": { + "node": ">=14.6" } }, "node_modules/color/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "license": "MIT" + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.2.tgz", + "integrity": "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A==", + "license": "MIT", + "engines": { + "node": ">=12.20" + } }, "node_modules/colors": { "version": "1.0.3", @@ -8572,16 +8694,6 @@ "node": ">=0.1.90" } }, - "node_modules/colorspace": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", - "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", - "license": "MIT", - "dependencies": { - "color": "^3.1.3", - "text-hex": "1.0.x" - } - }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -9549,9 +9661,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.220", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.220.tgz", - "integrity": "sha512-TWXijEwR1ggr4BdAKrb1nMNqYLTx1/4aD1fkeZU+FVJGTKu53/T7UyHKXlqEX3Ub02csyHePbHmkvnrjcaYzMA==", + "version": "1.5.230", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.230.tgz", + "integrity": "sha512-A6A6Fd3+gMdaed9wX83CvHYJb4UuapPD5X5SLq72VZJzxHSY0/LUweGXRWmQlh2ln7KV7iw7jnwXK7dlPoOnHQ==", "dev": true, "license": "ISC" }, @@ -9987,13 +10099,13 @@ } }, "node_modules/eslint-config-oclif": { - "version": "6.0.104", - "resolved": "https://registry.npmjs.org/eslint-config-oclif/-/eslint-config-oclif-6.0.104.tgz", - "integrity": "sha512-c6OMQPMS5uZtI1FOhJv/Ay+DmJxKlQ3cIRofsnnq6nFyMqHSDqg3gIPRRx91Ub0ET74CWzGRobRPHAo3jMzMKQ==", + "version": "6.0.108", + "resolved": "https://registry.npmjs.org/eslint-config-oclif/-/eslint-config-oclif-6.0.108.tgz", + "integrity": "sha512-FagAOpTrEQ9aKIlCFjkeo3kj0C7WCDv754Fx6un+NGfxVmmKQq5AS0jF00LTtaW6UzOrihQKDG6HsKuL0lXRKg==", "dev": true, "license": "MIT", "dependencies": { - "@eslint/compat": "^1.3.2", + "@eslint/compat": "^1.4.0", "@eslint/eslintrc": "^3.3.1", "@eslint/js": "^9.34.0", "@stylistic/eslint-plugin": "^3.1.0", @@ -10009,7 +10121,7 @@ "eslint-plugin-n": "^17.22.0", "eslint-plugin-perfectionist": "^4", "eslint-plugin-unicorn": "^56.0.1", - "typescript-eslint": "^8.43.0" + "typescript-eslint": "^8.45.0" }, "engines": { "node": ">=18.18.0" @@ -10427,9 +10539,9 @@ } }, "node_modules/eslint-config-oclif/node_modules/@eslint/js": { - "version": "9.35.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.35.0.tgz", - "integrity": "sha512-30iXE9whjlILfWobBkNerJo+TXYsgVM5ERQwMcMKCHckHflCmf7wXDAHlARoWnh0s1U72WqlbeyE7iAcCzuCPw==", + "version": "9.37.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.37.0.tgz", + "integrity": "sha512-jaS+NJ+hximswBG6pjNX0uEJZkrT0zwpVi3BA3vX22aFGjJjmgSTSmPpZCRKmoBL5VY/M6p0xsSJx7rk7sy5gg==", "dev": true, "license": "MIT", "engines": { @@ -10440,17 +10552,17 @@ } }, "node_modules/eslint-config-oclif/node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.44.0.tgz", - "integrity": "sha512-EGDAOGX+uwwekcS0iyxVDmRV9HX6FLSM5kzrAToLTsr9OWCIKG/y3lQheCq18yZ5Xh78rRKJiEpP0ZaCs4ryOQ==", + "version": "8.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.45.0.tgz", + "integrity": "sha512-HC3y9CVuevvWCl/oyZuI47dOeDF9ztdMEfMH8/DW/Mhwa9cCLnK1oD7JoTVGW/u7kFzNZUKUoyJEqkaJh5y3Wg==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.44.0", - "@typescript-eslint/type-utils": "8.44.0", - "@typescript-eslint/utils": "8.44.0", - "@typescript-eslint/visitor-keys": "8.44.0", + "@typescript-eslint/scope-manager": "8.45.0", + "@typescript-eslint/type-utils": "8.45.0", + "@typescript-eslint/utils": "8.45.0", + "@typescript-eslint/visitor-keys": "8.45.0", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", @@ -10464,7 +10576,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.44.0", + "@typescript-eslint/parser": "^8.45.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } @@ -10480,16 +10592,16 @@ } }, "node_modules/eslint-config-oclif/node_modules/@typescript-eslint/parser": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.44.0.tgz", - "integrity": "sha512-VGMpFQGUQWYT9LfnPcX8ouFojyrZ/2w3K5BucvxL/spdNehccKhB4jUyB1yBCXpr2XFm0jkECxgrpXBW2ipoAw==", + "version": "8.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.45.0.tgz", + "integrity": "sha512-TGf22kon8KW+DeKaUmOibKWktRY8b2NSAZNdtWh798COm1NWx8+xJ6iFBtk3IvLdv6+LGLJLRlyhrhEDZWargQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.44.0", - "@typescript-eslint/types": "8.44.0", - "@typescript-eslint/typescript-estree": "8.44.0", - "@typescript-eslint/visitor-keys": "8.44.0", + "@typescript-eslint/scope-manager": "8.45.0", + "@typescript-eslint/types": "8.45.0", + "@typescript-eslint/typescript-estree": "8.45.0", + "@typescript-eslint/visitor-keys": "8.45.0", "debug": "^4.3.4" }, "engines": { @@ -10505,14 +10617,14 @@ } }, "node_modules/eslint-config-oclif/node_modules/@typescript-eslint/scope-manager": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.44.0.tgz", - "integrity": "sha512-87Jv3E+al8wpD+rIdVJm/ItDBe/Im09zXIjFoipOjr5gHUhJmTzfFLuTJ/nPTMc2Srsroy4IBXwcTCHyRR7KzA==", + "version": "8.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.45.0.tgz", + "integrity": "sha512-clmm8XSNj/1dGvJeO6VGH7EUSeA0FMs+5au/u3lrA3KfG8iJ4u8ym9/j2tTEoacAffdW1TVUzXO30W1JTJS7dA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.44.0", - "@typescript-eslint/visitor-keys": "8.44.0" + "@typescript-eslint/types": "8.45.0", + "@typescript-eslint/visitor-keys": "8.45.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -10523,15 +10635,15 @@ } }, "node_modules/eslint-config-oclif/node_modules/@typescript-eslint/type-utils": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.44.0.tgz", - "integrity": "sha512-9cwsoSxJ8Sak67Be/hD2RNt/fsqmWnNE1iHohG8lxqLSNY8xNfyY7wloo5zpW3Nu9hxVgURevqfcH6vvKCt6yg==", + "version": "8.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.45.0.tgz", + "integrity": "sha512-bpjepLlHceKgyMEPglAeULX1vixJDgaKocp0RVJ5u4wLJIMNuKtUXIczpJCPcn2waII0yuvks/5m5/h3ZQKs0A==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.44.0", - "@typescript-eslint/typescript-estree": "8.44.0", - "@typescript-eslint/utils": "8.44.0", + "@typescript-eslint/types": "8.45.0", + "@typescript-eslint/typescript-estree": "8.45.0", + "@typescript-eslint/utils": "8.45.0", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, @@ -10548,9 +10660,9 @@ } }, "node_modules/eslint-config-oclif/node_modules/@typescript-eslint/types": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.44.0.tgz", - "integrity": "sha512-ZSl2efn44VsYM0MfDQe68RKzBz75NPgLQXuGypmym6QVOWL5kegTZuZ02xRAT9T+onqvM6T8CdQk0OwYMB6ZvA==", + "version": "8.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.45.0.tgz", + "integrity": "sha512-WugXLuOIq67BMgQInIxxnsSyRLFxdkJEJu8r4ngLR56q/4Q5LrbfkFRH27vMTjxEK8Pyz7QfzuZe/G15qQnVRA==", "dev": true, "license": "MIT", "engines": { @@ -10562,16 +10674,16 @@ } }, "node_modules/eslint-config-oclif/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.44.0.tgz", - "integrity": "sha512-lqNj6SgnGcQZwL4/SBJ3xdPEfcBuhCG8zdcwCPgYcmiPLgokiNDKlbPzCwEwu7m279J/lBYWtDYL+87OEfn8Jw==", + "version": "8.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.45.0.tgz", + "integrity": "sha512-GfE1NfVbLam6XQ0LcERKwdTTPlLvHvXXhOeUGC1OXi4eQBoyy1iVsW+uzJ/J9jtCz6/7GCQ9MtrQ0fml/jWCnA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.44.0", - "@typescript-eslint/tsconfig-utils": "8.44.0", - "@typescript-eslint/types": "8.44.0", - "@typescript-eslint/visitor-keys": "8.44.0", + "@typescript-eslint/project-service": "8.45.0", + "@typescript-eslint/tsconfig-utils": "8.45.0", + "@typescript-eslint/types": "8.45.0", + "@typescript-eslint/visitor-keys": "8.45.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -10607,16 +10719,16 @@ } }, "node_modules/eslint-config-oclif/node_modules/@typescript-eslint/utils": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.44.0.tgz", - "integrity": "sha512-nktOlVcg3ALo0mYlV+L7sWUD58KG4CMj1rb2HUVOO4aL3K/6wcD+NERqd0rrA5Vg06b42YhF6cFxeixsp9Riqg==", + "version": "8.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.45.0.tgz", + "integrity": "sha512-bxi1ht+tLYg4+XV2knz/F7RVhU0k6VrSMc9sb8DQ6fyCTrGQLHfo7lDtN0QJjZjKkLA2ThrKuCdHEvLReqtIGg==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.44.0", - "@typescript-eslint/types": "8.44.0", - "@typescript-eslint/typescript-estree": "8.44.0" + "@typescript-eslint/scope-manager": "8.45.0", + "@typescript-eslint/types": "8.45.0", + "@typescript-eslint/typescript-estree": "8.45.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -10631,13 +10743,13 @@ } }, "node_modules/eslint-config-oclif/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.44.0.tgz", - "integrity": "sha512-zaz9u8EJ4GBmnehlrpoKvj/E3dNbuQ7q0ucyZImm3cLqJ8INTc970B1qEqDX/Rzq65r3TvVTN7kHWPBoyW7DWw==", + "version": "8.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.45.0.tgz", + "integrity": "sha512-qsaFBA3e09MIDAGFUrTk+dzqtfv1XPVz8t8d1f0ybTzrCY7BKiMC5cjrl1O/P7UmHsNyW90EYSkU/ZWpmXelag==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.44.0", + "@typescript-eslint/types": "8.45.0", "eslint-visitor-keys": "^4.2.1" }, "engines": { @@ -10682,9 +10794,9 @@ } }, "node_modules/eslint-config-oclif/node_modules/eslint": { - "version": "9.35.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.35.0.tgz", - "integrity": "sha512-QePbBFMJFjgmlE+cXAlbHZbHpdFVS2E/6vzCy7aKlebddvl1vadiC4JFV5u/wqTkNUwEV8WrQi257jf5f06hrg==", + "version": "9.37.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.37.0.tgz", + "integrity": "sha512-XyLmROnACWqSxiGYArdef1fItQd47weqB7iwtfr9JHwRrqIXZdcFMvvEcL9xHCmL0SNsOvF0c42lWyM1U5dgig==", "dev": true, "license": "MIT", "peer": true, @@ -10692,11 +10804,11 @@ "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.21.0", - "@eslint/config-helpers": "^0.3.1", - "@eslint/core": "^0.15.2", + "@eslint/config-helpers": "^0.4.0", + "@eslint/core": "^0.16.0", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.35.0", - "@eslint/plugin-kit": "^0.3.5", + "@eslint/js": "9.37.0", + "@eslint/plugin-kit": "^0.4.0", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", @@ -10842,14 +10954,14 @@ } }, "node_modules/eslint-config-oclif/node_modules/eslint-config-xo/node_modules/@stylistic/eslint-plugin": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-5.3.1.tgz", - "integrity": "sha512-Ykums1VYonM0TgkD0VteVq9mrlO2FhF48MDJnPyv3MktIB2ydtuhlO0AfWm7xnW1kyf5bjOqA6xc7JjviuVTxg==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-5.4.0.tgz", + "integrity": "sha512-UG8hdElzuBDzIbjG1QDwnYH0MQ73YLXDFHgZzB4Zh/YJfnw8XNsloVtytqzx0I2Qky9THSdpTmi8Vjn/pf/Lew==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/types": "^8.41.0", + "@eslint-community/eslint-utils": "^4.9.0", + "@typescript-eslint/types": "^8.44.0", "eslint-visitor-keys": "^4.2.1", "espree": "^10.4.0", "estraverse": "^5.3.0", @@ -11354,9 +11466,9 @@ } }, "node_modules/eslint-plugin-n": { - "version": "17.23.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-17.23.0.tgz", - "integrity": "sha512-aPePGxUr5LezcXmMRBF83eK1MmqUYY1NdLdHC+jdpfc5b98eL7yDXY20gXJ6DcTxrHBhrLsfYYqo7J+m0h9YXQ==", + "version": "17.23.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-17.23.1.tgz", + "integrity": "sha512-68PealUpYoHOBh332JLLD9Sj7OQUDkFpmcfqt8R9sySfFSeuGJjMTJQvCRRB96zO3A/PELRLkPrzsHmzEFQQ5A==", "dev": true, "license": "MIT", "dependencies": { @@ -11394,14 +11506,14 @@ } }, "node_modules/eslint-plugin-perfectionist": { - "version": "4.15.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-perfectionist/-/eslint-plugin-perfectionist-4.15.0.tgz", - "integrity": "sha512-pC7PgoXyDnEXe14xvRUhBII8A3zRgggKqJFx2a82fjrItDs1BSI7zdZnQtM2yQvcyod6/ujmzb7ejKPx8lZTnw==", + "version": "4.15.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-perfectionist/-/eslint-plugin-perfectionist-4.15.1.tgz", + "integrity": "sha512-MHF0cBoOG0XyBf7G0EAFCuJJu4I18wy0zAoT1OHfx2o6EOx1EFTIzr2HGeuZa1kDcusoX0xJ9V7oZmaeFd773Q==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "^8.34.1", - "@typescript-eslint/utils": "^8.34.1", + "@typescript-eslint/types": "^8.38.0", + "@typescript-eslint/utils": "^8.38.0", "natural-orderby": "^5.0.0" }, "engines": { @@ -11412,14 +11524,14 @@ } }, "node_modules/eslint-plugin-perfectionist/node_modules/@typescript-eslint/scope-manager": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.44.0.tgz", - "integrity": "sha512-87Jv3E+al8wpD+rIdVJm/ItDBe/Im09zXIjFoipOjr5gHUhJmTzfFLuTJ/nPTMc2Srsroy4IBXwcTCHyRR7KzA==", + "version": "8.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.45.0.tgz", + "integrity": "sha512-clmm8XSNj/1dGvJeO6VGH7EUSeA0FMs+5au/u3lrA3KfG8iJ4u8ym9/j2tTEoacAffdW1TVUzXO30W1JTJS7dA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.44.0", - "@typescript-eslint/visitor-keys": "8.44.0" + "@typescript-eslint/types": "8.45.0", + "@typescript-eslint/visitor-keys": "8.45.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -11430,9 +11542,9 @@ } }, "node_modules/eslint-plugin-perfectionist/node_modules/@typescript-eslint/types": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.44.0.tgz", - "integrity": "sha512-ZSl2efn44VsYM0MfDQe68RKzBz75NPgLQXuGypmym6QVOWL5kegTZuZ02xRAT9T+onqvM6T8CdQk0OwYMB6ZvA==", + "version": "8.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.45.0.tgz", + "integrity": "sha512-WugXLuOIq67BMgQInIxxnsSyRLFxdkJEJu8r4ngLR56q/4Q5LrbfkFRH27vMTjxEK8Pyz7QfzuZe/G15qQnVRA==", "dev": true, "license": "MIT", "engines": { @@ -11444,16 +11556,16 @@ } }, "node_modules/eslint-plugin-perfectionist/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.44.0.tgz", - "integrity": "sha512-lqNj6SgnGcQZwL4/SBJ3xdPEfcBuhCG8zdcwCPgYcmiPLgokiNDKlbPzCwEwu7m279J/lBYWtDYL+87OEfn8Jw==", + "version": "8.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.45.0.tgz", + "integrity": "sha512-GfE1NfVbLam6XQ0LcERKwdTTPlLvHvXXhOeUGC1OXi4eQBoyy1iVsW+uzJ/J9jtCz6/7GCQ9MtrQ0fml/jWCnA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.44.0", - "@typescript-eslint/tsconfig-utils": "8.44.0", - "@typescript-eslint/types": "8.44.0", - "@typescript-eslint/visitor-keys": "8.44.0", + "@typescript-eslint/project-service": "8.45.0", + "@typescript-eslint/tsconfig-utils": "8.45.0", + "@typescript-eslint/types": "8.45.0", + "@typescript-eslint/visitor-keys": "8.45.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -11473,16 +11585,16 @@ } }, "node_modules/eslint-plugin-perfectionist/node_modules/@typescript-eslint/utils": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.44.0.tgz", - "integrity": "sha512-nktOlVcg3ALo0mYlV+L7sWUD58KG4CMj1rb2HUVOO4aL3K/6wcD+NERqd0rrA5Vg06b42YhF6cFxeixsp9Riqg==", + "version": "8.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.45.0.tgz", + "integrity": "sha512-bxi1ht+tLYg4+XV2knz/F7RVhU0k6VrSMc9sb8DQ6fyCTrGQLHfo7lDtN0QJjZjKkLA2ThrKuCdHEvLReqtIGg==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.44.0", - "@typescript-eslint/types": "8.44.0", - "@typescript-eslint/typescript-estree": "8.44.0" + "@typescript-eslint/scope-manager": "8.45.0", + "@typescript-eslint/types": "8.45.0", + "@typescript-eslint/typescript-estree": "8.45.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -11497,13 +11609,13 @@ } }, "node_modules/eslint-plugin-perfectionist/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.44.0.tgz", - "integrity": "sha512-zaz9u8EJ4GBmnehlrpoKvj/E3dNbuQ7q0ucyZImm3cLqJ8INTc970B1qEqDX/Rzq65r3TvVTN7kHWPBoyW7DWw==", + "version": "8.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.45.0.tgz", + "integrity": "sha512-qsaFBA3e09MIDAGFUrTk+dzqtfv1XPVz8t8d1f0ybTzrCY7BKiMC5cjrl1O/P7UmHsNyW90EYSkU/ZWpmXelag==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.44.0", + "@typescript-eslint/types": "8.45.0", "eslint-visitor-keys": "^4.2.1" }, "engines": { @@ -12731,6 +12843,15 @@ "node": ">= 0.6.0" } }, + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -12750,6 +12871,18 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-east-asian-width": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", + "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-func-name": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", @@ -14131,6 +14264,66 @@ "node": ">=0.6.0" } }, + "node_modules/inquirer/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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/inquirer/node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/inquirer/node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/inquirer/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==", + "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/inquirer/node_modules/rxjs": { "version": "7.8.2", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", @@ -14449,13 +14642,14 @@ } }, "node_modules/is-generator-function": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", - "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", "license": "MIT", "dependencies": { - "call-bound": "^1.0.3", - "get-proto": "^1.0.0", + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", "has-tostringtag": "^1.0.2", "safe-regex-test": "^1.1.0" }, @@ -14480,12 +14674,15 @@ } }, "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==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", + "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", "license": "MIT", "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-map": { @@ -14776,12 +14973,12 @@ "license": "MIT" }, "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", + "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", "license": "MIT", "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -16094,15 +16291,14 @@ } }, "node_modules/jsdoc-parse": { - "version": "6.2.4", - "resolved": "https://registry.npmjs.org/jsdoc-parse/-/jsdoc-parse-6.2.4.tgz", - "integrity": "sha512-MQA+lCe3ioZd0uGbyB3nDCDZcKgKC7m/Ivt0LgKZdUoOlMJxUWJQ3WI6GeyHp9ouznKaCjlp7CU9sw5k46yZTw==", + "version": "6.2.5", + "resolved": "https://registry.npmjs.org/jsdoc-parse/-/jsdoc-parse-6.2.5.tgz", + "integrity": "sha512-8JaSNjPLr2IuEY4Das1KM6Z4oLHZYUnjRrr27hKSa78Cj0i5Lur3DzNnCkz+DfrKBDoljGMoWOiBVQbtUZJBPw==", "dev": true, "license": "MIT", "dependencies": { "array-back": "^6.2.2", "find-replace": "^5.0.1", - "lodash.omit": "^4.5.0", "sort-array": "^5.0.0" }, "engines": { @@ -16876,14 +17072,6 @@ "dev": true, "license": "MIT" }, - "node_modules/lodash.omit": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz", - "integrity": "sha512-XeqSp49hNGmlkj2EJlfrQFIzQ6lXdNro9sddtQzcJY8QaoC2GO0DT7xaIokHeyM+mIT0mPMlPvkYzg2xCuHdZg==", - "deprecated": "This package is deprecated. Use destructuring assignment syntax instead.", - "dev": true, - "license": "MIT" - }, "node_modules/lodash.padend": { "version": "4.6.1", "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz", @@ -17402,6 +17590,18 @@ "node": ">=8" } }, + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/mimic-response": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", @@ -17588,6 +17788,19 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/mocha/node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/mocha/node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -17663,9 +17876,9 @@ "license": "ISC" }, "node_modules/napi-postinstall": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.3.tgz", - "integrity": "sha512-uTp172LLXSxuSYHv/kou+f6KW3SMppU9ivthaVTXian9sOt3XM/zHYHpRZiLgQoxeWfYUnslNWQHF1+G71xcow==", + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz", + "integrity": "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==", "dev": true, "license": "MIT", "bin": { @@ -17851,9 +18064,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.21", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.21.tgz", - "integrity": "sha512-5b0pgg78U3hwXkCM8Z9b2FJdPZlr9Psr9V2gQPESdGHqbntyFJKFW4r5TeWGFzafGY3hzs1JC62VEQMbl1JFkw==", + "version": "2.0.23", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.23.tgz", + "integrity": "sha512-cCmFDMSm26S6tQSDpBCg/NR8NENrVPhAJSf+XbxBG4rPFaaonlEoE9wHQmun+cls499TQGSb7ZyPBRlzgKfpeg==", "dev": true, "license": "MIT" }, @@ -17896,9 +18109,9 @@ } }, "node_modules/npm": { - "version": "10.9.3", - "resolved": "https://registry.npmjs.org/npm/-/npm-10.9.3.tgz", - "integrity": "sha512-6Eh1u5Q+kIVXeA8e7l2c/HpnFFcwrkt37xDMujD5be1gloWa9p6j3Fsv3mByXXmqJHy+2cElRMML8opNT7xIJQ==", + "version": "10.9.4", + "resolved": "https://registry.npmjs.org/npm/-/npm-10.9.4.tgz", + "integrity": "sha512-OnUG836FwboQIbqtefDNlyR0gTHzIfwRfE3DuiNewBvnMnWEpB0VEXwBlFVgqpNzIgYo/MHh3d2Hel/pszapAA==", "bundleDependencies": [ "@isaacs/string-locale-compare", "@npmcli/arborist", @@ -20830,21 +21043,21 @@ } }, "node_modules/oclif": { - "version": "4.22.22", - "resolved": "https://registry.npmjs.org/oclif/-/oclif-4.22.22.tgz", - "integrity": "sha512-fN1TVjLsITc1EMmkVwEoMfvus90eUMZSqabtwh/LTI4DMLJXq5zcCQiLJLV2MD0mnwj/Ou20UZJ7ENJ++KpwXQ==", + "version": "4.22.29", + "resolved": "https://registry.npmjs.org/oclif/-/oclif-4.22.29.tgz", + "integrity": "sha512-vflirEWfbH0idQNKpsc5TNMx4Tnlc9J6sVixF5apTADItrxMvb8L9AvathR0u+cIqVH3AymP8oZ+N2dBl//Qpw==", "dev": true, "license": "MIT", "dependencies": { - "@aws-sdk/client-cloudfront": "^3.888.0", - "@aws-sdk/client-s3": "^3.888.0", + "@aws-sdk/client-cloudfront": "^3.901.0", + "@aws-sdk/client-s3": "^3.901.0", "@inquirer/confirm": "^3.1.22", "@inquirer/input": "^2.2.4", "@inquirer/select": "^2.5.0", - "@oclif/core": "^4.5.3", - "@oclif/plugin-help": "^6.2.32", + "@oclif/core": "^4.5.4", + "@oclif/plugin-help": "^6.2.33", "@oclif/plugin-not-found": "^3.2.68", - "@oclif/plugin-warn-if-update-available": "^3.1.46", + "@oclif/plugin-warn-if-update-available": "^3.1.48", "ansis": "^3.16.0", "async-retry": "^1.3.3", "change-case": "^4", @@ -21024,44 +21237,176 @@ "license": "MIT" }, "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==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-8.2.0.tgz", + "integrity": "sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==", "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" + "chalk": "^5.3.0", + "cli-cursor": "^5.0.0", + "cli-spinners": "^2.9.2", + "is-interactive": "^2.0.0", + "is-unicode-supported": "^2.0.0", + "log-symbols": "^6.0.0", + "stdin-discarder": "^0.2.2", + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0" }, "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/ora/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ora/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==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/ora/node_modules/cli-cursor": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", + "license": "MIT", + "dependencies": { + "restore-cursor": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/emoji-regex": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.5.0.tgz", + "integrity": "sha512-lb49vf1Xzfx080OKA0o6l8DQQpV+6Vg95zyCJX9VB/BqKYlhG7N4wgROUUHRA+ZPUefLnteQOad7z1kT2bV7bg==", + "license": "MIT" + }, "node_modules/ora/node_modules/log-symbols": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-6.0.0.tgz", + "integrity": "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==", + "license": "MIT", + "dependencies": { + "chalk": "^5.3.0", + "is-unicode-supported": "^1.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/log-symbols/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==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/onetime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "license": "MIT", + "dependencies": { + "mimic-function": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/restore-cursor": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "license": "MIT", + "dependencies": { + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/signal-exit": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/ora/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", "license": "MIT", "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" }, "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/ora/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", @@ -22785,9 +23130,9 @@ } }, "node_modules/rollup": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.50.2.tgz", - "integrity": "sha512-BgLRGy7tNS9H66aIMASq1qSYbAAJV6Z6WR4QYTvj5FgF15rZ/ympT1uixHXwzbZUBDbkvqUI1KR0fH1FhMaQ9w==", + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.4.tgz", + "integrity": "sha512-CLEVl+MnPAiKh5pl4dEWSyMTpuflgNQiLGhMv8ezD5W/qP8AKvmYpCOKRRNOh7oRKnauBZ4SyeYkMS+1VSyKwQ==", "license": "MIT", "dependencies": { "@types/estree": "1.0.8" @@ -22800,27 +23145,28 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.50.2", - "@rollup/rollup-android-arm64": "4.50.2", - "@rollup/rollup-darwin-arm64": "4.50.2", - "@rollup/rollup-darwin-x64": "4.50.2", - "@rollup/rollup-freebsd-arm64": "4.50.2", - "@rollup/rollup-freebsd-x64": "4.50.2", - "@rollup/rollup-linux-arm-gnueabihf": "4.50.2", - "@rollup/rollup-linux-arm-musleabihf": "4.50.2", - "@rollup/rollup-linux-arm64-gnu": "4.50.2", - "@rollup/rollup-linux-arm64-musl": "4.50.2", - "@rollup/rollup-linux-loong64-gnu": "4.50.2", - "@rollup/rollup-linux-ppc64-gnu": "4.50.2", - "@rollup/rollup-linux-riscv64-gnu": "4.50.2", - "@rollup/rollup-linux-riscv64-musl": "4.50.2", - "@rollup/rollup-linux-s390x-gnu": "4.50.2", - "@rollup/rollup-linux-x64-gnu": "4.50.2", - "@rollup/rollup-linux-x64-musl": "4.50.2", - "@rollup/rollup-openharmony-arm64": "4.50.2", - "@rollup/rollup-win32-arm64-msvc": "4.50.2", - "@rollup/rollup-win32-ia32-msvc": "4.50.2", - "@rollup/rollup-win32-x64-msvc": "4.50.2", + "@rollup/rollup-android-arm-eabi": "4.52.4", + "@rollup/rollup-android-arm64": "4.52.4", + "@rollup/rollup-darwin-arm64": "4.52.4", + "@rollup/rollup-darwin-x64": "4.52.4", + "@rollup/rollup-freebsd-arm64": "4.52.4", + "@rollup/rollup-freebsd-x64": "4.52.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.52.4", + "@rollup/rollup-linux-arm-musleabihf": "4.52.4", + "@rollup/rollup-linux-arm64-gnu": "4.52.4", + "@rollup/rollup-linux-arm64-musl": "4.52.4", + "@rollup/rollup-linux-loong64-gnu": "4.52.4", + "@rollup/rollup-linux-ppc64-gnu": "4.52.4", + "@rollup/rollup-linux-riscv64-gnu": "4.52.4", + "@rollup/rollup-linux-riscv64-musl": "4.52.4", + "@rollup/rollup-linux-s390x-gnu": "4.52.4", + "@rollup/rollup-linux-x64-gnu": "4.52.4", + "@rollup/rollup-linux-x64-musl": "4.52.4", + "@rollup/rollup-openharmony-arm64": "4.52.4", + "@rollup/rollup-win32-arm64-msvc": "4.52.4", + "@rollup/rollup-win32-ia32-msvc": "4.52.4", + "@rollup/rollup-win32-x64-gnu": "4.52.4", + "@rollup/rollup-win32-x64-msvc": "4.52.4", "fsevents": "~2.3.2" } }, @@ -23448,21 +23794,6 @@ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "license": "ISC" }, - "node_modules/simple-swizzle": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.4.tgz", - "integrity": "sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==", - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.3.1" - } - }, - "node_modules/simple-swizzle/node_modules/is-arrayish": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.4.tgz", - "integrity": "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==", - "license": "MIT" - }, "node_modules/sinon": { "version": "19.0.5", "resolved": "https://registry.npmjs.org/sinon/-/sinon-19.0.5.tgz", @@ -23992,6 +24323,18 @@ "node": ">= 0.8" } }, + "node_modules/stdin-discarder": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.2.2.tgz", + "integrity": "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/stdout-stderr": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/stdout-stderr/-/stdout-stderr-0.1.13.tgz", @@ -24384,9 +24727,9 @@ } }, "node_modules/tapable": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.3.tgz", - "integrity": "sha512-ZL6DDuAlRlLGghwcfmSn9sK3Hr6ArtyudlSAiCqQ6IfE+b+HHbydbYDIG15IfS5do+7XQQBdBiubF/cV2dnDzg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", "dev": true, "license": "MIT", "engines": { @@ -24717,9 +25060,9 @@ } }, "node_modules/ts-jest": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.2.tgz", - "integrity": "sha512-pBNOkn4HtuLpNrXTMVRC9b642CBaDnKqWXny4OzuoULT9S7Kf8MMlaRe2veKax12rjf5WcpMBhVPbQurlWGNxA==", + "version": "29.4.4", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.4.tgz", + "integrity": "sha512-ccVcRABct5ZELCT5U0+DZwkXMCcOCLi2doHRrKy1nK/s7J7bch6TzJMsrY09WxgUUIP/ITfmcDS8D2yl63rnXw==", "dev": true, "license": "MIT", "dependencies": { @@ -24912,9 +25255,9 @@ "license": "0BSD" }, "node_modules/tsx": { - "version": "4.20.5", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.20.5.tgz", - "integrity": "sha512-+wKjMNU9w/EaQayHXb7WA7ZaHY6hN8WgfvHNQ3t1PnU91/7O8TcTnIhCDYTZwnt8JsO9IBqZ30Ln1r7pPF52Aw==", + "version": "4.20.6", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.20.6.tgz", + "integrity": "sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg==", "dev": true, "license": "MIT", "dependencies": { @@ -25147,16 +25490,16 @@ } }, "node_modules/typescript-eslint": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.44.0.tgz", - "integrity": "sha512-ib7mCkYuIzYonCq9XWF5XNw+fkj2zg629PSa9KNIQ47RXFF763S5BIX4wqz1+FLPogTZoiw8KmCiRPRa8bL3qw==", + "version": "8.45.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.45.0.tgz", + "integrity": "sha512-qzDmZw/Z5beNLUrXfd0HIW6MzIaAV5WNDxmMs9/3ojGOpYavofgNAAD/nC6tGV2PczIi0iw8vot2eAe/sBn7zg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.44.0", - "@typescript-eslint/parser": "8.44.0", - "@typescript-eslint/typescript-estree": "8.44.0", - "@typescript-eslint/utils": "8.44.0" + "@typescript-eslint/eslint-plugin": "8.45.0", + "@typescript-eslint/parser": "8.45.0", + "@typescript-eslint/typescript-estree": "8.45.0", + "@typescript-eslint/utils": "8.45.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -25171,17 +25514,17 @@ } }, "node_modules/typescript-eslint/node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.44.0.tgz", - "integrity": "sha512-EGDAOGX+uwwekcS0iyxVDmRV9HX6FLSM5kzrAToLTsr9OWCIKG/y3lQheCq18yZ5Xh78rRKJiEpP0ZaCs4ryOQ==", + "version": "8.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.45.0.tgz", + "integrity": "sha512-HC3y9CVuevvWCl/oyZuI47dOeDF9ztdMEfMH8/DW/Mhwa9cCLnK1oD7JoTVGW/u7kFzNZUKUoyJEqkaJh5y3Wg==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.44.0", - "@typescript-eslint/type-utils": "8.44.0", - "@typescript-eslint/utils": "8.44.0", - "@typescript-eslint/visitor-keys": "8.44.0", + "@typescript-eslint/scope-manager": "8.45.0", + "@typescript-eslint/type-utils": "8.45.0", + "@typescript-eslint/utils": "8.45.0", + "@typescript-eslint/visitor-keys": "8.45.0", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", @@ -25195,22 +25538,22 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.44.0", + "@typescript-eslint/parser": "^8.45.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/typescript-eslint/node_modules/@typescript-eslint/parser": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.44.0.tgz", - "integrity": "sha512-VGMpFQGUQWYT9LfnPcX8ouFojyrZ/2w3K5BucvxL/spdNehccKhB4jUyB1yBCXpr2XFm0jkECxgrpXBW2ipoAw==", + "version": "8.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.45.0.tgz", + "integrity": "sha512-TGf22kon8KW+DeKaUmOibKWktRY8b2NSAZNdtWh798COm1NWx8+xJ6iFBtk3IvLdv6+LGLJLRlyhrhEDZWargQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.44.0", - "@typescript-eslint/types": "8.44.0", - "@typescript-eslint/typescript-estree": "8.44.0", - "@typescript-eslint/visitor-keys": "8.44.0", + "@typescript-eslint/scope-manager": "8.45.0", + "@typescript-eslint/types": "8.45.0", + "@typescript-eslint/typescript-estree": "8.45.0", + "@typescript-eslint/visitor-keys": "8.45.0", "debug": "^4.3.4" }, "engines": { @@ -25226,14 +25569,14 @@ } }, "node_modules/typescript-eslint/node_modules/@typescript-eslint/scope-manager": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.44.0.tgz", - "integrity": "sha512-87Jv3E+al8wpD+rIdVJm/ItDBe/Im09zXIjFoipOjr5gHUhJmTzfFLuTJ/nPTMc2Srsroy4IBXwcTCHyRR7KzA==", + "version": "8.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.45.0.tgz", + "integrity": "sha512-clmm8XSNj/1dGvJeO6VGH7EUSeA0FMs+5au/u3lrA3KfG8iJ4u8ym9/j2tTEoacAffdW1TVUzXO30W1JTJS7dA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.44.0", - "@typescript-eslint/visitor-keys": "8.44.0" + "@typescript-eslint/types": "8.45.0", + "@typescript-eslint/visitor-keys": "8.45.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -25244,15 +25587,15 @@ } }, "node_modules/typescript-eslint/node_modules/@typescript-eslint/type-utils": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.44.0.tgz", - "integrity": "sha512-9cwsoSxJ8Sak67Be/hD2RNt/fsqmWnNE1iHohG8lxqLSNY8xNfyY7wloo5zpW3Nu9hxVgURevqfcH6vvKCt6yg==", + "version": "8.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.45.0.tgz", + "integrity": "sha512-bpjepLlHceKgyMEPglAeULX1vixJDgaKocp0RVJ5u4wLJIMNuKtUXIczpJCPcn2waII0yuvks/5m5/h3ZQKs0A==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.44.0", - "@typescript-eslint/typescript-estree": "8.44.0", - "@typescript-eslint/utils": "8.44.0", + "@typescript-eslint/types": "8.45.0", + "@typescript-eslint/typescript-estree": "8.45.0", + "@typescript-eslint/utils": "8.45.0", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, @@ -25269,9 +25612,9 @@ } }, "node_modules/typescript-eslint/node_modules/@typescript-eslint/types": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.44.0.tgz", - "integrity": "sha512-ZSl2efn44VsYM0MfDQe68RKzBz75NPgLQXuGypmym6QVOWL5kegTZuZ02xRAT9T+onqvM6T8CdQk0OwYMB6ZvA==", + "version": "8.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.45.0.tgz", + "integrity": "sha512-WugXLuOIq67BMgQInIxxnsSyRLFxdkJEJu8r4ngLR56q/4Q5LrbfkFRH27vMTjxEK8Pyz7QfzuZe/G15qQnVRA==", "dev": true, "license": "MIT", "engines": { @@ -25283,16 +25626,16 @@ } }, "node_modules/typescript-eslint/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.44.0.tgz", - "integrity": "sha512-lqNj6SgnGcQZwL4/SBJ3xdPEfcBuhCG8zdcwCPgYcmiPLgokiNDKlbPzCwEwu7m279J/lBYWtDYL+87OEfn8Jw==", + "version": "8.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.45.0.tgz", + "integrity": "sha512-GfE1NfVbLam6XQ0LcERKwdTTPlLvHvXXhOeUGC1OXi4eQBoyy1iVsW+uzJ/J9jtCz6/7GCQ9MtrQ0fml/jWCnA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.44.0", - "@typescript-eslint/tsconfig-utils": "8.44.0", - "@typescript-eslint/types": "8.44.0", - "@typescript-eslint/visitor-keys": "8.44.0", + "@typescript-eslint/project-service": "8.45.0", + "@typescript-eslint/tsconfig-utils": "8.45.0", + "@typescript-eslint/types": "8.45.0", + "@typescript-eslint/visitor-keys": "8.45.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -25312,16 +25655,16 @@ } }, "node_modules/typescript-eslint/node_modules/@typescript-eslint/utils": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.44.0.tgz", - "integrity": "sha512-nktOlVcg3ALo0mYlV+L7sWUD58KG4CMj1rb2HUVOO4aL3K/6wcD+NERqd0rrA5Vg06b42YhF6cFxeixsp9Riqg==", + "version": "8.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.45.0.tgz", + "integrity": "sha512-bxi1ht+tLYg4+XV2knz/F7RVhU0k6VrSMc9sb8DQ6fyCTrGQLHfo7lDtN0QJjZjKkLA2ThrKuCdHEvLReqtIGg==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.44.0", - "@typescript-eslint/types": "8.44.0", - "@typescript-eslint/typescript-estree": "8.44.0" + "@typescript-eslint/scope-manager": "8.45.0", + "@typescript-eslint/types": "8.45.0", + "@typescript-eslint/typescript-estree": "8.45.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -25336,13 +25679,13 @@ } }, "node_modules/typescript-eslint/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.44.0.tgz", - "integrity": "sha512-zaz9u8EJ4GBmnehlrpoKvj/E3dNbuQ7q0ucyZImm3cLqJ8INTc970B1qEqDX/Rzq65r3TvVTN7kHWPBoyW7DWw==", + "version": "8.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.45.0.tgz", + "integrity": "sha512-qsaFBA3e09MIDAGFUrTk+dzqtfv1XPVz8t8d1f0ybTzrCY7BKiMC5cjrl1O/P7UmHsNyW90EYSkU/ZWpmXelag==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.44.0", + "@typescript-eslint/types": "8.45.0", "eslint-visitor-keys": "^4.2.1" }, "engines": { @@ -25906,13 +26249,13 @@ } }, "node_modules/winston": { - "version": "3.17.0", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.17.0.tgz", - "integrity": "sha512-DLiFIXYC5fMPxaRg832S6F5mJYvePtmO5G9v9IgUFPhXm9/GkXarH/TUrBAVzhTCzAj9anE/+GjrgXp/54nOgw==", + "version": "3.18.3", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.18.3.tgz", + "integrity": "sha512-NoBZauFNNWENgsnC9YpgyYwOVrl2m58PpQ8lNHjV3kosGs7KJ7Npk9pCUE+WJlawVSe8mykWDKWFSVfs3QO9ww==", "license": "MIT", "dependencies": { "@colors/colors": "^1.6.0", - "@dabh/diagnostics": "^2.0.2", + "@dabh/diagnostics": "^2.0.8", "async": "^3.2.3", "is-stream": "^2.0.0", "logform": "^2.7.0", @@ -26275,38 +26618,40 @@ }, "packages/contentstack": { "name": "@contentstack/cli", - "version": "1.48.0", + "version": "2.0.0-beta", "license": "MIT", "dependencies": { "@contentstack/cli-audit": "~1.14.1", "@contentstack/cli-auth": "~1.6.1", - "@contentstack/cli-cm-bootstrap": "~1.16.0", + "@contentstack/cli-cm-bootstrap": "~2.0.0-beta", "@contentstack/cli-cm-branches": "~1.6.0", "@contentstack/cli-cm-bulk-publish": "~1.10.0", - "@contentstack/cli-cm-clone": "~1.16.1", - "@contentstack/cli-cm-export": "~1.20.1", + "@contentstack/cli-cm-clone": "~2.0.0-beta", + "@contentstack/cli-cm-export": "~2.0.0-beta", "@contentstack/cli-cm-export-to-csv": "~1.9.1", - "@contentstack/cli-cm-import": "~1.28.1", - "@contentstack/cli-cm-import-setup": "1.5.0", + "@contentstack/cli-cm-import": "~2.0.0-beta", + "@contentstack/cli-cm-import-setup": "1.6.0", "@contentstack/cli-cm-migrate-rte": "~1.6.1", - "@contentstack/cli-cm-seed": "~1.12.2", + "@contentstack/cli-cm-seed": "~2.0.0-beta", "@contentstack/cli-command": "~1.6.1", "@contentstack/cli-config": "~1.15.2", "@contentstack/cli-launch": "^1.9.2", "@contentstack/cli-migration": "~1.8.1", - "@contentstack/cli-utilities": "~1.14.2", - "@contentstack/cli-variants": "~1.3.1", + "@contentstack/cli-utilities": "~1.14.3", + "@contentstack/cli-variants": "~2.0.0-beta", "@contentstack/management": "~1.22.0", "@oclif/core": "^4.3.0", "@oclif/plugin-help": "^6.2.28", "@oclif/plugin-not-found": "^3.2.53", "@oclif/plugin-plugins": "^5.4.38", "chalk": "^4.1.2", + "cli-progress": "^3.12.0", "debug": "^4.4.1", "figlet": "1.8.1", "inquirer": "8.2.6", "node-machine-id": "^1.1.12", "open": "^8.4.2", + "ora": "^8.2.0", "semver": "^7.7.2", "short-uuid": "^4.2.2", "uuid": "^9.0.1", @@ -26396,9 +26741,9 @@ "license": "MIT" }, "packages/contentstack-audit/node_modules/@types/node": { - "version": "20.19.16", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.16.tgz", - "integrity": "sha512-VS6TTONVdgwJwtJr7U+ghEjpfmQdqehLLpg/iMYGOd1+ilaFjdBJwFuPggJ4EAYPDCzWfDUHoIxyVnu+tOWVuQ==", + "version": "20.19.19", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.19.tgz", + "integrity": "sha512-pb1Uqj5WJP7wrcbLU7Ru4QtA0+3kAXrkutGiD26wUKzSMgNNaPARTUDQmElUXp64kh3cWdou3Q0C7qwwxqSFmg==", "dev": true, "license": "MIT", "dependencies": { @@ -26406,9 +26751,9 @@ } }, "packages/contentstack-audit/node_modules/typescript": { - "version": "5.9.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", - "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", "bin": { @@ -26572,10 +26917,10 @@ }, "packages/contentstack-bootstrap": { "name": "@contentstack/cli-cm-bootstrap", - "version": "1.16.0", + "version": "2.0.0-beta", "license": "MIT", "dependencies": { - "@contentstack/cli-cm-seed": "~1.12.2", + "@contentstack/cli-cm-seed": "~2.0.0-beta", "@contentstack/cli-command": "~1.6.1", "@contentstack/cli-utilities": "~1.14.1", "@oclif/core": "^4.3.0", @@ -26716,12 +27061,12 @@ }, "packages/contentstack-clone": { "name": "@contentstack/cli-cm-clone", - "version": "1.16.1", + "version": "2.0.0-beta", "license": "MIT", "dependencies": { "@colors/colors": "^1.6.0", - "@contentstack/cli-cm-export": "~1.20.1", - "@contentstack/cli-cm-import": "~1.28.1", + "@contentstack/cli-cm-export": "~2.0.0-beta", + "@contentstack/cli-cm-import": "~2.0.0-beta", "@contentstack/cli-command": "~1.6.1", "@contentstack/cli-utilities": "~1.14.1", "@oclif/core": "^4.3.0", @@ -26749,6 +27094,66 @@ "node": ">=14.0.0" } }, + "packages/contentstack-clone/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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "packages/contentstack-clone/node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/contentstack-clone/node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/contentstack-clone/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==", + "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" + } + }, "packages/contentstack-command": { "name": "@contentstack/cli-command", "version": "1.6.1", @@ -27159,12 +27564,12 @@ }, "packages/contentstack-export": { "name": "@contentstack/cli-cm-export", - "version": "1.20.2", + "version": "2.0.0-beta", "license": "MIT", "dependencies": { "@contentstack/cli-command": "~1.6.1", "@contentstack/cli-utilities": "~1.14.1", - "@contentstack/cli-variants": "~1.3.3", + "@contentstack/cli-variants": "~2.0.0-beta", "@oclif/core": "^4.3.3", "async": "^3.2.6", "big-json": "^3.2.0", @@ -27314,14 +27719,14 @@ "license": "MIT" }, "packages/contentstack-export-to-csv/node_modules/@types/node": { - "version": "24.5.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.5.1.tgz", - "integrity": "sha512-/SQdmUP2xa+1rdx7VwB9yPq8PaKej8TD5cQ+XfKDPWWC+VDJU4rvVVagXqKUzhKjtFoNA8rXDJAkCxQPAe00+Q==", + "version": "24.7.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.7.0.tgz", + "integrity": "sha512-IbKooQVqUBrlzWTi79E8Fw78l8k1RNtlDDNWsFZs7XonuQSJ8oNYfEeclhprUldXISRMLzBpILuKgPlIxm+/Yw==", "license": "MIT", "optional": true, "peer": true, "dependencies": { - "undici-types": "~7.12.0" + "undici-types": "~7.14.0" } }, "packages/contentstack-export-to-csv/node_modules/acorn": { @@ -27566,6 +27971,27 @@ "node": ">=12.0.0" } }, + "packages/contentstack-export-to-csv/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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "packages/contentstack-export-to-csv/node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "packages/contentstack-export-to-csv/node_modules/js-yaml": { "version": "3.14.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", @@ -27587,6 +28013,22 @@ "dev": true, "license": "MIT" }, + "packages/contentstack-export-to-csv/node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "packages/contentstack-export-to-csv/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -27615,6 +28057,29 @@ "url": "https://github.com/sponsors/isaacs" } }, + "packages/contentstack-export-to-csv/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==", + "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" + } + }, "packages/contentstack-export-to-csv/node_modules/rxjs": { "version": "7.8.2", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", @@ -27625,9 +28090,9 @@ } }, "packages/contentstack-export-to-csv/node_modules/undici-types": { - "version": "7.12.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.12.0.tgz", - "integrity": "sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ==", + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.14.0.tgz", + "integrity": "sha512-QQiYxHuyZ9gQUIrmPo3IA+hUl4KYk8uSA7cHrcKd/l3p1OTpZcM0Tbp9x7FAtXdAYhlasd60ncPpgu6ihG6TOA==", "license": "MIT", "optional": true, "peer": true @@ -27648,13 +28113,13 @@ }, "packages/contentstack-import": { "name": "@contentstack/cli-cm-import", - "version": "1.28.1", + "version": "2.0.0-beta", "license": "MIT", "dependencies": { "@contentstack/cli-audit": "~1.14.1", "@contentstack/cli-command": "~1.6.1", "@contentstack/cli-utilities": "~1.14.1", - "@contentstack/cli-variants": "~1.3.3", + "@contentstack/cli-variants": "~2.0.0-beta", "@contentstack/management": "~1.22.0", "@oclif/core": "^4.3.0", "big-json": "^3.2.0", @@ -27695,7 +28160,7 @@ }, "packages/contentstack-import-setup": { "name": "@contentstack/cli-cm-import-setup", - "version": "1.5.0", + "version": "1.6.0", "license": "MIT", "dependencies": { "@contentstack/cli-command": "~1.6.1", @@ -27801,10 +28266,10 @@ }, "packages/contentstack-seed": { "name": "@contentstack/cli-cm-seed", - "version": "1.12.2", + "version": "2.0.0-beta", "license": "MIT", "dependencies": { - "@contentstack/cli-cm-import": "~1.28.1", + "@contentstack/cli-cm-import": "~2.0.0-beta", "@contentstack/cli-command": "~1.6.1", "@contentstack/cli-utilities": "~1.14.1", "@contentstack/management": "~1.22.0", @@ -27883,7 +28348,7 @@ }, "packages/contentstack-utilities": { "name": "@contentstack/cli-utilities", - "version": "1.14.2", + "version": "1.14.3", "license": "MIT", "dependencies": { "@contentstack/management": "~1.22.0", @@ -27943,9 +28408,69 @@ "dev": true, "license": "MIT" }, + "packages/contentstack-utilities/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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "packages/contentstack-utilities/node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/contentstack-utilities/node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/contentstack-utilities/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==", + "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" + } + }, "packages/contentstack-variants": { "name": "@contentstack/cli-variants", - "version": "1.3.3", + "version": "2.0.0-beta", "license": "MIT", "dependencies": { "@contentstack/cli-utilities": "~1.14.1", @@ -27967,9 +28492,9 @@ } }, "packages/contentstack-variants/node_modules/@types/node": { - "version": "20.19.16", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.16.tgz", - "integrity": "sha512-VS6TTONVdgwJwtJr7U+ghEjpfmQdqehLLpg/iMYGOd1+ilaFjdBJwFuPggJ4EAYPDCzWfDUHoIxyVnu+tOWVuQ==", + "version": "20.19.19", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.19.tgz", + "integrity": "sha512-pb1Uqj5WJP7wrcbLU7Ru4QtA0+3kAXrkutGiD26wUKzSMgNNaPARTUDQmElUXp64kh3cWdou3Q0C7qwwxqSFmg==", "dev": true, "license": "MIT", "dependencies": { @@ -27977,9 +28502,9 @@ } }, "packages/contentstack-variants/node_modules/typescript": { - "version": "5.9.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", - "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", "bin": { diff --git a/packages/contentstack-auth/README.md b/packages/contentstack-auth/README.md index 4133db5072..13b053a8a7 100644 --- a/packages/contentstack-auth/README.md +++ b/packages/contentstack-auth/README.md @@ -18,7 +18,7 @@ $ npm install -g @contentstack/cli-auth $ csdx COMMAND running command... $ csdx (--version) -@contentstack/cli-auth/1.5.1 darwin-arm64 node-v22.13.1 +@contentstack/cli-auth/1.6.1 darwin-arm64 node-v22.14.0 $ csdx --help [COMMAND] USAGE $ csdx COMMAND diff --git a/packages/contentstack-auth/src/base-command.ts b/packages/contentstack-auth/src/base-command.ts index efe15265c0..f9cca6e93e 100644 --- a/packages/contentstack-auth/src/base-command.ts +++ b/packages/contentstack-auth/src/base-command.ts @@ -51,7 +51,6 @@ export abstract class BaseCommand extends Command { command: this.context?.info?.command || 'auth', module: '', userId: configHandler.get('userUid') || '', - email: configHandler.get('email') || '', sessionId: this.context?.sessionId, apiKey: apiKey || '', orgId: configHandler.get('oauthOrgUid') || '', diff --git a/packages/contentstack-auth/src/interfaces/index.ts b/packages/contentstack-auth/src/interfaces/index.ts index cc9336b30a..373c0dfe48 100644 --- a/packages/contentstack-auth/src/interfaces/index.ts +++ b/packages/contentstack-auth/src/interfaces/index.ts @@ -28,7 +28,7 @@ export interface Context { command: string; module: string; userId: string | undefined; - email: string | undefined; + email?: string | undefined; sessionId: string | undefined; clientId?: string | undefined; apiKey: string; diff --git a/packages/contentstack-bootstrap/README.md b/packages/contentstack-bootstrap/README.md index 7ab57cb220..3beb695d58 100644 --- a/packages/contentstack-bootstrap/README.md +++ b/packages/contentstack-bootstrap/README.md @@ -15,7 +15,7 @@ $ npm install -g @contentstack/cli-cm-bootstrap $ csdx COMMAND running command... $ csdx (--version) -@contentstack/cli-cm-bootstrap/1.15.1 darwin-arm64 node-v22.14.0 +@contentstack/cli-cm-bootstrap/2.0.0-beta darwin-arm64 node-v22.14.0 $ csdx --help [COMMAND] USAGE $ csdx COMMAND diff --git a/packages/contentstack-bootstrap/package.json b/packages/contentstack-bootstrap/package.json index 5c266af0b6..dffb8b6f50 100644 --- a/packages/contentstack-bootstrap/package.json +++ b/packages/contentstack-bootstrap/package.json @@ -1,7 +1,7 @@ { "name": "@contentstack/cli-cm-bootstrap", "description": "Bootstrap contentstack apps", - "version": "1.16.0", + "version": "2.0.0-beta", "author": "Contentstack", "bugs": "https://github.com/contentstack/cli/issues", "scripts": { @@ -16,7 +16,7 @@ "test:report": "nyc --reporter=lcov mocha \"test/**/*.test.js\"" }, "dependencies": { - "@contentstack/cli-cm-seed": "~1.12.2", + "@contentstack/cli-cm-seed": "~2.0.0-beta", "@contentstack/cli-command": "~1.6.1", "@contentstack/cli-utilities": "~1.14.1", "@oclif/core": "^4.3.0", diff --git a/packages/contentstack-branches/README.md b/packages/contentstack-branches/README.md index a66ae9a7fa..fe6d306d13 100755 --- a/packages/contentstack-branches/README.md +++ b/packages/contentstack-branches/README.md @@ -37,7 +37,7 @@ $ npm install -g @contentstack/cli-cm-branches $ csdx COMMAND running command... $ csdx (--version) -@contentstack/cli-cm-branches/1.6.0 darwin-arm64 node-v22.13.0 +@contentstack/cli-cm-branches/1.6.0 darwin-arm64 node-v22.14.0 $ csdx --help [COMMAND] USAGE $ csdx COMMAND diff --git a/packages/contentstack-clone/README.md b/packages/contentstack-clone/README.md index f5092e380b..2310764945 100644 --- a/packages/contentstack-clone/README.md +++ b/packages/contentstack-clone/README.md @@ -16,7 +16,7 @@ $ npm install -g @contentstack/cli-cm-clone $ csdx COMMAND running command... $ csdx (--version) -@contentstack/cli-cm-clone/1.16.1 darwin-arm64 node-v22.13.1 +@contentstack/cli-cm-clone/2.0.0-beta darwin-arm64 node-v22.14.0 $ csdx --help [COMMAND] USAGE $ csdx COMMAND diff --git a/packages/contentstack-clone/package.json b/packages/contentstack-clone/package.json index cd270f22b2..83a635f65f 100644 --- a/packages/contentstack-clone/package.json +++ b/packages/contentstack-clone/package.json @@ -1,13 +1,13 @@ { "name": "@contentstack/cli-cm-clone", "description": "Contentstack stack clone plugin", - "version": "1.16.1", + "version": "2.0.0-beta", "author": "Contentstack", "bugs": "https://github.com/rohitmishra209/cli-cm-clone/issues", "dependencies": { "@colors/colors": "^1.6.0", - "@contentstack/cli-cm-export": "~1.20.1", - "@contentstack/cli-cm-import": "~1.28.1", + "@contentstack/cli-cm-export": "~2.0.0-beta", + "@contentstack/cli-cm-import": "~2.0.0-beta", "@contentstack/cli-command": "~1.6.1", "@contentstack/cli-utilities": "~1.14.1", "@oclif/core": "^4.3.0", diff --git a/packages/contentstack-config/src/commands/config/set/log.ts b/packages/contentstack-config/src/commands/config/set/log.ts index 82449f3461..0c9f96dee7 100644 --- a/packages/contentstack-config/src/commands/config/set/log.ts +++ b/packages/contentstack-config/src/commands/config/set/log.ts @@ -48,12 +48,12 @@ export default class LogSetCommand extends Command { if (pathExt && pathExt.length > 0) { resolvedPath = path.dirname(resolvedPath); } - + currentLoggingConfig.path = resolvedPath; } if (flags['show-console-logs'] !== undefined) { - currentLoggingConfig['show-console-logs'] = flags['show-console-logs']; + currentLoggingConfig['showConsoleLogs'] = flags['show-console-logs']; } configHandler.set('log', currentLoggingConfig); @@ -67,9 +67,10 @@ export default class LogSetCommand extends Command { if (flags['show-console-logs'] !== undefined) { cliux.success( - messageHandler.parse('CLI_CONFIG_LOG_CONSOLE_SET', String(currentLoggingConfig['show-console-logs'])), + messageHandler.parse('CLI_CONFIG_LOG_CONSOLE_SET', String(currentLoggingConfig['showConsoleLogs'])), ); } + cliux.success(messageHandler.parse('CLI_CONFIG_LOG_SET_SUCCESS')); } catch (error) { cliux.error('error', error); } diff --git a/packages/contentstack-config/src/utils/log-config-defaults.ts b/packages/contentstack-config/src/utils/log-config-defaults.ts index c882d3b7ce..2ef2f6e986 100644 --- a/packages/contentstack-config/src/utils/log-config-defaults.ts +++ b/packages/contentstack-config/src/utils/log-config-defaults.ts @@ -26,7 +26,7 @@ export function resolveLogPath(logPath: string): string { export function getEffectiveLogConfig(currentConfig: any = {}) { const logLevel = currentConfig?.level || LOG_CONFIG_DEFAULTS.LEVEL; const logPath = resolveLogPath(currentConfig?.path || LOG_CONFIG_DEFAULTS.PATH); - const showConsoleLogs = currentConfig?.['show-console-logs'] ?? LOG_CONFIG_DEFAULTS.SHOW_CONSOLE_LOGS; + const showConsoleLogs = currentConfig?.['showConsoleLogs'] ?? LOG_CONFIG_DEFAULTS.SHOW_CONSOLE_LOGS; return { level: logLevel, diff --git a/packages/contentstack-config/test/unit/commands/log.test.ts b/packages/contentstack-config/test/unit/commands/log.test.ts index fa3d825721..b8c22fc19b 100644 --- a/packages/contentstack-config/test/unit/commands/log.test.ts +++ b/packages/contentstack-config/test/unit/commands/log.test.ts @@ -31,7 +31,7 @@ describe('Log Commands', () => { const cmd = new LogSetCommand([], {} as any); const relativePath = './logs/app.log'; const expectedAbsolutePath = path.resolve(process.cwd(), './logs'); // Directory, not file - + sinon.stub(cmd as any, 'parse').resolves({ flags: { level: 'debug', @@ -49,7 +49,7 @@ describe('Log Commands', () => { setStub.calledWith('log', { level: 'debug', path: expectedAbsolutePath, // Should be directory path, not file path - 'show-console-logs': false, + showConsoleLogs: false, }), ).to.be.true; @@ -73,8 +73,9 @@ describe('Log Commands', () => { expect(setStub.called).to.be.true; expect(setStub.calledWith('log', { level: 'warn', path: './existing.log' })).to.be.true; - // Should not display any success messages when no flags are provided - expect(successMessage.length).to.equal(0); + // Should display the overall success message when no flags are provided + expect(successMessage.length).to.equal(1); + expect(successMessage.some((msg) => msg.includes('CLI_CONFIG_LOG_SET_SUCCESS'))).to.be.true; }); it('should call set even when no flags are provided and no existing config', async () => { @@ -92,23 +93,24 @@ describe('Log Commands', () => { expect(setStub.called).to.be.true; expect(setStub.calledWith('log', {})).to.be.true; - // Should not display any success messages when no flags are provided - expect(successMessage.length).to.equal(0); + // Should display the overall success message when no flags are provided + expect(successMessage.length).to.equal(1); + expect(successMessage.some((msg) => msg.includes('CLI_CONFIG_LOG_SET_SUCCESS'))).to.be.true; }); it('should preserve existing config values when only setting level', async () => { const cmd = new LogSetCommand([], {} as any); const existingPath = './existing/logs/app.log'; - + sinon.stub(cmd as any, 'parse').resolves({ flags: { level: 'warn', }, }); - sinon.stub(configHandler, 'get').returns({ + sinon.stub(configHandler, 'get').returns({ path: existingPath, - 'show-console-logs': true + 'show-console-logs': true, }); const setStub = sinon.stub(configHandler, 'set'); @@ -117,30 +119,31 @@ describe('Log Commands', () => { expect( setStub.calledWith('log', { level: 'warn', - path: existingPath, // Should preserve existing path unchanged - 'show-console-logs': true, // Should preserve existing console logs setting + path: existingPath, // Should preserve existing path unchanged + 'show-console-logs': true, // Should preserve existing console logs setting }), ).to.be.true; - expect(successMessage.some(msg => msg.includes('CLI_CONFIG_LOG_LEVEL_SET'))).to.be.true; - expect(successMessage.some(msg => msg.includes('CLI_CONFIG_LOG_PATH_SET'))).to.be.false; - expect(successMessage.some(msg => msg.includes('CLI_CONFIG_LOG_CONSOLE_SET'))).to.be.false; + expect(successMessage.some((msg) => msg.includes('CLI_CONFIG_LOG_LEVEL_SET'))).to.be.true; + expect(successMessage.some((msg) => msg.includes('CLI_CONFIG_LOG_PATH_SET'))).to.be.false; + expect(successMessage.some((msg) => msg.includes('CLI_CONFIG_LOG_CONSOLE_SET'))).to.be.false; + expect(successMessage.some((msg) => msg.includes('CLI_CONFIG_LOG_SET_SUCCESS'))).to.be.true; }); it('should preserve existing config values when only setting path', async () => { const cmd = new LogSetCommand([], {} as any); const newPath = './new/logs/app.log'; const expectedAbsolutePath = path.resolve(process.cwd(), './new/logs'); - + sinon.stub(cmd as any, 'parse').resolves({ flags: { path: newPath, }, }); - sinon.stub(configHandler, 'get').returns({ + sinon.stub(configHandler, 'get').returns({ level: 'error', - 'show-console-logs': false + 'show-console-logs': false, }); const setStub = sinon.stub(configHandler, 'set'); @@ -154,9 +157,10 @@ describe('Log Commands', () => { }), ).to.be.true; - expect(successMessage.some(msg => msg.includes('CLI_CONFIG_LOG_LEVEL_SET'))).to.be.false; - expect(successMessage.some(msg => msg.includes('CLI_CONFIG_LOG_PATH_SET'))).to.be.true; - expect(successMessage.some(msg => msg.includes('CLI_CONFIG_LOG_CONSOLE_SET'))).to.be.false; + expect(successMessage.some((msg) => msg.includes('CLI_CONFIG_LOG_LEVEL_SET'))).to.be.false; + expect(successMessage.some((msg) => msg.includes('CLI_CONFIG_LOG_PATH_SET'))).to.be.true; + expect(successMessage.some((msg) => msg.includes('CLI_CONFIG_LOG_CONSOLE_SET'))).to.be.false; + expect(successMessage.some((msg) => msg.includes('CLI_CONFIG_LOG_SET_SUCCESS'))).to.be.true; }); it('should set show-console-logs flag only when explicitly provided', async () => { @@ -172,15 +176,16 @@ describe('Log Commands', () => { expect( setStub.calledWith('log', { - level: 'debug', + level: 'debug', path: './existing.log', - 'show-console-logs': true, + showConsoleLogs: true, }), ).to.be.true; - expect(successMessage.some(msg => msg.includes('CLI_CONFIG_LOG_LEVEL_SET'))).to.be.false; - expect(successMessage.some(msg => msg.includes('CLI_CONFIG_LOG_PATH_SET'))).to.be.false; - expect(successMessage.some(msg => msg.includes('CLI_CONFIG_LOG_CONSOLE_SET'))).to.be.true; + expect(successMessage.some((msg) => msg.includes('CLI_CONFIG_LOG_LEVEL_SET'))).to.be.false; + expect(successMessage.some((msg) => msg.includes('CLI_CONFIG_LOG_PATH_SET'))).to.be.false; + expect(successMessage.some((msg) => msg.includes('CLI_CONFIG_LOG_CONSOLE_SET'))).to.be.true; + expect(successMessage.some((msg) => msg.includes('CLI_CONFIG_LOG_SET_SUCCESS'))).to.be.true; }); it('should set show-console-logs flag to false (--no-show-console-logs)', async () => { @@ -197,20 +202,21 @@ describe('Log Commands', () => { expect( setStub.calledWith('log', { level: 'info', - 'show-console-logs': false, + showConsoleLogs: false, }), ).to.be.true; - expect(successMessage.some(msg => msg.includes('CLI_CONFIG_LOG_LEVEL_SET'))).to.be.false; - expect(successMessage.some(msg => msg.includes('CLI_CONFIG_LOG_PATH_SET'))).to.be.false; - expect(successMessage.some(msg => msg.includes('CLI_CONFIG_LOG_CONSOLE_SET'))).to.be.true; + expect(successMessage.some((msg) => msg.includes('CLI_CONFIG_LOG_LEVEL_SET'))).to.be.false; + expect(successMessage.some((msg) => msg.includes('CLI_CONFIG_LOG_PATH_SET'))).to.be.false; + expect(successMessage.some((msg) => msg.includes('CLI_CONFIG_LOG_CONSOLE_SET'))).to.be.true; + expect(successMessage.some((msg) => msg.includes('CLI_CONFIG_LOG_SET_SUCCESS'))).to.be.true; }); it('should set all flags together (level, path, show-console-logs) with absolute path', async () => { const cmd = new LogSetCommand([], {} as any); const relativePath = './logs/warnings.log'; - const expectedAbsolutePath = path.resolve(process.cwd(), './logs'); - + const expectedAbsolutePath = path.resolve(process.cwd(), './logs'); + sinon.stub(cmd as any, 'parse').resolves({ flags: { level: 'warn', @@ -227,22 +233,23 @@ describe('Log Commands', () => { expect( setStub.calledWith('log', { level: 'warn', - path: expectedAbsolutePath, - 'show-console-logs': true, + path: expectedAbsolutePath, + showConsoleLogs: true, }), ).to.be.true; - expect(successMessage).to.have.length(3); + expect(successMessage).to.have.length(4); expect(successMessage.some((msg) => msg.includes('CLI_CONFIG_LOG_LEVEL_SET'))).to.be.true; expect(successMessage.some((msg) => msg.includes('CLI_CONFIG_LOG_PATH_SET'))).to.be.true; expect(successMessage.some((msg) => msg.includes('CLI_CONFIG_LOG_CONSOLE_SET'))).to.be.true; + expect(successMessage.some((msg) => msg.includes('CLI_CONFIG_LOG_SET_SUCCESS'))).to.be.true; }); it('should handle absolute paths correctly', async () => { const cmd = new LogSetCommand([], {} as any); const absolutePath = '/tmp/cli.log'; - const expectedDirectoryPath = '/tmp'; - + const expectedDirectoryPath = '/tmp'; + sinon.stub(cmd as any, 'parse').resolves({ flags: { path: absolutePath, @@ -258,7 +265,7 @@ describe('Log Commands', () => { expect( setStub.calledWith('log', { path: expectedDirectoryPath, - 'show-console-logs': false, + showConsoleLogs: false, }), ).to.be.true; }); @@ -299,28 +306,25 @@ describe('Log Commands', () => { const cmd = new LogGetCommand([], {} as any); const relativePath = './logs/app.log'; const expectedAbsolutePath = path.resolve(process.cwd(), relativePath); - + sinon.stub(configHandler, 'get').returns({ level: 'debug', path: relativePath }); await cmd.run(); expect(tableMessage).to.have.length(1); - expect(tableMessage[0].headers).to.deep.equal([ - { value: 'Setting' }, - { value: 'Value' } - ]); + expect(tableMessage[0].headers).to.deep.equal([{ value: 'Setting' }, { value: 'Value' }]); expect(tableMessage[0].data).to.deep.equal([ { - 'Setting': 'Log Level', - 'Value': 'debug' + Setting: 'Log Level', + Value: 'debug', }, { - 'Setting': 'Log Path', - 'Value': expectedAbsolutePath + Setting: 'Log Path', + Value: expectedAbsolutePath, }, { - 'Setting': 'Show Console Logs', - 'Value': 'false' + Setting: 'Show Console Logs', + Value: 'false', }, ]); }); @@ -332,22 +336,19 @@ describe('Log Commands', () => { await cmd.run(); expect(tableMessage).to.have.length(1); - expect(tableMessage[0].headers).to.deep.equal([ - { value: 'Setting' }, - { value: 'Value' } - ]); + expect(tableMessage[0].headers).to.deep.equal([{ value: 'Setting' }, { value: 'Value' }]); expect(tableMessage[0].data).to.deep.equal([ { - 'Setting': 'Log Level', - 'Value': 'info' + Setting: 'Log Level', + Value: 'info', }, { - 'Setting': 'Log Path', - 'Value': LOG_CONFIG_DEFAULTS.PATH + Setting: 'Log Path', + Value: LOG_CONFIG_DEFAULTS.PATH, }, { - 'Setting': 'Show Console Logs', - 'Value': 'false' + Setting: 'Show Console Logs', + Value: 'false', }, ]); }); @@ -356,28 +357,25 @@ describe('Log Commands', () => { const cmd = new LogGetCommand([], {} as any); const customPath = './custom/logs/app.log'; const expectedAbsolutePath = path.resolve(process.cwd(), customPath); - + sinon.stub(configHandler, 'get').returns({ path: customPath }); await cmd.run(); expect(tableMessage).to.have.length(1); - expect(tableMessage[0].headers).to.deep.equal([ - { value: 'Setting' }, - { value: 'Value' } - ]); + expect(tableMessage[0].headers).to.deep.equal([{ value: 'Setting' }, { value: 'Value' }]); expect(tableMessage[0].data).to.deep.equal([ { - 'Setting': 'Log Level', - 'Value': LOG_CONFIG_DEFAULTS.LEVEL + Setting: 'Log Level', + Value: LOG_CONFIG_DEFAULTS.LEVEL, }, { - 'Setting': 'Log Path', - 'Value': expectedAbsolutePath + Setting: 'Log Path', + Value: expectedAbsolutePath, }, { - 'Setting': 'Show Console Logs', - 'Value': 'false' + Setting: 'Show Console Logs', + Value: 'false', }, ]); }); @@ -391,26 +389,26 @@ describe('Log Commands', () => { expect(tableMessage).to.have.length(1); expect(tableMessage[0].data).to.deep.equal([ { - 'Setting': 'Log Level', - 'Value': LOG_CONFIG_DEFAULTS.LEVEL + Setting: 'Log Level', + Value: LOG_CONFIG_DEFAULTS.LEVEL, }, { - 'Setting': 'Log Path', - 'Value': LOG_CONFIG_DEFAULTS.PATH + Setting: 'Log Path', + Value: LOG_CONFIG_DEFAULTS.PATH, }, { - 'Setting': 'Show Console Logs', - 'Value': 'false' + Setting: 'Show Console Logs', + Value: 'false', }, ]); }); it('should display configured console logs setting', async () => { const cmd = new LogGetCommand([], {} as any); - sinon.stub(configHandler, 'get').returns({ - level: 'debug', + sinon.stub(configHandler, 'get').returns({ + level: 'debug', path: '/tmp/cli.log', - 'show-console-logs': true + showConsoleLogs: true, }); await cmd.run(); @@ -418,16 +416,16 @@ describe('Log Commands', () => { expect(tableMessage).to.have.length(1); expect(tableMessage[0].data).to.deep.equal([ { - 'Setting': 'Log Level', - 'Value': 'debug' + Setting: 'Log Level', + Value: 'debug', }, { - 'Setting': 'Log Path', - 'Value': '/tmp/cli.log' + Setting: 'Log Path', + Value: '/tmp/cli.log', }, { - 'Setting': 'Show Console Logs', - 'Value': 'true' + Setting: 'Show Console Logs', + Value: 'true', }, ]); }); @@ -465,14 +463,14 @@ describe('Log Commands', () => { it('should use existing config values when available and no flags provided', async () => { const cmd = new LogSetCommand([], {} as any); const existingPath = '/existing/path/cli.log'; - + sinon.stub(cmd as any, 'parse').resolves({ flags: { 'show-console-logs': false }, }); - sinon.stub(configHandler, 'get').returns({ - level: 'warn', - path: existingPath + sinon.stub(configHandler, 'get').returns({ + level: 'warn', + path: existingPath, }); const setStub = sinon.stub(configHandler, 'set'); @@ -480,9 +478,9 @@ describe('Log Commands', () => { expect( setStub.calledWith('log', { - level: 'warn', - path: existingPath, - 'show-console-logs': false, + level: 'warn', + path: existingPath, + showConsoleLogs: false, }), ).to.be.true; }); @@ -490,17 +488,17 @@ describe('Log Commands', () => { it('should mix existing config with new flag values', async () => { const cmd = new LogSetCommand([], {} as any); const newPath = './new-logs/cli.log'; - const expectedAbsolutePath = path.resolve(process.cwd(), './new-logs'); - + const expectedAbsolutePath = path.resolve(process.cwd(), './new-logs'); + sinon.stub(cmd as any, 'parse').resolves({ - flags: { + flags: { path: newPath, - 'show-console-logs': true + 'show-console-logs': true, }, }); - sinon.stub(configHandler, 'get').returns({ - level: 'error' + sinon.stub(configHandler, 'get').returns({ + level: 'error', }); const setStub = sinon.stub(configHandler, 'set'); @@ -508,9 +506,9 @@ describe('Log Commands', () => { expect( setStub.calledWith('log', { - level: 'error', - path: expectedAbsolutePath, - 'show-console-logs': true, + level: 'error', + path: expectedAbsolutePath, + showConsoleLogs: true, }), ).to.be.true; }); @@ -519,12 +517,12 @@ describe('Log Commands', () => { const cmd = new LogSetCommand([], {} as any); const windowsPath = 'C:\\logs\\cli.log'; const resolvedPath = path.resolve(process.cwd(), windowsPath); - const expectedPath = path.dirname(resolvedPath); - + const expectedPath = path.dirname(resolvedPath); + sinon.stub(cmd as any, 'parse').resolves({ - flags: { + flags: { path: windowsPath, - 'show-console-logs': false + 'show-console-logs': false, }, }); @@ -535,33 +533,34 @@ describe('Log Commands', () => { expect( setStub.calledWith('log', { - level: 'debug', - path: expectedPath, - 'show-console-logs': false, + level: 'debug', + path: expectedPath, + showConsoleLogs: false, }), ).to.be.true; - expect(successMessage.some(msg => msg.includes('CLI_CONFIG_LOG_LEVEL_SET'))).to.be.false; - expect(successMessage.some(msg => msg.includes('CLI_CONFIG_LOG_PATH_SET'))).to.be.true; - expect(successMessage.some(msg => msg.includes('CLI_CONFIG_LOG_CONSOLE_SET'))).to.be.true; + expect(successMessage.some((msg) => msg.includes('CLI_CONFIG_LOG_LEVEL_SET'))).to.be.false; + expect(successMessage.some((msg) => msg.includes('CLI_CONFIG_LOG_PATH_SET'))).to.be.true; + expect(successMessage.some((msg) => msg.includes('CLI_CONFIG_LOG_CONSOLE_SET'))).to.be.true; + expect(successMessage.some((msg) => msg.includes('CLI_CONFIG_LOG_SET_SUCCESS'))).to.be.true; }); it('should override existing values when flags are provided with file-to-directory conversion', async () => { const cmd = new LogSetCommand([], {} as any); const newPath = './override/logs/cli.log'; const expectedAbsolutePath = path.resolve(process.cwd(), './override/logs'); // Directory, not file - + sinon.stub(cmd as any, 'parse').resolves({ - flags: { + flags: { level: 'error', path: newPath, - 'show-console-logs': true + 'show-console-logs': true, }, }); - sinon.stub(configHandler, 'get').returns({ - level: 'debug', + sinon.stub(configHandler, 'get').returns({ + level: 'debug', path: './old/path.log', - 'show-console-logs': false + showConsoleLogs: false, }); const setStub = sinon.stub(configHandler, 'set'); @@ -569,25 +568,26 @@ describe('Log Commands', () => { expect( setStub.calledWith('log', { - level: 'error', + level: 'error', path: expectedAbsolutePath, - 'show-console-logs': true, + showConsoleLogs: true, }), ).to.be.true; - expect(successMessage.some(msg => msg.includes('CLI_CONFIG_LOG_LEVEL_SET'))).to.be.true; - expect(successMessage.some(msg => msg.includes('CLI_CONFIG_LOG_PATH_SET'))).to.be.true; - expect(successMessage.some(msg => msg.includes('CLI_CONFIG_LOG_CONSOLE_SET'))).to.be.true; + expect(successMessage.some((msg) => msg.includes('CLI_CONFIG_LOG_LEVEL_SET'))).to.be.true; + expect(successMessage.some((msg) => msg.includes('CLI_CONFIG_LOG_PATH_SET'))).to.be.true; + expect(successMessage.some((msg) => msg.includes('CLI_CONFIG_LOG_CONSOLE_SET'))).to.be.true; + expect(successMessage.some((msg) => msg.includes('CLI_CONFIG_LOG_SET_SUCCESS'))).to.be.true; }); it('should convert file paths to directory paths automatically', async () => { const cmd = new LogSetCommand([], {} as any); const filePath = './custom/logs/debug.log'; const expectedDirectoryPath = path.resolve(process.cwd(), './custom/logs'); - + sinon.stub(cmd as any, 'parse').resolves({ - flags: { - path: filePath + flags: { + path: filePath, }, }); @@ -602,17 +602,18 @@ describe('Log Commands', () => { }), ).to.be.true; - expect(successMessage.some(msg => msg.includes('CLI_CONFIG_LOG_PATH_SET'))).to.be.true; + expect(successMessage.some((msg) => msg.includes('CLI_CONFIG_LOG_PATH_SET'))).to.be.true; + expect(successMessage.some((msg) => msg.includes('CLI_CONFIG_LOG_SET_SUCCESS'))).to.be.true; }); it('should keep directory paths unchanged', async () => { const cmd = new LogSetCommand([], {} as any); const directoryPath = './custom/logs'; const expectedDirectoryPath = path.resolve(process.cwd(), directoryPath); - + sinon.stub(cmd as any, 'parse').resolves({ - flags: { - path: directoryPath + flags: { + path: directoryPath, }, }); @@ -623,12 +624,13 @@ describe('Log Commands', () => { expect( setStub.calledWith('log', { - path: expectedDirectoryPath, + path: expectedDirectoryPath, }), ).to.be.true; // Should show success message for path only - expect(successMessage.some(msg => msg.includes('CLI_CONFIG_LOG_PATH_SET'))).to.be.true; + expect(successMessage.some((msg) => msg.includes('CLI_CONFIG_LOG_PATH_SET'))).to.be.true; + expect(successMessage.some((msg) => msg.includes('CLI_CONFIG_LOG_SET_SUCCESS'))).to.be.true; }); }); }); diff --git a/packages/contentstack-export/README.md b/packages/contentstack-export/README.md index 8937d7f952..e247839a90 100755 --- a/packages/contentstack-export/README.md +++ b/packages/contentstack-export/README.md @@ -48,7 +48,7 @@ $ npm install -g @contentstack/cli-cm-export $ csdx COMMAND running command... $ csdx (--version) -@contentstack/cli-cm-export/1.20.1 darwin-arm64 node-v22.13.0 +@contentstack/cli-cm-export/2.0.0-beta darwin-arm64 node-v22.14.0 $ csdx --help [COMMAND] USAGE $ csdx COMMAND diff --git a/packages/contentstack-export/messages/index.json b/packages/contentstack-export/messages/index.json index b2bb7eb664..16fda7957d 100644 --- a/packages/contentstack-export/messages/index.json +++ b/packages/contentstack-export/messages/index.json @@ -1,6 +1,6 @@ { "ASSET_EXPORT_COMPLETE": "Asset export process completed successfully", -"ASSET_FOLDERS_EXPORT_COMPLETE": "Asset folder structure exported successfully", +"ASSET_FOLDERS_EXPORT_COMPLETE": "Asset folder structure exported successfully with %s folder(s)", "ASSET_METADATA_EXPORT_COMPLETE": "Asset metadata exported successfully", "ASSET_VERSIONED_METADATA_EXPORT_COMPLETE": "Versioned asset metadata exported successfully", "ASSET_DOWNLOAD_COMPLETE": "Asset download completed successfully", @@ -65,5 +65,7 @@ "BRANCH_EXPORT_FAILED": "Failed to export contents from branch (UID: %s)", "ROLES_NO_CUSTOM_ROLES": "No custom roles found in the current stack", -"ROLES_EXPORTING_ROLE": "Exporting role '%s'" +"ROLES_EXPORTING_ROLE": "Exporting role '%s'", + +"GLOBAL_FIELDS_NOT_FOUND": "No global fields found in the current stack" } diff --git a/packages/contentstack-export/package.json b/packages/contentstack-export/package.json index ea4a156563..585a953d7f 100644 --- a/packages/contentstack-export/package.json +++ b/packages/contentstack-export/package.json @@ -1,12 +1,12 @@ { "name": "@contentstack/cli-cm-export", "description": "Contentstack CLI plugin to export content from stack", - "version": "1.20.2", + "version": "2.0.0-beta", "author": "Contentstack", "bugs": "https://github.com/contentstack/cli/issues", "dependencies": { "@contentstack/cli-command": "~1.6.1", - "@contentstack/cli-variants": "~1.3.3", + "@contentstack/cli-variants": "~2.0.0-beta", "@oclif/core": "^4.3.3", "@contentstack/cli-utilities": "~1.14.1", "async": "^3.2.6", diff --git a/packages/contentstack-export/src/commands/cm/stacks/export.ts b/packages/contentstack-export/src/commands/cm/stacks/export.ts index 9a1539ad16..5304f4d059 100644 --- a/packages/contentstack-export/src/commands/cm/stacks/export.ts +++ b/packages/contentstack-export/src/commands/cm/stacks/export.ts @@ -13,11 +13,13 @@ import { log, handleAndLogError, getLogPath, + CLIProgressManager, + clearProgressModuleSetting, } from '@contentstack/cli-utilities'; import { ModuleExporter } from '../../../export'; import { Context, ExportConfig } from '../../../types'; -import { setupExportConfig, writeExportMetaFile } from '../../../utils'; +import { setupExportConfig } from '../../../utils'; export default class ExportCommand extends Command { static description: string = messageHandler.parse('Export content from a stack'); @@ -132,18 +134,28 @@ export default class ExportCommand extends Command { const managementAPIClient: ContentstackClient = await managementSDKClient(exportConfig); const moduleExporter = new ModuleExporter(managementAPIClient, exportConfig); await moduleExporter.start(); - if (!exportConfig.branches?.length) { - writeExportMetaFile(exportConfig); - } log.success( `The content of the stack ${exportConfig.apiKey} has been exported successfully!`, exportConfig.context, ); log.info(`The exported content has been stored at '${exportDir}'`, exportConfig.context); log.success(`The log has been stored at '${getLogPath()}'`, exportConfig.context); + + // Print comprehensive summary at the end + if (!exportConfig.branches) CLIProgressManager.printGlobalSummary(); + if (!configHandler.get('log')?.showConsoleLogs) { + cliux.print(`The log has been stored at '${getLogPath()}'`, { color: 'green' }); + } + // Clear progress module setting now that export is complete + clearProgressModuleSetting(); } catch (error) { + // Clear progress module setting even on error + clearProgressModuleSetting(); handleAndLogError(error); - log.info(`The log has been stored at '${getLogPath()}'`); + if (!configHandler.get('log')?.showConsoleLogs) { + cliux.print(`Error: ${error}`, { color: 'red' }); + cliux.print(`The log has been stored at '${getLogPath()}'`, { color: 'green' }); + } } } @@ -153,7 +165,6 @@ export default class ExportCommand extends Command { command: this.context?.info?.command || 'cm:stacks:export', module: '', userId: configHandler.get('userUid') || '', - email: configHandler.get('email') || '', sessionId: this.context?.sessionId || '', apiKey: apiKey || '', orgId: configHandler.get('oauthOrgUid') || '', diff --git a/packages/contentstack-export/src/config/index.ts b/packages/contentstack-export/src/config/index.ts index 6823e2a534..dee5213920 100644 --- a/packages/contentstack-export/src/config/index.ts +++ b/packages/contentstack-export/src/config/index.ts @@ -1,7 +1,6 @@ import { DefaultConfig } from '../types'; const config: DefaultConfig = { - contentVersion: 2, versioning: false, host: 'https://api.contentstack.io/v3', developerHubUrls: { @@ -489,7 +488,6 @@ const config: DefaultConfig = { writeConcurrency: 5, developerHubBaseUrl: '', marketplaceAppEncryptionKey: 'nF2ejRQcTv', - onlyTSModules: ['taxonomies'], }; export default config; diff --git a/packages/contentstack-export/src/export/module-exporter.ts b/packages/contentstack-export/src/export/module-exporter.ts index dcf39ba515..90bc73f854 100644 --- a/packages/contentstack-export/src/export/module-exporter.ts +++ b/packages/contentstack-export/src/export/module-exporter.ts @@ -5,11 +5,11 @@ import { messageHandler, log, getBranchFromAlias, + CLIProgressManager, } from '@contentstack/cli-utilities'; -import { setupBranches, setupExportDir, writeExportMetaFile } from '../utils'; import startModuleExport from './modules'; -import startJSModuleExport from './modules-js'; import { ExportConfig, Modules } from '../types'; +import { setupBranches, setupExportDir } from '../utils'; class ModuleExporter { private managementAPIClient: ContentstackClient; @@ -38,6 +38,8 @@ class ModuleExporter { this.exportConfig.branchEnabled = true; return this.exportByBranches(); } + // If branches disabled then initialize the global summary + CLIProgressManager.initializeGlobalSummary('EXPORT', this.exportConfig.branchName, 'Exporting content...'); return this.export(); } catch (error) { throw error; @@ -45,29 +47,55 @@ class ModuleExporter { } async exportByBranches(): Promise { - // loop through the branches and export it parallel - for (const branch of this.exportConfig.branches) { - try { - this.exportConfig.branchName = branch.uid; - this.stackAPIClient.stackHeaders.branch = branch.uid; - this.exportConfig.branchDir = path.join(this.exportConfig.exportDir, branch.uid); - log.info(`Exporting content from branch ${branch.uid}`, this.exportConfig.context); - writeExportMetaFile(this.exportConfig, this.exportConfig.branchDir); - await this.export(); - log.success(`The content of branch ${branch.uid} has been exported successfully!`, this.exportConfig.context); - } catch (error) { - handleAndLogError( - error, - { ...this.exportConfig.context, branch: branch.uid }, - messageHandler.parse('FAILED_EXPORT_CONTENT_BRANCH', { branch: branch.uid }), - ); - throw new Error(messageHandler.parse('FAILED_EXPORT_CONTENT_BRANCH', { branch: branch.uid })); + let targetBranch; + + if (this.exportConfig.branchName) { + // User specified a branch - export only that branch + targetBranch = this.exportConfig.branches.find((branch) => branch.uid === this.exportConfig.branchName); + if (!targetBranch) { + throw new Error(`Branch '${this.exportConfig.branchName}' not found in available branches`); + } + } else { + // No specific branch mentioned - export only the main branch + targetBranch = this.exportConfig.branches.find((branch) => branch.uid === 'main'); + if (!targetBranch) { + throw new Error('No main branch or available branches found'); } } + + try { + this.exportConfig.branchName = targetBranch.uid; + this.stackAPIClient.stackHeaders.branch = targetBranch.uid; + this.exportConfig.branchDir = path.join(this.exportConfig.exportDir, targetBranch.uid); + + // Initialize progress manager for the target branch + CLIProgressManager.clearGlobalSummary(); + CLIProgressManager.initializeGlobalSummary( + `EXPORT-${targetBranch.uid}`, + targetBranch.uid, + `Exporting "${targetBranch.uid}" branch content...`, + ); + + log.info(`Exporting content from '${targetBranch.uid}' branch`, this.exportConfig.context); + await this.export(); + CLIProgressManager.printGlobalSummary(); + + log.success( + `The content of branch ${targetBranch.uid} has been exported successfully!`, + this.exportConfig.context, + ); + } catch (error) { + handleAndLogError( + error, + { ...this.exportConfig.context, branch: targetBranch?.uid }, + messageHandler.parse('FAILED_EXPORT_CONTENT_BRANCH', { branch: targetBranch?.uid }), + ); + throw new Error(messageHandler.parse('FAILED_EXPORT_CONTENT_BRANCH', { branch: targetBranch?.uid })); + } } async export() { - log.info(`Started to export content, version is ${this.exportConfig.contentVersion}`, this.exportConfig.context); + log.info(`Started to export content`, this.exportConfig.context); // checks for single module or all modules if (this.exportConfig.singleModuleExport) { return this.exportSingleModule(this.exportConfig.moduleName); @@ -79,28 +107,11 @@ class ModuleExporter { log.info(`Exporting module: ${moduleName}`, this.exportConfig.context); // export the modules by name // calls the module runner which inturn calls the module itself - let exportedModuleResponse; - if (this.exportConfig.contentVersion === 2) { - exportedModuleResponse = await startModuleExport({ - stackAPIClient: this.stackAPIClient, - exportConfig: this.exportConfig, - moduleName, - }); - } else { - //NOTE - new modules support only ts - if (this.exportConfig.onlyTSModules.indexOf(moduleName) === -1) { - exportedModuleResponse = await startJSModuleExport({ - stackAPIClient: this.stackAPIClient, - exportConfig: this.exportConfig, - moduleName, - }); - } - } - - // set master locale to config - if (moduleName === 'stack' && exportedModuleResponse?.code) { - this.exportConfig.master_locale = { code: exportedModuleResponse.code }; - } + await startModuleExport({ + stackAPIClient: this.stackAPIClient, + exportConfig: this.exportConfig, + moduleName, + }); } async exportSingleModule(moduleName: Modules): Promise { diff --git a/packages/contentstack-export/src/export/modules-js/assets.js b/packages/contentstack-export/src/export/modules-js/assets.js deleted file mode 100644 index 798e6320fd..0000000000 --- a/packages/contentstack-export/src/export/modules-js/assets.js +++ /dev/null @@ -1,445 +0,0 @@ -/*! - * Contentstack Export - * Copyright (c) 2024 Contentstack LLC - * MIT Licensed - */ - -const mkdirp = require('mkdirp'); -const path = require('path'); -const fs = require('fs'); -const Promise = require('bluebird'); -const _ = require('lodash'); -const chalk = require('chalk'); -const progress = require('progress-stream'); -const { HttpClient, configHandler, validateUids, sanitizePath, validateFileName } = require('@contentstack/cli-utilities'); -const { fileHelper, log, formatError } = require('../../utils'); -let { default: config } = require('../../config'); - -module.exports = class ExportAssets { - config; - bLimit; - vLimit; - invalidKeys; - folderJSONPath; - folderData = []; - assetsFolderPath; - assetContents = {}; - httpClient = HttpClient.create(); - assetConfig = config.modules.assets; - - constructor(exportConfig, stackAPIClient) { - this.stackAPIClient = stackAPIClient; - this.config = _.merge(config, exportConfig); - this.folderData = []; - this.assetContents = {}; - this.assetDownloadRetry = {}; - this.assetDownloadRetryLimit = 3; - this.invalidKeys = this.assetConfig.invalidKeys; - this.bLimit = this.assetConfig.batchLimit || 15; - this.vLimit = this.assetConfig.downloadLimit || this.config.fetchConcurrency || 3; - } - - start() { - const self = this; - this.assetsFolderPath = path.resolve(this.config.data, this.config.branchName || '', this.assetConfig.dirName); - this.assetContentsFile = path.resolve(this.assetsFolderPath, 'assets.json'); - this.folderJSONPath = path.resolve(this.assetsFolderPath, 'folders.json'); - - log(this.config, 'Starting assets export', 'success'); - - // Create asset folder - mkdirp.sync(this.assetsFolderPath); - - return new Promise((resolve, reject) => { - // TBD: getting all the assets should have optimized - return self - .getAssetCount() - .then((count) => { - const assetBatches = []; - - if (typeof count !== 'number' || count === 0) { - log(self.config, 'No assets found', 'success'); - return resolve(); - } - for (let i = 0; i <= count; i += self.bLimit) { - assetBatches.push(i); - } - - return Promise.map( - assetBatches, - (batch) => { - return self - .getAssetJSON(batch) - .then((assetsJSON) => { - return Promise.map( - assetsJSON, - (assetJSON) => { - if (self.assetConfig.downloadVersionAssets) { - return self - .getVersionedAssetJSON(assetJSON.uid, assetJSON._version) - .then(() => { - self.assetContents[assetJSON.uid] = assetJSON; - }) - .catch((error) => { - log( - self.config, - `Asset '${assetJSON.uid}' failed to download.\n ${formatError(error)}`, - 'error', - ); - log(self.config, error, 'error'); - }); - } else { - return self - .downloadAsset(assetJSON) - .then(() => { - self.assetContents[assetJSON.uid] = assetJSON; - }) - .catch((err) => { - log(self.config, `Asset '${assetJSON.uid}' download failed. ${formatError(err)}`, 'error'); - return err; - }); - } - }, - { concurrency: self.vLimit }, - ) - .then(() => { - log(self.config, 'Batch no ' + (batch + 1) + ' of assets is complete', 'success'); - // fileHelper.writeFileSync(this.assetContentsFile, self.assetContents) - }) - .catch((error) => { - log(self.config, `Asset batch ${batch + 1} failed to download`, 'error'); - log(self.config, formatError(error), 'error'); - log(self.config, error, 'error'); - }); - }) - .catch((error) => { - log(self.config, error, 'error'); - reject(error); - }); - }, - { concurrency: self.assetConfig.concurrencyLimit || 1 }, - ) - .then(() => { - fileHelper.writeFileSync(self.assetContentsFile, self.assetContents); - - return self - .exportFolders() - .then(() => { - log(self.config, chalk.green('Asset export completed successfully'), 'success'); - return resolve(); - }) - .catch((error) => { - log(self.config, error, 'error'); - reject(error); - }); - }) - .catch((error) => { - fileHelper.writeFileSync(self.assetContentsFile, self.assetContents); - log(self.config, `Asset export failed. ${formatError(error)}`, 'error'); - log(self.config, error, 'error'); - reject(error); - }); - }) - .catch((error) => { - log(self.config, error, 'error'); - reject(error); - }); - }); - } - - exportFolders() { - const self = this; - return new Promise((resolve, reject) => { - return self - .getAssetCount(true) - .then((fCount) => { - if (fCount === 0) { - log(self.config, 'No folders were found in the stack!', 'success'); - return resolve(); - } - - return self - .getFolderJSON(0, fCount) - .then(() => { - // asset folders have been successfully exported - log(self.config, 'Asset-folders have been successfully exported!', 'success'); - return resolve(); - }) - .catch((error) => { - log(self.config, `Error while exporting asset-folders!\n ${formatError(error)}`, 'error'); - return reject(error); - }); - }) - .catch((error) => { - log(self.config, error, 'error'); - // error while fetching asset folder count - return reject(error); - }); - }); - } - - getFolderJSON(skip, fCount) { - const self = this; - return new Promise((resolve, reject) => { - if (typeof skip !== 'number') { - skip = 0; - } - - if (skip >= fCount) { - fileHelper.writeFileSync(self.folderJSONPath, self.folderData); - return resolve(); - } - - const queryRequestObj = { - skip, - include_folders: true, - query: { is_dir: true }, - }; - - self.stackAPIClient - .asset() - .query(queryRequestObj) - .find() - .then((response) => { - skip += 100; - self.folderData.push(...response.items); - return self.getFolderJSON(skip, fCount).then(resolve).catch(reject); - }) - .catch((error) => reject(error)); - }); - } - - getAssetCount(folder) { - const self = this; - return new Promise((resolve, reject) => { - if (folder && typeof folder === 'boolean') { - const queryOptions = { - skip: 99999990, - include_count: true, - include_folders: true, - query: { is_dir: true }, - }; - self.stackAPIClient - .asset() - .query(queryOptions) - .find() - .then((asset) => { - return resolve(asset.count); - }) - .catch((error) => { - log(self.config, error, 'error'); - }); - } else { - const queryOptions = { skip: 99999990, include_count: true }; - self.stackAPIClient - .asset() - .query(queryOptions) - .find() - .then(({ count }) => resolve(count)) - .catch((error) => { - log(self.config, error, 'error'); - reject(error); - }); - } - }); - } - - getAssetJSON(skip) { - const self = this; - return new Promise((resolve, reject) => { - if (typeof skip !== 'number') { - skip = 0; - } - const queryRequestObj = { - skip: skip, - limit: self.bLimit, - include_publish_details: true, - except: { - BASE: self.invalidKeys, - }, - }; - - self.stackAPIClient - .asset() - .query(queryRequestObj) - .find() - .then(({ items }) => resolve(items)) - .catch((error) => { - log(self.config, error, 'error'); - return reject(); - }); - }); - } - - getVersionedAssetJSON(uid, version, bucket) { - const self = this; - const assetVersionInfo = bucket || []; - - return new Promise((resolve, reject) => { - if (self.assetDownloadRetry[uid + version] > self.assetDownloadRetryLimit) { - console.log('Reached max', self.assetDownloadRetry[uid + version]); - return reject(new Error('Asset Max download retry limit exceeded! ' + uid)); - } - - if (version <= 0) { - if(validateUids(uid)){ - const assetVersionInfoFile = path.resolve(sanitizePath(self.assetsFolderPath), sanitizePath(uid), '_contentstack_' + sanitizePath(uid) + '.json'); - fileHelper.writeFileSync(assetVersionInfoFile, assetVersionInfo); - return resolve(); - } - } - const queryrequestOption = { - version: version, - include_publish_details: true, - except: { - BASE: self.invalidKeys, - }, - }; - - self.stackAPIClient - .asset(uid) - .fetch(queryrequestOption) - .then((versionedAssetJSONResponse) => { - self - .downloadAsset(versionedAssetJSONResponse) - .then(() => { - assetVersionInfo.splice(0, 0, versionedAssetJSONResponse); - // Remove duplicates - assetVersionInfo = _.uniqWith(assetVersionInfo, _.isEqual); - self.getVersionedAssetJSON(uid, --version, assetVersionInfo).then(resolve).catch(reject); - }) - .catch(reject); - }) - .catch((error) => { - log(self.config, error, 'error'); - - if (error.status === 408) { - console.log('retrying', uid); - // retrying when timeout - self.assetDownloadRetry[uid + version] - ? ++self.assetDownloadRetry[uid + version] - : (self.assetDownloadRetry[uid + version] = 1); - return self.getVersionedAssetJSON(uid, version, assetVersionInfo).then(resolve).catch(reject); - } - reject(error); - }); - }); - } - - downloadAsset(asset) { - const self = this; - return new Promise(async (resolve, reject) => { - if(!validateUids(asset.uid) && !validateFileName(asset.filename)) { - reject(`UIDs not valid`) - } - const assetFolderPath = path.resolve(sanitizePath(self.assetsFolderPath), sanitizePath(asset.uid)); - const assetFilePath = path.resolve(sanitizePath(assetFolderPath), sanitizePath(asset.filename)); - - if (fs.existsSync(assetFilePath)) { - log( - self.config, - 'Skipping download of { title: ' + asset.filename + ', uid: ' + asset.uid + ' }, as they already exist', - 'success', - ); - return resolve(); - } - self.assetStream = { - url: self.config.securedAssets ? `${asset.url}?authtoken=${configHandler.get('authtoken')}` : asset.url, - }; - - fileHelper.makeDirectory(assetFolderPath); - const assetFileStream = fs.createWriteStream(assetFilePath); - self.assetStream.url = encodeURI(self.assetStream.url); - self.httpClient - .options({ responseType: 'stream' }) - .get(self.assetStream.url) - .then(({ data: assetStreamRequest }) => { - if (self.assetConfig.enableDownloadStatus) { - const str = progress({ - time: 5000, - length: assetStreamRequest.headers['content-length'], - }); - str.on('progress', (progressData) => { - console.log(`${asset.filename}: ${Math.round(progressData.percentage)}%`); - }); - assetStreamRequest.pipe(str).pipe(assetFileStream); - } - assetStreamRequest.pipe(assetFileStream); - }) - .catch((error) => { - log(self.config, error, 'error'); - reject(error); - }); - assetFileStream - .on('close', function () { - log(self.config, 'Downloaded ' + asset.filename + ': ' + asset.uid + ' successfully!', 'success'); - return resolve(); - }) - .on('error', (error) => { - log(self.config, `Download ${asset.filename}: ${asset.uid} failed!`, 'error'); - log(self.config, error, 'error'); - reject(error); - }); - }); - } - - getFolders() { - const self = this; - return new Promise((resolve, reject) => { - return self - .getAssetCount(true) - .then((count) => { - if (count === 0) { - log(self.config, 'No folders were found in the stack', 'success'); - return resolve(); - } - return self - .getFolderDetails(0, count) - .then(function () { - log(self.config, chalk.green('Exported asset-folders successfully!'), 'success'); - return resolve(); - }) - .catch(function (error) { - log(self.config, error, 'error'); - reject(error); - }); - }) - .catch(function (error) { - log(self.config, error, 'error'); - reject(error); - }); - }); - } - - getFolderDetails(skip, tCount) { - const self = this; - return new Promise((resolve, reject) => { - if (typeof skip !== 'number') { - skip = 0; - } - if (skip > tCount) { - fileHelper.writeFileSync(self.folderJSONPath, self.folderContents); - return resolve(); - } - const queryRequestObj = { - skip: skip, - include_folders: true, - query: { is_dir: true }, - }; - self.stackAPIClient - .asset() - .query(queryRequestObj) - .find() - .then((folderDetailsResponse) => { - for (let i in folderDetailsResponse.items) { - self.folderContents.push(folderDetailsResponse.items[i]); - } - skip += 100; - return self.getFolderDetails(skip, tCount).then(resolve).catch(reject); - }) - .catch((error) => { - log(self.config, error, 'error'); - }); - }); - } -}; diff --git a/packages/contentstack-export/src/export/modules-js/content-types.js b/packages/contentstack-export/src/export/modules-js/content-types.js deleted file mode 100644 index d5dcde84ee..0000000000 --- a/packages/contentstack-export/src/export/modules-js/content-types.js +++ /dev/null @@ -1,89 +0,0 @@ -const path = require('path'); -const chalk = require('chalk'); -const { fileHelper, executeTask, formatError, log } = require('../../utils'); -const { sanitizePath } = require('@contentstack/cli-utilities'); - -class ContentTypesExport { - constructor(exportConfig, stackAPIClient) { - this.stackAPIClient = stackAPIClient; - this.exportConfig = exportConfig; - this.contentTypesConfig = exportConfig.modules.content_types; - this.qs = { - include_count: true, - asc: 'updated_at', - limit: this.contentTypesConfig.limit, - include_global_field_schema: true, - }; - // If content type id is provided then use it as part of query - if (Array.isArray(this.exportConfig.contentTypes) && this.exportConfig.contentTypes.length > 0) { - this.qs.uid = { $in: this.exportConfig.contentTypes }; - } - this.contentTypesPath = path.resolve( - sanitizePath(exportConfig.data), - sanitizePath(exportConfig.branchName) || '', - sanitizePath(this.contentTypesConfig.dirName), - ); - this.contentTypes = []; - this.fetchConcurrency = this.contentTypesConfig.fetchConcurrency || this.exportConfig.fetchConcurrency; - this.writeConcurrency = this.contentTypesConfig.writeConcurrency || this.exportConfig.writeConcurrency; - } - - async start() { - try { - log(this.exportConfig, 'Starting content type export', 'success'); - await fileHelper.makeDirectory(this.contentTypesPath); - await this.getContentTypes(); - await this.writeContentTypes(this.contentTypes); - log(this.exportConfig, chalk.green('Content type(s) exported successfully'), 'success'); - } catch (error) { - log(this.exportConfig, `Failed to export content types ${formatError(error)}`, 'error'); - throw new Error('Failed to export content types'); - } - } - - async getContentTypes(skip = 0) { - if (skip) { - this.qs.skip = skip; - } - - const contentTypeSearchResponse = await this.stackAPIClient.contentType().query(this.qs).find(); - if (Array.isArray(contentTypeSearchResponse.items) && contentTypeSearchResponse.items.length > 0) { - let updatedContentTypes = this.sanitizeAttribs(contentTypeSearchResponse.items); - this.contentTypes.push(...updatedContentTypes); - - skip += this.contentTypesConfig.limit; - if (skip > contentTypeSearchResponse.count) { - return; - } - return await this.getContentTypes(skip); - } else { - log(this.exportConfig, 'No content types returned for the given query', 'info'); - } - } - - sanitizeAttribs(contentTypes) { - let updatedContentTypes = []; - contentTypes.forEach((contentType) => { - for (let key in contentType) { - if (this.contentTypesConfig.validKeys.indexOf(key) === -1) { - delete contentType[key]; - } - } - updatedContentTypes.push(contentType); - }); - return updatedContentTypes; - } - - async writeContentTypes(contentTypes) { - function write(contentType) { - return fileHelper.writeFile( - path.join(sanitizePath(this.contentTypesPath), `${sanitizePath (contentType.uid === 'schema' ? 'schema|1' : contentType.uid)}.json`), - contentType, - ); - } - await executeTask(contentTypes, write.bind(this), { concurrency: this.writeConcurrency }); - return fileHelper.writeFile(path.join(this.contentTypesPath, 'schema.json'), contentTypes); - } -} - -module.exports = ContentTypesExport; diff --git a/packages/contentstack-export/src/export/modules-js/custom-roles.js b/packages/contentstack-export/src/export/modules-js/custom-roles.js deleted file mode 100644 index b75681c9bd..0000000000 --- a/packages/contentstack-export/src/export/modules-js/custom-roles.js +++ /dev/null @@ -1,91 +0,0 @@ -'use strict'; - -const path = require('path'); -const chalk = require('chalk'); -const mkdirp = require('mkdirp'); -const { merge } = require('lodash'); -const { fileHelper, log, formatError } = require('../../utils'); -const { default: config } = require('../../config'); - -module.exports = class ExportCustomRoles { - roles = {}; - customRoles = {}; - EXISTING_ROLES = { - Admin: 1, - Developer: 1, - 'Content Manager': 1, - }; - rolesConfig = config.modules.customRoles; - - constructor(exportConfig, stackAPIClient) { - this.config = merge(config, exportConfig); - this.stackAPIClient = stackAPIClient; - } - - async start() { - const self = this; - - try { - log(this.config, 'Starting roles export', 'success'); - - const rolesFolderPath = path.resolve(this.config.data, this.config.branchName || '', this.rolesConfig.dirName); - mkdirp.sync(rolesFolderPath); - const roles = await self.stackAPIClient.role().fetchAll({ include_rules: true, include_permissions: true }); - const customRoles = roles.items.filter((role) => !self.EXISTING_ROLES[role.name]); - if (!customRoles.length) { - log(self.config, 'No custom roles were found in the Stack', 'success'); - return; - } - await self.getCustomRolesLocales( - customRoles, - path.join(rolesFolderPath, self.rolesConfig.customRolesLocalesFileName), - self.stackAPIClient, - self.config, - ); - self.customRoles = {}; - customRoles.forEach((role) => { - log(self.config, `'${role.name}' role was exported successfully`, 'success'); - self.customRoles[role.uid] = role; - }); - fileHelper.writeFileSync(path.join(rolesFolderPath, self.rolesConfig.fileName), self.customRoles); - log(self.config, chalk.green('All the custom roles have been exported successfully'), 'success'); - } catch (error) { - if (error.statusCode === 401) { - log( - self.config, - 'You are not allowed to export roles, Unless you provide email and password in config', - 'error', - ); - return; - } - log(self.config, `Error occurred in exporting roles. ${formatError(error)}`, 'error'); - throw error; - } - } - - async getCustomRolesLocales(customRoles, customRolesLocalesFilepath, stackAPIClient, config) { - const localesMap = {}; - for (const role of customRoles) { - const rulesLocales = role.rules.find((rule) => rule.module === 'locale'); - if (rulesLocales.locales && rulesLocales.locales.length) { - rulesLocales.locales.forEach((locale) => { - localesMap[locale] = 1; - }); - } - } - if (Object.keys(localesMap).length) { - const locales = await stackAPIClient.locale().query({}).find(); - const sourceLocalesMap = {}; - for (const locale of locales.items) { - sourceLocalesMap[locale.uid] = locale; - } - for (const locale in localesMap) { - if (sourceLocalesMap[locale] !== undefined) { - delete sourceLocalesMap[locale]['stackHeaders']; - } - localesMap[locale] = sourceLocalesMap[locale]; - } - fileHelper.writeFileSync(customRolesLocalesFilepath, localesMap); - } - } -}; diff --git a/packages/contentstack-export/src/export/modules-js/entries.js b/packages/contentstack-export/src/export/modules-js/entries.js deleted file mode 100644 index a9a9627be7..0000000000 --- a/packages/contentstack-export/src/export/modules-js/entries.js +++ /dev/null @@ -1,200 +0,0 @@ -const path = require('path'); -const chalk = require('chalk'); -const { values } = require('lodash'); -const { executeTask, formatError, fileHelper, log } = require('../../utils'); -const { sanitizePath } = require('@contentstack/cli-utilities'); - -class EntriesExport { - constructor(exportConfig, stackAPIClient) { - this.stackAPIClient = stackAPIClient; - this.exportConfig = exportConfig; - this.entriesConfig = exportConfig.modules.entries; - this.entriesRootPath = path.resolve((sanitizePath(exportConfig.data)), sanitizePath(exportConfig.branchName || ''), sanitizePath(this.entriesConfig.dirName)); - this.localesFilePath = path.resolve( - sanitizePath(exportConfig.data), - sanitizePath(exportConfig.branchName || ''), - sanitizePath(exportConfig.modules.locales.dirName), - sanitizePath(exportConfig.modules.locales.fileName), - ); - this.schemaFilePath = path.resolve( - sanitizePath(exportConfig.data), - sanitizePath(exportConfig.branchName || ''), - sanitizePath(exportConfig.modules.content_types.dirName), - 'schema.json', - ); - this.fetchConcurrency = this.entriesConfig.fetchConcurrency || exportConfig.fetchConcurrency; - this.writeConcurrency = this.entriesConfig.writeConcurrency || exportConfig.writeConcurrency; - } - - async start() { - try { - log(this.exportConfig, 'Starting entries export', 'info'); - const locales = await fileHelper.readFile(this.localesFilePath); - const contentTypes = await fileHelper.readFile(this.schemaFilePath); - if (contentTypes.length === 0) { - log(this.exportConfig, 'No content types found to export entries', 'info'); - return; - } - const entryRequestOptions = this.createRequestObjects(locales, contentTypes); - for (let requestOption of entryRequestOptions) { - log( - this.exportConfig, - `Starting export of entries of content_type - ${requestOption.content_type} locale - ${requestOption.locale}`, - 'info', - ); - await fileHelper.makeDirectory(path.join(this.entriesRootPath, requestOption.content_type)); - const entries = await this.getEntries(requestOption); - let entriesFilePath = path.join( - this.entriesRootPath, - requestOption.content_type, - requestOption.locale + '.json', - ); - await fileHelper.writeLargeFile(entriesFilePath, entries); - log( - this.exportConfig, - `Exported entries of type '${requestOption.content_type}' locale '${requestOption.locale}'`, - 'success', - ); - if (this.exportConfig.versioning) { - log( - this.exportConfig, - `Started export versioned entries of type '${requestOption.content_type}' locale '${requestOption.locale}'`, - 'info', - ); - for (let entry of values(entries)) { - const versionedEntries = await this.getEntryByVersion( - { - ...requestOption, - uid: entry.uid, - }, - entry._version, - ); - let versionedEntryPath = path.join( - this.entriesRootPath, - requestOption.locale, - requestOption.content_type, - entry.uid, - ); - await fileHelper.makeDirectory(versionedEntryPath); - if (versionedEntries.length > 0) { - const write = (versionedEntry) => - fileHelper.writeFile( - path.join(sanitizePath(versionedEntryPath), 'version-' + sanitizePath(versionedEntry._version) + '.json'), - versionedEntry, - ); - await executeTask(versionedEntries, write.bind(this), { concurrency: this.writeConcurrency }); - log( - this.exportConfig, - `Exported versioned entries of type '${requestOption.content_type}' locale '${requestOption.locale}'`, - 'success', - ); - } - } - } - } - log(this.exportConfig, chalk.green('Entries exported successfully'), 'success'); - } catch (error) { - log(this.exportConfig, `Failed to export entries ${formatError(error)}`, 'error'); - throw new Error('Failed to export entries'); - } - } - - async getEntries(requestOptions, skip = 0, entries = {}) { - let requestObject = { - locale: requestOptions.locale, - skip, - limit: this.entriesConfig.limit, - include_count: true, - include_publish_details: true, - query: { - locale: requestOptions.locale, - }, - }; - - const entriesSearchResponse = await this.stackAPIClient - .contentType(requestOptions.content_type) - .entry() - .query(requestObject) - .find(); - - if (Array.isArray(entriesSearchResponse.items) && entriesSearchResponse.items.length > 0) { - // clean up attribs and add to parent entry list - this.sanitizeAttribs(entriesSearchResponse.items, entries); - skip += this.entriesConfig.limit || 100; - if (skip > entriesSearchResponse.count) { - return entries; - } - return await this.getEntries(requestOptions, skip, entries); - } - return entries; - } - - async getEntryByVersion(requestOptions, version, entries = []) { - const queryRequestObject = { - locale: requestOptions.locale, - except: { - BASE: this.entriesConfig.invalidKeys, - }, - version, - }; - const entryResponse = await this.stackAPIClient - .contentType(requestOptions.content_type) - .entry(requestOptions.uid) - .fetch(queryRequestObject); - entries.push(entryResponse); - if (--version > 0) { - return await this.getEntryByVersion(requestOptions, version, entries); - } - return entries; - } - - async getEntriesCount(requestOptions) { - let requestObject = { - locale: requestOptions.locale, - limit: 1, - include_count: true, - include_publish_details: true, - query: { - locale: requestOptions.locale, - }, - }; - - const entriesSearchResponse = await this.stackAPIClient - .contentType(requestOptions.content_type) - .entry() - .query(requestObject) - .find(); - - return entriesSearchResponse.count; - } - - createRequestObjects(locales, contentTypes) { - let requestObjects = []; - contentTypes.forEach((contentType) => { - if (Object.keys(locales).length !== 0) { - for (let locale in locales) { - requestObjects.push({ - content_type: contentType.uid, - locale: locales[locale].code, - }); - } - } - requestObjects.push({ - content_type: contentType.uid, - locale: this.exportConfig.master_locale.code, - }); - }); - - return requestObjects; - } - - sanitizeAttribs(entries, entriesList = {}) { - entries.forEach((entry) => { - this.entriesConfig.invalidKeys.forEach((key) => delete entry[key]); - entriesList[entry.uid] = entry; - }); - return entriesList; - } -} - -module.exports = EntriesExport; diff --git a/packages/contentstack-export/src/export/modules-js/environments.js b/packages/contentstack-export/src/export/modules-js/environments.js deleted file mode 100644 index 6c8af23acf..0000000000 --- a/packages/contentstack-export/src/export/modules-js/environments.js +++ /dev/null @@ -1,69 +0,0 @@ -/*! - * Contentstack Export - * Copyright (c) 2024 Contentstack LLC - * MIT Licensed - */ -const path = require('path'); -const chalk = require('chalk'); -const mkdirp = require('mkdirp'); -const { merge } = require('lodash'); -const { fileHelper, log, formatError } = require('../../utils'); -module.exports = class ExportEnvironments { - config = {}; - master = {}; - environments = {}; - requestOptions = { - json: true, - qs: { - asc: 'updated_at', - include_count: true, - }, - }; - - constructor(exportConfig, stackAPIClient) { - this.config = merge(this.config, exportConfig); - this.stackAPIClient = stackAPIClient; - } - - start() { - const self = this; - const environmentConfig = self.config.modules.environments; - const environmentsFolderPath = path.resolve( - self.config.data, - self.config.branchName || '', - environmentConfig.dirName, - ); - - // Create folder for environments - fileHelper.makeDirectory(environmentsFolderPath); - log(this.config, 'Starting environment export', 'success'); - return new Promise(function (resolve, reject) { - self.stackAPIClient - .environment() - .query(self.requestOptions.qs) - .find() - .then((environmentResponse) => { - if (environmentResponse.items.length !== 0) { - for (let i = 0, total = environmentResponse.count; i < total; i++) { - const envUid = environmentResponse.items[i].uid; - self.master[envUid] = ''; - self.environments[envUid] = environmentResponse.items[i]; - delete self.environments[envUid].uid; - delete self.environments[envUid]['ACL']; - } - fileHelper.writeFileSync(path.join(environmentsFolderPath, environmentConfig.fileName), self.environments); - log(self.config, chalk.green('All the environments have been exported successfully'), 'success'); - return resolve(); - } - if (environmentResponse.items.length === 0) { - log(self.config, 'No environments found', 'success'); - resolve(); - } - }) - .catch((error) => { - log(self.config, `Environments export failed. ${formatError(error)}`, 'error'); - reject(error); - }); - }); - } -}; diff --git a/packages/contentstack-export/src/export/modules-js/extensions.js b/packages/contentstack-export/src/export/modules-js/extensions.js deleted file mode 100644 index 931b6f7c46..0000000000 --- a/packages/contentstack-export/src/export/modules-js/extensions.js +++ /dev/null @@ -1,66 +0,0 @@ -/*! - * Contentstack Export - * Copyright (c) 2024 Contentstack LLC - * MIT Licensed - */ - -const mkdirp = require('mkdirp'); -const path = require('path'); -const chalk = require('chalk'); -const { merge } = require('lodash'); -const { formatError, log, fileHelper } = require('../../utils'); -const { default: config } = require('../../config'); - -module.exports = class ExportExtensions { - master = {}; - extensions = {}; - extensionConfig = config.modules.extensions; - queryRequestOptions = { - asc: 'updated_at', - include_count: true, - }; - - constructor(exportConfig, stackAPIClient) { - this.config = merge(config, exportConfig); - this.stackAPIClient = stackAPIClient; - } - - start() { - log(this.config, 'Starting extension export', 'success'); - - const self = this; - const extensionsFolderPath = path.resolve( - this.config.data, - this.config.branchName || '', - this.extensionConfig.dirName, - ); - // Create folder for extensions - mkdirp.sync(extensionsFolderPath); - return new Promise(function (resolve, reject) { - self.stackAPIClient - .extension() - .query(self.queryRequestOptions) - .find() - .then((extension) => { - if (extension.items.length !== 0) { - for (let i = 0, total = extension.count; i < total; i++) { - const extUid = extension.items[i].uid; - self.master[extUid] = ''; - self.extensions[extUid] = extension.items[i]; - delete self.extensions[extUid].uid; - delete self.extensions[extUid].SYS_ACL; - } - fileHelper.writeFileSync(path.join(extensionsFolderPath, self.extensionConfig.fileName), self.extensions); - log(self.config, chalk.green('All the extensions have been exported successfully'), 'success'); - return resolve(); - } - log(self.config, 'No extensions found', 'success'); - resolve(); - }) - .catch((error) => { - log(self.config, `Failed to export extensions. ${formatError(error)}`, 'error'); - reject(); - }); - }); - } -}; diff --git a/packages/contentstack-export/src/export/modules-js/global-fields.js b/packages/contentstack-export/src/export/modules-js/global-fields.js deleted file mode 100644 index ef32dc6457..0000000000 --- a/packages/contentstack-export/src/export/modules-js/global-fields.js +++ /dev/null @@ -1,121 +0,0 @@ -/*! - * Contentstack Export - * Copyright (c) 2024 Contentstack LLC - * MIT Licensed - */ - -const path = require('path'); -const chalk = require('chalk'); -const mkdirp = require('mkdirp'); -const { merge } = require('lodash'); -const { formatError, log, fileHelper } = require('../../utils'); -const { default: config } = require('../../config'); -const { sanitizePath } = require('@contentstack/cli-utilities'); - -module.exports = class ExportGlobalFields { - limit = 100; - config = {}; - global_fields = []; - master = {}; - globalfields = {}; - requestOptions = {}; - globalfieldsFolderPath; - globalfieldsConfig = config.modules.globalfields; - validKeys = config.modules.globalfields.validKeys; - - constructor(exportConfig, stackAPIClient) { - this.requestOptions = { - qs: { - skip: 0, - limit: this.limit, - asc: 'updated_at', - include_count: true, - }, - }; - this.config = merge(config, exportConfig); - this.stackAPIClient = stackAPIClient; - this.globalfieldsFolderPath = path.resolve( - sanitizePath(this.config.data), - sanitizePath(this.config.branchName || ''), - sanitizePath(this.globalfieldsConfig.dirName), - ); - } - - start() { - const self = this; - // Create folder for Global Fields - mkdirp.sync(self.globalfieldsFolderPath); - log(self.config, 'Starting Global Fields export', 'success'); - - return new Promise(function (resolve, reject) { - try { - return self - .getGlobalFields(0, self.config) - .then(function (result) { - if (!result) { - return self.writeGlobalFields().then(resolve).catch(reject); - } - return resolve(); - }) - .catch(reject); - } catch (error) { - log(self.config, error, 'error'); - return reject(error); - } - }); - } - - getGlobalFields(skip, globalFieldConfig) { - const self = this; - self.requestOptions.qs.skip = skip; - return new Promise(function (resolve, reject) { - self.stackAPIClient - .globalField() - .query(self.requestOptions.qs) - .find() - .then((globalFieldResponse) => { - try { - if (globalFieldResponse.items.length === 0) { - log(globalFieldConfig, 'No global fields found', 'success'); - return resolve('No Global Fields'); - } - globalFieldResponse.items.forEach(function (globalField) { - for (const key in globalField) { - if (self.validKeys.indexOf(key) === -1) { - delete globalField[key]; - } - } - self.global_fields.push(globalField); - }); - skip += self.limit; - if (skip >= globalFieldResponse.count) { - return resolve(); - } - return self.getGlobalFields(skip, globalFieldConfig).then(resolve).catch(reject); - } catch (error) { - log(globalFieldConfig, `Failed to export global-fields. ${formatError(error)}`, 'error'); - reject(error); - } - }) - .catch(reject); - }); - } - - writeGlobalFields() { - const self = this; - return new Promise(function (resolve, reject) { - try { - fileHelper.writeFileSync( - path.join(self.globalfieldsFolderPath, self.globalfieldsConfig.fileName), - self.global_fields, - ); - log(self.config, chalk.green('Global Fields export completed successfully'), 'success'); - - resolve(); - } catch (error) { - log(self.config, error, 'error'); - reject(error); - } - }); - } -}; diff --git a/packages/contentstack-export/src/export/modules-js/index.js b/packages/contentstack-export/src/export/modules-js/index.js deleted file mode 100644 index 23233448ad..0000000000 --- a/packages/contentstack-export/src/export/modules-js/index.js +++ /dev/null @@ -1,8 +0,0 @@ -async function startModuleExport(modulePayload) { - const { moduleName, exportConfig, stackAPIClient } = modulePayload; - const { default: ModuleRunner } = await import(`./${moduleName}.js`); - const moduleRunner = new ModuleRunner(exportConfig, stackAPIClient); - return moduleRunner.start(); -} - -module.exports = startModuleExport; diff --git a/packages/contentstack-export/src/export/modules-js/labels.js b/packages/contentstack-export/src/export/modules-js/labels.js deleted file mode 100644 index 9b6f4fba20..0000000000 --- a/packages/contentstack-export/src/export/modules-js/labels.js +++ /dev/null @@ -1,63 +0,0 @@ -/*! - * Contentstack Export - * Copyright (c) 2024 Contentstack LLC - * MIT Licensed - */ - -const path = require('path'); -const chalk = require('chalk'); -const mkdirp = require('mkdirp'); -const { merge } = require('lodash'); -const { formatError, log, fileHelper } = require('../../utils'); -const { default: config } = require('../../config'); - -module.exports = class ExportLabels { - labels = {}; - labelConfig = config.modules.labels; - - constructor(exportConfig, stackAPIClient) { - this.config = merge(config, exportConfig); - this.stackAPIClient = stackAPIClient; - } - - start() { - log(this.config, 'Starting labels export', 'success'); - const self = this; - const labelsFolderPath = path.resolve(config.data, this.config.branchName || '', self.labelConfig.dirName); - // Create locale folder - mkdirp.sync(labelsFolderPath); - return new Promise(function (resolve, reject) { - return self.stackAPIClient - .label() - .query() - .find() - .then((response) => { - if (response.items.length !== 0) { - response.items.forEach(function (label) { - log(self.config, `'${label.name}' label was exported successfully`, 'success'); - self.labels[label.uid] = label; - const deleteItems = self.config.modules.labels.invalidKeys; - deleteItems.forEach((e) => delete label[e]); - }); - log(self.config, chalk.green('All the labels have been exported successfully'), 'success'); - } else { - log(self.config, 'No labels found', 'success'); - } - fileHelper.writeFileSync(path.join(labelsFolderPath, self.labelConfig.fileName), self.labels); - resolve(); - }) - .catch(function (error) { - if (error.statusCode === 401) { - log( - self.config, - 'You are not allowed to export label, Unless you provide email and password in config', - 'error', - ); - return resolve(); - } - log(self.config, `Failed to export labels. ${formatError(error)}`, 'error'); - reject(); - }); - }); - } -}; diff --git a/packages/contentstack-export/src/export/modules-js/locales.js b/packages/contentstack-export/src/export/modules-js/locales.js deleted file mode 100644 index a377737d7b..0000000000 --- a/packages/contentstack-export/src/export/modules-js/locales.js +++ /dev/null @@ -1,71 +0,0 @@ -const path = require('path'); -const chalk = require('chalk'); -const { formatError, log, fileHelper } = require('../../utils'); -const { sanitizePath } = require('@contentstack/cli-utilities'); -class LocaleExport { - constructor(exportConfig, stackAPIClient) { - this.stackAPIClient = stackAPIClient; - this.exportConfig = exportConfig; - this.localeConfig = exportConfig.modules.locales; - this.masterLocaleConfig = exportConfig.modules.masterLocale; - this.qs = { - include_count: true, - asc: 'updated_at', - only: { - BASE: this.localeConfig.requiredKeys, - }, - }; - - this.localesPath = path.resolve(sanitizePath(exportConfig.data), sanitizePath(exportConfig.branchName || ''), sanitizePath(this.localeConfig.dirName)); - this.locales = {}; - this.masterLocale = {}; - this.fetchConcurrency = this.localeConfig.fetchConcurrency || this.exportConfig.fetchConcurrency; - this.writeConcurrency = this.localeConfig.writeConcurrency || this.exportConfig.writeConcurrency; - } - - async start() { - try { - log(this.exportConfig, 'Starting locale export', 'success'); - fileHelper.makeDirectory(this.localesPath); - await this.getLocales(); - await fileHelper.writeFile(path.join(this.localesPath, this.localeConfig.fileName), this.locales); - await fileHelper.writeFile(path.join(this.localesPath, this.masterLocaleConfig.fileName), this.masterLocale); - log(this.exportConfig, 'Completed locale export', 'success'); - } catch (error) { - log(this.exportConfig, `Failed to export locales. ${formatError(error)}`, 'error'); - throw new Error('Failed to export locales'); - } - } - - async getLocales(skip = 0) { - if (skip) { - this.qs.skip = skip; - } - let localesFetchResponse = await this.stackAPIClient.locale().query(this.qs).find(); - if (Array.isArray(localesFetchResponse.items) && localesFetchResponse.items.length > 0) { - this.sanitizeAttribs(localesFetchResponse.items); - skip += this.localeConfig.limit || 100; - if (skip > localesFetchResponse.count) { - return; - } - return await this.getLocales(skip); - } - } - - sanitizeAttribs(locales) { - locales.forEach((locale) => { - for (let key in locale) { - if (this.localeConfig.requiredKeys.indexOf(key) === -1) { - delete locale[key]; - } - } - if (locale.code === this.exportConfig.master_locale.code) { - this.masterLocale[locale.uid] = locale; - } else { - this.locales[locale.uid] = locale; - } - }); - } -} - -module.exports = LocaleExport; diff --git a/packages/contentstack-export/src/export/modules-js/marketplace-apps.js b/packages/contentstack-export/src/export/modules-js/marketplace-apps.js deleted file mode 100644 index ca4d7526f9..0000000000 --- a/packages/contentstack-export/src/export/modules-js/marketplace-apps.js +++ /dev/null @@ -1,172 +0,0 @@ -/*! - * Contentstack Export - * Copyright (c) 2024 Contentstack LLC - * MIT Licensed - */ -const _ = require('lodash'); -const path = require('path'); -const chalk = require('chalk'); -const mkdirp = require('mkdirp'); -const eachOf = require('async/eachOf'); -const { - cliux, - HttpClient, - NodeCrypto, - managementSDKClient, - HttpClientDecorator, - OauthDecorator, - isAuthenticated, -} = require('@contentstack/cli-utilities'); -const { default: config } = require('../../config'); -const { formatError, log, fileHelper } = require('../../utils'); -const { createNodeCryptoInstance } = require('../../utils'); - -module.exports = class ExportMarketplaceApps { - client; - config; - httpClient; - nodeCrypto; - marketplaceAppPath = null; - developerHubBaseUrl = null; - marketplaceAppConfig = config.modules.marketplace_apps; - - constructor(credentialConfig) { - this.config = _.merge(config, credentialConfig); - } - - async start() { - if (!isAuthenticated()) { - cliux.print( - 'WARNING!!! To export Marketplace apps, you must be logged in. Please check csdx auth:login --help to log in', - { color: 'yellow' }, - ); - return Promise.resolve(); - } - - this.developerHubBaseUrl = this.config.developerHubBaseUrl || (await getDeveloperHubUrl(this.config)); - this.appSdkAxiosInstance = await managementSDKClient({ - endpoint: this.developerHubBaseUrl, - }); - await this.getOrgUid(); - - const httpClient = new HttpClient(); - if (!this.config.auth_token) { - this.httpClient = new OauthDecorator(httpClient); - const headers = await this.httpClient.preHeadersCheck(this.config); - this.httpClient = this.httpClient.headers(headers); - } else { - this.httpClient = new HttpClientDecorator(httpClient); - this.httpClient.headers(this.config); - } - - log(this.config, 'Starting marketplace app export', 'success'); - this.marketplaceAppPath = path.resolve( - this.config.data, - this.config.branchName || '', - this.marketplaceAppConfig.dirName, - ); - mkdirp.sync(this.marketplaceAppPath); - - this.nodeCrypto = await createNodeCryptoInstance(config); - - return this.exportInstalledExtensions(); - } - - async getOrgUid() { - const tempAPIClient = await managementSDKClient({ host: this.config.host }); - const tempStackData = await tempAPIClient - .stack({ api_key: this.config.source_stack }) - .fetch() - .catch((error) => { - log(this.config, formatError(error), 'error'); - console.log(error); - }); - - if (tempStackData?.org_uid) { - this.config.org_uid = tempStackData.org_uid; - } - } - - async exportInstalledExtensions() { - const client = await managementSDKClient({ host: this.developerHubBaseUrl.split('://').pop() }); - const installedApps = (await this.getAllStackSpecificApps()) || []; - - if (!_.isEmpty(installedApps)) { - for (const [index, app] of _.entries(installedApps)) { - await this.getAppConfigurations(client, installedApps, [+index, app]); - } - - fileHelper.writeFileSync(path.join(this.marketplaceAppPath, this.marketplaceAppConfig.fileName), installedApps); - - log(this.config, chalk.green('All the marketplace apps have been exported successfully'), 'success'); - } else { - log(this.config, 'No marketplace apps found', 'success'); - } - } - - getAllStackSpecificApps(listOfApps = [], skip = 0) { - return this.appSdkAxiosInstance.axiosInstance - .get(`/installations?target_uids=${this.config.source_stack}&skip=${skip}`, { - headers: { - organization_uid: this.config.org_uid - }, - }) - .then(async ({ data }) => { - const { data: apps, count } = data; - - if (!this.nodeCrypto && _.find(apps, (app) => !_.isEmpty(app.configuration))) { - await this.createNodeCryptoInstance(); - } - - listOfApps.push( - ..._.map(apps, (app) => { - if (_.has(app, 'configuration')) { - app['configuration'] = this.nodeCrypto.encrypt(app.configuration || configuration); - } - - return app; - }), - ); - - if (count - (skip + 50) > 0) { - return await this.getAllStackSpecificApps(listOfApps, skip + 50); - } - - return listOfApps; - }) - .catch((error) => { - log(this.config, `Failed to export marketplace-apps. ${formatError(error)}`, 'error'); - }); - } - - async getAppConfigurations(sdkClient, installedApps, [index, appInstallation]) { - const appName = appInstallation.manifest.name; - log(this.config, `Exporting ${appName} app and it's config.`, 'success'); - - await sdkClient - .organization(this.config.org_uid) - .app(appInstallation.manifest.uid) - .installation(appInstallation.uid) - .installationData() - .then(async (result) => { - const { data, error } = result; - if (_.has(data, 'server_configuration')) { - if (!this.nodeCrypto && _.has(data, 'server_configuration')) { - await this.createNodeCryptoInstance(); - } - - if (!_.isEmpty(data.server_configuration)) { - installedApps[index]['server_configuration'] = this.nodeCrypto.encrypt(data.server_configuration); - log(this.config, `Exported ${appName} app and it's config.`, 'success'); - } else { - log(this.config, `Exported ${appName} app`, 'success'); - } - } else if (error) { - log(this.config, `Error on exporting ${appName} app and it's config.`, 'error'); - } - }) - .catch((err) => { - log(this.config, `Failed to export ${appName} app config ${formatError(err)}`, 'error'); - }); - } -}; diff --git a/packages/contentstack-export/src/export/modules-js/stack.js b/packages/contentstack-export/src/export/modules-js/stack.js deleted file mode 100644 index d585964c04..0000000000 --- a/packages/contentstack-export/src/export/modules-js/stack.js +++ /dev/null @@ -1,99 +0,0 @@ -/*! - * Contentstack Export - * Copyright (c) 2024 Contentstack LLC - * MIT Licensed - */ - -const path = require('path'); -const mkdirp = require('mkdirp'); -const merge = require('lodash/merge'); -const { default: config } = require('../../config'); -const { managementSDKClient, isAuthenticated } = require('@contentstack/cli-utilities'); -const { log, fileHelper, formatError } = require('../../utils'); - -class ExportStack { - stackConfig = config.modules.stack; - - constructor(exportConfig, stackAPIClient) { - this.config = merge(config, exportConfig); - this.stackAPIClient = stackAPIClient; - this.requestOption = { - uri: this.config.host + this.config.apis.stacks, - headers: this.config.headers, - json: true, - }; - } - - async start() { - const self = this; - if (isAuthenticated()) { - const tempAPIClient = await managementSDKClient({ host: config.host }); - const tempStackData = await tempAPIClient - .stack({ api_key: self.config.source_stack }) - .fetch() - .catch((error) => { - }); - - if (tempStackData && tempStackData.org_uid) { - self.config.org_uid = tempStackData.org_uid; - self.config.sourceStackName = tempStackData.name; - } - } - - if (!self.config.preserveStackVersion && !self.config.hasOwnProperty('master_locale')) { - const apiDetails = { - limit: 100, - skip: 0, - include_count: true, - }; - return self.getLocales(apiDetails); - } else if (self.config.preserveStackVersion) { - log(self.config, 'Exporting stack details', 'success'); - let stackFolderPath = path.resolve(self.config.data, this.stackConfig.dirName); - let stackContentsFile = path.resolve(stackFolderPath, this.stackConfig.fileName); - - mkdirp.sync(stackFolderPath); - - return new Promise((resolve, reject) => { - return self.stackAPIClient - .fetch() - .then((response) => { - fileHelper.writeFile(stackContentsFile, response); - log(self.config, 'Exported stack details successfully!', 'success'); - return resolve(response); - }) - .catch(reject); - }); - } - } - - getLocales(apiDetails) { - const self = this; - return new Promise((resolve, reject) => { - const result = self.stackAPIClient.locale().query(apiDetails); - - result - .find() - .then((response) => { - const masterLocalObj = response.items.find((obj) => { - if (obj.fallback_locale === null) { - return obj; - } - }); - apiDetails.skip += apiDetails.limit; - if (masterLocalObj) { - return resolve(masterLocalObj); - } else if (apiDetails.skip <= response.count) { - return resolve(self.getLocales(apiDetails)); - } else { - return reject('Master locale not found'); - } - }) - .catch((error) => { - return reject(error); - }); - }); - } -} - -module.exports = ExportStack; diff --git a/packages/contentstack-export/src/export/modules-js/webhooks.js b/packages/contentstack-export/src/export/modules-js/webhooks.js deleted file mode 100644 index ec5e559a20..0000000000 --- a/packages/contentstack-export/src/export/modules-js/webhooks.js +++ /dev/null @@ -1,73 +0,0 @@ -/*! - * Contentstack Export - * Copyright (c) 2024 Contentstack LLC - * MIT Licensed - */ - -const path = require('path'); -const chalk = require('chalk'); -const mkdirp = require('mkdirp'); -const { merge } = require('lodash'); -const { default: config } = require('../../config'); -const { formatError, log, fileHelper } = require('../../utils'); - -// Create folder for environments -module.exports = class ExportWebhooks { - config; - master = {}; - webhooks = {}; - requestOptions = { - include_count: true, - asc: 'updated_at', - }; - webhooksConfig = config.modules.webhooks; - - constructor(exportConfig, stackAPIClient) { - this.config = merge(config, exportConfig); - this.stackAPIClient = stackAPIClient; - } - - start() { - log(this.config, 'Starting webhooks export', 'success'); - const self = this; - const webhooksFolderPath = path.resolve( - this.config.data, - this.config.branchName || '', - self.webhooksConfig.dirName, - ); - mkdirp.sync(webhooksFolderPath); - return new Promise((resolve, reject) => { - self.stackAPIClient - .webhook() - .fetchAll(self.requestOptions) - .then((webhooks) => { - if (webhooks.items.length !== 0) { - for (let i = 0, total = webhooks.count; i < total; i++) { - const webUid = webhooks.items[i].uid; - self.master[webUid] = ''; - self.webhooks[webUid] = webhooks.items[i]; - delete self.webhooks[webUid].uid; - delete self.webhooks[webUid].SYS_ACL; - } - fileHelper.writeFileSync(path.join(webhooksFolderPath, self.webhooksConfig.fileName), self.webhooks); - log(self.config, chalk.green('All the webhooks have been exported successfully'), 'success'); - return resolve(); - } - log(self.config, 'No webhooks found', 'success'); - resolve(); - }) - .catch(function (error) { - if (error.statusCode === 401) { - log( - self.config, - 'You are not allowed to export webhooks, Unless you provide email and password in config', - 'error', - ); - return resolve(); - } - log(self.config, `Failed to export webhooks. ${formatError(error)}`, 'error'); - reject('Failed to export webhooks'); - }); - }); - } -}; diff --git a/packages/contentstack-export/src/export/modules-js/workflows.js b/packages/contentstack-export/src/export/modules-js/workflows.js deleted file mode 100644 index e7cd7667ff..0000000000 --- a/packages/contentstack-export/src/export/modules-js/workflows.js +++ /dev/null @@ -1,102 +0,0 @@ -/*! - * Contentstack Export - * Copyright (c) 2024 Contentstack LLC - * MIT Licensed - */ - -const path = require('path'); -const chalk = require('chalk'); -const mkdirp = require('mkdirp'); -const { merge } = require('lodash'); -const { formatError, log, fileHelper } = require('../../utils'); -const { default: config } = require('../../config'); -module.exports = class ExportWorkFlows { - config; - workflows = {}; - workFlowConfig = config.modules.workflows; - - constructor(exportConfig, stackAPIClient) { - this.config = merge(config, exportConfig); - this.stackAPIClient = stackAPIClient; - } - - start() { - log(this.config, 'Starting workflow export', 'success'); - - const self = this; - const workflowsFolderPath = path.resolve( - this.config.data, - this.config.branchName || '', - this.workFlowConfig.dirName, - ); - mkdirp.sync(workflowsFolderPath); - - return new Promise(function (resolve, reject) { - return self.stackAPIClient - .workflow() - .fetchAll() - .then(async (response) => { - try { - if (response.items.length) { - await self.getWorkflowsData(self, response.items); - log(self.config, chalk.green('All the workflow have been exported successfully'), 'success'); - } - if (!response.items.length) { - log(self.config, 'No workflow were found in the Stack', 'success'); - } - fileHelper.writeFileSync(path.join(workflowsFolderPath, self.workFlowConfig.fileName), self.workflows); - resolve(); - } catch (error) { - log(self.config, formatError(error), 'error'); - reject(error); - } - }) - .catch(function (error) { - if (error.statusCode === 401) { - log( - self.config, - 'You are not allowed to export workflow, Unless you provide email and password in config', - 'error', - ); - return resolve(); - } - log(self.config, formatError(error), 'error'); - resolve(); - }); - }); - } - - async getWorkflowRoles(self, workflow) { - try { - for (const stage of workflow.workflow_stages) { - if (stage.SYS_ACL.roles.uids.length) { - for (let i = 0; i < stage.SYS_ACL.roles.uids.length; i++) { - const roleUid = stage.SYS_ACL.roles.uids[i]; - const roleData = await self.stackAPIClient - .role(roleUid) - .fetch({ include_rules: true, include_permissions: true }); - stage.SYS_ACL.roles.uids[i] = roleData; - } - } - } - } catch (error) { - log(self.config, `Error fetching roles in export workflows task. ${formatError(error)}`, 'error'); - throw new Error({ message: 'Error fetching roles in export workflows task.' }); - } - } - - async getWorkflowsData(self, workflows) { - try { - for (const workflow of workflows) { - log(self.config, workflow.name + ' workflow was exported successfully', 'success'); - await self.getWorkflowRoles(self, workflow); - self.workflows[workflow.uid] = workflow; - const deleteItems = config.modules.workflows.invalidKeys; - deleteItems.forEach((e) => delete workflow[e]); - } - } catch (error) { - log(self.config, `Error fetching workflow data in export workflows task. ${formatError(error)}`, 'error'); - throw error; - } - } -}; diff --git a/packages/contentstack-export/src/export/modules/assets.ts b/packages/contentstack-export/src/export/modules/assets.ts index 1a95d5f257..f774f2c6eb 100644 --- a/packages/contentstack-export/src/export/modules/assets.ts +++ b/packages/contentstack-export/src/export/modules/assets.ts @@ -1,4 +1,5 @@ import map from 'lodash/map'; +import chalk from 'chalk'; import chunk from 'lodash/chunk'; import first from 'lodash/first'; import merge from 'lodash/merge'; @@ -23,6 +24,7 @@ import { import config from '../../config'; import { ModuleClassParams } from '../../types'; import BaseClass, { CustomPromiseHandler, CustomPromiseHandlerInput } from './base-class'; +import { PROCESS_NAMES, MODULE_CONTEXTS, PROCESS_STATUS, MODULE_NAMES } from '../../utils'; export default class ExportAssets extends BaseClass { private assetsRootPath: string; @@ -32,7 +34,8 @@ export default class ExportAssets extends BaseClass { constructor({ exportConfig, stackAPIClient }: ModuleClassParams) { super({ exportConfig, stackAPIClient }); - this.exportConfig.context.module = 'assets'; + this.exportConfig.context.module = MODULE_CONTEXTS.ASSETS; + this.currentModuleName = MODULE_NAMES[MODULE_CONTEXTS.ASSETS]; } get commonQueryParam(): Record { @@ -49,27 +52,79 @@ export default class ExportAssets extends BaseClass { this.exportConfig.branchName || '', this.assetConfig.dirName, ); - log.debug(`Assets root path resolved to: ${this.assetsRootPath}`, this.exportConfig.context); log.debug('Fetching assets and folders count...', this.exportConfig.context); // NOTE step 1: Get assets and it's folder count in parallel - const [assetsCount, assetsFolderCount] = await Promise.all([this.getAssetsCount(), this.getAssetsCount(true)]); + const [assetsCount, assetsFolderCount] = await this.withLoadingSpinner( + `${chalk.bold('ASSETS')}: Analyzing stack content...`, + () => Promise.all([this.getAssetsCount(), this.getAssetsCount(true)]), + ); - log.debug('Fetching assets and folders data...', this.exportConfig.context); - // NOTE step 2: Get assets and it's folder data in parallel - await Promise.all([this.getAssetsFolders(assetsFolderCount), this.getAssets(assetsCount)]); + // Create nested progress manager + const progress = this.createNestedProgress(this.currentModuleName); - // NOTE step 3: Get versioned assets - if (!isEmpty(this.versionedAssets) && this.assetConfig.includeVersionedAssets) { - log.debug('Fetching versioned assets metadata...', this.exportConfig.context); - await this.getVersionedAssets(); + // Add sub-processes + if (typeof assetsFolderCount === 'number' && assetsFolderCount > 0) { + progress.addProcess(PROCESS_NAMES.ASSET_FOLDERS, assetsFolderCount); + } + if (typeof assetsCount === 'number' && assetsCount > 0) { + progress.addProcess(PROCESS_NAMES.ASSET_METADATA, assetsCount); + progress.addProcess(PROCESS_NAMES.ASSET_DOWNLOADS, assetsCount); } - log.debug('Starting download of all assets...', this.exportConfig.context); - // NOTE step 4: Download all assets - await this.downloadAssets(); + try { + // Process asset folders + if (typeof assetsFolderCount === 'number' && assetsFolderCount > 0) { + progress + .startProcess(PROCESS_NAMES.ASSET_FOLDERS) + .updateStatus( + PROCESS_STATUS[PROCESS_NAMES.ASSET_FOLDERS].FETCHING, + PROCESS_NAMES.ASSET_FOLDERS, + ); + await this.getAssetsFolders(assetsFolderCount); + progress.completeProcess(PROCESS_NAMES.ASSET_FOLDERS, true); + } + + // Process asset metadata + if (typeof assetsCount === 'number' && assetsCount > 0) { + progress + .startProcess(PROCESS_NAMES.ASSET_METADATA) + .updateStatus( + PROCESS_STATUS[PROCESS_NAMES.ASSET_METADATA].FETCHING, + PROCESS_NAMES.ASSET_METADATA, + ); + await this.getAssets(assetsCount); + progress.completeProcess(PROCESS_NAMES.ASSET_METADATA, true); + } + + // Get versioned assets + if (!isEmpty(this.versionedAssets) && this.assetConfig.includeVersionedAssets) { + log.debug('Fetching versioned assets metadata...', this.exportConfig.context); + progress.updateStatus( + PROCESS_STATUS[PROCESS_NAMES.ASSET_METADATA].FETCHING_VERSION, + PROCESS_NAMES.ASSET_METADATA, + ); + await this.getVersionedAssets(); + } + + // Download all assets + if (typeof assetsCount === 'number' && assetsCount > 0) { + progress + .startProcess(PROCESS_NAMES.ASSET_DOWNLOADS) + .updateStatus( + PROCESS_STATUS[PROCESS_NAMES.ASSET_DOWNLOADS].DOWNLOADING, + PROCESS_NAMES.ASSET_DOWNLOADS, + ); + log.debug('Starting download of all assets...', this.exportConfig.context); + await this.downloadAssets(); + progress.completeProcess(PROCESS_NAMES.ASSET_DOWNLOADS, true); + } - log.success(messageHandler.parse('ASSET_EXPORT_COMPLETE'), this.exportConfig.context); + this.completeProgress(true); + log.success(messageHandler.parse('ASSET_EXPORT_COMPLETE'), this.exportConfig.context); + } catch (error) { + this.completeProgress(false, error?.message || 'Asset export failed'); + } } /** @@ -89,10 +144,26 @@ export default class ExportAssets extends BaseClass { const onSuccess = ({ response: { items } }: any) => { log.debug(`Fetched ${items?.length || 0} asset folders`, this.exportConfig.context); - if (!isEmpty(items)) this.assetsFolder.push(...items); + if (!isEmpty(items)) { + this.assetsFolder.push(...items); + items.forEach((folder: any) => { + this.progressManager?.tick( + true, + `folder: ${folder.name || folder.uid}`, + null, + PROCESS_NAMES.ASSET_FOLDERS, + ); + }); + } }; const onReject = ({ error }: any) => { + this.progressManager?.tick( + false, + 'asset folder', + error?.message || PROCESS_STATUS[PROCESS_NAMES.ASSET_FOLDERS].FAILED, + PROCESS_NAMES.ASSET_FOLDERS, + ); handleAndLogError(error, { ...this.exportConfig.context }); }; @@ -155,6 +226,12 @@ export default class ExportAssets extends BaseClass { } const onReject = ({ error }: any) => { + this.progressManager?.tick( + false, + 'asset', + error?.message || PROCESS_STATUS[PROCESS_NAMES.ASSET_METADATA].FAILED, + PROCESS_NAMES.ASSET_METADATA, + ); handleAndLogError(error, { ...this.exportConfig.context }, messageHandler.parse('ASSET_QUERY_FAILED')); }; @@ -174,6 +251,15 @@ export default class ExportAssets extends BaseClass { if (!isEmpty(items)) { log.debug(`Writing ${items.length} assets into file`, this.exportConfig.context); fs?.writeIntoFile(items, { mapKeyVal: true }); + // Track progress for each asset with process name + items.forEach((asset: any) => { + this.progressManager?.tick( + true, + `asset: ${asset.filename || asset.uid}`, + null, + PROCESS_NAMES.ASSET_METADATA, + ); + }); } }; @@ -371,12 +457,23 @@ export default class ExportAssets extends BaseClass { } else { data.pipe(assetWriterStream); } - + this.progressManager?.tick( + true, + `Downloaded asset: ${asset.filename || asset.uid}`, + null, + PROCESS_NAMES.ASSET_DOWNLOADS, + ); log.success(messageHandler.parse('ASSET_DOWNLOAD_SUCCESS', asset.filename, asset.uid), this.exportConfig.context); }; const onReject = ({ error, additionalInfo }: any) => { const { asset } = additionalInfo; + this.progressManager?.tick( + false, + `Failed to download asset: ${asset.filename || asset.uid}`, + null, + PROCESS_NAMES.ASSET_DOWNLOADS, + ); handleAndLogError( error, { ...this.exportConfig.context, uid: asset.uid, filename: asset.filename }, diff --git a/packages/contentstack-export/src/export/modules/base-class.ts b/packages/contentstack-export/src/export/modules/base-class.ts index a683e2fc40..f1298468bb 100644 --- a/packages/contentstack-export/src/export/modules/base-class.ts +++ b/packages/contentstack-export/src/export/modules/base-class.ts @@ -5,7 +5,7 @@ import chunk from 'lodash/chunk'; import isEmpty from 'lodash/isEmpty'; import entries from 'lodash/entries'; import isEqual from 'lodash/isEqual'; -import { log } from '@contentstack/cli-utilities'; +import { log, CLIProgressManager, configHandler } from '@contentstack/cli-utilities'; import { ExportConfig, ModuleClassParams } from '../../types'; @@ -53,12 +53,59 @@ export type ApiModuleType = export default abstract class BaseClass { readonly client: any; public exportConfig: ExportConfig; + protected progressManager: CLIProgressManager | null = null; + protected currentModuleName: string = ''; constructor({ exportConfig, stackAPIClient }: Omit) { this.client = stackAPIClient; this.exportConfig = exportConfig; } + static printFinalSummary(): void { + CLIProgressManager.printGlobalSummary(); + } + + /** + * Create simple progress manager + */ + protected createSimpleProgress(moduleName: string, total?: number): CLIProgressManager { + this.currentModuleName = moduleName; + const logConfig = configHandler.get('log') || {}; + const showConsoleLogs = logConfig.showConsoleLogs ?? false; // Default to true for better UX + this.progressManager = CLIProgressManager.createSimple(moduleName, total, showConsoleLogs); + return this.progressManager; + } + + /** + * Create nested progress manager + */ + protected createNestedProgress(moduleName: string): CLIProgressManager { + this.currentModuleName = moduleName; + const logConfig = configHandler.get('log') || {}; + const showConsoleLogs = logConfig.showConsoleLogs ?? false; // Default to true for better UX + this.progressManager = CLIProgressManager.createNested(moduleName, showConsoleLogs); + return this.progressManager; + } + + /** + * Complete progress manager + */ + protected completeProgress(success: boolean = true, error?: string): void { + this.progressManager?.complete(success, error); + this.progressManager = null; + } + + protected async withLoadingSpinner(message: string, action: () => Promise): Promise { + const logConfig = configHandler.get('log') || {}; + const showConsoleLogs = logConfig.showConsoleLogs ?? false; + + if (showConsoleLogs) { + // If console logs are enabled, don't show spinner, just execute the action + return await action(); + } + return await CLIProgressManager.withLoadingSpinner(message, action); + } + get stack(): any { return this.client; } diff --git a/packages/contentstack-export/src/export/modules/content-types.ts b/packages/contentstack-export/src/export/modules/content-types.ts index ace072ec53..28c6f1cbdd 100644 --- a/packages/contentstack-export/src/export/modules/content-types.ts +++ b/packages/contentstack-export/src/export/modules/content-types.ts @@ -1,15 +1,9 @@ import * as path from 'path'; -import { - ContentstackClient, - handleAndLogError, - messageHandler, - log, - sanitizePath, -} from '@contentstack/cli-utilities'; +import { ContentstackClient, handleAndLogError, messageHandler, log, sanitizePath } from '@contentstack/cli-utilities'; import BaseClass from './base-class'; -import { fsUtil, executeTask } from '../../utils'; import { ExportConfig, ModuleClassParams } from '../../types'; +import { fsUtil, executeTask, MODULE_CONTEXTS, MODULE_NAMES } from '../../utils'; export default class ContentTypesExport extends BaseClass { private stackAPIClient: ReturnType; @@ -58,21 +52,43 @@ export default class ContentTypesExport extends BaseClass { sanitizePath(this.contentTypesConfig.dirName), ); this.contentTypes = []; - this.exportConfig.context.module = 'content-types'; + this.exportConfig.context.module = MODULE_CONTEXTS.CONTENT_TYPES; + this.currentModuleName = MODULE_NAMES[MODULE_CONTEXTS.CONTENT_TYPES]; } async start() { try { log.debug('Starting content types export process...', this.exportConfig.context); + await fsUtil.makeDirectory(this.contentTypesDirPath); - log.debug(`Created directory at path: ${this.contentTypesDirPath}`, this.exportConfig.context); + // Get content types count for progress tracking + const [totalCount] = await this.withLoadingSpinner('CONTENT-TYPES: Analyzing content types...', async () => { + const countResponse = await this.stackAPIClient + .contentType() + .query({ ...this.qs, limit: 1, include_count: true }) + .find(); + return [countResponse.count || 0]; + }); + + if (totalCount === 0) { + log.info(messageHandler.parse('CONTENT_TYPE_NO_TYPES'), this.exportConfig.context); + return; + } + + // Create simple progress manager with total count + const progress = this.createSimpleProgress(this.currentModuleName, totalCount); + + progress.updateStatus('Fetching content types...'); await this.getContentTypes(); + await this.writeContentTypes(this.contentTypes); log.success(messageHandler.parse('CONTENT_TYPE_EXPORT_COMPLETE'), this.exportConfig.context); + this.completeProgress(true); } catch (error) { handleAndLogError(error, { ...this.exportConfig.context }); + this.completeProgress(false, error?.message || 'Content types export failed'); } } @@ -86,7 +102,9 @@ export default class ContentTypesExport extends BaseClass { const contentTypeSearchResponse = await this.stackAPIClient.contentType().query(this.qs).find(); log.debug( - `Fetched ${contentTypeSearchResponse.items?.length || 0} content types out of total ${contentTypeSearchResponse.count}`, + `Fetched ${contentTypeSearchResponse.items?.length || 0} content types out of total ${ + contentTypeSearchResponse.count + }`, this.exportConfig.context, ); @@ -105,11 +123,12 @@ export default class ContentTypesExport extends BaseClass { } sanitizeAttribs(contentTypes: Record[]): Record[] { - log.debug(`Sanitizing ${contentTypes?.length} content types`, this.exportConfig.context); + log.debug(`Sanitizing ${contentTypes.length} content types`, this.exportConfig.context); const updatedContentTypes: Record[] = []; contentTypes.forEach((contentType) => { + this.progressManager?.tick(true, `content-type: ${contentType.uid}`); for (const key in contentType) { if (this.contentTypesConfig.validKeys.indexOf(key) === -1) { delete contentType[key]; @@ -121,19 +140,17 @@ export default class ContentTypesExport extends BaseClass { } async writeContentTypes(contentTypes: Record[]) { - log.debug(`Writing ${contentTypes?.length} content types to disk`, this.exportConfig.context); - - function write(contentType: Record) { - return fsUtil.writeFile( - path.join( - sanitizePath(this.contentTypesDirPath), - sanitizePath(`${contentType.uid === 'schema' ? 'schema|1' : contentType.uid}.json`), - ), - contentType, - ); - } + log.debug(`Writing ${contentTypes.length} content types to disk`, this.exportConfig.context); + + const writeWithProgress = (contentType: Record) => { + const filename = `${contentType.uid === 'schema' ? 'schema|1' : contentType.uid}.json`; + const fullPath = path.join(sanitizePath(this.contentTypesDirPath), sanitizePath(filename)); + + log.debug(`Writing content type to: ${fullPath}`, this.exportConfig.context); + return fsUtil.writeFile(fullPath, contentType); + }; - await executeTask(contentTypes, write.bind(this), { + await executeTask(contentTypes, writeWithProgress.bind(this), { concurrency: this.exportConfig.writeConcurrency, }); diff --git a/packages/contentstack-export/src/export/modules/custom-roles.ts b/packages/contentstack-export/src/export/modules/custom-roles.ts index a88e4792c9..48bb96fdcc 100644 --- a/packages/contentstack-export/src/export/modules/custom-roles.ts +++ b/packages/contentstack-export/src/export/modules/custom-roles.ts @@ -6,7 +6,13 @@ import { resolve as pResolve } from 'node:path'; import { handleAndLogError, messageHandler, log } from '@contentstack/cli-utilities'; import BaseClass from './base-class'; -import { fsUtil } from '../../utils'; +import { + fsUtil, + PROCESS_NAMES, + MODULE_CONTEXTS, + PROCESS_STATUS, + MODULE_NAMES, +} from '../../utils'; import { CustomRoleConfig, ModuleClassParams } from '../../types'; export default class ExportCustomRoles extends BaseClass { @@ -25,35 +31,92 @@ export default class ExportCustomRoles extends BaseClass { this.existingRoles = { Admin: 1, Developer: 1, 'Content Manager': 1 }; this.localesMap = {}; this.sourceLocalesMap = {}; - this.exportConfig.context.module = 'custom-roles'; + this.exportConfig.context.module = MODULE_CONTEXTS.CUSTOM_ROLES; + this.currentModuleName = MODULE_NAMES[MODULE_CONTEXTS.CUSTOM_ROLES]; } async start(): Promise { - log.debug('Starting custom roles export process...', this.exportConfig.context); + try { + log.debug('Starting custom roles export process...', this.exportConfig.context); - this.rolesFolderPath = pResolve( - this.exportConfig.data, - this.exportConfig.branchName || '', - this.customRolesConfig.dirName, - ); - log.debug(`Custom roles folder path: ${this.rolesFolderPath}`, this.exportConfig.context); - - await fsUtil.makeDirectory(this.rolesFolderPath); - log.debug('Created custom roles directory', this.exportConfig.context); - - this.customRolesLocalesFilepath = pResolve(this.rolesFolderPath, this.customRolesConfig.customRolesLocalesFileName); - log.debug(`Custom roles locales file path: ${this.customRolesLocalesFilepath}`, this.exportConfig.context); - - await this.getCustomRoles(); - await this.getLocales(); - await this.getCustomRolesLocales(); - - log.debug(`Custom roles export completed. Total custom roles: ${Object.keys(this.customRoles)?.length}`, this.exportConfig.context); + const [totalRoles, totalLocales] = await this.withLoadingSpinner( + 'CUSTOM-ROLES: Analyzing roles and locales...', + async () => { + this.rolesFolderPath = pResolve( + this.exportConfig.data, + this.exportConfig.branchName || '', + this.customRolesConfig.dirName, + ); + + await fsUtil.makeDirectory(this.rolesFolderPath); + this.customRolesLocalesFilepath = pResolve( + this.rolesFolderPath, + this.customRolesConfig.customRolesLocalesFileName, + ); + + // Get counts for progress tracking + const rolesResponse = await this.stack.role().fetchAll({ include_rules: true, include_permissions: true }); + const customRolesCount = rolesResponse?.items?.filter((role: any) => !this.existingRoles[role.name]).length; + + const localesResponse = await this.stack.locale().query({ include_count: true, limit: 1 }).find(); + const localesCount = localesResponse?.count || 0; + + return [customRolesCount, localesCount]; + }, + ); + + if (totalRoles === 0) { + log.info(messageHandler.parse('ROLES_NO_CUSTOM_ROLES'), this.exportConfig.context); + return; + } + + // Create nested progress manager + const progress = this.createNestedProgress(this.currentModuleName) + .addProcess(PROCESS_NAMES.FETCH_ROLES, totalRoles) + .addProcess(PROCESS_NAMES.FETCH_LOCALES, totalLocales) + .addProcess(PROCESS_NAMES.PROCESS_MAPPINGS, 1); + + progress + .startProcess(PROCESS_NAMES.FETCH_ROLES) + .updateStatus( + PROCESS_STATUS[PROCESS_NAMES.FETCH_ROLES].FETCHING, + PROCESS_NAMES.FETCH_ROLES, + ); + await this.getCustomRoles(); + progress.completeProcess(PROCESS_NAMES.FETCH_ROLES, true); + + progress + .startProcess(PROCESS_NAMES.FETCH_LOCALES) + .updateStatus( + PROCESS_STATUS[PROCESS_NAMES.FETCH_LOCALES].FETCHING, + PROCESS_NAMES.FETCH_LOCALES, + ); + await this.getLocales(); + progress.completeProcess(PROCESS_NAMES.FETCH_LOCALES, true); + + progress + .startProcess(PROCESS_NAMES.PROCESS_MAPPINGS) + .updateStatus( + PROCESS_STATUS[PROCESS_NAMES.PROCESS_MAPPINGS].PROCESSING, + PROCESS_NAMES.PROCESS_MAPPINGS, + ); + await this.getCustomRolesLocales(); + progress.completeProcess(PROCESS_NAMES.PROCESS_MAPPINGS, true); + + log.debug( + `Custom roles export completed. Total custom roles: ${Object.keys(this.customRoles || {}).length}`, + this.exportConfig.context, + ); + this.completeProgress(true); + } catch (error) { + handleAndLogError(error, { ...this.exportConfig.context }); + this.completeProgress(false, error?.message || 'Custom roles export failed'); + } } async getCustomRoles(): Promise { log.debug('Fetching all roles from the stack...', this.exportConfig.context); - + const roles = await this.stack .role() .fetchAll({ include_rules: true, include_permissions: true }) @@ -65,9 +128,12 @@ export default class ExportCustomRoles extends BaseClass { log.debug('Error occurred while fetching roles', this.exportConfig.context); return handleAndLogError(err, { ...this.exportConfig.context }); }); - + const customRoles = roles.items.filter((role: any) => !this.existingRoles[role.name]); - log.debug(`Found ${customRoles.length} custom roles out of ${roles.items?.length || 0} total roles`, this.exportConfig.context); + log.debug( + `Found ${customRoles.length} custom roles out of ${roles.items?.length || 0} total roles`, + this.exportConfig.context, + ); if (!customRoles.length) { log.info(messageHandler.parse('ROLES_NO_CUSTOM_ROLES'), this.exportConfig.context); @@ -75,11 +141,13 @@ export default class ExportCustomRoles extends BaseClass { } customRoles.forEach((role: any) => { - log.debug(`Processing custom role: ${role?.name} (${role?.uid})`, this.exportConfig.context); - log.info(messageHandler.parse('ROLES_EXPORTING_ROLE', role?.name), this.exportConfig.context); + log.debug(`Processing custom role: ${role.name} (${role.uid})`, this.exportConfig.context); + log.info(messageHandler.parse('ROLES_EXPORTING_ROLE', role.name), this.exportConfig.context); this.customRoles[role.uid] = role; + + this.progressManager?.tick(true, `role: ${role.name}`, null, PROCESS_NAMES.FETCH_ROLES); }); - + const customRolesFilePath = pResolve(this.rolesFolderPath, this.customRolesConfig.fileName); log.debug(`Writing custom roles to: ${customRolesFilePath}`, this.exportConfig.context); fsUtil.writeFile(customRolesFilePath, this.customRoles); @@ -87,7 +155,7 @@ export default class ExportCustomRoles extends BaseClass { async getLocales() { log.debug('Fetching locales for custom roles mapping...', this.exportConfig.context); - + const locales = await this.stack .locale() .query({}) @@ -100,25 +168,31 @@ export default class ExportCustomRoles extends BaseClass { log.debug('Error occurred while fetching locales', this.exportConfig.context); return handleAndLogError(err, { ...this.exportConfig.context }); }); - - for (const locale of locales.items) { - log.debug(`Mapping locale: ${locale?.name} (${locale?.uid})`, this.exportConfig.context); + + for (const locale of locales?.items) { + log.debug(`Mapping locale: ${locale.name} (${locale.uid})`, this.exportConfig.context); this.sourceLocalesMap[locale.uid] = locale; + + // Track progress for each locale + this.progressManager?.tick(true, `locale: ${locale.name}`, null, PROCESS_NAMES.FETCH_LOCALES); } - - log.debug(`Mapped ${Object.keys(this.sourceLocalesMap)?.length} locales`, this.exportConfig.context); + + log.debug(`Mapped ${Object.keys(this.sourceLocalesMap || {}).length} locales`, this.exportConfig.context); } async getCustomRolesLocales() { log.debug('Processing custom roles locales mapping...', this.exportConfig.context); - + for (const role of values(this.customRoles)) { const customRole = role as Record; - log.debug(`Processing locales for custom role: ${customRole?.name}`, this.exportConfig.context); - + log.debug(`Processing locales for custom role: ${customRole.name}`, this.exportConfig.context); + const rulesLocales = find(customRole.rules, (rule: any) => rule.module === 'locale'); if (rulesLocales?.locales?.length) { - log.debug(`Found ${rulesLocales.locales.length} locales for role: ${customRole?.name}`, this.exportConfig.context); + log.debug( + `Found ${rulesLocales.locales.length} locales for role: ${customRole.name}`, + this.exportConfig.context, + ); forEach(rulesLocales.locales, (locale: any) => { log.debug(`Adding locale ${locale} to custom roles mapping`, this.exportConfig.context); this.localesMap[locale] = 1; @@ -127,8 +201,8 @@ export default class ExportCustomRoles extends BaseClass { } if (keys(this.localesMap)?.length) { - log.debug(`Processing ${keys(this.localesMap)?.length} custom role locales`, this.exportConfig.context); - + log.debug(`Processing ${keys(this.localesMap).length} custom role locales`, this.exportConfig.context); + for (const locale in this.localesMap) { if (this.sourceLocalesMap[locale] !== undefined) { const sourceLocale = this.sourceLocalesMap[locale] as Record; @@ -137,11 +211,14 @@ export default class ExportCustomRoles extends BaseClass { } this.localesMap[locale] = this.sourceLocalesMap[locale]; } - + log.debug(`Writing custom roles locales to: ${this.customRolesLocalesFilepath}`, this.exportConfig.context); fsUtil.writeFile(this.customRolesLocalesFilepath, this.localesMap); } else { log.debug('No custom role locales found to process', this.exportConfig.context); } + + // Track progress for mapping completion + this.progressManager?.tick(true, 'role-locale mappings', null, PROCESS_NAMES.PROCESS_MAPPINGS); } } diff --git a/packages/contentstack-export/src/export/modules/entries.ts b/packages/contentstack-export/src/export/modules/entries.ts index 9bdf10784d..616a069f55 100644 --- a/packages/contentstack-export/src/export/modules/entries.ts +++ b/packages/contentstack-export/src/export/modules/entries.ts @@ -3,7 +3,13 @@ import { ContentstackClient, FsUtility, handleAndLogError, messageHandler, log } import { Export, ExportProjects } from '@contentstack/cli-variants'; import { sanitizePath } from '@contentstack/cli-utilities'; -import { fsUtil } from '../../utils'; +import { + fsUtil, + PROCESS_NAMES, + MODULE_CONTEXTS, + PROCESS_STATUS, + MODULE_NAMES, +} from '../../utils'; import BaseClass, { ApiOptions } from './base-class'; import { ExportConfig, ModuleClassParams } from '../../types'; @@ -52,67 +58,175 @@ export default class EntriesExport extends BaseClass { 'schema.json', ); this.projectInstance = new ExportProjects(this.exportConfig); - this.exportConfig.context.module = 'entries'; + this.exportConfig.context.module = MODULE_CONTEXTS.ENTRIES; + this.currentModuleName = MODULE_NAMES[MODULE_CONTEXTS.ENTRIES]; } async start() { try { log.debug('Starting entries export process...', this.exportConfig.context); - const locales = fsUtil.readFile(this.localesFilePath) as Array>; - if (!Array.isArray(locales) || locales?.length === 0) { - log.debug(`No locales found in ${this.localesFilePath}`, this.exportConfig.context); - } else { - log.debug(`Loaded ${locales?.length} locales from ${this.localesFilePath}`, this.exportConfig.context); - } - const contentTypes = fsUtil.readFile(this.schemaFilePath) as Array>; + // Initial analysis with loading spinner + const [locales, contentTypes, entryRequestOptions, totalEntriesCount, variantInfo] = + await this.withLoadingSpinner('ENTRIES: Analyzing content structure and entries...', async () => { + const locales = fsUtil.readFile(this.localesFilePath) as Array>; + const contentTypes = fsUtil.readFile(this.schemaFilePath) as Array>; + + if (!Array.isArray(locales) || locales?.length === 0) { + log.debug(`No locales found in ${this.localesFilePath}`, this.exportConfig.context); + } else { + log.debug(`Loaded ${locales?.length} locales from ${this.localesFilePath}`, this.exportConfig.context); + } + + if (contentTypes?.length === 0) { + log.info(messageHandler.parse('CONTENT_TYPE_NO_TYPES'), this.exportConfig.context); + return [locales, contentTypes, [], 0, null]; + } + log.debug( + `Loaded ${contentTypes?.length} content types from ${this.schemaFilePath}`, + this.exportConfig.context, + ); + + // Create entry request objects + const entryRequestOptions = this.createRequestObjects(locales, contentTypes); + log.debug( + `Created ${entryRequestOptions.length} entry request objects for processing`, + this.exportConfig.context, + ); + + // Get total entries count for better progress tracking + const totalEntriesCount = await this.getTotalEntriesCount(entryRequestOptions); + const variantInfo = await this.setupVariantExport(); + return [locales, contentTypes, entryRequestOptions, totalEntriesCount, variantInfo]; + }); + if (contentTypes?.length === 0) { - log.info(messageHandler.parse('CONTENT_TYPE_NO_TYPES'), this.exportConfig.context); return; } - log.debug(`Loaded ${contentTypes?.length} content types from ${this.schemaFilePath}`, this.exportConfig.context); - // NOTE Check if variant is enabled in specific stack - if (this.exportConfig.personalizationEnabled) { - log.debug('Personalization is enabled, checking for variant entries...', this.exportConfig.context); - let project_id; - try { - const project = await this.projectInstance.projects({ connectedStackApiKey: this.exportConfig.apiKey }); + // Create nested progress manager + const progress = this.createNestedProgress(this.currentModuleName); - if (project && project[0]?.uid) { - project_id = project[0].uid; - this.exportVariantEntry = true; - log.debug(`Found project with ID: ${project_id}, enabling variant entry export`, this.exportConfig.context); - } + // Add sub-processes + if (totalEntriesCount > 0) { + progress.addProcess(PROCESS_NAMES.ENTRIES, totalEntriesCount); - this.variantEntries = new Export.VariantEntries(Object.assign(this.exportConfig, { project_id })); - } catch (error) { - handleAndLogError(error, { ...this.exportConfig.context }); + if (this.entriesConfig.exportVersions) { + progress.addProcess(PROCESS_NAMES.ENTRY_VERSIONS, totalEntriesCount); } + } - const entryRequestOptions = this.createRequestObjects(locales, contentTypes); - log.debug( - `Created ${entryRequestOptions.length} entry request objects for processing`, - this.exportConfig.context, - ); + // Process entry collections + if (totalEntriesCount > 0) { + progress + .startProcess(PROCESS_NAMES.ENTRIES) + .updateStatus(PROCESS_STATUS[PROCESS_NAMES.ENTRIES].PROCESSING, PROCESS_NAMES.ENTRIES); + + for (let entryRequestOption of entryRequestOptions) { + try { + log.debug( + `Processing entries for content type: ${entryRequestOption.contentType}, locale: ${entryRequestOption.locale}`, + this.exportConfig.context, + ); + await this.getEntries(entryRequestOption); + this.entriesFileHelper?.completeFile(true); + + log.success( + messageHandler.parse( + 'ENTRIES_EXPORT_COMPLETE', + entryRequestOption.contentType, + entryRequestOption.locale, + ), + this.exportConfig.context, + ); + } catch (error) { + this.progressManager?.tick( + false, + `${entryRequestOption.contentType}:${entryRequestOption.locale}`, + error?.message || PROCESS_STATUS[PROCESS_NAMES.ENTRIES].FAILED, + PROCESS_NAMES.ENTRIES, + ); + throw error; + } + } + progress.completeProcess(PROCESS_NAMES.ENTRIES, true); - for (let entryRequestOption of entryRequestOptions) { - log.debug( - `Processing entries for content type: ${entryRequestOption.contentType}, locale: ${entryRequestOption.locale}`, - this.exportConfig.context, - ); - await this.getEntries(entryRequestOption); - this.entriesFileHelper?.completeFile(true); - log.success( - messageHandler.parse('ENTRIES_EXPORT_COMPLETE', entryRequestOption.contentType, entryRequestOption.locale), - this.exportConfig.context, - ); + if (this.entriesConfig.exportVersions) { + progress.completeProcess(PROCESS_NAMES.ENTRY_VERSIONS, true); + } + + if (this.exportVariantEntry && this.variantEntries) { + // Complete the variant entries export process + this.variantEntries.completeExport(); + } } + + this.completeProgress(true); log.success(messageHandler.parse('ENTRIES_EXPORT_SUCCESS'), this.exportConfig.context); } catch (error) { handleAndLogError(error, { ...this.exportConfig.context }); + this.completeProgress(false, error?.message || 'Entries export failed'); + } + } + + async getTotalEntriesCount(entryRequestOptions: Array>): Promise { + log.debug('Calculating total entries count for progress tracking...', this.exportConfig.context); + + const countPromises = entryRequestOptions.map(async (option) => { + const countQuery = { + locale: option.locale, + limit: 1, + include_count: true, + query: { locale: option.locale }, + }; + + this.applyQueryFilters(countQuery, 'entries'); + + try { + const response = await this.stackAPIClient.contentType(option.contentType).entry().query(countQuery).find(); + const count = response.count || 0; + log.debug(`Content type ${option.contentType} (${option.locale}): ${count} entries`, this.exportConfig.context); + return count; + } catch (error) { + log.debug(`Failed to get count for ${option.contentType}:${option.locale}`, this.exportConfig.context); + return 0; + } + }); + + const results = await Promise.allSettled(countPromises); + const totalCount = results.reduce((sum, result) => { + return sum + (result.status === 'fulfilled' ? result.value : 0); + }, 0); + + log.debug(`Total entries count: ${totalCount}`, this.exportConfig.context); + return totalCount; + } + + async setupVariantExport(): Promise { + if (!this.exportConfig.personalizationEnabled) { + return null; + } + + log.debug('Personalization is enabled, checking for variant entries...', this.exportConfig.context); + + try { + const project = await this.projectInstance.projects({ connectedStackApiKey: this.exportConfig.apiKey }); + + if (project && project[0]?.uid) { + const project_id = project[0].uid; + this.exportVariantEntry = true; + log.debug(`Found project with ID: ${project_id}, enabling variant entry export`, this.exportConfig.context); + + this.variantEntries = new Export.VariantEntries(Object.assign(this.exportConfig, { project_id })); + return { project_id }; + } + } catch (error) { + log.debug('Failed to setup variant export', this.exportConfig.context); + handleAndLogError(error, { ...this.exportConfig.context }); } + + return null; } createRequestObjects( @@ -211,6 +325,11 @@ export default class EntriesExport extends BaseClass { log.debug(`Writing ${entriesSearchResponse.items.length} entries to file`, this.exportConfig.context); this.entriesFileHelper.writeIntoFile(entriesSearchResponse.items, { mapKeyVal: true }); + // Track progress for individual entries + entriesSearchResponse.items.forEach((entry: any) => { + this.progressManager?.tick(true, `entry: ${entry.uid}`, null, PROCESS_NAMES.ENTRIES); + }); + if (this.entriesConfig.exportVersions) { log.debug('Exporting entry versions is enabled', this.exportConfig.context); let versionedEntryPath = path.join( @@ -231,11 +350,25 @@ export default class EntriesExport extends BaseClass { // NOTE Export all base entry specific 'variant entries' if (this.exportVariantEntry) { log.debug('Exporting variant entries for base entries', this.exportConfig.context); - await this.variantEntries.exportVariantEntry({ - locale: options.locale, - contentTypeUid: options.contentType, - entries: entriesSearchResponse.items, - }); + try { + // Set parent progress manager for variant entries + if (this.variantEntries && typeof this.variantEntries.setParentProgressManager === 'function') { + this.variantEntries.setParentProgressManager(this.progressManager); + } + + await this.variantEntries.exportVariantEntry({ + locale: options.locale, + contentTypeUid: options.contentType, + entries: entriesSearchResponse.items, + }); + + log.debug( + `Successfully exported variant entries for ${entriesSearchResponse.items.length} entries`, + this.exportConfig.context, + ); + } catch (error) { + log.debug('Failed to export variant entries', this.exportConfig.context); + } } options.skip += this.entriesConfig.limit || 100; @@ -248,6 +381,11 @@ export default class EntriesExport extends BaseClass { } log.debug(`Continuing to fetch entries with skip: ${options.skip}`, this.exportConfig.context); return await this.getEntries(options); + } else { + log.debug( + `No entries found for content type: ${options.contentType}, locale: ${options.locale}`, + this.exportConfig.context, + ); } } @@ -261,6 +399,8 @@ export default class EntriesExport extends BaseClass { const versionFilePath = path.join(sanitizePath(options.versionedEntryPath), sanitizePath(`${entry.uid}.json`)); log.debug(`Writing versioned entry to: ${versionFilePath}`, this.exportConfig.context); fsUtil.writeFile(versionFilePath, response); + // Track version progress if the process exists + this.progressManager?.tick(true, `version: ${entry.uid}`, null, PROCESS_NAMES.ENTRY_VERSIONS); log.success( messageHandler.parse('ENTRIES_VERSIONED_EXPORT_SUCCESS', options.contentType, entry.uid, options.locale), this.exportConfig.context, @@ -268,6 +408,13 @@ export default class EntriesExport extends BaseClass { }; const onReject = ({ error, apiData: { uid } = undefined }: any) => { log.debug(`Failed to fetch versioned entry for uid: ${uid}`, this.exportConfig.context); + // Track version failure if the process exists + this.progressManager?.tick( + false, + `version: ${uid}`, + error?.message || PROCESS_STATUS[PROCESS_NAMES.ENTRY_VERSIONS].FAILED, + PROCESS_NAMES.ENTRY_VERSIONS, + ); handleAndLogError( error, { diff --git a/packages/contentstack-export/src/export/modules/environments.ts b/packages/contentstack-export/src/export/modules/environments.ts index df7a0c5a47..68961f3e17 100644 --- a/packages/contentstack-export/src/export/modules/environments.ts +++ b/packages/contentstack-export/src/export/modules/environments.ts @@ -4,8 +4,8 @@ import isEmpty from 'lodash/isEmpty'; import { handleAndLogError, messageHandler, log } from '@contentstack/cli-utilities'; import BaseClass from './base-class'; -import { fsUtil } from '../../utils'; import { EnvironmentConfig, ModuleClassParams } from '../../types'; +import { fsUtil, MODULE_CONTEXTS, MODULE_NAMES } from '../../utils'; export default class ExportEnvironments extends BaseClass { private environments: Record; @@ -21,34 +21,59 @@ export default class ExportEnvironments extends BaseClass { this.environments = {}; this.environmentConfig = exportConfig.modules.environments; this.qs = { include_count: true }; - this.exportConfig.context.module = 'environments'; + this.exportConfig.context.module = MODULE_CONTEXTS.ENVIRONMENTS; + this.currentModuleName = MODULE_NAMES[MODULE_CONTEXTS.ENVIRONMENTS]; } async start(): Promise { - log.debug('Starting environment export process...', this.exportConfig.context); - this.environmentsFolderPath = pResolve( - this.exportConfig.data, - this.exportConfig.branchName || '', - this.environmentConfig.dirName, - ); - log.debug(`Environments folder path: ${this.environmentsFolderPath}`, this.exportConfig.context); + try { + log.debug('Starting environment export process...', this.exportConfig.context); - await fsUtil.makeDirectory(this.environmentsFolderPath); - log.debug('Created environments directory', this.exportConfig.context); - - await this.getEnvironments(); - log.debug(`Retrieved ${Object.keys(this.environments).length} environments`, this.exportConfig.context); + // Setup with loading spinner + const [totalCount] = await this.withLoadingSpinner('ENVIRONMENTS: Analyzing environments...', async () => { + this.environmentsFolderPath = pResolve( + this.exportConfig.data, + this.exportConfig.branchName || '', + this.environmentConfig.dirName, + ); + await fsUtil.makeDirectory(this.environmentsFolderPath); + log.debug(`Environments folder path: ${this.environmentsFolderPath}`, this.exportConfig.context); - if (this.environments === undefined || isEmpty(this.environments)) { - log.info(messageHandler.parse('ENVIRONMENT_NOT_FOUND'), this.exportConfig.context); - } else { - const environmentsFilePath = pResolve(this.environmentsFolderPath, this.environmentConfig.fileName); - log.debug(`Writing environments to: ${environmentsFilePath}`, this.exportConfig.context); - fsUtil.writeFile(environmentsFilePath, this.environments); - log.success( - messageHandler.parse('ENVIRONMENT_EXPORT_COMPLETE', Object.keys(this.environments).length), - this.exportConfig.context, - ); + // Get count for progress tracking + const countResponse = await this.stack + .environment() + .query({ ...this.qs, include_count: true, limit: 1 }) + .find(); + return [countResponse.count || 0]; + }); + + if (totalCount === 0) { + log.info(messageHandler.parse('ENVIRONMENT_NOT_FOUND'), this.exportConfig.context); + return; + } + + // Create simple progress manager with total count + const progress = this.createSimpleProgress(this.currentModuleName, totalCount); + + progress.updateStatus('Fetching environments...'); + await this.getEnvironments(); + log.debug(`Retrieved ${Object.keys(this.environments || {}).length} environments`, this.exportConfig.context); + + if (this.environments === undefined || isEmpty(this.environments)) { + log.info(messageHandler.parse('ENVIRONMENT_NOT_FOUND'), this.exportConfig.context); + } else { + const environmentsFilePath = pResolve(this.environmentsFolderPath, this.environmentConfig.fileName); + log.debug(`Writing environments to: ${environmentsFilePath}`, this.exportConfig.context); + fsUtil.writeFile(environmentsFilePath, this.environments); + log.success( + messageHandler.parse('ENVIRONMENT_EXPORT_COMPLETE', Object.keys(this.environments || {}).length), + this.exportConfig.context, + ); + } + this.completeProgress(true); + } catch (error) { + handleAndLogError(error, { ...this.exportConfig.context }); + this.completeProgress(false, error?.message || 'Environments export failed'); } } @@ -59,9 +84,9 @@ export default class ExportEnvironments extends BaseClass { } else { log.debug('Fetching environments with initial query', this.exportConfig.context); } - + log.debug(`Query parameters: ${JSON.stringify(this.qs)}`, this.exportConfig.context); - + await this.stack .environment() .query(this.qs) @@ -69,7 +94,7 @@ export default class ExportEnvironments extends BaseClass { .then(async (data: any) => { const { items, count } = data; log.debug(`Fetched ${items?.length || 0} environments out of total ${count}`, this.exportConfig.context); - + if (items?.length) { log.debug(`Processing ${items.length} environments`, this.exportConfig.context); this.sanitizeAttribs(items); @@ -92,16 +117,21 @@ export default class ExportEnvironments extends BaseClass { sanitizeAttribs(environments: Record[]) { log.debug(`Sanitizing ${environments.length} environments`, this.exportConfig.context); - + for (let index = 0; index < environments?.length; index++) { - const extUid = environments[index].uid; + const envUID = environments[index].uid; const envName = environments[index]?.name; - log.debug(`Processing environment: ${envName} (${extUid})`, this.exportConfig.context); - - this.environments[extUid] = omit(environments[index], ['ACL']); - log.success(messageHandler.parse('ENVIRONMENT_EXPORT_SUCCESS', envName ), this.exportConfig.context); + log.debug(`Processing environment: ${envName} (${envUID})`, this.exportConfig.context); + + this.environments[envUID] = omit(environments[index], ['ACL']); + // Track progress for each environment + this.progressManager?.tick(true, `environment: ${envName || envUID}`); + log.success(messageHandler.parse('ENVIRONMENT_EXPORT_SUCCESS', envName), this.exportConfig.context); } - - log.debug(`Sanitization complete. Total environments processed: ${Object.keys(this.environments).length}`, this.exportConfig.context); + + log.debug( + `Sanitization complete. Total environments processed: ${Object.keys(this.environments || {}).length}`, + this.exportConfig.context, + ); } } diff --git a/packages/contentstack-export/src/export/modules/extensions.ts b/packages/contentstack-export/src/export/modules/extensions.ts index beb50325ca..7665aa30c9 100644 --- a/packages/contentstack-export/src/export/modules/extensions.ts +++ b/packages/contentstack-export/src/export/modules/extensions.ts @@ -4,8 +4,8 @@ import { resolve as pResolve } from 'node:path'; import { handleAndLogError, messageHandler, log } from '@contentstack/cli-utilities'; import BaseClass from './base-class'; -import { fsUtil } from '../../utils'; import { ExtensionsConfig, ModuleClassParams } from '../../types'; +import { fsUtil, MODULE_CONTEXTS, MODULE_NAMES } from '../../utils'; export default class ExportExtensions extends BaseClass { private extensionsFolderPath: string; @@ -22,35 +22,59 @@ export default class ExportExtensions extends BaseClass { this.extensionConfig = exportConfig.modules.extensions; this.qs = { include_count: true }; this.applyQueryFilters(this.qs, 'extensions'); - this.exportConfig.context.module = 'extensions'; + this.exportConfig.context.module = MODULE_CONTEXTS.EXTENSIONS; + this.currentModuleName = MODULE_NAMES[MODULE_CONTEXTS.EXTENSIONS]; } async start(): Promise { - log.debug('Starting extensions export process...', this.exportConfig.context); - - this.extensionsFolderPath = pResolve( - this.exportConfig.data, - this.exportConfig.branchName || '', - this.extensionConfig.dirName, - ); - log.debug(`Extensions folder path: ${this.extensionsFolderPath}`, this.exportConfig.context); + try { + log.debug('Starting extensions export process...', this.exportConfig.context); - await fsUtil.makeDirectory(this.extensionsFolderPath); - log.debug('Created extensions directory', this.exportConfig.context); - - await this.getExtensions(); - log.debug(`Retrieved ${Object.keys(this.extensions).length} extensions`, this.exportConfig.context); + // Setup with loading spinner + const [totalCount] = await this.withLoadingSpinner('EXTENSIONS: Analyzing extensions...', async () => { + this.extensionsFolderPath = pResolve( + this.exportConfig.data, + this.exportConfig.branchName || '', + this.extensionConfig.dirName, + ); + await fsUtil.makeDirectory(this.extensionsFolderPath); + log.debug(`Extensions folder path: ${this.extensionsFolderPath}`, this.exportConfig.context); - if (this.extensions === undefined || isEmpty(this.extensions)) { - log.info(messageHandler.parse('EXTENSION_NOT_FOUND'), this.exportConfig.context); - } else { - const extensionsFilePath = pResolve(this.extensionsFolderPath, this.extensionConfig.fileName); - log.debug(`Writing extensions to: ${extensionsFilePath}`, this.exportConfig.context); - fsUtil.writeFile(extensionsFilePath, this.extensions); - log.success( - messageHandler.parse('EXTENSION_EXPORT_COMPLETE', Object.keys(this.extensions).length ), - this.exportConfig.context, - ); + // Get count for progress tracking + const countResponse = await this.stack + .extension() + .query({ ...this.qs, include_count: true, limit: 1 }) + .find(); + return [countResponse.count || 0]; + }); + + if (totalCount === 0) { + log.info(messageHandler.parse('EXTENSION_NOT_FOUND'), this.exportConfig.context); + return; + } + + // Create simple progress manager with total count + const progress = this.createSimpleProgress(this.currentModuleName, totalCount); + + progress.updateStatus('Fetching extensions...'); + await this.getExtensions(); + log.debug(`Retrieved ${Object.keys(this.extensions || {}).length} extensions`, this.exportConfig.context); + + if (this.extensions === undefined || isEmpty(this.extensions)) { + log.info(messageHandler.parse('EXTENSION_NOT_FOUND'), this.exportConfig.context); + } else { + const extensionsFilePath = pResolve(this.extensionsFolderPath, this.extensionConfig.fileName); + log.debug(`Writing extensions to: ${extensionsFilePath}`, this.exportConfig.context); + fsUtil.writeFile(extensionsFilePath, this.extensions); + log.success( + messageHandler.parse('EXTENSION_EXPORT_COMPLETE', Object.keys(this.extensions || {}).length), + this.exportConfig.context, + ); + } + this.completeProgress(true); + } catch (error) { + handleAndLogError(error, { ...this.exportConfig.context }); + this.completeProgress(false, error?.message || 'Extensions export failed'); } } @@ -61,9 +85,9 @@ export default class ExportExtensions extends BaseClass { } else { log.debug('Fetching extensions with initial query', this.exportConfig.context); } - + log.debug(`Query parameters: ${JSON.stringify(this.qs)}`, this.exportConfig.context); - + await this.stack .extension() .query(this.qs) @@ -71,7 +95,7 @@ export default class ExportExtensions extends BaseClass { .then(async (data: any) => { const { items, count } = data; log.debug(`Fetched ${items?.length || 0} extensions out of total ${count}`, this.exportConfig.context); - + if (items?.length) { log.debug(`Processing ${items.length} extensions`, this.exportConfig.context); this.sanitizeAttribs(items); @@ -94,16 +118,21 @@ export default class ExportExtensions extends BaseClass { sanitizeAttribs(extensions: Record[]) { log.debug(`Sanitizing ${extensions.length} extensions`, this.exportConfig.context); - + for (let index = 0; index < extensions?.length; index++) { const extUid = extensions[index].uid; const extTitle = extensions[index]?.title; log.debug(`Processing extension: ${extTitle} (${extUid})`, this.exportConfig.context); - + this.extensions[extUid] = omit(extensions[index], ['SYS_ACL']); + // Track progress for each extension + this.progressManager?.tick(true, `extension: ${extTitle || extUid}`); log.info(messageHandler.parse('EXTENSION_EXPORT_SUCCESS', extTitle), this.exportConfig.context); } - - log.debug(`Sanitization complete. Total extensions processed: ${Object.keys(this.extensions).length}`, this.exportConfig.context); + + log.debug( + `Sanitization complete. Total extensions processed: ${Object.keys(this.extensions || {}).length}`, + this.exportConfig.context, + ); } } diff --git a/packages/contentstack-export/src/export/modules/global-fields.ts b/packages/contentstack-export/src/export/modules/global-fields.ts index c7472e982d..0d74f8da3b 100644 --- a/packages/contentstack-export/src/export/modules/global-fields.ts +++ b/packages/contentstack-export/src/export/modules/global-fields.ts @@ -1,15 +1,9 @@ import * as path from 'path'; -import { - ContentstackClient, - handleAndLogError, - messageHandler, - log, - sanitizePath, -} from '@contentstack/cli-utilities'; - -import { fsUtil } from '../../utils'; -import { ExportConfig, ModuleClassParams } from '../../types'; +import { ContentstackClient, handleAndLogError, messageHandler, log, sanitizePath } from '@contentstack/cli-utilities'; + import BaseClass from './base-class'; +import { ExportConfig, ModuleClassParams } from '../../types'; +import { fsUtil, MODULE_CONTEXTS, MODULE_NAMES } from '../../utils'; export default class GlobalFieldsExport extends BaseClass { private stackAPIClient: ReturnType; @@ -50,30 +44,49 @@ export default class GlobalFieldsExport extends BaseClass { ); this.globalFields = []; this.applyQueryFilters(this.qs, 'global-fields'); - this.exportConfig.context.module = 'global-fields'; + this.exportConfig.context.module = MODULE_CONTEXTS.GLOBAL_FIELDS; + this.currentModuleName = MODULE_NAMES[MODULE_CONTEXTS.GLOBAL_FIELDS]; } async start() { try { log.debug('Starting global fields export process...', this.exportConfig.context); - log.debug(`Global fields directory path: ${this.globalFieldsDirPath}`, this.exportConfig.context); - await fsUtil.makeDirectory(this.globalFieldsDirPath); - log.debug('Created global fields directory', this.exportConfig.context); - + + // Get global fields count and setup with loading spinner + const [totalCount] = await this.withLoadingSpinner('GLOBAL-FIELDS: Analyzing global fields...', async () => { + await fsUtil.makeDirectory(this.globalFieldsDirPath); + const countResponse = await this.stackAPIClient + .globalField() + .query({ ...this.qs, include_count: true, limit: 1 }) + .find(); + return [countResponse.count || 0]; + }); + + if (totalCount === 0) { + log.info(messageHandler.parse('GLOBAL_FIELDS_NOT_FOUND'), this.exportConfig.context); + return; + } + + // Create simple progress manager for global fields + const progress = this.createSimpleProgress(this.currentModuleName, totalCount); + + progress.updateStatus('Fetching global fields...'); await this.getGlobalFields(); - log.debug(`Retrieved ${this.globalFields.length} global fields`, this.exportConfig.context); - + const globalFieldsFilePath = path.join(this.globalFieldsDirPath, this.globalFieldsConfig.fileName); log.debug(`Writing global fields to: ${globalFieldsFilePath}`, this.exportConfig.context); fsUtil.writeFile(globalFieldsFilePath, this.globalFields); - + log.success( messageHandler.parse('GLOBAL_FIELDS_EXPORT_COMPLETE', this.globalFields.length), this.exportConfig.context, ); + + this.completeProgress(true); } catch (error) { log.debug('Error occurred during global fields export', this.exportConfig.context); handleAndLogError(error, { ...this.exportConfig.context }); + this.completeProgress(false, error?.message || 'Global fields export failed'); } } @@ -83,11 +96,16 @@ export default class GlobalFieldsExport extends BaseClass { log.debug(`Fetching global fields with skip: ${skip}`, this.exportConfig.context); } log.debug(`Query parameters: ${JSON.stringify(this.qs)}`, this.exportConfig.context); - + let globalFieldsFetchResponse = await this.stackAPIClient.globalField({ api_version: '3.2' }).query(this.qs).find(); - - log.debug(`Fetched ${globalFieldsFetchResponse.items?.length || 0} global fields out of total ${globalFieldsFetchResponse.count}`, this.exportConfig.context); - + + log.debug( + `Fetched ${globalFieldsFetchResponse.items?.length || 0} global fields out of total ${ + globalFieldsFetchResponse.count + }`, + this.exportConfig.context, + ); + if (Array.isArray(globalFieldsFetchResponse.items) && globalFieldsFetchResponse.items.length > 0) { log.debug(`Processing ${globalFieldsFetchResponse.items.length} global fields`, this.exportConfig.context); this.sanitizeAttribs(globalFieldsFetchResponse.items); @@ -105,18 +123,24 @@ export default class GlobalFieldsExport extends BaseClass { sanitizeAttribs(globalFields: Record[]) { log.debug(`Sanitizing ${globalFields.length} global fields`, this.exportConfig.context); - + globalFields.forEach((globalField: Record) => { log.debug(`Processing global field: ${globalField.uid || 'unknown'}`, this.exportConfig.context); - + for (let key in globalField) { if (this.globalFieldsConfig.validKeys.indexOf(key) === -1) { delete globalField[key]; } } this.globalFields.push(globalField); + + // Track progress for each global field + this.progressManager?.tick(true, `global-field: ${globalField.uid}`); }); - - log.debug(`Sanitization complete. Total global fields processed: ${this.globalFields.length}`, this.exportConfig.context); + + log.debug( + `Sanitization complete. Total global fields processed: ${this.globalFields.length}`, + this.exportConfig.context, + ); } } diff --git a/packages/contentstack-export/src/export/modules/index.ts b/packages/contentstack-export/src/export/modules/index.ts index f13bc4fa3d..7de75d860d 100644 --- a/packages/contentstack-export/src/export/modules/index.ts +++ b/packages/contentstack-export/src/export/modules/index.ts @@ -1,5 +1,6 @@ import { handleAndLogError } from '@contentstack/cli-utilities'; import { ModuleClassParams } from '../../types'; +import '../../utils/progress-strategy-registry'; export default async function startModuleExport(modulePayload: ModuleClassParams) { try { diff --git a/packages/contentstack-export/src/export/modules/labels.ts b/packages/contentstack-export/src/export/modules/labels.ts index 194f2e124c..aa9edab2bf 100644 --- a/packages/contentstack-export/src/export/modules/labels.ts +++ b/packages/contentstack-export/src/export/modules/labels.ts @@ -4,8 +4,8 @@ import { resolve as pResolve } from 'node:path'; import { handleAndLogError, messageHandler, log } from '@contentstack/cli-utilities'; import BaseClass from './base-class'; -import { fsUtil } from '../../utils'; import { LabelConfig, ModuleClassParams } from '../../types'; +import { fsUtil, MODULE_CONTEXTS, MODULE_NAMES } from '../../utils'; export default class ExportLabels extends BaseClass { private labels: Record>; @@ -21,35 +21,61 @@ export default class ExportLabels extends BaseClass { this.labels = {}; this.labelConfig = exportConfig.modules.labels; this.qs = { include_count: true }; - this.exportConfig.context.module = 'labels'; + this.exportConfig.context.module = MODULE_CONTEXTS.LABELS; + this.currentModuleName = MODULE_NAMES[MODULE_CONTEXTS.LABELS]; } async start(): Promise { - log.debug('Starting labels export process...', this.exportConfig.context); - - this.labelsFolderPath = pResolve( - this.exportConfig.data, - this.exportConfig.branchName || '', - this.labelConfig.dirName, - ); - log.debug(`Labels folder path: ${this.labelsFolderPath}`, this.exportConfig.context); - - await fsUtil.makeDirectory(this.labelsFolderPath); - log.debug('Created labels directory', this.exportConfig.context); - - await this.getLabels(); - log.debug(`Retrieved ${Object.keys(this.labels).length} labels`, this.exportConfig.context); - - if (this.labels === undefined || isEmpty(this.labels)) { - log.info(messageHandler.parse('LABELS_NOT_FOUND'), this.exportConfig.context); - } else { - const labelsFilePath = pResolve(this.labelsFolderPath, this.labelConfig.fileName); - log.debug(`Writing labels to: ${labelsFilePath}`, this.exportConfig.context); - fsUtil.writeFile(labelsFilePath, this.labels); - log.success( - messageHandler.parse('LABELS_EXPORT_COMPLETE', Object.keys(this.labels).length), - this.exportConfig.context, - ); + try { + log.debug('Starting labels export process...', this.exportConfig.context); + + // Setup with loading spinner + const [totalCount] = await this.withLoadingSpinner('LABELS: Analyzing labels...', async () => { + this.labelsFolderPath = pResolve( + this.exportConfig.data, + this.exportConfig.branchName || '', + this.labelConfig.dirName, + ); + + await fsUtil.makeDirectory(this.labelsFolderPath); + log.debug(`Labels folder path: ${this.labelsFolderPath}`, this.exportConfig.context); + + // Get count for progress tracking + const countResponse = await this.stack + .label() + .query({ ...this.qs, include_count: true, limit: 1 }) + .find(); + return [countResponse.count || 0]; + }); + + if (totalCount === 0) { + log.info(messageHandler.parse('LABELS_NOT_FOUND'), this.exportConfig.context); + return; + } + + // Create simple progress manager with total count + const progress = this.createSimpleProgress(this.currentModuleName, totalCount); + + progress.updateStatus('Fetching labels...'); + await this.getLabels(); + log.debug(`Retrieved ${Object.keys(this.labels || {}).length} labels`, this.exportConfig.context); + + if (this.labels === undefined || isEmpty(this.labels)) { + log.info(messageHandler.parse('LABELS_NOT_FOUND'), this.exportConfig.context); + } else { + const labelsFilePath = pResolve(this.labelsFolderPath, this.labelConfig.fileName); + log.debug(`Writing labels to: ${labelsFilePath}`, this.exportConfig.context); + fsUtil.writeFile(labelsFilePath, this.labels); + log.success( + messageHandler.parse('LABELS_EXPORT_COMPLETE', Object.keys(this.labels || {}).length), + this.exportConfig.context, + ); + } + + this.completeProgress(true); + } catch (error) { + handleAndLogError(error, { ...this.exportConfig.context }); + this.completeProgress(false, error?.message || 'Labels export failed'); } } @@ -60,9 +86,9 @@ export default class ExportLabels extends BaseClass { } else { log.debug('Fetching labels with initial query', this.exportConfig.context); } - + log.debug(`Query parameters: ${JSON.stringify(this.qs)}`, this.exportConfig.context); - + await this.stack .label() .query(this.qs) @@ -70,7 +96,7 @@ export default class ExportLabels extends BaseClass { .then(async (data: any) => { const { items, count } = data; log.debug(`Fetched ${items?.length || 0} labels out of total ${count}`, this.exportConfig.context); - + if (items?.length) { log.debug(`Processing ${items.length} labels`, this.exportConfig.context); this.sanitizeAttribs(items); @@ -86,6 +112,7 @@ export default class ExportLabels extends BaseClass { } }) .catch((error: any) => { + this.progressManager?.tick(false, 'labels', error?.message || 'Failed to export labels'); log.debug('Error occurred while fetching labels', this.exportConfig.context); handleAndLogError(error, { ...this.exportConfig.context }); }); @@ -93,16 +120,22 @@ export default class ExportLabels extends BaseClass { sanitizeAttribs(labels: Record[]) { log.debug(`Sanitizing ${labels.length} labels`, this.exportConfig.context); - + for (let index = 0; index < labels?.length; index++) { const labelUid = labels[index].uid; const labelName = labels[index]?.name; log.debug(`Processing label: ${labelName} (${labelUid})`, this.exportConfig.context); - + this.labels[labelUid] = omit(labels[index], this.labelConfig.invalidKeys); log.info(messageHandler.parse('LABEL_EXPORT_SUCCESS', labelName), this.exportConfig.context); + + // Track progress for each label + this.progressManager?.tick(true, `label: ${labelName}`); } - - log.debug(`Sanitization complete. Total labels processed: ${Object.keys(this.labels).length}`, this.exportConfig.context); + + log.debug( + `Sanitization complete. Total labels processed: ${Object.keys(this.labels).length}`, + this.exportConfig.context, + ); } } diff --git a/packages/contentstack-export/src/export/modules/locales.ts b/packages/contentstack-export/src/export/modules/locales.ts index c441285215..58cc3960ee 100644 --- a/packages/contentstack-export/src/export/modules/locales.ts +++ b/packages/contentstack-export/src/export/modules/locales.ts @@ -1,15 +1,9 @@ import * as path from 'path'; -import { - ContentstackClient, - handleAndLogError, - messageHandler, - log, - sanitizePath, -} from '@contentstack/cli-utilities'; - -import { fsUtil } from '../../utils'; +import { ContentstackClient, handleAndLogError, messageHandler, log, sanitizePath } from '@contentstack/cli-utilities'; + import BaseClass from './base-class'; import { ExportConfig, ModuleClassParams } from '../../types'; +import { fsUtil, MODULE_CONTEXTS, MODULE_NAMES } from '../../utils'; export default class LocaleExport extends BaseClass { private stackAPIClient: ReturnType; @@ -54,39 +48,56 @@ export default class LocaleExport extends BaseClass { ); this.locales = {}; this.masterLocale = {}; - this.exportConfig.context.module = 'locales'; + this.exportConfig.context.module = MODULE_CONTEXTS.LOCALES; + this.currentModuleName = MODULE_NAMES[MODULE_CONTEXTS.LOCALES]; } async start() { try { log.debug('Starting locales export process...', this.exportConfig.context); - log.debug(`Locales path: ${this.localesPath}`, this.exportConfig.context); - - await fsUtil.makeDirectory(this.localesPath); - log.debug('Created locales directory', this.exportConfig.context); - + + // Get locales count and setup with loading spinner + const [totalCount] = await this.withLoadingSpinner('LOCALES: Analyzing locales...', async () => { + await fsUtil.makeDirectory(this.localesPath); + log.debug(`Locales path: ${this.localesPath}`, this.exportConfig.context); + const countResponse = await this.stackAPIClient + .locale() + .query({ ...this.qs, include_count: true, limit: 1 }) + .find(); + return [countResponse.count || 0]; + }); + + // Create simple progress manager with total count + const progress = this.createSimpleProgress(this.currentModuleName, totalCount); + + // Fetch locales + progress.updateStatus('Fetching locale definitions...'); await this.getLocales(); - log.debug(`Retrieved ${Object.keys(this.locales).length} locales and ${Object.keys(this.masterLocale).length} master locales`, this.exportConfig.context); - + log.debug( + `Retrieved ${Object.keys(this.locales || {}).length} locales and ${ + Object.keys(this.masterLocale || {}).length + } master locales`, + this.exportConfig.context, + ); + const localesFilePath = path.join(this.localesPath, this.localeConfig.fileName); const masterLocaleFilePath = path.join(this.localesPath, this.masterLocaleConfig.fileName); - log.debug(`Writing locales to: ${localesFilePath}`, this.exportConfig.context); fsUtil.writeFile(localesFilePath, this.locales); - log.debug(`Writing master locale to: ${masterLocaleFilePath}`, this.exportConfig.context); fsUtil.writeFile(masterLocaleFilePath, this.masterLocale); - log.success( messageHandler.parse( 'LOCALES_EXPORT_COMPLETE', - Object.keys(this.locales).length, - Object.keys(this.masterLocale).length, + Object.keys(this.locales || {}).length, + Object.keys(this.masterLocale || {}).length, ), this.exportConfig.context, ); + this.completeProgress(true); } catch (error) { handleAndLogError(error, { ...this.exportConfig.context }); + this.completeProgress(false, error?.message || 'Locales export failed'); throw error; } } @@ -97,15 +108,18 @@ export default class LocaleExport extends BaseClass { log.debug(`Fetching locales with skip: ${skip}`, this.exportConfig.context); } log.debug(`Query parameters: ${JSON.stringify(this.qs)}`, this.exportConfig.context); - + let localesFetchResponse = await this.stackAPIClient.locale().query(this.qs).find(); - - log.debug(`Fetched ${localesFetchResponse.items?.length || 0} locales out of total ${localesFetchResponse.count}`, this.exportConfig.context); - + + log.debug( + `Fetched ${localesFetchResponse.items?.length || 0} locales out of total ${localesFetchResponse.count}`, + this.exportConfig.context, + ); + if (Array.isArray(localesFetchResponse.items) && localesFetchResponse.items.length > 0) { log.debug(`Processing ${localesFetchResponse.items.length} locales`, this.exportConfig.context); this.sanitizeAttribs(localesFetchResponse.items); - + skip += this.localeConfig.limit || 100; if (skip > localesFetchResponse.count) { log.debug('Completed fetching all locales', this.exportConfig.context); @@ -120,23 +134,32 @@ export default class LocaleExport extends BaseClass { sanitizeAttribs(locales: Record[]) { log.debug(`Sanitizing ${locales.length} locales`, this.exportConfig.context); - + locales.forEach((locale: Record) => { for (let key in locale) { if (this.localeConfig.requiredKeys.indexOf(key) === -1) { delete locale[key]; } } - - if (locale?.code === this.exportConfig?.master_locale?.code) { + let uid = locale.uid; + if (this.exportConfig?.master_locale?.code === locale?.code) { log.debug(`Adding locale ${locale.uid} to master locale`, this.exportConfig.context); - this.masterLocale[locale.uid] = locale; + this.masterLocale[uid] = locale; + // Track progress for master locale + this.progressManager?.tick(true, `master-locale: ${uid}`); } else { log.debug(`Adding locale ${locale.uid} to regular locales`, this.exportConfig.context); - this.locales[locale.uid] = locale; + this.locales[uid] = locale; + // Track progress for regular locale + this.progressManager?.tick(true, `locale: ${uid}`); } }); - - log.debug(`Sanitization complete. Master locales: ${Object.keys(this.masterLocale).length}, Regular locales: ${Object.keys(this.locales).length}`, this.exportConfig.context); + + log.debug( + `Sanitization complete. Master locales: ${Object.keys(this.masterLocale || {}).length}, Regular locales: ${ + Object.keys(this.locales || {}).length + }`, + this.exportConfig.context, + ); } } diff --git a/packages/contentstack-export/src/export/modules/marketplace-apps.ts b/packages/contentstack-export/src/export/modules/marketplace-apps.ts index 1158fa29b6..9aa5854ef4 100644 --- a/packages/contentstack-export/src/export/modules/marketplace-apps.ts +++ b/packages/contentstack-export/src/export/modules/marketplace-apps.ts @@ -17,10 +17,21 @@ import { handleAndLogError, } from '@contentstack/cli-utilities'; -import { fsUtil, getOrgUid, createNodeCryptoInstance, getDeveloperHubUrl } from '../../utils'; +import BaseClass from './base-class'; +import { + fsUtil, + getOrgUid, + createNodeCryptoInstance, + getDeveloperHubUrl, + MODULE_CONTEXTS, + MODULE_NAMES, + PROCESS_NAMES, + PROCESS_STATUS, + askEncryptionKey, +} from '../../utils'; import { ModuleClassParams, MarketplaceAppsConfig, ExportConfig, Installation, Manifest } from '../../types'; -export default class ExportMarketplaceApps { +export default class ExportMarketplaceApps extends BaseClass { protected marketplaceAppConfig: MarketplaceAppsConfig; protected installedApps: Installation[] = []; public developerHubBaseUrl: string; @@ -31,36 +42,97 @@ export default class ExportMarketplaceApps { public command: Command; public query: Record; - constructor({ exportConfig }: Omit) { + constructor({ exportConfig, stackAPIClient }: ModuleClassParams) { + super({ exportConfig, stackAPIClient }); this.exportConfig = exportConfig; this.marketplaceAppConfig = exportConfig.modules.marketplace_apps; - this.exportConfig.context.module = 'marketplace-apps'; + this.exportConfig.context.module = MODULE_CONTEXTS.MARKETPLACE_APPS; + this.currentModuleName = MODULE_NAMES[MODULE_CONTEXTS.MARKETPLACE_APPS]; } async start(): Promise { - log.debug('Starting marketplace apps export process...', this.exportConfig.context); - - if (!isAuthenticated()) { - cliux.print( - 'WARNING!!! To export Marketplace apps, you must be logged in. Please check csdx auth:login --help to log in', - { color: 'yellow' }, - ); - return Promise.resolve(); + try { + log.debug('Starting marketplace apps export process...', this.exportConfig.context); + + if (!isAuthenticated()) { + cliux.print( + 'WARNING!!! To export Marketplace apps, you must be logged in. Please check csdx auth:login --help to log in', + { color: 'yellow' }, + ); + return Promise.resolve(); + } + + // Initial setup and analysis with loading spinner + const [appsCount] = await this.withLoadingSpinner('MARKETPLACE-APPS: Analyzing marketplace apps...', async () => { + await this.setupPaths(); + const appsCount = await this.getAppsCount(); + return [appsCount]; + }); + + if (appsCount === 0) { + log.info(messageHandler.parse('MARKETPLACE_APPS_NOT_FOUND'), this.exportConfig.context); + return; + } + + // Handle encryption key prompt BEFORE starting progress + if (!this.exportConfig.forceStopMarketplaceAppsPrompt) { + log.debug('Validating security configuration before progress start', this.exportConfig.context); + cliux.print('\n'); + await askEncryptionKey(this.exportConfig); + this.nodeCrypto = await createNodeCryptoInstance(this.exportConfig); + + cliux.print('\n'); + } + + // Create nested progress manager + const progress = this.createNestedProgress(this.currentModuleName); + + // Add processes based on what we found + progress.addProcess(PROCESS_NAMES.FETCH_APPS, appsCount); + progress.addProcess(PROCESS_NAMES.FETCH_CONFIG_MANIFEST, appsCount); // Manifests and configurations + + // Fetch stack specific apps + progress + .startProcess(PROCESS_NAMES.FETCH_APPS) + .updateStatus(PROCESS_STATUS[PROCESS_NAMES.FETCH_APPS].FETCHING, PROCESS_NAMES.FETCH_APPS); + await this.exportApps(); + progress.completeProcess(PROCESS_NAMES.FETCH_APPS, true); + + // Process apps (manifests and configurations) + if (this.installedApps.length > 0) { + progress + .startProcess(PROCESS_NAMES.FETCH_CONFIG_MANIFEST) + .updateStatus( + PROCESS_STATUS[PROCESS_NAMES.FETCH_CONFIG_MANIFEST].PROCESSING, + PROCESS_NAMES.FETCH_CONFIG_MANIFEST, + ); + await this.getAppManifestAndAppConfig(); + progress.completeProcess(PROCESS_NAMES.FETCH_CONFIG_MANIFEST, true); + } + + this.completeProgress(true); + log.success('Marketplace apps export completed successfully', this.exportConfig.context); + } catch (error) { + log.debug('Error occurred during marketplace apps export', this.exportConfig.context); + handleAndLogError(error, { ...this.exportConfig.context }); + this.completeProgress(false, error?.message || 'Marketplace apps export failed'); } + } + async setupPaths(): Promise { this.marketplaceAppPath = pResolve( this.exportConfig.data, this.exportConfig.branchName || '', this.marketplaceAppConfig.dirName, ); log.debug(`Marketplace apps folder path: ${this.marketplaceAppPath}`, this.exportConfig.context); - + await fsUtil.makeDirectory(this.marketplaceAppPath); log.debug('Created marketplace apps directory', this.exportConfig.context); - + this.developerHubBaseUrl = this.exportConfig.developerHubBaseUrl || (await getDeveloperHubUrl(this.exportConfig)); log.debug(`Developer hub base URL: ${this.developerHubBaseUrl}`, this.exportConfig.context); - + this.exportConfig.org_uid = await getOrgUid(this.exportConfig); this.query = { target_uids: this.exportConfig.source_stack }; log.debug(`Organization UID: ${this.exportConfig.org_uid}`, this.exportConfig.context); @@ -69,9 +141,34 @@ export default class ExportMarketplaceApps { const host = this.developerHubBaseUrl.split('://').pop(); log.debug(`Initializing marketplace SDK with host: ${host}`, this.exportConfig.context); this.appSdk = await marketplaceSDKClient({ host }); + } + + async getAppsCount(): Promise { + log.debug('Fetching marketplace apps count...', this.exportConfig.context); + + try { + const externalQuery = this.exportConfig.query?.modules['marketplace-apps']; + if (externalQuery) { + if (externalQuery.app_uid?.$in?.length > 0) { + this.query.app_uids = externalQuery.app_uid.$in.join(','); + } + if (externalQuery.installation_uid?.$in?.length > 0) { + this.query.installation_uids = externalQuery.installation_uid?.$in?.join(','); + } + } + + const collection = await this.appSdk + .marketplace(this.exportConfig.org_uid) + .installation() + .fetchAll({ ...this.query, limit: 1, skip: 0 }); - await this.exportApps(); - log.debug('Marketplace apps export process completed', this.exportConfig.context); + const count = collection?.count || 0; + log.debug(`Total marketplace apps count: ${count}`, this.exportConfig.context); + return count; + } catch (error) { + log.debug('Failed to fetch marketplace apps count', this.exportConfig.context); + return 0; + } } /** @@ -80,22 +177,9 @@ export default class ExportMarketplaceApps { */ async exportApps(): Promise { log.debug('Starting apps export process...', this.exportConfig.context); - // currently support only app_uids or installation_uids - const externalQuery = this.exportConfig.query?.modules['marketplace-apps']; - if (externalQuery) { - if (externalQuery.app_uid?.$in?.length > 0) { - this.query.app_uids = externalQuery.app_uid.$in.join(','); - } - if (externalQuery.installation_uid?.$in?.length > 0) { - this.query.installation_uids = externalQuery.installation_uid?.$in?.join(','); - } - } - + await this.getStackSpecificApps(); log.debug(`Retrieved ${this.installedApps.length} stack-specific apps`, this.exportConfig.context); - - await this.getAppManifestAndAppConfig(); - log.debug('Completed app manifest and configuration processing', this.exportConfig.context); if (!this.nodeCrypto && find(this.installedApps, (app) => !isEmpty(app.configuration))) { log.debug('Initializing NodeCrypto for app configuration encryption', this.exportConfig.context); @@ -109,7 +193,7 @@ export default class ExportMarketplaceApps { } return app; }); - + log.debug(`Processed ${this.installedApps.length} total marketplace apps`, this.exportConfig.context); } @@ -122,7 +206,7 @@ export default class ExportMarketplaceApps { log.info(messageHandler.parse('MARKETPLACE_APPS_NOT_FOUND'), this.exportConfig.context); } else { log.debug(`Processing ${this.installedApps.length} installed apps`, this.exportConfig.context); - + for (const [index, app] of entries(this.installedApps)) { if (app.manifest.visibility === 'private') { log.debug(`Processing private app manifest: ${app.manifest.name}`, this.exportConfig.context); @@ -133,6 +217,14 @@ export default class ExportMarketplaceApps { for (const [index, app] of entries(this.installedApps)) { log.debug(`Processing app configurations: ${app.manifest?.name || app.uid}`, this.exportConfig.context); await this.getAppConfigurations(+index, app); + + // Track progress for each app processed + this.progressManager?.tick( + true, + `app: ${app.manifest?.name || app.uid}`, + null, + PROCESS_NAMES.FETCH_CONFIG_MANIFEST, + ); } const marketplaceAppsFilePath = pResolve(this.marketplaceAppPath, this.marketplaceAppConfig.fileName); @@ -140,7 +232,7 @@ export default class ExportMarketplaceApps { fsUtil.writeFile(marketplaceAppsFilePath, this.installedApps); log.success( - messageHandler.parse('MARKETPLACE_APPS_EXPORT_COMPLETE', Object.keys(this.installedApps).length), + messageHandler.parse('MARKETPLACE_APPS_EXPORT_COMPLETE', Object.keys(this.installedApps || {}).length), this.exportConfig.context, ); } @@ -156,14 +248,20 @@ export default class ExportMarketplaceApps { * app's manifest. */ async getPrivateAppsManifest(index: number, appInstallation: Installation) { - log.debug(`Fetching private app manifest for: ${appInstallation.manifest.name} (${appInstallation.manifest.uid})`, this.exportConfig.context); - + log.debug( + `Fetching private app manifest for: ${appInstallation.manifest.name} (${appInstallation.manifest.uid})`, + this.exportConfig.context, + ); + const manifest = await this.appSdk .marketplace(this.exportConfig.org_uid) .app(appInstallation.manifest.uid) .fetch({ include_oauth: true }) .catch((error) => { - log.debug(`Failed to fetch private app manifest for: ${appInstallation.manifest.name}`, this.exportConfig.context); + log.debug( + `Failed to fetch private app manifest for: ${appInstallation.manifest.name}`, + this.exportConfig.context, + ); handleAndLogError( error, { @@ -174,7 +272,10 @@ export default class ExportMarketplaceApps { }); if (manifest) { - log.debug(`Successfully fetched private app manifest for: ${appInstallation.manifest.name}`, this.exportConfig.context); + log.debug( + `Successfully fetched private app manifest for: ${appInstallation.manifest.name}`, + this.exportConfig.context, + ); this.installedApps[index].manifest = manifest as unknown as Manifest; } } @@ -205,10 +306,14 @@ export default class ExportMarketplaceApps { if (has(data, 'server_configuration') || has(data, 'configuration')) { log.debug(`Found configuration data for app: ${app}`, this.exportConfig.context); - + if (!this.nodeCrypto && (has(data, 'server_configuration') || has(data, 'configuration'))) { - log.debug(`Initializing NodeCrypto for app: ${app}`, this.exportConfig.context); this.nodeCrypto = await createNodeCryptoInstance(this.exportConfig); + + this.progressManager?.updateStatus( + PROCESS_STATUS[PROCESS_NAMES.FETCH_CONFIG_MANIFEST].PROCESSING, + PROCESS_NAMES.FETCH_CONFIG_MANIFEST, + ); } if (!isEmpty(data?.configuration)) { @@ -254,7 +359,7 @@ export default class ExportMarketplaceApps { * the API. In this code, it is initially set to 0, indicating that no items should be skipped in */ async getStackSpecificApps(skip = 0) { - log.debug(`Fetching stack-specific apps with skip: ${skip}`, this.exportConfig.context); + log.debug(`Fetching stack-specific apps with skip: ${skip}`, this.exportConfig.context); const collection = await this.appSdk .marketplace(this.exportConfig.org_uid) .installation() @@ -269,7 +374,7 @@ export default class ExportMarketplaceApps { if (collection) { const { items: apps, count } = collection; log.debug(`Fetched ${apps?.length || 0} apps out of total ${count}`, this.exportConfig.context); - + // NOTE Remove all the chain functions const installation = map(apps, (app) => omitBy(app, (val, _key) => { @@ -277,8 +382,14 @@ export default class ExportMarketplaceApps { return false; }), ) as unknown as Installation[]; - + log.debug(`Processed ${installation.length} app installations`, this.exportConfig.context); + + // Track progress for each app fetched + installation.forEach((app) => { + this.progressManager?.tick(true, `app: ${app.manifest?.name || app.uid}`, null, PROCESS_NAMES.FETCH_APPS); + }); + this.installedApps = this.installedApps.concat(installation); if (count - (skip + 50) > 0) { diff --git a/packages/contentstack-export/src/export/modules/personalize.ts b/packages/contentstack-export/src/export/modules/personalize.ts index c06ea02564..d3eaeb7459 100644 --- a/packages/contentstack-export/src/export/modules/personalize.ts +++ b/packages/contentstack-export/src/export/modules/personalize.ts @@ -6,84 +6,248 @@ import { ExportAudiences, AnyProperty, } from '@contentstack/cli-variants'; -import { handleAndLogError, messageHandler, log } from '@contentstack/cli-utilities'; +import { handleAndLogError, messageHandler, log, CLIProgressManager } from '@contentstack/cli-utilities'; +import BaseClass from './base-class'; import { ModuleClassParams, ExportConfig } from '../../types'; +import { MODULE_CONTEXTS, MODULE_NAMES, PROCESS_NAMES, PROCESS_STATUS } from '../../utils'; -export default class ExportPersonalize { +export default class ExportPersonalize extends BaseClass { public exportConfig: ExportConfig; public personalizeConfig: { dirName: string; baseURL: Record } & AnyProperty; - constructor({ exportConfig }: ModuleClassParams) { + + private readonly moduleInstanceMapper = { + events: ExportEvents, + attributes: ExportAttributes, + audiences: ExportAudiences, + experiences: ExportExperiences, + }; + + private readonly moduleDisplayMapper = { + events: PROCESS_NAMES.PERSONALIZE_EVENTS, + attributes: PROCESS_NAMES.PERSONALIZE_ATTRIBUTES, + audiences: PROCESS_NAMES.PERSONALIZE_AUDIENCES, + experiences: PROCESS_NAMES.PERSONALIZE_EXPERIENCES, + } as const; + + constructor({ exportConfig, stackAPIClient }: ModuleClassParams) { + super({ exportConfig, stackAPIClient }); this.exportConfig = exportConfig; this.personalizeConfig = exportConfig.modules.personalize; - this.exportConfig.context.module = 'personalize'; + this.exportConfig.context.module = MODULE_CONTEXTS.PERSONALIZE; + this.currentModuleName = MODULE_NAMES[MODULE_CONTEXTS.PERSONALIZE]; } async start(): Promise { try { log.debug('Starting personalize export process...', this.exportConfig.context); - - if (!this.personalizeConfig.baseURL[this.exportConfig.region.name]) { - log.debug(`Personalize URL not set for region: ${this.exportConfig.region.name}`, this.exportConfig.context); - log.info(messageHandler.parse('PERSONALIZE_URL_NOT_SET'), this.exportConfig.context); - this.exportConfig.personalizationEnabled = false; - return; - } - - if (this.exportConfig.management_token) { - log.debug('Management token detected, skipping personalize export', this.exportConfig.context); - log.info(messageHandler.parse('PERSONALIZE_SKIPPING_WITH_MANAGEMENT_TOKEN'), this.exportConfig.context); - this.exportConfig.personalizationEnabled = false; + + const [canProceed, projectCount, moduleCount] = await this.withLoadingSpinner( + 'PERSONALIZE: Analyzing personalization configuration and connectivity...', + async () => { + // Step 1: Basic validation (URL, tokens) + const basicValidation = this.validatePersonalizeSetup(); + if (!basicValidation) { + return [false, 0, 0]; + } + + // Step 2: Check actual project connectivity + const projectCount = await this.validateProjectConnectivity(); + if (projectCount === 0) { + log.info('No Personalize Project connected with the given stack', this.exportConfig.context); + this.exportConfig.personalizationEnabled = false; + return [false, 0, 0]; + } + + // Step 3: Get module count only if projects exist + const moduleCount = this.getPersonalizeModuleCount(); + + log.debug( + `Personalize validation - canProceed: true, projectCount: ${projectCount}, moduleCount: ${moduleCount}`, + this.exportConfig.context, + ); + + // Enable personalization since we have connected projects + this.exportConfig.personalizationEnabled = true; + return [true, projectCount, moduleCount]; + }, + ); + + if (!canProceed) { return; } - - log.debug('Starting projects export for personalization...', this.exportConfig.context); - await new ExportProjects(this.exportConfig).start(); - - if (this.exportConfig.personalizationEnabled) { - log.debug('Personalization is enabled, processing personalize modules...', this.exportConfig.context); - - const moduleMapper = { - events: new ExportEvents(this.exportConfig), - attributes: new ExportAttributes(this.exportConfig), - audiences: new ExportAudiences(this.exportConfig), - experiences: new ExportExperiences(this.exportConfig), - }; - - const order: (keyof typeof moduleMapper)[] = this.exportConfig.modules.personalize - .exportOrder as (keyof typeof moduleMapper)[]; - - log.debug(`Personalize export order: ${order.join(', ')}`, this.exportConfig.context); - - for (const module of order) { - log.debug(`Processing personalize module: ${module}`, this.exportConfig.context); - - if (moduleMapper[module]) { - log.debug(`Starting export for module: ${module}`, this.exportConfig.context); - await moduleMapper[module].start(); - log.debug(`Completed export for module: ${module}`, this.exportConfig.context); - } else { - log.debug(`Module not implemented: ${module}`, this.exportConfig.context); - log.info( - messageHandler.parse('PERSONALIZE_MODULE_NOT_IMPLEMENTED', module), - this.exportConfig.context, - ); - } + + log.debug( + `Creating personalize progress with projectCount: ${projectCount}, moduleCount: ${moduleCount}`, + this.exportConfig.context, + ); + const progress = this.createNestedProgress(this.currentModuleName); + + this.addProjectProcess(progress, projectCount); + this.addModuleProcesses(progress, moduleCount); + + try { + await this.exportProjects(progress); + + if (moduleCount > 0) { + log.debug('Processing personalize modules...', this.exportConfig.context); + await this.exportModules(progress); + } else { + log.debug('No personalize modules configured for processing', this.exportConfig.context); + } + + this.completeProgress(true); + log.success('Personalize export completed successfully', this.exportConfig.context); + } catch (moduleError) { + if (moduleError === 'Forbidden') { + log.debug('Personalize access forbidden, personalization not enabled', this.exportConfig.context); + log.info(messageHandler.parse('PERSONALIZE_NOT_ENABLED'), this.exportConfig.context); + this.exportConfig.personalizationEnabled = false; + this.completeProgress(true); // considered successful even if skipped + } else { + log.debug('Error occurred during personalize module processing', this.exportConfig.context); + this.completeProgress(false, moduleError?.message || 'Personalize module processing failed'); + throw moduleError; } - - log.debug('Completed all personalize module exports', this.exportConfig.context); - } else { - log.debug('Personalization is disabled, skipping personalize module exports', this.exportConfig.context); } } catch (error) { - if (error === 'Forbidden') { - log.debug('Personalize access forbidden, personalization not enabled', this.exportConfig.context); - log.info(messageHandler.parse('PERSONALIZE_NOT_ENABLED'), this.exportConfig.context); + log.debug('Error occurred during personalize export', this.exportConfig.context); + handleAndLogError(error, { ...this.exportConfig.context }); + this.exportConfig.personalizationEnabled = false; + this.completeProgress(false, error?.message || 'Personalize export failed'); + } + } + + private validatePersonalizeSetup(): boolean { + if (!this.personalizeConfig.baseURL[this.exportConfig.region.name]) { + log.debug(`Personalize URL not set for region: ${this.exportConfig.region.name}`, this.exportConfig.context); + log.info(messageHandler.parse('PERSONALIZE_URL_NOT_SET'), this.exportConfig.context); + this.exportConfig.personalizationEnabled = false; + return false; + } + + if (this.exportConfig.management_token) { + log.debug('Management token detected, skipping personalize export', this.exportConfig.context); + log.info(messageHandler.parse('PERSONALIZE_SKIPPING_WITH_MANAGEMENT_TOKEN'), this.exportConfig.context); + this.exportConfig.personalizationEnabled = false; + return false; + } + + return true; + } + + private async validateProjectConnectivity(): Promise { + try { + // Create a temporary ExportProjects instance to check connectivity + const tempProjectsExporter = new ExportProjects(this.exportConfig); + + // Initialize and fetch projects + await tempProjectsExporter.init(); + // talisman-ignore-line + const projectsData = await tempProjectsExporter.projects({ connectedStackApiKey: this.exportConfig.apiKey }); + + const projectCount = projectsData?.length || 0; + log.debug(`Found ${projectCount} connected projects`, this.exportConfig.context); + + return projectCount; + } catch (error) { + log.debug(`Error checking project connectivity: ${error}`, this.exportConfig.context); + return 0; + } + } + + private getPersonalizeModuleCount(): number { + const order = this.exportConfig.modules?.personalize?.exportOrder; + return Array.isArray(order) ? order.length : 0; + } + + private addProjectProcess(progress: CLIProgressManager, projectCount: number) { + progress.addProcess(PROCESS_NAMES.PERSONALIZE_PROJECTS, projectCount); + log.debug( + `Added ${PROCESS_NAMES.PERSONALIZE_PROJECTS} process with count: ${projectCount}`, + this.exportConfig.context, + ); + } + + private addModuleProcesses(progress: CLIProgressManager, moduleCount: number) { + if (moduleCount > 0) { + // talisman-ignore-start + const order: (keyof typeof this.moduleDisplayMapper)[] = this.exportConfig.modules.personalize + .exportOrder as (keyof typeof this.moduleDisplayMapper)[]; + // talisman-ignore-end + + log.debug(`Adding ${order.length} personalize module processes: ${order.join(', ')}`, this.exportConfig.context); + + for (const module of order) { + const processName = this.moduleDisplayMapper[module]; + progress.addProcess(processName, 1); + log.debug(`Added ${processName} process to personalize progress`, this.exportConfig.context); + } + } else { + log.debug('No personalize modules to add to progress', this.exportConfig.context); + } + } + + private async exportProjects(progress: CLIProgressManager) { + progress + .startProcess(PROCESS_NAMES.PERSONALIZE_PROJECTS) + .updateStatus(PROCESS_STATUS[PROCESS_NAMES.PERSONALIZE_PROJECTS].EXPORTING, PROCESS_NAMES.PERSONALIZE_PROJECTS); + log.debug('Starting projects export for personalization...', this.exportConfig.context); + + const projectsExporter = new ExportProjects(this.exportConfig); + projectsExporter.setParentProgressManager(progress); + await projectsExporter.start(); + + progress.completeProcess(PROCESS_NAMES.PERSONALIZE_PROJECTS, true); + } + + private async exportModules(progress: CLIProgressManager) { + // Set parent progress for all module instances + Object.entries(this.moduleInstanceMapper).forEach(([_, ModuleClass]) => { + const instance = new ModuleClass(this.exportConfig); + instance.setParentProgressManager(progress); + }); + + // talisman-ignore-start + const order: (keyof typeof this.moduleInstanceMapper)[] = this.exportConfig.modules.personalize + .exportOrder as (keyof typeof this.moduleInstanceMapper)[]; + // talisman-ignore-end + + log.debug(`Personalize export order: ${order.join(', ')}`, this.exportConfig.context); + + for (const module of order) { + log.debug(`Processing personalize module: ${module}`, this.exportConfig.context); + const processName = this.moduleDisplayMapper[module]; + const ModuleClass = this.moduleInstanceMapper[module]; + + if (ModuleClass) { + progress + .startProcess(processName) + .updateStatus((PROCESS_STATUS as any)[processName]?.EXPORTING || `Exporting ${module}...`, processName); + log.debug(`Starting export for module: ${module}`, this.exportConfig.context); + + if (this.exportConfig.personalizationEnabled) { + const exporter = new ModuleClass(this.exportConfig); + exporter.setParentProgressManager(progress); + await exporter.start(); + + progress.completeProcess(processName, true); + log.debug(`Completed export for module: ${module}`, this.exportConfig.context); + } else { + log.debug(`Skipping ${module} - personalization not enabled`, this.exportConfig.context); + this.progressManager?.tick(true, `${module} skipped (no project)`, null, processName); + progress.completeProcess(processName, true); + log.info(`Skipped ${module} export - no personalize project found`, this.exportConfig.context); + } } else { - log.debug('Error occurred during personalize export', this.exportConfig.context); - handleAndLogError(error, { ...this.exportConfig.context }); + log.debug(`Module not implemented: ${module}`, this.exportConfig.context); + progress.startProcess(processName).updateStatus(`Module not implemented: ${module}`, processName); + this.progressManager?.tick(false, `module: ${module}`, 'Module not implemented', processName); + progress.completeProcess(processName, false); + log.info(messageHandler.parse('PERSONALIZE_MODULE_NOT_IMPLEMENTED', module), this.exportConfig.context); } - this.exportConfig.personalizationEnabled = false; } + + log.debug('Completed all personalize module processing', this.exportConfig.context); } } diff --git a/packages/contentstack-export/src/export/modules/stack.ts b/packages/contentstack-export/src/export/modules/stack.ts index f8a843c920..d2bb149b06 100644 --- a/packages/contentstack-export/src/export/modules/stack.ts +++ b/packages/contentstack-export/src/export/modules/stack.ts @@ -3,7 +3,13 @@ import { resolve as pResolve } from 'node:path'; import { handleAndLogError, isAuthenticated, managementSDKClient, log } from '@contentstack/cli-utilities'; import BaseClass from './base-class'; -import { fsUtil } from '../../utils'; +import { + fsUtil, + PROCESS_NAMES, + MODULE_CONTEXTS, + PROCESS_STATUS, + MODULE_NAMES, +} from '../../utils'; import { StackConfig, ModuleClassParams } from '../../types'; export default class ExportStack extends BaseClass { @@ -23,47 +29,103 @@ export default class ExportStack extends BaseClass { this.exportConfig.branchName || '', this.stackConfig.dirName, ); - this.exportConfig.context.module = 'stack'; + this.exportConfig.context.module = MODULE_CONTEXTS.STACK; + this.currentModuleName = MODULE_NAMES[MODULE_CONTEXTS.STACK]; } async start(): Promise { - log.debug('Starting stack export process...', this.exportConfig.context); + try { + log.debug('Starting stack export process...', this.exportConfig.context); + + // Initial analysis with loading spinner + const [stackData] = await this.withLoadingSpinner('STACK: Analyzing stack configuration...', async () => { + const stackData = isAuthenticated() ? await this.getStack() : null; + return [stackData]; + }); + + // Create nested progress manager + const progress = this.createNestedProgress(this.currentModuleName); + + // Add processes based on configuration + let processCount = 0; - if (isAuthenticated()) { - log.debug('User is authenticated, fetching stack data...', this.exportConfig.context); - const stackData = await this.getStack(); if (stackData?.org_uid) { log.debug(`Found organization UID: ${stackData.org_uid}`, this.exportConfig.context); this.exportConfig.org_uid = stackData.org_uid; this.exportConfig.sourceStackName = stackData.name; log.debug(`Set source stack name: ${stackData.name}`, this.exportConfig.context); + } + + if (!this.exportConfig.management_token) { + progress.addProcess(PROCESS_NAMES.STACK_SETTINGS, 1); + processCount++; + } + + if (!this.exportConfig.preserveStackVersion && !this.exportConfig.hasOwnProperty('master_locale')) { + progress.addProcess(PROCESS_NAMES.STACK_LOCALE, 1); + processCount++; + } else if (this.exportConfig.preserveStackVersion) { + progress.addProcess(PROCESS_NAMES.STACK_DETAILS, 1); + processCount++; + } + + // Execute processes + if (!this.exportConfig.management_token) { + progress + .startProcess(PROCESS_NAMES.STACK_SETTINGS) + .updateStatus( + PROCESS_STATUS[PROCESS_NAMES.STACK_SETTINGS].EXPORTING, + PROCESS_NAMES.STACK_SETTINGS, + ); + await this.exportStackSettings(); + progress.completeProcess(PROCESS_NAMES.STACK_SETTINGS, true); } else { - log.debug('No stack data found or missing org_uid', this.exportConfig.context); + log.info( + 'Skipping stack settings export: Operation is not supported when using a management token.', + this.exportConfig.context, + ); } - } else { - log.debug('User is not authenticated, skipping stack data fetch', this.exportConfig.context); - } - if (this.exportConfig.management_token) { - log.info( - 'Skipping stack settings export: Operation is not supported when using a management token.', - this.exportConfig.context, - ); - } else { - await this.exportStackSettings(); - } - if (!this.exportConfig.preserveStackVersion && !this.exportConfig.hasOwnProperty('master_locale')) { - log.debug( - 'Preserve stack version is false and master locale not set, fetching locales...', - this.exportConfig.context, - ); - //fetch master locale details - return this.getLocales(); - } else if (this.exportConfig.preserveStackVersion) { - log.debug('Preserve stack version is true, exporting stack...', this.exportConfig.context); - return this.exportStack(); - } else { - log.debug('Master locale already set, skipping locale fetch', this.exportConfig.context); + if (!this.exportConfig.preserveStackVersion && !this.exportConfig.hasOwnProperty('master_locale')) { + progress + .startProcess(PROCESS_NAMES.STACK_LOCALE) + .updateStatus( + PROCESS_STATUS[PROCESS_NAMES.STACK_LOCALE].FETCHING, + PROCESS_NAMES.STACK_LOCALE, + ); + const masterLocale = await this.getLocales(); + progress.completeProcess(PROCESS_NAMES.STACK_LOCALE, true); + + if (masterLocale?.code) { + this.exportConfig.master_locale = { code: masterLocale.code }; + log.debug(`Set master locale: ${masterLocale.code}`, this.exportConfig.context); + } + + this.completeProgress(true); + return masterLocale; + } else if (this.exportConfig.preserveStackVersion) { + progress + .startProcess(PROCESS_NAMES.STACK_DETAILS) + .updateStatus( + PROCESS_STATUS[PROCESS_NAMES.STACK_DETAILS].EXPORTING, + PROCESS_NAMES.STACK_DETAILS, + ); + const stackResult = await this.exportStack(); + progress.completeProcess(PROCESS_NAMES.STACK_DETAILS, true); + + this.completeProgress(true); + return stackResult; + } else { + log.debug('Locale locale already set, skipping locale fetch', this.exportConfig.context); + } + + this.completeProgress(true); + log.success('Stack export completed successfully', this.exportConfig.context); + } catch (error) { + log.debug('Error occurred during stack export', this.exportConfig.context); + handleAndLogError(error, { ...this.exportConfig.context }); + this.completeProgress(false, error?.message || 'Stack export failed'); + throw error; } } @@ -106,6 +168,10 @@ export default class ExportStack extends BaseClass { if (items?.length) { log.debug(`Processing ${items.length} locales to find master locale`, this.exportConfig.context); + + // Track progress for each locale processed + this.progressManager?.tick(true, 'Fetch locale', null, PROCESS_NAMES.STACK_LOCALE); + skip += this.stackConfig.limit || 100; const masterLocalObj = find(items, (locale: any) => { if (locale.fallback_locale === null) { @@ -118,14 +184,14 @@ export default class ExportStack extends BaseClass { return masterLocalObj; } else if (skip >= count) { log.error( - `Master locale not found in the stack ${this.exportConfig.source_stack}. Please ensure that the stack has a master locale.`, + `Locale locale not found in the stack ${this.exportConfig.source_stack}. Please ensure that the stack has a master locale.`, this.exportConfig.context, ); log.debug('Completed searching all locales without finding master locale', this.exportConfig.context); return; } else { log.debug( - `Master locale not found in current batch, continuing with skip: ${skip}`, + `Locale locale not found in current batch, continuing with skip: ${skip}`, this.exportConfig.context, ); return await this.getLocales(skip); @@ -139,6 +205,12 @@ export default class ExportStack extends BaseClass { `Error occurred while fetching locales for stack: ${this.exportConfig.source_stack}`, this.exportConfig.context, ); + this.progressManager?.tick( + false, + 'locale fetch', + error?.message || PROCESS_STATUS[PROCESS_NAMES.STACK_LOCALE].FAILED, + PROCESS_NAMES.STACK_LOCALE, + ); handleAndLogError( error, { ...this.exportConfig.context }, @@ -160,6 +232,15 @@ export default class ExportStack extends BaseClass { const stackFilePath = pResolve(this.stackFolderPath, this.stackConfig.fileName); log.debug(`Writing stack data to: ${stackFilePath}`, this.exportConfig.context); fsUtil.writeFile(stackFilePath, resp); + + // Track progress for stack export completion + this.progressManager?.tick( + true, + `stack: ${this.exportConfig.source_stack}`, + null, + PROCESS_NAMES.STACK_DETAILS, + ); + log.success( `Stack details exported successfully for stack ${this.exportConfig.source_stack}`, this.exportConfig.context, @@ -169,6 +250,12 @@ export default class ExportStack extends BaseClass { }) .catch((error: any) => { log.debug(`Error occurred while exporting stack: ${this.exportConfig.source_stack}`, this.exportConfig.context); + this.progressManager?.tick( + false, + 'stack export', + error?.message || PROCESS_STATUS[PROCESS_NAMES.STACK_DETAILS].FAILED, + PROCESS_NAMES.STACK_DETAILS, + ); handleAndLogError(error, { ...this.exportConfig.context }); }); } @@ -180,10 +267,20 @@ export default class ExportStack extends BaseClass { .settings() .then((resp: any) => { fsUtil.writeFile(pResolve(this.stackFolderPath, 'settings.json'), resp); + + // Track progress for stack settings completion + this.progressManager?.tick(true, 'stack settings', null, PROCESS_NAMES.STACK_SETTINGS); + log.success('Exported stack settings successfully!', this.exportConfig.context); return resp; }) .catch((error: any) => { + this.progressManager?.tick( + false, + 'stack settings', + error?.message || PROCESS_STATUS[PROCESS_NAMES.STACK_SETTINGS].FAILED, + PROCESS_NAMES.STACK_SETTINGS, + ); handleAndLogError(error, { ...this.exportConfig.context }); }); } diff --git a/packages/contentstack-export/src/export/modules/taxonomies.ts b/packages/contentstack-export/src/export/modules/taxonomies.ts index 74e6d539ff..54b7b555e9 100644 --- a/packages/contentstack-export/src/export/modules/taxonomies.ts +++ b/packages/contentstack-export/src/export/modules/taxonomies.ts @@ -5,7 +5,13 @@ import { resolve as pResolve } from 'node:path'; import { handleAndLogError, messageHandler, log } from '@contentstack/cli-utilities'; import BaseClass from './base-class'; -import { fsUtil } from '../../utils'; +import { + fsUtil, + PROCESS_NAMES, + MODULE_CONTEXTS, + PROCESS_STATUS, + MODULE_NAMES, +} from '../../utils'; import { ModuleClassParams, ExportConfig } from '../../types'; export default class ExportTaxonomies extends BaseClass { @@ -25,47 +31,91 @@ export default class ExportTaxonomies extends BaseClass { this.taxonomiesConfig = exportConfig.modules.taxonomies; this.qs = { include_count: true, limit: this.taxonomiesConfig.limit || 100, skip: 0 }; this.applyQueryFilters(this.qs, 'taxonomies'); - this.exportConfig.context.module = 'taxonomies'; + this.exportConfig.context.module = MODULE_CONTEXTS.TAXONOMIES; + this.currentModuleName = MODULE_NAMES[MODULE_CONTEXTS.TAXONOMIES]; } async start(): Promise { - log.debug('Starting taxonomies export process...', this.exportConfig.context); - - //create taxonomies folder - this.taxonomiesFolderPath = pResolve( - this.exportConfig.data, - this.exportConfig.branchName || '', - this.taxonomiesConfig.dirName, - ); - log.debug(`Taxonomies folder path: ${this.taxonomiesFolderPath}`, this.exportConfig.context); - - await fsUtil.makeDirectory(this.taxonomiesFolderPath); - log.debug('Created taxonomies directory', this.exportConfig.context); - - //fetch all taxonomies and write into taxonomies folder - log.debug('Fetching all taxonomies...', this.exportConfig.context); - await this.getAllTaxonomies(); - log.debug(`Retrieved ${Object.keys(this.taxonomies).length} taxonomies`, this.exportConfig.context); - - if (this.taxonomies === undefined || isEmpty(this.taxonomies)) { - log.info(messageHandler.parse('TAXONOMY_NOT_FOUND'), this.exportConfig.context); - return; - } else { - const taxonomiesFilePath = pResolve(this.taxonomiesFolderPath, 'taxonomies.json'); - log.debug(`Writing taxonomies metadata to: ${taxonomiesFilePath}`, this.exportConfig.context); - fsUtil.writeFile(taxonomiesFilePath, this.taxonomies); - - log.debug('Starting detailed taxonomy export...', this.exportConfig.context); - await this.exportTaxonomies(); + try { + log.debug('Starting taxonomies export process...', this.exportConfig.context); + + // Setup with loading spinner + const [totalCount] = await this.withLoadingSpinner('TAXONOMIES: Analyzing taxonomy structure...', async () => { + this.taxonomiesFolderPath = pResolve( + this.exportConfig.data, + this.exportConfig.branchName || '', + this.taxonomiesConfig.dirName, + ); + + await fsUtil.makeDirectory(this.taxonomiesFolderPath); + + // Get count first for progress tracking + const countResponse = await this.stack + .taxonomy() + .query({ ...this.qs, include_count: true, limit: 1 }) + .find(); + return [countResponse.count || 0]; + }); + + if (totalCount === 0) { + log.info(messageHandler.parse('TAXONOMY_NOT_FOUND'), this.exportConfig.context); + return; + } + + // Create nested progress manager + const progress = this.createNestedProgress(this.currentModuleName); + + // Add sub-processes + progress.addProcess(PROCESS_NAMES.FETCH_TAXONOMIES, totalCount); + progress.addProcess(PROCESS_NAMES.EXPORT_TAXONOMIES_TERMS, totalCount); + + // Fetch taxonomies + progress + .startProcess(PROCESS_NAMES.FETCH_TAXONOMIES) + .updateStatus( + PROCESS_STATUS[PROCESS_NAMES.FETCH_TAXONOMIES].FETCHING, + PROCESS_NAMES.FETCH_TAXONOMIES, + ); + await this.getAllTaxonomies(); + progress.completeProcess(PROCESS_NAMES.FETCH_TAXONOMIES, true); + + const actualTaxonomyCount = Object.keys(this.taxonomies || {})?.length; + log.debug( + `Found ${actualTaxonomyCount} taxonomies to export (API reported ${totalCount})`, + this.exportConfig.context, + ); + + // Update progress for export step if counts differ + if (actualTaxonomyCount !== totalCount && actualTaxonomyCount > 0) { + // Remove the old process and add with correct count + progress.addProcess(PROCESS_NAMES.EXPORT_TAXONOMIES_TERMS, actualTaxonomyCount); + } + + // Export detailed taxonomies + if (actualTaxonomyCount > 0) { + progress + .startProcess(PROCESS_NAMES.EXPORT_TAXONOMIES_TERMS) + .updateStatus( + PROCESS_STATUS[PROCESS_NAMES.EXPORT_TAXONOMIES_TERMS].EXPORTING, + PROCESS_NAMES.EXPORT_TAXONOMIES_TERMS, + ); + await this.exportTaxonomies(); + progress.completeProcess(PROCESS_NAMES.EXPORT_TAXONOMIES_TERMS, true); + } else { + log.info('No taxonomies found to export detailed information', this.exportConfig.context); + } + + const taxonomyCount = Object.keys(this.taxonomies || {}).length; + log.success(messageHandler.parse('TAXONOMY_EXPORT_COMPLETE', taxonomyCount), this.exportConfig.context); + this.completeProgress(true); + } catch (error) { + handleAndLogError(error, { ...this.exportConfig.context }); + this.completeProgress(false, error?.message || 'Taxonomies export failed'); } - log.success( - messageHandler.parse('TAXONOMY_EXPORT_COMPLETE', keys(this.taxonomies).length ), - this.exportConfig.context, - ); } /** - * fetch all taxonomies in the provided stack + * Fetch in the provided stack * @param {number} skip * @returns {Promise} */ @@ -76,92 +126,135 @@ export default class ExportTaxonomies extends BaseClass { } else { log.debug('Fetching taxonomies with initial query', this.exportConfig.context); } - + log.debug(`Query parameters: ${JSON.stringify(this.qs)}`, this.exportConfig.context); - - await this.stack - .taxonomy() - .query(this.qs) - .find() - .then(async (data: any) => { - const { items, count } = data; - const taxonomiesCount = count !== undefined ? count : items?.length; - log.debug(`Fetched ${items?.length || 0} taxonomies out of total ${taxonomiesCount}`, this.exportConfig.context); - - if (items?.length) { - log.debug(`Processing ${items.length} taxonomies`, this.exportConfig.context); - this.sanitizeTaxonomiesAttribs(items); - skip += this.qs.limit || 100; - if (skip >= taxonomiesCount) { - log.debug('Completed fetching all taxonomies', this.exportConfig.context); - return; - } - log.debug(`Continuing to fetch taxonomies with skip: ${skip}`, this.exportConfig.context); - return await this.getAllTaxonomies(skip); - } else { - log.debug('No taxonomies found to process', this.exportConfig.context); - } - }) - .catch((error: any) => { - log.debug('Error occurred while fetching taxonomies', this.exportConfig.context); - handleAndLogError(error, { ...this.exportConfig.context }); - }); + + let taxonomyResult = await this.stack.taxonomy().query(this.qs).find(); + + log.debug( + `Fetched ${taxonomyResult.items?.length || 0} taxonomies out of total ${taxonomyResult.count}`, + this.exportConfig.context, + ); + + if (taxonomyResult?.items && taxonomyResult?.items?.length > 0) { + log.debug(`Processing ${taxonomyResult.items.length} taxonomies`, this.exportConfig.context); + this.sanitizeTaxonomiesAttribs(taxonomyResult.items); + + skip += this.taxonomiesConfig.limit; + if (skip >= taxonomyResult.count) { + log.debug('Completed fetching all taxonomies', this.exportConfig.context); + return; + } + + log.debug(`Continuing to fetch taxonomies with skip: ${skip}`, this.exportConfig.context); + return await this.getAllTaxonomies(skip); + } else { + log.info(messageHandler.parse('TAXONOMY_NOT_FOUND'), this.exportConfig.context); + } } - /** - * remove invalid keys and write data into taxonomies - * @function sanitizeTaxonomiesAttribs - * @param taxonomies - */ - sanitizeTaxonomiesAttribs(taxonomies: Record[]) { + sanitizeTaxonomiesAttribs(taxonomies: Record[]) { log.debug(`Sanitizing ${taxonomies.length} taxonomies`, this.exportConfig.context); - + for (let index = 0; index < taxonomies?.length; index++) { - const taxonomyUID = taxonomies[index].uid; - const taxonomyName = taxonomies[index]?.name; - log.debug(`Processing taxonomy: ${taxonomyName} (${taxonomyUID})`, this.exportConfig.context); - - this.taxonomies[taxonomyUID] = omit(taxonomies[index], this.taxonomiesConfig.invalidKeys); + const taxonomy = taxonomies[index]; + const taxonomyUid = taxonomy.uid; + const taxonomyName = taxonomy?.name; + log.debug(`Processing taxonomy: ${taxonomyName} (${taxonomyUid})`, this.exportConfig.context); + + if (this.taxonomiesConfig.invalidKeys && this.taxonomiesConfig.invalidKeys.length > 0) { + this.taxonomies[taxonomyUid] = omit(taxonomy, this.taxonomiesConfig.invalidKeys); + } else { + this.taxonomies[taxonomyUid] = taxonomy; + } + + // Track progress for each taxonomy + this.progressManager?.tick( + true, + `taxonomy: ${taxonomyName || taxonomyUid}`, + null, + PROCESS_NAMES.FETCH_TAXONOMIES, + ); } - - log.debug(`Sanitization complete. Total taxonomies processed: ${Object.keys(this.taxonomies).length}`, this.exportConfig.context); + + log.debug( + `Sanitization complete. Total taxonomies processed: ${Object.keys(this.taxonomies || {}).length}`, + this.exportConfig.context, + ); } /** * Export all taxonomies details using metadata(this.taxonomies) and write it into respective .json file - * @returns {Promise} + * @returns {Promise} */ - async exportTaxonomies(): Promise { - const taxonomiesUID = keys(this.taxonomies) || []; - log.debug(`Exporting detailed data for ${taxonomiesUID.length} taxonomies`, this.exportConfig.context); + async exportTaxonomies(): Promise { + log.debug( + `Exporting ${Object.keys(this.taxonomies || {})?.length} taxonomies with detailed information`, + this.exportConfig.context, + ); + + if (isEmpty(this.taxonomies)) { + log.info(messageHandler.parse('TAXONOMY_NOT_FOUND'), this.exportConfig.context); + return; + } const onSuccess = ({ response, uid }: any) => { + const taxonomyName = this.taxonomies[uid]?.name; const filePath = pResolve(this.taxonomiesFolderPath, `${uid}.json`); - log.debug(`Writing detailed taxonomy data to: ${filePath}`, this.exportConfig.context); + + log.debug(`Writing detailed taxonomy to: ${filePath}`, this.exportConfig.context); fsUtil.writeFile(filePath, response); - log.success( - messageHandler.parse('TAXONOMY_EXPORT_SUCCESS', uid), - this.exportConfig.context, + + // Track progress for each exported taxonomy + this.progressManager?.tick( + true, + `taxonomy: ${taxonomyName || uid}`, + null, + PROCESS_NAMES.EXPORT_TAXONOMIES_TERMS, ); + + log.success(messageHandler.parse('TAXONOMY_EXPORT_SUCCESS', taxonomyName || uid), this.exportConfig.context); }; const onReject = ({ error, uid }: any) => { - log.debug(`Failed to export detailed data for taxonomy: ${uid}`, this.exportConfig.context); - handleAndLogError(error, { ...this.exportConfig.context, uid }); + const taxonomyName = this.taxonomies[uid]?.name; + + // Track failure + this.progressManager?.tick( + false, + `taxonomy: ${taxonomyName || uid}`, + error?.message || PROCESS_STATUS[PROCESS_NAMES.EXPORT_TAXONOMIES_TERMS].FAILED, + PROCESS_NAMES.EXPORT_TAXONOMIES_TERMS, + ); + + handleAndLogError( + error, + { ...this.exportConfig.context, uid }, + messageHandler.parse('TAXONOMY_EXPORT_FAILED', taxonomyName || uid), + ); }; - for (let index = 0; index < taxonomiesUID?.length; index++) { - const taxonomyUID = taxonomiesUID[index]; - log.debug(`Processing detailed export for taxonomy: ${taxonomyUID}`, this.exportConfig.context); - - await this.makeAPICall({ - reject: onReject, - resolve: onSuccess, - uid: taxonomyUID, - module: 'export-taxonomy', - }); + const taxonomyUids = keys(this.taxonomies); + log.debug(`Starting detailed export for ${taxonomyUids.length} taxonomies`, this.exportConfig.context); + + // Export each taxonomy individually + for (const uid of taxonomyUids) { + try { + log.debug(`Exporting detailed taxonomy: ${uid}`, this.exportConfig.context); + await this.makeAPICall({ + module: 'export-taxonomy', + uid, + resolve: onSuccess, + reject: onReject, + }); + } catch (error) { + onReject({ error, uid }); + } } - - log.debug('Completed detailed taxonomy export process', this.exportConfig.context); + + // Write the taxonomies index file + const taxonomiesFilePath = pResolve(this.taxonomiesFolderPath, this.taxonomiesConfig.fileName); + log.debug(`Writing taxonomies index to: ${taxonomiesFilePath}`, this.exportConfig.context); + fsUtil.writeFile(taxonomiesFilePath, this.taxonomies); } } diff --git a/packages/contentstack-export/src/export/modules/webhooks.ts b/packages/contentstack-export/src/export/modules/webhooks.ts index 42d6574905..26f3d40232 100644 --- a/packages/contentstack-export/src/export/modules/webhooks.ts +++ b/packages/contentstack-export/src/export/modules/webhooks.ts @@ -4,8 +4,8 @@ import { resolve as pResolve } from 'node:path'; import { handleAndLogError, messageHandler, log } from '@contentstack/cli-utilities'; import BaseClass from './base-class'; -import { fsUtil } from '../../utils'; import { WebhookConfig, ModuleClassParams } from '../../types'; +import { fsUtil, MODULE_CONTEXTS, MODULE_NAMES } from '../../utils'; export default class ExportWebhooks extends BaseClass { private webhooks: Record>; @@ -22,35 +22,57 @@ export default class ExportWebhooks extends BaseClass { this.webhooks = {}; this.webhookConfig = exportConfig.modules.webhooks; this.qs = { include_count: true, asc: 'updated_at' }; - this.exportConfig.context.module = 'webhooks'; + this.exportConfig.context.module = MODULE_CONTEXTS.WEBHOOKS; + this.currentModuleName = MODULE_NAMES[MODULE_CONTEXTS.WEBHOOKS]; } async start(): Promise { - log.debug('Starting webhooks export process...', this.exportConfig.context); - - this.webhooksFolderPath = pResolve( - this.exportConfig.data, - this.exportConfig.branchName || '', - this.webhookConfig.dirName, - ); - log.debug(`Webhooks folder path: ${this.webhooksFolderPath}`, this.exportConfig.context); - - await fsUtil.makeDirectory(this.webhooksFolderPath); - log.debug('Created webhooks directory', this.exportConfig.context); - - await this.getWebhooks(); - log.debug(`Retrieved ${Object.keys(this.webhooks).length} webhooks`, this.exportConfig.context); - - if (this.webhooks === undefined || isEmpty(this.webhooks)) { - log.info(messageHandler.parse('WEBHOOK_NOT_FOUND'), this.exportConfig.context); - } else { - const webhooksFilePath = pResolve(this.webhooksFolderPath, this.webhookConfig.fileName); - log.debug(`Writing webhooks to: ${webhooksFilePath}`, this.exportConfig.context); - fsUtil.writeFile(webhooksFilePath, this.webhooks); - log.success( - messageHandler.parse('WEBHOOK_EXPORT_COMPLETE', Object.keys(this.webhooks).length), - this.exportConfig.context, - ); + try { + log.debug('Starting webhooks export process...', this.exportConfig.context); + + // Setup with loading spinner + const [totalCount] = await this.withLoadingSpinner('WEBHOOKS: Analyzing webhooks...', async () => { + this.webhooksFolderPath = pResolve( + this.exportConfig.data, + this.exportConfig.branchName || '', + this.webhookConfig.dirName, + ); + + await fsUtil.makeDirectory(this.webhooksFolderPath); + + // Get count for progress tracking + const countResponse = await this.stack.webhook().fetchAll({ ...this.qs, limit: 1 }); + return [countResponse.count || 0]; + }); + + if (totalCount === 0) { + log.info(messageHandler.parse('WEBHOOK_NOT_FOUND'), this.exportConfig.context); + return; + } + + // Create simple progress manager with total count + const progress = this.createSimpleProgress(this.currentModuleName, totalCount); + + progress.updateStatus('Fetching webhooks...'); + await this.getWebhooks(); + log.debug(`Retrieved ${Object.keys(this.webhooks || {}).length} webhooks`, this.exportConfig.context); + + if (this.webhooks === undefined || isEmpty(this.webhooks)) { + log.info(messageHandler.parse('WEBHOOK_NOT_FOUND'), this.exportConfig.context); + } else { + const webhooksFilePath = pResolve(this.webhooksFolderPath, this.webhookConfig.fileName); + log.debug(`Writing webhooks to: ${webhooksFilePath}`, this.exportConfig.context); + fsUtil.writeFile(webhooksFilePath, this.webhooks); + log.success( + messageHandler.parse('WEBHOOK_EXPORT_COMPLETE', Object.keys(this.webhooks || {}).length), + this.exportConfig.context, + ); + } + + this.completeProgress(true); + } catch (error) { + handleAndLogError(error, { ...this.exportConfig.context }); + this.completeProgress(false, error?.message || 'Webhooks export failed'); } } @@ -61,7 +83,7 @@ export default class ExportWebhooks extends BaseClass { } else { log.debug('Fetching webhooks with initial query', this.exportConfig.context); } - + log.debug(`Query parameters: ${JSON.stringify(this.qs)}`, this.exportConfig.context); await this.stack @@ -70,7 +92,7 @@ export default class ExportWebhooks extends BaseClass { .then(async (data: any) => { const { items, count } = data; log.debug(`Fetched ${items?.length || 0} webhooks out of total ${count}`, this.exportConfig.context); - + if (items?.length) { log.debug(`Processing ${items.length} webhooks`, this.exportConfig.context); this.sanitizeAttribs(items); @@ -86,6 +108,7 @@ export default class ExportWebhooks extends BaseClass { } }) .catch((error: any) => { + this.progressManager?.tick(false, 'webhooks', error?.message || 'Failed to export webhooks'); log.debug('Error occurred while fetching webhooks', this.exportConfig.context); handleAndLogError(error, { ...this.exportConfig.context }); }); @@ -93,16 +116,22 @@ export default class ExportWebhooks extends BaseClass { sanitizeAttribs(webhooks: Record[]) { log.debug(`Sanitizing ${webhooks.length} webhooks`, this.exportConfig.context); - + for (let index = 0; index < webhooks?.length; index++) { const webhookUid = webhooks[index].uid; const webhookName = webhooks[index]?.name; log.debug(`Processing webhook: ${webhookName} (${webhookUid})`, this.exportConfig.context); - + this.webhooks[webhookUid] = omit(webhooks[index], ['SYS_ACL']); log.success(messageHandler.parse('WEBHOOK_EXPORT_SUCCESS', webhookName), this.exportConfig.context); + + // Track progress for each webhook + this.progressManager?.tick(true, `webhook: ${webhookName}`); } - - log.debug(`Sanitization complete. Total webhooks processed: ${Object.keys(this.webhooks).length}`, this.exportConfig.context); + + log.debug( + `Sanitization complete. Total webhooks processed: ${Object.keys(this.webhooks || {}).length}`, + this.exportConfig.context, + ); } } diff --git a/packages/contentstack-export/src/export/modules/workflows.ts b/packages/contentstack-export/src/export/modules/workflows.ts index 6a9fedb8a2..1107b87cfa 100644 --- a/packages/contentstack-export/src/export/modules/workflows.ts +++ b/packages/contentstack-export/src/export/modules/workflows.ts @@ -4,8 +4,8 @@ import { resolve as pResolve } from 'node:path'; import { handleAndLogError, messageHandler, log } from '@contentstack/cli-utilities'; import BaseClass from './base-class'; -import { fsUtil } from '../../utils'; import { WorkflowConfig, ModuleClassParams } from '../../types'; +import { fsUtil, MODULE_CONTEXTS, MODULE_NAMES } from '../../utils'; export default class ExportWorkFlows extends BaseClass { private workflows: Record>; @@ -21,33 +21,61 @@ export default class ExportWorkFlows extends BaseClass { this.workflows = {}; this.workflowConfig = exportConfig.modules.workflows; this.qs = { include_count: true }; - this.exportConfig.context.module = 'workflows'; + this.exportConfig.context.module = MODULE_CONTEXTS.WORKFLOWS; + this.currentModuleName = MODULE_NAMES[MODULE_CONTEXTS.WORKFLOWS]; } - async start(): Promise { - this.webhooksFolderPath = pResolve( - this.exportConfig.data, - this.exportConfig.branchName || '', - this.workflowConfig.dirName, - ); - log.debug(`Workflows folder path: ${this.webhooksFolderPath}`, this.exportConfig.context); - - await fsUtil.makeDirectory(this.webhooksFolderPath); - log.debug('Created workflows directory', this.exportConfig.context); - - await this.getWorkflows(); - log.debug(`Retrieved ${Object.keys(this.workflows).length} workflows`, this.exportConfig.context); - - if (this.workflows === undefined || isEmpty(this.workflows)) { - log.info(messageHandler.parse('WORKFLOW_NOT_FOUND'), this.exportConfig.context); - } else { - const workflowsFilePath = pResolve(this.webhooksFolderPath, this.workflowConfig.fileName); - log.debug(`Writing workflows to: ${workflowsFilePath}`, this.exportConfig.context); - fsUtil.writeFile(workflowsFilePath, this.workflows); - log.success( - messageHandler.parse('WORKFLOW_EXPORT_COMPLETE', Object.keys(this.workflows).length ), - this.exportConfig.context, - ); + async start(): Promise { + try { + log.debug('Starting workflows export process...', this.exportConfig.context); + + // Setup with loading spinner + const [totalCount] = await this.withLoadingSpinner('WORKFLOWS: Analyzing workflows...', async () => { + this.webhooksFolderPath = pResolve( + this.exportConfig.data, + this.exportConfig.branchName || '', + this.workflowConfig.dirName, + ); + + await fsUtil.makeDirectory(this.webhooksFolderPath); + + // Get count for progress tracking + const countResponse = await this.stack.workflow().fetchAll({ ...this.qs, limit: 1 }); + const workflowCount = + countResponse.count !== undefined ? countResponse.count : countResponse.items?.length || 0; + return [workflowCount]; + }); + + if (totalCount === 0) { + log.info(messageHandler.parse('WORKFLOW_NOT_FOUND'), this.exportConfig.context); + return; + } + + // Create nested progress manager for complex workflow processing + const progress = this.createSimpleProgress(this.currentModuleName, totalCount); + + // Fetch workflows + progress.updateStatus('Fetching workflow definitions...'); + await this.getWorkflows(); + + log.debug(`Retrieved ${Object.keys(this.workflows || {}).length} workflows`, this.exportConfig.context); + + if (this.workflows === undefined || isEmpty(this.workflows)) { + log.info(messageHandler.parse('WORKFLOW_NOT_FOUND'), this.exportConfig.context); + } else { + const workflowsFilePath = pResolve(this.webhooksFolderPath, this.workflowConfig.fileName); + log.debug(`Writing workflows to: ${workflowsFilePath}`, this.exportConfig.context); + fsUtil.writeFile(workflowsFilePath, this.workflows); + log.success( + messageHandler.parse('WORKFLOW_EXPORT_COMPLETE', Object.keys(this.workflows || {}).length), + this.exportConfig.context, + ); + } + + this.completeProgress(true); + } catch (error) { + handleAndLogError(error, { ...this.exportConfig.context }); + this.completeProgress(false, error?.message || 'Workflows export failed'); } } @@ -66,7 +94,7 @@ export default class ExportWorkFlows extends BaseClass { //NOTE - Handle the case where old workflow api is enabled in that case getting responses as objects. const workflowCount = count !== undefined ? count : items.length; log.debug(`Fetched ${items?.length || 0} workflows out of total ${workflowCount}`, this.exportConfig.context); - + if (items?.length) { log.debug(`Processing ${items.length} workflows`, this.exportConfig.context); await this.sanitizeAttribs(items); @@ -89,41 +117,54 @@ export default class ExportWorkFlows extends BaseClass { async sanitizeAttribs(workflows: Record[]) { log.debug(`Sanitizing ${workflows.length} workflows`, this.exportConfig.context); - + for (let index = 0; index < workflows?.length; index++) { const workflowUid = workflows[index].uid; const workflowName = workflows[index]?.name || ''; log.debug(`Processing workflow: ${workflowName} (${workflowUid})`, this.exportConfig.context); - - await this.getWorkflowRoles(workflows[index]); - this.workflows[workflowUid] = omit(workflows[index], this.workflowConfig.invalidKeys); - log.success( - messageHandler.parse('WORKFLOW_EXPORT_SUCCESS', workflowName), - this.exportConfig.context, - ); + + try { + await this.getWorkflowRoles(workflows[index]); + this.workflows[workflowUid] = omit(workflows[index], this.workflowConfig.invalidKeys); + log.success(messageHandler.parse('WORKFLOW_EXPORT_SUCCESS', workflowName), this.exportConfig.context); + + // Track progress for each workflow + this.progressManager?.tick(true, `workflow: ${workflowName}`); + } catch (error) { + log.error(`Failed to process workflow: ${workflowName}`, this.exportConfig.context); + this.progressManager?.tick(false, `workflow: ${workflowName}`, error?.message || 'Processing failed', 'Fetch'); + } } - - log.debug(`Sanitization complete. Total workflows processed: ${Object.keys(this.workflows).length}`, this.exportConfig.context); + + log.debug( + `Sanitization complete. Total workflows processed: ${Object.keys(this.workflows).length}`, + this.exportConfig.context, + ); } async getWorkflowRoles(workflow: Record) { log.debug(`Processing workflow roles for workflow: ${workflow.uid}`, this.exportConfig.context); - + for (const stage of workflow?.workflow_stages) { log.debug(`Processing workflow stage: ${stage.name}`, this.exportConfig.context); - + for (let i = 0; i < stage?.SYS_ACL?.roles?.uids?.length; i++) { const roleUid = stage.SYS_ACL.roles.uids[i]; log.debug(`Fetching role data for role UID: ${roleUid}`, this.exportConfig.context); - const roleData = await this.getRoles(roleUid); - stage.SYS_ACL.roles.uids[i] = roleData; + + try { + const roleData = await this.getRoles(roleUid); + stage.SYS_ACL.roles.uids[i] = roleData; + } catch (error) { + log.error(`Failed to fetch role ${roleUid}`, this.exportConfig.context); + } } } } async getRoles(roleUid: number): Promise { log.debug(`Fetching role with UID: ${roleUid}`, this.exportConfig.context); - + return await this.stack .role(roleUid) .fetch({ include_rules: true, include_permissions: true }) @@ -133,10 +174,8 @@ export default class ExportWorkFlows extends BaseClass { }) .catch((err: any) => { log.debug(`Failed to fetch role data for UID: ${roleUid}`, this.exportConfig.context); - handleAndLogError( - err, - { ...this.exportConfig.context } - ); + handleAndLogError(err, { ...this.exportConfig.context }); + throw err; }); } } diff --git a/packages/contentstack-export/src/types/default-config.ts b/packages/contentstack-export/src/types/default-config.ts index c70a1de2dc..4345185b8c 100644 --- a/packages/contentstack-export/src/types/default-config.ts +++ b/packages/contentstack-export/src/types/default-config.ts @@ -5,7 +5,6 @@ interface AnyProperty { } export default interface DefaultConfig { - contentVersion: number; versioning: boolean; host: string; cdn?: string; @@ -215,5 +214,4 @@ export default interface DefaultConfig { writeConcurrency: number; developerHubBaseUrl: string; marketplaceAppEncryptionKey: string; - onlyTSModules: string[]; } diff --git a/packages/contentstack-export/src/types/index.ts b/packages/contentstack-export/src/types/index.ts index 736b7538dd..b1b23dddb6 100644 --- a/packages/contentstack-export/src/types/index.ts +++ b/packages/contentstack-export/src/types/index.ts @@ -133,7 +133,7 @@ export interface Context { command: string; module: string; userId: string | undefined; - email: string | undefined; + email?: string | undefined; sessionId: string | undefined; clientId?: string | undefined; apiKey: string; diff --git a/packages/contentstack-export/src/utils/common-helper.ts b/packages/contentstack-export/src/utils/common-helper.ts index 0ece3d4205..8721244370 100644 --- a/packages/contentstack-export/src/utils/common-helper.ts +++ b/packages/contentstack-export/src/utils/common-helper.ts @@ -4,7 +4,6 @@ * MIT Licensed */ -import * as path from 'path'; import promiseLimit from 'promise-limit'; import { isAuthenticated, getLogPath, sanitizePath } from '@contentstack/cli-utilities'; @@ -79,12 +78,3 @@ export const executeTask = function ( }), ); }; - -// Note: we can add more useful details in meta file -export const writeExportMetaFile = (exportConfig: ExportConfig, metaFilePath?: string) => { - const exportMeta = { - contentVersion: exportConfig.contentVersion, - logsPath: getLogPath(), - }; - fsUtil.writeFile(path.join(sanitizePath(metaFilePath || exportConfig.exportDir), 'export-info.json'), exportMeta); -}; diff --git a/packages/contentstack-export/src/utils/constants.ts b/packages/contentstack-export/src/utils/constants.ts new file mode 100644 index 0000000000..fc2f7dd287 --- /dev/null +++ b/packages/contentstack-export/src/utils/constants.ts @@ -0,0 +1,170 @@ +export const PROCESS_NAMES = { + // Assets module + ASSET_FOLDERS: 'Folders', + ASSET_METADATA: 'Metadata', + ASSET_DOWNLOADS: 'Downloads', + + // Custom Roles module + FETCH_ROLES: 'Fetch Roles', + FETCH_LOCALES: 'Fetch Locales', + PROCESS_MAPPINGS: 'Process Mappings', + + // Entries module + ENTRIES: 'Entries', + ENTRY_VERSIONS: 'Entry Versions', + VARIANT_ENTRIES: 'Variant Entries', + + // Marketplace Apps module + FETCH_APPS: 'Fetch Apps', + FETCH_CONFIG_MANIFEST: 'Fetch config & manifest', + + // Stack module + STACK_SETTINGS: 'Settings', + STACK_LOCALE: 'Locale', + STACK_DETAILS: 'Details', + + // Taxonomies module + FETCH_TAXONOMIES: 'Fetch Taxonomies', + EXPORT_TAXONOMIES_TERMS: 'Taxonomies & Terms', + + // Personalize module + PERSONALIZE_PROJECTS: 'Projects', + PERSONALIZE_EVENTS: 'Events', + PERSONALIZE_ATTRIBUTES: 'Attributes', + PERSONALIZE_AUDIENCES: 'Audiences', + PERSONALIZE_EXPERIENCES: 'Experiences', +} as const; + +export const MODULE_CONTEXTS = { + ASSETS: 'assets', + CONTENT_TYPES: 'content-types', + CUSTOM_ROLES: 'custom-roles', + ENTRIES: 'entries', + ENVIRONMENTS: 'environments', + EXTENSIONS: 'extensions', + GLOBAL_FIELDS: 'global-fields', + LABELS: 'labels', + LOCALES: 'locales', + MARKETPLACE_APPS: 'marketplace-apps', + PERSONALIZE: 'personalize', + STACK: 'stack', + TAXONOMIES: 'taxonomies', + WEBHOOKS: 'webhooks', + WORKFLOWS: 'workflows', +} as const; + +// Display names for modules to avoid scattering user-facing strings +export const MODULE_NAMES = { + [MODULE_CONTEXTS.ASSETS]: 'Assets', + [MODULE_CONTEXTS.CONTENT_TYPES]: 'Content Types', + [MODULE_CONTEXTS.CUSTOM_ROLES]: 'Custom Roles', + [MODULE_CONTEXTS.ENTRIES]: 'Entries', + [MODULE_CONTEXTS.ENVIRONMENTS]: 'Environments', + [MODULE_CONTEXTS.EXTENSIONS]: 'Extensions', + [MODULE_CONTEXTS.GLOBAL_FIELDS]: 'Global Fields', + [MODULE_CONTEXTS.LABELS]: 'Labels', + [MODULE_CONTEXTS.LOCALES]: 'Locales', + [MODULE_CONTEXTS.MARKETPLACE_APPS]: 'Marketplace Apps', + [MODULE_CONTEXTS.PERSONALIZE]: 'Personalize', + [MODULE_CONTEXTS.STACK]: 'Stack', + [MODULE_CONTEXTS.TAXONOMIES]: 'Taxonomies', + [MODULE_CONTEXTS.WEBHOOKS]: 'Webhooks', + [MODULE_CONTEXTS.WORKFLOWS]: 'Workflows', +} as const; + +export const PROCESS_STATUS = { + [PROCESS_NAMES.ASSET_FOLDERS]: { + FETCHING: 'Fetching folder structure...', + FAILED: 'Failed to fetch folder structure.', + }, + [PROCESS_NAMES.ASSET_METADATA]: { + FETCHING: 'Fetching asset information...', + FAILED: 'Failed to fetch asset', + FETCHING_VERSION: 'Processing versioned assets...', + }, + [PROCESS_NAMES.ASSET_DOWNLOADS]: { + DOWNLOADING: 'Downloading asset file...', + FAILED: 'Failed to download asset:', + }, + // Custom Roles + [PROCESS_NAMES.FETCH_ROLES]: { + FETCHING: 'Fetching custom roles...', + FAILED: 'Failed to fetch custom roles.', + }, + [PROCESS_NAMES.FETCH_LOCALES]: { + FETCHING: 'Fetching locales...', + FAILED: 'Failed to fetch locales.', + }, + [PROCESS_NAMES.PROCESS_MAPPINGS]: { + PROCESSING: 'Processing role-locale mappings...', + FAILED: 'Failed to process role-locale mappings.', + }, + [PROCESS_NAMES.ENTRIES]: { + PROCESSING: 'Processing entry collections...', + FAILED: 'Failed to export entries.', + }, + [PROCESS_NAMES.ENTRY_VERSIONS]: { + PROCESSING: 'Processing entry versions...', + FAILED: 'Failed to export entry versions.', + }, + [PROCESS_NAMES.VARIANT_ENTRIES]: { + PROCESSING: 'Processing variant entries...', + FAILED: 'Failed to export variant entries.', + }, + // Marketplace Apps + [PROCESS_NAMES.FETCH_APPS]: { + FETCHING: 'Fetching marketplace apps...', + FAILED: 'Failed to fetch marketplace apps.', + }, + [PROCESS_NAMES.FETCH_CONFIG_MANIFEST]: { + PROCESSING: 'Processing app manifests and configurations...', + FAILED: 'Failed to process app manifests/configurations.', + }, + // Stack + [PROCESS_NAMES.STACK_SETTINGS]: { + EXPORTING: 'Exporting stack settings...', + FAILED: 'Failed to export stack settings.', + }, + [PROCESS_NAMES.STACK_LOCALE]: { + FETCHING: 'Fetching master locale...', + FAILED: 'Failed to fetch master locale.', + }, + [PROCESS_NAMES.STACK_DETAILS]: { + EXPORTING: 'Exporting stack data...', + FAILED: 'Failed to export stack data.', + }, + // Taxonomies + [PROCESS_NAMES.FETCH_TAXONOMIES]: { + FETCHING: 'Fetching taxonomy metadata...', + FAILED: 'Failed to fetch taxonomies.', + }, + [PROCESS_NAMES.EXPORT_TAXONOMIES_TERMS]: { + EXPORTING: 'Exporting taxonomy details...', + FAILED: 'Failed to export taxonomy details.', + }, + // Personalize + [PROCESS_NAMES.PERSONALIZE_PROJECTS]: { + EXPORTING: 'Exporting personalization projects...', + FAILED: 'Failed to export personalization projects.', + }, + [PROCESS_NAMES.PERSONALIZE_EVENTS]: { + EXPORTING: 'Exporting events...', + FAILED: 'Failed to export events.', + }, + [PROCESS_NAMES.PERSONALIZE_ATTRIBUTES]: { + EXPORTING: 'Exporting attributes...', + FAILED: 'Failed to export attributes.', + }, + [PROCESS_NAMES.PERSONALIZE_AUDIENCES]: { + EXPORTING: 'Exporting audiences...', + FAILED: 'Failed to export audiences.', + }, + [PROCESS_NAMES.PERSONALIZE_EXPERIENCES]: { + EXPORTING: 'Exporting experiences...', + FAILED: 'Failed to export experiences.', + }, +}; + +export type ExportProcessName = (typeof PROCESS_NAMES)[keyof typeof PROCESS_NAMES]; +export type ExportModuleContext = (typeof MODULE_CONTEXTS)[keyof typeof MODULE_CONTEXTS]; +export type ExportProcessStatus = (typeof PROCESS_STATUS)[keyof typeof PROCESS_STATUS]; diff --git a/packages/contentstack-export/src/utils/export-config-handler.ts b/packages/contentstack-export/src/utils/export-config-handler.ts index eb647a0028..80250fb54d 100644 --- a/packages/contentstack-export/src/utils/export-config-handler.ts +++ b/packages/contentstack-export/src/utils/export-config-handler.ts @@ -1,6 +1,6 @@ import merge from 'merge'; import * as path from 'path'; -import { configHandler, isAuthenticated,cliux, sanitizePath, log } from '@contentstack/cli-utilities'; +import { configHandler, isAuthenticated, cliux, sanitizePath, log } from '@contentstack/cli-utilities'; import defaultConfig from '../config'; import { readFile } from './file-helper'; import { askExportDir, askAPIKey } from './interactive'; @@ -132,8 +132,9 @@ const setupConfig = async (exportCmdFlags: any): Promise => { throw new Error(`Invalid query format: ${error.message}`); } } - - // Add authentication details to config for context tracking + // Set progress supported module to check and display console logs + configHandler.set('log.progressSupportedModule', 'export'); + // Add authentication details to config for context tracking config.authenticationMethod = authenticationMethod; log.debug('Export configuration setup completed', { ...config }); diff --git a/packages/contentstack-export/src/utils/index.ts b/packages/contentstack-export/src/utils/index.ts index 3ab3476518..9cbd32cac5 100644 --- a/packages/contentstack-export/src/utils/index.ts +++ b/packages/contentstack-export/src/utils/index.ts @@ -8,3 +8,4 @@ export { log, unlinkFileLogger } from './logger'; export { default as login } from './basic-login'; export * from './common-helper'; export * from './marketplace-app-helper'; +export { MODULE_CONTEXTS, MODULE_NAMES, PROCESS_NAMES, PROCESS_STATUS } from './constants'; diff --git a/packages/contentstack-export/src/utils/marketplace-app-helper.ts b/packages/contentstack-export/src/utils/marketplace-app-helper.ts index 970f355277..fe08d2812a 100644 --- a/packages/contentstack-export/src/utils/marketplace-app-helper.ts +++ b/packages/contentstack-export/src/utils/marketplace-app-helper.ts @@ -1,4 +1,10 @@ -import { cliux, handleAndLogError, NodeCrypto, managementSDKClient, createDeveloperHubUrl } from '@contentstack/cli-utilities'; +import { + cliux, + handleAndLogError, + NodeCrypto, + managementSDKClient, + createDeveloperHubUrl, +} from '@contentstack/cli-utilities'; import { ExportConfig } from '../types'; @@ -12,7 +18,7 @@ export async function getOrgUid(config: ExportConfig): Promise { .stack({ api_key: config.source_stack }) .fetch() .catch((error: any) => { - handleAndLogError(error, {...config.context}); + handleAndLogError(error, { ...config.context }); }); return tempStackData?.org_uid; @@ -23,19 +29,27 @@ export async function createNodeCryptoInstance(config: ExportConfig): Promise { - if (!url) return "Encryption key can't be empty."; - - return true; - }, - message: 'Enter Marketplace app configurations encryption key', - }); + cliux.print(''); + cryptoArgs['encryptionKey'] = await askEncryptionKey(config); + cliux.print(''); } return new NodeCrypto(cryptoArgs); } + +export async function askEncryptionKey(config: ExportConfig): Promise { + return await cliux.inquire({ + type: 'input', + name: 'name', + default: config.marketplaceAppEncryptionKey, + validate: (url: any) => { + if (!url) return "Encryption key can't be empty."; + + return true; + }, + message: 'Enter Marketplace app configurations encryption key', + }); +} diff --git a/packages/contentstack-export/src/utils/progress-strategy-registry.ts b/packages/contentstack-export/src/utils/progress-strategy-registry.ts new file mode 100644 index 0000000000..ef7ea3c8d3 --- /dev/null +++ b/packages/contentstack-export/src/utils/progress-strategy-registry.ts @@ -0,0 +1,136 @@ +import { MODULE_CONTEXTS, MODULE_NAMES, PROCESS_NAMES } from './constants'; +/** + * Progress Strategy Registrations for Export Modules + * This file registers progress calculation strategies for all export modules + * to ensure correct item counts in the final summary. + */ + +import { + ProgressStrategyRegistry, + PrimaryProcessStrategy, + CustomProgressStrategy, + DefaultProgressStrategy, +} from '@contentstack/cli-utilities'; + +ProgressStrategyRegistry.register(MODULE_NAMES[MODULE_CONTEXTS.CONTENT_TYPES], new DefaultProgressStrategy()); + +// Register strategy for Assets - custom strategy to avoid double counting +ProgressStrategyRegistry.register( + MODULE_NAMES[MODULE_CONTEXTS.ASSETS], + new CustomProgressStrategy((processes) => { + // Both ASSET_METADATA and ASSET_DOWNLOADS represent the same assets + // Count only the downloads process to avoid double counting in summary + const downloadsProcess = processes.get(PROCESS_NAMES.ASSET_DOWNLOADS); + if (downloadsProcess) { + return { + total: downloadsProcess.total, + success: downloadsProcess.successCount, + failures: downloadsProcess.failureCount, + }; + } + + // Fallback to metadata process if downloads don't exist + const metadataProcess = processes.get(PROCESS_NAMES.ASSET_METADATA); + if (metadataProcess) { + return { + total: metadataProcess.total, + success: metadataProcess.successCount, + failures: metadataProcess.failureCount, + }; + } + + return null; // Fall back to default aggregation + }), +); + +ProgressStrategyRegistry.register(MODULE_NAMES[MODULE_CONTEXTS.GLOBAL_FIELDS], new DefaultProgressStrategy()); + +ProgressStrategyRegistry.register(MODULE_NAMES[MODULE_CONTEXTS.EXTENSIONS], new DefaultProgressStrategy()); + +// Register strategy for Environments - simple module +ProgressStrategyRegistry.register(MODULE_NAMES[MODULE_CONTEXTS.ENVIRONMENTS], new DefaultProgressStrategy()); + +ProgressStrategyRegistry.register(MODULE_NAMES[MODULE_CONTEXTS.LOCALES], new DefaultProgressStrategy()); + +ProgressStrategyRegistry.register(MODULE_NAMES[MODULE_CONTEXTS.LABELS], new DefaultProgressStrategy()); + +ProgressStrategyRegistry.register(MODULE_NAMES[MODULE_CONTEXTS.WEBHOOKS], new DefaultProgressStrategy()); + +ProgressStrategyRegistry.register(MODULE_NAMES[MODULE_CONTEXTS.WORKFLOWS], new DefaultProgressStrategy()); + +ProgressStrategyRegistry.register(MODULE_NAMES[MODULE_CONTEXTS.CUSTOM_ROLES], new DefaultProgressStrategy()); + +// Register strategy for Taxonomies - use Taxonomies & Terms as primary process +ProgressStrategyRegistry.register( + MODULE_NAMES[MODULE_CONTEXTS.TAXONOMIES], + new PrimaryProcessStrategy(PROCESS_NAMES.EXPORT_TAXONOMIES_TERMS), +); + +// Register strategy for Marketplace Apps - complex module with app installations +ProgressStrategyRegistry.register( + MODULE_NAMES[MODULE_CONTEXTS.MARKETPLACE_APPS], + new CustomProgressStrategy((processes) => { + // For marketplace apps, count the actual apps exported + const appsExport = processes.get(PROCESS_NAMES.FETCH_APPS); + if (appsExport) { + return { + total: appsExport.total, + success: appsExport.successCount, + failures: appsExport.failureCount, + }; + } + + const setup = processes.get(PROCESS_NAMES.FETCH_CONFIG_MANIFEST); + if (setup) { + return { + total: setup.total, + success: setup.successCount, + failures: setup.failureCount, + }; + } + + return null; + }), +); + +// Register strategy for Stack Settings - use Settings as primary process +ProgressStrategyRegistry.register( + MODULE_NAMES[MODULE_CONTEXTS.STACK], + new PrimaryProcessStrategy(PROCESS_NAMES.STACK_SETTINGS), +); + +// Register strategy for Personalize - complex module with projects/experiences +ProgressStrategyRegistry.register( + MODULE_NAMES[MODULE_CONTEXTS.PERSONALIZE], + new CustomProgressStrategy((processes) => { + // For personalize, we want to count projects as the main metric + const projectExport = processes.get(PROCESS_NAMES.PERSONALIZE_PROJECTS); + if (projectExport) { + return { + total: projectExport.total, + success: projectExport.successCount, + failures: projectExport.failureCount, + }; + } + + // Fallback to any other main process + const mainProcess = Array.from(processes.values())[0]; + if (mainProcess) { + return { + total: mainProcess.total, + success: mainProcess.successCount, + failures: mainProcess.failureCount, + }; + } + + return null; + }), +); + +// Register strategy for Entries - use Entries as primary process +ProgressStrategyRegistry.register( + MODULE_NAMES[MODULE_CONTEXTS.ENTRIES], + new PrimaryProcessStrategy(PROCESS_NAMES.ENTRIES), +); + +export default ProgressStrategyRegistry; diff --git a/packages/contentstack-import-setup/README.md b/packages/contentstack-import-setup/README.md index 42f5bfa525..e90e4f9f84 100644 --- a/packages/contentstack-import-setup/README.md +++ b/packages/contentstack-import-setup/README.md @@ -47,7 +47,7 @@ $ npm install -g @contentstack/cli-cm-import-setup $ csdx COMMAND running command... $ csdx (--version) -@contentstack/cli-cm-import-setup/1.5.0 darwin-arm64 node-v22.13.1 +@contentstack/cli-cm-import-setup/1.6.0 darwin-arm64 node-v22.13.1 $ csdx --help [COMMAND] USAGE $ csdx COMMAND @@ -78,6 +78,8 @@ FLAGS branches involved, then the path should point till the particular branch. For example, “-d "C:\Users\Name\Desktop\cli\content\branch_name" -k, --stack-api-key= API key of the target stack + --branch-alias= The alias of the branch where you want to import your content. If you don't mention the + branch alias, then by default the content will be imported to the main branch. --module=