diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bd8b7ca..dabb7c7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -3,6 +3,7 @@ on: push: branches: - main + - develop pull_request: types: [opened, synchronize, reopened] workflow_dispatch: @@ -22,7 +23,6 @@ jobs: steps: - uses: actions/checkout@v4 with: - # Shallow clones should be disabled for a better relevancy of sonarqube analysis fetch-depth: 0 - uses: pnpm/action-setup@v4 with: @@ -33,9 +33,20 @@ jobs: node-version: ${{ matrix.node_version }} cache: 'pnpm' - run: pnpm run test:coverage - - name: SonarCloud Scan + - name: SonarQube Scan if: matrix.os == 'ubuntu-latest' - uses: SonarSource/sonarcloud-github-action@master + uses: SonarSource/sonarqube-scan-action@v4.1.0 env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + - name: Codecov Scan + uses: codecov/codecov-action@v5 + with: + token: ${{ secrets.CODECOV_TOKEN }} + - name: Upload test results to Codecov + if: ${{ !cancelled() }} + uses: codecov/test-results-action@v1.0.1 + with: + token: ${{ secrets.CODECOV_TOKEN }} + files: coverage/junit.xml,!./cache + fail_ci_if_error: true diff --git a/.mocharc.json b/.mocharc.json index b9cf1e7..90a2e48 100644 --- a/.mocharc.json +++ b/.mocharc.json @@ -1,7 +1,8 @@ { "$schema": "https://json.schemastore.org/mocharc.json", "import": ["tsx"], - "reporter": "spec", + "reporter": "mocha-junit-reporter", + "reporter-option": ["mochaFile=coverage/junit.xml"], "timeout": 5000, "forbidOnly": true, "watch-files": ["src"], diff --git a/.nycrc.json b/.nycrc.json index f60736a..7ee89d7 100644 --- a/.nycrc.json +++ b/.nycrc.json @@ -10,7 +10,11 @@ "coverage/**", "dist/**", "node_modules/**", - "test/**", - "bin/**" + "bin/**", + "**/test/**", + "**/*.test.ts", + "src/utils/testing.ts", + "src/commands", + "**/*.d.ts" ] } diff --git a/README.md b/README.md index 598cfa4..03e1593 100644 --- a/README.md +++ b/README.md @@ -1,292 +1,22 @@ -[![NPM Version](https://img.shields.io/npm/v/ovm)](http://npmjs.com/package/ovm) -[![GitHub License](https://img.shields.io/github/license/msudgh/ovm)](LICENSE) -[![GitHub Actions Test Workflow Status](https://github.com/msudgh/ovm/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/msudgh/ovm/actions/workflows/test.yml) +# Obsidian Vaults Manager [![NPM Version](https://img.shields.io/npm/v/ovm)](http://npmjs.com/package/ovm) [![GitHub License](https://img.shields.io/github/license/msudgh/ovm)](LICENSE) [![GitHub Actions Test Workflow Status](https://github.com/msudgh/ovm/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/msudgh/ovm/actions/workflows/test.yml) ![Sonar Coverage](https://img.shields.io/sonar/coverage/msudgh_ovm?server=https%3A%2F%2Fsonarcloud.io) -ovm (Obsidian Vaults Manager) is a CLI application designed to streamline the management of vaults in Obsidian. This tool aims to overcome the limitations associated with performing bulk tasks on specific vaults and plugins. It enables users to install, uninstall, prune, and generate reports for a set of favorite plugins across multiple vaults, enhancing productivity and efficiency. - -**Table of Contents** - -- [Features](#features) -- [Requirements](#requirements) -- [Usage](#usage) -- [Config file](#config-file) -- [Commands](#commands) - - [`ovm config init`](#ovm-config-init) - - [`ovm plugins install`](#ovm-plugins-install) - - [`ovm plugins prune`](#ovm-plugins-prune) - - [`ovm plugins uninstall`](#ovm-plugins-uninstall) - - [`ovm reports stats`](#ovm-reports-stats) - - [`ovm vaults run`](#ovm-vaults-run) - - [Reserved placeholders](#reserved-placeholders) -- [License](#license) +OVM is a CLI application designed to independently streamline management of vaults and plugins for Obsidian end-users by enhancing productivity and efficiency. ## Features -- **Manage Obsidian plugins**: Install/Uninstall/Prune plugins in multiple vaults at one go. -- **Perform actions on Obsidian or custom vaults**: By default, Obsidian vaults are supported and detected. The vault-related commands support `-p` flag to define a custom vault/s from a path or [`Glob`]() pattern. e.g. `~/Documents/obsidian/*`. -- **Generate reports**: Generate statistics of vaults and installed plugins with Table/JSON output format. -- **Interactive CLI**: User-friendly interface to select vaults and plugins for each command. +- **Manage plugins**: Install, Uninstall, and Prune plugins in vaults. +- **Execute commands on vaults**: Run shell commands on vaults. +- **Generate reports**: Generate statistics of vaults and installed plugins. +- **Interactive CLI**: Easy wizard interface to select vaults and plugins for each command. - **Cross-platform**: Windows, macOS, and Linux. -## Requirements - -- Node.js 18.x or higher - -## Usage - -```bash -$ npm install -g ovm -$ ovm version -ovm/0.1.0 darwin-x64 node-v20.11.0 # Output may vary -$ ovm COMMAND -running command... -$ ovm --help [COMMAND] -USAGE - $ ovm COMMAND -... -``` - -**Common flags** - -```bash - -c, --config= [default: ~/ovm.json] Path to the config file. - -d, --debug Enable debugging mode. - -t, --timestamp Enable timestamp in logs. -``` - -## Config file - -The config file is created in the user's home directory by [`ovm ci`](#ovm-config-init--ovm-ci) and is named `ovm.json`. It contains an array of plugins that are to be installed across single/multiple vault. - -```json -{ - "plugins": [] -} -``` - -Example config file for following [Commands](#commands) section is as follows: - -```json -{ - "plugins": [ - { - "id": "colored-tags", - "version": "latest" - }, - { - "id": "copilot", - "version": "latest" - }, - { - "id": "dataview", - "version": "latest" - } - ] -} -``` - -## Commands - -> The content used in the examples below is for illustrative purposes only. e.g. In the output sections, the vaults are stored in `~/Documents/` directory. The actual output may vary. - -### `ovm config init` - -Aliases: `ovm ci` - -Configure an ovm.json config file in user's home directory. - -- _Usage:_ `ovm help config init` -- _See code:_ [src/commands/config/init.ts](src/commands/config/init.ts) - -Output - -```bash -$ ovm config init -info: Config file created {"path":"~/ovm.json"} - -$ cat ~/ovm.json -{ - "plugins": [] -} -``` - -### `ovm plugins install` - -Aliases: `ovm pi` - -Install plugin(s) in specified vaults. - -- _Usage:_ `ovm help plugins install` -- _See code:_ [src/commands/plugins/install.ts](src/commands/plugins/install.ts) - -Output - -```bash -$ ovm plugins install -? Select the vaults: Career, Financial, Goals -info: Installed plugin {"plugin":{"id":"colored-tags","version":"latest"},"vault":{"name":"Career","path":"~/Documents/obsidian/Career"}} -info: Installed plugin {"plugin":{"id":"copilot","version":"latest"},"vault":{"name":"Career","path":"~/Documents/obsidian/Career"}} -info: Installed plugin {"plugin":{"id":"dataview","version":"latest"},"vault":{"name":"Career","path":"~/Documents/obsidian/Career"}} -info: Installed 3 plugins {"vault":{"name":"Career","path":"~/Documents/obsidian/Career"}} -info: Installed plugin {"plugin":{"id":"colored-tags","version":"latest"},"vault":{"name":"Financial","path":"~/Documents/obsidian/Financial"}} -info: Installed plugin {"plugin":{"id":"copilot","version":"latest"},"vault":{"name":"Financial","path":"~/Documents/obsidian/Financial"}} -info: Installed plugin {"plugin":{"id":"dataview","version":"latest"},"vault":{"name":"Financial","path":"~/Documents/obsidian/Financial"}} -info: Installed 3 plugins {"vault":{"name":"Financial","path":"~/Documents/obsidian/Financial"}} -info: Installed plugin {"plugin":{"id":"colored-tags","version":"latest"},"vault":{"name":"Goals","path":"~/Documents/obsidian/Goals"}} -info: Installed plugin {"plugin":{"id":"copilot","version":"latest"},"vault":{"name":"Goals","path":"~/Documents/obsidian/Goals"}} -info: Installed plugin {"plugin":{"id":"dataview","version":"latest"},"vault":{"name":"Goals","path":"~/Documents/obsidian/Goals"}} -info: Installed 3 plugins {"vault":{"name":"Goals","path":"~/Documents/obsidian/Goals"}} -``` - -### `ovm plugins prune` - -Aliases: `ovm pp` - -Prune existing plugin(s) from vaults that are unspecified in the config file. - -- _Usage:_ `ovm help plugins prune` -- _See code:_ [src/commands/plugins/prune.ts](src/commands/plugins/prune.ts) - -Output - -```bash -$ ovm plugins prune -? Select the vaults: Test -info: Removed plugin {"pluginId":"obsidian-tasks-plugin","vaultPath":"~/Documents/obsidian/Test"} -info: Pruned 1 plugins {"vault":{"name":"Test","path":"~/Documents/obsidian/Test"}} -``` - -### `ovm plugins uninstall` - -Aliases: `ovm pu` - -Uninstall plugin(s) from vaults. - -- _Usage:_ `ovm help plugins uninstall` -- _See code:_ [src/commands/plugins/uninstall.ts](src/commands/plugins/uninstall.ts) - -Output - -```bash -$ ovm plugins uninstall -? Select the vaults: Career, Financial, Goals -? Select the plugins: colored-tags, copilot, dataview -info: Removed plugin {"pluginId":"colored-tags","vaultPath":"~/Documents/obsidian/Career"} -info: Removed plugin {"pluginId":"copilot","vaultPath":"~/Documents/obsidian/Career"} -info: Removed plugin {"pluginId":"dataview","vaultPath":"~/Documents/obsidian/Career"} -info: Uninstalled 3 plugins {"vault":{"name":"Career","path":"~/Documents/obsidian/Career"}} -info: Removed plugin {"pluginId":"colored-tags","vaultPath":"~/Documents/obsidian/Financial"} -info: Removed plugin {"pluginId":"copilot","vaultPath":"~/Documents/obsidian/Financial"} -info: Removed plugin {"pluginId":"dataview","vaultPath":"~/Documents/obsidian/Financial"} -info: Uninstalled 3 plugins {"vault":{"name":"Financial","path":"~/Documents/obsidian/Financial"}} -info: Removed plugin {"pluginId":"colored-tags","vaultPath":"~/Documents/obsidian/Goals"} -info: Removed plugin {"pluginId":"copilot","vaultPath":"~/Documents/obsidian/Goals"} -info: Removed plugin {"pluginId":"dataview","vaultPath":"~/Documents/obsidian/Goals"} -info: Uninstalled 3 plugins {"vault":{"name":"Goals","path":"~/Documents/obsidian/Goals"}} -``` - -### `ovm reports stats` - -Aliases: `ovm rs` - -Statistics of vaults and installed plugins. - -- _Usage:_ `ovm help reports stats` -- _See code:_ [src/commands/reports/stats.ts](src/commands/reports/stats.ts) - -Output: `Table (default)` / `JSON` - -```bash -$ ovm reports stats -? Select the vaults: Career, Financial, Goals -┌──────────────┬────────┐ -│ (index) │ Values │ -├──────────────┼────────┤ -│ totalVaults │ 3 │ -│ totalPlugins │ 3 │ -└──────────────┴────────┘ -┌──────────────────────────────────────────────────┬─────────────┬─────────────┬─────────┐ -│ (index) │ 0 │ 1 │ 2 │ -├──────────────────────────────────────────────────┼─────────────┼─────────────┼─────────┤ -│ colored-tags@5.0.0 (118.78 kB) │ 'Career' │ 'Financial' │ 'Goals' │ -│ copilot@2.5.2 (4.02 MB) │ 'Career' │ │ │ -│ dataview@0.5.67 (2.38 MB) │ 'Career' │ 'Financial' │ │ -└──────────────────────────────────────────────────┴─────────────┴─────────────┴─────────┘ -``` - -### `ovm vaults run` - -Aliases: `ovm vr` / `ovm r` / `ovm run` - -Run a shell command on selected vaults (using Node.js child_process). - -**Disclaimer: Any input containing shell metacharacters may be used to trigger arbitrary command execution, using of this command is at risk of command's caller.** - -- _Usage:_ `ovm help vaults run` -- _See code:_ [src/commands/vaults/run.ts](src/commands/vaults/run.ts) - -Output: `Table (default)` / `JSON` - -```bash -$ ovm vaults run -s "tar -cf '{0}.tar' '{0}'" -o=json -? Select the vaults: Career, Financial, Goals -info: Run command {"command":"tar -cf '~/Documents/obsidian/Career.tar' '~/Documents/obsidian/Career'","vault":{"name":"Career","path":"~/Documents/obsidian/Career"}} - -info: Run operation finished! {"custom_commands_log_path":"/var/folders/_v/j4w6kv1s27b6xjfzvl5k6lqm0000gn/T/ovm-custom-command.json"} -{ - "Career": { - "success": true, - "duration": "2 seconds", - "error": null - }, - "Financial": { - "success": true, - "duration": "1 second", - "error": null - }, - "Goals": { - "success": true, - "duration": "1 second", - "error": null - } -} - -$ ovm r "echo 'Path: {0}'" -info: Run command {"command":"echo 'Path: ~/Documents/obsidian/Career'","vault":{"name":"Career","path":"~/Documents/obsidian/Career"}} - -Path: ~/Documents/obsidian/Career - -info: Run operation finished! {"custom_commands_log_path":"/var/folders/_v/j4w6kv1s27b6xjfzvl5k6lqm0000gn/T/ovm-custom-command.json"} -┌─────────┬─────────┬──────────┬───────┐ -│ (index) │ success │ duration │ error │ -├─────────┼─────────┼──────────┼───────┤ -│ Career │ true │ '10 ms' │ null │ -└─────────┴─────────┴──────────┴───────┘ -``` - -#### Reserved placeholders - -A custom command can be executed on vault(s) by using reserved placeholders as string value within the shell command. The placeholders are replaced with the actual values during the execution. - -List of placeholders: - -- `{0}`: Vault path -- `{1}`: Vault name +## Documentation -Examples: +You can checkout the detailed documentation for OVM: -- Echo vault(s) path - - `ovm run "echo 'Path: {0}'"` -- Echo vault(s) path and name - - `ovm run "echo 'Path: {0}, Name: {1}'"` -- Echo vault(s) name and silent the command's result - - `ovm run -s "echo 'Path: {0}'"` -- Create an archive of vault(s) by `tar` command - - `ovm run "tar -cf '{0}.tar' '{0}'"` -- Encrypt vault(s) directory by `gpg` command [algo: `AES256`, passphrase `password`] - - `ovm run "tar -cf '{0}.tar' '{0}' && gpg --batch --symmetric --cipher-algo AES256 --passphrase 'password' '{0}.tar'"` -- Decrypt the archive of vault(s) by `gpg` command [passphrase: `password`] - - `ovm run "gpg -q --batch --decrypt --passphrase 'password' -o '{0}.tar' '{0}.tar.gpg'"` +- [Installation](docs/installation.md) +- [Configuration](docs/configuration.md) +- [Commands](docs/commands.md) ## License diff --git a/docs/commands.md b/docs/commands.md new file mode 100644 index 0000000..03f6c26 --- /dev/null +++ b/docs/commands.md @@ -0,0 +1,211 @@ +# Commands + +> OVM automatically detects Obsidian vaults for related commands and by using the `-p` flag with a path or a Glob pattern specify custom vaults (e.g., ~/Documents/obsidian/\*). +> The content used in the examples below is for illustrative purposes only. e.g. In the output sections, the vaults are stored in `~/Documents/` directory. + +All commands have a common set of options: + +```bash + -c, --config= [default: ~/ovm.json] Path to the config file. + -d, --debug Enable debugging mode. + -t, --timestamp Enable timestamp in logs. +``` + +## `ovm config init` + +Aliases: `ovm ci` + +Configure an ovm.json config file in user's home directory. + +- _Usage:_ `ovm help config init` +- _See code:_ [src/commands/config/init.ts](src/commands/config/init.ts) + +Output + +```bash +$ ovm config init +info: Config file created {"path":"~/ovm.json"} + +$ cat ~/ovm.json +{ + "plugins": [] +} +``` + +## `ovm plugins install` + +Aliases: `ovm pi` + +Install plugin(s) in specified vaults. + +- _Usage:_ `ovm help plugins install` +- _See code:_ [src/commands/plugins/install.ts](src/commands/plugins/install.ts) + +Output + +```bash +$ ovm plugins install +? Select the vaults: Career, Financial, Goals +info: Installed plugin {"plugin":{"id":"colored-tags","version":"latest"},"vault":{"name":"Career","path":"~/Documents/obsidian/Career"}} +info: Installed plugin {"plugin":{"id":"copilot","version":"latest"},"vault":{"name":"Career","path":"~/Documents/obsidian/Career"}} +info: Installed plugin {"plugin":{"id":"dataview","version":"latest"},"vault":{"name":"Career","path":"~/Documents/obsidian/Career"}} +info: Installed 3 plugins {"vault":{"name":"Career","path":"~/Documents/obsidian/Career"}} +info: Installed plugin {"plugin":{"id":"colored-tags","version":"latest"},"vault":{"name":"Financial","path":"~/Documents/obsidian/Financial"}} +info: Installed plugin {"plugin":{"id":"copilot","version":"latest"},"vault":{"name":"Financial","path":"~/Documents/obsidian/Financial"}} +info: Installed plugin {"plugin":{"id":"dataview","version":"latest"},"vault":{"name":"Financial","path":"~/Documents/obsidian/Financial"}} +info: Installed 3 plugins {"vault":{"name":"Financial","path":"~/Documents/obsidian/Financial"}} +info: Installed plugin {"plugin":{"id":"colored-tags","version":"latest"},"vault":{"name":"Goals","path":"~/Documents/obsidian/Goals"}} +info: Installed plugin {"plugin":{"id":"copilot","version":"latest"},"vault":{"name":"Goals","path":"~/Documents/obsidian/Goals"}} +info: Installed plugin {"plugin":{"id":"dataview","version":"latest"},"vault":{"name":"Goals","path":"~/Documents/obsidian/Goals"}} +info: Installed 3 plugins {"vault":{"name":"Goals","path":"~/Documents/obsidian/Goals"}} +``` + +## `ovm plugins prune` + +Aliases: `ovm pp` + +Prune existing plugin(s) from vaults that are unspecified in the config file. + +- _Usage:_ `ovm help plugins prune` +- _See code:_ [src/commands/plugins/prune.ts](src/commands/plugins/prune.ts) + +Output + +```bash +$ ovm plugins prune +? Select the vaults: Test +info: Removed plugin {"pluginId":"obsidian-tasks-plugin","vaultPath":"~/Documents/obsidian/Test"} +info: Pruned 1 plugins {"vault":{"name":"Test","path":"~/Documents/obsidian/Test"}} +``` + +## `ovm plugins uninstall` + +Aliases: `ovm pu` + +Uninstall plugin(s) from vaults. + +- _Usage:_ `ovm help plugins uninstall` +- _See code:_ [src/commands/plugins/uninstall.ts](src/commands/plugins/uninstall.ts) + +Output + +```bash +$ ovm plugins uninstall +? Select the vaults: Career, Financial, Goals +? Select the plugins: colored-tags, copilot, dataview +info: Removed plugin {"pluginId":"colored-tags","vaultPath":"~/Documents/obsidian/Career"} +info: Removed plugin {"pluginId":"copilot","vaultPath":"~/Documents/obsidian/Career"} +info: Removed plugin {"pluginId":"dataview","vaultPath":"~/Documents/obsidian/Career"} +info: Uninstalled 3 plugins {"vault":{"name":"Career","path":"~/Documents/obsidian/Career"}} +info: Removed plugin {"pluginId":"colored-tags","vaultPath":"~/Documents/obsidian/Financial"} +info: Removed plugin {"pluginId":"copilot","vaultPath":"~/Documents/obsidian/Financial"} +info: Removed plugin {"pluginId":"dataview","vaultPath":"~/Documents/obsidian/Financial"} +info: Uninstalled 3 plugins {"vault":{"name":"Financial","path":"~/Documents/obsidian/Financial"}} +info: Removed plugin {"pluginId":"colored-tags","vaultPath":"~/Documents/obsidian/Goals"} +info: Removed plugin {"pluginId":"copilot","vaultPath":"~/Documents/obsidian/Goals"} +info: Removed plugin {"pluginId":"dataview","vaultPath":"~/Documents/obsidian/Goals"} +info: Uninstalled 3 plugins {"vault":{"name":"Goals","path":"~/Documents/obsidian/Goals"}} +``` + +## `ovm reports stats` + +Aliases: `ovm rs` + +Statistics of vaults and installed plugins. + +- _Usage:_ `ovm help reports stats` +- _See code:_ [src/commands/reports/stats.ts](src/commands/reports/stats.ts) + +Output: `Table (default)` / `JSON` + +```bash +$ ovm reports stats +? Select the vaults: Career, Financial, Goals +┌──────────────┬────────┐ +│ (index) │ Values │ +├──────────────┼────────┤ +│ totalVaults │ 3 │ +│ totalPlugins │ 3 │ +└──────────────┴────────┘ +┌──────────────────────────────────────────────────┬─────────────┬─────────────┬─────────┐ +│ (index) │ 0 │ 1 │ 2 │ +├──────────────────────────────────────────────────┼─────────────┼─────────────┼─────────┤ +│ colored-tags@5.0.0 (118.78 kB) │ 'Career' │ 'Financial' │ 'Goals' │ +│ copilot@2.5.2 (4.02 MB) │ 'Career' │ │ │ +│ dataview@0.5.67 (2.38 MB) │ 'Career' │ 'Financial' │ │ +└──────────────────────────────────────────────────┴─────────────┴─────────────┴─────────┘ +``` + +## `ovm vaults run` + +Aliases: `ovm vr` / `ovm r` / `ovm run` + +Run a shell command on selected vaults (using Node.js child_process). + +**Disclaimer: Any input containing shell metacharacters may be used to trigger arbitrary command execution, using of this command is at risk of command's caller.** + +- _Usage:_ `ovm help vaults run` +- _See code:_ [src/commands/vaults/run.ts](src/commands/vaults/run.ts) + +Output: `Table (default)` / `JSON` + +```bash +$ ovm vaults run -s "tar -cf '{0}.tar' '{0}'" -o=json +? Select the vaults: Career, Financial, Goals +info: Run command {"command":"tar -cf '~/Documents/obsidian/Career.tar' '~/Documents/obsidian/Career'","vault":{"name":"Career","path":"~/Documents/obsidian/Career"}} + +info: Run operation finished! {"custom_commands_log_path":"/var/folders/_v/j4w6kv1s27b6xjfzvl5k6lqm0000gn/T/ovm-custom-command.json"} +{ + "Career": { + "success": true, + "duration": "2 seconds", + "error": null + }, + "Financial": { + "success": true, + "duration": "1 second", + "error": null + }, + "Goals": { + "success": true, + "duration": "1 second", + "error": null + } +} + +$ ovm r "echo 'Path: {0}'" +info: Run command {"command":"echo 'Path: ~/Documents/obsidian/Career'","vault":{"name":"Career","path":"~/Documents/obsidian/Career"}} + +Path: ~/Documents/obsidian/Career + +info: Run operation finished! {"custom_commands_log_path":"/var/folders/_v/j4w6kv1s27b6xjfzvl5k6lqm0000gn/T/ovm-custom-command.json"} +┌─────────┬─────────┬──────────┬───────┐ +│ (index) │ success │ duration │ error │ +├─────────┼─────────┼──────────┼───────┤ +│ Career │ true │ '10 ms' │ null │ +└─────────┴─────────┴──────────┴───────┘ +``` + +### Reserved placeholders + +A custom command can be executed on vault(s) by using reserved placeholders as string value within the shell command. The placeholders are replaced with the actual values during the execution. + +List of placeholders: + +- `{0}`: Vault path +- `{1}`: Vault name + +Examples: + +- Echo vault(s) path + - `ovm run "echo 'Path: {0}'"` +- Echo vault(s) path and name + - `ovm run "echo 'Path: {0}, Name: {1}'"` +- Echo vault(s) name and silent the command's result + - `ovm run -s "echo 'Path: {0}'"` +- Create an archive of vault(s) by `tar` command + - `ovm run "tar -cf '{0}.tar' '{0}'"` +- Encrypt vault(s) directory by `gpg` command [algo: `AES256`, passphrase `password`] + - `ovm run "tar -cf '{0}.tar' '{0}' && gpg --batch --symmetric --cipher-algo AES256 --passphrase 'password' '{0}.tar'"` +- Decrypt the archive of vault(s) by `gpg` command [passphrase: `password`] + - `ovm run "gpg -q --batch --decrypt --passphrase 'password' -o '{0}.tar' '{0}.tar.gpg'"` diff --git a/docs/configuration.md b/docs/configuration.md new file mode 100644 index 0000000..dfa005e --- /dev/null +++ b/docs/configuration.md @@ -0,0 +1,30 @@ +# Configuration + +The config file is created in the user's home directory by [`ovm ci`](#ovm-config-init) and is named `ovm.json`. It contains an array of plugins that are to be installed across single/multiple vault. + +```json +{ + "plugins": [] +} +``` + +Example config file for following [Commands](#commands) section is as follows: + +```json +{ + "plugins": [ + { + "id": "colored-tags", + "version": "latest" + }, + { + "id": "copilot", + "version": "latest" + }, + { + "id": "dataview", + "version": "latest" + } + ] +} +``` diff --git a/docs/installation.md b/docs/installation.md new file mode 100644 index 0000000..50215be --- /dev/null +++ b/docs/installation.md @@ -0,0 +1,13 @@ +# Installation + +```bash +$ npm install -g ovm +$ ovm version +ovm/0.1.0 darwin-x64 node-v20.11.0 # Output may vary +$ ovm COMMAND +running command... +$ ovm --help [COMMAND] +USAGE + $ ovm COMMAND +... +``` diff --git a/eslint.config.cjs b/eslint.config.cjs index 9c79ec7..3cc349d 100644 --- a/eslint.config.cjs +++ b/eslint.config.cjs @@ -1,43 +1,48 @@ -/* eslint-disable @typescript-eslint/no-var-requires */ -const pluginJs = require('@eslint/js') + +const eslint = require('@eslint/js') const globals = require('globals') -const tsEslint = require('typescript-eslint') +const tseslint = require('typescript-eslint') const rulesConfig = [ { rules: { 'no-unused-vars': [ 'error', - { - 'vars': 'all', - 'args': 'after-used', + { + 'vars': 'all', + 'args': 'after-used', 'ignoreRestSiblings': true, 'varsIgnorePattern': '^_', // Ignore variables that start with _ 'argsIgnorePattern': '^_' // Ignore arguments that start with _ } ], 'no-undef': 'warn', - 'prefer-arrow-callback': ['error', {allowNamedFunctions: false}], - 'func-style': ['error', 'expression', {allowArrowFunctions: true}], + 'prefer-arrow-callback': ['error', { allowNamedFunctions: false }], + 'func-style': ['error', 'expression', { allowArrowFunctions: true }], + 'no-unused-expressions': 'off', + '@typescript-eslint/no-unused-expressions': 'off', }, }, ] -const ignoresConfig = [{ignores: ['dist', 'bin', 'eslint.config.cjs']}] +const ignoresConfig = [{ ignores: ['dist', 'bin', 'eslint.config.cjs', 'coverage'] }] module.exports = [ - {files: ['**/*.{ts}', '**/*.test.ts', '**/*.spec.ts']}, { + files: ['**/*.ts', '**/*.test.ts', '**/*.spec.ts'], languageOptions: { globals: { - ...globals.browser, ...globals.node, ...globals.mocha, }, + parserOptions: { + projectService: true, + tsconfigRootDir: __dirname, + }, }, }, - pluginJs.configs.recommended, - ...tsEslint.configs.recommended, + eslint.configs.recommended, + ...tseslint.configs.recommended, ...rulesConfig, ...ignoresConfig, ] diff --git a/package.json b/package.json index 4c6917a..d56f958 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "ovm", "description": "Obsidian Vaults Manager", "type": "commonjs", - "version": "0.4.3", + "version": "0.4.6", "license": "MIT", "author": "Masoud Ghorbani", "homepage": "https://github.com/msudgh/ovm", @@ -12,7 +12,7 @@ "types": "dist/index.d.ts", "scripts": { "build": "shx rm -rf dist && tsc -p tsconfig.release.json", - "build:watch": "shx rm -rf dist && tsc -p tsconfig.release.json -w", + "build:watch": "shx rm -rf dist && tsc -p tsconfig.json -w", "build:release": "shx rm -rf dist && tsc -p tsconfig.release.json", "lint": "eslint .", "lint:fix": "eslint . --fix", @@ -21,8 +21,8 @@ "postpack": "shx rm -f oclif.manifest.json", "posttest": "pnpm run lint", "prepack": "oclif manifest && pnpm run build:release && pnpm run test:unit", - "test:unit": "pnpm run build && mocha", - "test:coverage": "nyc npm run test:unit" + "test:unit": "mocha -R=spec", + "test:coverage": "nyc mocha" }, "keywords": [ "obsidian", @@ -62,55 +62,60 @@ "/oclif.manifest.json" ], "dependencies": { - "@inquirer/core": "^9.0.10", - "@inquirer/prompts": "^5.3.8", - "@oclif/core": "^4.0.17", - "@oclif/plugin-help": "^6.2.8", - "async": "^3.2.5", - "date-fns": "^3.6.0", - "fast-folder-size": "^2.2.0", - "filesize": "^10.1.4", - "glob": "^11.0.0", - "inquirer": "^10.1.8", - "node-fetch-cache": "^4.1.2", - "obsidian-utils": "^0.10.2", - "winston": "^3.14.1", - "zod": "^3.23.8" + "@inquirer/core": "9.0.10", + "@inquirer/prompts": "5.3.8", + "@oclif/core": "4.0.36", + "@oclif/plugin-help": "6.2.19", + "async": "3.2.5", + "date-fns": "3.6.0", + "fast-folder-size": "2.2.0", + "filesize": "10.1.4", + "glob": "11.0.0", + "inquirer": "10.1.8", + "node-fetch-cache": "4.1.2", + "obsidian-utils": "0.10.2", + "winston": "3.14.1", + "zod": "3.23.8" }, "devDependencies": { - "@istanbuljs/nyc-config-typescript": "^1.0.2", - "@oclif/prettier-config": "^0.2.1", - "@oclif/test": "^4.0.8", - "@total-typescript/ts-reset": "^0.5.1", - "@types/async": "^3.2.24", - "@types/cacache": "^17.0.2", - "@types/chai": "^4.3.17", - "@types/inquirer": "^9.0.7", - "@types/mocha": "^10.0.7", - "@types/mock-fs": "^4.13.4", - "@types/node": "^22.1.0", - "@types/sinon": "^17.0.3", - "@types/validator": "^13.12.0", - "chai": "^5.1.1", - "eslint": "^9.8.0", - "eslint-config-prettier": "^9.1.0", - "globals": "^15.9.0", - "mocha": "^10.7.3", - "mock-fs": "^5.2.0", - "nyc": "^17.0.0", + "@istanbuljs/nyc-config-typescript": "1.0.2", + "@oclif/prettier-config": "0.2.1", + "@oclif/test": "4.1.3", + "@total-typescript/ts-reset": "0.5.1", + "@types/async": "3.2.24", + "@types/cacache": "17.0.2", + "@types/chai": "4.3.17", + "@types/fs-extra": "^11.0.4", + "@types/inquirer": "9.0.7", + "@types/mocha": "10.0.7", + "@types/mock-fs": "4.13.4", + "@types/node": "22.1.0", + "@types/sinon": "17.0.3", + "@types/validator": "13.12.0", + "chai": "5.1.1", + "eslint": "9.8.0", + "eslint-config-prettier": "9.1.0", + "fs-extra": "^11.2.0", + "globals": "15.9.0", + "mocha": "10.7.3", + "mocha-junit-reporter": "^2.2.1", + "mock-fs": "5.2.0", + "nyc": "17.0.0", "obsidian": "1.6.6", - "oclif": "^4.14.15", - "prettier": "^3.3.3", - "shx": "^0.3.4", - "sinon": "^18.0.0", - "ts-node": "^10.9.2", - "tsx": "^4.17.0", - "typescript": "^5.5.4", - "typescript-eslint": "^8.0.1" + "oclif": "4.16.0", + "prettier": "3.3.3", + "shx": "0.3.4", + "sinon": "19.0.2", + "ts-node": "10.9.2", + "tsx": "4.17.0", + "typescript": "5.5.4", + "typescript-eslint": "8.0.1" }, "pnpm": { "overrides": { - "fast-xml-parser@<4.4.1": ">=4.4.1" + "fast-xml-parser@<4.4.1": ">=4.4.1", + "eslint>ajv": "6", + "whatwg-url@<6.0.0": ">=14.0.0" } } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1a4a5ad..14591e0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,140 +6,151 @@ settings: overrides: fast-xml-parser@<4.4.1: '>=4.4.1' + eslint>ajv: '6' + whatwg-url@<6.0.0: '>=14.0.0' importers: .: dependencies: '@inquirer/core': - specifier: ^9.0.10 + specifier: 9.0.10 version: 9.0.10 '@inquirer/prompts': - specifier: ^5.3.8 + specifier: 5.3.8 version: 5.3.8 '@oclif/core': - specifier: ^4.0.17 - version: 4.0.17 + specifier: 4.0.36 + version: 4.0.36 '@oclif/plugin-help': - specifier: ^6.2.8 - version: 6.2.8 + specifier: 6.2.19 + version: 6.2.19 async: - specifier: ^3.2.5 + specifier: 3.2.5 version: 3.2.5 date-fns: - specifier: ^3.6.0 + specifier: 3.6.0 version: 3.6.0 fast-folder-size: - specifier: ^2.2.0 + specifier: 2.2.0 version: 2.2.0 filesize: - specifier: ^10.1.4 + specifier: 10.1.4 version: 10.1.4 glob: - specifier: ^11.0.0 + specifier: 11.0.0 version: 11.0.0 inquirer: - specifier: ^10.1.8 + specifier: 10.1.8 version: 10.1.8 node-fetch-cache: - specifier: ^4.1.2 + specifier: 4.1.2 version: 4.1.2 obsidian-utils: - specifier: ^0.10.2 + specifier: 0.10.2 version: 0.10.2 winston: - specifier: ^3.14.1 + specifier: 3.14.1 version: 3.14.1 zod: - specifier: ^3.23.8 + specifier: 3.23.8 version: 3.23.8 devDependencies: '@istanbuljs/nyc-config-typescript': - specifier: ^1.0.2 + specifier: 1.0.2 version: 1.0.2(nyc@17.0.0) '@oclif/prettier-config': - specifier: ^0.2.1 + specifier: 0.2.1 version: 0.2.1 '@oclif/test': - specifier: ^4.0.8 - version: 4.0.8(@oclif/core@4.0.17) + specifier: 4.1.3 + version: 4.1.3(@oclif/core@4.0.36) '@total-typescript/ts-reset': - specifier: ^0.5.1 + specifier: 0.5.1 version: 0.5.1 '@types/async': - specifier: ^3.2.24 + specifier: 3.2.24 version: 3.2.24 '@types/cacache': - specifier: ^17.0.2 + specifier: 17.0.2 version: 17.0.2 '@types/chai': - specifier: ^4.3.17 + specifier: 4.3.17 version: 4.3.17 + '@types/fs-extra': + specifier: ^11.0.4 + version: 11.0.4 '@types/inquirer': - specifier: ^9.0.7 + specifier: 9.0.7 version: 9.0.7 '@types/mocha': - specifier: ^10.0.7 + specifier: 10.0.7 version: 10.0.7 '@types/mock-fs': - specifier: ^4.13.4 + specifier: 4.13.4 version: 4.13.4 '@types/node': - specifier: ^22.1.0 + specifier: 22.1.0 version: 22.1.0 '@types/sinon': - specifier: ^17.0.3 + specifier: 17.0.3 version: 17.0.3 '@types/validator': - specifier: ^13.12.0 + specifier: 13.12.0 version: 13.12.0 chai: - specifier: ^5.1.1 + specifier: 5.1.1 version: 5.1.1 eslint: - specifier: ^9.8.0 + specifier: 9.8.0 version: 9.8.0 eslint-config-prettier: - specifier: ^9.1.0 + specifier: 9.1.0 version: 9.1.0(eslint@9.8.0) + fs-extra: + specifier: ^11.2.0 + version: 11.2.0 globals: - specifier: ^15.9.0 + specifier: 15.9.0 version: 15.9.0 mocha: - specifier: ^10.7.3 + specifier: 10.7.3 version: 10.7.3 + mocha-junit-reporter: + specifier: ^2.2.1 + version: 2.2.1(mocha@10.7.3) mock-fs: - specifier: ^5.2.0 + specifier: 5.2.0 version: 5.2.0 nyc: - specifier: ^17.0.0 + specifier: 17.0.0 version: 17.0.0 obsidian: specifier: 1.6.6 version: 1.6.6(@codemirror/state@6.4.1)(@codemirror/view@6.28.4) oclif: - specifier: ^4.14.15 - version: 4.14.15 + specifier: 4.16.0 + version: 4.16.0(@types/node@22.1.0) prettier: - specifier: ^3.3.3 + specifier: 3.3.3 version: 3.3.3 shx: - specifier: ^0.3.4 + specifier: 0.3.4 version: 0.3.4 sinon: - specifier: ^18.0.0 - version: 18.0.0 + specifier: 19.0.2 + version: 19.0.2 ts-node: - specifier: ^10.9.2 + specifier: 10.9.2 version: 10.9.2(@types/node@22.1.0)(typescript@5.5.4) tsx: - specifier: ^4.17.0 + specifier: 4.17.0 version: 4.17.0 typescript: - specifier: ^5.5.4 + specifier: 5.5.4 version: 5.5.4 typescript-eslint: - specifier: ^8.0.1 + specifier: 8.0.1 version: 8.0.1(eslint@9.8.0)(typescript@5.5.4) packages: @@ -171,205 +182,139 @@ packages: '@aws-crypto/util@5.2.0': resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==} - '@aws-sdk/client-cloudfront@3.624.0': - resolution: {integrity: sha512-QORmDtRjnhnZhKAQO8V2wVt/BN7CVli24CKfBd1SwTPS9evdjorzWlx+nFkzjpsgLAPpQbGnTC6AKDqTh8CRuw==} + '@aws-sdk/client-cloudfront@3.699.0': + resolution: {integrity: sha512-0tHdtyJ9xmlNsfZppYEflrtskxZjbwPCD4DzcFXRxXEteDtZhRshF1YGAEYUZ7Iad4ps+XbQOEiAJmWW+G2QFw==} engines: {node: '>=16.0.0'} - '@aws-sdk/client-s3@3.614.0': - resolution: {integrity: sha512-9BlhfeBegvyjOqHtcr9kvrT80wiy7EVUiqYyTFiiDv/hJIcG88XHQCZdLU7658XBkQ7aFrr5b8rF2HRD1oroxw==} + '@aws-sdk/client-s3@3.701.0': + resolution: {integrity: sha512-7iXmPC5r7YNjvwSsRbGq9oLVgfIWZesXtEYl908UqMmRj2sVAW/leLopDnbLT7TEedqlK0RasOZT05I0JTNdKw==} engines: {node: '>=16.0.0'} - '@aws-sdk/client-sso-oidc@3.614.0': - resolution: {integrity: sha512-BI1NWcpppbHg/28zbUg54dZeckork8BItZIcjls12vxasy+p3iEzrJVG60jcbUTTsk3Qc1tyxNfrdcVqx0y7Ww==} + '@aws-sdk/client-sso-oidc@3.699.0': + resolution: {integrity: sha512-u8a1GorY5D1l+4FQAf4XBUC1T10/t7neuwT21r0ymrtMFSK2a9QqVHKMoLkvavAwyhJnARSBM9/UQC797PFOFw==} engines: {node: '>=16.0.0'} peerDependencies: - '@aws-sdk/client-sts': ^3.614.0 + '@aws-sdk/client-sts': ^3.699.0 - '@aws-sdk/client-sso-oidc@3.624.0': - resolution: {integrity: sha512-Ki2uKYJKKtfHxxZsiMTOvJoVRP6b2pZ1u3rcUb2m/nVgBPUfLdl8ZkGpqE29I+t5/QaS/sEdbn6cgMUZwl+3Dg==} - engines: {node: '>=16.0.0'} - peerDependencies: - '@aws-sdk/client-sts': ^3.624.0 - - '@aws-sdk/client-sso@3.614.0': - resolution: {integrity: sha512-p5pyYaxRzBttjBkqfc8i3K7DzBdTg3ECdVgBo6INIUxfvDy0J8QUE8vNtCgvFIkq+uPw/8M+Eo4zzln7anuO0Q==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/client-sso@3.624.0': - resolution: {integrity: sha512-EX6EF+rJzMPC5dcdsu40xSi2To7GSvdGQNIpe97pD9WvZwM9tRNQnNM4T6HA4gjV1L6Jwk8rBlG/CnveXtLEMw==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/client-sts@3.614.0': - resolution: {integrity: sha512-i6QmaVA1KHHYNnI2VYQy/sc31rLm4+jSp8b/YbQpFnD0w3aXsrEEHHlxek45uSkHb4Nrj1omFBVy/xp1WVYx2Q==} + '@aws-sdk/client-sso@3.696.0': + resolution: {integrity: sha512-q5TTkd08JS0DOkHfUL853tuArf7NrPeqoS5UOvqJho8ibV9Ak/a/HO4kNvy9Nj3cib/toHYHsQIEtecUPSUUrQ==} engines: {node: '>=16.0.0'} - '@aws-sdk/client-sts@3.624.0': - resolution: {integrity: sha512-k36fLZCb2nfoV/DKK3jbRgO/Yf7/R80pgYfMiotkGjnZwDmRvNN08z4l06L9C+CieazzkgRxNUzyppsYcYsQaw==} + '@aws-sdk/client-sts@3.699.0': + resolution: {integrity: sha512-++lsn4x2YXsZPIzFVwv3fSUVM55ZT0WRFmPeNilYIhZClxHLmVAWKH4I55cY9ry60/aTKYjzOXkWwyBKGsGvQg==} engines: {node: '>=16.0.0'} - '@aws-sdk/core@3.614.0': - resolution: {integrity: sha512-BUuS5/1YkgmKc4J0bg83XEtMyDHVyqG2QDzfmhYe8gbOIZabUl1FlrFVwhCAthtrrI6MPGTQcERB4BtJKUSplw==} + '@aws-sdk/core@3.696.0': + resolution: {integrity: sha512-3c9III1k03DgvRZWg8vhVmfIXPG6hAciN9MzQTzqGngzWAELZF/WONRTRQuDFixVtarQatmLHYVw/atGeA2Byw==} engines: {node: '>=16.0.0'} - '@aws-sdk/core@3.624.0': - resolution: {integrity: sha512-WyFmPbhRIvtWi7hBp8uSFy+iPpj8ccNV/eX86hwF4irMjfc/FtsGVIAeBXxXM/vGCjkdfEzOnl+tJ2XACD4OXg==} + '@aws-sdk/credential-provider-env@3.696.0': + resolution: {integrity: sha512-T9iMFnJL7YTlESLpVFT3fg1Lkb1lD+oiaIC8KMpepb01gDUBIpj9+Y+pA/cgRWW0yRxmkDXNazAE2qQTVFGJzA==} engines: {node: '>=16.0.0'} - '@aws-sdk/credential-provider-env@3.609.0': - resolution: {integrity: sha512-v69ZCWcec2iuV9vLVJMa6fAb5xwkzN4jYIT8yjo2c4Ia/j976Q+TPf35Pnz5My48Xr94EFcaBazrWedF+kwfuQ==} + '@aws-sdk/credential-provider-http@3.696.0': + resolution: {integrity: sha512-GV6EbvPi2eq1+WgY/o2RFA3P7HGmnkIzCNmhwtALFlqMroLYWKE7PSeHw66Uh1dFQeVESn0/+hiUNhu1mB0emA==} engines: {node: '>=16.0.0'} - '@aws-sdk/credential-provider-env@3.620.1': - resolution: {integrity: sha512-ExuILJ2qLW5ZO+rgkNRj0xiAipKT16Rk77buvPP8csR7kkCflT/gXTyzRe/uzIiETTxM7tr8xuO9MP/DQXqkfg==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/credential-provider-http@3.614.0': - resolution: {integrity: sha512-YIEjlNUKb3Vo/iTnGAPdsiDC3FUUnNoex2OwU8LmR7AkYZiWdB8nx99DfgkkY+OFMUpw7nKD2PCOtuFONelfGA==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/credential-provider-http@3.622.0': - resolution: {integrity: sha512-VUHbr24Oll1RK3WR8XLUugLpgK9ZuxEm/NVeVqyFts1Ck9gsKpRg1x4eH7L7tW3SJ4TDEQNMbD7/7J+eoL2svg==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/credential-provider-ini@3.614.0': - resolution: {integrity: sha512-KfLuLFGwlvFSZ2MuzYwWGPb1y5TeiwX5okIDe0aQ1h10oD3924FXbN+mabOnUHQ8EFcGAtCaWbrC86mI7ktC6A==} + '@aws-sdk/credential-provider-ini@3.699.0': + resolution: {integrity: sha512-dXmCqjJnKmG37Q+nLjPVu22mNkrGHY8hYoOt3Jo9R2zr5MYV7s/NHsCHr+7E+BZ+tfZYLRPeB1wkpTeHiEcdRw==} engines: {node: '>=16.0.0'} peerDependencies: - '@aws-sdk/client-sts': ^3.614.0 + '@aws-sdk/client-sts': ^3.699.0 - '@aws-sdk/credential-provider-ini@3.624.0': - resolution: {integrity: sha512-mMoNIy7MO2WTBbdqMyLpbt6SZpthE6e0GkRYpsd0yozPt0RZopcBhEh+HG1U9Y1PVODo+jcMk353vAi61CfnhQ==} + '@aws-sdk/credential-provider-node@3.699.0': + resolution: {integrity: sha512-MmEmNDo1bBtTgRmdNfdQksXu4uXe66s0p1hi1YPrn1h59Q605eq/xiWbGL6/3KdkViH6eGUuABeV2ODld86ylg==} engines: {node: '>=16.0.0'} - peerDependencies: - '@aws-sdk/client-sts': ^3.624.0 - '@aws-sdk/credential-provider-node@3.614.0': - resolution: {integrity: sha512-4J6gPEuFZP0mkWq5E//oMS1vrmMM88iNNcv7TEljYnsc6JTAlKejCyFwx6CN+nkIhmIZsl06SXIhBemzBdBPfg==} + '@aws-sdk/credential-provider-process@3.696.0': + resolution: {integrity: sha512-mL1RcFDe9sfmyU5K1nuFkO8UiJXXxLX4JO1gVaDIOvPqwStpUAwi3A1BoeZhWZZNQsiKI810RnYGo0E0WB/hUA==} engines: {node: '>=16.0.0'} - '@aws-sdk/credential-provider-node@3.624.0': - resolution: {integrity: sha512-vYyGK7oNpd81BdbH5IlmQ6zfaQqU+rPwsKTDDBeLRjshtrGXOEpfoahVpG9PX0ibu32IOWp4ZyXBNyVrnvcMOw==} + '@aws-sdk/credential-provider-sso@3.699.0': + resolution: {integrity: sha512-Ekp2cZG4pl9D8+uKWm4qO1xcm8/MeiI8f+dnlZm8aQzizeC+aXYy9GyoclSf6daK8KfRPiRfM7ZHBBL5dAfdMA==} engines: {node: '>=16.0.0'} - '@aws-sdk/credential-provider-process@3.614.0': - resolution: {integrity: sha512-Q0SI0sTRwi8iNODLs5+bbv8vgz8Qy2QdxbCHnPk/6Cx6LMf7i3dqmWquFbspqFRd8QiqxStrblwxrUYZi09tkA==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/credential-provider-process@3.620.1': - resolution: {integrity: sha512-hWqFMidqLAkaV9G460+1at6qa9vySbjQKKc04p59OT7lZ5cO5VH5S4aI05e+m4j364MBROjjk2ugNvfNf/8ILg==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/credential-provider-sso@3.614.0': - resolution: {integrity: sha512-55+gp0JY4451cWI1qXmVMFM0GQaBKiQpXv2P0xmd9P3qLDyeFUSEW8XPh0d2lb1ICr6x4s47ynXVdGCIv2mXMg==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/credential-provider-sso@3.624.0': - resolution: {integrity: sha512-A02bayIjU9APEPKr3HudrFHEx0WfghoSPsPopckDkW7VBqO4wizzcxr75Q9A3vNX+cwg0wCN6UitTNe6pVlRaQ==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/credential-provider-web-identity@3.609.0': - resolution: {integrity: sha512-U+PG8NhlYYF45zbr1km3ROtBMYqyyj/oK8NRp++UHHeuavgrP+4wJ4wQnlEaKvJBjevfo3+dlIBcaeQ7NYejWg==} - engines: {node: '>=16.0.0'} - peerDependencies: - '@aws-sdk/client-sts': ^3.609.0 - - '@aws-sdk/credential-provider-web-identity@3.621.0': - resolution: {integrity: sha512-w7ASSyfNvcx7+bYGep3VBgC3K6vEdLmlpjT7nSIHxxQf+WSdvy+HynwJosrpZax0sK5q0D1Jpn/5q+r5lwwW6w==} + '@aws-sdk/credential-provider-web-identity@3.696.0': + resolution: {integrity: sha512-XJ/CVlWChM0VCoc259vWguFUjJDn/QwDqHwbx+K9cg3v6yrqXfK5ai+p/6lx0nQpnk4JzPVeYYxWRpaTsGC9rg==} engines: {node: '>=16.0.0'} peerDependencies: - '@aws-sdk/client-sts': ^3.621.0 - - '@aws-sdk/middleware-bucket-endpoint@3.614.0': - resolution: {integrity: sha512-TqEY8KcZeZ0LIxXaqG9RSSNnDHvD8RAFP4Xenwsxqnyad0Yn7LgCoFwRByelJ0t54ROYL1/ETJleWE4U4TOXdg==} - engines: {node: '>=16.0.0'} + '@aws-sdk/client-sts': ^3.696.0 - '@aws-sdk/middleware-expect-continue@3.609.0': - resolution: {integrity: sha512-+zeg//mSer4JZRxOB/4mUOMUJyuYPwATnIC5moBB8P8Xe+mJaVRFy8qlCtzYNj2TycnlsBPzTK0j7P1yvDh97w==} + '@aws-sdk/middleware-bucket-endpoint@3.696.0': + resolution: {integrity: sha512-V07jishKHUS5heRNGFpCWCSTjRJyQLynS/ncUeE8ZYtG66StOOQWftTwDfFOSoXlIqrXgb4oT9atryzXq7Z4LQ==} engines: {node: '>=16.0.0'} - '@aws-sdk/middleware-flexible-checksums@3.614.0': - resolution: {integrity: sha512-ZLpxVXMboDeMT7p2Kdp5m1uLVKOktkZoMgLvvbe3zbrU4Ji5IU5xVE0aa4X7H28BtuODCs6SLESnPs19bhMKlA==} + '@aws-sdk/middleware-expect-continue@3.696.0': + resolution: {integrity: sha512-vpVukqY3U2pb+ULeX0shs6L0aadNep6kKzjme/MyulPjtUDJpD3AekHsXRrCCGLmOqSKqRgQn5zhV9pQhHsb6Q==} engines: {node: '>=16.0.0'} - '@aws-sdk/middleware-host-header@3.609.0': - resolution: {integrity: sha512-iTKfo158lc4jLDfYeZmYMIBHsn8m6zX+XB6birCSNZ/rrlzAkPbGE43CNdKfvjyWdqgLMRXF+B+OcZRvqhMXPQ==} + '@aws-sdk/middleware-flexible-checksums@3.701.0': + resolution: {integrity: sha512-adNaPCyTT+CiVM0ufDiO1Fe7nlRmJdI9Hcgj0M9S6zR7Dw70Ra5z8Lslkd7syAccYvZaqxLklGjPQH/7GNxwTA==} engines: {node: '>=16.0.0'} - '@aws-sdk/middleware-host-header@3.620.0': - resolution: {integrity: sha512-VMtPEZwqYrII/oUkffYsNWY9PZ9xpNJpMgmyU0rlDQ25O1c0Hk3fJmZRe6pEkAJ0omD7kLrqGl1DUjQVxpd/Rg==} + '@aws-sdk/middleware-host-header@3.696.0': + resolution: {integrity: sha512-zELJp9Ta2zkX7ELggMN9qMCgekqZhFC5V2rOr4hJDEb/Tte7gpfKSObAnw/3AYiVqt36sjHKfdkoTsuwGdEoDg==} engines: {node: '>=16.0.0'} - '@aws-sdk/middleware-location-constraint@3.609.0': - resolution: {integrity: sha512-xzsdoTkszGVqGVPjUmgoP7TORiByLueMHieI1fhQL888WPdqctwAx3ES6d/bA9Q/i8jnc6hs+Fjhy8UvBTkE9A==} + '@aws-sdk/middleware-location-constraint@3.696.0': + resolution: {integrity: sha512-FgH12OB0q+DtTrP2aiDBddDKwL4BPOrm7w3VV9BJrSdkqQCNBPz8S1lb0y5eVH4tBG+2j7gKPlOv1wde4jF/iw==} engines: {node: '>=16.0.0'} - '@aws-sdk/middleware-logger@3.609.0': - resolution: {integrity: sha512-S62U2dy4jMDhDFDK5gZ4VxFdWzCtLzwbYyFZx2uvPYTECkepLUfzLic2BHg2Qvtu4QjX+oGE3P/7fwaGIsGNuQ==} + '@aws-sdk/middleware-logger@3.696.0': + resolution: {integrity: sha512-KhkHt+8AjCxcR/5Zp3++YPJPpFQzxpr+jmONiT/Jw2yqnSngZ0Yspm5wGoRx2hS1HJbyZNuaOWEGuJoxLeBKfA==} engines: {node: '>=16.0.0'} - '@aws-sdk/middleware-recursion-detection@3.609.0': - resolution: {integrity: sha512-6sewsYB7/o/nbUfA99Aa/LokM+a/u4Wpm/X2o0RxOsDtSB795ObebLJe2BxY5UssbGaWkn7LswyfvrdZNXNj1w==} + '@aws-sdk/middleware-recursion-detection@3.696.0': + resolution: {integrity: sha512-si/maV3Z0hH7qa99f9ru2xpS5HlfSVcasRlNUXKSDm611i7jFMWwGNLUOXFAOLhXotPX5G3Z6BLwL34oDeBMug==} engines: {node: '>=16.0.0'} - '@aws-sdk/middleware-recursion-detection@3.620.0': - resolution: {integrity: sha512-nh91S7aGK3e/o1ck64sA/CyoFw+gAYj2BDOnoNa6ouyCrVJED96ZXWbhye/fz9SgmNUZR2g7GdVpiLpMKZoI5w==} + '@aws-sdk/middleware-sdk-s3@3.696.0': + resolution: {integrity: sha512-M7fEiAiN7DBMHflzOFzh1I2MNSlLpbiH2ubs87bdRc2wZsDPSbs4l3v6h3WLhxoQK0bq6vcfroudrLBgvCuX3Q==} engines: {node: '>=16.0.0'} - '@aws-sdk/middleware-sdk-s3@3.614.0': - resolution: {integrity: sha512-9fJTaiuuOfFV4FqmUEhPYzrtv7JOfYpB7q65oG3uayVH4ngWHIJkjnnX79zRhNZKdPGta+XIsnZzjEghg82ngA==} + '@aws-sdk/middleware-ssec@3.696.0': + resolution: {integrity: sha512-w/d6O7AOZ7Pg3w2d3BxnX5RmGNWb5X4RNxF19rJqcgu/xqxxE/QwZTNd5a7eTsqLXAUIfbbR8hh0czVfC1pJLA==} engines: {node: '>=16.0.0'} - '@aws-sdk/middleware-signing@3.609.0': - resolution: {integrity: sha512-2w3dBLjQVKIajYzokO4hduq8/0hSMUYHHmIo1Kdl+MSY8uwRBt12bLL6pyreobTcRMxizvn2ph/CQ9I1ST/WGQ==} + '@aws-sdk/middleware-user-agent@3.696.0': + resolution: {integrity: sha512-Lvyj8CTyxrHI6GHd2YVZKIRI5Fmnugt3cpJo0VrKKEgK5zMySwEZ1n4dqPK6czYRWKd5+WnYHYAuU+Wdk6Jsjw==} engines: {node: '>=16.0.0'} - '@aws-sdk/middleware-ssec@3.609.0': - resolution: {integrity: sha512-GZSD1s7+JswWOTamVap79QiDaIV7byJFssBW68GYjyRS5EBjNfwA/8s+6uE6g39R3ojyTbYOmvcANoZEhSULXg==} + '@aws-sdk/region-config-resolver@3.696.0': + resolution: {integrity: sha512-7EuH142lBXjI8yH6dVS/CZeiK/WZsmb/8zP6bQbVYpMrppSTgB3MzZZdxVZGzL5r8zPQOU10wLC4kIMy0qdBVQ==} engines: {node: '>=16.0.0'} - '@aws-sdk/middleware-user-agent@3.614.0': - resolution: {integrity: sha512-xUxh0UPQiMTG6E31Yvu6zVYlikrIcFDKljM11CaatInzvZubGTGiX0DjpqRlfGzUNsuPc/zNrKwRP2+wypgqIw==} + '@aws-sdk/signature-v4-multi-region@3.696.0': + resolution: {integrity: sha512-ijPkoLjXuPtgxAYlDoYls8UaG/VKigROn9ebbvPL/orEY5umedd3iZTcS9T+uAf4Ur3GELLxMQiERZpfDKaz3g==} engines: {node: '>=16.0.0'} - '@aws-sdk/middleware-user-agent@3.620.0': - resolution: {integrity: sha512-bvS6etn+KsuL32ubY5D3xNof1qkenpbJXf/ugGXbg0n98DvDFQ/F+SMLxHgbnER5dsKYchNnhmtI6/FC3HFu/A==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/region-config-resolver@3.614.0': - resolution: {integrity: sha512-vDCeMXvic/LU0KFIUjpC3RiSTIkkvESsEfbVHiHH0YINfl8HnEqR5rj+L8+phsCeVg2+LmYwYxd5NRz4PHxt5g==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/signature-v4-multi-region@3.614.0': - resolution: {integrity: sha512-6mW3ONW4oLzxrePznYhz7sNT9ji9Am9ufLeV722tbOVS5lArBOZ6E1oPz0uYBhisUPznWKhcLRMggt7vIJWMng==} - engines: {node: '>=16.0.0'} - - '@aws-sdk/token-providers@3.614.0': - resolution: {integrity: sha512-okItqyY6L9IHdxqs+Z116y5/nda7rHxLvROxtAJdLavWTYDydxrZstImNgGWTeVdmc0xX2gJCI77UYUTQWnhRw==} + '@aws-sdk/token-providers@3.699.0': + resolution: {integrity: sha512-kuiEW9DWs7fNos/SM+y58HCPhcIzm1nEZLhe2/7/6+TvAYLuEWURYsbK48gzsxXlaJ2k/jGY3nIsA7RptbMOwA==} engines: {node: '>=16.0.0'} peerDependencies: - '@aws-sdk/client-sso-oidc': ^3.614.0 + '@aws-sdk/client-sso-oidc': ^3.699.0 - '@aws-sdk/types@3.609.0': - resolution: {integrity: sha512-+Tqnh9w0h2LcrUsdXyT1F8mNhXz+tVYBtP19LpeEGntmvHwa2XzvLUCWpoIAIVsHp5+HdB2X9Sn0KAtmbFXc2Q==} + '@aws-sdk/types@3.696.0': + resolution: {integrity: sha512-9rTvUJIAj5d3//U5FDPWGJ1nFJLuWb30vugGOrWk7aNZ6y9tuA3PI7Cc9dP8WEXKVyK1vuuk8rSFP2iqXnlgrw==} engines: {node: '>=16.0.0'} - '@aws-sdk/util-arn-parser@3.568.0': - resolution: {integrity: sha512-XUKJWWo+KOB7fbnPP0+g/o5Ulku/X53t7i/h+sPHr5xxYTJJ9CYnbToo95mzxe7xWvkLrsNtJ8L+MnNn9INs2w==} + '@aws-sdk/util-arn-parser@3.693.0': + resolution: {integrity: sha512-WC8x6ca+NRrtpAH64rWu+ryDZI3HuLwlEr8EU6/dbC/pt+r/zC0PBoC15VEygUaBA+isppCikQpGyEDu0Yj7gQ==} engines: {node: '>=16.0.0'} - '@aws-sdk/util-endpoints@3.614.0': - resolution: {integrity: sha512-wK2cdrXHH4oz4IomV/yrGkftU9A+ITB6nFL+rxxyO78is2ifHJpFdV4aqk4LSkXYPi6CXWNru/Dqc7yiKXgJPw==} + '@aws-sdk/util-endpoints@3.696.0': + resolution: {integrity: sha512-T5s0IlBVX+gkb9g/I6CLt4yAZVzMSiGnbUqWihWsHvQR1WOoIcndQy/Oz/IJXT9T2ipoy7a80gzV6a5mglrioA==} engines: {node: '>=16.0.0'} '@aws-sdk/util-locate-window@3.568.0': resolution: {integrity: sha512-3nh4TINkXYr+H41QaPelCceEB2FXP3fxp93YZXB/kqJvX0U9j0N0Uk45gvsjmEPzG8XxkPEeLIfT2I1M7A6Lig==} engines: {node: '>=16.0.0'} - '@aws-sdk/util-user-agent-browser@3.609.0': - resolution: {integrity: sha512-fojPU+mNahzQ0YHYBsx0ZIhmMA96H+ZIZ665ObU9tl+SGdbLneVZVikGve+NmHTQwHzwkFsZYYnVKAkreJLAtA==} + '@aws-sdk/util-user-agent-browser@3.696.0': + resolution: {integrity: sha512-Z5rVNDdmPOe6ELoM5AhF/ja5tSjbe6ctSctDPb0JdDf4dT0v2MfwhJKzXju2RzX8Es/77Glh7MlaXLE0kCB9+Q==} - '@aws-sdk/util-user-agent-node@3.614.0': - resolution: {integrity: sha512-15ElZT88peoHnq5TEoEtZwoXTXRxNrk60TZNdpl/TUBJ5oNJ9Dqb5Z4ryb8ofN6nm9aFf59GVAerFDz8iUoHBA==} + '@aws-sdk/util-user-agent-node@3.696.0': + resolution: {integrity: sha512-KhKqcfyXIB0SCCt+qsu4eJjsfiOrNzK5dCV7RAW2YIpp+msxGUUX0NdRE9rkzjiv+3EMktgJm3eEIS+yxtlVdQ==} engines: {node: '>=16.0.0'} peerDependencies: aws-crt: '>=1.0.0' @@ -377,8 +322,8 @@ packages: aws-crt: optional: true - '@aws-sdk/xml-builder@3.609.0': - resolution: {integrity: sha512-l9XxNcA4HX98rwCC2/KoiWcmEiRfZe4G+mYwDbCFT87JIMj6GBhLDkAzr/W8KAaA2IDr8Vc6J8fZPgVulxxfMA==} + '@aws-sdk/xml-builder@3.696.0': + resolution: {integrity: sha512-dn1mX+EeqivoLYnY7p2qLrir0waPnCgS/0YdRCAVU2x14FgfUYCH6Im3w3oi2dMwhxfKY5lYVB5NKvZu7uI9lQ==} engines: {node: '>=16.0.0'} '@babel/code-frame@7.24.7': @@ -671,74 +616,142 @@ packages: resolution: {integrity: sha512-5YwCySyV1UEgqzz34gNsC38eKxRBtlRDpJLlKcRtTjlYA/yDKuc1rfw+hjw+2WJxbAZtaDPsRl5Zk7J14SBoBw==} engines: {node: '>=18'} - '@inquirer/confirm@3.1.16': - resolution: {integrity: sha512-DXgLZim+YVTk05zRywvFRfJt2Jje7sZ4DO6Ss9RpGtgXEd/T0IiTqubHWst0IazCwdPI9g/06Rtm/nm4IBFJBA==} + '@inquirer/checkbox@4.0.2': + resolution: {integrity: sha512-+gznPl8ip8P8HYHYecDtUtdsh1t2jvb+sWCD72GAiZ9m45RqwrLmReDaqdC0umQfamtFXVRoMVJ2/qINKGm9Tg==} engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' '@inquirer/confirm@3.1.22': resolution: {integrity: sha512-gsAKIOWBm2Q87CDfs9fEo7wJT3fwWIJfnDGMn9Qy74gBnNFOACDNfhUzovubbJjWnKLGBln7/NcSmZwj5DuEXg==} engines: {node: '>=18'} + '@inquirer/confirm@5.0.2': + resolution: {integrity: sha512-KJLUHOaKnNCYzwVbryj3TNBxyZIrr56fR5N45v6K9IPrbT6B7DcudBMfylkV1A8PUdJE15mybkEQyp2/ZUpxUA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + + '@inquirer/core@10.1.0': + resolution: {integrity: sha512-I+ETk2AL+yAVbvuKx5AJpQmoaWhpiTFOg/UJb7ZkMAK4blmtG8ATh5ct+T/8xNld0CZG/2UhtkdMwpgvld92XQ==} + engines: {node: '>=18'} + '@inquirer/core@9.0.10': resolution: {integrity: sha512-TdESOKSVwf6+YWDz8GhS6nKscwzkIyakEzCLJ5Vh6O3Co2ClhCJ0A4MG909MUWfaWdpJm7DE45ii51/2Kat9tA==} engines: {node: '>=18'} + '@inquirer/core@9.2.1': + resolution: {integrity: sha512-F2VBt7W/mwqEU4bL0RnHNZmC/OxzNx9cOYxHqnXX3MP6ruYvZUZAW9imgN9+h/uBT/oP8Gh888J2OZSbjSeWcg==} + engines: {node: '>=18'} + '@inquirer/editor@2.1.22': resolution: {integrity: sha512-K1QwTu7GCK+nKOVRBp5HY9jt3DXOfPGPr6WRDrPImkcJRelG9UTx2cAtK1liXmibRrzJlTWOwqgWT3k2XnS62w==} engines: {node: '>=18'} + '@inquirer/editor@4.1.0': + resolution: {integrity: sha512-K1gGWsxEqO23tVdp5MT3H799OZ4ER1za7Dlc8F4um0W7lwSv0KGR/YyrUEyimj0g7dXZd8XknM/5QA2/Uy+TbA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + '@inquirer/expand@2.1.22': resolution: {integrity: sha512-wTZOBkzH+ItPuZ3ZPa9lynBsdMp6kQ9zbjVPYEtSBG7UulGjg2kQiAnUjgyG4SlntpTce5bOmXAPvE4sguXjpA==} engines: {node: '>=18'} - '@inquirer/figures@1.0.4': - resolution: {integrity: sha512-R7Gsg6elpuqdn55fBH2y9oYzrU/yKrSmIsDX4ROT51vohrECFzTf2zw9BfUbOW8xjfmM2QbVoVYdTwhrtEKWSQ==} + '@inquirer/expand@4.0.2': + resolution: {integrity: sha512-WdgCX1cUtinz+syKyZdJomovULYlKUWZbVYZzhf+ZeeYf4htAQ3jLymoNs3koIAKfZZl3HUBb819ClCBfyznaw==} engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' - '@inquirer/figures@1.0.5': - resolution: {integrity: sha512-79hP/VWdZ2UVc9bFGJnoQ/lQMpL74mGgzSYX1xUqCVk7/v73vJCMw1VuyWN1jGkZ9B3z7THAbySqGbCNefcjfA==} + '@inquirer/figures@1.0.8': + resolution: {integrity: sha512-tKd+jsmhq21AP1LhexC0pPwsCxEhGgAkg28byjJAd+xhmIs8LUX8JbUc3vBf3PhLxWiB5EvyBE5X7JSPAqMAqg==} engines: {node: '>=18'} '@inquirer/input@2.2.9': resolution: {integrity: sha512-7Z6N+uzkWM7+xsE+3rJdhdG/+mQgejOVqspoW+w0AbSZnL6nq5tGMEVASaYVWbkoSzecABWwmludO2evU3d31g==} engines: {node: '>=18'} + '@inquirer/input@4.0.2': + resolution: {integrity: sha512-yCLCraigU085EcdpIVEDgyfGv4vBiE4I+k1qRkc9C5dMjWF42ADMGy1RFU94+eZlz4YlkmFsiyHZy0W1wdhaNg==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + '@inquirer/number@1.0.10': resolution: {integrity: sha512-kWTxRF8zHjQOn2TJs+XttLioBih6bdc5CcosXIzZsrTY383PXI35DuhIllZKu7CdXFi2rz2BWPN9l0dPsvrQOA==} engines: {node: '>=18'} + '@inquirer/number@3.0.2': + resolution: {integrity: sha512-MKQhYofdUNk7eqJtz52KvM1dH6R93OMrqHduXCvuefKrsiMjHiMwjc3NZw5Imm2nqY7gWd9xdhYrtcHMJQZUxA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + '@inquirer/password@2.1.22': resolution: {integrity: sha512-5Fxt1L9vh3rAKqjYwqsjU4DZsEvY/2Gll+QkqR4yEpy6wvzLxdSgFhUcxfDAOtO4BEoTreWoznC0phagwLU5Kw==} engines: {node: '>=18'} + '@inquirer/password@4.0.2': + resolution: {integrity: sha512-tQXGSu7IO07gsYlGy3VgXRVsbOWqFBMbqAUrJSc1PDTQQ5Qdm+QVwkP0OC0jnUZ62D19iPgXOMO+tnWG+HhjNQ==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + '@inquirer/prompts@5.3.8': resolution: {integrity: sha512-b2BudQY/Si4Y2a0PdZZL6BeJtl8llgeZa7U2j47aaJSCeAl1e4UI7y8a9bSkO3o/ZbZrgT5muy/34JbsjfIWxA==} engines: {node: '>=18'} + '@inquirer/prompts@7.1.0': + resolution: {integrity: sha512-5U/XiVRH2pp1X6gpNAjWOglMf38/Ys522ncEHIKT1voRUvSj/DQnR22OVxHnwu5S+rCFaUiPQ57JOtMFQayqYA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + '@inquirer/rawlist@2.2.4': resolution: {integrity: sha512-pb6w9pWrm7EfnYDgQObOurh2d2YH07+eDo3xQBsNAM2GRhliz6wFXGi1thKQ4bN6B0xDd6C3tBsjdr3obsCl3Q==} engines: {node: '>=18'} + '@inquirer/rawlist@4.0.2': + resolution: {integrity: sha512-3XGcskMoVF8H0Dl1S5TSZ3rMPPBWXRcM0VeNVsS4ByWeWjSeb0lPqfnBg6N7T0608I1B2bSVnbi2cwCrmOD1Yw==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + '@inquirer/search@1.0.7': resolution: {integrity: sha512-p1wpV+3gd1eST/o5N3yQpYEdFNCzSP0Klrl+5bfD3cTTz8BGG6nf4Z07aBW0xjlKIj1Rp0y3x/X4cZYi6TfcLw==} engines: {node: '>=18'} - '@inquirer/select@2.4.1': - resolution: {integrity: sha512-m15ZwV2E2QDy0VbO/BRkVZ6TX6chYU+7K7//R47c3/Xai1d2AESHy4U88G7uq2mR1atl/p4HvMClKASNJvUDRg==} + '@inquirer/search@3.0.2': + resolution: {integrity: sha512-Zv4FC7w4dJ13BOJfKRQCICQfShinGjb1bCEIHxTSnjj2telu3+3RHwHubPG9HyD4aix5s+lyAMEK/wSFD75HLA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + + '@inquirer/select@2.5.0': + resolution: {integrity: sha512-YmDobTItPP3WcEI86GvPo+T2sRHkxxOq/kXmsBjHS5BVXUgvgZ5AfJjkvQvZr03T81NnI3KrrRuMzeuYUQRFOA==} engines: {node: '>=18'} - '@inquirer/select@2.4.7': - resolution: {integrity: sha512-JH7XqPEkBpNWp3gPCqWqY8ECbyMoFcCZANlL6pV9hf59qK6dGmkOlx1ydyhY+KZ0c5X74+W6Mtp+nm2QX0/MAQ==} + '@inquirer/select@4.0.2': + resolution: {integrity: sha512-uSWUzaSYAEj0hlzxa1mUB6VqrKaYx0QxGBLZzU4xWFxaSyGaXxsSE4OSOwdU24j0xl8OajgayqFXW0l2bkl2kg==} engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' - '@inquirer/type@1.5.0': - resolution: {integrity: sha512-L/UdayX9Z1lLN+itoTKqJ/X4DX5DaWu2Sruwt4XgZzMNv32x4qllbzMX4MbJlz0yxAQtU19UvABGOjmdq1u3qA==} + '@inquirer/type@1.5.5': + resolution: {integrity: sha512-MzICLu4yS7V8AA61sANROZ9vT1H3ooca5dSmI1FjZkzq7o/koMsRfQSzRtFo+F3Ao4Sf1C0bpLKejpKB/+j6MA==} engines: {node: '>=18'} - '@inquirer/type@1.5.2': - resolution: {integrity: sha512-w9qFkumYDCNyDZmNQjf/n6qQuvQ4dMC3BJesY4oF+yr0CxR5vxujflAVeIcS6U336uzi9GM0kAfZlLrZ9UTkpA==} + '@inquirer/type@2.0.0': + resolution: {integrity: sha512-XvJRx+2KR3YXyYtPUUy+qd9i7p+GO9Ko6VIIpWlBrpWwXDv8WLFeHTxz35CfQFUiBMLXlGHhGzys7lqit9gWag==} engines: {node: '>=18'} + '@inquirer/type@3.0.1': + resolution: {integrity: sha512-+ksJMIy92sOAiAccGpcKZUc3bYO07cADnscIxHBknEm3uNts3movSmBofc1908BNy5edKscxYeAdaX1NXkHS6A==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -794,27 +807,27 @@ packages: resolution: {integrity: sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - '@oclif/core@4.0.17': - resolution: {integrity: sha512-zfdSRip9DVMOklMojWCLZEB4iOzy7LDTABCDzCXqmpZGS+o1e1xts4jGhnte3mi0WV0YthNfYqF16tqk6CWITA==} + '@oclif/core@4.0.36': + resolution: {integrity: sha512-Dk0bK2Abl/AJ3Fn6ountX037lbXGJY/xcTnBJs2SKDqex9wMcgkbnkKd6xXC/zJnRlfA+jE+niC3FnbxgTRcHg==} engines: {node: '>=18.0.0'} - '@oclif/plugin-help@6.2.8': - resolution: {integrity: sha512-QRpFYlBeJffl4cXGBi8e+EfGogDmU7y8do1ZHxmPKZ5eZ0mfeKiqq2WA9dwRMZJriy1qSaGsbkOYgYQWlOYhSg==} + '@oclif/plugin-help@6.2.19': + resolution: {integrity: sha512-q2fIACWHJehppWTTgJm/llleKDgxt42IBVcK6Rp4H6qzET24t2zs0vbALx5XxsNCKl3/UuJhyW2XXQqvGmvWJQ==} engines: {node: '>=18.0.0'} - '@oclif/plugin-not-found@3.2.15': - resolution: {integrity: sha512-+i+ieIXS0Tqh/m7n5Mat81hjeY46Wo4pWV8dQKbX+kw2u0BxidBTYugZtMxz47PbYUT5rS/xYB5l31CAZf4yTg==} + '@oclif/plugin-not-found@3.2.29': + resolution: {integrity: sha512-TOS46arY8+YK30ks+mvLXwLq4YElMygXKsb8VPdYxUTvbn3yS9fpZ+4IjBo/IM4sZ88D51iXkNZFWt/nItT1Sg==} engines: {node: '>=18.0.0'} - '@oclif/plugin-warn-if-update-available@3.1.7': - resolution: {integrity: sha512-kQYwlSWNLqoT91H2NBKmj5HPyNcAiatJn4lAIGWbVgk08t+lMD7zOSAoRSN7gc2chelpAfmk4e5Mz4ANL8c7IQ==} + '@oclif/plugin-warn-if-update-available@3.1.23': + resolution: {integrity: sha512-0R15OCkpWktUsEdfVNvOIY078rE92Dkor2mB/F2/xW0/VEe3NQEVtiXMatpwYsjc4KKIiWtAVm2P0oQhEbodkg==} engines: {node: '>=18.0.0'} '@oclif/prettier-config@0.2.1': resolution: {integrity: sha512-XB8kwQj8zynXjIIWRm+6gO/r8Qft2xKtwBMSmq1JRqtA6TpwpqECqiu8LosBCyg2JBXuUy2lU23/L98KIR7FrQ==} - '@oclif/test@4.0.8': - resolution: {integrity: sha512-1UDwN2zrNRquQiWfn5wcokeQOOlJMrrn5KPufcrXzrh5otX9C/rkAGyQsJnEisbruPjOO541hzdybUzvK7Kvwg==} + '@oclif/test@4.1.3': + resolution: {integrity: sha512-GzV6BlCBX766htPW2dHmW5zgj4JNGhBXHjGx9Sq9UbdKcSc7G808bb+zx8+36f2DDveseFZ8LEd6l/S/qgyjFA==} engines: {node: '>=18.0.0'} peerDependencies: '@oclif/core': '>= 3.0.0' @@ -823,93 +836,91 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} + '@pnpm/config.env-replace@1.1.0': + resolution: {integrity: sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==} + engines: {node: '>=12.22.0'} + + '@pnpm/network.ca-file@1.0.2': + resolution: {integrity: sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==} + engines: {node: '>=12.22.0'} + + '@pnpm/npm-conf@2.3.1': + resolution: {integrity: sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw==} + engines: {node: '>=12'} + '@sindresorhus/is@5.6.0': resolution: {integrity: sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==} engines: {node: '>=14.16'} - '@sinonjs/commons@2.0.0': - resolution: {integrity: sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==} - '@sinonjs/commons@3.0.1': resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} - '@sinonjs/fake-timers@11.2.2': - resolution: {integrity: sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==} + '@sinonjs/fake-timers@13.0.5': + resolution: {integrity: sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==} - '@sinonjs/samsam@8.0.0': - resolution: {integrity: sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==} + '@sinonjs/samsam@8.0.2': + resolution: {integrity: sha512-v46t/fwnhejRSFTGqbpn9u+LQ9xJDse10gNnPgAcxgdoCDMXj/G2asWAC/8Qs+BAZDicX+MNZouXT1A7c83kVw==} - '@sinonjs/text-encoding@0.7.2': - resolution: {integrity: sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==} + '@sinonjs/text-encoding@0.7.3': + resolution: {integrity: sha512-DE427ROAphMQzU4ENbliGYrBSYPXF+TtLg9S8vzeA+OF4ZKzoDdzfL8sxuMUGS/lgRhM6j1URSk9ghf7Xo1tyA==} - '@smithy/abort-controller@3.1.1': - resolution: {integrity: sha512-MBJBiidoe+0cTFhyxT8g+9g7CeVccLM0IOKKUMCNQ1CNMJ/eIfoo0RTfVrXOONEI1UCN1W+zkiHSbzUNE9dZtQ==} + '@smithy/abort-controller@3.1.8': + resolution: {integrity: sha512-+3DOBcUn5/rVjlxGvUPKc416SExarAQ+Qe0bqk30YSUjbepwpS7QN0cyKUSifvLJhdMZ0WPzPP5ymut0oonrpQ==} engines: {node: '>=16.0.0'} - '@smithy/chunked-blob-reader-native@3.0.0': - resolution: {integrity: sha512-VDkpCYW+peSuM4zJip5WDfqvg2Mo/e8yxOv3VF1m11y7B8KKMKVFtmZWDe36Fvk8rGuWrPZHHXZ7rR7uM5yWyg==} + '@smithy/chunked-blob-reader-native@3.0.1': + resolution: {integrity: sha512-VEYtPvh5rs/xlyqpm5NRnfYLZn+q0SRPELbvBV+C/G7IQ+ouTuo+NKKa3ShG5OaFR8NYVMXls9hPYLTvIKKDrQ==} - '@smithy/chunked-blob-reader@3.0.0': - resolution: {integrity: sha512-sbnURCwjF0gSToGlsBiAmd1lRCmSn72nu9axfJu5lIx6RUEgHu6GwTMbqCdhQSi0Pumcm5vFxsi9XWXb2mTaoA==} + '@smithy/chunked-blob-reader@4.0.0': + resolution: {integrity: sha512-jSqRnZvkT4egkq/7b6/QRCNXmmYVcHwnJldqJ3IhVpQE2atObVJ137xmGeuGFhjFUr8gCEVAOKwSY79OvpbDaQ==} - '@smithy/config-resolver@3.0.5': - resolution: {integrity: sha512-SkW5LxfkSI1bUC74OtfBbdz+grQXYiPYolyu8VfpLIjEoN/sHVBlLeGXMQ1vX4ejkgfv6sxVbQJ32yF2cl1veA==} + '@smithy/config-resolver@3.0.12': + resolution: {integrity: sha512-YAJP9UJFZRZ8N+UruTeq78zkdjUHmzsY62J4qKWZ4SXB4QXJ/+680EfXXgkYA2xj77ooMqtUY9m406zGNqwivQ==} engines: {node: '>=16.0.0'} - '@smithy/core@2.2.6': - resolution: {integrity: sha512-tBbVIv/ui7/lLTKayYJJvi8JLVL2SwOQTbNFEOrvzSE3ktByvsa1erwBOnAMo8N5Vu30g7lN4lLStrU75oDGuw==} + '@smithy/core@2.5.4': + resolution: {integrity: sha512-iFh2Ymn2sCziBRLPuOOxRPkuCx/2gBdXtBGuCUFLUe6bWYjKnhHyIPqGeNkLZ5Aco/5GjebRTBFiWID3sDbrKw==} engines: {node: '>=16.0.0'} - '@smithy/core@2.3.2': - resolution: {integrity: sha512-in5wwt6chDBcUv1Lw1+QzZxN9fBffi+qOixfb65yK4sDuKG7zAUO9HAFqmVzsZM3N+3tTyvZjtnDXePpvp007Q==} + '@smithy/credential-provider-imds@3.2.7': + resolution: {integrity: sha512-cEfbau+rrWF8ylkmmVAObOmjbTIzKyUC5TkBL58SbLywD0RCBC4JAUKbmtSm2w5KUJNRPGgpGFMvE2FKnuNlWQ==} engines: {node: '>=16.0.0'} - '@smithy/credential-provider-imds@3.1.4': - resolution: {integrity: sha512-NKyH01m97Xa5xf3pB2QOF3lnuE8RIK0hTVNU5zvZAwZU8uspYO4DHQVlK+Y5gwSrujTfHvbfd1D9UFJAc0iYKQ==} - engines: {node: '>=16.0.0'} + '@smithy/eventstream-codec@3.1.9': + resolution: {integrity: sha512-F574nX0hhlNOjBnP+noLtsPFqXnWh2L0+nZKCwcu7P7J8k+k+rdIDs+RMnrMwrzhUE4mwMgyN0cYnEn0G8yrnQ==} - '@smithy/credential-provider-imds@3.2.0': - resolution: {integrity: sha512-0SCIzgd8LYZ9EJxUjLXBmEKSZR/P/w6l7Rz/pab9culE/RWuqelAKGJvn5qUOl8BgX8Yj5HWM50A5hiB/RzsgA==} + '@smithy/eventstream-serde-browser@3.0.13': + resolution: {integrity: sha512-Nee9m+97o9Qj6/XeLz2g2vANS2SZgAxV4rDBMKGHvFJHU/xz88x2RwCkwsvEwYjSX4BV1NG1JXmxEaDUzZTAtw==} engines: {node: '>=16.0.0'} - '@smithy/eventstream-codec@3.1.2': - resolution: {integrity: sha512-0mBcu49JWt4MXhrhRAlxASNy0IjDRFU+aWNDRal9OtUJvJNiwDuyKMUONSOjLjSCeGwZaE0wOErdqULer8r7yw==} - - '@smithy/eventstream-serde-browser@3.0.4': - resolution: {integrity: sha512-Eo4anLZX6ltGJTZ5yJMc80gZPYYwBn44g0h7oFq6et+TYr5dUsTpIcDbz2evsOKIZhZ7zBoFWHtBXQ4QQeb5xA==} + '@smithy/eventstream-serde-config-resolver@3.0.10': + resolution: {integrity: sha512-K1M0x7P7qbBUKB0UWIL5KOcyi6zqV5mPJoL0/o01HPJr0CSq3A9FYuJC6e11EX6hR8QTIR++DBiGrYveOu6trw==} engines: {node: '>=16.0.0'} - '@smithy/eventstream-serde-config-resolver@3.0.3': - resolution: {integrity: sha512-NVTYjOuYpGfrN/VbRQgn31x73KDLfCXCsFdad8DiIc3IcdxL+dYA9zEQPyOP7Fy2QL8CPy2WE4WCUD+ZsLNfaQ==} + '@smithy/eventstream-serde-node@3.0.12': + resolution: {integrity: sha512-kiZymxXvZ4tnuYsPSMUHe+MMfc4FTeFWJIc0Q5wygJoUQM4rVHNghvd48y7ppuulNMbuYt95ah71pYc2+o4JOA==} engines: {node: '>=16.0.0'} - '@smithy/eventstream-serde-node@3.0.4': - resolution: {integrity: sha512-mjlG0OzGAYuUpdUpflfb9zyLrBGgmQmrobNT8b42ZTsGv/J03+t24uhhtVEKG/b2jFtPIHF74Bq+VUtbzEKOKg==} + '@smithy/eventstream-serde-universal@3.0.12': + resolution: {integrity: sha512-1i8ifhLJrOZ+pEifTlF0EfZzMLUGQggYQ6WmZ4d5g77zEKf7oZ0kvh1yKWHPjofvOwqrkwRDVuxuYC8wVd662A==} engines: {node: '>=16.0.0'} - '@smithy/eventstream-serde-universal@3.0.4': - resolution: {integrity: sha512-Od9dv8zh3PgOD7Vj4T3HSuox16n0VG8jJIM2gvKASL6aCtcS8CfHZDWe1Ik3ZXW6xBouU+45Q5wgoliWDZiJ0A==} - engines: {node: '>=16.0.0'} - - '@smithy/fetch-http-handler@3.2.1': - resolution: {integrity: sha512-0w0bgUvZmfa0vHN8a+moByhCJT07WN6AHKEhFSOLsDpnszm+5dLVv5utGaqbhOrZ/aF5x3xuPMs/oMCd+4O5xg==} - - '@smithy/fetch-http-handler@3.2.4': - resolution: {integrity: sha512-kBprh5Gs5h7ug4nBWZi1FZthdqSM+T7zMmsZxx0IBvWUn7dK3diz2SHn7Bs4dQGFDk8plDv375gzenDoNwrXjg==} + '@smithy/fetch-http-handler@4.1.1': + resolution: {integrity: sha512-bH7QW0+JdX0bPBadXt8GwMof/jz0H28I84hU1Uet9ISpzUqXqRQ3fEZJ+ANPOhzSEczYvANNl3uDQDYArSFDtA==} - '@smithy/hash-blob-browser@3.1.2': - resolution: {integrity: sha512-hAbfqN2UbISltakCC2TP0kx4LqXBttEv2MqSPE98gVuDFMf05lU+TpC41QtqGP3Ff5A3GwZMPfKnEy0VmEUpmg==} + '@smithy/hash-blob-browser@3.1.9': + resolution: {integrity: sha512-wOu78omaUuW5DE+PVWXiRKWRZLecARyP3xcq5SmkXUw9+utgN8HnSnBfrjL2B/4ZxgqPjaAJQkC/+JHf1ITVaQ==} - '@smithy/hash-node@3.0.3': - resolution: {integrity: sha512-2ctBXpPMG+B3BtWSGNnKELJ7SH9e4TNefJS0cd2eSkOOROeBnnVBnAy9LtJ8tY4vUEoe55N4CNPxzbWvR39iBw==} + '@smithy/hash-node@3.0.10': + resolution: {integrity: sha512-3zWGWCHI+FlJ5WJwx73Mw2llYR8aflVyZN5JhoqLxbdPZi6UyKSdCeXAWJw9ja22m6S6Tzz1KZ+kAaSwvydi0g==} engines: {node: '>=16.0.0'} - '@smithy/hash-stream-node@3.1.2': - resolution: {integrity: sha512-PBgDMeEdDzi6JxKwbfBtwQG9eT9cVwsf0dZzLXoJF4sHKHs5HEo/3lJWpn6jibfJwT34I1EBXpBnZE8AxAft6g==} + '@smithy/hash-stream-node@3.1.9': + resolution: {integrity: sha512-3XfHBjSP3oDWxLmlxnt+F+FqXpL3WlXs+XXaB6bV9Wo8BBu87fK1dSEsyH7Z4ZHRmwZ4g9lFMdf08m9hoX1iRA==} engines: {node: '>=16.0.0'} - '@smithy/invalid-dependency@3.0.3': - resolution: {integrity: sha512-ID1eL/zpDULmHJbflb864k72/SNOZCADRc9i7Exq3RUNJw6raWUSlFEQ+3PX3EYs++bTxZB2dE9mEHTQLv61tw==} + '@smithy/invalid-dependency@3.0.10': + resolution: {integrity: sha512-Lp2L65vFi+cj0vFMu2obpPW69DU+6O5g3086lmI4XcnRCG8PxvpWC7XyaVwJCxsZFzueHjXnrOH/E0pl0zikfA==} '@smithy/is-array-buffer@2.2.0': resolution: {integrity: sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==} @@ -919,103 +930,75 @@ packages: resolution: {integrity: sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ==} engines: {node: '>=16.0.0'} - '@smithy/md5-js@3.0.3': - resolution: {integrity: sha512-O/SAkGVwpWmelpj/8yDtsaVe6sINHLB1q8YE/+ZQbDxIw3SRLbTZuRaI10K12sVoENdnHqzPp5i3/H+BcZ3m3Q==} + '@smithy/md5-js@3.0.10': + resolution: {integrity: sha512-m3bv6dApflt3fS2Y1PyWPUtRP7iuBlvikEOGwu0HsCZ0vE7zcIX+dBoh3e+31/rddagw8nj92j0kJg2TfV+SJA==} - '@smithy/middleware-content-length@3.0.3': - resolution: {integrity: sha512-Dbz2bzexReYIQDWMr+gZhpwBetNXzbhnEMhYKA6urqmojO14CsXjnsoPYO8UL/xxcawn8ZsuVU61ElkLSltIUQ==} + '@smithy/middleware-content-length@3.0.12': + resolution: {integrity: sha512-1mDEXqzM20yywaMDuf5o9ue8OkJ373lSPbaSjyEvkWdqELhFMyNNgKGWL/rCSf4KME8B+HlHKuR8u9kRj8HzEQ==} engines: {node: '>=16.0.0'} - '@smithy/middleware-content-length@3.0.5': - resolution: {integrity: sha512-ILEzC2eyxx6ncej3zZSwMpB5RJ0zuqH7eMptxC4KN3f+v9bqT8ohssKbhNR78k/2tWW+KS5Spw+tbPF4Ejyqvw==} + '@smithy/middleware-endpoint@3.2.4': + resolution: {integrity: sha512-TybiW2LA3kYVd3e+lWhINVu1o26KJbBwOpADnf0L4x/35vLVica77XVR5hvV9+kWeTGeSJ3IHTcYxbRxlbwhsg==} engines: {node: '>=16.0.0'} - '@smithy/middleware-endpoint@3.0.5': - resolution: {integrity: sha512-V4acqqrh5tDxUEGVTOgf2lYMZqPQsoGntCrjrJZEeBzEzDry2d2vcI1QCXhGltXPPY+BMc6eksZMguA9fIY8vA==} + '@smithy/middleware-retry@3.0.28': + resolution: {integrity: sha512-vK2eDfvIXG1U64FEUhYxoZ1JSj4XFbYWkK36iz02i3pFwWiDz1Q7jKhGTBCwx/7KqJNk4VS7d7cDLXFOvP7M+g==} engines: {node: '>=16.0.0'} - '@smithy/middleware-endpoint@3.1.0': - resolution: {integrity: sha512-5y5aiKCEwg9TDPB4yFE7H6tYvGFf1OJHNczeY10/EFF8Ir8jZbNntQJxMWNfeQjC1mxPsaQ6mR9cvQbf+0YeMw==} + '@smithy/middleware-serde@3.0.10': + resolution: {integrity: sha512-MnAuhh+dD14F428ubSJuRnmRsfOpxSzvRhaGVTvd/lrUDE3kxzCCmH8lnVTvoNQnV2BbJ4c15QwZ3UdQBtFNZA==} engines: {node: '>=16.0.0'} - '@smithy/middleware-retry@3.0.14': - resolution: {integrity: sha512-7ZaWZJOjUxa5hgmuMspyt8v/zVsh0GXYuF7OvCmdcbVa/xbnKQoYC+uYKunAqRGTkxjOyuOCw9rmFUFOqqC0eQ==} + '@smithy/middleware-stack@3.0.10': + resolution: {integrity: sha512-grCHyoiARDBBGPyw2BeicpjgpsDFWZZxptbVKb3CRd/ZA15F/T6rZjCCuBUjJwdck1nwUuIxYtsS4H9DDpbP5w==} engines: {node: '>=16.0.0'} - '@smithy/middleware-retry@3.0.9': - resolution: {integrity: sha512-Mrv9omExU1gA7Y0VEJG2LieGfPYtwwcEiOnVGZ54a37NEMr66TJ0glFslOJFuKWG6izg5DpKIUmDV9rRxjm47Q==} + '@smithy/node-config-provider@3.1.11': + resolution: {integrity: sha512-URq3gT3RpDikh/8MBJUB+QGZzfS7Bm6TQTqoh4CqE8NBuyPkWa5eUXj0XFcFfeZVgg3WMh1u19iaXn8FvvXxZw==} engines: {node: '>=16.0.0'} - '@smithy/middleware-serde@3.0.3': - resolution: {integrity: sha512-puUbyJQBcg9eSErFXjKNiGILJGtiqmuuNKEYNYfUD57fUl4i9+mfmThtQhvFXU0hCVG0iEJhvQUipUf+/SsFdA==} + '@smithy/node-http-handler@3.3.1': + resolution: {integrity: sha512-fr+UAOMGWh6bn4YSEezBCpJn9Ukp9oR4D32sCjCo7U81evE11YePOQ58ogzyfgmjIO79YeOdfXXqr0jyhPQeMg==} engines: {node: '>=16.0.0'} - '@smithy/middleware-stack@3.0.3': - resolution: {integrity: sha512-r4klY9nFudB0r9UdSMaGSyjyQK5adUyPnQN/ZM6M75phTxOdnc/AhpvGD1fQUvgmqjQEBGCwpnPbDm8pH5PapA==} + '@smithy/property-provider@3.1.10': + resolution: {integrity: sha512-n1MJZGTorTH2DvyTVj+3wXnd4CzjJxyXeOgnTlgNVFxaaMeT4OteEp4QrzF8p9ee2yg42nvyVK6R/awLCakjeQ==} engines: {node: '>=16.0.0'} - '@smithy/node-config-provider@3.1.4': - resolution: {integrity: sha512-YvnElQy8HR4vDcAjoy7Xkx9YT8xZP4cBXcbJSgm/kxmiQu08DwUwj8rkGnyoJTpfl/3xYHH+d8zE+eHqoDCSdQ==} + '@smithy/protocol-http@4.1.7': + resolution: {integrity: sha512-FP2LepWD0eJeOTm0SjssPcgqAlDFzOmRXqXmGhfIM52G7Lrox/pcpQf6RP4F21k0+O12zaqQt5fCDOeBtqY6Cg==} engines: {node: '>=16.0.0'} - '@smithy/node-http-handler@3.1.2': - resolution: {integrity: sha512-Td3rUNI7qqtoSLTsJBtsyfoG4cF/XMFmJr6Z2dX8QNzIi6tIW6YmuyFml8mJ2cNpyWNqITKbROMOFrvQjmsOvw==} + '@smithy/querystring-builder@3.0.10': + resolution: {integrity: sha512-nT9CQF3EIJtIUepXQuBFb8dxJi3WVZS3XfuDksxSCSn+/CzZowRLdhDn+2acbBv8R6eaJqPupoI/aRFIImNVPQ==} engines: {node: '>=16.0.0'} - '@smithy/node-http-handler@3.1.4': - resolution: {integrity: sha512-+UmxgixgOr/yLsUxcEKGH0fMNVteJFGkmRltYFHnBMlogyFdpzn2CwqWmxOrfJELhV34v0WSlaqG1UtE1uXlJg==} + '@smithy/querystring-parser@3.0.10': + resolution: {integrity: sha512-Oa0XDcpo9SmjhiDD9ua2UyM3uU01ZTuIrNdZvzwUTykW1PM8o2yJvMh1Do1rY5sUQg4NDV70dMi0JhDx4GyxuQ==} engines: {node: '>=16.0.0'} - '@smithy/property-provider@3.1.3': - resolution: {integrity: sha512-zahyOVR9Q4PEoguJ/NrFP4O7SMAfYO1HLhB18M+q+Z4KFd4V2obiMnlVoUFzFLSPeVt1POyNWneHHrZaTMoc/g==} + '@smithy/service-error-classification@3.0.10': + resolution: {integrity: sha512-zHe642KCqDxXLuhs6xmHVgRwy078RfqxP2wRDpIyiF8EmsWXptMwnMwbVa50lw+WOGNrYm9zbaEg0oDe3PTtvQ==} engines: {node: '>=16.0.0'} - '@smithy/protocol-http@4.0.3': - resolution: {integrity: sha512-x5jmrCWwQlx+Zv4jAtc33ijJ+vqqYN+c/ZkrnpvEe/uDas7AT7A/4Rc2CdfxgWv4WFGmEqODIrrUToPN6DDkGw==} + '@smithy/shared-ini-file-loader@3.1.11': + resolution: {integrity: sha512-AUdrIZHFtUgmfSN4Gq9nHu3IkHMa1YDcN+s061Nfm+6pQ0mJy85YQDB0tZBCmls0Vuj22pLwDPmL92+Hvfwwlg==} engines: {node: '>=16.0.0'} - '@smithy/protocol-http@4.1.0': - resolution: {integrity: sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA==} + '@smithy/signature-v4@4.2.3': + resolution: {integrity: sha512-pPSQQ2v2vu9vc8iew7sszLd0O09I5TRc5zhY71KA+Ao0xYazIG+uLeHbTJfIWGO3BGVLiXjUr3EEeCcEQLjpWQ==} engines: {node: '>=16.0.0'} - '@smithy/querystring-builder@3.0.3': - resolution: {integrity: sha512-vyWckeUeesFKzCDaRwWLUA1Xym9McaA6XpFfAK5qI9DKJ4M33ooQGqvM4J+LalH4u/Dq9nFiC8U6Qn1qi0+9zw==} + '@smithy/smithy-client@3.4.5': + resolution: {integrity: sha512-k0sybYT9zlP79sIKd1XGm4TmK0AS1nA2bzDHXx7m0nGi3RQ8dxxQUs4CPkSmQTKAo+KF9aINU3KzpGIpV7UoMw==} engines: {node: '>=16.0.0'} - '@smithy/querystring-parser@3.0.3': - resolution: {integrity: sha512-zahM1lQv2YjmznnfQsWbYojFe55l0SLG/988brlLv1i8z3dubloLF+75ATRsqPBboUXsW6I9CPGE5rQgLfY0vQ==} + '@smithy/types@3.7.1': + resolution: {integrity: sha512-XKLcLXZY7sUQgvvWyeaL/qwNPp6V3dWcUjqrQKjSb+tzYiCy340R/c64LV5j+Tnb2GhmunEX0eou+L+m2hJNYA==} engines: {node: '>=16.0.0'} - '@smithy/service-error-classification@3.0.3': - resolution: {integrity: sha512-Jn39sSl8cim/VlkLsUhRFq/dKDnRUFlfRkvhOJaUbLBXUsLRLNf9WaxDv/z9BjuQ3A6k/qE8af1lsqcwm7+DaQ==} - engines: {node: '>=16.0.0'} - - '@smithy/shared-ini-file-loader@3.1.4': - resolution: {integrity: sha512-qMxS4hBGB8FY2GQqshcRUy1K6k8aBWP5vwm8qKkCT3A9K2dawUwOIJfqh9Yste/Bl0J2lzosVyrXDj68kLcHXQ==} - engines: {node: '>=16.0.0'} - - '@smithy/signature-v4@3.1.2': - resolution: {integrity: sha512-3BcPylEsYtD0esM4Hoyml/+s7WP2LFhcM3J2AGdcL2vx9O60TtfpDOL72gjb4lU8NeRPeKAwR77YNyyGvMbuEA==} - engines: {node: '>=16.0.0'} - - '@smithy/signature-v4@4.1.0': - resolution: {integrity: sha512-aRryp2XNZeRcOtuJoxjydO6QTaVhxx/vjaR+gx7ZjaFgrgPRyZ3HCTbfwqYj6ZWEBHkCSUfcaymKPURaByukag==} - engines: {node: '>=16.0.0'} - - '@smithy/smithy-client@3.1.12': - resolution: {integrity: sha512-wtm8JtsycthkHy1YA4zjIh2thJgIQ9vGkoR639DBx5lLlLNU0v4GARpQZkr2WjXue74nZ7MiTSWfVrLkyD8RkA==} - engines: {node: '>=16.0.0'} - - '@smithy/smithy-client@3.1.7': - resolution: {integrity: sha512-nZbJZB0XI3YnaFBWGDBr7kjaew6O0oNYNmopyIz6gKZEbxzrtH7rwvU1GcVxcSFoOwWecLJEe79fxEMljHopFQ==} - engines: {node: '>=16.0.0'} - - '@smithy/types@3.3.0': - resolution: {integrity: sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==} - engines: {node: '>=16.0.0'} - - '@smithy/url-parser@3.0.3': - resolution: {integrity: sha512-pw3VtZtX2rg+s6HMs6/+u9+hu6oY6U7IohGhVNnjbgKy86wcIsSZwgHrFR+t67Uyxvp4Xz3p3kGXXIpTNisq8A==} + '@smithy/url-parser@3.0.10': + resolution: {integrity: sha512-j90NUalTSBR2NaZTuruEgavSdh8MLirf58LoGSk4AtQfyIymogIhgnGUU2Mga2bkMkpSoC9gxb74xBXL5afKAQ==} '@smithy/util-base64@3.0.0': resolution: {integrity: sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==} @@ -1040,44 +1023,32 @@ packages: resolution: {integrity: sha512-pbjk4s0fwq3Di/ANL+rCvJMKM5bzAQdE5S/6RL5NXgMExFAi6UgQMPOm5yPaIWPpr+EOXKXRonJ3FoxKf4mCJQ==} engines: {node: '>=16.0.0'} - '@smithy/util-defaults-mode-browser@3.0.14': - resolution: {integrity: sha512-0iwTgKKmAIf+vFLV8fji21Jb2px11ktKVxbX6LIDPAUJyWQqGqBVfwba7xwa1f2FZUoolYQgLvxQEpJycXuQ5w==} - engines: {node: '>= 10.0.0'} - - '@smithy/util-defaults-mode-browser@3.0.9': - resolution: {integrity: sha512-WKPcElz92MAQG09miBdb0GxEH/MwD5GfE8g07WokITq5g6J1ROQfYCKC1wNnkqAGfrSywT7L0rdvvqlBplqiyA==} + '@smithy/util-defaults-mode-browser@3.0.28': + resolution: {integrity: sha512-6bzwAbZpHRFVJsOztmov5PGDmJYsbNSoIEfHSJJyFLzfBGCCChiO3od9k7E/TLgrCsIifdAbB9nqbVbyE7wRUw==} engines: {node: '>= 10.0.0'} - '@smithy/util-defaults-mode-node@3.0.14': - resolution: {integrity: sha512-e9uQarJKfXApkTMMruIdxHprhcXivH1flYCe8JRDTzkkLx8dA3V5J8GZlST9yfDiRWkJpZJlUXGN9Rc9Ade3OQ==} + '@smithy/util-defaults-mode-node@3.0.28': + resolution: {integrity: sha512-78ENJDorV1CjOQselGmm3+z7Yqjj5HWCbjzh0Ixuq736dh1oEnD9sAttSBNSLlpZsX8VQnmERqA2fEFlmqWn8w==} engines: {node: '>= 10.0.0'} - '@smithy/util-defaults-mode-node@3.0.9': - resolution: {integrity: sha512-dQLrUqFxqpf0GvEKEuFdgXcdZwz6oFm752h4d6C7lQz+RLddf761L2r7dSwGWzESMMB3wKj0jL+skRhEGlecjw==} - engines: {node: '>= 10.0.0'} - - '@smithy/util-endpoints@2.0.5': - resolution: {integrity: sha512-ReQP0BWihIE68OAblC/WQmDD40Gx+QY1Ez8mTdFMXpmjfxSyz2fVQu3A4zXRfQU9sZXtewk3GmhfOHswvX+eNg==} + '@smithy/util-endpoints@2.1.6': + resolution: {integrity: sha512-mFV1t3ndBh0yZOJgWxO9J/4cHZVn5UG1D8DeCc6/echfNkeEJWu9LD7mgGH5fHrEdR7LDoWw7PQO6QiGpHXhgA==} engines: {node: '>=16.0.0'} '@smithy/util-hex-encoding@3.0.0': resolution: {integrity: sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ==} engines: {node: '>=16.0.0'} - '@smithy/util-middleware@3.0.3': - resolution: {integrity: sha512-l+StyYYK/eO3DlVPbU+4Bi06Jjal+PFLSMmlWM1BEwyLxZ3aKkf1ROnoIakfaA7mC6uw3ny7JBkau4Yc+5zfWw==} - engines: {node: '>=16.0.0'} - - '@smithy/util-retry@3.0.3': - resolution: {integrity: sha512-AFw+hjpbtVApzpNDhbjNG5NA3kyoMs7vx0gsgmlJF4s+yz1Zlepde7J58zpIRIsdjc+emhpAITxA88qLkPF26w==} + '@smithy/util-middleware@3.0.10': + resolution: {integrity: sha512-eJO+/+RsrG2RpmY68jZdwQtnfsxjmPxzMlQpnHKjFPwrYqvlcT+fHdT+ZVwcjlWSrByOhGr9Ff2GG17efc192A==} engines: {node: '>=16.0.0'} - '@smithy/util-stream@3.0.6': - resolution: {integrity: sha512-w9i//7egejAIvplX821rPWWgaiY1dxsQUw0hXX7qwa/uZ9U3zplqTQ871jWadkcVB9gFDhkPWYVZf4yfFbZ0xA==} + '@smithy/util-retry@3.0.10': + resolution: {integrity: sha512-1l4qatFp4PiU6j7UsbasUHL2VU023NRB/gfaa1M0rDqVrRN4g3mCArLRyH3OuktApA4ye+yjWQHjdziunw2eWA==} engines: {node: '>=16.0.0'} - '@smithy/util-stream@3.1.3': - resolution: {integrity: sha512-FIv/bRhIlAxC0U7xM1BCnF2aDRPq0UaelqBHkM2lsCp26mcBbgI0tCVTv+jGdsQLUmAMybua/bjDsSu8RQHbmw==} + '@smithy/util-stream@3.3.1': + resolution: {integrity: sha512-Ff68R5lJh2zj+AUTvbAU/4yx+6QPRzg7+pI7M1FbtQHcRIp7xvguxVsQBKyB3fwiOwhAKu0lnNyYBaQfSW6TNw==} engines: {node: '>=16.0.0'} '@smithy/util-uri-escape@3.0.0': @@ -1092,8 +1063,8 @@ packages: resolution: {integrity: sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA==} engines: {node: '>=16.0.0'} - '@smithy/util-waiter@3.1.2': - resolution: {integrity: sha512-4pP0EV3iTsexDx+8PPGAKCQpd/6hsQBaQhqWzU4hqKPHN5epPsxKbvUTIiYIHTxaKt6/kEaqPBpu/ufvfbrRzw==} + '@smithy/util-waiter@3.1.9': + resolution: {integrity: sha512-/aMXPANhMOlMPjfPtSrDfPeVP8l56SJlz93xeiLmhLe5xvlXA5T3abZ2ilEsDEPeY9T/wnN/vNGn9wa1SbufWA==} engines: {node: '>=16.0.0'} '@szmarczak/http-timer@5.0.1': @@ -1130,12 +1101,18 @@ packages: '@types/estree@1.0.5': resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + '@types/fs-extra@11.0.4': + resolution: {integrity: sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==} + '@types/http-cache-semantics@4.0.4': resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==} '@types/inquirer@9.0.7': resolution: {integrity: sha512-Q0zyBupO6NxGRZut/JdmqYKOnN95Eg5V8Csg3PGKkP+FnvsUZx1jAyK7fztIszxxMuoBA6E3KXWvdZVXIpx60g==} + '@types/jsonfile@6.1.4': + resolution: {integrity: sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==} + '@types/mocha@10.0.7': resolution: {integrity: sha512-GN8yJ1mNTcFcah/wKEFIJckJx9iJLoMSzWcfRRuxz/Jk+U6KQNnml+etbtxFK8lPjzOw3zp4Ha/kjSst9fsHYw==} @@ -1151,6 +1128,9 @@ packages: '@types/node@22.1.0': resolution: {integrity: sha512-AOmuRF0R2/5j1knA3c6G3HOk523Ga+l+ZXltX8SF1+5oqcXijjfTd8fY3XRZqSihEu9XhtQnKYLmkFaoxgsJHw==} + '@types/node@22.10.1': + resolution: {integrity: sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==} + '@types/sinon@17.0.3': resolution: {integrity: sha512-j3uovdn8ewky9kRBG19bOwaZbexJu/XjtkHyjvUgt4xfPFz18dcORIMqnYh66Fx3Powhcr85NT5+er3+oViapw==} @@ -1282,10 +1262,6 @@ packages: resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} - ansis@3.3.1: - resolution: {integrity: sha512-dW/sqnbVeWXW1UMRyKGHiJj+vBrlnnDcvyNMDB8BBI4Gu0tsohweIkvcqb3bNNwcVn70LTyvvnGgjUzUVFnK6Q==} - engines: {node: '>=15'} - ansis@3.3.2: resolution: {integrity: sha512-cFthbBlt+Oi0i9Pv/j6YdVWJh54CtjGACaMPCIrEV4Ha7HWsIjXDwseYV79TIL0B4+KfSwD5S70PeQDkPUd1rA==} engines: {node: '>=15'} @@ -1431,6 +1407,9 @@ packages: chardet@0.7.0: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + charenc@0.0.2: + resolution: {integrity: sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==} + check-error@2.1.1: resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} engines: {node: '>= 16'} @@ -1500,6 +1479,9 @@ packages: concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + config-chain@1.1.13: + resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==} + constant-case@3.0.4: resolution: {integrity: sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==} @@ -1523,6 +1505,9 @@ packages: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} + crypt@0.0.2: + resolution: {integrity: sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==} + date-fns@2.30.0: resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==} engines: {node: '>=0.11'} @@ -1530,8 +1515,8 @@ packages: date-fns@3.6.0: resolution: {integrity: sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==} - debug@4.3.5: - resolution: {integrity: sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==} + debug@4.3.7: + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' @@ -1539,8 +1524,8 @@ packages: supports-color: optional: true - debug@4.3.6: - resolution: {integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==} + debug@4.4.0: + resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' @@ -1615,6 +1600,10 @@ packages: resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==} engines: {node: '>=0.3.1'} + diff@7.0.0: + resolution: {integrity: sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==} + engines: {node: '>=0.3.1'} + dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} @@ -1758,6 +1747,14 @@ packages: fd-slicer@1.1.0: resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} + fdir@6.4.2: + resolution: {integrity: sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + fecha@4.2.3: resolution: {integrity: sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==} @@ -1839,6 +1836,10 @@ packages: fs-constants@1.0.0: resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + fs-extra@11.2.0: + resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} + engines: {node: '>=14.14'} + fs-extra@8.1.0: resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} engines: {node: '>=6 <7 || >=8'} @@ -1941,14 +1942,13 @@ packages: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} - globby@13.2.2: - resolution: {integrity: sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - got@13.0.0: resolution: {integrity: sha512-XfBk1CxOOScDcMr9O1yKkNaQyy865NbYs+F7dr4H0LZMVgCj2Le59k6PqbNHoL5ToeaEQUYh6c6yMfVcc6SJxA==} engines: {node: '>=16'} + graceful-fs@4.2.10: + resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} + graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} @@ -2034,6 +2034,9 @@ packages: inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + inquirer@10.1.8: resolution: {integrity: sha512-syxGpOzLyqVeZi1KDBjRTnCn5PiGWySGHP0BbqXbqsEK0ckkZk3egAepEWslUjZXj0rhkUapVXM/IpADWe4D6w==} engines: {node: '>=18'} @@ -2052,6 +2055,9 @@ packages: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} + is-buffer@1.1.6: + resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} + is-core-module@2.14.0: resolution: {integrity: sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==} engines: {node: '>= 0.4'} @@ -2202,6 +2208,9 @@ packages: jsonfile@4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + just-extend@6.2.0: resolution: {integrity: sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==} @@ -2215,8 +2224,8 @@ packages: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} - lilconfig@3.1.2: - resolution: {integrity: sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==} + lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} engines: {node: '>=14'} locate-path@5.0.0: @@ -2286,6 +2295,9 @@ packages: make-error@1.3.6: resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + md5@2.3.0: + resolution: {integrity: sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==} + merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} @@ -2368,6 +2380,16 @@ packages: engines: {node: '>=10'} hasBin: true + mkdirp@3.0.1: + resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} + engines: {node: '>=10'} + hasBin: true + + mocha-junit-reporter@2.2.1: + resolution: {integrity: sha512-iDn2tlKHn8Vh8o4nCzcUVW4q7iXp7cC4EB78N0cDHIobLymyHNwe0XG8HEHHjc3hJlXm0Vy6zcrxaIhnI2fWmw==} + peerDependencies: + mocha: '>=2.2.5' + mocha@10.7.3: resolution: {integrity: sha512-uQWxAu44wwiACGqjbPYmjo7Lg8sFrS3dQe7PP2FQI+woptP4vZXSMcfMyFL/e1yFEeEpV4RtyTpZROOKmxis+A==} engines: {node: '>= 14.0.0'} @@ -2380,9 +2402,6 @@ packages: moment@2.29.4: resolution: {integrity: sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==} - ms@2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -2390,11 +2409,15 @@ packages: resolution: {integrity: sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + mute-stream@2.0.0: + resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} + engines: {node: ^18.17.0 || >=20.5.0} + natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - nise@6.0.0: - resolution: {integrity: sha512-K8ePqo9BFvN31HXwEtTNGzgrPpmvgciDsFz8aztFjt4LqKO/JeFD8tBOeuDiCMXrIl/m1YvfH8auSpxfaD09wg==} + nise@6.1.1: + resolution: {integrity: sha512-aMSAzLVY7LyeM60gvBS423nBmIPP+Wy7St7hsb+8/fc1HmeoHJfLO8CKse4u3BtOZvQLJghYPI2i/1WZrEj5/g==} no-case@3.0.4: resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} @@ -2454,8 +2477,8 @@ packages: '@codemirror/state': ^6.0.0 '@codemirror/view': ^6.0.0 - oclif@4.14.15: - resolution: {integrity: sha512-VgifJ5SdgAqWPBtvNNVVgOosGF4Bcgesmc6jCOOV9/H8XPz3r5m7G7HbmsqLdbDU+gPPekHJklbojkRUEUOXeg==} + oclif@4.16.0: + resolution: {integrity: sha512-Y5bcJc4vwhAW0UN9ctZvfLYZz+nC4rQJPmmpKFXLj7A6uKS1c+GrNa4WwZnk9D4eN32kP/awyRRdd2lbX/S+KQ==} engines: {node: '>=18.0.0'} hasBin: true @@ -2556,8 +2579,9 @@ packages: resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==} engines: {node: 20 || >=22} - path-to-regexp@6.2.2: - resolution: {integrity: sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==} + path-to-regexp@8.2.0: + resolution: {integrity: sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==} + engines: {node: '>=16'} path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} @@ -2577,6 +2601,10 @@ packages: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} + picomatch@4.0.2: + resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + engines: {node: '>=12'} + pify@2.3.0: resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} engines: {node: '>=0.10.0'} @@ -2613,6 +2641,9 @@ packages: resolution: {integrity: sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==} engines: {node: '>=8'} + proto-list@1.2.4: + resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} + punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -2645,6 +2676,10 @@ packages: regenerator-runtime@0.14.1: resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + registry-auth-token@5.0.3: + resolution: {integrity: sha512-1bpc9IyC+e+CNFRaWyn77tk4xGG4PPUyfakSmA6F6cvUDjrm58dfyJ3II+9yb10EDkHoy1LaPSmHaWLOH3m6HA==} + engines: {node: '>=14'} + release-zalgo@1.0.0: resolution: {integrity: sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==} engines: {node: '>=4'} @@ -2722,11 +2757,6 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true - semver@7.6.2: - resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==} - engines: {node: '>=10'} - hasBin: true - semver@7.6.3: resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} engines: {node: '>=10'} @@ -2769,25 +2799,21 @@ packages: simple-swizzle@0.2.2: resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} - sinon@18.0.0: - resolution: {integrity: sha512-+dXDXzD1sBO6HlmZDd7mXZCR/y5ECiEiGCBSGuFD/kZ0bDTofPYc6JaeGmPSF+1j1MejGUWkORbYOLDyvqCWpA==} + sinon@19.0.2: + resolution: {integrity: sha512-euuToqM+PjO4UgXeLETsfQiuoyPXlqFezr6YZDFwHR3t4qaX0fZUe1MfPMznTL5f8BWrVS89KduLdMUsxFCO6g==} slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} - slash@4.0.0: - resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==} - engines: {node: '>=12'} - snake-case@3.0.4: resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} sort-object-keys@1.1.3: resolution: {integrity: sha512-855pvK+VkU7PaKYPc+Jjnmt4EzejQHyhhF33q31qG8x7maDzkeFhAAThdCYay11CISO+qAMwjOBP+fPZe0IPyg==} - sort-package-json@2.10.0: - resolution: {integrity: sha512-MYecfvObMwJjjJskhxYfuOADkXp1ZMMnCFC8yhp+9HDsk7HhR336hd7eiBs96lTXfiqmUNI+WQCeCMRBhl251g==} + sort-package-json@2.12.0: + resolution: {integrity: sha512-/HrPQAeeLaa+vbAH/znjuhwUluuiM/zL5XX9kop8UpDgjtyWKt43hGDk2vd/TBdDpzIyzIHVUgmYofzYrAQjew==} hasBin: true source-map@0.6.1: @@ -2903,6 +2929,10 @@ packages: tiny-jsonc@1.0.1: resolution: {integrity: sha512-ik6BCxzva9DoiEfDX/li0L2cWKPPENYvixUprFdl3YPi4bZZUhDnNI9YUkacrv+uIG90dnxR5mNqaoD6UhD6Bw==} + tinyglobby@0.2.10: + resolution: {integrity: sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew==} + engines: {node: '>=12.0.0'} + tmp@0.0.33: resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} engines: {node: '>=0.6.0'} @@ -2918,8 +2948,9 @@ packages: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} - tr46@0.0.3: - resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + tr46@5.0.0: + resolution: {integrity: sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==} + engines: {node: '>=18'} triple-beam@1.4.1: resolution: {integrity: sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==} @@ -2964,6 +2995,10 @@ packages: resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} engines: {node: '>=4'} + type-detect@4.1.0: + resolution: {integrity: sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==} + engines: {node: '>=4'} + type-fest@0.21.3: resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} engines: {node: '>=10'} @@ -2995,6 +3030,9 @@ packages: undici-types@6.13.0: resolution: {integrity: sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg==} + undici-types@6.20.0: + resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} + unique-filename@3.0.0: resolution: {integrity: sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} @@ -3007,6 +3045,10 @@ packages: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + update-browserslist-db@1.1.0: resolution: {integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==} hasBin: true @@ -3046,11 +3088,13 @@ packages: w3c-keyname@2.2.8: resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} - webidl-conversions@3.0.1: - resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + webidl-conversions@7.0.0: + resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} + engines: {node: '>=12'} - whatwg-url@5.0.0: - resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + whatwg-url@14.0.0: + resolution: {integrity: sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==} + engines: {node: '>=18'} which-module@2.0.1: resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} @@ -3100,6 +3144,9 @@ packages: write-file-atomic@3.0.3: resolution: {integrity: sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==} + xml@1.0.1: + resolution: {integrity: sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==} + xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} @@ -3165,20 +3212,20 @@ snapshots: '@aws-crypto/crc32@5.2.0': dependencies: '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.609.0 + '@aws-sdk/types': 3.696.0 tslib: 2.6.3 '@aws-crypto/crc32c@5.2.0': dependencies: '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.609.0 + '@aws-sdk/types': 3.696.0 tslib: 2.6.3 '@aws-crypto/sha1-browser@5.2.0': dependencies: '@aws-crypto/supports-web-crypto': 5.2.0 '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.609.0 + '@aws-sdk/types': 3.696.0 '@aws-sdk/util-locate-window': 3.568.0 '@smithy/util-utf8': 2.3.0 tslib: 2.6.3 @@ -3188,7 +3235,7 @@ snapshots: '@aws-crypto/sha256-js': 5.2.0 '@aws-crypto/supports-web-crypto': 5.2.0 '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.609.0 + '@aws-sdk/types': 3.696.0 '@aws-sdk/util-locate-window': 3.568.0 '@smithy/util-utf8': 2.3.0 tslib: 2.6.3 @@ -3196,7 +3243,7 @@ snapshots: '@aws-crypto/sha256-js@5.2.0': dependencies: '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.609.0 + '@aws-sdk/types': 3.696.0 tslib: 2.6.3 '@aws-crypto/supports-web-crypto@5.2.0': @@ -3205,765 +3252,517 @@ snapshots: '@aws-crypto/util@5.2.0': dependencies: - '@aws-sdk/types': 3.609.0 + '@aws-sdk/types': 3.696.0 '@smithy/util-utf8': 2.3.0 tslib: 2.6.3 - '@aws-sdk/client-cloudfront@3.624.0': + '@aws-sdk/client-cloudfront@3.699.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/client-sso-oidc': 3.624.0(@aws-sdk/client-sts@3.624.0) - '@aws-sdk/client-sts': 3.624.0 - '@aws-sdk/core': 3.624.0 - '@aws-sdk/credential-provider-node': 3.624.0(@aws-sdk/client-sso-oidc@3.624.0(@aws-sdk/client-sts@3.624.0))(@aws-sdk/client-sts@3.624.0) - '@aws-sdk/middleware-host-header': 3.620.0 - '@aws-sdk/middleware-logger': 3.609.0 - '@aws-sdk/middleware-recursion-detection': 3.620.0 - '@aws-sdk/middleware-user-agent': 3.620.0 - '@aws-sdk/region-config-resolver': 3.614.0 - '@aws-sdk/types': 3.609.0 - '@aws-sdk/util-endpoints': 3.614.0 - '@aws-sdk/util-user-agent-browser': 3.609.0 - '@aws-sdk/util-user-agent-node': 3.614.0 - '@aws-sdk/xml-builder': 3.609.0 - '@smithy/config-resolver': 3.0.5 - '@smithy/core': 2.3.2 - '@smithy/fetch-http-handler': 3.2.4 - '@smithy/hash-node': 3.0.3 - '@smithy/invalid-dependency': 3.0.3 - '@smithy/middleware-content-length': 3.0.5 - '@smithy/middleware-endpoint': 3.1.0 - '@smithy/middleware-retry': 3.0.14 - '@smithy/middleware-serde': 3.0.3 - '@smithy/middleware-stack': 3.0.3 - '@smithy/node-config-provider': 3.1.4 - '@smithy/node-http-handler': 3.1.4 - '@smithy/protocol-http': 4.1.0 - '@smithy/smithy-client': 3.1.12 - '@smithy/types': 3.3.0 - '@smithy/url-parser': 3.0.3 + '@aws-sdk/client-sso-oidc': 3.699.0(@aws-sdk/client-sts@3.699.0) + '@aws-sdk/client-sts': 3.699.0 + '@aws-sdk/core': 3.696.0 + '@aws-sdk/credential-provider-node': 3.699.0(@aws-sdk/client-sso-oidc@3.699.0(@aws-sdk/client-sts@3.699.0))(@aws-sdk/client-sts@3.699.0) + '@aws-sdk/middleware-host-header': 3.696.0 + '@aws-sdk/middleware-logger': 3.696.0 + '@aws-sdk/middleware-recursion-detection': 3.696.0 + '@aws-sdk/middleware-user-agent': 3.696.0 + '@aws-sdk/region-config-resolver': 3.696.0 + '@aws-sdk/types': 3.696.0 + '@aws-sdk/util-endpoints': 3.696.0 + '@aws-sdk/util-user-agent-browser': 3.696.0 + '@aws-sdk/util-user-agent-node': 3.696.0 + '@aws-sdk/xml-builder': 3.696.0 + '@smithy/config-resolver': 3.0.12 + '@smithy/core': 2.5.4 + '@smithy/fetch-http-handler': 4.1.1 + '@smithy/hash-node': 3.0.10 + '@smithy/invalid-dependency': 3.0.10 + '@smithy/middleware-content-length': 3.0.12 + '@smithy/middleware-endpoint': 3.2.4 + '@smithy/middleware-retry': 3.0.28 + '@smithy/middleware-serde': 3.0.10 + '@smithy/middleware-stack': 3.0.10 + '@smithy/node-config-provider': 3.1.11 + '@smithy/node-http-handler': 3.3.1 + '@smithy/protocol-http': 4.1.7 + '@smithy/smithy-client': 3.4.5 + '@smithy/types': 3.7.1 + '@smithy/url-parser': 3.0.10 '@smithy/util-base64': 3.0.0 '@smithy/util-body-length-browser': 3.0.0 '@smithy/util-body-length-node': 3.0.0 - '@smithy/util-defaults-mode-browser': 3.0.14 - '@smithy/util-defaults-mode-node': 3.0.14 - '@smithy/util-endpoints': 2.0.5 - '@smithy/util-middleware': 3.0.3 - '@smithy/util-retry': 3.0.3 - '@smithy/util-stream': 3.1.3 + '@smithy/util-defaults-mode-browser': 3.0.28 + '@smithy/util-defaults-mode-node': 3.0.28 + '@smithy/util-endpoints': 2.1.6 + '@smithy/util-middleware': 3.0.10 + '@smithy/util-retry': 3.0.10 + '@smithy/util-stream': 3.3.1 '@smithy/util-utf8': 3.0.0 - '@smithy/util-waiter': 3.1.2 + '@smithy/util-waiter': 3.1.9 tslib: 2.6.3 transitivePeerDependencies: - aws-crt - '@aws-sdk/client-s3@3.614.0': + '@aws-sdk/client-s3@3.701.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/client-sso-oidc': 3.614.0(@aws-sdk/client-sts@3.614.0) - '@aws-sdk/client-sts': 3.614.0 - '@aws-sdk/core': 3.614.0 - '@aws-sdk/credential-provider-node': 3.614.0(@aws-sdk/client-sso-oidc@3.614.0(@aws-sdk/client-sts@3.614.0))(@aws-sdk/client-sts@3.614.0) - '@aws-sdk/middleware-bucket-endpoint': 3.614.0 - '@aws-sdk/middleware-expect-continue': 3.609.0 - '@aws-sdk/middleware-flexible-checksums': 3.614.0 - '@aws-sdk/middleware-host-header': 3.609.0 - '@aws-sdk/middleware-location-constraint': 3.609.0 - '@aws-sdk/middleware-logger': 3.609.0 - '@aws-sdk/middleware-recursion-detection': 3.609.0 - '@aws-sdk/middleware-sdk-s3': 3.614.0 - '@aws-sdk/middleware-signing': 3.609.0 - '@aws-sdk/middleware-ssec': 3.609.0 - '@aws-sdk/middleware-user-agent': 3.614.0 - '@aws-sdk/region-config-resolver': 3.614.0 - '@aws-sdk/signature-v4-multi-region': 3.614.0 - '@aws-sdk/types': 3.609.0 - '@aws-sdk/util-endpoints': 3.614.0 - '@aws-sdk/util-user-agent-browser': 3.609.0 - '@aws-sdk/util-user-agent-node': 3.614.0 - '@aws-sdk/xml-builder': 3.609.0 - '@smithy/config-resolver': 3.0.5 - '@smithy/core': 2.2.6 - '@smithy/eventstream-serde-browser': 3.0.4 - '@smithy/eventstream-serde-config-resolver': 3.0.3 - '@smithy/eventstream-serde-node': 3.0.4 - '@smithy/fetch-http-handler': 3.2.1 - '@smithy/hash-blob-browser': 3.1.2 - '@smithy/hash-node': 3.0.3 - '@smithy/hash-stream-node': 3.1.2 - '@smithy/invalid-dependency': 3.0.3 - '@smithy/md5-js': 3.0.3 - '@smithy/middleware-content-length': 3.0.3 - '@smithy/middleware-endpoint': 3.0.5 - '@smithy/middleware-retry': 3.0.9 - '@smithy/middleware-serde': 3.0.3 - '@smithy/middleware-stack': 3.0.3 - '@smithy/node-config-provider': 3.1.4 - '@smithy/node-http-handler': 3.1.2 - '@smithy/protocol-http': 4.0.3 - '@smithy/smithy-client': 3.1.7 - '@smithy/types': 3.3.0 - '@smithy/url-parser': 3.0.3 - '@smithy/util-base64': 3.0.0 - '@smithy/util-body-length-browser': 3.0.0 - '@smithy/util-body-length-node': 3.0.0 - '@smithy/util-defaults-mode-browser': 3.0.9 - '@smithy/util-defaults-mode-node': 3.0.9 - '@smithy/util-endpoints': 2.0.5 - '@smithy/util-retry': 3.0.3 - '@smithy/util-stream': 3.0.6 - '@smithy/util-utf8': 3.0.0 - '@smithy/util-waiter': 3.1.2 - tslib: 2.6.3 - transitivePeerDependencies: - - aws-crt - - '@aws-sdk/client-sso-oidc@3.614.0(@aws-sdk/client-sts@3.614.0)': - dependencies: - '@aws-crypto/sha256-browser': 5.2.0 - '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/client-sts': 3.614.0 - '@aws-sdk/core': 3.614.0 - '@aws-sdk/credential-provider-node': 3.614.0(@aws-sdk/client-sso-oidc@3.614.0(@aws-sdk/client-sts@3.614.0))(@aws-sdk/client-sts@3.614.0) - '@aws-sdk/middleware-host-header': 3.609.0 - '@aws-sdk/middleware-logger': 3.609.0 - '@aws-sdk/middleware-recursion-detection': 3.609.0 - '@aws-sdk/middleware-user-agent': 3.614.0 - '@aws-sdk/region-config-resolver': 3.614.0 - '@aws-sdk/types': 3.609.0 - '@aws-sdk/util-endpoints': 3.614.0 - '@aws-sdk/util-user-agent-browser': 3.609.0 - '@aws-sdk/util-user-agent-node': 3.614.0 - '@smithy/config-resolver': 3.0.5 - '@smithy/core': 2.2.6 - '@smithy/fetch-http-handler': 3.2.1 - '@smithy/hash-node': 3.0.3 - '@smithy/invalid-dependency': 3.0.3 - '@smithy/middleware-content-length': 3.0.3 - '@smithy/middleware-endpoint': 3.0.5 - '@smithy/middleware-retry': 3.0.9 - '@smithy/middleware-serde': 3.0.3 - '@smithy/middleware-stack': 3.0.3 - '@smithy/node-config-provider': 3.1.4 - '@smithy/node-http-handler': 3.1.2 - '@smithy/protocol-http': 4.0.3 - '@smithy/smithy-client': 3.1.7 - '@smithy/types': 3.3.0 - '@smithy/url-parser': 3.0.3 + '@aws-sdk/client-sso-oidc': 3.699.0(@aws-sdk/client-sts@3.699.0) + '@aws-sdk/client-sts': 3.699.0 + '@aws-sdk/core': 3.696.0 + '@aws-sdk/credential-provider-node': 3.699.0(@aws-sdk/client-sso-oidc@3.699.0(@aws-sdk/client-sts@3.699.0))(@aws-sdk/client-sts@3.699.0) + '@aws-sdk/middleware-bucket-endpoint': 3.696.0 + '@aws-sdk/middleware-expect-continue': 3.696.0 + '@aws-sdk/middleware-flexible-checksums': 3.701.0 + '@aws-sdk/middleware-host-header': 3.696.0 + '@aws-sdk/middleware-location-constraint': 3.696.0 + '@aws-sdk/middleware-logger': 3.696.0 + '@aws-sdk/middleware-recursion-detection': 3.696.0 + '@aws-sdk/middleware-sdk-s3': 3.696.0 + '@aws-sdk/middleware-ssec': 3.696.0 + '@aws-sdk/middleware-user-agent': 3.696.0 + '@aws-sdk/region-config-resolver': 3.696.0 + '@aws-sdk/signature-v4-multi-region': 3.696.0 + '@aws-sdk/types': 3.696.0 + '@aws-sdk/util-endpoints': 3.696.0 + '@aws-sdk/util-user-agent-browser': 3.696.0 + '@aws-sdk/util-user-agent-node': 3.696.0 + '@aws-sdk/xml-builder': 3.696.0 + '@smithy/config-resolver': 3.0.12 + '@smithy/core': 2.5.4 + '@smithy/eventstream-serde-browser': 3.0.13 + '@smithy/eventstream-serde-config-resolver': 3.0.10 + '@smithy/eventstream-serde-node': 3.0.12 + '@smithy/fetch-http-handler': 4.1.1 + '@smithy/hash-blob-browser': 3.1.9 + '@smithy/hash-node': 3.0.10 + '@smithy/hash-stream-node': 3.1.9 + '@smithy/invalid-dependency': 3.0.10 + '@smithy/md5-js': 3.0.10 + '@smithy/middleware-content-length': 3.0.12 + '@smithy/middleware-endpoint': 3.2.4 + '@smithy/middleware-retry': 3.0.28 + '@smithy/middleware-serde': 3.0.10 + '@smithy/middleware-stack': 3.0.10 + '@smithy/node-config-provider': 3.1.11 + '@smithy/node-http-handler': 3.3.1 + '@smithy/protocol-http': 4.1.7 + '@smithy/smithy-client': 3.4.5 + '@smithy/types': 3.7.1 + '@smithy/url-parser': 3.0.10 '@smithy/util-base64': 3.0.0 '@smithy/util-body-length-browser': 3.0.0 '@smithy/util-body-length-node': 3.0.0 - '@smithy/util-defaults-mode-browser': 3.0.9 - '@smithy/util-defaults-mode-node': 3.0.9 - '@smithy/util-endpoints': 2.0.5 - '@smithy/util-middleware': 3.0.3 - '@smithy/util-retry': 3.0.3 + '@smithy/util-defaults-mode-browser': 3.0.28 + '@smithy/util-defaults-mode-node': 3.0.28 + '@smithy/util-endpoints': 2.1.6 + '@smithy/util-middleware': 3.0.10 + '@smithy/util-retry': 3.0.10 + '@smithy/util-stream': 3.3.1 '@smithy/util-utf8': 3.0.0 + '@smithy/util-waiter': 3.1.9 tslib: 2.6.3 transitivePeerDependencies: - aws-crt - '@aws-sdk/client-sso-oidc@3.624.0(@aws-sdk/client-sts@3.624.0)': + '@aws-sdk/client-sso-oidc@3.699.0(@aws-sdk/client-sts@3.699.0)': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/client-sts': 3.624.0 - '@aws-sdk/core': 3.624.0 - '@aws-sdk/credential-provider-node': 3.624.0(@aws-sdk/client-sso-oidc@3.624.0(@aws-sdk/client-sts@3.624.0))(@aws-sdk/client-sts@3.624.0) - '@aws-sdk/middleware-host-header': 3.620.0 - '@aws-sdk/middleware-logger': 3.609.0 - '@aws-sdk/middleware-recursion-detection': 3.620.0 - '@aws-sdk/middleware-user-agent': 3.620.0 - '@aws-sdk/region-config-resolver': 3.614.0 - '@aws-sdk/types': 3.609.0 - '@aws-sdk/util-endpoints': 3.614.0 - '@aws-sdk/util-user-agent-browser': 3.609.0 - '@aws-sdk/util-user-agent-node': 3.614.0 - '@smithy/config-resolver': 3.0.5 - '@smithy/core': 2.3.2 - '@smithy/fetch-http-handler': 3.2.4 - '@smithy/hash-node': 3.0.3 - '@smithy/invalid-dependency': 3.0.3 - '@smithy/middleware-content-length': 3.0.5 - '@smithy/middleware-endpoint': 3.1.0 - '@smithy/middleware-retry': 3.0.14 - '@smithy/middleware-serde': 3.0.3 - '@smithy/middleware-stack': 3.0.3 - '@smithy/node-config-provider': 3.1.4 - '@smithy/node-http-handler': 3.1.4 - '@smithy/protocol-http': 4.1.0 - '@smithy/smithy-client': 3.1.12 - '@smithy/types': 3.3.0 - '@smithy/url-parser': 3.0.3 + '@aws-sdk/client-sts': 3.699.0 + '@aws-sdk/core': 3.696.0 + '@aws-sdk/credential-provider-node': 3.699.0(@aws-sdk/client-sso-oidc@3.699.0(@aws-sdk/client-sts@3.699.0))(@aws-sdk/client-sts@3.699.0) + '@aws-sdk/middleware-host-header': 3.696.0 + '@aws-sdk/middleware-logger': 3.696.0 + '@aws-sdk/middleware-recursion-detection': 3.696.0 + '@aws-sdk/middleware-user-agent': 3.696.0 + '@aws-sdk/region-config-resolver': 3.696.0 + '@aws-sdk/types': 3.696.0 + '@aws-sdk/util-endpoints': 3.696.0 + '@aws-sdk/util-user-agent-browser': 3.696.0 + '@aws-sdk/util-user-agent-node': 3.696.0 + '@smithy/config-resolver': 3.0.12 + '@smithy/core': 2.5.4 + '@smithy/fetch-http-handler': 4.1.1 + '@smithy/hash-node': 3.0.10 + '@smithy/invalid-dependency': 3.0.10 + '@smithy/middleware-content-length': 3.0.12 + '@smithy/middleware-endpoint': 3.2.4 + '@smithy/middleware-retry': 3.0.28 + '@smithy/middleware-serde': 3.0.10 + '@smithy/middleware-stack': 3.0.10 + '@smithy/node-config-provider': 3.1.11 + '@smithy/node-http-handler': 3.3.1 + '@smithy/protocol-http': 4.1.7 + '@smithy/smithy-client': 3.4.5 + '@smithy/types': 3.7.1 + '@smithy/url-parser': 3.0.10 '@smithy/util-base64': 3.0.0 '@smithy/util-body-length-browser': 3.0.0 '@smithy/util-body-length-node': 3.0.0 - '@smithy/util-defaults-mode-browser': 3.0.14 - '@smithy/util-defaults-mode-node': 3.0.14 - '@smithy/util-endpoints': 2.0.5 - '@smithy/util-middleware': 3.0.3 - '@smithy/util-retry': 3.0.3 + '@smithy/util-defaults-mode-browser': 3.0.28 + '@smithy/util-defaults-mode-node': 3.0.28 + '@smithy/util-endpoints': 2.1.6 + '@smithy/util-middleware': 3.0.10 + '@smithy/util-retry': 3.0.10 '@smithy/util-utf8': 3.0.0 tslib: 2.6.3 transitivePeerDependencies: - aws-crt - '@aws-sdk/client-sso@3.614.0': + '@aws-sdk/client-sso@3.696.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.614.0 - '@aws-sdk/middleware-host-header': 3.609.0 - '@aws-sdk/middleware-logger': 3.609.0 - '@aws-sdk/middleware-recursion-detection': 3.609.0 - '@aws-sdk/middleware-user-agent': 3.614.0 - '@aws-sdk/region-config-resolver': 3.614.0 - '@aws-sdk/types': 3.609.0 - '@aws-sdk/util-endpoints': 3.614.0 - '@aws-sdk/util-user-agent-browser': 3.609.0 - '@aws-sdk/util-user-agent-node': 3.614.0 - '@smithy/config-resolver': 3.0.5 - '@smithy/core': 2.2.6 - '@smithy/fetch-http-handler': 3.2.1 - '@smithy/hash-node': 3.0.3 - '@smithy/invalid-dependency': 3.0.3 - '@smithy/middleware-content-length': 3.0.3 - '@smithy/middleware-endpoint': 3.0.5 - '@smithy/middleware-retry': 3.0.9 - '@smithy/middleware-serde': 3.0.3 - '@smithy/middleware-stack': 3.0.3 - '@smithy/node-config-provider': 3.1.4 - '@smithy/node-http-handler': 3.1.2 - '@smithy/protocol-http': 4.0.3 - '@smithy/smithy-client': 3.1.7 - '@smithy/types': 3.3.0 - '@smithy/url-parser': 3.0.3 + '@aws-sdk/core': 3.696.0 + '@aws-sdk/middleware-host-header': 3.696.0 + '@aws-sdk/middleware-logger': 3.696.0 + '@aws-sdk/middleware-recursion-detection': 3.696.0 + '@aws-sdk/middleware-user-agent': 3.696.0 + '@aws-sdk/region-config-resolver': 3.696.0 + '@aws-sdk/types': 3.696.0 + '@aws-sdk/util-endpoints': 3.696.0 + '@aws-sdk/util-user-agent-browser': 3.696.0 + '@aws-sdk/util-user-agent-node': 3.696.0 + '@smithy/config-resolver': 3.0.12 + '@smithy/core': 2.5.4 + '@smithy/fetch-http-handler': 4.1.1 + '@smithy/hash-node': 3.0.10 + '@smithy/invalid-dependency': 3.0.10 + '@smithy/middleware-content-length': 3.0.12 + '@smithy/middleware-endpoint': 3.2.4 + '@smithy/middleware-retry': 3.0.28 + '@smithy/middleware-serde': 3.0.10 + '@smithy/middleware-stack': 3.0.10 + '@smithy/node-config-provider': 3.1.11 + '@smithy/node-http-handler': 3.3.1 + '@smithy/protocol-http': 4.1.7 + '@smithy/smithy-client': 3.4.5 + '@smithy/types': 3.7.1 + '@smithy/url-parser': 3.0.10 '@smithy/util-base64': 3.0.0 '@smithy/util-body-length-browser': 3.0.0 '@smithy/util-body-length-node': 3.0.0 - '@smithy/util-defaults-mode-browser': 3.0.9 - '@smithy/util-defaults-mode-node': 3.0.9 - '@smithy/util-endpoints': 2.0.5 - '@smithy/util-middleware': 3.0.3 - '@smithy/util-retry': 3.0.3 + '@smithy/util-defaults-mode-browser': 3.0.28 + '@smithy/util-defaults-mode-node': 3.0.28 + '@smithy/util-endpoints': 2.1.6 + '@smithy/util-middleware': 3.0.10 + '@smithy/util-retry': 3.0.10 '@smithy/util-utf8': 3.0.0 tslib: 2.6.3 transitivePeerDependencies: - aws-crt - '@aws-sdk/client-sso@3.624.0': + '@aws-sdk/client-sts@3.699.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.624.0 - '@aws-sdk/middleware-host-header': 3.620.0 - '@aws-sdk/middleware-logger': 3.609.0 - '@aws-sdk/middleware-recursion-detection': 3.620.0 - '@aws-sdk/middleware-user-agent': 3.620.0 - '@aws-sdk/region-config-resolver': 3.614.0 - '@aws-sdk/types': 3.609.0 - '@aws-sdk/util-endpoints': 3.614.0 - '@aws-sdk/util-user-agent-browser': 3.609.0 - '@aws-sdk/util-user-agent-node': 3.614.0 - '@smithy/config-resolver': 3.0.5 - '@smithy/core': 2.3.2 - '@smithy/fetch-http-handler': 3.2.4 - '@smithy/hash-node': 3.0.3 - '@smithy/invalid-dependency': 3.0.3 - '@smithy/middleware-content-length': 3.0.5 - '@smithy/middleware-endpoint': 3.1.0 - '@smithy/middleware-retry': 3.0.14 - '@smithy/middleware-serde': 3.0.3 - '@smithy/middleware-stack': 3.0.3 - '@smithy/node-config-provider': 3.1.4 - '@smithy/node-http-handler': 3.1.4 - '@smithy/protocol-http': 4.1.0 - '@smithy/smithy-client': 3.1.12 - '@smithy/types': 3.3.0 - '@smithy/url-parser': 3.0.3 + '@aws-sdk/client-sso-oidc': 3.699.0(@aws-sdk/client-sts@3.699.0) + '@aws-sdk/core': 3.696.0 + '@aws-sdk/credential-provider-node': 3.699.0(@aws-sdk/client-sso-oidc@3.699.0(@aws-sdk/client-sts@3.699.0))(@aws-sdk/client-sts@3.699.0) + '@aws-sdk/middleware-host-header': 3.696.0 + '@aws-sdk/middleware-logger': 3.696.0 + '@aws-sdk/middleware-recursion-detection': 3.696.0 + '@aws-sdk/middleware-user-agent': 3.696.0 + '@aws-sdk/region-config-resolver': 3.696.0 + '@aws-sdk/types': 3.696.0 + '@aws-sdk/util-endpoints': 3.696.0 + '@aws-sdk/util-user-agent-browser': 3.696.0 + '@aws-sdk/util-user-agent-node': 3.696.0 + '@smithy/config-resolver': 3.0.12 + '@smithy/core': 2.5.4 + '@smithy/fetch-http-handler': 4.1.1 + '@smithy/hash-node': 3.0.10 + '@smithy/invalid-dependency': 3.0.10 + '@smithy/middleware-content-length': 3.0.12 + '@smithy/middleware-endpoint': 3.2.4 + '@smithy/middleware-retry': 3.0.28 + '@smithy/middleware-serde': 3.0.10 + '@smithy/middleware-stack': 3.0.10 + '@smithy/node-config-provider': 3.1.11 + '@smithy/node-http-handler': 3.3.1 + '@smithy/protocol-http': 4.1.7 + '@smithy/smithy-client': 3.4.5 + '@smithy/types': 3.7.1 + '@smithy/url-parser': 3.0.10 '@smithy/util-base64': 3.0.0 '@smithy/util-body-length-browser': 3.0.0 '@smithy/util-body-length-node': 3.0.0 - '@smithy/util-defaults-mode-browser': 3.0.14 - '@smithy/util-defaults-mode-node': 3.0.14 - '@smithy/util-endpoints': 2.0.5 - '@smithy/util-middleware': 3.0.3 - '@smithy/util-retry': 3.0.3 + '@smithy/util-defaults-mode-browser': 3.0.28 + '@smithy/util-defaults-mode-node': 3.0.28 + '@smithy/util-endpoints': 2.1.6 + '@smithy/util-middleware': 3.0.10 + '@smithy/util-retry': 3.0.10 '@smithy/util-utf8': 3.0.0 tslib: 2.6.3 transitivePeerDependencies: - aws-crt - '@aws-sdk/client-sts@3.614.0': - dependencies: - '@aws-crypto/sha256-browser': 5.2.0 - '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/client-sso-oidc': 3.614.0(@aws-sdk/client-sts@3.614.0) - '@aws-sdk/core': 3.614.0 - '@aws-sdk/credential-provider-node': 3.614.0(@aws-sdk/client-sso-oidc@3.614.0(@aws-sdk/client-sts@3.614.0))(@aws-sdk/client-sts@3.614.0) - '@aws-sdk/middleware-host-header': 3.609.0 - '@aws-sdk/middleware-logger': 3.609.0 - '@aws-sdk/middleware-recursion-detection': 3.609.0 - '@aws-sdk/middleware-user-agent': 3.614.0 - '@aws-sdk/region-config-resolver': 3.614.0 - '@aws-sdk/types': 3.609.0 - '@aws-sdk/util-endpoints': 3.614.0 - '@aws-sdk/util-user-agent-browser': 3.609.0 - '@aws-sdk/util-user-agent-node': 3.614.0 - '@smithy/config-resolver': 3.0.5 - '@smithy/core': 2.2.6 - '@smithy/fetch-http-handler': 3.2.1 - '@smithy/hash-node': 3.0.3 - '@smithy/invalid-dependency': 3.0.3 - '@smithy/middleware-content-length': 3.0.3 - '@smithy/middleware-endpoint': 3.0.5 - '@smithy/middleware-retry': 3.0.9 - '@smithy/middleware-serde': 3.0.3 - '@smithy/middleware-stack': 3.0.3 - '@smithy/node-config-provider': 3.1.4 - '@smithy/node-http-handler': 3.1.2 - '@smithy/protocol-http': 4.0.3 - '@smithy/smithy-client': 3.1.7 - '@smithy/types': 3.3.0 - '@smithy/url-parser': 3.0.3 - '@smithy/util-base64': 3.0.0 - '@smithy/util-body-length-browser': 3.0.0 - '@smithy/util-body-length-node': 3.0.0 - '@smithy/util-defaults-mode-browser': 3.0.9 - '@smithy/util-defaults-mode-node': 3.0.9 - '@smithy/util-endpoints': 2.0.5 - '@smithy/util-middleware': 3.0.3 - '@smithy/util-retry': 3.0.3 - '@smithy/util-utf8': 3.0.0 - tslib: 2.6.3 - transitivePeerDependencies: - - aws-crt - - '@aws-sdk/client-sts@3.624.0': - dependencies: - '@aws-crypto/sha256-browser': 5.2.0 - '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/client-sso-oidc': 3.624.0(@aws-sdk/client-sts@3.624.0) - '@aws-sdk/core': 3.624.0 - '@aws-sdk/credential-provider-node': 3.624.0(@aws-sdk/client-sso-oidc@3.624.0(@aws-sdk/client-sts@3.624.0))(@aws-sdk/client-sts@3.624.0) - '@aws-sdk/middleware-host-header': 3.620.0 - '@aws-sdk/middleware-logger': 3.609.0 - '@aws-sdk/middleware-recursion-detection': 3.620.0 - '@aws-sdk/middleware-user-agent': 3.620.0 - '@aws-sdk/region-config-resolver': 3.614.0 - '@aws-sdk/types': 3.609.0 - '@aws-sdk/util-endpoints': 3.614.0 - '@aws-sdk/util-user-agent-browser': 3.609.0 - '@aws-sdk/util-user-agent-node': 3.614.0 - '@smithy/config-resolver': 3.0.5 - '@smithy/core': 2.3.2 - '@smithy/fetch-http-handler': 3.2.4 - '@smithy/hash-node': 3.0.3 - '@smithy/invalid-dependency': 3.0.3 - '@smithy/middleware-content-length': 3.0.5 - '@smithy/middleware-endpoint': 3.1.0 - '@smithy/middleware-retry': 3.0.14 - '@smithy/middleware-serde': 3.0.3 - '@smithy/middleware-stack': 3.0.3 - '@smithy/node-config-provider': 3.1.4 - '@smithy/node-http-handler': 3.1.4 - '@smithy/protocol-http': 4.1.0 - '@smithy/smithy-client': 3.1.12 - '@smithy/types': 3.3.0 - '@smithy/url-parser': 3.0.3 - '@smithy/util-base64': 3.0.0 - '@smithy/util-body-length-browser': 3.0.0 - '@smithy/util-body-length-node': 3.0.0 - '@smithy/util-defaults-mode-browser': 3.0.14 - '@smithy/util-defaults-mode-node': 3.0.14 - '@smithy/util-endpoints': 2.0.5 - '@smithy/util-middleware': 3.0.3 - '@smithy/util-retry': 3.0.3 - '@smithy/util-utf8': 3.0.0 - tslib: 2.6.3 - transitivePeerDependencies: - - aws-crt - - '@aws-sdk/core@3.614.0': - dependencies: - '@smithy/core': 2.2.6 - '@smithy/protocol-http': 4.0.3 - '@smithy/signature-v4': 3.1.2 - '@smithy/smithy-client': 3.1.7 - '@smithy/types': 3.3.0 - fast-xml-parser: 4.4.1 - tslib: 2.6.3 - - '@aws-sdk/core@3.624.0': - dependencies: - '@smithy/core': 2.3.2 - '@smithy/node-config-provider': 3.1.4 - '@smithy/protocol-http': 4.1.0 - '@smithy/signature-v4': 4.1.0 - '@smithy/smithy-client': 3.1.12 - '@smithy/types': 3.3.0 - '@smithy/util-middleware': 3.0.3 + '@aws-sdk/core@3.696.0': + dependencies: + '@aws-sdk/types': 3.696.0 + '@smithy/core': 2.5.4 + '@smithy/node-config-provider': 3.1.11 + '@smithy/property-provider': 3.1.10 + '@smithy/protocol-http': 4.1.7 + '@smithy/signature-v4': 4.2.3 + '@smithy/smithy-client': 3.4.5 + '@smithy/types': 3.7.1 + '@smithy/util-middleware': 3.0.10 fast-xml-parser: 4.4.1 tslib: 2.6.3 - '@aws-sdk/credential-provider-env@3.609.0': - dependencies: - '@aws-sdk/types': 3.609.0 - '@smithy/property-provider': 3.1.3 - '@smithy/types': 3.3.0 - tslib: 2.6.3 - - '@aws-sdk/credential-provider-env@3.620.1': + '@aws-sdk/credential-provider-env@3.696.0': dependencies: - '@aws-sdk/types': 3.609.0 - '@smithy/property-provider': 3.1.3 - '@smithy/types': 3.3.0 + '@aws-sdk/core': 3.696.0 + '@aws-sdk/types': 3.696.0 + '@smithy/property-provider': 3.1.10 + '@smithy/types': 3.7.1 tslib: 2.6.3 - '@aws-sdk/credential-provider-http@3.614.0': + '@aws-sdk/credential-provider-http@3.696.0': dependencies: - '@aws-sdk/types': 3.609.0 - '@smithy/fetch-http-handler': 3.2.1 - '@smithy/node-http-handler': 3.1.2 - '@smithy/property-provider': 3.1.3 - '@smithy/protocol-http': 4.0.3 - '@smithy/smithy-client': 3.1.7 - '@smithy/types': 3.3.0 - '@smithy/util-stream': 3.0.6 + '@aws-sdk/core': 3.696.0 + '@aws-sdk/types': 3.696.0 + '@smithy/fetch-http-handler': 4.1.1 + '@smithy/node-http-handler': 3.3.1 + '@smithy/property-provider': 3.1.10 + '@smithy/protocol-http': 4.1.7 + '@smithy/smithy-client': 3.4.5 + '@smithy/types': 3.7.1 + '@smithy/util-stream': 3.3.1 tslib: 2.6.3 - '@aws-sdk/credential-provider-http@3.622.0': + '@aws-sdk/credential-provider-ini@3.699.0(@aws-sdk/client-sso-oidc@3.699.0(@aws-sdk/client-sts@3.699.0))(@aws-sdk/client-sts@3.699.0)': dependencies: - '@aws-sdk/types': 3.609.0 - '@smithy/fetch-http-handler': 3.2.4 - '@smithy/node-http-handler': 3.1.4 - '@smithy/property-provider': 3.1.3 - '@smithy/protocol-http': 4.1.0 - '@smithy/smithy-client': 3.1.12 - '@smithy/types': 3.3.0 - '@smithy/util-stream': 3.1.3 - tslib: 2.6.3 - - '@aws-sdk/credential-provider-ini@3.614.0(@aws-sdk/client-sso-oidc@3.614.0(@aws-sdk/client-sts@3.614.0))(@aws-sdk/client-sts@3.614.0)': - dependencies: - '@aws-sdk/client-sts': 3.614.0 - '@aws-sdk/credential-provider-env': 3.609.0 - '@aws-sdk/credential-provider-http': 3.614.0 - '@aws-sdk/credential-provider-process': 3.614.0 - '@aws-sdk/credential-provider-sso': 3.614.0(@aws-sdk/client-sso-oidc@3.614.0(@aws-sdk/client-sts@3.614.0)) - '@aws-sdk/credential-provider-web-identity': 3.609.0(@aws-sdk/client-sts@3.614.0) - '@aws-sdk/types': 3.609.0 - '@smithy/credential-provider-imds': 3.1.4 - '@smithy/property-provider': 3.1.3 - '@smithy/shared-ini-file-loader': 3.1.4 - '@smithy/types': 3.3.0 - tslib: 2.6.3 - transitivePeerDependencies: - - '@aws-sdk/client-sso-oidc' - - aws-crt - - '@aws-sdk/credential-provider-ini@3.624.0(@aws-sdk/client-sso-oidc@3.624.0(@aws-sdk/client-sts@3.624.0))(@aws-sdk/client-sts@3.624.0)': - dependencies: - '@aws-sdk/client-sts': 3.624.0 - '@aws-sdk/credential-provider-env': 3.620.1 - '@aws-sdk/credential-provider-http': 3.622.0 - '@aws-sdk/credential-provider-process': 3.620.1 - '@aws-sdk/credential-provider-sso': 3.624.0(@aws-sdk/client-sso-oidc@3.624.0(@aws-sdk/client-sts@3.624.0)) - '@aws-sdk/credential-provider-web-identity': 3.621.0(@aws-sdk/client-sts@3.624.0) - '@aws-sdk/types': 3.609.0 - '@smithy/credential-provider-imds': 3.2.0 - '@smithy/property-provider': 3.1.3 - '@smithy/shared-ini-file-loader': 3.1.4 - '@smithy/types': 3.3.0 - tslib: 2.6.3 - transitivePeerDependencies: - - '@aws-sdk/client-sso-oidc' - - aws-crt - - '@aws-sdk/credential-provider-node@3.614.0(@aws-sdk/client-sso-oidc@3.614.0(@aws-sdk/client-sts@3.614.0))(@aws-sdk/client-sts@3.614.0)': - dependencies: - '@aws-sdk/credential-provider-env': 3.609.0 - '@aws-sdk/credential-provider-http': 3.614.0 - '@aws-sdk/credential-provider-ini': 3.614.0(@aws-sdk/client-sso-oidc@3.614.0(@aws-sdk/client-sts@3.614.0))(@aws-sdk/client-sts@3.614.0) - '@aws-sdk/credential-provider-process': 3.614.0 - '@aws-sdk/credential-provider-sso': 3.614.0(@aws-sdk/client-sso-oidc@3.614.0(@aws-sdk/client-sts@3.614.0)) - '@aws-sdk/credential-provider-web-identity': 3.609.0(@aws-sdk/client-sts@3.614.0) - '@aws-sdk/types': 3.609.0 - '@smithy/credential-provider-imds': 3.1.4 - '@smithy/property-provider': 3.1.3 - '@smithy/shared-ini-file-loader': 3.1.4 - '@smithy/types': 3.3.0 + '@aws-sdk/client-sts': 3.699.0 + '@aws-sdk/core': 3.696.0 + '@aws-sdk/credential-provider-env': 3.696.0 + '@aws-sdk/credential-provider-http': 3.696.0 + '@aws-sdk/credential-provider-process': 3.696.0 + '@aws-sdk/credential-provider-sso': 3.699.0(@aws-sdk/client-sso-oidc@3.699.0(@aws-sdk/client-sts@3.699.0)) + '@aws-sdk/credential-provider-web-identity': 3.696.0(@aws-sdk/client-sts@3.699.0) + '@aws-sdk/types': 3.696.0 + '@smithy/credential-provider-imds': 3.2.7 + '@smithy/property-provider': 3.1.10 + '@smithy/shared-ini-file-loader': 3.1.11 + '@smithy/types': 3.7.1 tslib: 2.6.3 transitivePeerDependencies: - '@aws-sdk/client-sso-oidc' - - '@aws-sdk/client-sts' - aws-crt - '@aws-sdk/credential-provider-node@3.624.0(@aws-sdk/client-sso-oidc@3.624.0(@aws-sdk/client-sts@3.624.0))(@aws-sdk/client-sts@3.624.0)': - dependencies: - '@aws-sdk/credential-provider-env': 3.620.1 - '@aws-sdk/credential-provider-http': 3.622.0 - '@aws-sdk/credential-provider-ini': 3.624.0(@aws-sdk/client-sso-oidc@3.624.0(@aws-sdk/client-sts@3.624.0))(@aws-sdk/client-sts@3.624.0) - '@aws-sdk/credential-provider-process': 3.620.1 - '@aws-sdk/credential-provider-sso': 3.624.0(@aws-sdk/client-sso-oidc@3.624.0(@aws-sdk/client-sts@3.624.0)) - '@aws-sdk/credential-provider-web-identity': 3.621.0(@aws-sdk/client-sts@3.624.0) - '@aws-sdk/types': 3.609.0 - '@smithy/credential-provider-imds': 3.2.0 - '@smithy/property-provider': 3.1.3 - '@smithy/shared-ini-file-loader': 3.1.4 - '@smithy/types': 3.3.0 + '@aws-sdk/credential-provider-node@3.699.0(@aws-sdk/client-sso-oidc@3.699.0(@aws-sdk/client-sts@3.699.0))(@aws-sdk/client-sts@3.699.0)': + dependencies: + '@aws-sdk/credential-provider-env': 3.696.0 + '@aws-sdk/credential-provider-http': 3.696.0 + '@aws-sdk/credential-provider-ini': 3.699.0(@aws-sdk/client-sso-oidc@3.699.0(@aws-sdk/client-sts@3.699.0))(@aws-sdk/client-sts@3.699.0) + '@aws-sdk/credential-provider-process': 3.696.0 + '@aws-sdk/credential-provider-sso': 3.699.0(@aws-sdk/client-sso-oidc@3.699.0(@aws-sdk/client-sts@3.699.0)) + '@aws-sdk/credential-provider-web-identity': 3.696.0(@aws-sdk/client-sts@3.699.0) + '@aws-sdk/types': 3.696.0 + '@smithy/credential-provider-imds': 3.2.7 + '@smithy/property-provider': 3.1.10 + '@smithy/shared-ini-file-loader': 3.1.11 + '@smithy/types': 3.7.1 tslib: 2.6.3 transitivePeerDependencies: - '@aws-sdk/client-sso-oidc' - '@aws-sdk/client-sts' - aws-crt - '@aws-sdk/credential-provider-process@3.614.0': + '@aws-sdk/credential-provider-process@3.696.0': dependencies: - '@aws-sdk/types': 3.609.0 - '@smithy/property-provider': 3.1.3 - '@smithy/shared-ini-file-loader': 3.1.4 - '@smithy/types': 3.3.0 + '@aws-sdk/core': 3.696.0 + '@aws-sdk/types': 3.696.0 + '@smithy/property-provider': 3.1.10 + '@smithy/shared-ini-file-loader': 3.1.11 + '@smithy/types': 3.7.1 tslib: 2.6.3 - '@aws-sdk/credential-provider-process@3.620.1': + '@aws-sdk/credential-provider-sso@3.699.0(@aws-sdk/client-sso-oidc@3.699.0(@aws-sdk/client-sts@3.699.0))': dependencies: - '@aws-sdk/types': 3.609.0 - '@smithy/property-provider': 3.1.3 - '@smithy/shared-ini-file-loader': 3.1.4 - '@smithy/types': 3.3.0 - tslib: 2.6.3 - - '@aws-sdk/credential-provider-sso@3.614.0(@aws-sdk/client-sso-oidc@3.614.0(@aws-sdk/client-sts@3.614.0))': - dependencies: - '@aws-sdk/client-sso': 3.614.0 - '@aws-sdk/token-providers': 3.614.0(@aws-sdk/client-sso-oidc@3.614.0(@aws-sdk/client-sts@3.614.0)) - '@aws-sdk/types': 3.609.0 - '@smithy/property-provider': 3.1.3 - '@smithy/shared-ini-file-loader': 3.1.4 - '@smithy/types': 3.3.0 + '@aws-sdk/client-sso': 3.696.0 + '@aws-sdk/core': 3.696.0 + '@aws-sdk/token-providers': 3.699.0(@aws-sdk/client-sso-oidc@3.699.0(@aws-sdk/client-sts@3.699.0)) + '@aws-sdk/types': 3.696.0 + '@smithy/property-provider': 3.1.10 + '@smithy/shared-ini-file-loader': 3.1.11 + '@smithy/types': 3.7.1 tslib: 2.6.3 transitivePeerDependencies: - '@aws-sdk/client-sso-oidc' - aws-crt - '@aws-sdk/credential-provider-sso@3.624.0(@aws-sdk/client-sso-oidc@3.624.0(@aws-sdk/client-sts@3.624.0))': + '@aws-sdk/credential-provider-web-identity@3.696.0(@aws-sdk/client-sts@3.699.0)': dependencies: - '@aws-sdk/client-sso': 3.624.0 - '@aws-sdk/token-providers': 3.614.0(@aws-sdk/client-sso-oidc@3.624.0(@aws-sdk/client-sts@3.624.0)) - '@aws-sdk/types': 3.609.0 - '@smithy/property-provider': 3.1.3 - '@smithy/shared-ini-file-loader': 3.1.4 - '@smithy/types': 3.3.0 + '@aws-sdk/client-sts': 3.699.0 + '@aws-sdk/core': 3.696.0 + '@aws-sdk/types': 3.696.0 + '@smithy/property-provider': 3.1.10 + '@smithy/types': 3.7.1 tslib: 2.6.3 - transitivePeerDependencies: - - '@aws-sdk/client-sso-oidc' - - aws-crt - '@aws-sdk/credential-provider-web-identity@3.609.0(@aws-sdk/client-sts@3.614.0)': + '@aws-sdk/middleware-bucket-endpoint@3.696.0': dependencies: - '@aws-sdk/client-sts': 3.614.0 - '@aws-sdk/types': 3.609.0 - '@smithy/property-provider': 3.1.3 - '@smithy/types': 3.3.0 - tslib: 2.6.3 - - '@aws-sdk/credential-provider-web-identity@3.621.0(@aws-sdk/client-sts@3.624.0)': - dependencies: - '@aws-sdk/client-sts': 3.624.0 - '@aws-sdk/types': 3.609.0 - '@smithy/property-provider': 3.1.3 - '@smithy/types': 3.3.0 - tslib: 2.6.3 - - '@aws-sdk/middleware-bucket-endpoint@3.614.0': - dependencies: - '@aws-sdk/types': 3.609.0 - '@aws-sdk/util-arn-parser': 3.568.0 - '@smithy/node-config-provider': 3.1.4 - '@smithy/protocol-http': 4.0.3 - '@smithy/types': 3.3.0 + '@aws-sdk/types': 3.696.0 + '@aws-sdk/util-arn-parser': 3.693.0 + '@smithy/node-config-provider': 3.1.11 + '@smithy/protocol-http': 4.1.7 + '@smithy/types': 3.7.1 '@smithy/util-config-provider': 3.0.0 tslib: 2.6.3 - '@aws-sdk/middleware-expect-continue@3.609.0': + '@aws-sdk/middleware-expect-continue@3.696.0': dependencies: - '@aws-sdk/types': 3.609.0 - '@smithy/protocol-http': 4.0.3 - '@smithy/types': 3.3.0 + '@aws-sdk/types': 3.696.0 + '@smithy/protocol-http': 4.1.7 + '@smithy/types': 3.7.1 tslib: 2.6.3 - '@aws-sdk/middleware-flexible-checksums@3.614.0': + '@aws-sdk/middleware-flexible-checksums@3.701.0': dependencies: '@aws-crypto/crc32': 5.2.0 '@aws-crypto/crc32c': 5.2.0 - '@aws-sdk/types': 3.609.0 + '@aws-crypto/util': 5.2.0 + '@aws-sdk/core': 3.696.0 + '@aws-sdk/types': 3.696.0 '@smithy/is-array-buffer': 3.0.0 - '@smithy/protocol-http': 4.0.3 - '@smithy/types': 3.3.0 + '@smithy/node-config-provider': 3.1.11 + '@smithy/protocol-http': 4.1.7 + '@smithy/types': 3.7.1 + '@smithy/util-middleware': 3.0.10 + '@smithy/util-stream': 3.3.1 '@smithy/util-utf8': 3.0.0 tslib: 2.6.3 - '@aws-sdk/middleware-host-header@3.609.0': - dependencies: - '@aws-sdk/types': 3.609.0 - '@smithy/protocol-http': 4.0.3 - '@smithy/types': 3.3.0 - tslib: 2.6.3 - - '@aws-sdk/middleware-host-header@3.620.0': - dependencies: - '@aws-sdk/types': 3.609.0 - '@smithy/protocol-http': 4.1.0 - '@smithy/types': 3.3.0 - tslib: 2.6.3 - - '@aws-sdk/middleware-location-constraint@3.609.0': + '@aws-sdk/middleware-host-header@3.696.0': dependencies: - '@aws-sdk/types': 3.609.0 - '@smithy/types': 3.3.0 + '@aws-sdk/types': 3.696.0 + '@smithy/protocol-http': 4.1.7 + '@smithy/types': 3.7.1 tslib: 2.6.3 - '@aws-sdk/middleware-logger@3.609.0': + '@aws-sdk/middleware-location-constraint@3.696.0': dependencies: - '@aws-sdk/types': 3.609.0 - '@smithy/types': 3.3.0 + '@aws-sdk/types': 3.696.0 + '@smithy/types': 3.7.1 tslib: 2.6.3 - '@aws-sdk/middleware-recursion-detection@3.609.0': + '@aws-sdk/middleware-logger@3.696.0': dependencies: - '@aws-sdk/types': 3.609.0 - '@smithy/protocol-http': 4.0.3 - '@smithy/types': 3.3.0 + '@aws-sdk/types': 3.696.0 + '@smithy/types': 3.7.1 tslib: 2.6.3 - '@aws-sdk/middleware-recursion-detection@3.620.0': + '@aws-sdk/middleware-recursion-detection@3.696.0': dependencies: - '@aws-sdk/types': 3.609.0 - '@smithy/protocol-http': 4.1.0 - '@smithy/types': 3.3.0 + '@aws-sdk/types': 3.696.0 + '@smithy/protocol-http': 4.1.7 + '@smithy/types': 3.7.1 tslib: 2.6.3 - '@aws-sdk/middleware-sdk-s3@3.614.0': + '@aws-sdk/middleware-sdk-s3@3.696.0': dependencies: - '@aws-sdk/types': 3.609.0 - '@aws-sdk/util-arn-parser': 3.568.0 - '@smithy/node-config-provider': 3.1.4 - '@smithy/protocol-http': 4.0.3 - '@smithy/signature-v4': 3.1.2 - '@smithy/smithy-client': 3.1.7 - '@smithy/types': 3.3.0 + '@aws-sdk/core': 3.696.0 + '@aws-sdk/types': 3.696.0 + '@aws-sdk/util-arn-parser': 3.693.0 + '@smithy/core': 2.5.4 + '@smithy/node-config-provider': 3.1.11 + '@smithy/protocol-http': 4.1.7 + '@smithy/signature-v4': 4.2.3 + '@smithy/smithy-client': 3.4.5 + '@smithy/types': 3.7.1 '@smithy/util-config-provider': 3.0.0 + '@smithy/util-middleware': 3.0.10 + '@smithy/util-stream': 3.3.1 + '@smithy/util-utf8': 3.0.0 tslib: 2.6.3 - '@aws-sdk/middleware-signing@3.609.0': - dependencies: - '@aws-sdk/types': 3.609.0 - '@smithy/property-provider': 3.1.3 - '@smithy/protocol-http': 4.0.3 - '@smithy/signature-v4': 3.1.2 - '@smithy/types': 3.3.0 - '@smithy/util-middleware': 3.0.3 - tslib: 2.6.3 - - '@aws-sdk/middleware-ssec@3.609.0': - dependencies: - '@aws-sdk/types': 3.609.0 - '@smithy/types': 3.3.0 - tslib: 2.6.3 - - '@aws-sdk/middleware-user-agent@3.614.0': + '@aws-sdk/middleware-ssec@3.696.0': dependencies: - '@aws-sdk/types': 3.609.0 - '@aws-sdk/util-endpoints': 3.614.0 - '@smithy/protocol-http': 4.0.3 - '@smithy/types': 3.3.0 + '@aws-sdk/types': 3.696.0 + '@smithy/types': 3.7.1 tslib: 2.6.3 - '@aws-sdk/middleware-user-agent@3.620.0': + '@aws-sdk/middleware-user-agent@3.696.0': dependencies: - '@aws-sdk/types': 3.609.0 - '@aws-sdk/util-endpoints': 3.614.0 - '@smithy/protocol-http': 4.1.0 - '@smithy/types': 3.3.0 + '@aws-sdk/core': 3.696.0 + '@aws-sdk/types': 3.696.0 + '@aws-sdk/util-endpoints': 3.696.0 + '@smithy/core': 2.5.4 + '@smithy/protocol-http': 4.1.7 + '@smithy/types': 3.7.1 tslib: 2.6.3 - '@aws-sdk/region-config-resolver@3.614.0': + '@aws-sdk/region-config-resolver@3.696.0': dependencies: - '@aws-sdk/types': 3.609.0 - '@smithy/node-config-provider': 3.1.4 - '@smithy/types': 3.3.0 + '@aws-sdk/types': 3.696.0 + '@smithy/node-config-provider': 3.1.11 + '@smithy/types': 3.7.1 '@smithy/util-config-provider': 3.0.0 - '@smithy/util-middleware': 3.0.3 - tslib: 2.6.3 - - '@aws-sdk/signature-v4-multi-region@3.614.0': - dependencies: - '@aws-sdk/middleware-sdk-s3': 3.614.0 - '@aws-sdk/types': 3.609.0 - '@smithy/protocol-http': 4.0.3 - '@smithy/signature-v4': 3.1.2 - '@smithy/types': 3.3.0 + '@smithy/util-middleware': 3.0.10 tslib: 2.6.3 - '@aws-sdk/token-providers@3.614.0(@aws-sdk/client-sso-oidc@3.614.0(@aws-sdk/client-sts@3.614.0))': + '@aws-sdk/signature-v4-multi-region@3.696.0': dependencies: - '@aws-sdk/client-sso-oidc': 3.614.0(@aws-sdk/client-sts@3.614.0) - '@aws-sdk/types': 3.609.0 - '@smithy/property-provider': 3.1.3 - '@smithy/shared-ini-file-loader': 3.1.4 - '@smithy/types': 3.3.0 + '@aws-sdk/middleware-sdk-s3': 3.696.0 + '@aws-sdk/types': 3.696.0 + '@smithy/protocol-http': 4.1.7 + '@smithy/signature-v4': 4.2.3 + '@smithy/types': 3.7.1 tslib: 2.6.3 - '@aws-sdk/token-providers@3.614.0(@aws-sdk/client-sso-oidc@3.624.0(@aws-sdk/client-sts@3.624.0))': + '@aws-sdk/token-providers@3.699.0(@aws-sdk/client-sso-oidc@3.699.0(@aws-sdk/client-sts@3.699.0))': dependencies: - '@aws-sdk/client-sso-oidc': 3.624.0(@aws-sdk/client-sts@3.624.0) - '@aws-sdk/types': 3.609.0 - '@smithy/property-provider': 3.1.3 - '@smithy/shared-ini-file-loader': 3.1.4 - '@smithy/types': 3.3.0 + '@aws-sdk/client-sso-oidc': 3.699.0(@aws-sdk/client-sts@3.699.0) + '@aws-sdk/types': 3.696.0 + '@smithy/property-provider': 3.1.10 + '@smithy/shared-ini-file-loader': 3.1.11 + '@smithy/types': 3.7.1 tslib: 2.6.3 - '@aws-sdk/types@3.609.0': + '@aws-sdk/types@3.696.0': dependencies: - '@smithy/types': 3.3.0 + '@smithy/types': 3.7.1 tslib: 2.6.3 - '@aws-sdk/util-arn-parser@3.568.0': + '@aws-sdk/util-arn-parser@3.693.0': dependencies: tslib: 2.6.3 - '@aws-sdk/util-endpoints@3.614.0': + '@aws-sdk/util-endpoints@3.696.0': dependencies: - '@aws-sdk/types': 3.609.0 - '@smithy/types': 3.3.0 - '@smithy/util-endpoints': 2.0.5 + '@aws-sdk/types': 3.696.0 + '@smithy/types': 3.7.1 + '@smithy/util-endpoints': 2.1.6 tslib: 2.6.3 '@aws-sdk/util-locate-window@3.568.0': dependencies: tslib: 2.6.3 - '@aws-sdk/util-user-agent-browser@3.609.0': + '@aws-sdk/util-user-agent-browser@3.696.0': dependencies: - '@aws-sdk/types': 3.609.0 - '@smithy/types': 3.3.0 + '@aws-sdk/types': 3.696.0 + '@smithy/types': 3.7.1 bowser: 2.11.0 tslib: 2.6.3 - '@aws-sdk/util-user-agent-node@3.614.0': + '@aws-sdk/util-user-agent-node@3.696.0': dependencies: - '@aws-sdk/types': 3.609.0 - '@smithy/node-config-provider': 3.1.4 - '@smithy/types': 3.3.0 + '@aws-sdk/middleware-user-agent': 3.696.0 + '@aws-sdk/types': 3.696.0 + '@smithy/node-config-provider': 3.1.11 + '@smithy/types': 3.7.1 tslib: 2.6.3 - '@aws-sdk/xml-builder@3.609.0': + '@aws-sdk/xml-builder@3.696.0': dependencies: - '@smithy/types': 3.3.0 + '@smithy/types': 3.7.1 tslib: 2.6.3 '@babel/code-frame@7.24.7': @@ -3986,7 +3785,7 @@ snapshots: '@babel/traverse': 7.24.7 '@babel/types': 7.24.7 convert-source-map: 2.0.0 - debug: 4.3.5(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -4092,7 +3891,7 @@ snapshots: '@babel/helper-split-export-declaration': 7.24.7 '@babel/parser': 7.24.7 '@babel/types': 7.24.7 - debug: 4.3.5(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -4205,7 +4004,7 @@ snapshots: '@eslint/config-array@0.17.1': dependencies: '@eslint/object-schema': 2.1.4 - debug: 4.3.5(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -4213,7 +4012,7 @@ snapshots: '@eslint/eslintrc@3.1.0': dependencies: ajv: 6.12.6 - debug: 4.3.5(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) espree: 10.1.0 globals: 14.0.0 ignore: 5.3.1 @@ -4235,25 +4034,49 @@ snapshots: '@inquirer/checkbox@2.4.7': dependencies: '@inquirer/core': 9.0.10 - '@inquirer/figures': 1.0.5 - '@inquirer/type': 1.5.2 + '@inquirer/figures': 1.0.8 + '@inquirer/type': 1.5.5 ansi-escapes: 4.3.2 yoctocolors-cjs: 2.1.2 - '@inquirer/confirm@3.1.16': + '@inquirer/checkbox@4.0.2(@types/node@22.1.0)': dependencies: - '@inquirer/core': 9.0.10 - '@inquirer/type': 1.5.0 + '@inquirer/core': 10.1.0(@types/node@22.1.0) + '@inquirer/figures': 1.0.8 + '@inquirer/type': 3.0.1(@types/node@22.1.0) + '@types/node': 22.1.0 + ansi-escapes: 4.3.2 + yoctocolors-cjs: 2.1.2 '@inquirer/confirm@3.1.22': dependencies: '@inquirer/core': 9.0.10 - '@inquirer/type': 1.5.2 + '@inquirer/type': 1.5.5 + + '@inquirer/confirm@5.0.2(@types/node@22.1.0)': + dependencies: + '@inquirer/core': 10.1.0(@types/node@22.1.0) + '@inquirer/type': 3.0.1(@types/node@22.1.0) + '@types/node': 22.1.0 + + '@inquirer/core@10.1.0(@types/node@22.1.0)': + dependencies: + '@inquirer/figures': 1.0.8 + '@inquirer/type': 3.0.1(@types/node@22.1.0) + ansi-escapes: 4.3.2 + cli-width: 4.1.0 + mute-stream: 2.0.0 + signal-exit: 4.1.0 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + yoctocolors-cjs: 2.1.2 + transitivePeerDependencies: + - '@types/node' '@inquirer/core@9.0.10': dependencies: - '@inquirer/figures': 1.0.5 - '@inquirer/type': 1.5.2 + '@inquirer/figures': 1.0.8 + '@inquirer/type': 1.5.5 '@types/mute-stream': 0.0.4 '@types/node': 22.1.0 '@types/wrap-ansi': 3.0.0 @@ -4266,36 +4089,82 @@ snapshots: wrap-ansi: 6.2.0 yoctocolors-cjs: 2.1.2 + '@inquirer/core@9.2.1': + dependencies: + '@inquirer/figures': 1.0.8 + '@inquirer/type': 2.0.0 + '@types/mute-stream': 0.0.4 + '@types/node': 22.10.1 + '@types/wrap-ansi': 3.0.0 + ansi-escapes: 4.3.2 + cli-width: 4.1.0 + mute-stream: 1.0.0 + signal-exit: 4.1.0 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + yoctocolors-cjs: 2.1.2 + '@inquirer/editor@2.1.22': dependencies: '@inquirer/core': 9.0.10 - '@inquirer/type': 1.5.2 + '@inquirer/type': 1.5.5 + external-editor: 3.1.0 + + '@inquirer/editor@4.1.0(@types/node@22.1.0)': + dependencies: + '@inquirer/core': 10.1.0(@types/node@22.1.0) + '@inquirer/type': 3.0.1(@types/node@22.1.0) + '@types/node': 22.1.0 external-editor: 3.1.0 '@inquirer/expand@2.1.22': dependencies: '@inquirer/core': 9.0.10 - '@inquirer/type': 1.5.2 + '@inquirer/type': 1.5.5 yoctocolors-cjs: 2.1.2 - '@inquirer/figures@1.0.4': {} + '@inquirer/expand@4.0.2(@types/node@22.1.0)': + dependencies: + '@inquirer/core': 10.1.0(@types/node@22.1.0) + '@inquirer/type': 3.0.1(@types/node@22.1.0) + '@types/node': 22.1.0 + yoctocolors-cjs: 2.1.2 - '@inquirer/figures@1.0.5': {} + '@inquirer/figures@1.0.8': {} '@inquirer/input@2.2.9': dependencies: '@inquirer/core': 9.0.10 - '@inquirer/type': 1.5.2 + '@inquirer/type': 1.5.5 + + '@inquirer/input@4.0.2(@types/node@22.1.0)': + dependencies: + '@inquirer/core': 10.1.0(@types/node@22.1.0) + '@inquirer/type': 3.0.1(@types/node@22.1.0) + '@types/node': 22.1.0 '@inquirer/number@1.0.10': dependencies: '@inquirer/core': 9.0.10 - '@inquirer/type': 1.5.2 + '@inquirer/type': 1.5.5 + + '@inquirer/number@3.0.2(@types/node@22.1.0)': + dependencies: + '@inquirer/core': 10.1.0(@types/node@22.1.0) + '@inquirer/type': 3.0.1(@types/node@22.1.0) + '@types/node': 22.1.0 '@inquirer/password@2.1.22': dependencies: '@inquirer/core': 9.0.10 - '@inquirer/type': 1.5.2 + '@inquirer/type': 1.5.5 + ansi-escapes: 4.3.2 + + '@inquirer/password@4.0.2(@types/node@22.1.0)': + dependencies: + '@inquirer/core': 10.1.0(@types/node@22.1.0) + '@inquirer/type': 3.0.1(@types/node@22.1.0) + '@types/node': 22.1.0 ansi-escapes: 4.3.2 '@inquirer/prompts@5.3.8': @@ -4309,45 +4178,79 @@ snapshots: '@inquirer/password': 2.1.22 '@inquirer/rawlist': 2.2.4 '@inquirer/search': 1.0.7 - '@inquirer/select': 2.4.7 + '@inquirer/select': 2.5.0 + + '@inquirer/prompts@7.1.0(@types/node@22.1.0)': + dependencies: + '@inquirer/checkbox': 4.0.2(@types/node@22.1.0) + '@inquirer/confirm': 5.0.2(@types/node@22.1.0) + '@inquirer/editor': 4.1.0(@types/node@22.1.0) + '@inquirer/expand': 4.0.2(@types/node@22.1.0) + '@inquirer/input': 4.0.2(@types/node@22.1.0) + '@inquirer/number': 3.0.2(@types/node@22.1.0) + '@inquirer/password': 4.0.2(@types/node@22.1.0) + '@inquirer/rawlist': 4.0.2(@types/node@22.1.0) + '@inquirer/search': 3.0.2(@types/node@22.1.0) + '@inquirer/select': 4.0.2(@types/node@22.1.0) + '@types/node': 22.1.0 '@inquirer/rawlist@2.2.4': dependencies: '@inquirer/core': 9.0.10 - '@inquirer/type': 1.5.2 + '@inquirer/type': 1.5.5 + yoctocolors-cjs: 2.1.2 + + '@inquirer/rawlist@4.0.2(@types/node@22.1.0)': + dependencies: + '@inquirer/core': 10.1.0(@types/node@22.1.0) + '@inquirer/type': 3.0.1(@types/node@22.1.0) + '@types/node': 22.1.0 yoctocolors-cjs: 2.1.2 '@inquirer/search@1.0.7': dependencies: '@inquirer/core': 9.0.10 - '@inquirer/figures': 1.0.5 - '@inquirer/type': 1.5.2 + '@inquirer/figures': 1.0.8 + '@inquirer/type': 1.5.5 yoctocolors-cjs: 2.1.2 - '@inquirer/select@2.4.1': + '@inquirer/search@3.0.2(@types/node@22.1.0)': dependencies: - '@inquirer/core': 9.0.10 - '@inquirer/figures': 1.0.4 - '@inquirer/type': 1.5.0 + '@inquirer/core': 10.1.0(@types/node@22.1.0) + '@inquirer/figures': 1.0.8 + '@inquirer/type': 3.0.1(@types/node@22.1.0) + '@types/node': 22.1.0 + yoctocolors-cjs: 2.1.2 + + '@inquirer/select@2.5.0': + dependencies: + '@inquirer/core': 9.2.1 + '@inquirer/figures': 1.0.8 + '@inquirer/type': 1.5.5 ansi-escapes: 4.3.2 yoctocolors-cjs: 2.1.2 - '@inquirer/select@2.4.7': + '@inquirer/select@4.0.2(@types/node@22.1.0)': dependencies: - '@inquirer/core': 9.0.10 - '@inquirer/figures': 1.0.5 - '@inquirer/type': 1.5.2 + '@inquirer/core': 10.1.0(@types/node@22.1.0) + '@inquirer/figures': 1.0.8 + '@inquirer/type': 3.0.1(@types/node@22.1.0) + '@types/node': 22.1.0 ansi-escapes: 4.3.2 yoctocolors-cjs: 2.1.2 - '@inquirer/type@1.5.0': + '@inquirer/type@1.5.5': dependencies: mute-stream: 1.0.0 - '@inquirer/type@1.5.2': + '@inquirer/type@2.0.0': dependencies: mute-stream: 1.0.0 + '@inquirer/type@3.0.1(@types/node@22.1.0)': + dependencies: + '@types/node': 22.1.0 + '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 @@ -4408,213 +4311,198 @@ snapshots: '@npmcli/fs@3.1.1': dependencies: - semver: 7.6.2 + semver: 7.6.3 - '@oclif/core@4.0.17': + '@oclif/core@4.0.36': dependencies: ansi-escapes: 4.3.2 ansis: 3.3.2 clean-stack: 3.0.1 cli-spinners: 2.9.2 - debug: 4.3.5(supports-color@8.1.1) + debug: 4.4.0(supports-color@8.1.1) ejs: 3.1.10 get-package-type: 0.1.0 globby: 11.1.0 indent-string: 4.0.0 is-wsl: 2.2.0 - lilconfig: 3.1.2 + lilconfig: 3.1.3 minimatch: 9.0.5 + semver: 7.6.3 string-width: 4.2.3 supports-color: 8.1.1 widest-line: 3.1.0 wordwrap: 1.0.0 wrap-ansi: 7.0.0 - '@oclif/plugin-help@6.2.8': + '@oclif/plugin-help@6.2.19': dependencies: - '@oclif/core': 4.0.17 + '@oclif/core': 4.0.36 - '@oclif/plugin-not-found@3.2.15': + '@oclif/plugin-not-found@3.2.29(@types/node@22.1.0)': dependencies: - '@inquirer/confirm': 3.1.16 - '@oclif/core': 4.0.17 - ansis: 3.3.1 + '@inquirer/prompts': 7.1.0(@types/node@22.1.0) + '@oclif/core': 4.0.36 + ansis: 3.3.2 fast-levenshtein: 3.0.0 + transitivePeerDependencies: + - '@types/node' - '@oclif/plugin-warn-if-update-available@3.1.7': + '@oclif/plugin-warn-if-update-available@3.1.23': dependencies: - '@oclif/core': 4.0.17 - ansis: 3.3.1 - debug: 4.3.5(supports-color@8.1.1) + '@oclif/core': 4.0.36 + ansis: 3.3.2 + debug: 4.3.7(supports-color@8.1.1) http-call: 5.3.0 lodash: 4.17.21 + registry-auth-token: 5.0.3 transitivePeerDependencies: - supports-color '@oclif/prettier-config@0.2.1': {} - '@oclif/test@4.0.8(@oclif/core@4.0.17)': + '@oclif/test@4.1.3(@oclif/core@4.0.36)': dependencies: - '@oclif/core': 4.0.17 + '@oclif/core': 4.0.36 ansis: 3.3.2 - debug: 4.3.6 + debug: 4.4.0(supports-color@8.1.1) transitivePeerDependencies: - supports-color '@pkgjs/parseargs@0.11.0': optional: true - '@sindresorhus/is@5.6.0': {} + '@pnpm/config.env-replace@1.1.0': {} - '@sinonjs/commons@2.0.0': + '@pnpm/network.ca-file@1.0.2': dependencies: - type-detect: 4.0.8 + graceful-fs: 4.2.10 + + '@pnpm/npm-conf@2.3.1': + dependencies: + '@pnpm/config.env-replace': 1.1.0 + '@pnpm/network.ca-file': 1.0.2 + config-chain: 1.1.13 + + '@sindresorhus/is@5.6.0': {} '@sinonjs/commons@3.0.1': dependencies: type-detect: 4.0.8 - '@sinonjs/fake-timers@11.2.2': + '@sinonjs/fake-timers@13.0.5': dependencies: '@sinonjs/commons': 3.0.1 - '@sinonjs/samsam@8.0.0': + '@sinonjs/samsam@8.0.2': dependencies: - '@sinonjs/commons': 2.0.0 + '@sinonjs/commons': 3.0.1 lodash.get: 4.4.2 - type-detect: 4.0.8 + type-detect: 4.1.0 - '@sinonjs/text-encoding@0.7.2': {} + '@sinonjs/text-encoding@0.7.3': {} - '@smithy/abort-controller@3.1.1': + '@smithy/abort-controller@3.1.8': dependencies: - '@smithy/types': 3.3.0 + '@smithy/types': 3.7.1 tslib: 2.6.3 - '@smithy/chunked-blob-reader-native@3.0.0': + '@smithy/chunked-blob-reader-native@3.0.1': dependencies: '@smithy/util-base64': 3.0.0 tslib: 2.6.3 - '@smithy/chunked-blob-reader@3.0.0': + '@smithy/chunked-blob-reader@4.0.0': dependencies: tslib: 2.6.3 - '@smithy/config-resolver@3.0.5': + '@smithy/config-resolver@3.0.12': dependencies: - '@smithy/node-config-provider': 3.1.4 - '@smithy/types': 3.3.0 + '@smithy/node-config-provider': 3.1.11 + '@smithy/types': 3.7.1 '@smithy/util-config-provider': 3.0.0 - '@smithy/util-middleware': 3.0.3 - tslib: 2.6.3 - - '@smithy/core@2.2.6': - dependencies: - '@smithy/middleware-endpoint': 3.0.5 - '@smithy/middleware-retry': 3.0.9 - '@smithy/middleware-serde': 3.0.3 - '@smithy/protocol-http': 4.0.3 - '@smithy/smithy-client': 3.1.7 - '@smithy/types': 3.3.0 - '@smithy/util-middleware': 3.0.3 - tslib: 2.6.3 - - '@smithy/core@2.3.2': - dependencies: - '@smithy/middleware-endpoint': 3.1.0 - '@smithy/middleware-retry': 3.0.14 - '@smithy/middleware-serde': 3.0.3 - '@smithy/protocol-http': 4.1.0 - '@smithy/smithy-client': 3.1.12 - '@smithy/types': 3.3.0 - '@smithy/util-middleware': 3.0.3 + '@smithy/util-middleware': 3.0.10 tslib: 2.6.3 - '@smithy/credential-provider-imds@3.1.4': + '@smithy/core@2.5.4': dependencies: - '@smithy/node-config-provider': 3.1.4 - '@smithy/property-provider': 3.1.3 - '@smithy/types': 3.3.0 - '@smithy/url-parser': 3.0.3 + '@smithy/middleware-serde': 3.0.10 + '@smithy/protocol-http': 4.1.7 + '@smithy/types': 3.7.1 + '@smithy/util-body-length-browser': 3.0.0 + '@smithy/util-middleware': 3.0.10 + '@smithy/util-stream': 3.3.1 + '@smithy/util-utf8': 3.0.0 tslib: 2.6.3 - '@smithy/credential-provider-imds@3.2.0': + '@smithy/credential-provider-imds@3.2.7': dependencies: - '@smithy/node-config-provider': 3.1.4 - '@smithy/property-provider': 3.1.3 - '@smithy/types': 3.3.0 - '@smithy/url-parser': 3.0.3 + '@smithy/node-config-provider': 3.1.11 + '@smithy/property-provider': 3.1.10 + '@smithy/types': 3.7.1 + '@smithy/url-parser': 3.0.10 tslib: 2.6.3 - '@smithy/eventstream-codec@3.1.2': + '@smithy/eventstream-codec@3.1.9': dependencies: '@aws-crypto/crc32': 5.2.0 - '@smithy/types': 3.3.0 + '@smithy/types': 3.7.1 '@smithy/util-hex-encoding': 3.0.0 tslib: 2.6.3 - '@smithy/eventstream-serde-browser@3.0.4': - dependencies: - '@smithy/eventstream-serde-universal': 3.0.4 - '@smithy/types': 3.3.0 - tslib: 2.6.3 - - '@smithy/eventstream-serde-config-resolver@3.0.3': + '@smithy/eventstream-serde-browser@3.0.13': dependencies: - '@smithy/types': 3.3.0 + '@smithy/eventstream-serde-universal': 3.0.12 + '@smithy/types': 3.7.1 tslib: 2.6.3 - '@smithy/eventstream-serde-node@3.0.4': + '@smithy/eventstream-serde-config-resolver@3.0.10': dependencies: - '@smithy/eventstream-serde-universal': 3.0.4 - '@smithy/types': 3.3.0 + '@smithy/types': 3.7.1 tslib: 2.6.3 - '@smithy/eventstream-serde-universal@3.0.4': + '@smithy/eventstream-serde-node@3.0.12': dependencies: - '@smithy/eventstream-codec': 3.1.2 - '@smithy/types': 3.3.0 + '@smithy/eventstream-serde-universal': 3.0.12 + '@smithy/types': 3.7.1 tslib: 2.6.3 - '@smithy/fetch-http-handler@3.2.1': + '@smithy/eventstream-serde-universal@3.0.12': dependencies: - '@smithy/protocol-http': 4.0.3 - '@smithy/querystring-builder': 3.0.3 - '@smithy/types': 3.3.0 - '@smithy/util-base64': 3.0.0 + '@smithy/eventstream-codec': 3.1.9 + '@smithy/types': 3.7.1 tslib: 2.6.3 - '@smithy/fetch-http-handler@3.2.4': + '@smithy/fetch-http-handler@4.1.1': dependencies: - '@smithy/protocol-http': 4.1.0 - '@smithy/querystring-builder': 3.0.3 - '@smithy/types': 3.3.0 + '@smithy/protocol-http': 4.1.7 + '@smithy/querystring-builder': 3.0.10 + '@smithy/types': 3.7.1 '@smithy/util-base64': 3.0.0 tslib: 2.6.3 - '@smithy/hash-blob-browser@3.1.2': + '@smithy/hash-blob-browser@3.1.9': dependencies: - '@smithy/chunked-blob-reader': 3.0.0 - '@smithy/chunked-blob-reader-native': 3.0.0 - '@smithy/types': 3.3.0 + '@smithy/chunked-blob-reader': 4.0.0 + '@smithy/chunked-blob-reader-native': 3.0.1 + '@smithy/types': 3.7.1 tslib: 2.6.3 - '@smithy/hash-node@3.0.3': + '@smithy/hash-node@3.0.10': dependencies: - '@smithy/types': 3.3.0 + '@smithy/types': 3.7.1 '@smithy/util-buffer-from': 3.0.0 '@smithy/util-utf8': 3.0.0 tslib: 2.6.3 - '@smithy/hash-stream-node@3.1.2': + '@smithy/hash-stream-node@3.1.9': dependencies: - '@smithy/types': 3.3.0 + '@smithy/types': 3.7.1 '@smithy/util-utf8': 3.0.0 tslib: 2.6.3 - '@smithy/invalid-dependency@3.0.3': + '@smithy/invalid-dependency@3.0.10': dependencies: - '@smithy/types': 3.3.0 + '@smithy/types': 3.7.1 tslib: 2.6.3 '@smithy/is-array-buffer@2.2.0': @@ -4625,183 +4513,125 @@ snapshots: dependencies: tslib: 2.6.3 - '@smithy/md5-js@3.0.3': + '@smithy/md5-js@3.0.10': dependencies: - '@smithy/types': 3.3.0 + '@smithy/types': 3.7.1 '@smithy/util-utf8': 3.0.0 tslib: 2.6.3 - '@smithy/middleware-content-length@3.0.3': + '@smithy/middleware-content-length@3.0.12': dependencies: - '@smithy/protocol-http': 4.0.3 - '@smithy/types': 3.3.0 + '@smithy/protocol-http': 4.1.7 + '@smithy/types': 3.7.1 tslib: 2.6.3 - '@smithy/middleware-content-length@3.0.5': + '@smithy/middleware-endpoint@3.2.4': dependencies: - '@smithy/protocol-http': 4.1.0 - '@smithy/types': 3.3.0 + '@smithy/core': 2.5.4 + '@smithy/middleware-serde': 3.0.10 + '@smithy/node-config-provider': 3.1.11 + '@smithy/shared-ini-file-loader': 3.1.11 + '@smithy/types': 3.7.1 + '@smithy/url-parser': 3.0.10 + '@smithy/util-middleware': 3.0.10 tslib: 2.6.3 - '@smithy/middleware-endpoint@3.0.5': + '@smithy/middleware-retry@3.0.28': dependencies: - '@smithy/middleware-serde': 3.0.3 - '@smithy/node-config-provider': 3.1.4 - '@smithy/shared-ini-file-loader': 3.1.4 - '@smithy/types': 3.3.0 - '@smithy/url-parser': 3.0.3 - '@smithy/util-middleware': 3.0.3 - tslib: 2.6.3 - - '@smithy/middleware-endpoint@3.1.0': - dependencies: - '@smithy/middleware-serde': 3.0.3 - '@smithy/node-config-provider': 3.1.4 - '@smithy/shared-ini-file-loader': 3.1.4 - '@smithy/types': 3.3.0 - '@smithy/url-parser': 3.0.3 - '@smithy/util-middleware': 3.0.3 - tslib: 2.6.3 - - '@smithy/middleware-retry@3.0.14': - dependencies: - '@smithy/node-config-provider': 3.1.4 - '@smithy/protocol-http': 4.1.0 - '@smithy/service-error-classification': 3.0.3 - '@smithy/smithy-client': 3.1.12 - '@smithy/types': 3.3.0 - '@smithy/util-middleware': 3.0.3 - '@smithy/util-retry': 3.0.3 - tslib: 2.6.3 - uuid: 9.0.1 - - '@smithy/middleware-retry@3.0.9': - dependencies: - '@smithy/node-config-provider': 3.1.4 - '@smithy/protocol-http': 4.0.3 - '@smithy/service-error-classification': 3.0.3 - '@smithy/smithy-client': 3.1.7 - '@smithy/types': 3.3.0 - '@smithy/util-middleware': 3.0.3 - '@smithy/util-retry': 3.0.3 + '@smithy/node-config-provider': 3.1.11 + '@smithy/protocol-http': 4.1.7 + '@smithy/service-error-classification': 3.0.10 + '@smithy/smithy-client': 3.4.5 + '@smithy/types': 3.7.1 + '@smithy/util-middleware': 3.0.10 + '@smithy/util-retry': 3.0.10 tslib: 2.6.3 uuid: 9.0.1 - '@smithy/middleware-serde@3.0.3': + '@smithy/middleware-serde@3.0.10': dependencies: - '@smithy/types': 3.3.0 + '@smithy/types': 3.7.1 tslib: 2.6.3 - '@smithy/middleware-stack@3.0.3': + '@smithy/middleware-stack@3.0.10': dependencies: - '@smithy/types': 3.3.0 + '@smithy/types': 3.7.1 tslib: 2.6.3 - '@smithy/node-config-provider@3.1.4': + '@smithy/node-config-provider@3.1.11': dependencies: - '@smithy/property-provider': 3.1.3 - '@smithy/shared-ini-file-loader': 3.1.4 - '@smithy/types': 3.3.0 + '@smithy/property-provider': 3.1.10 + '@smithy/shared-ini-file-loader': 3.1.11 + '@smithy/types': 3.7.1 tslib: 2.6.3 - '@smithy/node-http-handler@3.1.2': + '@smithy/node-http-handler@3.3.1': dependencies: - '@smithy/abort-controller': 3.1.1 - '@smithy/protocol-http': 4.0.3 - '@smithy/querystring-builder': 3.0.3 - '@smithy/types': 3.3.0 + '@smithy/abort-controller': 3.1.8 + '@smithy/protocol-http': 4.1.7 + '@smithy/querystring-builder': 3.0.10 + '@smithy/types': 3.7.1 tslib: 2.6.3 - '@smithy/node-http-handler@3.1.4': + '@smithy/property-provider@3.1.10': dependencies: - '@smithy/abort-controller': 3.1.1 - '@smithy/protocol-http': 4.1.0 - '@smithy/querystring-builder': 3.0.3 - '@smithy/types': 3.3.0 + '@smithy/types': 3.7.1 tslib: 2.6.3 - '@smithy/property-provider@3.1.3': + '@smithy/protocol-http@4.1.7': dependencies: - '@smithy/types': 3.3.0 + '@smithy/types': 3.7.1 tslib: 2.6.3 - '@smithy/protocol-http@4.0.3': + '@smithy/querystring-builder@3.0.10': dependencies: - '@smithy/types': 3.3.0 - tslib: 2.6.3 - - '@smithy/protocol-http@4.1.0': - dependencies: - '@smithy/types': 3.3.0 - tslib: 2.6.3 - - '@smithy/querystring-builder@3.0.3': - dependencies: - '@smithy/types': 3.3.0 + '@smithy/types': 3.7.1 '@smithy/util-uri-escape': 3.0.0 tslib: 2.6.3 - '@smithy/querystring-parser@3.0.3': + '@smithy/querystring-parser@3.0.10': dependencies: - '@smithy/types': 3.3.0 + '@smithy/types': 3.7.1 tslib: 2.6.3 - '@smithy/service-error-classification@3.0.3': + '@smithy/service-error-classification@3.0.10': dependencies: - '@smithy/types': 3.3.0 + '@smithy/types': 3.7.1 - '@smithy/shared-ini-file-loader@3.1.4': + '@smithy/shared-ini-file-loader@3.1.11': dependencies: - '@smithy/types': 3.3.0 + '@smithy/types': 3.7.1 tslib: 2.6.3 - '@smithy/signature-v4@3.1.2': + '@smithy/signature-v4@4.2.3': dependencies: '@smithy/is-array-buffer': 3.0.0 - '@smithy/types': 3.3.0 + '@smithy/protocol-http': 4.1.7 + '@smithy/types': 3.7.1 '@smithy/util-hex-encoding': 3.0.0 - '@smithy/util-middleware': 3.0.3 + '@smithy/util-middleware': 3.0.10 '@smithy/util-uri-escape': 3.0.0 '@smithy/util-utf8': 3.0.0 tslib: 2.6.3 - '@smithy/signature-v4@4.1.0': + '@smithy/smithy-client@3.4.5': dependencies: - '@smithy/is-array-buffer': 3.0.0 - '@smithy/protocol-http': 4.1.0 - '@smithy/types': 3.3.0 - '@smithy/util-hex-encoding': 3.0.0 - '@smithy/util-middleware': 3.0.3 - '@smithy/util-uri-escape': 3.0.0 - '@smithy/util-utf8': 3.0.0 + '@smithy/core': 2.5.4 + '@smithy/middleware-endpoint': 3.2.4 + '@smithy/middleware-stack': 3.0.10 + '@smithy/protocol-http': 4.1.7 + '@smithy/types': 3.7.1 + '@smithy/util-stream': 3.3.1 tslib: 2.6.3 - '@smithy/smithy-client@3.1.12': + '@smithy/types@3.7.1': dependencies: - '@smithy/middleware-endpoint': 3.1.0 - '@smithy/middleware-stack': 3.0.3 - '@smithy/protocol-http': 4.1.0 - '@smithy/types': 3.3.0 - '@smithy/util-stream': 3.1.3 tslib: 2.6.3 - '@smithy/smithy-client@3.1.7': + '@smithy/url-parser@3.0.10': dependencies: - '@smithy/middleware-endpoint': 3.0.5 - '@smithy/middleware-stack': 3.0.3 - '@smithy/protocol-http': 4.0.3 - '@smithy/types': 3.3.0 - '@smithy/util-stream': 3.0.6 - tslib: 2.6.3 - - '@smithy/types@3.3.0': - dependencies: - tslib: 2.6.3 - - '@smithy/url-parser@3.0.3': - dependencies: - '@smithy/querystring-parser': 3.0.3 - '@smithy/types': 3.3.0 + '@smithy/querystring-parser': 3.0.10 + '@smithy/types': 3.7.1 tslib: 2.6.3 '@smithy/util-base64@3.0.0': @@ -4832,79 +4662,50 @@ snapshots: dependencies: tslib: 2.6.3 - '@smithy/util-defaults-mode-browser@3.0.14': + '@smithy/util-defaults-mode-browser@3.0.28': dependencies: - '@smithy/property-provider': 3.1.3 - '@smithy/smithy-client': 3.1.12 - '@smithy/types': 3.3.0 + '@smithy/property-provider': 3.1.10 + '@smithy/smithy-client': 3.4.5 + '@smithy/types': 3.7.1 bowser: 2.11.0 tslib: 2.6.3 - '@smithy/util-defaults-mode-browser@3.0.9': + '@smithy/util-defaults-mode-node@3.0.28': dependencies: - '@smithy/property-provider': 3.1.3 - '@smithy/smithy-client': 3.1.7 - '@smithy/types': 3.3.0 - bowser: 2.11.0 + '@smithy/config-resolver': 3.0.12 + '@smithy/credential-provider-imds': 3.2.7 + '@smithy/node-config-provider': 3.1.11 + '@smithy/property-provider': 3.1.10 + '@smithy/smithy-client': 3.4.5 + '@smithy/types': 3.7.1 tslib: 2.6.3 - '@smithy/util-defaults-mode-node@3.0.14': + '@smithy/util-endpoints@2.1.6': dependencies: - '@smithy/config-resolver': 3.0.5 - '@smithy/credential-provider-imds': 3.2.0 - '@smithy/node-config-provider': 3.1.4 - '@smithy/property-provider': 3.1.3 - '@smithy/smithy-client': 3.1.12 - '@smithy/types': 3.3.0 - tslib: 2.6.3 - - '@smithy/util-defaults-mode-node@3.0.9': - dependencies: - '@smithy/config-resolver': 3.0.5 - '@smithy/credential-provider-imds': 3.1.4 - '@smithy/node-config-provider': 3.1.4 - '@smithy/property-provider': 3.1.3 - '@smithy/smithy-client': 3.1.7 - '@smithy/types': 3.3.0 - tslib: 2.6.3 - - '@smithy/util-endpoints@2.0.5': - dependencies: - '@smithy/node-config-provider': 3.1.4 - '@smithy/types': 3.3.0 + '@smithy/node-config-provider': 3.1.11 + '@smithy/types': 3.7.1 tslib: 2.6.3 '@smithy/util-hex-encoding@3.0.0': dependencies: tslib: 2.6.3 - '@smithy/util-middleware@3.0.3': + '@smithy/util-middleware@3.0.10': dependencies: - '@smithy/types': 3.3.0 + '@smithy/types': 3.7.1 tslib: 2.6.3 - '@smithy/util-retry@3.0.3': + '@smithy/util-retry@3.0.10': dependencies: - '@smithy/service-error-classification': 3.0.3 - '@smithy/types': 3.3.0 - tslib: 2.6.3 - - '@smithy/util-stream@3.0.6': - dependencies: - '@smithy/fetch-http-handler': 3.2.1 - '@smithy/node-http-handler': 3.1.2 - '@smithy/types': 3.3.0 - '@smithy/util-base64': 3.0.0 - '@smithy/util-buffer-from': 3.0.0 - '@smithy/util-hex-encoding': 3.0.0 - '@smithy/util-utf8': 3.0.0 + '@smithy/service-error-classification': 3.0.10 + '@smithy/types': 3.7.1 tslib: 2.6.3 - '@smithy/util-stream@3.1.3': + '@smithy/util-stream@3.3.1': dependencies: - '@smithy/fetch-http-handler': 3.2.4 - '@smithy/node-http-handler': 3.1.4 - '@smithy/types': 3.3.0 + '@smithy/fetch-http-handler': 4.1.1 + '@smithy/node-http-handler': 3.3.1 + '@smithy/types': 3.7.1 '@smithy/util-base64': 3.0.0 '@smithy/util-buffer-from': 3.0.0 '@smithy/util-hex-encoding': 3.0.0 @@ -4925,10 +4726,10 @@ snapshots: '@smithy/util-buffer-from': 3.0.0 tslib: 2.6.3 - '@smithy/util-waiter@3.1.2': + '@smithy/util-waiter@3.1.9': dependencies: - '@smithy/abort-controller': 3.1.1 - '@smithy/types': 3.3.0 + '@smithy/abort-controller': 3.1.8 + '@smithy/types': 3.7.1 tslib: 2.6.3 '@szmarczak/http-timer@5.0.1': @@ -4959,6 +4760,11 @@ snapshots: '@types/estree@1.0.5': {} + '@types/fs-extra@11.0.4': + dependencies: + '@types/jsonfile': 6.1.4 + '@types/node': 22.1.0 + '@types/http-cache-semantics@4.0.4': {} '@types/inquirer@9.0.7': @@ -4966,6 +4772,10 @@ snapshots: '@types/through': 0.0.33 rxjs: 7.8.1 + '@types/jsonfile@6.1.4': + dependencies: + '@types/node': 22.1.0 + '@types/mocha@10.0.7': {} '@types/mock-fs@4.13.4': @@ -4985,6 +4795,10 @@ snapshots: dependencies: undici-types: 6.13.0 + '@types/node@22.10.1': + dependencies: + undici-types: 6.20.0 + '@types/sinon@17.0.3': dependencies: '@types/sinonjs__fake-timers': 8.1.5 @@ -5029,7 +4843,7 @@ snapshots: '@typescript-eslint/types': 8.0.1 '@typescript-eslint/typescript-estree': 8.0.1(typescript@5.5.4) '@typescript-eslint/visitor-keys': 8.0.1 - debug: 4.3.5(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) eslint: 9.8.0 optionalDependencies: typescript: 5.5.4 @@ -5045,7 +4859,7 @@ snapshots: dependencies: '@typescript-eslint/typescript-estree': 8.0.1(typescript@5.5.4) '@typescript-eslint/utils': 8.0.1(eslint@9.8.0)(typescript@5.5.4) - debug: 4.3.5(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) ts-api-utils: 1.3.0(typescript@5.5.4) optionalDependencies: typescript: 5.5.4 @@ -5059,11 +4873,11 @@ snapshots: dependencies: '@typescript-eslint/types': 8.0.1 '@typescript-eslint/visitor-keys': 8.0.1 - debug: 4.3.5(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.5 - semver: 7.6.2 + semver: 7.6.3 ts-api-utils: 1.3.0(typescript@5.5.4) optionalDependencies: typescript: 5.5.4 @@ -5098,7 +4912,7 @@ snapshots: agent-base@7.1.1: dependencies: - debug: 4.3.5(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -5134,8 +4948,6 @@ snapshots: ansi-styles@6.2.1: {} - ansis@3.3.1: {} - ansis@3.3.2: {} anymatch@3.1.3: @@ -5309,6 +5121,8 @@ snapshots: chardet@0.7.0: {} + charenc@0.0.2: {} + check-error@2.1.1: {} chokidar@3.6.0: @@ -5384,6 +5198,11 @@ snapshots: concat-map@0.0.1: {} + config-chain@1.1.13: + dependencies: + ini: 1.3.8 + proto-list: 1.2.4 + constant-case@3.0.4: dependencies: no-case: 3.0.4 @@ -5406,21 +5225,25 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 + crypt@0.0.2: {} + date-fns@2.30.0: dependencies: '@babel/runtime': 7.24.7 date-fns@3.6.0: {} - debug@4.3.5(supports-color@8.1.1): + debug@4.3.7(supports-color@8.1.1): dependencies: - ms: 2.1.2 + ms: 2.1.3 optionalDependencies: supports-color: 8.1.1 - debug@4.3.6: + debug@4.4.0(supports-color@8.1.1): dependencies: - ms: 2.1.2 + ms: 2.1.3 + optionalDependencies: + supports-color: 8.1.1 decamelize@1.2.0: {} @@ -5488,6 +5311,8 @@ snapshots: diff@5.2.0: {} + diff@7.0.0: {} + dir-glob@3.0.1: dependencies: path-type: 4.0.0 @@ -5580,7 +5405,7 @@ snapshots: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 - debug: 4.3.5(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) escape-string-regexp: 4.0.0 eslint-scope: 8.0.2 eslint-visitor-keys: 4.0.0 @@ -5683,6 +5508,10 @@ snapshots: dependencies: pend: 1.2.0 + fdir@6.4.2(picomatch@4.0.2): + optionalDependencies: + picomatch: 4.0.2 + fecha@4.2.3: {} file-entry-cache@8.0.0: @@ -5758,6 +5587,12 @@ snapshots: fs-constants@1.0.0: {} + fs-extra@11.2.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + fs-extra@8.1.0: dependencies: graceful-fs: 4.2.11 @@ -5862,14 +5697,6 @@ snapshots: merge2: 1.4.1 slash: 3.0.0 - globby@13.2.2: - dependencies: - dir-glob: 3.0.1 - fast-glob: 3.3.2 - ignore: 5.3.1 - merge2: 1.4.1 - slash: 4.0.0 - got@13.0.0: dependencies: '@sindresorhus/is': 5.6.0 @@ -5884,6 +5711,8 @@ snapshots: p-cancelable: 3.0.0 responselike: 3.0.0 + graceful-fs@4.2.10: {} + graceful-fs@4.2.11: {} graphemer@1.4.0: {} @@ -5919,7 +5748,7 @@ snapshots: http-call@5.3.0: dependencies: content-type: 1.0.5 - debug: 4.3.5(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) is-retry-allowed: 1.2.0 is-stream: 2.0.1 parse-json: 4.0.0 @@ -5935,7 +5764,7 @@ snapshots: https-proxy-agent@7.0.5: dependencies: agent-base: 7.1.1 - debug: 4.3.5(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -5965,10 +5794,12 @@ snapshots: inherits@2.0.4: {} + ini@1.3.8: {} + inquirer@10.1.8: dependencies: '@inquirer/prompts': 5.3.8 - '@inquirer/type': 1.5.2 + '@inquirer/type': 1.5.5 '@types/mute-stream': 0.0.4 ansi-escapes: 4.3.2 mute-stream: 1.0.0 @@ -5985,6 +5816,8 @@ snapshots: dependencies: binary-extensions: 2.3.0 + is-buffer@1.1.6: {} + is-core-module@2.14.0: dependencies: hasown: 2.0.2 @@ -6041,7 +5874,7 @@ snapshots: '@babel/parser': 7.24.7 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 - semver: 7.6.2 + semver: 7.6.3 transitivePeerDependencies: - supports-color @@ -6062,7 +5895,7 @@ snapshots: istanbul-lib-source-maps@4.0.1: dependencies: - debug: 4.3.5(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) istanbul-lib-coverage: 3.2.2 source-map: 0.6.1 transitivePeerDependencies: @@ -6119,6 +5952,12 @@ snapshots: optionalDependencies: graceful-fs: 4.2.11 + jsonfile@6.1.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + just-extend@6.2.0: {} keyv@4.5.4: @@ -6132,7 +5971,7 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 - lilconfig@3.1.2: {} + lilconfig@3.1.3: {} locate-path@5.0.0: dependencies: @@ -6194,10 +6033,16 @@ snapshots: make-dir@4.0.0: dependencies: - semver: 7.6.2 + semver: 7.6.3 make-error@1.3.6: {} + md5@2.3.0: + dependencies: + charenc: 0.0.2 + crypt: 0.0.2 + is-buffer: 1.1.6 + merge-stream@2.0.0: {} merge2@1.4.1: {} @@ -6264,12 +6109,25 @@ snapshots: mkdirp@1.0.4: {} + mkdirp@3.0.1: {} + + mocha-junit-reporter@2.2.1(mocha@10.7.3): + dependencies: + debug: 4.4.0(supports-color@8.1.1) + md5: 2.3.0 + mkdirp: 3.0.1 + mocha: 10.7.3 + strip-ansi: 6.0.1 + xml: 1.0.1 + transitivePeerDependencies: + - supports-color + mocha@10.7.3: dependencies: ansi-colors: 4.1.3 browser-stdout: 1.3.1 chokidar: 3.6.0 - debug: 4.3.5(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) diff: 5.2.0 escape-string-regexp: 4.0.0 find-up: 5.0.0 @@ -6291,21 +6149,21 @@ snapshots: moment@2.29.4: {} - ms@2.1.2: {} - ms@2.1.3: {} mute-stream@1.0.0: {} + mute-stream@2.0.0: {} + natural-compare@1.4.0: {} - nise@6.0.0: + nise@6.1.1: dependencies: '@sinonjs/commons': 3.0.1 - '@sinonjs/fake-timers': 11.2.2 - '@sinonjs/text-encoding': 0.7.2 + '@sinonjs/fake-timers': 13.0.5 + '@sinonjs/text-encoding': 0.7.3 just-extend: 6.2.0 - path-to-regexp: 6.2.2 + path-to-regexp: 8.2.0 no-case@3.0.4: dependencies: @@ -6324,7 +6182,7 @@ snapshots: node-fetch@2.7.0: dependencies: - whatwg-url: 5.0.0 + whatwg-url: 14.0.0 node-preload@0.2.1: dependencies: @@ -6396,21 +6254,21 @@ snapshots: '@types/codemirror': 5.60.8 moment: 2.29.4 - oclif@4.14.15: + oclif@4.16.0(@types/node@22.1.0): dependencies: - '@aws-sdk/client-cloudfront': 3.624.0 - '@aws-sdk/client-s3': 3.614.0 - '@inquirer/confirm': 3.1.16 + '@aws-sdk/client-cloudfront': 3.699.0 + '@aws-sdk/client-s3': 3.701.0 + '@inquirer/confirm': 3.1.22 '@inquirer/input': 2.2.9 - '@inquirer/select': 2.4.1 - '@oclif/core': 4.0.17 - '@oclif/plugin-help': 6.2.8 - '@oclif/plugin-not-found': 3.2.15 - '@oclif/plugin-warn-if-update-available': 3.1.7 + '@inquirer/select': 2.5.0 + '@oclif/core': 4.0.36 + '@oclif/plugin-help': 6.2.19 + '@oclif/plugin-not-found': 3.2.29(@types/node@22.1.0) + '@oclif/plugin-warn-if-update-available': 3.1.23 async-retry: 1.3.3 chalk: 4.1.2 change-case: 4.1.2 - debug: 4.3.5(supports-color@8.1.1) + debug: 4.3.7(supports-color@8.1.1) ejs: 3.1.10 find-yarn-workspace-root: 2.0.0 fs-extra: 8.1.0 @@ -6419,10 +6277,11 @@ snapshots: lodash: 4.17.21 normalize-package-data: 6.0.2 semver: 7.6.3 - sort-package-json: 2.10.0 + sort-package-json: 2.12.0 tiny-jsonc: 1.0.1 validate-npm-package-name: 5.0.1 transitivePeerDependencies: + - '@types/node' - aws-crt - supports-color @@ -6528,7 +6387,7 @@ snapshots: lru-cache: 11.0.0 minipass: 7.1.2 - path-to-regexp@6.2.2: {} + path-to-regexp@8.2.0: {} path-type@4.0.0: {} @@ -6540,6 +6399,8 @@ snapshots: picomatch@2.3.1: {} + picomatch@4.0.2: {} + pify@2.3.0: {} pify@3.0.0: {} @@ -6564,6 +6425,8 @@ snapshots: dependencies: fromentries: 1.3.2 + proto-list@1.2.4: {} + punycode@2.3.1: {} queue-microtask@1.2.3: {} @@ -6600,6 +6463,10 @@ snapshots: regenerator-runtime@0.14.1: {} + registry-auth-token@5.0.3: + dependencies: + '@pnpm/npm-conf': 2.3.1 + release-zalgo@1.0.0: dependencies: es6-error: 4.1.1 @@ -6658,8 +6525,6 @@ snapshots: semver@6.3.1: {} - semver@7.6.2: {} - semver@7.6.3: {} sentence-case@3.0.4: @@ -6699,19 +6564,17 @@ snapshots: dependencies: is-arrayish: 0.3.2 - sinon@18.0.0: + sinon@19.0.2: dependencies: '@sinonjs/commons': 3.0.1 - '@sinonjs/fake-timers': 11.2.2 - '@sinonjs/samsam': 8.0.0 - diff: 5.2.0 - nise: 6.0.0 + '@sinonjs/fake-timers': 13.0.5 + '@sinonjs/samsam': 8.0.2 + diff: 7.0.0 + nise: 6.1.1 supports-color: 7.2.0 slash@3.0.0: {} - slash@4.0.0: {} - snake-case@3.0.4: dependencies: dot-case: 3.0.4 @@ -6719,16 +6582,16 @@ snapshots: sort-object-keys@1.1.3: {} - sort-package-json@2.10.0: + sort-package-json@2.12.0: dependencies: detect-indent: 7.0.1 detect-newline: 4.0.1 get-stdin: 9.0.0 git-hooks-list: 3.1.0 - globby: 13.2.2 is-plain-obj: 4.1.0 semver: 7.6.3 sort-object-keys: 1.1.3 + tinyglobby: 0.2.10 source-map@0.6.1: {} @@ -6852,6 +6715,11 @@ snapshots: tiny-jsonc@1.0.1: {} + tinyglobby@0.2.10: + dependencies: + fdir: 6.4.2(picomatch@4.0.2) + picomatch: 4.0.2 + tmp@0.0.33: dependencies: os-tmpdir: 1.0.2 @@ -6864,7 +6732,9 @@ snapshots: dependencies: is-number: 7.0.0 - tr46@0.0.3: {} + tr46@5.0.0: + dependencies: + punycode: 2.3.1 triple-beam@1.4.1: {} @@ -6909,6 +6779,8 @@ snapshots: type-detect@4.0.8: {} + type-detect@4.1.0: {} + type-fest@0.21.3: {} type-fest@0.8.1: {} @@ -6937,6 +6809,8 @@ snapshots: undici-types@6.13.0: {} + undici-types@6.20.0: {} + unique-filename@3.0.0: dependencies: unique-slug: 4.0.0 @@ -6947,6 +6821,8 @@ snapshots: universalify@0.1.2: {} + universalify@2.0.1: {} + update-browserslist-db@1.1.0(browserslist@4.23.1): dependencies: browserslist: 4.23.1 @@ -6982,12 +6858,12 @@ snapshots: w3c-keyname@2.2.8: {} - webidl-conversions@3.0.1: {} + webidl-conversions@7.0.0: {} - whatwg-url@5.0.0: + whatwg-url@14.0.0: dependencies: - tr46: 0.0.3 - webidl-conversions: 3.0.1 + tr46: 5.0.0 + webidl-conversions: 7.0.0 which-module@2.0.1: {} @@ -7052,6 +6928,8 @@ snapshots: signal-exit: 3.0.7 typedarray-to-buffer: 3.1.5 + xml@1.0.1: {} + xtend@4.0.2: {} y18n@4.0.3: {} diff --git a/sonar-project.properties b/sonar-project.properties index cee870e..d969c4f 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -1,7 +1,7 @@ sonar.projectKey=msudgh_ovm sonar.organization=msudgh sonar.javascript.lcov.reportPaths=coverage/lcov.info -sonar.sources=src +sonar.sources=. sonar.exclusions=**/node_modules/**,**/coverage/**,**/dist/** sonar.tests=. sonar.test.inclusions=**/*.test.ts diff --git a/src/commands.d.ts b/src/commands.d.ts deleted file mode 100644 index b6a769a..0000000 --- a/src/commands.d.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { Vault } from 'obsidian-utils' -import { Config } from './providers/config' - -export interface PruneFlags { - path: string -} - -export interface PrunePluginVaultOpts { - vault: Vault - config: Config -} - -export interface InstallFlags { - path: string - enable: boolean -} - -export interface InstallArgs { - pluginId?: string -} - -export interface InstallPluginVaultOpts { - vault: Vault - config: Config -} - -export interface UninstallArgs { - pluginId?: string -} - -export interface UninstallFlags { - path: string -} - -export interface UninstallPluginVaultOpts { - vault: Vault - config: Config -} - -export type CommandsExecutedOnVaults = Record< - string, - { - success: null | boolean - duration: string - error: null | Error | string - } -> diff --git a/src/commands/config/init.test.ts b/src/commands/config/init.test.ts deleted file mode 100644 index b32b391..0000000 --- a/src/commands/config/init.test.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { expect } from 'chai' -import { existsSync } from 'fs' -import { destroyConfigMockFile, getTmpConfigFilePath, runCommand } from '../../utils/testing' - -describe('Command: config init', () => { - beforeEach(async () => { - const tmpConfigFilePath = getTmpConfigFilePath() - if (tmpConfigFilePath && existsSync(tmpConfigFilePath)) { - await destroyConfigMockFile(tmpConfigFilePath.normalize('NFC')) - } - }) - - it('should create a config file', async () => { - const tmpConfigFilePath = getTmpConfigFilePath() - const result = await runCommand(`config init -c ${tmpConfigFilePath}`) - const normalizedOutput = result?.stdout?.trim().replace(/\\\\/g, '\\') - expect(normalizedOutput).to.equal( - `info: Config file created {"path":"${tmpConfigFilePath.replace(/\\\\/g, '\\')}"}`, - ) - await destroyConfigMockFile(tmpConfigFilePath.normalize('NFC')) - }) -}) diff --git a/src/commands/config/init.ts b/src/commands/config/init.ts index 6ee9272..91f9b45 100644 --- a/src/commands/config/init.ts +++ b/src/commands/config/init.ts @@ -1,10 +1,16 @@ import { flush } from '@oclif/core' import { ArgInput } from '@oclif/core/lib/parser' -import FactoryCommand, { - CommonFlags, +import { FactoryCommand } from '../../providers/command' +import { + Config, + createDefaultConfig, + safeLoadConfig, +} from '../../services/config' +import { FactoryFlags, -} from '../../providers/command' -import { createDefaultConfig, safeLoadConfig } from '../../providers/config' + InitCommandCallback, + InitFlags, +} from '../../types/commands' /** * Init command configure an ovm.json config file in user's home dir. @@ -25,46 +31,47 @@ export default class Init extends FactoryCommand { public async run() { try { const { args, flags } = await this.parse(Init) - await this.action(args, this.flagsInterceptor(flags)) + return action(args, this.flagsInterceptor(flags)) } catch (error) { this.handleError(error) } finally { flush() } } +} - /** - * Main action method for the command. - * @param {ArgInput} args - The arguments passed to the command. - * @param {FactoryFlags} flags - The flags passed to the command. - * @returns {Promise} - */ - private async action( - args: ArgInput, - flags: FactoryFlags, - ): Promise { - try { - const { data: config, error } = await safeLoadConfig(flags.config) - - if (config) { - throw new Error('File already exists!') - } +/** + * Main action function for the Init command. + * @param {ArgInput} args - The arguments passed to the command. + * @param {FactoryFlags} flags - The flags passed to the command. + * @param {InitCommandCallback} callback - Error handling function. + * @returns {Promise} + */ +export const action = async ( + args: ArgInput, + flags: FactoryFlags, + callback?: InitCommandCallback, +): Promise => { + const { config: configPath } = flags + const { data: config, error } = await safeLoadConfig(configPath) - if (error) { - throw error - } - } catch (error) { - const typedError = error as Error + if (error && error.message === 'Config file not found') { + const defaultConfig = createDefaultConfig(configPath) - if (typedError && typedError.message === 'Config file not found') { - try { - await createDefaultConfig(flags.config) - } catch (error) { - this.handleError(error) - } - } else { - this.handleError(typedError) - } + if (callback) { + callback({ + success: true, + }) + } + return defaultConfig + } else if (error) { + if (callback) { + callback({ + success: false, + error, + }) } } + + return config } diff --git a/src/commands/plugins/install.ts b/src/commands/plugins/install.ts index 96771a7..cada097 100644 --- a/src/commands/plugins/install.ts +++ b/src/commands/plugins/install.ts @@ -1,27 +1,11 @@ -import { Args, Flags, flush, handle } from '@oclif/core' -import { eachSeries } from 'async' -import { - installPluginFromGithub, - isPluginInstalled, - Vault, -} from 'obsidian-utils' -import { InstallArgs, InstallFlags } from '../../commands' -import FactoryCommand, { FactoryFlags } from '../../providers/command' -import { Config, safeLoadConfig, writeConfig } from '../../providers/config' -import { - findPluginInRegistry, - handleExceedRateLimitError, -} from '../../providers/github' -import { modifyCommunityPlugins } from '../../providers/plugins' -import { vaultsSelector } from '../../providers/vaults' -import { VAULTS_PATH_FLAG_DESCRIPTION } from '../../utils/constants' -import { PluginNotFoundInRegistryError } from '../../utils/errors' -import { logger } from '../../utils/logger' +import { Args, Flags, flush } from '@oclif/core' +import { FactoryCommandWithVaults } from '../../providers/command' +import { action } from '../../services/install' /** * Install command installs specified plugins in vaults. */ -export default class Install extends FactoryCommand { +export default class Install extends FactoryCommandWithVaults { static readonly aliases = ['pi', 'plugins install'] static override readonly description = `Install plugin(s) in specified vaults.` static override readonly examples = [ @@ -31,17 +15,12 @@ export default class Install extends FactoryCommand { '<%= config.bin %> <%= command.id %> id', ] static override readonly flags = { - path: Flags.string({ - char: 'p', - description: VAULTS_PATH_FLAG_DESCRIPTION, - default: '', - }), enable: Flags.boolean({ char: 'e', description: 'Enable all chosen plugins', default: true, }), - ...this.commonFlags, + ...this.commonFlagsWithPath, } static override readonly args = { pluginId: Args.string({ @@ -53,147 +32,20 @@ export default class Install extends FactoryCommand { /** * Executes the command. * Parses the arguments and flags, and calls the action method. + * Loads vaults, selects vaults, and install specified plugins. * Handles errors and ensures flushing of logs. + * @returns {Promise} + * @throws {Error} - Throws an error if the command fails. */ - public async run() { + public async run(): Promise { try { const { args, flags } = await this.parse(Install) - await this.action(args, this.flagsInterceptor(flags)) + return action(args, this.flagsInterceptor(flags)) } catch (error) { this.handleError(error) + throw error } finally { flush() } } - - /** - * Main action method for the command. - * Loads vaults, selects vaults, and install specified plugins. - * @param {InstallArgs} args - The arguments passed to the command. - * @param {FactoryFlags} flags - The flags passed to the command. - * @returns {Promise} - */ - private async action( - args: InstallArgs, - flags: FactoryFlags, - ): Promise { - const { path, enable } = flags - const { - success: loadConfigSuccess, - data: config, - error: loadConfigError, - } = await safeLoadConfig(flags.config) - - if (!loadConfigSuccess) { - logger.error('Failed to load config', { error: loadConfigError }) - process.exit(1) - } - - const vaults = await this.loadVaults(path) - const selectedVaults = await vaultsSelector(vaults) - - // Check if pluginId is provided and install only that plugin - const { pluginId } = args - if (pluginId) { - await this.installPluginInVaults(selectedVaults, config, flags, pluginId) - } else { - await this.installPluginsInVaults(selectedVaults, config, flags, enable) - } - } - - private async installPluginsInVaults( - vaults: Vault[], - config: Config, - flags: FactoryFlags, - specific = false, - ) { - const installVaultIterator = async (vault: Vault) => { - logger.debug(`Install plugins for vault`, { vault }) - const installedPlugins = [] - const failedPlugins = [] - - for (const stagePlugin of config.plugins) { - const childLogger = logger.child({ plugin: stagePlugin, vault }) - - const pluginInRegistry = await findPluginInRegistry(stagePlugin.id) - if (!pluginInRegistry) { - throw new PluginNotFoundInRegistryError(stagePlugin.id) - } - - if (await isPluginInstalled(pluginInRegistry.id, vault.path)) { - childLogger.info(`Plugin already installed`) - continue - } - - stagePlugin.version = stagePlugin.version ?? 'latest' - - try { - await installPluginFromGithub( - pluginInRegistry.repo, - stagePlugin.version, - vault.path, - ) - installedPlugins.push({ - repo: pluginInRegistry.repo, - version: stagePlugin.version, - }) - - if (flags.enable) { - // Enable the plugin - await modifyCommunityPlugins(stagePlugin, vault.path, 'enable') - } - - if (specific) { - // Add the plugin to the config - const newPlugins = new Set([...config.plugins]) - const updatedConfig = { ...config, plugins: [...newPlugins] } - await writeConfig(updatedConfig, flags.config) - } - - childLogger.info(`Installed plugin`) - } catch (error) { - failedPlugins.push({ - repo: pluginInRegistry.repo, - version: stagePlugin.version, - }) - handleExceedRateLimitError(error) - childLogger.error(`Failed to install plugin`, { error }) - } - } - - if (installedPlugins.length) { - logger.info(`Installed ${installedPlugins.length} plugins`, { - vault, - }) - } - - return { installedPlugins, failedPlugins } - } - - eachSeries(vaults, installVaultIterator, (error) => { - if (error) { - logger.debug('Error installing plugins', { error }) - handle(error) - } - }) - } - - private async installPluginInVaults( - vaults: Vault[], - config: Config, - flags: FactoryFlags, - pluginId: string, - ) { - const pluginInRegistry = await findPluginInRegistry(pluginId) - if (!pluginInRegistry) { - throw new PluginNotFoundInRegistryError(pluginId) - } - - await this.installPluginsInVaults( - vaults, - { ...config, plugins: [{ id: pluginId }] }, - flags, - true, - ) - } } diff --git a/src/commands/plugins/prune.ts b/src/commands/plugins/prune.ts index 21b89b8..c7a089c 100644 --- a/src/commands/plugins/prune.ts +++ b/src/commands/plugins/prune.ts @@ -1,18 +1,11 @@ -import { Flags, flush, handle } from '@oclif/core' -import { ArgInput } from '@oclif/core/lib/parser' -import { eachSeries } from 'async' -import { PruneFlags, PrunePluginVaultOpts } from '../../commands' -import FactoryCommand, { FactoryFlags } from '../../providers/command' -import { safeLoadConfig } from '../../providers/config' -import { listInstalledPlugins, removePluginDir } from '../../providers/plugins' -import { vaultsSelector } from '../../providers/vaults' -import { VAULTS_PATH_FLAG_DESCRIPTION } from '../../utils/constants' -import { logger } from '../../utils/logger' +import { flush } from '@oclif/core' +import { FactoryCommandWithVaults } from '../../providers/command' +import { action } from '../../services/prune' /** * Prune command list and remove plugins that aren't referred in config file. */ -export default class Prune extends FactoryCommand { +export default class Prune extends FactoryCommandWithVaults { static readonly aliases = ['pp', 'plugins prune'] static override readonly description = `Prune existing plugin(s) from vaults that are unspecified in the config file.` static override readonly examples = [ @@ -21,12 +14,7 @@ export default class Prune extends FactoryCommand { '<%= config.bin %> <%= command.id %> --path=/path/to/vaults/**/.obsidian', ] static override readonly flags = { - path: Flags.string({ - char: 'p', - description: VAULTS_PATH_FLAG_DESCRIPTION, - default: '', - }), - ...this.commonFlags, + ...this.commonFlagsWithPath, } /** @@ -37,62 +25,11 @@ export default class Prune extends FactoryCommand { public async run() { try { const { args, flags } = await this.parse(Prune) - await this.action(args, this.flagsInterceptor(flags)) + await action(args, this.flagsInterceptor(flags)) } catch (error) { this.handleError(error) } finally { flush() } } - - /** - * Main action method for the command. - * Loads vaults, selects vaults, loads configuration, and prunes unused plugins. - * @param {ArgInput} args - The arguments passed to the command. - * @param {CustomFlags} flags - The flags passed to the command. - * @returns {Promise} - */ - private async action( - args: ArgInput, - flags: FactoryFlags, - ): Promise { - const { path } = flags - const { - success: loadConfigSuccess, - data: config, - error: loadConfigError, - } = await safeLoadConfig(flags.config) - - if (!loadConfigSuccess) { - logger.error('Failed to load config', { error: loadConfigError }) - process.exit(1) - } - - const vaults = await this.loadVaults(path) - const selectedVaults = await vaultsSelector(vaults) - const vaultsWithConfig = selectedVaults.map((vault) => ({ vault, config })) - const prunePluginsIterator = async (opts: PrunePluginVaultOpts) => { - const { vault, config } = opts - const childLogger = logger.child({ vault }) - const installedPlugins = await listInstalledPlugins(vault.path) - const referencedPlugins = config.plugins.map(({ id }) => id) - const toBePruned = installedPlugins.filter( - ({ id }) => !referencedPlugins.includes(id), - ) - - for (const plugin of toBePruned) { - childLogger.debug(`Pruning plugin`, { plugin }) - await removePluginDir(plugin.id, vault.path) - } - - childLogger.info(`Pruned ${toBePruned.length} plugins`) - } - - eachSeries(vaultsWithConfig, prunePluginsIterator, (error) => { - if (error) { - logger.debug('Error pruning plugins', { error }) - handle(error) - } - }) - } } diff --git a/src/commands/plugins/uninstall.ts b/src/commands/plugins/uninstall.ts index 14d36e4..bc76726 100644 --- a/src/commands/plugins/uninstall.ts +++ b/src/commands/plugins/uninstall.ts @@ -1,18 +1,21 @@ -import { Args, Flags, flush, handle } from '@oclif/core' +import { Args, flush, handle } from '@oclif/core' import { eachSeries } from 'async' import { isPluginInstalled, Vault } from 'obsidian-utils' -import { UninstallArgs, UninstallFlags } from '../../commands' -import FactoryCommand, { FactoryFlags } from '../../providers/command' -import { Plugin, safeLoadConfig } from '../../providers/config' +import { FactoryCommandWithVaults } from '../../providers/command' import { pluginsSelector, removePluginDir } from '../../providers/plugins' -import { vaultsSelector } from '../../providers/vaults' -import { VAULTS_PATH_FLAG_DESCRIPTION } from '../../utils/constants' +import { loadVaults, vaultsSelector } from '../../providers/vaults' +import { Plugin, safeLoadConfig } from '../../services/config' +import { + FactoryFlagsWithVaults, + UninstallArgs, + UninstallFlags, +} from '../../types/commands' import { logger } from '../../utils/logger' /** * Uninstall command removes specified plugins from vaults. */ -export default class Uninstall extends FactoryCommand { +export default class Uninstall extends FactoryCommandWithVaults { static readonly aliases = ['pu', 'plugins uninstall'] static override readonly description = `Uninstall plugin(s) from vaults.` static override readonly examples = [ @@ -22,12 +25,7 @@ export default class Uninstall extends FactoryCommand { '<%= config.bin %> <%= command.id %> id', ] static override readonly flags = { - path: Flags.string({ - char: 'p', - description: VAULTS_PATH_FLAG_DESCRIPTION, - default: '', - }), - ...this.commonFlags, + ...this.commonFlagsWithPath, } static override readonly args = { pluginId: Args.string({ @@ -56,12 +54,12 @@ export default class Uninstall extends FactoryCommand { * Main action method for the command. * Loads vaults, selects vaults, and uninstall specified plugins. * @param {UninstallArgs} args - The arguments passed to the command. - * @param {FactoryFlags} flags - The flags passed to the command. + * @param {FactoryFlagsWithVaults} flags - The flags passed to the command. * @returns {Promise} */ private async action( args: UninstallArgs, - flags: FactoryFlags, + flags: FactoryFlagsWithVaults, ): Promise { const { path } = flags const { @@ -75,7 +73,7 @@ export default class Uninstall extends FactoryCommand { process.exit(1) } - const vaults = await this.loadVaults(path) + const vaults = await loadVaults(path) const selectedVaults = await vaultsSelector(vaults) // Check if pluginId is provided and uninstall only that plugin diff --git a/src/commands/reports/stats.ts b/src/commands/reports/stats.ts index a4c4486..f82a1f7 100644 --- a/src/commands/reports/stats.ts +++ b/src/commands/reports/stats.ts @@ -1,29 +1,8 @@ -import { Flags, flush, handle } from '@oclif/core' -import { ArgInput } from '@oclif/core/lib/parser' -import { eachSeries, ErrorCallback } from 'async' -import fastFolderSize from 'fast-folder-size' -import { filesize } from 'filesize' -import { existsSync } from 'fs' -import { readFile } from 'fs/promises' -import { - isPluginInstalled, - Vault, - vaultPathToPluginsPath, -} from 'obsidian-utils' -import { join } from 'path' -import { promisify } from 'util' -import FactoryCommand, { FactoryFlags } from '../../providers/command' -import { Config, safeLoadConfig } from '../../providers/config' -import { InstalledPlugins } from '../../providers/plugins' -import { vaultsSelector } from '../../providers/vaults' -import { VAULTS_PATH_FLAG_DESCRIPTION } from '../../utils/constants' -import { logger } from '../../utils/logger' -interface StatsFlags { - path: string - output: string -} +import { Flags, flush } from '@oclif/core' +import { FactoryCommandWithVaults } from '../../providers/command' +import { action } from '../../services/stats' -export default class Stats extends FactoryCommand { +export default class Stats extends FactoryCommandWithVaults { static readonly aliases = ['rs', 'reports stats'] static override readonly description = `Statistics of vaults and installed plugins.` static override readonly examples = [ @@ -32,11 +11,6 @@ export default class Stats extends FactoryCommand { '<%= config.bin %> <%= command.id %> --path=/path/to/vaults/**/.obsidian', ] static override readonly flags = { - path: Flags.string({ - char: 'p', - description: VAULTS_PATH_FLAG_DESCRIPTION, - default: '', - }), output: Flags.string({ char: 'o', description: 'Display the output with a specific transformer.', @@ -49,113 +23,20 @@ export default class Stats extends FactoryCommand { /** * Executes the command. * Parses the arguments and flags, and calls the action method. + * Loads vaults, selects vaults, and gets stats about number of vaults and installed plugins per vault. * Handles errors and ensures flushing of logs. + * @returns {Promise} + * @throws {Error} - Throws an error if the command fails. */ - public async run() { + public async run(): Promise { try { const { args, flags } = await this.parse(Stats) - await this.action(args, this.flagsInterceptor(flags)) + return await action(args, this.flagsInterceptor(flags), this.handleError) } catch (error) { this.handleError(error) + throw error } finally { flush() } } - - /** - * Main action method for the command. - * Loads vaults, selects vaults, and gets stats about number of vaults and installed plugins per vault. - * @param {ArgInput} args - The arguments passed to the command. - * @param {FactoryFlags} flags - The flags passed to the command. - * @returns {Promise} - */ - private async action( - args: ArgInput, - flags: FactoryFlags, - ): Promise { - const { path, output } = flags - const { - success: loadConfigSuccess, - data: config, - error: loadConfigError, - } = await safeLoadConfig(flags.config) - if (!loadConfigSuccess) { - logger.error('Failed to load config', { error: loadConfigError }) - process.exit(1) - } - - const vaults = await this.loadVaults(path) - const selectedVaults = await vaultsSelector(vaults) - const vaultsWithConfig = selectedVaults.map((vault) => ({ vault, config })) - - const installedPlugins: InstalledPlugins = {} - - const statsVaultIterator = async (opts: { - vault: Vault - config: Config - }) => { - const { vault, config } = opts - logger.debug(`Checking stats for vault`, { vault }) - - const pluginsDir = vaultPathToPluginsPath(vault.path) - for (const stagePlugin of config.plugins) { - const pluginDir = join(pluginsDir, stagePlugin.id) - const pluginDirExists = existsSync(pluginDir) - - if (!pluginDirExists) { - continue - } - const manifestFile = await readFile( - pluginDir + '/manifest.json', - 'utf8', - ) - const manifestVersion = ( - JSON.parse(manifestFile) as { version: string } - ).version - const pluginDirSize = await promisify(fastFolderSize)(pluginDir) - const pluginNameWithSize = pluginDirSize - ? `${stagePlugin.id}@${manifestVersion} (${filesize(pluginDirSize)})` - : stagePlugin.id - if (await isPluginInstalled(stagePlugin.id, vault.path)) { - installedPlugins[pluginNameWithSize] = [ - ...(installedPlugins[pluginNameWithSize] || []), - vault.name, - ] - } - } - } - - const statsVaultErrorCallback: ErrorCallback = (error) => { - if (error) { - logger.debug('Error getting stats', { error }) - handle(error) - return error - } else { - const totalStats = { - totalVaults: selectedVaults.length, - totalPlugins: config.plugins.length, - } - - const sortedInstalledPlugins = Object.entries(installedPlugins) - .sort(([keyA], [keyB]) => keyA.localeCompare(keyB)) - .reduce( - (acc, [key, value]) => { - acc[key] = value - return acc - }, - {} as Record, - ) - - if (output === 'table') { - console.table(totalStats) - console.table(sortedInstalledPlugins) - } else if (output === 'json') { - console.log(JSON.stringify(totalStats, null, 2)) - console.log(JSON.stringify(sortedInstalledPlugins, null, 2)) - } - } - } - - eachSeries(vaultsWithConfig, statsVaultIterator, statsVaultErrorCallback) - } } diff --git a/src/commands/vaults/run.ts b/src/commands/vaults/run.ts index ada653f..0d69587 100644 --- a/src/commands/vaults/run.ts +++ b/src/commands/vaults/run.ts @@ -1,42 +1,8 @@ -import { Args, Flags, flush, handle } from '@oclif/core' -import { each, eachSeries, ErrorCallback } from 'async' -import { exec, ExecException } from 'child_process' -import { formatDuration, intervalToDuration } from 'date-fns' -import { Vault } from 'obsidian-utils' -import { CommandsExecutedOnVaults } from '../../commands' -import FactoryCommand, { FactoryFlags } from '../../providers/command' -import { safeLoadConfig } from '../../providers/config' -import { vaultsSelector } from '../../providers/vaults' -import { - RESERVED_VARIABLES, - VAULTS_PATH_FLAG_DESCRIPTION, -} from '../../utils/constants' -import { - CUSTOM_COMMAND_LOGGER_FILE, - customCommandLogger, - logger, -} from '../../utils/logger' +import { Args, Flags, flush } from '@oclif/core' +import { FactoryCommandWithVaults } from '../../providers/command' +import { action } from '../../services/run' -interface CommandArgs { - [key: string]: string -} - -interface RunFlags { - path: string - output: string - unescape: boolean - async: boolean - silent: boolean - runFromVaultDirectoryAsWorkDir: boolean -} - -interface ExecuteCustomCommandResult { - stdout: string - stderr: string - error: ExecException | null -} - -export default class Run extends FactoryCommand { +export default class Run extends FactoryCommandWithVaults { static readonly aliases = ['r', 'run', 'vr', 'vaults run'] static override readonly description = `Run a shell command on selected vaults (using Node.js child_process).\nDisclaimer: Any input containing shell metacharacters may be used to trigger arbitrary command execution, using of this command is at risk of command's caller.` static override readonly examples = [ @@ -48,11 +14,6 @@ export default class Run extends FactoryCommand { '<%= config.bin %> <%= command.id %> --output=json --runFromVaultDirectoryAsWorkDir=false', ] static override readonly flags = { - path: Flags.string({ - char: 'p', - description: VAULTS_PATH_FLAG_DESCRIPTION, - default: '', - }), output: Flags.string({ char: 'o', description: 'Display the output with a specific transformer.', @@ -80,7 +41,7 @@ export default class Run extends FactoryCommand { description: 'Run the command from the vault directory as working dir.', default: true, }), - ...this.commonFlags, + ...this.commonFlagsWithPath, } static override readonly args = { @@ -95,177 +56,17 @@ export default class Run extends FactoryCommand { * Executes the command. * Parses the arguments and flags, and calls the action method. * Handles errors and ensures flushing of logs. + * @returns {Promise} + * @throws {Error} - Throws an error if the command fails. */ - public async run() { + public async run(): Promise { try { const { args, flags } = await this.parse(Run) - await this.action(args, this.flagsInterceptor(flags)) + await action(args, this.flagsInterceptor(flags)) } catch (error) { this.handleError(error) } finally { flush() } } - - /** - * Main action method for the command. - * Loads vaults, selects vaults, and gets stats about number of vaults and installed plugins per vault. - * @param {ArgInput} args - The arguments passed to the command. - * @param {FactoryFlags} flags - The flags passed to the command. - * @returns {Promise} - */ - private async action( - args: CommandArgs, - flags: FactoryFlags, - ): Promise { - const { command } = args - const { path, output } = flags - const { success: loadConfigSuccess, error: loadConfigError } = - await safeLoadConfig(flags.config) - if (!loadConfigSuccess) { - logger.error('Failed to load config', { error: loadConfigError }) - process.exit(1) - } - - const vaults = await this.loadVaults(path) - const selectedVaults = await vaultsSelector(vaults) - const vaultsWithCommand = selectedVaults.map((vault: Vault) => ({ - vault, - command: this.commandInterpolation(vault, command), - })) - - const taskExecutedOnVaults: CommandsExecutedOnVaults = {} - - const commandVaultIterator = async (opts: { - vault: Vault - command: CommandArgs['command'] - }) => { - const { vault, command } = opts - logger.debug(`Execute command`, { vault, command }) - - try { - const startDate = new Date() - const result = await this.asyncExecCustomCommand( - command, - flags.runFromVaultDirectoryAsWorkDir, - vault, - ) - const endDate = new Date() - const durationLessThanSecond = endDate.getTime() - startDate.getTime() - const durationMoreThanSecond = intervalToDuration({ - start: startDate, - end: endDate, - }) - - const formattedDuration = - formatDuration(durationMoreThanSecond, { - format: ['hours', 'minutes', 'seconds'], - }) || `${durationLessThanSecond} ms` - - taskExecutedOnVaults[vault.name] = { - success: null, - duration: formattedDuration, - error: null, - } - - if (result) { - taskExecutedOnVaults[vault.name]['success'] = true - customCommandLogger.info('Executed successfully', { - result, - vault, - command, - }) - if (!flags.silent) { - logger.info(`Run command`, { vault, command }) - console.log(result) - } - } - } catch (error) { - taskExecutedOnVaults[vault.name]['error'] = JSON.stringify(error) - customCommandLogger.error('Execution failed', { - error: JSON.stringify(error), - vault, - command, - }) - } - } - - const commandVaultErrorCallback: ErrorCallback = ( - error: Error | null | undefined, - ) => { - if (error) { - logger.debug('UnhandledException', { - error: JSON.stringify(error), - path, - }) - handle(error) - return error - } else { - const sortedTaskExecutedOnVaults = Object.entries(taskExecutedOnVaults) - .sort(([keyA], [keyB]) => keyA.localeCompare(keyB)) - .reduce((acc, [key, value]) => { - acc[key] = value - return acc - }, {} as CommandsExecutedOnVaults) - - logger.info('Run operation finished!', { - custom_commands_log_path: CUSTOM_COMMAND_LOGGER_FILE, - }) - - if (output === 'table') { - console.table(sortedTaskExecutedOnVaults) - } else if (output === 'json') { - console.log(JSON.stringify(sortedTaskExecutedOnVaults, null, 2)) - } - } - } - customCommandLogger.debug('Running command on selected vaults...', { - vaults: vaultsWithCommand.length, - }) - - if (flags.async) { - each(vaultsWithCommand, commandVaultIterator, commandVaultErrorCallback) - } else { - eachSeries( - vaultsWithCommand, - commandVaultIterator, - commandVaultErrorCallback, - ) - } - } - - private async asyncExecCustomCommand( - command: string, - runFromVaultDirectoryAsWorkDir: boolean, - vault: Vault, - ): Promise | string> { - return new Promise((resolve, reject) => { - exec( - command, - { cwd: runFromVaultDirectoryAsWorkDir ? vault.path : __dirname }, - (error, stdout, stderr) => { - if (error) { - return reject(error) - } - resolve(`${stderr}\n${stdout}`) - }, - ) - }) - } - - private commandInterpolation(vault: Vault, command: string): string { - const variableRegex = /\{(\d*?)}/g - const replacer = (match: string, variable: string) => { - const variableFunction = RESERVED_VARIABLES[variable] - - if (variableFunction) { - return variableFunction(vault) - } else { - return match - } - } - const interpolatedCommand = command.replace(variableRegex, replacer) - - return interpolatedCommand - } } diff --git a/src/providers/command.ts b/src/providers/command.ts index 0260162..79335b0 100644 --- a/src/providers/command.ts +++ b/src/providers/command.ts @@ -1,46 +1,68 @@ -import { ExitPromptError } from '@inquirer/core' -import { Command, Flags, handle } from '@oclif/core' +import { Command, Flags } from '@oclif/core' +import { ParserInput } from '@oclif/core/lib/interfaces/parser' +import { exec } from 'child_process' import { Vault } from 'obsidian-utils' -import { DEFAULT_CONFIG_PATH } from '../utils/constants' +import { homedir } from 'os' +import path from 'path' +import { + ExecuteCustomCommandResult, + FactoryFlags, + FactoryFlagsWithVaults, +} from '../types/commands' +import { handlerCommandError } from '../utils/command' +import { + OVM_CONFIG_FILENAME, + RESERVED_VARIABLES, + VAULTS_PATH_FLAG_DESCRIPTION, +} from '../utils/constants' import { logger } from '../utils/logger' -import { findVaultsByPatternMatching, findVaultsFromConfig } from './vaults' -export type CommonFlags = { - debug: boolean - timestamp: boolean - config: string -} +const DEFAULT_CONFIG_PATH = path.join(homedir(), OVM_CONFIG_FILENAME) -export type FactoryFlags = T & CommonFlags +const commonFlags = { + debug: Flags.boolean({ + char: 'd', + default: false, + description: 'Enable debugging mode.', + }), + timestamp: Flags.boolean({ + char: 't', + default: false, + description: 'Enable timestamp in logs.', + }), + config: Flags.file({ + char: 'c', + description: `Path to the config file.`, + default: DEFAULT_CONFIG_PATH, + required: false, + }), +} -export default class FactoryCommand extends Command { - static readonly commonFlags = { - debug: Flags.boolean({ - char: 'd', - default: false, - description: 'Enable debugging mode.', - }), - timestamp: Flags.boolean({ - char: 't', - default: false, - description: 'Enable timestamp in logs.', - }), - config: Flags.file({ - char: 'c', - description: `Path to the config file.`, - default: DEFAULT_CONFIG_PATH, - required: false, - }), - } +class FactoryCommand extends Command { + static readonly commonFlags = commonFlags run(): Promise { throw new Error('Method not implemented.') } + public enableLoggingTimestamp(timestamp: boolean): void { + process.env.OVM_ENABLE_LOG_TIMESTAMP = timestamp ? '0' : '1' + } + + public enableDebugLogLevel( + debug: boolean, + flags: ParserInput['flags'], + ): void { + if (debug) { + logger.level = 'debug' + logger.debug(`Command called`, { flags }) + } + } + public flagsInterceptor(flags: FactoryFlags): FactoryFlags { const { debug, timestamp } = flags - process.env.OVM_ENABLE_LOG_TIMESTAMP = timestamp ? 'true' : 'false' + this.enableLoggingTimestamp(timestamp) if (debug) { logger.level = 'debug' @@ -50,42 +72,95 @@ export default class FactoryCommand extends Command { return flags } - /** - * Loads vaults based on the specified path or from the configuration. - * If a path is specified, it will find vaults by pattern matching. - * If no path is specified, it will find vaults from the Obsidian configuration. - * Throws an error if no vaults are found. - * - * @param path - The path to search for vaults. - * @returns A promise that resolves to an array of Vault objects. - * @throws An error if no vaults are found. - */ - public async loadVaults(path: string): Promise { - const isPathSpecifiedAndValid = path && path.trim().length > 0 - let vaults: Vault[] = [] - - if (isPathSpecifiedAndValid) { - vaults = await findVaultsByPatternMatching(path) - } else { - vaults = await findVaultsFromConfig() - } + public handleError(error: unknown) { + handlerCommandError(error) + } +} + +class FactoryCommandWithVaults extends Command { + static readonly commonFlagsWithPath = { + ...FactoryCommand.commonFlags, + path: Flags.string({ + char: 'p', + description: VAULTS_PATH_FLAG_DESCRIPTION, + default: '', + }), + } + + static readonly commonFlags = FactoryCommandWithVaults.commonFlagsWithPath - if (vaults.length === 0) { - throw new Error(`No vaults found!`) + run(): Promise { + throw new Error('Method not implemented.') + } + + public enableLoggingTimestamp(timestamp: boolean): void { + process.env.OVM_ENABLE_LOG_TIMESTAMP = timestamp ? '0' : '1' + } + + public enableDebugLogLevel( + debug: boolean, + flags: ParserInput['flags'], + ): void { + if (debug) { + logger.level = 'debug' + logger.debug(`Command called`, { flags }) } + } + + public flagsInterceptor( + flags: FactoryFlagsWithVaults, + ): FactoryFlagsWithVaults { + const { debug, timestamp } = flags + + this.enableLoggingTimestamp(timestamp) + this.enableDebugLogLevel(debug, flags as ParserInput['flags']) - return vaults + return flags } public handleError(error: unknown) { - // Avoid handling errors by logger for CI environment - if (process.env.CI) { - throw error - } else if (error instanceof ExitPromptError) { - logger.debug('Exit prompt error:', { error }) - } else if (error instanceof Error) { - logger.debug('An error occurred while installation:', { error }) - handle(error) + handlerCommandError(error) + } +} + +const commandInterpolation = (vault: Vault, command: string): string => { + const variableRegex = /\{(\d*?)}/g + const replacer = (match: string, variable: string) => { + const variableFunction = RESERVED_VARIABLES[variable] + + if (variableFunction) { + return variableFunction(vault) + } else { + return match } } + const interpolatedCommand = command.replace(variableRegex, replacer) + + return interpolatedCommand +} + +const asyncExecCustomCommand = async ( + command: string, + runFromVaultDirectoryAsWorkDir: boolean, + vault: Vault, +): Promise | string> => { + return new Promise((resolve, reject) => { + exec( + command, + { cwd: runFromVaultDirectoryAsWorkDir ? vault.path : __dirname }, + (error, stdout, stderr) => { + if (error) { + reject(error) + } + resolve(`${stderr}\n${stdout}`) + }, + ) + }) +} + +export { + asyncExecCustomCommand, + commandInterpolation, + FactoryCommand, + FactoryCommandWithVaults, } diff --git a/src/providers/config.test.ts b/src/providers/config.test.ts deleted file mode 100644 index 99b4a34..0000000 --- a/src/providers/config.test.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { ConfigSchema, safeLoadConfig } from './config' - -import { expect } from 'chai' -import mock from 'mock-fs' -import { OVM_CONFIG_FILENAME } from '../utils/constants' - -describe('Config', () => { - it("should load config from user's home dir", async () => { - const userHome = '/home/user' - const configPath = `${userHome}/${OVM_CONFIG_FILENAME}` - - const sampleDefaultConfig = ConfigSchema.parse({}) - - mock({ - [userHome]: { - [OVM_CONFIG_FILENAME]: JSON.stringify(sampleDefaultConfig), - }, - }) - - const config = await safeLoadConfig(configPath) - - expect(config.success).to.be.true.equal(true) - expect(config.error).to.be.undefined.equal(undefined) - expect(config.data).to.deep.equal(sampleDefaultConfig) - mock.restore() - }) - - it('should throw an error if the config file is invalid', async () => { - const userHome = '/home/user' - const configPath = `${userHome}/${OVM_CONFIG_FILENAME}` - mock({ - [userHome]: { - [OVM_CONFIG_FILENAME]: 'invalid-json', - }, - }) - - try { - const { error } = await safeLoadConfig(configPath) - throw error - } catch (error) { - expect(error).to.be.an('error') - } - }) -}) diff --git a/src/providers/config.ts b/src/providers/config.ts deleted file mode 100644 index d7015bc..0000000 --- a/src/providers/config.ts +++ /dev/null @@ -1,105 +0,0 @@ -import { readFileSync, writeFileSync } from 'fs' -import { GitHubPluginVersion } from 'obsidian-utils' -import z from 'zod' -import { logger } from '../utils/logger' - -const PluginSchema = z.object({ - id: z.string(), - version: z.custom().optional(), -}) - -export type Plugin = z.infer - -export const ConfigSchema = z.object({ - plugins: z.array(PluginSchema).default([]), -}) - -export type Config = z.infer - -type SafeLoadConfigResultSuccess = { - success: true - data: Config - error: undefined -} - -type SafeLoadConfigResultError = { - success: false - data: undefined - error: Error -} - -type SafeLoadConfigResult = - | ({ - success: boolean - } & SafeLoadConfigResultSuccess) - | SafeLoadConfigResultError - -export const safeLoadConfig = ( - configPath: string, -): Promise => { - return new Promise((resolve) => { - try { - const config = readFileSync(configPath) - const parsed = JSON.parse(config.toString()) as Config - const { success, data, error } = ConfigSchema.safeParse(parsed) - - if (!success) { - logger.debug('Invalid config file', { data, error }) - throw new Error('Invalid config file') - } - - resolve({ success, data, error: undefined }) - } catch (error) { - const typedError = error as Error - if ( - typedError instanceof Error && - typedError.message.includes('ENOENT') - ) { - resolve({ - success: false, - data: undefined, - error: new Error('Config file not found'), - }) - } - - resolve({ success: false, data: undefined, error: typedError }) - } - }) -} - -export const writeConfig = ( - config: Config, - path: string, -): Promise => { - logger.debug('Writing config', { path }) - return new Promise((resolve, reject) => { - try { - const content = JSON.stringify(config, null, 2) - - writeFileSync(path, content) - logger.debug('Config written', { path }) - resolve() - } catch (error) { - reject(error as Error) - } - }) -} - -export const createDefaultConfig = ( - path: string, -): Promise => { - return new Promise((resolve, reject) => { - try { - const defaultConfig = ConfigSchema.parse({}) - - writeConfig(defaultConfig, path) - - logger.info('Config file created', { path }) - - resolve(defaultConfig) - } catch (error) { - const typedError = error as Error - reject(typedError) - } - }) -} diff --git a/src/providers/github.ts b/src/providers/github.ts index cb82d0e..3b901b8 100644 --- a/src/providers/github.ts +++ b/src/providers/github.ts @@ -39,7 +39,7 @@ export const fetchPlugins = async (): Promise => { if (!response.ok) { throw new Error('Failed to fetch plugins') } - return response.json() + return response.json() as unknown as PluginRegistry[] } export const findPluginInRegistry = async ( diff --git a/src/providers/plugins.ts b/src/providers/plugins.ts index 8eb1759..de79e57 100644 --- a/src/providers/plugins.ts +++ b/src/providers/plugins.ts @@ -1,10 +1,8 @@ import { checkbox } from '@inquirer/prompts' import { readdir, readFile, rm, writeFile } from 'fs/promises' import { vaultPathToPluginsPath } from 'obsidian-utils' +import { Plugin } from '../services/config' import { logger } from '../utils/logger' -import { Plugin } from './config' - -export type InstalledPlugins = Record> export const removePluginDir = async (pluginId: string, vaultPath: string) => { const childLogger = logger.child({ pluginId, vaultPath }) diff --git a/src/providers/vaults.ts b/src/providers/vaults.ts index fe2a638..4c8d7dd 100644 --- a/src/providers/vaults.ts +++ b/src/providers/vaults.ts @@ -1,7 +1,8 @@ import { checkbox } from '@inquirer/prompts' import { glob } from 'glob' import { findVault, Vault } from 'obsidian-utils' -import path from 'path' +import { basename, dirname } from 'path' +import { isTestEnv } from '../utils/env' import { logger } from '../utils/logger' export const findVaultsByPatternMatching = async (pathPattern: string) => { @@ -20,8 +21,8 @@ export const findVaultsByPatternMatching = async (pathPattern: string) => { for await (const [vault] of vaultsQueryPromises) { detectedVaults.push({ ...vault, - name: path.basename(path.dirname(vault.path)), - path: path.dirname(vault.path), + name: basename(dirname(vault.path)), + path: dirname(vault.path), }) } @@ -38,6 +39,11 @@ export const vaultsSelector = async (vaults: Vault[]) => { })) .sort((a, b) => a.name.localeCompare(b.name)) + if (isTestEnv()) { + const [{ value: testVault }] = choices + return [testVault] + } + const selectedVaults = await checkbox({ choices, message: 'Select the vaults:', @@ -46,10 +52,37 @@ export const vaultsSelector = async (vaults: Vault[]) => { required: true, }) - logger.debug('selectedVaults', { selectedVaults }) + logger.debug('Selected vaults', { selectedVaults }) return selectedVaults } export const getVaultPath = (vault: Vault) => vault.path export const getVaultName = (vault: Vault) => vault.name + +/** + * Loads vaults based on the specified path or from the configuration. + * If a path is specified, it will find vaults by pattern matching. + * If no path is specified, it will find vaults from the Obsidian configuration. + * Throws an error if no vaults are found. + * + * @param path - The path to search for vaults. + * @returns A promise that resolves to an array of Vault objects. + * @throws An error if no vaults are found. + */ +export const loadVaults = async (path: string): Promise => { + const isPathSpecifiedAndValid = path && path.trim().length > 0 + let vaults: Vault[] = [] + + if (isPathSpecifiedAndValid) { + vaults = await findVaultsByPatternMatching(path) + } else { + vaults = await findVaultsFromConfig() + } + + if (vaults.length === 0) { + throw new Error(`No vaults found!`) + } + + return vaults +} diff --git a/src/services/config.test.ts b/src/services/config.test.ts new file mode 100644 index 0000000..40fad82 --- /dev/null +++ b/src/services/config.test.ts @@ -0,0 +1,51 @@ +import { expect } from 'chai' +import fs from 'fs' +import { destroyConfigMockFile, getTmpConfigFilePath } from '../utils/testing' +import { ConfigSchema, createDefaultConfig, safeLoadConfig } from './config' + +const tmpConfigFilePath = getTmpConfigFilePath() + +describe('Config', () => { + beforeEach(() => { + destroyConfigMockFile(tmpConfigFilePath) + }) + it("should load config from user's home dir", async () => { + const sampleDefaultConfig = ConfigSchema.parse({}) + createDefaultConfig(tmpConfigFilePath) + const config = await safeLoadConfig(tmpConfigFilePath) + + expect(config.success).to.be.true.equal(true) + expect(config.error).to.be.undefined.equal(undefined) + expect(config.data).to.deep.equal(sampleDefaultConfig) + }) + + it("should throw an error if the config file doesn't exist", async () => { + try { + const { error } = await safeLoadConfig('non-existent-file') + throw error + } catch (error) { + expect(error).to.be.an('error') + } + }) + + it('should throw an error if the config file is not JSON', async () => { + fs.writeFileSync(tmpConfigFilePath, 'invalid content') + try { + const { error } = await safeLoadConfig(tmpConfigFilePath) + throw error + } catch (error) { + const typedError = error as Error + expect(typedError.message).to.include('Invalid JSON format') + } + }) + + it('should throw an error if the config file is invalid', async () => { + createDefaultConfig(tmpConfigFilePath, { + // @ts-expect-error To create an invalid config + invalidKey: 'invalidValue', + }) + + const { error } = await safeLoadConfig(tmpConfigFilePath) + expect(error?.message).to.include('Invalid config file') + }) +}) diff --git a/src/services/config.ts b/src/services/config.ts new file mode 100644 index 0000000..fe0c355 --- /dev/null +++ b/src/services/config.ts @@ -0,0 +1,94 @@ +import { readFileSync, writeFileSync } from 'fs' +import { GitHubPluginVersion } from 'obsidian-utils' +import z from 'zod' +import { logger } from '../utils/logger' +import { stringToJSONSchema } from '../utils/transformer' + +const PluginSchema = z.object({ + id: z.string(), + version: z.custom().optional(), +}) + +export type Plugin = z.infer + +export const ConfigSchema = z + .object({ + plugins: z.array(PluginSchema).default([]), + }) + .strict() + +export type Config = z.infer + +type SafeLoadConfigResultSuccess = { + success: true + data: Config + error: undefined +} + +type SafeLoadConfigResultError = { + success: false + data: undefined + error: Error +} + +type SafeLoadConfigResult = + | ({ + success: boolean + } & SafeLoadConfigResultSuccess) + | SafeLoadConfigResultError + +export const safeLoadConfig = ( + configPath: string, +): Promise => { + return new Promise((resolve) => { + try { + const config = readFileSync(configPath) + const { success, data, error } = stringToJSONSchema + .pipe(ConfigSchema) + .safeParse(config.toString()) + + if (!success) { + logger.debug('Schema validation failed', { error }) + + return resolve({ + success, + data, + error: new Error('Invalid config file'), + }) + } + + return resolve({ success, data, error: undefined }) + } catch (error) { + const typedError = error as Error + if (typedError.message.includes('ENOENT')) { + return resolve({ + success: false, + data: undefined, + error: new Error('Config file not found'), + }) + } + + return resolve({ success: false, data: undefined, error: typedError }) + } + }) +} + +export const writeConfig = (config: Config, path: string): void => { + logger.debug('Writing config', { path }) + + const content = JSON.stringify(config, null, 2) + + writeFileSync(path, content) + + logger.debug('Config written', { path }) +} + +export const createDefaultConfig = (path: string, opts?: Config): Config => { + const defaultConfig = opts ?? ConfigSchema.parse({}) + + writeConfig(defaultConfig, path) + + logger.info('Config file created', { path }) + + return defaultConfig +} diff --git a/src/services/init.test.ts b/src/services/init.test.ts new file mode 100644 index 0000000..7c93145 --- /dev/null +++ b/src/services/init.test.ts @@ -0,0 +1,43 @@ +import { expect } from 'chai' +import { action } from '../commands/config/init' +import { + destroyConfigMockFile, + getTmpConfigFilePath, + testCommonFlags, +} from '../utils/testing' +import { safeLoadConfig } from './config' + +const tmpConfigFilePath = getTmpConfigFilePath() + +describe('Command: config init', () => { + beforeEach(async () => { + await destroyConfigMockFile(tmpConfigFilePath) + }) + + afterEach(async () => { + await destroyConfigMockFile(tmpConfigFilePath) + }) + + it('should create a config file and fail for second attempt', async () => { + await action({}, testCommonFlags, (result) => { + expect(result.success).to.be.true + }) + + // Verify that the config file was created + const result = await safeLoadConfig(tmpConfigFilePath) + expect(result.success).to.be.true + expect(result.error).to.be.undefined + + // Verify that the second attempt fails + try { + await action({}, testCommonFlags, (result) => { + expect(result.success).to.be.false + }) + } catch (error) { + const typedError = error as Error + expect(typedError.message).to.match(/File already exists!/) + } + }) + + it.skip('should throw an error if opening config fail forbidden', async () => {}) +}) diff --git a/src/services/install.test.ts b/src/services/install.test.ts new file mode 100644 index 0000000..ce59cdc --- /dev/null +++ b/src/services/install.test.ts @@ -0,0 +1,75 @@ +import { expect } from 'chai' +import sinon from 'sinon' +import { + createTmpVault, + destroyConfigMockFile, + destroyVault, + testCommonFlags, + testVaultPath, + tmpConfigFilePath, +} from '../utils/testing' +import { createDefaultConfig } from './config' +import { action } from './install' + +const samplePluginId = 'obsidian-linter' +describe('Command: install', () => { + beforeEach(async () => { + await destroyConfigMockFile(tmpConfigFilePath) + await destroyVault(testVaultPath) + createDefaultConfig(tmpConfigFilePath) + }) + + afterEach(async () => { + sinon.restore() + }) + + it('should perform installation successfully', async () => { + await createTmpVault(testVaultPath) + await action( + { pluginId: samplePluginId }, + { ...testCommonFlags, enable: true, path: testVaultPath }, + (iterator) => { + expect(iterator).to.be.an('object') + expect(iterator).to.have.property('installedPlugins') + expect(iterator).to.have.property('failedPlugins') + expect(iterator.installedPlugins).to.be.an('array') + expect(iterator.failedPlugins).to.be.an('array') + expect(iterator.installedPlugins.length).to.be.greaterThan(0) + expect(iterator.failedPlugins.length).to.equal(0) + expect(iterator.installedPlugins[0].repo).to.match( + new RegExp(samplePluginId), + ) + }, + (result) => { + expect(result).to.be.an('object') + expect(result).to.have.property('success') + expect(result.success).to.be.true + }, + ) + }) + + it('should throw PluginNotFoundInRegistryError when plugin is not found', async () => { + await createTmpVault(testVaultPath) + const pluginId = 'nonExistentPluginId' + + await action( + { pluginId }, + { ...testCommonFlags, enable: true, path: testVaultPath }, + (iterator) => { + expect(iterator).to.be.an('object') + expect(iterator).to.have.property('installedPlugins') + expect(iterator).to.have.property('failedPlugins') + expect(iterator.installedPlugins).to.be.an('array') + expect(iterator.failedPlugins).to.be.an('array') + expect(iterator.installedPlugins.length).to.equal(0) + expect(iterator.failedPlugins.length).to.equal(1) + expect(iterator.failedPlugins[0].repo).to.equal(pluginId) + }, + (result) => { + expect(result).to.be.an('object') + expect(result).to.have.property('success') + expect(result.success).to.be.false + }, + ) + }) +}) diff --git a/src/services/install.ts b/src/services/install.ts new file mode 100644 index 0000000..d57634f --- /dev/null +++ b/src/services/install.ts @@ -0,0 +1,160 @@ +import { eachSeries } from 'async' +import { + installPluginFromGithub, + isPluginInstalled, + Vault, +} from 'obsidian-utils' +import { + findPluginInRegistry, + handleExceedRateLimitError, +} from '../providers/github' +import { modifyCommunityPlugins } from '../providers/plugins' +import { loadVaults, vaultsSelector } from '../providers/vaults' +import { + FactoryFlagsWithVaults, + InstallArgs, + InstallCommandCallback, + InstallCommandIterator, + InstallFlags, + StagedPlugins, +} from '../types/commands' +import { PluginNotFoundInRegistryError } from '../utils/errors' +import { logger } from '../utils/logger' +import { Config, safeLoadConfig, writeConfig } from './config' + +export const installPluginsInVaults = async ( + vaults: Vault[], + config: Config, + flags: FactoryFlagsWithVaults, + specific: boolean, + iterator: InstallCommandIterator, + callback: InstallCommandCallback, +) => { + const installVaultIterator = async (vault: Vault) => { + logger.debug(`Install plugins for vault`, { vault }) + const installedPlugins: StagedPlugins = [] + const failedPlugins: StagedPlugins = [] + + for (const stagePlugin of config.plugins) { + const childLogger = logger.child({ plugin: stagePlugin, vault }) + + const pluginInRegistry = await findPluginInRegistry(stagePlugin.id) + if (!pluginInRegistry) { + throw new PluginNotFoundInRegistryError(stagePlugin.id) + } + + if (await isPluginInstalled(pluginInRegistry.id, vault.path)) { + childLogger.info(`Plugin already installed`) + continue + } + + stagePlugin.version = stagePlugin.version ?? 'latest' + + try { + await installPluginFromGithub( + pluginInRegistry.repo, + stagePlugin.version, + vault.path, + ) + installedPlugins.push({ + repo: pluginInRegistry.repo, + version: stagePlugin.version, + }) + + if (flags.enable) { + await modifyCommunityPlugins(stagePlugin, vault.path, 'enable') + } + + if (specific) { + const newPlugins = new Set([...config.plugins]) + const updatedConfig = { ...config, plugins: [...newPlugins] } + writeConfig(updatedConfig, flags.config) + } + + childLogger.info(`Installed plugin`) + } catch (error) { + failedPlugins.push({ + repo: pluginInRegistry.repo, + version: stagePlugin.version, + }) + handleExceedRateLimitError(error) + childLogger.error(`Failed to install plugin`, { error }) + } + } + + if (installedPlugins.length) { + logger.info(`Installed ${installedPlugins.length} plugins`, { + vault, + }) + } + + if (iterator) { + iterator({ installedPlugins, failedPlugins }) + } + + return { installedPlugins, failedPlugins } + } + + return eachSeries(vaults, installVaultIterator, (error) => { + if (error) { + logger.debug('Error installing plugins', { error }) + callback({ success: false, error }) + return + } + + callback({ success: true }) + }) +} + +/** + * + * + * @param {InstallArgs} args + * @param {FactoryFlagsWithVaults} flags + * @param {InstallCommandIterator} [iterator=() => {}] + * @param {InstallCommandCallback} [callback=() => {}] + * @return {Promise} + */ +export const action = async ( + args: InstallArgs, + flags: FactoryFlagsWithVaults, + iterator: InstallCommandIterator = () => {}, + callback: InstallCommandCallback = () => {}, +): Promise => { + const { path } = flags + const { + success: loadConfigSuccess, + data: config, + error: loadConfigError, + } = await safeLoadConfig(flags.config) + + if (!loadConfigSuccess) { + logger.error('Failed to load config', { error: loadConfigError }) + process.exit(1) + } + + const vaults = await loadVaults(path) + const selectedVaults = await vaultsSelector(vaults) + + // Check if pluginId is provided and install only that plugin + const { pluginId } = args + if (pluginId) { + await installPluginsInVaults( + selectedVaults, + { ...config, plugins: [{ id: pluginId }] }, + flags, + true, + iterator, + callback, + ) + } else { + await installPluginsInVaults( + selectedVaults, + config, + flags, + false, + iterator, + callback, + ) + } +} diff --git a/src/services/prune.test.ts b/src/services/prune.test.ts new file mode 100644 index 0000000..58d2706 --- /dev/null +++ b/src/services/prune.test.ts @@ -0,0 +1,36 @@ +import sinon from 'sinon' +import { + createTmpVault, + destroyConfigMockFile, + destroyVault, + testCommonFlags, + testVaultPath, + tmpConfigFilePath, +} from '../utils/testing' +import { createDefaultConfig } from './config' +import { action } from './prune' + +describe('Command: prune', () => { + beforeEach(async () => { + await destroyConfigMockFile(tmpConfigFilePath) + await destroyVault(testVaultPath) + createDefaultConfig(tmpConfigFilePath) + }) + + afterEach(async () => { + sinon.restore() + }) + + it('should prune plugins successfully', async () => { + await createTmpVault(testVaultPath) + await action({}, { ...testCommonFlags, path: testVaultPath }) + // Add assertions to verify the plugins were pruned + }) + + it('should handle errors during pruning', async () => { + await createTmpVault(testVaultPath) + sinon.stub(process, 'exit') + await action({}, { ...testCommonFlags, path: testVaultPath }) + // Add assertions to verify error handling + }) +}) diff --git a/src/services/prune.ts b/src/services/prune.ts new file mode 100644 index 0000000..99097c9 --- /dev/null +++ b/src/services/prune.ts @@ -0,0 +1,74 @@ +import { ArgInput } from '@oclif/core/lib/parser' +import { eachSeries } from 'async' +import { listInstalledPlugins, removePluginDir } from '../providers/plugins' +import { loadVaults, vaultsSelector } from '../providers/vaults' +import { + FactoryFlagsWithVaults, + PruneCommandCallback, + PruneCommandIterator, + PruneFlags, + PrunePluginVaultOpts, +} from '../types/commands' +import { logger } from '../utils/logger' +import { safeLoadConfig } from './config' + +/** + * Main action method for the prune command. + * Loads vaults, selects vaults, loads configuration, and prunes unused plugins. + * @param {ArgInput} args + * @param {FactoryFlagsWithVaults} flags + * @param {PruneCommandIterator} [iterator=() => {}] + * @param {PruneCommandCallback} [callback=() => {}] + * @returns {Promise} + */ +export const action = async ( + args: ArgInput, + flags: FactoryFlagsWithVaults, + iterator: PruneCommandIterator = () => {}, + callback: PruneCommandCallback = () => {}, +): Promise => { + const { path } = flags + const { + success: loadConfigSuccess, + data: config, + error: loadConfigError, + } = await safeLoadConfig(flags.config) + + if (!loadConfigSuccess) { + logger.error('Failed to load config', { error: loadConfigError }) + process.exit(1) + } + + const vaults = await loadVaults(path) + const selectedVaults = await vaultsSelector(vaults) + const vaultsWithConfig = selectedVaults.map((vault) => ({ vault, config })) + const prunePluginsIterator = async (opts: PrunePluginVaultOpts) => { + const { vault, config } = opts + const childLogger = logger.child({ vault }) + const installedPlugins = await listInstalledPlugins(vault.path) + const referencedPlugins = config.plugins.map(({ id }) => id) + const toBePruned = installedPlugins.filter( + ({ id }) => !referencedPlugins.includes(id), + ) + + for (const plugin of toBePruned) { + childLogger.debug(`Pruning plugin`, { plugin }) + await removePluginDir(plugin.id, vault.path) + } + + childLogger.info(`Pruned ${toBePruned.length} plugins`) + + if (iterator) { + iterator({ prunedPlugins: toBePruned }) + } + } + + eachSeries(vaultsWithConfig, prunePluginsIterator, (error) => { + if (error) { + logger.debug('Error pruning plugins', { error }) + callback({ success: false, error }) + } else { + callback({ success: true }) + } + }) +} diff --git a/src/services/run.test.ts b/src/services/run.test.ts new file mode 100644 index 0000000..cc95bdb --- /dev/null +++ b/src/services/run.test.ts @@ -0,0 +1,79 @@ +import { expect } from 'chai' +import { + createTmpVault, + destroyConfigMockFile, + testVaultName, + testVaultPath, + tmpConfigFilePath, +} from '../utils/testing' +import { createDefaultConfig } from './config' +import { action } from './run' + +describe('Command: run', () => { + beforeEach(async () => { + await destroyConfigMockFile(tmpConfigFilePath) + createDefaultConfig(tmpConfigFilePath) + await createTmpVault(testVaultPath) + }) + + afterEach(async () => { + await destroyConfigMockFile(tmpConfigFilePath) + }) + + it('should fail with invalid command', async () => { + try { + await action( + { + command: '', + }, + { + config: tmpConfigFilePath, + debug: false, + timestamp: false, + path: testVaultPath, + runFromVaultDirectoryAsWorkDir: false, + }, + ) + } catch (error) { + expect(error).to.not.be.undefined + } + }) + + it('should echo path and name of vault by echo command and reserved placeholder {0} {1}', async () => { + await action( + { + command: "echo 'Path: {0} {1}'", + }, + { + config: tmpConfigFilePath, + debug: false, + timestamp: false, + path: testVaultPath, + runFromVaultDirectoryAsWorkDir: false, + }, + async (result) => { + const expected = `Path: ${testVaultPath} ${testVaultName}` + expect(result.toString().trim()).to.match(new RegExp(expected)) + }, + ) + }) + + it('should echo path and name of vault by echo command and reserved placeholder {0} {1} and not {10000}', async () => { + await action( + { + command: "echo 'Path: {0} {1} {10000}'", + }, + { + config: tmpConfigFilePath, + debug: false, + timestamp: false, + path: testVaultPath, + runFromVaultDirectoryAsWorkDir: false, + }, + async (result) => { + const expected = `Path: ${testVaultPath} ${testVaultName} {10000}` + expect(result.toString().trim()).to.match(new RegExp(expected)) + }, + ) + }) +}) diff --git a/src/services/run.ts b/src/services/run.ts new file mode 100644 index 0000000..2a9acc4 --- /dev/null +++ b/src/services/run.ts @@ -0,0 +1,171 @@ +import { handle } from '@oclif/core' +import { each, eachSeries } from 'async' +import { formatDuration, intervalToDuration } from 'date-fns' +import { Vault } from 'obsidian-utils' +import { + asyncExecCustomCommand, + commandInterpolation, +} from '../providers/command' +import { loadVaults, vaultsSelector } from '../providers/vaults' +import { + CommandArgs, + CommandsExecutedOnVaults, + CommandVault, + ExecuteCustomCommandCallbackResult, + FactoryFlagsWithVaults, + RunFlags, +} from '../types/commands' +import { + CUSTOM_COMMAND_LOGGER_FILE, + customCommandLogger, + logger, +} from '../utils/logger' +import { safeLoadConfig } from './config' + +export const action = async ( + args: CommandArgs, + flags: FactoryFlagsWithVaults, + iterator?: (_result: string | Error) => void, + callback?: (_result: ExecuteCustomCommandCallbackResult | null) => void, +) => { + const { path, output } = flags + const { success: loadConfigSuccess, error: loadConfigError } = + await safeLoadConfig(flags.config) + if (!loadConfigSuccess) { + logger.error('Failed to load config', { error: loadConfigError }) + process.exit(1) + } + + if (!args.command || args.command === '') { + customCommandLogger.error('Command is empty', { + command: args.command, + }) + const emptyCommandError = new Error('Command is empty') + throw emptyCommandError + } + + const vaults = await loadVaults(path) + const selectedVaults = await vaultsSelector(vaults) + const vaultsWithCommand = selectedVaults.map((vault: Vault) => ({ + vault, + command: commandInterpolation(vault, args.command), + })) + + const taskExecutedOnVaults: CommandsExecutedOnVaults = {} + + const commandVaultIterator = async (opts: CommandVault) => { + const { vault, command } = opts + + logger.debug(`Execute command`, { vault, command }) + + try { + const startDate = new Date() + const result = await asyncExecCustomCommand( + command, + flags.runFromVaultDirectoryAsWorkDir, + vault, + ) + const endDate = new Date() + const durationLessThanSecond = endDate.getTime() - startDate.getTime() + const durationMoreThanSecond = intervalToDuration({ + start: startDate, + end: endDate, + }) + + const formattedDuration = + formatDuration(durationMoreThanSecond, { + format: ['hours', 'minutes', 'seconds'], + }) || `${durationLessThanSecond.toString()} ms` + + taskExecutedOnVaults[vault.name] = { + success: null, + duration: formattedDuration, + error: null, + } + + if (typeof result === 'string') { + taskExecutedOnVaults[vault.name]['success'] = true + customCommandLogger.info('Executed successfully', { + result, + vault, + command, + }) + if (!flags.silent) { + logger.info(`Run command`, { vault, command }) + } + + if (iterator) { + iterator(result) + } + } else { + taskExecutedOnVaults[vault.name]['success'] = false + customCommandLogger.error('Execution failed', { + error: result.error, + vault, + command, + }) + if (iterator) { + iterator(result.error as Error) + } + } + } catch (error) { + taskExecutedOnVaults[vault.name]['error'] = JSON.stringify(error) + customCommandLogger.error('Execution failed', { + error: JSON.stringify(error), + vault, + command, + }) + + if (iterator) { + iterator(error as Error) + } + } + } + + const commandVaultCallback = (error: Error | null | undefined) => { + if (error) { + logger.debug('UnhandledException', { + error: JSON.stringify(error), + path, + }) + handle(error) + return error + } else { + const sortedTaskExecutedOnVaults = Object.entries(taskExecutedOnVaults) + .sort(([keyA], [keyB]) => keyA.localeCompare(keyB)) + .reduce((acc, [key, value]) => { + acc[key] = value + return acc + }, {}) + + logger.info('Run operation finished!', { + custom_commands_log_path: CUSTOM_COMMAND_LOGGER_FILE, + }) + + if (output === 'table') { + console.table(sortedTaskExecutedOnVaults) + } else if (output === 'json') { + console.log(JSON.stringify(sortedTaskExecutedOnVaults, null, 2)) + } + + if (callback) { + callback({ + sortedTaskExecutedOnVaults, + }) + } + } + } + customCommandLogger.debug('Running command on selected vaults...', { + vaults: vaultsWithCommand.length, + }) + + if (flags.async) { + return each(vaultsWithCommand, commandVaultIterator, commandVaultCallback) + } else { + return eachSeries( + vaultsWithCommand, + commandVaultIterator, + commandVaultCallback, + ) + } +} diff --git a/src/services/stats.test.ts b/src/services/stats.test.ts new file mode 100644 index 0000000..4873d18 --- /dev/null +++ b/src/services/stats.test.ts @@ -0,0 +1,46 @@ +import { expect } from 'chai' +import { + createTmpVault, + destroyConfigMockFile, + testVaultPath, + tmpConfigFilePath, +} from '../utils/testing' +import { Config, createDefaultConfig } from './config' +import { action } from './stats' + +describe('Command: stats', () => { + let config: Config | null = null + beforeEach(async () => { + await destroyConfigMockFile(tmpConfigFilePath) + config = createDefaultConfig(tmpConfigFilePath) as Config + await createTmpVault(testVaultPath) + }) + + afterEach(async () => { + await destroyConfigMockFile(tmpConfigFilePath) + }) + + it('should display stats for vaults and plugins', async () => { + await action( + {}, + { + config: tmpConfigFilePath, + debug: false, + timestamp: false, + path: testVaultPath, + output: 'json', + }, + (iterated) => { + expect(iterated).to.not.be.undefined + }, + (result) => { + expect(result).to.have.property('totalStats') + expect(result).to.have.property('installedPlugins') + expect(result.totalStats?.totalVaults).to.be.equal(1) + expect(result.totalStats?.totalPlugins).to.be.equal( + config?.plugins.length, + ) + }, + ) + }) +}) diff --git a/src/services/stats.ts b/src/services/stats.ts new file mode 100644 index 0000000..5886c27 --- /dev/null +++ b/src/services/stats.ts @@ -0,0 +1,125 @@ +import { handle } from '@oclif/core' +import { ArgInput } from '@oclif/core/lib/interfaces' +import { eachSeries, ErrorCallback } from 'async' +import fastFolderSize from 'fast-folder-size' +import { filesize } from 'filesize' +import { existsSync } from 'fs' +import { readFile } from 'fs/promises' +import { + isPluginInstalled, + Vault, + vaultPathToPluginsPath, +} from 'obsidian-utils' +import { join } from 'path' +import { promisify } from 'util' +import { loadVaults, vaultsSelector } from '../providers/vaults' +import { + ExecuteCustomCommandResult, + FactoryFlagsWithVaults, + InstalledPlugins, + StatsCommandCallbackResult, + StatsFlags, +} from '../types/commands' +import { logger } from '../utils/logger' +import { Config, safeLoadConfig } from './config' + +export const action = async ( + args: ArgInput, + flags: FactoryFlagsWithVaults, + iterator?: ( + _result: Record | ExecuteCustomCommandResult, + ) => void, + callback?: (_result: StatsCommandCallbackResult) => void, +) => { + const { path, output } = flags + const { + success: loadConfigSuccess, + data: config, + error: loadConfigError, + } = await safeLoadConfig(flags.config) + if (!loadConfigSuccess) { + logger.error('Failed to load config', { error: loadConfigError }) + process.exit(1) + } + + const vaults = await loadVaults(path) + const selectedVaults = await vaultsSelector(vaults) + const vaultsWithConfig = selectedVaults.map((vault) => ({ vault, config })) + + const installedPlugins: InstalledPlugins = {} + + const statsVaultIterator = async (opts: { vault: Vault; config: Config }) => { + const { vault, config } = opts + logger.debug(`Checking stats for vault`, { vault }) + + const pluginsDir = vaultPathToPluginsPath(vault.path) + for (const stagePlugin of config.plugins) { + const pluginDir = join(pluginsDir, stagePlugin.id) + const pluginDirExists = existsSync(pluginDir) + + if (!pluginDirExists) { + continue + } + const manifestFile = await readFile(pluginDir + '/manifest.json', 'utf8') + const manifestVersion = (JSON.parse(manifestFile) as { version: string }) + .version + const pluginDirSize = await promisify(fastFolderSize)(pluginDir) + const pluginNameWithSize = pluginDirSize + ? `${stagePlugin.id}@${manifestVersion} (${filesize(pluginDirSize)})` + : stagePlugin.id + if (await isPluginInstalled(stagePlugin.id, vault.path)) { + installedPlugins[pluginNameWithSize] = [ + ...(installedPlugins[pluginNameWithSize] || []), + vault.name, + ] + } + + if (iterator) { + iterator({ + plugin: stagePlugin, + }) + } + } + } + + const statsVaultErrorCallback: ErrorCallback = (error) => { + if (error) { + logger.debug('Error getting stats', { error }) + callback && callback({ success: false, error }) + handle(error) + } else { + const totalStats = { + totalVaults: selectedVaults.length, + totalPlugins: config.plugins.length, + } + + const sortedInstalledPlugins = Object.entries(installedPlugins) + .sort(([keyA], [keyB]) => keyA.localeCompare(keyB)) + .reduce((acc, [key, value]) => { + acc[key] = value + return acc + }, {}) + + if (output === 'table') { + console.table(totalStats) + console.table(sortedInstalledPlugins) + } else if (output === 'json') { + console.log(JSON.stringify(totalStats, null, 2)) + + if (Object.keys(sortedInstalledPlugins).length > 0) { + console.log(JSON.stringify(sortedInstalledPlugins, null, 2)) + } + } + + if (callback) { + callback({ + success: true, + totalStats, + installedPlugins: sortedInstalledPlugins, + }) + } + } + } + + eachSeries(vaultsWithConfig, statsVaultIterator, statsVaultErrorCallback) +} diff --git a/src/types.d.ts b/src/types.d.ts deleted file mode 100644 index 3887500..0000000 --- a/src/types.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { Vault } from 'obsidian-utils' - -export type CommandOnVault = (_vault: Vault, ..._args: string[]) => string -export type ReservedVariables = { - [key: string]: CommandOnVault -} diff --git a/src/types/commands.d.ts b/src/types/commands.d.ts new file mode 100644 index 0000000..85f8edf --- /dev/null +++ b/src/types/commands.d.ts @@ -0,0 +1,149 @@ +import { ExecException } from 'child_process' +import { Vault } from 'obsidian-utils' +import { Config } from '../services/config' + +export type CommonFlags = { + debug: boolean + timestamp: boolean + config: string +} + +export type CommonFlagsWithPath = CommonFlags & { + path: string +} + +export type FactoryFlags = CommonFlags & T + +export type FactoryFlagsWithVaults = CommonFlagsWithPath & T + +export type CommandsExecutedOnVaults = Record< + string, + { + success: null | boolean + duration: string + error: null | Error | string + } +> +export type CommandOnVault = (_vault: Vault, ..._args: string[]) => string +export type ReservedVariables = { + [key: string]: CommandOnVault | undefined +} + +export type InitFlags = Record + +export interface StagePlugin { + repo: string + version: string +} + +export interface PrunedPlugin { + id: string +} + +export type StagedPlugins = Array + +export type InstalledPlugins = Record> + +export type PruneFlags = Record + +export interface PrunePluginVaultOpts { + vault: Vault + config: Config +} + +export interface InstallFlags { + enable: boolean +} + +export interface InstallArgs { + pluginId?: string +} + +export interface InstallPluginVaultOpts { + vault: Vault + config: Config +} + +export interface UninstallArgs { + pluginId?: string +} + +export type UninstallFlags = Record + +export interface UninstallPluginVaultOpts { + vault: Vault + config: Config +} + +export interface StatsFlags { + output: string +} + +export interface RunFlags { + output?: string + unescape?: boolean + async?: boolean + silent?: boolean + runFromVaultDirectoryAsWorkDir: boolean +} + +export interface CommandArgs { + [key: string]: string +} + +export interface ExecuteCustomCommandResult { + stdout: string + stderr: string + error: ExecException | null +} + +export interface ExecuteCustomCommandCallbackResult { + sortedTaskExecutedOnVaults: CommandsExecutedOnVaults +} + +export type StatsCommandCallbackResult = CommandCallbackBaseResult & { + totalStats?: { + totalVaults: number + totalPlugins: number + } + installedPlugins?: InstalledPlugins +} + +export interface CommandVault { + vault: Vault + command: CommandArgs['command'] +} + +export type CommandCallbackBaseResult = { + success: boolean + error?: Error +} + +export type InitCommandCallbackResult = CommandCallbackBaseResult + +export type InitCommandCallback = (_result: InitCommandCallbackResult) => void + +export interface InstallCommandIteratorResult { + installedPlugins: StagedPlugins + failedPlugins: StagedPlugins +} + +export type InstallCommandIterator = ( + _result: InstallCommandIteratorResult, +) => void + +export type InstallCommandCallbackResult = CommandCallbackBaseResult + +export type InstallCommandCallback = ( + _result: InstallCommandCallbackResult, +) => void + +export interface PruneCommandIteratorResult { + prunedPlugins: Array +} + +export type PruneCommandIterator = (_result: PruneCommandIteratorResult) => void + +export type PruneCommandCallbackResult = CommandCallbackBaseResult + +export type PruneCommandCallback = (_result: PruneCommandCallbackResult) => void diff --git a/src/reset.d.ts b/src/types/reset.d.ts similarity index 100% rename from src/reset.d.ts rename to src/types/reset.d.ts diff --git a/src/utils/command.ts b/src/utils/command.ts new file mode 100644 index 0000000..83f2cb2 --- /dev/null +++ b/src/utils/command.ts @@ -0,0 +1,15 @@ +import { ExitPromptError } from '@inquirer/core' +import { handle } from '@oclif/core' +import { logger } from './logger' + +export const handlerCommandError = (error: unknown) => { + if (process.env.CI) { + throw error + } + if (error instanceof ExitPromptError) { + logger.debug('Exit prompt error:', { error }) + } else if (error instanceof Error) { + logger.debug('An error occurred while installation:', { error }) + handle(error) + } +} diff --git a/src/utils/constants.ts b/src/utils/constants.ts index dfe1904..6b84924 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -1,13 +1,10 @@ -import { homedir } from 'os' -import path from 'path' import { getVaultName, getVaultPath } from '../providers/vaults' -import { ReservedVariables } from '../types' +import { ReservedVariables } from '../types/commands' export const OVM_CONFIG_FILENAME = 'ovm.json' -export const DEFAULT_CONFIG_PATH = path.join(homedir(), OVM_CONFIG_FILENAME) export const VAULTS_PATH_FLAG_DESCRIPTION = '[default: detect from Obsidian config] Path or Glob pattern of vaults to install plugins.' export const RESERVED_VARIABLES: ReservedVariables = { - 0: getVaultPath, - 1: getVaultName, + '0': getVaultPath, + '1': getVaultName, } diff --git a/src/utils/env.ts b/src/utils/env.ts new file mode 100644 index 0000000..bf9c556 --- /dev/null +++ b/src/utils/env.ts @@ -0,0 +1,3 @@ +export const isTestEnv = () => { + return typeof global.it === 'function' || process.env.CI === 'true' +} diff --git a/src/utils/testing.ts b/src/utils/testing.ts index 46f58e9..da5df70 100644 --- a/src/utils/testing.ts +++ b/src/utils/testing.ts @@ -1,43 +1,10 @@ -import { exec, ExecException } from 'child_process' +import { existsSync, writeFileSync } from 'fs' +import fse from 'fs-extra' import { rm } from 'fs/promises' import { platform, tmpdir } from 'os' import path from 'path' import { OVM_CONFIG_FILENAME } from './constants' -type CommandResult = { - stdout: string - stderr: string -} - -export const runCommand = async ( - command: string, - dev = false, -): Promise => { - return new Promise((resolve, reject) => { - const detectedPlatform = platform() - const runnerExt = detectedPlatform === 'win32' ? 'cmd' : 'js' - const runnerType = dev ? 'dev' : 'run' - const runnerFilePath = `${runnerType}.${runnerExt}` - const formattedCommand = - detectedPlatform === 'win32' - ? path.win32.normalize( - path.join( - __dirname, - '..', - '..', - `bin/${runnerFilePath} ${command}`, - ), - ) - : `./bin/${runnerFilePath} ${command}` - exec(formattedCommand, (error, stdout, stderr) => { - if (error) { - reject(error) - } - resolve({ stdout, stderr }) - }) - }) -} - export const getTmpConfigFilePath = () => { if (platform() === 'win32') { return path.win32.join(tmpdir(), OVM_CONFIG_FILENAME) @@ -47,5 +14,44 @@ export const getTmpConfigFilePath = () => { } export const destroyConfigMockFile = async (path: string) => { - return await rm(path, { force: true }) + const normalizedPath = path.normalize('NFC') + + if (normalizedPath && existsSync(normalizedPath)) { + await rm(normalizedPath, { force: true }) + } +} + +export const createTmpVault = async (vaultPath: string) => { + const normalizedPath = path.normalize(vaultPath) + const obsidianDir = path.resolve(normalizedPath, '.obsidian') + if (normalizedPath && !existsSync(normalizedPath)) { + fse.mkdirpSync(obsidianDir) + } + + const normalizedVaultCommunityPluginsPath = path.resolve( + obsidianDir, + 'community-plugins.json', + ) + + if (!existsSync(normalizedVaultCommunityPluginsPath)) { + writeFileSync(normalizedVaultCommunityPluginsPath, JSON.stringify([])) + } + + return normalizedPath +} + +export const tmpConfigFilePath = getTmpConfigFilePath() +export const testVaultName = 'test' +export const testVaultPath = `${tmpdir()}/${testVaultName}` +export const testCommonFlags = { + debug: false, + timestamp: false, + config: tmpConfigFilePath, +} + +export const destroyVault = async (vaultPath: string) => { + const normalizedPath = path.normalize(vaultPath) + if (normalizedPath && existsSync(normalizedPath)) { + await rm(normalizedPath, { recursive: true, force: true }) + } } diff --git a/src/utils/transformer.ts b/src/utils/transformer.ts new file mode 100644 index 0000000..35864e2 --- /dev/null +++ b/src/utils/transformer.ts @@ -0,0 +1,14 @@ +import { z } from 'zod' + +export const stringToJSONSchema = z.string().pipe( + z.preprocess( + (input) => { + try { + return JSON.parse(input as string) + } catch { + throw new Error('Invalid JSON format') + } + }, + z.union([z.object({}).passthrough(), z.array(z.unknown())]), + ), +)