From 6a3cf42a12f4a8f61dd8b1ceb2d2443f1e9c7cdc Mon Sep 17 00:00:00 2001 From: Anupam Bista Date: Mon, 16 Sep 2024 22:10:57 +0545 Subject: [PATCH 01/17] Refactored install command which copy the content from sample yaml file and create yaml file --- index.ts | 2 +- src/commands/install.ts | 64 +++++++++++++++++++++++++++++------------ 2 files changed, 46 insertions(+), 20 deletions(-) diff --git a/index.ts b/index.ts index 9d02ffd..b523235 100644 --- a/index.ts +++ b/index.ts @@ -15,7 +15,7 @@ program .description( "Check required commands, create .env file and install dependencies" ) - .action(install); + .action(async () => await install()); program .command("update-backup-destination") diff --git a/src/commands/install.ts b/src/commands/install.ts index 71652f7..6b12d38 100644 --- a/src/commands/install.ts +++ b/src/commands/install.ts @@ -1,11 +1,9 @@ -import { intro, outro } from "@clack/prompts"; +import { intro, confirm, spinner } from "@clack/prompts"; import * as fs from "fs"; import process from "process"; -import backUpDest from "./backUpDest"; -import { checkCommands } from "./commandChecker"; import chalk from "chalk"; -import notificationDest from "./notificationDest"; -import database from "./database"; +import path from "path"; +import { checkCommands } from "./commandChecker"; function centerText(text: string) { const terminalWidth = process.stdout.columns; @@ -22,10 +20,37 @@ function centerMultilineText(text: string) { .join("\n"); } +const createBackupdbeeYaml = () => { + // eslint-disable-next-line no-undef + const sourceFile = path.join(__dirname, "../../backupdbee.yaml.sample"); + // eslint-disable-next-line no-undef + const destinationFile = path.join(__dirname, "../../backupdbee.yaml"); + + const s = spinner(); + s.start("Creating backupdbee.yaml file"); + + fs.readFile(sourceFile, "utf8", (err, data) => { + if (err) { + console.error("Error reading the source file:", err); + process.exit(0); + } + + // Write the content to the destination file + fs.writeFile(destinationFile, data, (err) => { + if (err) { + s.stop(`Error writing to the destination file: ${err}`); + process.exit(0); + } else { + s.stop(`File copied successfully to ${destinationFile}`); + } + }); + }); +}; + const install = async () => { const multiLineMessage = ` Welcome to My Backupdbee Cli! -Using this cli you can manage your database backup and email notification! +Using this cli you can manage your database backup and notification! `; console.log(centerMultilineText(multiLineMessage)); @@ -35,20 +60,21 @@ Using this cli you can manage your database backup and email notification! intro(chalk.inverse("Installation")); try { - await backUpDest(); - await notificationDest(); - await database(); - outro(chalk.green("Installation successful!")); - } catch (err) { - console.log(chalk.red("Error occured while installing")); - console.log(chalk.red("Deleting .env file")); - //delete .env file from root folder - try { - fs.unlinkSync(".env"); - } catch (err) { - console.log(err); - console.log(chalk.red("Error occured while deleting .env file")); + // check if backupdbee.yaml file exists in root folder or not + if (!fs.existsSync("backupdbee.yaml")) { + createBackupdbeeYaml(); + } else { + const shouldContinue = await confirm({ + message: "Do you want to continue?", + initialValue: false, + }); + if (!shouldContinue) { + process.exit(0); + } else { + createBackupdbeeYaml(); + } } + } catch (err) { console.log(err); } }; From c60baa466cffec0a6bb9f51890f4b4333e44a793 Mon Sep 17 00:00:00 2001 From: Anupam Bista Date: Tue, 17 Sep 2024 08:32:04 +0545 Subject: [PATCH 02/17] configured vitepress for documentation and added db:list command --- .gitignore | 4 +- docs/.vitepress/config.mts | 44 +++++++++++++ docs/api-examples.md | 49 ++++++++++++++ docs/guide/getting-started.md | 28 ++++++++ docs/guide/what-is-backupdbee.md | 19 ++++++ docs/index.md | 25 +++++++ docs/markdown-examples.md | 85 ++++++++++++++++++++++++ index.ts | 13 ++-- package.json | 10 ++- src/commands/database.ts | 108 +++++-------------------------- src/commands/general.ts | 53 +++++++++++++++ src/commands/install.ts | 7 +- src/commands/notification.ts | 0 src/commands/utils.ts | 39 +++++++++++ 14 files changed, 375 insertions(+), 109 deletions(-) create mode 100644 docs/.vitepress/config.mts create mode 100644 docs/api-examples.md create mode 100644 docs/guide/getting-started.md create mode 100644 docs/guide/what-is-backupdbee.md create mode 100644 docs/index.md create mode 100644 docs/markdown-examples.md create mode 100644 src/commands/general.ts create mode 100644 src/commands/notification.ts create mode 100644 src/commands/utils.ts diff --git a/.gitignore b/.gitignore index b469280..fe380c4 100644 --- a/.gitignore +++ b/.gitignore @@ -14,4 +14,6 @@ limited_dump.sql tmp/ config.ts backupdbee.yaml -backupdbee.yml \ No newline at end of file +backupdbee.yml +docs/.vitepress/dist +docs/.vitepress/cache \ No newline at end of file diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts new file mode 100644 index 0000000..b56a0e7 --- /dev/null +++ b/docs/.vitepress/config.mts @@ -0,0 +1,44 @@ +import { defineConfig, type DefaultTheme } from "vitepress"; + +// https://vitepress.dev/reference/site-config +export default defineConfig({ + title: "BackupDBee", + description: "Automatic CLI Based Advance DB Backup System", + themeConfig: { + // https://vitepress.dev/reference/default-theme-config + nav: [ + { text: "Home", link: "/" }, + { + text: "Guide", + link: "/guide/what-is-backupdbee", + activeMatch: "/guide/", + }, + ], + + sidebar: { + "/guide/": { base: "/guide/", items: sidebarGuide() }, + }, + + socialLinks: [ + { icon: "github", link: "https://github.com/28softwares/BackupDBee" }, + ], + }, +}); + +function sidebarGuide(): DefaultTheme.SidebarItem[] { + return [ + { + text: "Introduction", + collapsed: false, + items: [ + { text: "What is backupdbee?", link: "what-is-backupdbee" }, + { text: "Getting Started", link: "getting-started" }, + ], + }, + { + text: "Cli Commands", + collapsed: false, + items: [{ text: "db:list", link: "markdown" }], + }, + ]; +} diff --git a/docs/api-examples.md b/docs/api-examples.md new file mode 100644 index 0000000..6bd8bb5 --- /dev/null +++ b/docs/api-examples.md @@ -0,0 +1,49 @@ +--- +outline: deep +--- + +# Runtime API Examples + +This page demonstrates usage of some of the runtime APIs provided by VitePress. + +The main `useData()` API can be used to access site, theme, and page data for the current page. It works in both `.md` and `.vue` files: + +```md + + +## Results + +### Theme Data +
{{ theme }}
+ +### Page Data +
{{ page }}
+ +### Page Frontmatter +
{{ frontmatter }}
+``` + + + +## Results + +### Theme Data +
{{ theme }}
+ +### Page Data +
{{ page }}
+ +### Page Frontmatter +
{{ frontmatter }}
+ +## More + +Check out the documentation for the [full list of runtime APIs](https://vitepress.dev/reference/runtime-api#usedata). diff --git a/docs/guide/getting-started.md b/docs/guide/getting-started.md new file mode 100644 index 0000000..083d92d --- /dev/null +++ b/docs/guide/getting-started.md @@ -0,0 +1,28 @@ +# Getting Started + +## Installation + +### Prerequisites + +- [Node.js](https://nodejs.org/) version 18 or higher. +- Terminal for accessing VitePress via its command line interface (CLI). +- [zip] +- [pg_dump] +- [mysqldump] + +## Clone the project 📦 + +``` +git clone https://github.com/28softwares/backupdbee.git +cd backupdbee +``` + +### Initial Setup + +```bash +ts-node index.ts install #this creates backupdbee.yaml +``` + +### Configurations ⚒️ + +According to your requirements, you can configure from `backupdbee.yaml` file or using cli diff --git a/docs/guide/what-is-backupdbee.md b/docs/guide/what-is-backupdbee.md new file mode 100644 index 0000000..dc3fdf7 --- /dev/null +++ b/docs/guide/what-is-backupdbee.md @@ -0,0 +1,19 @@ +# What is BackupDBee 🐝? + +BackupDBee is a automatic CLI based advance DB backup system. It helps to effortlessly manage your database backups at one go. This easy-to-use tool supports MySQL & PostgreSQL allowing you to back up multiple databases at once. + +
+ +Just want to try it out? Skip to the [Quickstart](./getting-started). + +
+ +#### Key features: 🚀 + +✅ Multiple Database Support: Seamlessly back up MySQL & PostgreSQL in one go. (Note: For now we support MySQL and PostgreSQl.) + +✅ Support for GMAIL,S3 BUCKET for storing the backup. (Backups are transfered in zip format, reducing backup size.) + +✅ Notify on Discord or Slack or Telegram for successful and failed backups. + +✅ Automated Backups: Schedule and automate backups (using crons or pm2) to ensure your data is always protected without manual intervention. diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..146b8eb --- /dev/null +++ b/docs/index.md @@ -0,0 +1,25 @@ +--- +# https://vitepress.dev/reference/default-theme-home-page +layout: home + +hero: + name: "BackupDBee" + text: "Automatic CLI Based Advance DB Backup System" + tagline: My great project tagline + actions: + - theme: brand + text: Markdown Examples + link: /markdown-examples + - theme: alt + text: API Examples + link: /api-examples + +features: + - title: Feature A + details: Lorem ipsum dolor sit amet, consectetur adipiscing elit + - title: Feature B + details: Lorem ipsum dolor sit amet, consectetur adipiscing elit + - title: Feature C + details: Lorem ipsum dolor sit amet, consectetur adipiscing elit +--- + diff --git a/docs/markdown-examples.md b/docs/markdown-examples.md new file mode 100644 index 0000000..f9258a5 --- /dev/null +++ b/docs/markdown-examples.md @@ -0,0 +1,85 @@ +# Markdown Extension Examples + +This page demonstrates some of the built-in markdown extensions provided by VitePress. + +## Syntax Highlighting + +VitePress provides Syntax Highlighting powered by [Shiki](https://github.com/shikijs/shiki), with additional features like line-highlighting: + +**Input** + +````md +```js{4} +export default { + data () { + return { + msg: 'Highlighted!' + } + } +} +``` +```` + +**Output** + +```js{4} +export default { + data () { + return { + msg: 'Highlighted!' + } + } +} +``` + +## Custom Containers + +**Input** + +```md +::: info +This is an info box. +::: + +::: tip +This is a tip. +::: + +::: warning +This is a warning. +::: + +::: danger +This is a dangerous warning. +::: + +::: details +This is a details block. +::: +``` + +**Output** + +::: info +This is an info box. +::: + +::: tip +This is a tip. +::: + +::: warning +This is a warning. +::: + +::: danger +This is a dangerous warning. +::: + +::: details +This is a details block. +::: + +## More + +Check out the documentation for the [full list of markdown extensions](https://vitepress.dev/guide/markdown). diff --git a/index.ts b/index.ts index b523235..8fc5f68 100644 --- a/index.ts +++ b/index.ts @@ -4,7 +4,7 @@ import install from "./src/commands/install"; import backUpDest from "./src/commands/backUpDest"; import updateHelper from "./src/commands/updateHelper"; import notificationDest from "./src/commands/notificationDest"; -import database from "./src/commands/database"; +import { dbList } from "./src/commands/database"; const program = new Command(); program.version("1.0.0").description("AutoBackup DB CLI"); @@ -17,6 +17,11 @@ program ) .action(async () => await install()); +program + .command("db:list") + .description("List all databases and show the total count") + .action(dbList); + program .command("update-backup-destination") .alias("ubd") @@ -33,10 +38,4 @@ program async () => await updateHelper("Update notification", notificationDest) ); -program - .command("add-database") - .alias("ad") - .description("Add database") - .action(async () => await updateHelper("Add database", database)); - program.parse(process.argv); diff --git a/package.json b/package.json index a61fde5..085a34a 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,10 @@ "test": "echo \"Error: no test specified\" && exit 1", "lint": "eslint \"**/*.{ts,tsx}\"", "start": "ts-node ./src/index.ts", - "prepare": "husky" + "prepare": "husky", + "docs:dev": "vitepress dev docs", + "docs:build": "vitepress build docs", + "docs:preview": "vitepress preview docs" }, "keywords": [], "author": "", @@ -34,7 +37,8 @@ "husky": "^9.1.5", "ts-node-dev": "^2.0.0", "typescript": "^5.5.4", - "typescript-eslint": "^8.1.0" + "typescript-eslint": "^8.1.0", + "vitepress": "^1.3.4" }, "packageManager": "pnpm@9.1.4+sha512.9df9cf27c91715646c7d675d1c9c8e41f6fce88246f1318c1aa6a1ed1aeb3c4f032fcdf4ba63cc69c4fe6d634279176b5358727d8f2cc1e65b65f43ce2f8bfb0" -} +} \ No newline at end of file diff --git a/src/commands/database.ts b/src/commands/database.ts index 670e2aa..d26681e 100644 --- a/src/commands/database.ts +++ b/src/commands/database.ts @@ -1,96 +1,20 @@ -import { isCancel, select, text, confirm } from "@clack/prompts"; -import process from "process"; -import * as fs from "fs"; -import * as path from "path"; -import { promptWithCancel } from "./promptWithCancel"; - -type Config = { - dbType: string | symbol; - host?: string | symbol; - username?: string | symbol; - password?: string | symbol; - dbname?: string | symbol; - port?: string | symbol; -}; - -const database = async () => { - let wantToAddDatabase = true; - do { - const config: Config = { - dbType: await promptWithCancel(select, { - message: "Choose database type", - options: [ - { - name: "Postgres", - value: "POSTGRES", - }, - { - name: "MySQL", - value: "MYSQL", - }, - ], - initialValue: "POSTGRES", - }), - }; - - if (isCancel(config.dbType)) { - console.log("Operation cancelled"); - process.exit(0); - } - - Object.assign(config, { - host: await text({ message: "Enter db host" }), - username: await text({ message: "Enter db username" }), - password: await text({ message: "Enter db password" }), - dbname: await text({ message: "Enter db name" }), - port: await text({ message: "Enter db port" }), +import { loadConfig } from "./utils"; +import { Database } from "../@types/config"; +import chalk from "chalk"; + +export const dbList = () => { + const config = loadConfig(); + console.log("Database List"); + const databases = config.databases; + if (databases && databases.length > 0) { + databases.forEach((db: Database, index: number) => { + console.log(`${index + 1}. ${db.name}`); }); - // Construct the new entry for the dbConfig array - const newEntry = ` - { - host: "${String(config.host)}", - db_name: "${String(config.dbname)}", - user: "${String(config.username)}", - password: "${String(config.password)}", - type: "${config.dbType.toLowerCase()}", - port: ${Number(config.port)} - }, - `; - - // eslint-disable-next-line no-undef - const dbConfigFile = path.join(__dirname, "../../config.ts"); // Adjust path to the root folder - - if (!fs.existsSync(dbConfigFile)) { - // If it doesn't exist, create a new one with the proper structure - const fileContent = ` - import { ConfigType } from "./src/@types/types"; - - const dbConfig: ConfigType[] = [ - ${newEntry} - // add multiple databases here - ]; - - export default dbConfig; - `; - - fs.writeFileSync(dbConfigFile, fileContent); - } else { - // If it exists, append the new config entry before the comment - const fileContent = fs.readFileSync(dbConfigFile, "utf-8"); - const updatedContent = fileContent.replace( - "// add multiple databases here", - `${newEntry} // add multiple databases here` - ); - fs.writeFileSync(dbConfigFile, updatedContent); - } - wantToAddDatabase = Boolean( - await confirm({ - message: "Do you want to add another database?", - initialValue: true, - }) + console.log( + `\n${chalk.yellow("Total databases:")} ${chalk.magenta(databases.length)}` ); - } while (wantToAddDatabase); + } else { + console.log(chalk.red("No databases found in configuration.")); + } }; - -export default database; diff --git a/src/commands/general.ts b/src/commands/general.ts new file mode 100644 index 0000000..6de2a1b --- /dev/null +++ b/src/commands/general.ts @@ -0,0 +1,53 @@ +import { text } from "@clack/prompts"; + +async function updateBackupLocation(current: string) { + const value = await text({ + message: "Enter new backup location (current: " + current + ")", + }); + return value as string; +} + +async function updateLogLevel(current: string) { + const value = await text({ + message: "Enter new log level (current: " + current + ")", + }); + return value as string; +} + +async function updateRetentionPolicyDays(current: number) { + const value = await text({ + message: "Enter new retention policy days (current: " + current + ")", + }); + return parseInt(value as string); +} + +async function updateBackupSchedule(current: string) { + const value = await text({ + message: "Enter new backup schedule (current: " + current + ")", + }); + return value as string; +} + +export const updateGeneralSetting = async ( + key: string, + currentValue: string | number +) => { + let newValue: string | number; + switch (key) { + case "backup_location": + newValue = await updateBackupLocation(currentValue as string); + break; + case "log_level": + newValue = await updateLogLevel(currentValue as string); + break; + case "retention_policy_days": + newValue = await updateRetentionPolicyDays(currentValue as number); + break; + case "backup_schedule": + newValue = await updateBackupSchedule(currentValue as string); + break; + default: + throw new Error("Invalid setting key"); + } + console.log(`${key} updated to: ${newValue}`); +}; diff --git a/src/commands/install.ts b/src/commands/install.ts index 6b12d38..d146fe9 100644 --- a/src/commands/install.ts +++ b/src/commands/install.ts @@ -2,8 +2,8 @@ import { intro, confirm, spinner } from "@clack/prompts"; import * as fs from "fs"; import process from "process"; import chalk from "chalk"; -import path from "path"; import { checkCommands } from "./commandChecker"; +import { destinationFile, sourceFile } from "./utils"; function centerText(text: string) { const terminalWidth = process.stdout.columns; @@ -21,11 +21,6 @@ function centerMultilineText(text: string) { } const createBackupdbeeYaml = () => { - // eslint-disable-next-line no-undef - const sourceFile = path.join(__dirname, "../../backupdbee.yaml.sample"); - // eslint-disable-next-line no-undef - const destinationFile = path.join(__dirname, "../../backupdbee.yaml"); - const s = spinner(); s.start("Creating backupdbee.yaml file"); diff --git a/src/commands/notification.ts b/src/commands/notification.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/commands/utils.ts b/src/commands/utils.ts new file mode 100644 index 0000000..1dc6755 --- /dev/null +++ b/src/commands/utils.ts @@ -0,0 +1,39 @@ +import * as fs from "fs"; +import path from "path"; +import * as yaml from "yaml"; +import { DataBeeConfig } from "../@types/config"; +import { isCancel } from "@clack/prompts"; +import process from "process"; +import chalk from "chalk"; + +// eslint-disable-next-line no-undef +export const sourceFile = path.join(__dirname, "../../backupdbee.yaml.sample"); +// eslint-disable-next-line no-undef +export const destinationFile = path.join(__dirname, "../../backupdbee.yaml"); + +export function loadConfig() { + try { + const file = fs.readFileSync(destinationFile, "utf8"); + return yaml.parse(file); + } catch (error) { + console.error(chalk.red("Error loading configuration file:"), error); + process.exit(1); + } +} + +// Save YAML config file +export function saveYamlConfig(config: DataBeeConfig) { + const yamlStr = yaml.stringify(config); + fs.writeFileSync(destinationFile, yamlStr, "utf8"); + console.log("Configuration saved to config.yaml"); +} + +// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type +export const promptWithCancel = async (promptFn: Function, options: object) => { + const result = await promptFn(options); + if (isCancel(result)) { + console.log("Operation cancelled"); + process.exit(0); + } + return result; +}; From c30e5909571cf3955caa112b1fe1e56e0cadd7fe Mon Sep 17 00:00:00 2001 From: Anupam Bista Date: Tue, 17 Sep 2024 09:15:10 +0545 Subject: [PATCH 03/17] added db:backup command with --name flag --- docs/.vitepress/config.mts | 2 +- docs/guide/cli/db-list.md | 11 +++++++++++ index.ts | 27 ++++++++----------------- package.json | 2 +- src/commands/database.ts | 40 +++++++++++++++++++++++++++++++++++++- src/index.ts | 2 +- 6 files changed, 61 insertions(+), 23 deletions(-) create mode 100644 docs/guide/cli/db-list.md diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts index b56a0e7..ae69932 100644 --- a/docs/.vitepress/config.mts +++ b/docs/.vitepress/config.mts @@ -38,7 +38,7 @@ function sidebarGuide(): DefaultTheme.SidebarItem[] { { text: "Cli Commands", collapsed: false, - items: [{ text: "db:list", link: "markdown" }], + items: [{ text: "db:list", link: "cli/db-list" }], }, ]; } diff --git a/docs/guide/cli/db-list.md b/docs/guide/cli/db-list.md new file mode 100644 index 0000000..76fe174 --- /dev/null +++ b/docs/guide/cli/db-list.md @@ -0,0 +1,11 @@ +# List Databases Command + +The `db:list` command lists all the databases defined in the YAML configuration file and shows the total count of databases. + +## Usage + +Run the following command in your terminal: + +```bash +ts-node index.ts db:list +``` diff --git a/index.ts b/index.ts index 8fc5f68..0e2a2eb 100644 --- a/index.ts +++ b/index.ts @@ -1,13 +1,10 @@ import process from "process"; import { Command } from "commander"; import install from "./src/commands/install"; -import backUpDest from "./src/commands/backUpDest"; -import updateHelper from "./src/commands/updateHelper"; -import notificationDest from "./src/commands/notificationDest"; -import { dbList } from "./src/commands/database"; +import { dbBackup, dbList } from "./src/commands/database"; const program = new Command(); -program.version("1.0.0").description("AutoBackup DB CLI"); +program.version("1.0.0").description("BackupDBee CLI"); program .command("install") @@ -23,19 +20,11 @@ program .action(dbList); program - .command("update-backup-destination") - .alias("ubd") - .description("Update backup destinations") - .action( - async () => await updateHelper("Update backup destinations", backUpDest) - ); - -program - .command("update-notification") - .alias("un") - .description("Update notification") - .action( - async () => await updateHelper("Update notification", notificationDest) - ); + .command("db:backup") + .description("Backup all databases or a specific one with --name flag") + .option("--name ", "Name of the database to backup") + .action((options: { name?: string }) => { + dbBackup(options); + }); program.parse(process.argv); diff --git a/package.json b/package.json index 085a34a..4ec8db4 100644 --- a/package.json +++ b/package.json @@ -41,4 +41,4 @@ "vitepress": "^1.3.4" }, "packageManager": "pnpm@9.1.4+sha512.9df9cf27c91715646c7d675d1c9c8e41f6fce88246f1318c1aa6a1ed1aeb3c4f032fcdf4ba63cc69c4fe6d634279176b5358727d8f2cc1e65b65f43ce2f8bfb0" -} \ No newline at end of file +} diff --git a/src/commands/database.ts b/src/commands/database.ts index d26681e..1834f7f 100644 --- a/src/commands/database.ts +++ b/src/commands/database.ts @@ -1,6 +1,10 @@ import { loadConfig } from "./utils"; -import { Database } from "../@types/config"; +import { Database, DataBeeConfig } from "../@types/config"; import chalk from "chalk"; +import { intro, outro } from "@clack/prompts"; +import { main } from ".."; +import { setupDBConfig, setupDestinations, setupNotifications } from "../setup"; +import process from "process"; export const dbList = () => { const config = loadConfig(); @@ -18,3 +22,37 @@ export const dbList = () => { console.log(chalk.red("No databases found in configuration.")); } }; +const setupMainFunction = async (config: DataBeeConfig) => { + const dbConfig = setupDBConfig(config); + const destinations = setupDestinations(config); + const notifications = setupNotifications(config); + await main(dbConfig, destinations, notifications); +}; + +export const dbBackup = async (options: { name?: string }) => { + const config = loadConfig(); + const databases = config.databases; + + try { + if (options.name) { + // Backup specific database + const db = databases.find((db: Database) => db.name === options.name); + // update config with the specific database + if (db) { + config.databases = [db]; + intro(chalk.blueBright(`Backing up database: ${options.name}`)); + await setupMainFunction(config); // Call main function to backup specific database + } else { + console.log(chalk.red(`Database "${options.name}" not found.`)); + process.exit(1); + } + } else { + // Backup all databases + intro(chalk.blueBright("Backing up all databases...")); + await setupMainFunction(config); // Call main function to backup all databases + } + } catch (e) { + console.log(e); + outro(chalk.red("Backup failed.")); + } +}; diff --git a/src/index.ts b/src/index.ts index 8cc9d84..16f0c0c 100755 --- a/src/index.ts +++ b/src/index.ts @@ -18,7 +18,7 @@ import { // Promisify exec to use with async/await export const execAsync = promisify(exec); -const main = async ( +export const main = async ( configs: ConfigType[], destinations: Destinations, notifications: Notifications From d8cf70093770ed6d0d332bfcc94401dd74d2fd78 Mon Sep 17 00:00:00 2001 From: Anupam Bista Date: Tue, 17 Sep 2024 10:18:18 +0545 Subject: [PATCH 04/17] removed unused files and directly calling main function from index.ts file --- package.json | 2 +- src/commands/backUpDest.ts | 66 -------------------------------- src/commands/commandChecker.ts | 6 +++ src/commands/database.ts | 32 +++++++++++++--- src/commands/envWriter.ts | 60 ----------------------------- src/commands/general.ts | 53 ------------------------- src/commands/install.ts | 40 ++++++++----------- src/commands/notificationDest.ts | 54 -------------------------- src/commands/updateHelper.ts | 21 ---------- src/commands/utils.ts | 39 ------------------- src/index.ts | 24 +----------- src/utils/cli.utils.ts | 15 ++++++++ 12 files changed, 68 insertions(+), 344 deletions(-) delete mode 100644 src/commands/backUpDest.ts delete mode 100644 src/commands/envWriter.ts delete mode 100644 src/commands/general.ts delete mode 100644 src/commands/notificationDest.ts delete mode 100644 src/commands/updateHelper.ts delete mode 100644 src/commands/utils.ts create mode 100644 src/utils/cli.utils.ts diff --git a/package.json b/package.json index 4ec8db4..561032a 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "lint": "eslint \"**/*.{ts,tsx}\"", - "start": "ts-node ./src/index.ts", + "start": "ts-node index.ts db:backup", "prepare": "husky", "docs:dev": "vitepress dev docs", "docs:build": "vitepress build docs", diff --git a/src/commands/backUpDest.ts b/src/commands/backUpDest.ts deleted file mode 100644 index 55c09b0..0000000 --- a/src/commands/backUpDest.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { select, text } from "@clack/prompts"; -import { saveConfigToEnv } from "./envWriter"; -import { promptWithCancel } from "./promptWithCancel"; - -type Config = { - backupDestination: string | symbol; - mailUsername?: string | symbol; - mailPassword?: string | symbol; - bucketName?: string | symbol; - accesskey?: string | symbol; - secretKey?: string | symbol; - region?: string | symbol; -}; - -const backUpDest = async () => { - const config: Config = { - backupDestination: await promptWithCancel(select, { - message: "Select a backup destination", - options: [ - { label: "Gmail", value: "GMAIL" }, - { label: "Aws s3 Bucket", value: "S3_BUCKET" }, - { label: "None", value: "NONE" }, - ], - initialValue: "GMAIL", - }), - }; - - if (config.backupDestination === "GMAIL") { - Object.assign(config, { - mailUsername: await promptWithCancel(text, { - message: "Enter your Gmail", - }), - mailPassword: await promptWithCancel(text, { - message: "Enter Gmail password", - }), - }); - } else if (config.backupDestination === "S3_BUCKET") { - Object.assign(config, { - bucketName: await promptWithCancel(text, { - message: "Enter AWS S3 bucket name", - }), - accesskey: await promptWithCancel(text, { - message: "Enter AWS S3 access key", - }), - secretKey: await promptWithCancel(text, { - message: "Enter AWS S3 secret key", - }), - region: await promptWithCancel(text, { message: "Enter AWS S3 region" }), - }); - } - - // Only pass defined values to the env writer - const envConfig = { - BACKUP_DEST: config.backupDestination, - ...(config.mailUsername && { MAIL_USER: config.mailUsername }), - ...(config.mailPassword && { MAIL_PASSWORD: config.mailPassword }), - ...(config.bucketName && { AWS_S3_BUCKET_NAME: config.bucketName }), - ...(config.accesskey && { AWS_ACCESS_KEY_ID: config.accesskey }), - ...(config.secretKey && { AWS_SECRET_ACCESS_KEY: config.secretKey }), - ...(config.region && { AWS_REGION: config.region }), - }; - - saveConfigToEnv(envConfig); -}; - -export default backUpDest; diff --git a/src/commands/commandChecker.ts b/src/commands/commandChecker.ts index 16c7661..869c70d 100644 --- a/src/commands/commandChecker.ts +++ b/src/commands/commandChecker.ts @@ -2,6 +2,12 @@ import { execSync } from "child_process"; import process from "process"; import chalk from "chalk"; +/** + * Checks if the required commands are available. + * + * @param commands - An array of commands to check. + * @returns void + */ export const checkCommands = (commands: string[]) => { console.log(chalk.cyan("Checking required commands...")); for (const command of commands) { diff --git a/src/commands/database.ts b/src/commands/database.ts index 1834f7f..0b12cef 100644 --- a/src/commands/database.ts +++ b/src/commands/database.ts @@ -1,13 +1,16 @@ -import { loadConfig } from "./utils"; import { Database, DataBeeConfig } from "../@types/config"; import chalk from "chalk"; import { intro, outro } from "@clack/prompts"; -import { main } from ".."; import { setupDBConfig, setupDestinations, setupNotifications } from "../setup"; import process from "process"; +import { main } from ".."; +import { parseConfigFile } from "../utils/cli.utils"; +/** + * Retrieves the list of databases from the configuration and logs them to the console. + */ export const dbList = () => { - const config = loadConfig(); + const config = parseConfigFile(); console.log("Database List"); const databases = config.databases; if (databases && databases.length > 0) { @@ -22,6 +25,13 @@ export const dbList = () => { console.log(chalk.red("No databases found in configuration.")); } }; + +/** + * Sets up the main function for performing database operations. + * + * @param config - The configuration object for setting up the main function. + * @returns A Promise that resolves when the main function completes. + */ const setupMainFunction = async (config: DataBeeConfig) => { const dbConfig = setupDBConfig(config); const destinations = setupDestinations(config); @@ -29,13 +39,25 @@ const setupMainFunction = async (config: DataBeeConfig) => { await main(dbConfig, destinations, notifications); }; +/** + * Performs a database backup. + * + * @param options - An optional object containing the name of the specific database to backup. + * @param options.name - The name of the specific database to backup. + * + * @remarks + * If the `options.name` parameter is provided, the function will backup only the specified database. + * If the `options.name` parameter is not provided, the function will backup all databases. + * + * @throws {Error} If the backup fails. + */ export const dbBackup = async (options: { name?: string }) => { - const config = loadConfig(); + const config = parseConfigFile(); const databases = config.databases; try { if (options.name) { - // Backup specific database + // select specific database const db = databases.find((db: Database) => db.name === options.name); // update config with the specific database if (db) { diff --git a/src/commands/envWriter.ts b/src/commands/envWriter.ts deleted file mode 100644 index 2d861c3..0000000 --- a/src/commands/envWriter.ts +++ /dev/null @@ -1,60 +0,0 @@ -import fs from "fs"; -import path from "path"; - -const getProjectRoot = () => { - // eslint-disable-next-line no-undef - return path.resolve(__dirname, "../../"); // Adjust this as necessary if your project root is further up -}; -// Utility function to update or append environment variables -export const updateEnv = (key: string, value: string) => { - try { - const projectRoot = getProjectRoot(); - const envPath = path.join(projectRoot, ".env"); - let envContent = ""; - - // Check if .env file exists - if (fs.existsSync(envPath)) { - envContent = fs.readFileSync(envPath, { encoding: "utf8" }); - - const envLines = envContent.split("\n"); - let found = false; - - // Loop through each line to find the key and update its value - const updatedLines = envLines.map((line) => { - const [currentKey] = line.split("="); - - // If the key is found, replace the value - if (currentKey === key) { - found = true; - return `${key}=${value}`; - } - return line; - }); - - // If the key was not found, append the key-value pair to the end - if (!found) { - updatedLines.push(`${key}=${value}`); - } - - envContent = updatedLines.join("\n"); - } else { - // If the .env file does not exist, create it with the new key-value pair - envContent = `${key}=${value}\n`; - } - - // Write the updated content back to the .env file - fs.writeFileSync(envPath, envContent.trim(), { encoding: "utf8" }); - } catch (error) { - console.log(error); - } -}; - -export const saveConfigToEnv = async (config: { - [key: string]: string | symbol; -}) => { - for (const [key, value] of Object.entries(config)) { - if (typeof value === "string" && value !== "") { - updateEnv(key, value); - } - } -}; diff --git a/src/commands/general.ts b/src/commands/general.ts deleted file mode 100644 index 6de2a1b..0000000 --- a/src/commands/general.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { text } from "@clack/prompts"; - -async function updateBackupLocation(current: string) { - const value = await text({ - message: "Enter new backup location (current: " + current + ")", - }); - return value as string; -} - -async function updateLogLevel(current: string) { - const value = await text({ - message: "Enter new log level (current: " + current + ")", - }); - return value as string; -} - -async function updateRetentionPolicyDays(current: number) { - const value = await text({ - message: "Enter new retention policy days (current: " + current + ")", - }); - return parseInt(value as string); -} - -async function updateBackupSchedule(current: string) { - const value = await text({ - message: "Enter new backup schedule (current: " + current + ")", - }); - return value as string; -} - -export const updateGeneralSetting = async ( - key: string, - currentValue: string | number -) => { - let newValue: string | number; - switch (key) { - case "backup_location": - newValue = await updateBackupLocation(currentValue as string); - break; - case "log_level": - newValue = await updateLogLevel(currentValue as string); - break; - case "retention_policy_days": - newValue = await updateRetentionPolicyDays(currentValue as number); - break; - case "backup_schedule": - newValue = await updateBackupSchedule(currentValue as string); - break; - default: - throw new Error("Invalid setting key"); - } - console.log(`${key} updated to: ${newValue}`); -}; diff --git a/src/commands/install.ts b/src/commands/install.ts index d146fe9..660c3ef 100644 --- a/src/commands/install.ts +++ b/src/commands/install.ts @@ -3,23 +3,18 @@ import * as fs from "fs"; import process from "process"; import chalk from "chalk"; import { checkCommands } from "./commandChecker"; -import { destinationFile, sourceFile } from "./utils"; - -function centerText(text: string) { - const terminalWidth = process.stdout.columns; - const textLength = text.length; - const padding = Math.max(0, Math.floor((terminalWidth - textLength) / 2)); - const paddedText = " ".repeat(padding) + text; - return paddedText; -} - -function centerMultilineText(text: string) { - return text - .split("\n") - .map((line) => centerText(line)) - .join("\n"); -} +import { destinationFile, sourceFile } from "../utils/cli.utils"; +/** + * Creates a backupdbee.yaml file by reading the content from a source file and writing it to a destination file. + * + * @remarks + * This function uses the `fs.readFile` and `fs.writeFile` methods to read and write files respectively. + * It also utilizes a spinner to display the progress of the operation. + * + * @param sourceFile - The path to the source file. + * @param destinationFile - The path to the destination file. + */ const createBackupdbeeYaml = () => { const s = spinner(); s.start("Creating backupdbee.yaml file"); @@ -42,13 +37,12 @@ const createBackupdbeeYaml = () => { }); }; -const install = async () => { - const multiLineMessage = ` -Welcome to My Backupdbee Cli! -Using this cli you can manage your database backup and notification! -`; - - console.log(centerMultilineText(multiLineMessage)); +/** + * Checks the necessary dependencies and create backupdbee.yaml file. + * + * @returns {Promise} A promise that resolves once the installation is complete. + */ +const install = async (): Promise => { const commands = ["zip", "pg_dump", "mysqldump", "pnpm", "node"]; checkCommands(commands); console.log(); diff --git a/src/commands/notificationDest.ts b/src/commands/notificationDest.ts deleted file mode 100644 index 0bf7507..0000000 --- a/src/commands/notificationDest.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { select, text } from "@clack/prompts"; -import { saveConfigToEnv } from "./envWriter"; -import { promptWithCancel } from "./promptWithCancel"; - -type Config = { - notificationDestination: string | symbol; - discordWebhookUrl?: string | symbol; - slackWebhookUrl?: string | symbol; -}; - -const notificationDest = async () => { - const config: Config = { - notificationDestination: await promptWithCancel(select, { - message: "Select a notification destination", - options: [ - { label: "Slack", value: "SLACK" }, - { label: "Discord", value: "DISCORD" }, - { label: "Both", value: "SLACK,DISCORD" }, - ], - initialValue: "SLACK", - }), - }; - - switch (config.notificationDestination) { - case "SLACK": - config.slackWebhookUrl = await promptWithCancel(text, { - message: "Enter slack webhook url", - }); - break; - case "DISCORD": - config.discordWebhookUrl = await promptWithCancel(text, { - message: "Enter discord webhook url", - }); - break; - case "SLACK,DISCORD": - config.slackWebhookUrl = await promptWithCancel(text, { - message: "Enter slack webhook url", - }); - config.discordWebhookUrl = await promptWithCancel(text, { - message: "Enter discord webhook url", - }); - break; - default: - break; - } - - saveConfigToEnv({ - BACKUP_NOTIFICATION: config.notificationDestination, - SLACK_WEBHOOK_URL: String(config.slackWebhookUrl), - DISCORD_WEBHOOK_URL: String(config.discordWebhookUrl), - }); -}; - -export default notificationDest; diff --git a/src/commands/updateHelper.ts b/src/commands/updateHelper.ts deleted file mode 100644 index edb68e2..0000000 --- a/src/commands/updateHelper.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { intro, outro } from "@clack/prompts"; -import chalk from "chalk"; -import * as fs from "fs"; -import process from "process"; - -// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type -const updateHelper = async (updateType: string, action: Function) => { - //check .env file exists in root folder - if (!fs.existsSync(".env")) { - console.log(chalk.red("Please create .env file first!")); - console.log( - chalk.blue("Run 'ts-node index.ts install' to create .env file using cli") - ); - process.exit(1); - } - intro(chalk.inverse(updateType)); - await action(); - outro(chalk.green(`${updateType} successfully!`)); -}; - -export default updateHelper; diff --git a/src/commands/utils.ts b/src/commands/utils.ts deleted file mode 100644 index 1dc6755..0000000 --- a/src/commands/utils.ts +++ /dev/null @@ -1,39 +0,0 @@ -import * as fs from "fs"; -import path from "path"; -import * as yaml from "yaml"; -import { DataBeeConfig } from "../@types/config"; -import { isCancel } from "@clack/prompts"; -import process from "process"; -import chalk from "chalk"; - -// eslint-disable-next-line no-undef -export const sourceFile = path.join(__dirname, "../../backupdbee.yaml.sample"); -// eslint-disable-next-line no-undef -export const destinationFile = path.join(__dirname, "../../backupdbee.yaml"); - -export function loadConfig() { - try { - const file = fs.readFileSync(destinationFile, "utf8"); - return yaml.parse(file); - } catch (error) { - console.error(chalk.red("Error loading configuration file:"), error); - process.exit(1); - } -} - -// Save YAML config file -export function saveYamlConfig(config: DataBeeConfig) { - const yamlStr = yaml.stringify(config); - fs.writeFileSync(destinationFile, yamlStr, "utf8"); - console.log("Configuration saved to config.yaml"); -} - -// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type -export const promptWithCancel = async (promptFn: Function, options: object) => { - const result = await promptFn(options); - if (isCancel(result)) { - console.log("Operation cancelled"); - process.exit(0); - } - return result; -}; diff --git a/src/index.ts b/src/index.ts index 16f0c0c..131394f 100755 --- a/src/index.ts +++ b/src/index.ts @@ -5,16 +5,9 @@ import { ConfigType } from "./@types/types"; import { promisify } from "util"; import Log from "./constants/log"; import { sendNotification } from "./utils/notify.utils"; -import { readFileSync } from "fs"; -import * as yaml from "yaml"; -import { DataBeeConfig, Destinations, Notifications } from "./@types/config"; +import { Destinations, Notifications } from "./@types/config"; import { validateDBConfig } from "./validators/config"; -import { - getDefaultPortOfDBType, - setupDBConfig, - setupDestinations, - setupNotifications, -} from "./setup"; +import { getDefaultPortOfDBType } from "./setup"; // Promisify exec to use with async/await export const execAsync = promisify(exec); @@ -46,16 +39,3 @@ export const main = async ( } } }; - -function parseConfigFile(path: string = "backupdbee.yaml"): DataBeeConfig { - const configFile = readFileSync(path, "utf-8"); - const yamlConfig = yaml.parse(configFile) as DataBeeConfig; - return yamlConfig; -} - -const dataBeeConfig = parseConfigFile(); -main( - setupDBConfig(dataBeeConfig), - setupDestinations(dataBeeConfig), - setupNotifications(dataBeeConfig) -); diff --git a/src/utils/cli.utils.ts b/src/utils/cli.utils.ts new file mode 100644 index 0000000..24a9760 --- /dev/null +++ b/src/utils/cli.utils.ts @@ -0,0 +1,15 @@ +import { readFileSync } from "fs"; +import path from "path"; +import * as yaml from "yaml"; +import { DataBeeConfig } from "../@types/config"; + +// eslint-disable-next-line no-undef +export const sourceFile = path.join(__dirname, "../../backupdbee.yaml.sample"); +// eslint-disable-next-line no-undef +export const destinationFile = path.join(__dirname, "../../backupdbee.yaml"); + +export function parseConfigFile(): DataBeeConfig { + const configFile = readFileSync(destinationFile, "utf-8"); + const yamlConfig = yaml.parse(configFile) as DataBeeConfig; + return yamlConfig; +} From 193a6d06c4b9eac09723157d1e8679cd13cc9585 Mon Sep 17 00:00:00 2001 From: Anupam Bista Date: Tue, 17 Sep 2024 11:06:26 +0545 Subject: [PATCH 05/17] minor fixes and added documentation for db:backup command --- docs/.vitepress/config.mts | 5 ++++- docs/guide/cli/db-backup.md | 21 +++++++++++++++++++++ docs/guide/getting-started.md | 10 ++++++++-- docs/index.md | 3 +-- index.ts | 4 +--- src/commands/database.ts | 12 ++++++++---- src/commands/install.ts | 8 +++++++- 7 files changed, 50 insertions(+), 13 deletions(-) create mode 100644 docs/guide/cli/db-backup.md diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts index ae69932..50d8077 100644 --- a/docs/.vitepress/config.mts +++ b/docs/.vitepress/config.mts @@ -38,7 +38,10 @@ function sidebarGuide(): DefaultTheme.SidebarItem[] { { text: "Cli Commands", collapsed: false, - items: [{ text: "db:list", link: "cli/db-list" }], + items: [ + { text: "db:list", link: "cli/db-list" }, + { text: "db:backup", link: "cli/db-backup" }, + ], }, ]; } diff --git a/docs/guide/cli/db-backup.md b/docs/guide/cli/db-backup.md new file mode 100644 index 0000000..d57746f --- /dev/null +++ b/docs/guide/cli/db-backup.md @@ -0,0 +1,21 @@ +# Backup Databases Command + +The `db:backup` command is used to back up all databases defined in the YAML configuration, or a specific one using the `--name` flag. + +## Usage + +### Backup All Databases + +To back up all databases, simply run the following command: + +```bash +ts-node index.ts db:backup +``` + +### Backup Specific Database + +To back up a specific database, use the `--name` flag followed by the name of the database. For example: + +```bash +node index.ts db:backup --name +``` diff --git a/docs/guide/getting-started.md b/docs/guide/getting-started.md index 083d92d..59d2e34 100644 --- a/docs/guide/getting-started.md +++ b/docs/guide/getting-started.md @@ -5,18 +5,24 @@ ### Prerequisites - [Node.js](https://nodejs.org/) version 18 or higher. -- Terminal for accessing VitePress via its command line interface (CLI). +- Terminal for accessing BackupDBee cli via its command line interface (CLI). - [zip] - [pg_dump] - [mysqldump] -## Clone the project 📦 +### Clone the project 📦 ``` git clone https://github.com/28softwares/backupdbee.git cd backupdbee ``` +### Install Required Dependencies + +```bash +pnpm install +``` + ### Initial Setup ```bash diff --git a/docs/index.md b/docs/index.md index 146b8eb..9ed7c9a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -3,7 +3,7 @@ layout: home hero: - name: "BackupDBee" + name: "BackupDBee 🐝" text: "Automatic CLI Based Advance DB Backup System" tagline: My great project tagline actions: @@ -22,4 +22,3 @@ features: - title: Feature C details: Lorem ipsum dolor sit amet, consectetur adipiscing elit --- - diff --git a/index.ts b/index.ts index 0e2a2eb..2ec3ec1 100644 --- a/index.ts +++ b/index.ts @@ -9,9 +9,7 @@ program.version("1.0.0").description("BackupDBee CLI"); program .command("install") .alias("i") - .description( - "Check required commands, create .env file and install dependencies" - ) + .description("Check required commands, create backupdbee.yaml file") .action(async () => await install()); program diff --git a/src/commands/database.ts b/src/commands/database.ts index 0b12cef..ee28763 100644 --- a/src/commands/database.ts +++ b/src/commands/database.ts @@ -1,6 +1,6 @@ import { Database, DataBeeConfig } from "../@types/config"; import chalk from "chalk"; -import { intro, outro } from "@clack/prompts"; +import { spinner } from "@clack/prompts"; import { setupDBConfig, setupDestinations, setupNotifications } from "../setup"; import process from "process"; import { main } from ".."; @@ -62,19 +62,23 @@ export const dbBackup = async (options: { name?: string }) => { // update config with the specific database if (db) { config.databases = [db]; - intro(chalk.blueBright(`Backing up database: ${options.name}`)); + const s = spinner(); + s.start(`Backing up database: ${options.name}\n`); await setupMainFunction(config); // Call main function to backup specific database + s.stop(); } else { console.log(chalk.red(`Database "${options.name}" not found.`)); process.exit(1); } } else { // Backup all databases - intro(chalk.blueBright("Backing up all databases...")); + const s = spinner(); + s.start("Backing up all databases\n"); await setupMainFunction(config); // Call main function to backup all databases + s.stop(); } } catch (e) { console.log(e); - outro(chalk.red("Backup failed.")); + console.log(chalk.red("Backup failed.")); } }; diff --git a/src/commands/install.ts b/src/commands/install.ts index 660c3ef..934c31a 100644 --- a/src/commands/install.ts +++ b/src/commands/install.ts @@ -54,7 +54,7 @@ const install = async (): Promise => { createBackupdbeeYaml(); } else { const shouldContinue = await confirm({ - message: "Do you want to continue?", + message: "Backupdbee.yaml file exits. Do you want to override?", initialValue: false, }); if (!shouldContinue) { @@ -63,6 +63,12 @@ const install = async (): Promise => { createBackupdbeeYaml(); } } + + console.log( + chalk.green( + "Next Step: Update the backupdbee.yaml file with your configurations." + ) + ); } catch (err) { console.log(err); } From 5588b71d6d5d2c84934e6bb36fae7deef5f6510d Mon Sep 17 00:00:00 2001 From: Anupam Bista Date: Tue, 17 Sep 2024 12:17:27 +0545 Subject: [PATCH 06/17] added general command and its documentation --- .env.sample | 26 -------------- docs/.vitepress/config.mts | 7 +++- docs/guide/automate-backup.md | 7 ++++ docs/guide/cli/db-backup.md | 2 +- docs/guide/cli/db-list.md | 2 +- docs/guide/cli/general.md | 41 +++++++++++++++++++++ docs/index.md | 21 ++++++----- index.ts | 13 +++++++ run-ts.sh | 1 - src/commands/general.ts | 67 +++++++++++++++++++++++++++++++++++ src/utils/cli.utils.ts | 7 +++- 11 files changed, 152 insertions(+), 42 deletions(-) delete mode 100644 .env.sample create mode 100644 docs/guide/automate-backup.md create mode 100644 docs/guide/cli/general.md delete mode 100644 run-ts.sh create mode 100644 src/commands/general.ts diff --git a/.env.sample b/.env.sample deleted file mode 100644 index 21746b5..0000000 --- a/.env.sample +++ /dev/null @@ -1,26 +0,0 @@ -#MAIL -MAIL_USER='user@duck.com' -MAIL_PASSWORD='examplepassword' - -#BACKUP_CONFIG -BACKUP_DEST= # To implement other Future features will be S3_BUCKET, DROPBOX, GOOGLE_DRIVE -# To be implemented in future -# BACKUP_NOTFICATION= DISCORD # other Future features will be SLACK, Telegram - - -# POSTGRES DATABASE CONFIGURATION -POSTGRES_DB_HOST='127.0.0.1' -POSTGRES_DB_NAME='dbname' -POSTGRES_DB_USER='postgres' -POSTGRES_DB_PASSWORD='pass' - -# MYSQL DATABASE CONFIGURATION -MYSQL_HOST='127.0.0.1' -MYSQL_DB_NAME='mysqldb' -MYSQL_DB_USER='root' -MYSQL_DB_PASSWORD='my-secret-pw' - -SLACK_WEBHOOK_URL="https://hooks.slack.com/services/XXXX/XXXX/XXXX" -BACKUP_NOTIFICATION=SLACK - -CONFIG=backupbee.json \ No newline at end of file diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts index 50d8077..9734e6e 100644 --- a/docs/.vitepress/config.mts +++ b/docs/.vitepress/config.mts @@ -2,7 +2,7 @@ import { defineConfig, type DefaultTheme } from "vitepress"; // https://vitepress.dev/reference/site-config export default defineConfig({ - title: "BackupDBee", + title: "BackupDBee 🐝", description: "Automatic CLI Based Advance DB Backup System", themeConfig: { // https://vitepress.dev/reference/default-theme-config @@ -39,9 +39,14 @@ function sidebarGuide(): DefaultTheme.SidebarItem[] { text: "Cli Commands", collapsed: false, items: [ + { text: "general", link: "cli/general" }, { text: "db:list", link: "cli/db-list" }, { text: "db:backup", link: "cli/db-backup" }, ], }, + { + text: "Automation", + link: "automate-backup", + }, ]; } diff --git a/docs/guide/automate-backup.md b/docs/guide/automate-backup.md new file mode 100644 index 0000000..e68cddf --- /dev/null +++ b/docs/guide/automate-backup.md @@ -0,0 +1,7 @@ +# Automate Backup + +You can use process managers to automate your backup + +```bash +pm2 start ts-node index.ts db:backup --name dbbackup --cron "* * * * *" +``` diff --git a/docs/guide/cli/db-backup.md b/docs/guide/cli/db-backup.md index d57746f..e91af40 100644 --- a/docs/guide/cli/db-backup.md +++ b/docs/guide/cli/db-backup.md @@ -1,4 +1,4 @@ -# Backup Databases Command +# `db:backup` Command Documentation The `db:backup` command is used to back up all databases defined in the YAML configuration, or a specific one using the `--name` flag. diff --git a/docs/guide/cli/db-list.md b/docs/guide/cli/db-list.md index 76fe174..13308d0 100644 --- a/docs/guide/cli/db-list.md +++ b/docs/guide/cli/db-list.md @@ -1,4 +1,4 @@ -# List Databases Command +# `db:list` Command Documentation The `db:list` command lists all the databases defined in the YAML configuration file and shows the total count of databases. diff --git a/docs/guide/cli/general.md b/docs/guide/cli/general.md new file mode 100644 index 0000000..486ae5d --- /dev/null +++ b/docs/guide/cli/general.md @@ -0,0 +1,41 @@ +# `general` Command Documentation + +The `general` command is used to configure the general settings of your `backupdbee.yaml` file. You can either use flags to update specific settings or use an interactive mode where you'll be prompted to provide input. + +## Command: `general` + +```bash +ts-node index.ts general [options] +``` + +### Description + +The `general` command allows you to modify the following general settings in the `backupdbee.yaml` file: + +- Backup location +- Log location +- Log level (INFO, DEBUG, ERROR) +- Retention policy (number of days) +- Backup schedule (in cron format) + +You can configure each setting individually using the provided flags or choose to use the interactive mode (i.e., no flags) to update settings step-by-step. + +--- + +## Flags + +Below is a table describing each flag you can use with the `general` command. + +| Flag | Description | Example Command | +| -------------------- | --------------------------------------------------------------------------- | --------------------------------------------------------------- | +| `--backup-location` | Specify the directory where backups will be stored. | `ts-node index.ts general --backup-location "/path/to/backups"` | +| `--log-location` | Set the directory where logs will be stored. | `ts-node index.ts general --log-location "/path/to/logs"` | +| `--log-level` | Set the log verbosity level. Accepts values: `INFO`, `DEBUG`, `ERROR`. | `ts-node index.ts general --log-level DEBUG` | +| `--retention-policy` | Specify how many days backups will be retained. Takes a number as an input. | `ts-node index.ts general --retention-policy 10` | +| `--backup-schedule` | Set the cron schedule for automatic backups. | `ts-node index.ts general --backup-schedule "0 3 * * *"` | + +--- + +## Interactive Mode + +If no flags are provided, the `general` command will enter an interactive mode, where you will be prompted to input values for each setting. diff --git a/docs/index.md b/docs/index.md index 9ed7c9a..8f7eebf 100644 --- a/docs/index.md +++ b/docs/index.md @@ -5,20 +5,19 @@ layout: home hero: name: "BackupDBee 🐝" text: "Automatic CLI Based Advance DB Backup System" - tagline: My great project tagline actions: - theme: brand - text: Markdown Examples - link: /markdown-examples + text: Documentation + link: /guide/what-is-backupdbee - theme: alt - text: API Examples - link: /api-examples + text: Github + link: https://github.com/28softwares/backupdbee features: - - title: Feature A - details: Lorem ipsum dolor sit amet, consectetur adipiscing elit - - title: Feature B - details: Lorem ipsum dolor sit amet, consectetur adipiscing elit - - title: Feature C - details: Lorem ipsum dolor sit amet, consectetur adipiscing elit + - title: Multiple Database Support + details: Seamlessly back up MySQL & PostgreSQL in one go. + - title: Notifify on different channels + details: Notify on Discord or Slack or Telegram for successful and failed backups. + - title: Automated Backups + details: Schedule and automate backups (using crons or pm2) to ensure your data is always protected without manual intervention. --- diff --git a/index.ts b/index.ts index 2ec3ec1..63672a2 100644 --- a/index.ts +++ b/index.ts @@ -2,6 +2,7 @@ import process from "process"; import { Command } from "commander"; import install from "./src/commands/install"; import { dbBackup, dbList } from "./src/commands/database"; +import general from "./src/commands/general"; const program = new Command(); program.version("1.0.0").description("BackupDBee CLI"); @@ -25,4 +26,16 @@ program dbBackup(options); }); +program + .command("general") + .description("Configure general settings in backupdbee.yaml") + .option("--backup-location ", "Set the backup location") + .option("--log-location ", "Set the log location") + .option("--log-level ", "Set the log level (e.g., INFO, DEBUG)") + .option("--retention-policy ", "Set retention policy in days", parseInt) + .option("--backup-schedule ", "Set backup schedule in cron format") + .action(async (options) => { + general(options); + }); + program.parse(process.argv); diff --git a/run-ts.sh b/run-ts.sh deleted file mode 100644 index 50cd41d..0000000 --- a/run-ts.sh +++ /dev/null @@ -1 +0,0 @@ -ts-node -T src/index.ts diff --git a/src/commands/general.ts b/src/commands/general.ts new file mode 100644 index 0000000..8cf1582 --- /dev/null +++ b/src/commands/general.ts @@ -0,0 +1,67 @@ +import { select, text } from "@clack/prompts"; +import { promptWithCancel } from "./promptWithCancel"; +import { parseConfigFile, saveConfig } from "../utils/cli.utils"; + +const general = async (options: { + backupLocation?: string; + logLocation?: string; + logLevel?: string; + retentionPolicy?: string; + backupSchedule?: string; +}) => { + const config = parseConfigFile(); + if (!Object.keys(options).length) { + const backupLocation = await promptWithCancel(text, { + message: "Enter backup location", + initialValue: config.general.backup_location, + }); + + const logLocation = await text({ + message: "Enter log location", + initialValue: config.general.log_location, + }); + + const logLevel = await select({ + message: "Select log level", + options: [ + { value: "INFO", label: "INFO" }, + { value: "DEBUG", label: "DEBUG" }, + { value: "ERROR", label: "ERROR" }, + ], + initialValue: config.general.log_level, + }); + + const retentionPolicy = (await text({ + message: "Enter retention policy (days)", + initialValue: String(config.general.retention_policy_days), + })) as unknown as number; + + const backupSchedule = await text({ + message: "Enter backup schedule (cron format)", + initialValue: config.general.backup_schedule, + }); + + config.general.backup_location = backupLocation as string; + config.general.log_location = logLocation as string; + config.general.log_level = logLevel as string; + config.general.retention_policy_days = Number(retentionPolicy); + config.general.backup_schedule = backupSchedule as string; + } else { + // If flags are provided, use them to update the config directly + if (options.backupLocation) + config.general.backup_location = options.backupLocation; + if (options.logLocation) config.general.log_location = options.logLocation; + if (options.logLevel) config.general.log_level = options.logLevel; + if (options.retentionPolicy) + config.general.retention_policy_days = Number(options.retentionPolicy); + if (options.backupSchedule) + config.general.backup_schedule = options.backupSchedule; + } + + // Save the updated config back to the YAML file + saveConfig(config); + + console.log("General settings updated successfully!"); +}; + +export default general; diff --git a/src/utils/cli.utils.ts b/src/utils/cli.utils.ts index 24a9760..3c70a96 100644 --- a/src/utils/cli.utils.ts +++ b/src/utils/cli.utils.ts @@ -1,4 +1,4 @@ -import { readFileSync } from "fs"; +import { readFileSync, writeFileSync } from "fs"; import path from "path"; import * as yaml from "yaml"; import { DataBeeConfig } from "../@types/config"; @@ -13,3 +13,8 @@ export function parseConfigFile(): DataBeeConfig { const yamlConfig = yaml.parse(configFile) as DataBeeConfig; return yamlConfig; } + +export function saveConfig(config: DataBeeConfig) { + const yamlString = yaml.stringify(config); + writeFileSync(destinationFile, yamlString, "utf8"); +} From 1d2c2eecb055109de3f70dab590219e184147b7b Mon Sep 17 00:00:00 2001 From: Anupam Bista Date: Tue, 17 Sep 2024 12:25:21 +0545 Subject: [PATCH 07/17] updated readme.md --- README.md | 33 ++------------------------------- 1 file changed, 2 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 282c7e1..6200ef1 100644 --- a/README.md +++ b/README.md @@ -14,38 +14,9 @@ Effortlessly manage your database backups at one go. This easy-to-use tool suppo ✅ Automated Backups: Schedule and automate backups (using crons or pm2) to ensure your data is always protected without manual intervention. -## Clone the project 📦 +## Documentation -``` -git clone https://github.com/28softwares/backupdbee.git -cd backupdbee -``` - -### Initial Setup - -Make sure to install nodejs and zip in the linux server. - -```bash -node index.mjs install #this creates .env file -``` - -### Configurations ⚒️ - -For GMAIL, you need to enable less secure apps in your gmail account. [Click here to enable less secure apps](https://myaccount.google.com/lesssecureapps) - -```bash -crontab -e - -#at the crontab file, add the following script. -#minute hour dayOfMonth month dayOfWeek commandToRun -* * * * * commandToRun {_ can be any value}~~ -``` - -_OR, you can use process managers as_ - -``` -pm2 start src/index.mjs --name dbbackup --cron "* * * * *" -``` +Check out the documentation at: (https://github.com/28softwares/backupdbee/tree/main/docs/guide/getting-started) ## Feel Free To Contribute 👌 From 8bc935cd0242347a992999b65244b4af2a80305c Mon Sep 17 00:00:00 2001 From: Anupam Bista Date: Tue, 17 Sep 2024 14:12:27 +0545 Subject: [PATCH 08/17] made src compatible with yaml configuration --- package.json | 1 - src/@types/config.ts | 20 ++++++++++------ src/commands/database.ts | 4 +--- src/commands/general.ts | 11 ++++----- src/commands/notification.ts | 0 src/constants/env.config.ts | 44 ---------------------------------- src/constants/notifications.ts | 2 -- src/destinations/email.ts | 13 ++++++---- src/destinations/s3.ts | 10 ++++---- src/utils/cli.utils.ts | 2 ++ src/utils/notify.utils.ts | 3 --- src/validators/destination.ts | 15 +++++++----- src/validators/email.ts | 10 ++++---- src/validators/s3.ts | 10 +++++--- 14 files changed, 56 insertions(+), 89 deletions(-) delete mode 100644 src/commands/notification.ts delete mode 100644 src/constants/env.config.ts diff --git a/package.json b/package.json index 561032a..54c0323 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,6 @@ "chalk": "^4.1.2", "class-transformer": "^0.5.1", "commander": "^12.1.0", - "dotenv": "^16.4.5", "nodemailer": "^6.9.14", "ts-node": "^10.9.2", "winston": "^3.14.1", diff --git a/src/@types/config.ts b/src/@types/config.ts index eafd122..48bda86 100644 --- a/src/@types/config.ts +++ b/src/@types/config.ts @@ -14,12 +14,6 @@ export interface Notifications { telegram: Telegram; } -export interface Email { - enabled: boolean; - from: string; - to: string[]; -} - export interface Slack { enabled: boolean; webhook_url: string; @@ -59,8 +53,20 @@ export interface Local { export interface S3Bucket { enabled: boolean; - bucket: string; + bucket_name: string; region: string; + access_key: string; + secret_key: string; +} + +export interface Email { + enabled: boolean; + smtp_server: string; + smtp_port: number; + smtp_username: string; + smtp_password: string; + from: string; + to: string[]; } export interface Destinations { diff --git a/src/commands/database.ts b/src/commands/database.ts index ee28763..a7b9246 100644 --- a/src/commands/database.ts +++ b/src/commands/database.ts @@ -4,13 +4,12 @@ import { spinner } from "@clack/prompts"; import { setupDBConfig, setupDestinations, setupNotifications } from "../setup"; import process from "process"; import { main } from ".."; -import { parseConfigFile } from "../utils/cli.utils"; +import { config } from "../utils/cli.utils"; /** * Retrieves the list of databases from the configuration and logs them to the console. */ export const dbList = () => { - const config = parseConfigFile(); console.log("Database List"); const databases = config.databases; if (databases && databases.length > 0) { @@ -52,7 +51,6 @@ const setupMainFunction = async (config: DataBeeConfig) => { * @throws {Error} If the backup fails. */ export const dbBackup = async (options: { name?: string }) => { - const config = parseConfigFile(); const databases = config.databases; try { diff --git a/src/commands/general.ts b/src/commands/general.ts index 8cf1582..c113b98 100644 --- a/src/commands/general.ts +++ b/src/commands/general.ts @@ -1,6 +1,6 @@ import { select, text } from "@clack/prompts"; import { promptWithCancel } from "./promptWithCancel"; -import { parseConfigFile, saveConfig } from "../utils/cli.utils"; +import { config, saveConfig } from "../utils/cli.utils"; const general = async (options: { backupLocation?: string; @@ -9,19 +9,18 @@ const general = async (options: { retentionPolicy?: string; backupSchedule?: string; }) => { - const config = parseConfigFile(); if (!Object.keys(options).length) { const backupLocation = await promptWithCancel(text, { message: "Enter backup location", initialValue: config.general.backup_location, }); - const logLocation = await text({ + const logLocation = await promptWithCancel(text, { message: "Enter log location", initialValue: config.general.log_location, }); - const logLevel = await select({ + const logLevel = await promptWithCancel(select, { message: "Select log level", options: [ { value: "INFO", label: "INFO" }, @@ -31,12 +30,12 @@ const general = async (options: { initialValue: config.general.log_level, }); - const retentionPolicy = (await text({ + const retentionPolicy = (await promptWithCancel(text, { message: "Enter retention policy (days)", initialValue: String(config.general.retention_policy_days), })) as unknown as number; - const backupSchedule = await text({ + const backupSchedule = await promptWithCancel(text, { message: "Enter backup schedule (cron format)", initialValue: config.general.backup_schedule, }); diff --git a/src/commands/notification.ts b/src/commands/notification.ts deleted file mode 100644 index e69de29..0000000 diff --git a/src/constants/env.config.ts b/src/constants/env.config.ts deleted file mode 100644 index 2debdf5..0000000 --- a/src/constants/env.config.ts +++ /dev/null @@ -1,44 +0,0 @@ -/* eslint-disable no-undef */ -import "dotenv/config"; - -export type BackupDest = "GMAIL" | "S3_BUCKET" | undefined; - -class EnvConfig { - // MAIL - public static MAIL_USER = process.env.MAIL_USER as string; - public static MAIL_PASSWORD = process.env.MAIL_PASSWORD as string; - //Multiple emails - public static CC_MAIL = process.env.CC_MAIL as string; - //BACKUP_CONFIG - public static BACKUP_DEST = process.env.BACKUP_DEST as BackupDest; - - // POSTGRES DATABASE CONFIGURATION - public static POSTGRES_DB_HOST = process.env.POSTGRES_DB_HOST as string; - public static POSTGRES_DB_NAME = process.env.POSTGRES_DB_NAME as string; - public static POSTGRES_DB_USER = process.env.POSTGRES_DB_USER as string; - public static POSTGRES_DB_PASSWORD = process.env.POSTGRES_DB_PASSWORD as string; - - // MYSQL DATABASE CONFIGURATION - public static MYSQL_DB_HOST = process.env.MYSQL_DB_HOST as string; - public static MYSQL_DB_NAME = process.env.MYSQL_DB_NAME as string; - public static MYSQL_DB_USER = process.env.MYSQL_DB_USER as string; - public static MYSQL_DB_PASSWORD = process.env.MYSQL_DB_PASSWORD as string; - - // WEBHOOK NOTIFICATION CONFIGURATION - public static BACKUP_NOTIFICATION = process.env.BACKUP_NOTIFICATION as string; - public static DISCORD_WEBHOOK_URL = process.env.DISCORD_WEBHOOK_URL as string; - public static SLACK_WEBHOOK_URL = process.env.SLACK_WEBHOOK_URL as string; - public static CUSTOM_WEBHOOK_URL = process.env.CUSTOM_WEBHOOK_URL as string; - - - // S3 CONFIGURATION - public static AWS_ACCESS_KEY_ID = process.env.AWS_ACCESS_KEY_ID as string; - public static AWS_SECRET_ACCESS_KEY = process.env.AWS_SECRET_ACCESS_KEY as string; - public static AWS_S3_BUCKET_NAME = process.env.AWS_S3_BUCKET_NAME as string; - public static AWS_REGION = process.env.AWS_REGION as string; - - // Backup Configuration - public static CONFIG = process.env.CONFIG as string; -} - -export default EnvConfig; diff --git a/src/constants/notifications.ts b/src/constants/notifications.ts index bb51392..f827129 100644 --- a/src/constants/notifications.ts +++ b/src/constants/notifications.ts @@ -1,12 +1,10 @@ export const NOTIFICATION = { - EMAIL: "EMAIL", SLACK: "SLACK", CUSTOM: "CUSTOM", DISCORD: "DISCORD", TELEGRAM: "TELEGRAM", }; - export const DESTINATION = { EMAIL: "EMAIL", S3_BUCKET: "S3_BUCKET", diff --git a/src/destinations/email.ts b/src/destinations/email.ts index b8c9e9f..eb9ccce 100644 --- a/src/destinations/email.ts +++ b/src/destinations/email.ts @@ -1,20 +1,20 @@ import { createTransport } from "nodemailer"; -import EnvConfig from "../constants/env.config"; import Log from "../constants/log"; import { Sender, SenderOption } from "./sender"; import Mail from "nodemailer/lib/mailer"; +import { config } from "../utils/cli.utils"; export class EmailSender implements Sender { private static transporterInstance: Mail | null = null; private static getTransporter(): Mail { if (!EmailSender.transporterInstance) { EmailSender.transporterInstance = createTransport({ - host: "smtp.gmail.com", + host: config.destinations.email.smtp_server, secure: true, requireTLS: true, auth: { - user: EnvConfig.MAIL_USER, - pass: EnvConfig.MAIL_PASSWORD, + user: config.destinations.email.smtp_username, + pass: config.destinations.email.smtp_password, }, }); } @@ -42,7 +42,10 @@ export class EmailSender implements Sender { throw new Error("[-] Email address is invalid."); } - if (!EnvConfig.MAIL_USER || !EnvConfig.MAIL_PASSWORD) { + if ( + !config.destinations.email.smtp_username || + !config.destinations.email.smtp_password + ) { throw new Error("[-] MAIL_USER or MAIL_PASSWORD is not set"); } const transporter = EmailSender.getTransporter(); diff --git a/src/destinations/s3.ts b/src/destinations/s3.ts index b4de679..5a6bb1e 100644 --- a/src/destinations/s3.ts +++ b/src/destinations/s3.ts @@ -4,17 +4,17 @@ import { PutObjectCommand, PutObjectCommandInput, } from "@aws-sdk/client-s3"; -import EnvConfig from "../constants/env.config"; +import { config } from "../utils/cli.utils"; export class S3Sender implements Sender { private static s3ClientInstance: S3Client | null = null; private static getS3ClientInstance(): S3Client { if (!S3Sender.s3ClientInstance) { S3Sender.s3ClientInstance = new S3Client({ - region: EnvConfig.AWS_REGION, + region: config.destinations.s3_bucket.region, credentials: { - accessKeyId: EnvConfig.AWS_ACCESS_KEY_ID, - secretAccessKey: EnvConfig.AWS_SECRET_ACCESS_KEY, + accessKeyId: config.destinations.s3_bucket.access_key, + secretAccessKey: config.destinations.s3_bucket.secret_key, }, }); } @@ -37,7 +37,7 @@ export class S3Sender implements Sender { async uploadToS3(fileName?: string, fileContent?: unknown) { try { const uploadParams = { - Bucket: EnvConfig.AWS_S3_BUCKET_NAME, + Bucket: config.destinations.s3_bucket.bucket_name, Key: fileName, Body: fileContent, ContentType: "application/octet-stream", diff --git a/src/utils/cli.utils.ts b/src/utils/cli.utils.ts index 3c70a96..5f2f761 100644 --- a/src/utils/cli.utils.ts +++ b/src/utils/cli.utils.ts @@ -18,3 +18,5 @@ export function saveConfig(config: DataBeeConfig) { const yamlString = yaml.stringify(config); writeFileSync(destinationFile, yamlString, "utf8"); } + +export const config = parseConfigFile(); diff --git a/src/utils/notify.utils.ts b/src/utils/notify.utils.ts index a4d5fb0..7dcf50a 100644 --- a/src/utils/notify.utils.ts +++ b/src/utils/notify.utils.ts @@ -46,9 +46,6 @@ export const sendNotification = async ( ) ); break; - case NOTIFICATION.EMAIL: - Log.warn("Email notification is not supported yet."); - break; default: console.error(`[-] Unsupported notification medium: ${medium}`); Log.error(`Unsupported notification medium: ${medium}`); diff --git a/src/validators/destination.ts b/src/validators/destination.ts index f2c42b2..27a2573 100644 --- a/src/validators/destination.ts +++ b/src/validators/destination.ts @@ -1,6 +1,6 @@ import { Email, Local, S3Bucket } from "../@types/config"; -import EnvConfig from "../constants/env.config"; import Log from "../constants/log"; +import { config } from "../utils/cli.utils"; export function validateLocalDestination(local: Local): boolean { if (local?.enabled) { @@ -24,7 +24,10 @@ export function validateEmailDestination(email?: Email): boolean { return false; } - if (!EnvConfig.MAIL_USER || !EnvConfig.MAIL_PASSWORD) { + if ( + !config.destinations.email.smtp_username || + !config.destinations.email.smtp_password + ) { Log.error("Mail credentials not set in the environment variables."); return false; } @@ -34,7 +37,7 @@ export function validateEmailDestination(email?: Email): boolean { export function validateS3Destination(s3_bucket: S3Bucket): boolean { if (s3_bucket?.enabled) { - if (!s3_bucket?.bucket) { + if (!s3_bucket?.bucket_name) { Log.error("S3 bucket name not set in the config file."); return false; } @@ -45,9 +48,9 @@ export function validateS3Destination(s3_bucket: S3Bucket): boolean { } if ( - !EnvConfig.AWS_ACCESS_KEY_ID || - !EnvConfig.AWS_SECRET_ACCESS_KEY || - !EnvConfig.AWS_REGION + !config.destinations.s3_bucket.access_key || + !config.destinations.s3_bucket.secret_key || + !config.destinations.s3_bucket.region ) { Log.error("AWS credentials not set in the environment variables."); return false; diff --git a/src/validators/email.ts b/src/validators/email.ts index e1451df..1448e57 100644 --- a/src/validators/email.ts +++ b/src/validators/email.ts @@ -1,6 +1,6 @@ import { Email } from "../@types/config"; -import EnvConfig from "../constants/env.config"; import Log from "../constants/log"; +import { config } from "../utils/cli.utils"; export function validateEmailDestination(email?: Email): boolean { if (email?.enabled) { @@ -14,7 +14,10 @@ export function validateEmailDestination(email?: Email): boolean { return false; } - if (!EnvConfig.MAIL_USER || !EnvConfig.MAIL_PASSWORD) { + if ( + !config.destinations.email.smtp_username || + !config.destinations.email.smtp_password + ) { Log.error("Mail credentials not set in the environment variables."); return false; } @@ -22,7 +25,6 @@ export function validateEmailDestination(email?: Email): boolean { return true; } - export function validateEmailNotification(email: Email): boolean { if (!email.from) { Log.error("Email from address not set in the config file."); @@ -35,4 +37,4 @@ export function validateEmailNotification(email: Email): boolean { } return true; -} \ No newline at end of file +} diff --git a/src/validators/s3.ts b/src/validators/s3.ts index 13971c0..6e329f6 100644 --- a/src/validators/s3.ts +++ b/src/validators/s3.ts @@ -1,10 +1,10 @@ import { S3Bucket } from "../@types/config"; -import EnvConfig from "../constants/env.config"; +import { config } from "../utils/cli.utils"; import Log from "../constants/log"; export function validateS3Destination(s3_bucket: S3Bucket): boolean { if (s3_bucket?.enabled) { - if (!s3_bucket?.bucket) { + if (!s3_bucket?.bucket_name) { Log.error("S3 bucket name not set in the config file."); return false; } @@ -14,7 +14,11 @@ export function validateS3Destination(s3_bucket: S3Bucket): boolean { return false; } - if (!EnvConfig.AWS_ACCESS_KEY_ID || !EnvConfig.AWS_SECRET_ACCESS_KEY || !EnvConfig.AWS_REGION) { + if ( + !config.destinations.s3_bucket.access_key || + !config.destinations.s3_bucket.secret_key || + !config.destinations.s3_bucket.region + ) { Log.error("AWS credentials not set in the environment variables."); return false; } From c9bf9f6b0807eebecbb69b1c235a631195b51acb Mon Sep 17 00:00:00 2001 From: Anupam Bista Date: Tue, 17 Sep 2024 16:43:53 +0545 Subject: [PATCH 09/17] added github actions which deploys documentation automatically --- .github/workflows/deploy.yml | 59 ++++++++++++++++++++++++++++++++++++ docs/.vitepress/config.mts | 1 + 2 files changed, 60 insertions(+) create mode 100644 .github/workflows/deploy.yml diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..d7857ef --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,59 @@ +name: Deploy VitePress site to Pages + +on: + push: + branches: [main] + paths: + - "docs/**" # Only trigger when files in the docs/ directory change + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: pages + cancel-in-progress: false + +jobs: + # Build job + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Not needed if lastUpdated is not enabled + - uses: pnpm/action-setup@v3 # Uncomment this if you're using pnpm + # - uses: oven-sh/setup-bun@v1 # Uncomment this if you're using Bun + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: npm # or pnpm / yarn + - name: Setup Pages + uses: actions/configure-pages@v4 + - name: Install dependencies + run: pnpm install # or pnpm install / yarn install / bun install + - name: Build with VitePress + run: pnpm docs:build # or pnpm docs:build / yarn docs:build / bun run docs:build + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: docs/.vitepress/dist + + # Deployment job + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + needs: build + runs-on: ubuntu-latest + name: Deploy + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts index 9734e6e..b559ce1 100644 --- a/docs/.vitepress/config.mts +++ b/docs/.vitepress/config.mts @@ -2,6 +2,7 @@ import { defineConfig, type DefaultTheme } from "vitepress"; // https://vitepress.dev/reference/site-config export default defineConfig({ + base: "/backupdbee/", title: "BackupDBee 🐝", description: "Automatic CLI Based Advance DB Backup System", themeConfig: { From bd778bd28069ff49d51d06f64bf7909f81f89fee Mon Sep 17 00:00:00 2001 From: Anupam Bista Date: Tue, 17 Sep 2024 16:46:39 +0545 Subject: [PATCH 10/17] fixed minor bug related to deployment --- .github/workflows/deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index d7857ef..2bd5df2 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -33,7 +33,7 @@ jobs: uses: actions/setup-node@v4 with: node-version: 20 - cache: npm # or pnpm / yarn + cache: pnpm # or pnpm / yarn - name: Setup Pages uses: actions/configure-pages@v4 - name: Install dependencies From 7cf83bac56d744d0939206513dd3d1e27d025134 Mon Sep 17 00:00:00 2001 From: Anupam Bista Date: Tue, 17 Sep 2024 16:54:24 +0545 Subject: [PATCH 11/17] removed pnpm-lock.yaml file gitignore --- .gitignore | 1 - pnpm-lock.yaml | 4448 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 4448 insertions(+), 1 deletion(-) create mode 100644 pnpm-lock.yaml diff --git a/.gitignore b/.gitignore index fe380c4..4600248 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ node_modules log .sql -pnpm-lock.yaml yarn.lock package-lock.json .env diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..9db82e2 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,4448 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@aws-sdk/client-s3': + specifier: ^3.637.0 + version: 3.651.1 + '@clack/prompts': + specifier: ^0.7.0 + version: 0.7.0 + '@types/nodemailer': + specifier: ^6.4.15 + version: 6.4.15 + chalk: + specifier: ^4.1.2 + version: 4.1.2 + class-transformer: + specifier: ^0.5.1 + version: 0.5.1 + commander: + specifier: ^12.1.0 + version: 12.1.0 + nodemailer: + specifier: ^6.9.14 + version: 6.9.15 + ts-node: + specifier: ^10.9.2 + version: 10.9.2(@types/node@18.19.50)(typescript@5.6.2) + winston: + specifier: ^3.14.1 + version: 3.14.2 + yaml: + specifier: ^2.5.1 + version: 2.5.1 + devDependencies: + '@eslint/js': + specifier: ^9.9.0 + version: 9.10.0 + '@types/express': + specifier: ^4.17.21 + version: 4.17.21 + '@types/node': + specifier: ^18.19.44 + version: 18.19.50 + eslint: + specifier: ^9.9.0 + version: 9.10.0 + globals: + specifier: ^15.9.0 + version: 15.9.0 + husky: + specifier: ^9.1.5 + version: 9.1.6 + ts-node-dev: + specifier: ^2.0.0 + version: 2.0.0(@types/node@18.19.50)(typescript@5.6.2) + typescript: + specifier: ^5.5.4 + version: 5.6.2 + typescript-eslint: + specifier: ^8.1.0 + version: 8.6.0(eslint@9.10.0)(typescript@5.6.2) + vitepress: + specifier: ^1.3.4 + version: 1.3.4(@algolia/client-search@4.24.0)(@types/node@18.19.50)(postcss@8.4.47)(search-insights@2.17.2)(typescript@5.6.2) + +packages: + + '@algolia/autocomplete-core@1.9.3': + resolution: {integrity: sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==} + + '@algolia/autocomplete-plugin-algolia-insights@1.9.3': + resolution: {integrity: sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==} + peerDependencies: + search-insights: '>= 1 < 3' + + '@algolia/autocomplete-preset-algolia@1.9.3': + resolution: {integrity: sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==} + peerDependencies: + '@algolia/client-search': '>= 4.9.1 < 6' + algoliasearch: '>= 4.9.1 < 6' + + '@algolia/autocomplete-shared@1.9.3': + resolution: {integrity: sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==} + peerDependencies: + '@algolia/client-search': '>= 4.9.1 < 6' + algoliasearch: '>= 4.9.1 < 6' + + '@algolia/cache-browser-local-storage@4.24.0': + resolution: {integrity: sha512-t63W9BnoXVrGy9iYHBgObNXqYXM3tYXCjDSHeNwnsc324r4o5UiVKUiAB4THQ5z9U5hTj6qUvwg/Ez43ZD85ww==} + + '@algolia/cache-common@4.24.0': + resolution: {integrity: sha512-emi+v+DmVLpMGhp0V9q9h5CdkURsNmFC+cOS6uK9ndeJm9J4TiqSvPYVu+THUP8P/S08rxf5x2P+p3CfID0Y4g==} + + '@algolia/cache-in-memory@4.24.0': + resolution: {integrity: sha512-gDrt2so19jW26jY3/MkFg5mEypFIPbPoXsQGQWAi6TrCPsNOSEYepBMPlucqWigsmEy/prp5ug2jy/N3PVG/8w==} + + '@algolia/client-account@4.24.0': + resolution: {integrity: sha512-adcvyJ3KjPZFDybxlqnf+5KgxJtBjwTPTeyG2aOyoJvx0Y8dUQAEOEVOJ/GBxX0WWNbmaSrhDURMhc+QeevDsA==} + + '@algolia/client-analytics@4.24.0': + resolution: {integrity: sha512-y8jOZt1OjwWU4N2qr8G4AxXAzaa8DBvyHTWlHzX/7Me1LX8OayfgHexqrsL4vSBcoMmVw2XnVW9MhL+Y2ZDJXg==} + + '@algolia/client-common@4.24.0': + resolution: {integrity: sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==} + + '@algolia/client-personalization@4.24.0': + resolution: {integrity: sha512-l5FRFm/yngztweU0HdUzz1rC4yoWCFo3IF+dVIVTfEPg906eZg5BOd1k0K6rZx5JzyyoP4LdmOikfkfGsKVE9w==} + + '@algolia/client-search@4.24.0': + resolution: {integrity: sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==} + + '@algolia/logger-common@4.24.0': + resolution: {integrity: sha512-LLUNjkahj9KtKYrQhFKCzMx0BY3RnNP4FEtO+sBybCjJ73E8jNdaKJ/Dd8A/VA4imVHP5tADZ8pn5B8Ga/wTMA==} + + '@algolia/logger-console@4.24.0': + resolution: {integrity: sha512-X4C8IoHgHfiUROfoRCV+lzSy+LHMgkoEEU1BbKcsfnV0i0S20zyy0NLww9dwVHUWNfPPxdMU+/wKmLGYf96yTg==} + + '@algolia/recommend@4.24.0': + resolution: {integrity: sha512-P9kcgerfVBpfYHDfVZDvvdJv0lEoCvzNlOy2nykyt5bK8TyieYyiD0lguIJdRZZYGre03WIAFf14pgE+V+IBlw==} + + '@algolia/requester-browser-xhr@4.24.0': + resolution: {integrity: sha512-Z2NxZMb6+nVXSjF13YpjYTdvV3032YTBSGm2vnYvYPA6mMxzM3v5rsCiSspndn9rzIW4Qp1lPHBvuoKJV6jnAA==} + + '@algolia/requester-common@4.24.0': + resolution: {integrity: sha512-k3CXJ2OVnvgE3HMwcojpvY6d9kgKMPRxs/kVohrwF5WMr2fnqojnycZkxPoEg+bXm8fi5BBfFmOqgYztRtHsQA==} + + '@algolia/requester-node-http@4.24.0': + resolution: {integrity: sha512-JF18yTjNOVYvU/L3UosRcvbPMGT9B+/GQWNWnenIImglzNVGpyzChkXLnrSf6uxwVNO6ESGu6oN8MqcGQcjQJw==} + + '@algolia/transporter@4.24.0': + resolution: {integrity: sha512-86nI7w6NzWxd1Zp9q3413dRshDqAzSbsQjhcDhPIatEFiZrL1/TjnHL8S7jVKFePlIMzDsZWXAXwXzcok9c5oA==} + + '@aws-crypto/crc32@5.2.0': + resolution: {integrity: sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==} + engines: {node: '>=16.0.0'} + + '@aws-crypto/crc32c@5.2.0': + resolution: {integrity: sha512-+iWb8qaHLYKrNvGRbiYRHSdKRWhto5XlZUEBwDjYNf+ly5SVYG6zEoYIdxvf5R3zyeP16w4PLBn3rH1xc74Rag==} + + '@aws-crypto/sha1-browser@5.2.0': + resolution: {integrity: sha512-OH6lveCFfcDjX4dbAvCFSYUjJZjDr/3XJ3xHtjn3Oj5b9RjojQo8npoLeA/bNwkOkrSQ0wgrHzXk4tDRxGKJeg==} + + '@aws-crypto/sha256-browser@5.2.0': + resolution: {integrity: sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==} + + '@aws-crypto/sha256-js@5.2.0': + resolution: {integrity: sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==} + engines: {node: '>=16.0.0'} + + '@aws-crypto/supports-web-crypto@5.2.0': + resolution: {integrity: sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==} + + '@aws-crypto/util@5.2.0': + resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==} + + '@aws-sdk/client-s3@3.651.1': + resolution: {integrity: sha512-xNm+ixNRcotyrHgjUGGEyara6kCKgDdW2EVjHBZa5T+tbmtyqezwH3UzbSDZ6MlNoLhJMfR7ozuwYTIOARoBfA==} + engines: {node: '>=16.0.0'} + + '@aws-sdk/client-sso-oidc@3.651.1': + resolution: {integrity: sha512-PKwAyTJW8pgaPIXm708haIZWBAwNycs25yNcD7OQ3NLcmgGxvrx6bSlhPEGcvwdTYwQMJsdx8ls+khlYbLqTvQ==} + engines: {node: '>=16.0.0'} + peerDependencies: + '@aws-sdk/client-sts': ^3.651.1 + + '@aws-sdk/client-sso@3.651.1': + resolution: {integrity: sha512-Fm8PoMgiBKmmKrY6QQUGj/WW6eIiQqC1I0AiVXfO+Sqkmxcg3qex+CZBAYrTuIDnvnc/89f9N4mdL8V9DRn03Q==} + engines: {node: '>=16.0.0'} + + '@aws-sdk/client-sts@3.651.1': + resolution: {integrity: sha512-4X2RqLqeDuVLk+Omt4X+h+Fa978Wn+zek/AM4HSPi4C5XzRBEFLRRtOQUvkETvIjbEwTYQhm0LdgzcBH4bUqIg==} + engines: {node: '>=16.0.0'} + + '@aws-sdk/core@3.651.1': + resolution: {integrity: sha512-eqOq3W39K+5QTP5GAXtmP2s9B7hhM2pVz8OPe5tqob8o1xQgkwdgHerf3FoshO9bs0LDxassU/fUSz1wlwqfqg==} + engines: {node: '>=16.0.0'} + + '@aws-sdk/credential-provider-env@3.649.0': + resolution: {integrity: sha512-tViwzM1dauksA3fdRjsg0T8mcHklDa8EfveyiQKK6pUJopkqV6FQx+X5QNda0t/LrdEVlFZvwHNdXqOEfc83TA==} + engines: {node: '>=16.0.0'} + + '@aws-sdk/credential-provider-http@3.649.0': + resolution: {integrity: sha512-ODAJ+AJJq6ozbns6ejGbicpsQ0dyMOpnGlg0J9J0jITQ05DKQZ581hdB8APDOZ9N8FstShP6dLZflSj8jb5fNA==} + engines: {node: '>=16.0.0'} + + '@aws-sdk/credential-provider-ini@3.651.1': + resolution: {integrity: sha512-yOzPC3GbwLZ8IYzke4fy70ievmunnBUni/MOXFE8c9kAIV+/RMC7IWx14nAAZm0gAcY+UtCXvBVZprFqmctfzA==} + engines: {node: '>=16.0.0'} + peerDependencies: + '@aws-sdk/client-sts': ^3.651.1 + + '@aws-sdk/credential-provider-node@3.651.1': + resolution: {integrity: sha512-QKA74Qs83FTUz3jS39kBuNbLAnm6cgDqomm7XS/BkYgtUq+1lI9WL97astNIuoYvumGIS58kuIa+I3ycOA4wgw==} + engines: {node: '>=16.0.0'} + + '@aws-sdk/credential-provider-process@3.649.0': + resolution: {integrity: sha512-6VYPQpEVpU+6DDS/gLoI40ppuNM5RPIEprK30qZZxnhTr5wyrGOeJ7J7wbbwPOZ5dKwta290BiJDU2ipV8Y9BQ==} + engines: {node: '>=16.0.0'} + + '@aws-sdk/credential-provider-sso@3.651.1': + resolution: {integrity: sha512-7jeU+Jbn65aDaNjkjWDQcXwjNTzpYNKovkSSRmfVpP5WYiKerVS5mrfg3RiBeiArou5igCUtYcOKlRJiGRO47g==} + engines: {node: '>=16.0.0'} + + '@aws-sdk/credential-provider-web-identity@3.649.0': + resolution: {integrity: sha512-XVk3WsDa0g3kQFPmnCH/LaCtGY/0R2NDv7gscYZSXiBZcG/fixasglTprgWSp8zcA0t7tEIGu9suyjz8ZwhymQ==} + engines: {node: '>=16.0.0'} + peerDependencies: + '@aws-sdk/client-sts': ^3.649.0 + + '@aws-sdk/middleware-bucket-endpoint@3.649.0': + resolution: {integrity: sha512-ZdDICtUU4YZkrVllTUOH1Fj/F3WShLhkfNKJE3HJ/yj6pS8JS9P2lWzHiHkHiidjrHSxc6NuBo6vuZ+182XLbw==} + engines: {node: '>=16.0.0'} + + '@aws-sdk/middleware-expect-continue@3.649.0': + resolution: {integrity: sha512-pW2id/mWNd+L0/hZKp5yL3J+8rTwsamu9E69Hc5pM3qTF4K4DTZZ+A0sQbY6duIvZvc8IbQHbSMulBOLyWNP3A==} + engines: {node: '>=16.0.0'} + + '@aws-sdk/middleware-flexible-checksums@3.651.1': + resolution: {integrity: sha512-cFlXSzhdRKU1vOFTIYC3HzkN7Dwwcf07rKU1sB/PrDy4ztLhGgAwvcRwj2AqErZB62C5AdN4l7peB1Iw/oSxRQ==} + engines: {node: '>=16.0.0'} + + '@aws-sdk/middleware-host-header@3.649.0': + resolution: {integrity: sha512-PjAe2FocbicHVgNNwdSZ05upxIO7AgTPFtQLpnIAmoyzMcgv/zNB5fBn3uAnQSAeEPPCD+4SYVEUD1hw1ZBvEg==} + engines: {node: '>=16.0.0'} + + '@aws-sdk/middleware-location-constraint@3.649.0': + resolution: {integrity: sha512-O9AXhaFUQx34UTnp/cKCcaWW/IVk4mntlWfFjsIxvRatamKaY33b5fOiakGG+J1t0QFK0niDBSvOYUR1fdlHzw==} + engines: {node: '>=16.0.0'} + + '@aws-sdk/middleware-logger@3.649.0': + resolution: {integrity: sha512-qdqRx6q7lYC6KL/NT9x3ShTL0TBuxdkCczGzHzY3AnOoYUjnCDH7Vlq867O6MAvb4EnGNECFzIgtkZkQ4FhY5w==} + engines: {node: '>=16.0.0'} + + '@aws-sdk/middleware-recursion-detection@3.649.0': + resolution: {integrity: sha512-IPnO4wlmaLRf6IYmJW2i8gJ2+UPXX0hDRv1it7Qf8DpBW+lGyF2rnoN7NrFX0WIxdGOlJF1RcOr/HjXb2QeXfQ==} + engines: {node: '>=16.0.0'} + + '@aws-sdk/middleware-sdk-s3@3.651.1': + resolution: {integrity: sha512-4BameU35aBSzrm3L/Iphc6vFLRhz6sBwgQf09mqPA2ZlX/YFqVe8HbS8wM4DG02W8A2MRTnHXRIfFoOrErp2sw==} + engines: {node: '>=16.0.0'} + + '@aws-sdk/middleware-ssec@3.649.0': + resolution: {integrity: sha512-r/WBIpX+Kcx+AV5vJ+LbdDOuibk7spBqcFK2LytQjOZKPksZNRAM99khbFe9vr9S1+uDmCLVjAVkIfQ5seJrOw==} + engines: {node: '>=16.0.0'} + + '@aws-sdk/middleware-user-agent@3.649.0': + resolution: {integrity: sha512-q6sO10dnCXoxe9thobMJxekhJumzd1j6dxcE1+qJdYKHJr6yYgWbogJqrLCpWd30w0lEvnuAHK8lN2kWLdJxJw==} + engines: {node: '>=16.0.0'} + + '@aws-sdk/region-config-resolver@3.649.0': + resolution: {integrity: sha512-xURBvdQXvRvca5Du8IlC5FyCj3pkw8Z75+373J3Wb+vyg8GjD14HfKk1Je1HCCQDyIE9VB/scYDcm9ri0ppePw==} + engines: {node: '>=16.0.0'} + + '@aws-sdk/signature-v4-multi-region@3.651.1': + resolution: {integrity: sha512-aLPCMq4c/A9DmdZLhufWOgfHN2Vgft65dB2tfbATjs6kZjusSaDFxWzjmWX3y8i2ZQ+vU0nAkkWIHFJdf+47fA==} + engines: {node: '>=16.0.0'} + + '@aws-sdk/token-providers@3.649.0': + resolution: {integrity: sha512-ZBqr+JuXI9RiN+4DSZykMx5gxpL8Dr3exIfFhxMiwAP3DQojwl0ub8ONjMuAjq9OvmX6n+jHZL6fBnNgnNFC8w==} + engines: {node: '>=16.0.0'} + peerDependencies: + '@aws-sdk/client-sso-oidc': ^3.649.0 + + '@aws-sdk/types@3.649.0': + resolution: {integrity: sha512-PuPw8RysbhJNlaD2d/PzOTf8sbf4Dsn2b7hwyGh7YVG3S75yTpxSAZxrnhKsz9fStgqFmnw/jUfV/G+uQAeTVw==} + engines: {node: '>=16.0.0'} + + '@aws-sdk/util-arn-parser@3.568.0': + resolution: {integrity: sha512-XUKJWWo+KOB7fbnPP0+g/o5Ulku/X53t7i/h+sPHr5xxYTJJ9CYnbToo95mzxe7xWvkLrsNtJ8L+MnNn9INs2w==} + engines: {node: '>=16.0.0'} + + '@aws-sdk/util-endpoints@3.649.0': + resolution: {integrity: sha512-bZI1Wc3R/KibdDVWFxX/N4AoJFG4VJ92Dp4WYmOrVD6VPkb8jPz7ZeiYc7YwPl8NoDjYyPneBV0lEoK/V8OKAA==} + 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.649.0': + resolution: {integrity: sha512-IY43r256LhKAvdEVQO/FPdUyVpcZS5EVxh/WHVdNzuN1bNLoUK2rIzuZqVA0EGguvCxoXVmQv9m50GvG7cGktg==} + + '@aws-sdk/util-user-agent-node@3.649.0': + resolution: {integrity: sha512-x5DiLpZDG/AJmCIBnE3Xhpwy35QIo3WqNiOpw6ExVs1NydbM/e90zFPSfhME0FM66D/WorigvluBxxwjxDm/GA==} + engines: {node: '>=16.0.0'} + peerDependencies: + aws-crt: '>=1.0.0' + peerDependenciesMeta: + aws-crt: + optional: true + + '@aws-sdk/xml-builder@3.649.0': + resolution: {integrity: sha512-XVESKkK7m5LdCVzZ3NvAja40BEyCrfPqtaiFAAhJIvW2U1Edyugf2o3XikuQY62crGT6BZagxJFgOiLKvuTiTg==} + engines: {node: '>=16.0.0'} + + '@babel/helper-string-parser@7.24.8': + resolution: {integrity: sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.24.7': + resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.25.6': + resolution: {integrity: sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/types@7.25.6': + resolution: {integrity: sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==} + engines: {node: '>=6.9.0'} + + '@clack/core@0.3.4': + resolution: {integrity: sha512-H4hxZDXgHtWTwV3RAVenqcC4VbJZNegbBjlPvzOzCouXtS2y3sDvlO3IsbrPNWuLWPPlYVYPghQdSF64683Ldw==} + + '@clack/prompts@0.7.0': + resolution: {integrity: sha512-0MhX9/B4iL6Re04jPrttDm+BsP8y6mS7byuv0BvXgdXhbV5PdlsHt55dvNsuBCPZ7xq1oTAOOuotR9NFbQyMSA==} + bundledDependencies: + - is-unicode-supported + + '@colors/colors@1.6.0': + resolution: {integrity: sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==} + engines: {node: '>=0.1.90'} + + '@cspotcode/source-map-support@0.8.1': + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + + '@dabh/diagnostics@2.0.3': + resolution: {integrity: sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==} + + '@docsearch/css@3.6.1': + resolution: {integrity: sha512-VtVb5DS+0hRIprU2CO6ZQjK2Zg4QU5HrDM1+ix6rT0umsYvFvatMAnf97NHZlVWDaaLlx7GRfR/7FikANiM2Fg==} + + '@docsearch/js@3.6.1': + resolution: {integrity: sha512-erI3RRZurDr1xES5hvYJ3Imp7jtrXj6f1xYIzDzxiS7nNBufYWPbJwrmMqWC5g9y165PmxEmN9pklGCdLi0Iqg==} + + '@docsearch/react@3.6.1': + resolution: {integrity: sha512-qXZkEPvybVhSXj0K7U3bXc233tk5e8PfhoZ6MhPOiik/qUQxYC+Dn9DnoS7CxHQQhHfCvTiN0eY9M12oRghEXw==} + peerDependencies: + '@types/react': '>= 16.8.0 < 19.0.0' + react: '>= 16.8.0 < 19.0.0' + react-dom: '>= 16.8.0 < 19.0.0' + search-insights: '>= 1 < 3' + peerDependenciesMeta: + '@types/react': + optional: true + react: + optional: true + react-dom: + optional: true + search-insights: + optional: true + + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@eslint-community/eslint-utils@4.4.0': + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.11.1': + resolution: {integrity: sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/config-array@0.18.0': + resolution: {integrity: sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/eslintrc@3.1.0': + resolution: {integrity: sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.10.0': + resolution: {integrity: sha512-fuXtbiP5GWIn8Fz+LWoOMVf/Jxm+aajZYkhi6CuEm4SxymFM+eUWzbO9qXT+L0iCkL5+KGYMCSGxo686H19S1g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.4': + resolution: {integrity: sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.1.0': + resolution: {integrity: sha512-autAXT203ixhqei9xt+qkYOvY8l6LAFIdT2UXc/RPNeUVfqRF1BV94GTJyVPFKT8nFM6MyVJhjLj9E8JWvf5zQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.3.0': + resolution: {integrity: sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==} + engines: {node: '>=18.18'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@jridgewell/trace-mapping@0.3.9': + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@rollup/rollup-android-arm-eabi@4.21.3': + resolution: {integrity: sha512-MmKSfaB9GX+zXl6E8z4koOr/xU63AMVleLEa64v7R0QF/ZloMs5vcD1sHgM64GXXS1csaJutG+ddtzcueI/BLg==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.21.3': + resolution: {integrity: sha512-zrt8ecH07PE3sB4jPOggweBjJMzI1JG5xI2DIsUbkA+7K+Gkjys6eV7i9pOenNSDJH3eOr/jLb/PzqtmdwDq5g==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.21.3': + resolution: {integrity: sha512-P0UxIOrKNBFTQaXTxOH4RxuEBVCgEA5UTNV6Yz7z9QHnUJ7eLX9reOd/NYMO3+XZO2cco19mXTxDMXxit4R/eQ==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.21.3': + resolution: {integrity: sha512-L1M0vKGO5ASKntqtsFEjTq/fD91vAqnzeaF6sfNAy55aD+Hi2pBI5DKwCO+UNDQHWsDViJLqshxOahXyLSh3EA==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-linux-arm-gnueabihf@4.21.3': + resolution: {integrity: sha512-btVgIsCjuYFKUjopPoWiDqmoUXQDiW2A4C3Mtmp5vACm7/GnyuprqIDPNczeyR5W8rTXEbkmrJux7cJmD99D2g==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.21.3': + resolution: {integrity: sha512-zmjbSphplZlau6ZTkxd3+NMtE4UKVy7U4aVFMmHcgO5CUbw17ZP6QCgyxhzGaU/wFFdTfiojjbLG3/0p9HhAqA==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.21.3': + resolution: {integrity: sha512-nSZfcZtAnQPRZmUkUQwZq2OjQciR6tEoJaZVFvLHsj0MF6QhNMg0fQ6mUOsiCUpTqxTx0/O6gX0V/nYc7LrgPw==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.21.3': + resolution: {integrity: sha512-MnvSPGO8KJXIMGlQDYfvYS3IosFN2rKsvxRpPO2l2cum+Z3exiExLwVU+GExL96pn8IP+GdH8Tz70EpBhO0sIQ==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-powerpc64le-gnu@4.21.3': + resolution: {integrity: sha512-+W+p/9QNDr2vE2AXU0qIy0qQE75E8RTwTwgqS2G5CRQ11vzq0tbnfBd6brWhS9bCRjAjepJe2fvvkvS3dno+iw==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.21.3': + resolution: {integrity: sha512-yXH6K6KfqGXaxHrtr+Uoy+JpNlUlI46BKVyonGiaD74ravdnF9BUNC+vV+SIuB96hUMGShhKV693rF9QDfO6nQ==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.21.3': + resolution: {integrity: sha512-R8cwY9wcnApN/KDYWTH4gV/ypvy9yZUHlbJvfaiXSB48JO3KpwSpjOGqO4jnGkLDSk1hgjYkTbTt6Q7uvPf8eg==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.21.3': + resolution: {integrity: sha512-kZPbX/NOPh0vhS5sI+dR8L1bU2cSO9FgxwM8r7wHzGydzfSjLRCFAT87GR5U9scj2rhzN3JPYVC7NoBbl4FZ0g==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.21.3': + resolution: {integrity: sha512-S0Yq+xA1VEH66uiMNhijsWAafffydd2X5b77eLHfRmfLsRSpbiAWiRHV6DEpz6aOToPsgid7TI9rGd6zB1rhbg==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-win32-arm64-msvc@4.21.3': + resolution: {integrity: sha512-9isNzeL34yquCPyerog+IMCNxKR8XYmGd0tHSV+OVx0TmE0aJOo9uw4fZfUuk2qxobP5sug6vNdZR6u7Mw7Q+Q==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.21.3': + resolution: {integrity: sha512-nMIdKnfZfzn1Vsk+RuOvl43ONTZXoAPUUxgcU0tXooqg4YrAqzfKzVenqqk2g5efWh46/D28cKFrOzDSW28gTA==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.21.3': + resolution: {integrity: sha512-fOvu7PCQjAj4eWDEuD8Xz5gpzFqXzGlxHZozHP4b9Jxv9APtdxL6STqztDzMLuRXEc4UpXGGhx029Xgm91QBeA==} + cpu: [x64] + os: [win32] + + '@shikijs/core@1.17.7': + resolution: {integrity: sha512-ZnIDxFu/yvje3Q8owSHaEHd+bu/jdWhHAaJ17ggjXofHx5rc4bhpCSW+OjC6smUBi5s5dd023jWtZ1gzMu/yrw==} + + '@shikijs/engine-javascript@1.17.7': + resolution: {integrity: sha512-wwSf7lKPsm+hiYQdX+1WfOXujtnUG6fnN4rCmExxa4vo+OTmvZ9B1eKauilvol/LHUPrQgW12G3gzem7pY5ckw==} + + '@shikijs/engine-oniguruma@1.17.7': + resolution: {integrity: sha512-pvSYGnVeEIconU28NEzBXqSQC/GILbuNbAHwMoSfdTBrobKAsV1vq2K4cAgiaW1TJceLV9QMGGh18hi7cCzbVQ==} + + '@shikijs/transformers@1.17.7': + resolution: {integrity: sha512-Nu7DaUT/qHDqbEsWBBqX6MyPMFbR4hUZcK11TA+zU/nPu9eDFE8v0p+n+eT4A3+3mxX6czMSF81W4QNsQ/NSpQ==} + + '@shikijs/types@1.17.7': + resolution: {integrity: sha512-+qA4UyhWLH2q4EFd+0z4K7GpERDU+c+CN2XYD3sC+zjvAr5iuwD1nToXZMt1YODshjkEGEDV86G7j66bKjqDdg==} + + '@shikijs/vscode-textmate@9.2.2': + resolution: {integrity: sha512-TMp15K+GGYrWlZM8+Lnj9EaHEFmOen0WJBrfa17hF7taDOYthuPPV0GWzfd/9iMij0akS/8Yw2ikquH7uVi/fg==} + + '@smithy/abort-controller@3.1.4': + resolution: {integrity: sha512-VupaALAQlXViW3/enTf/f5l5JZYSAxoJL7f0nanhNNKnww6DGCg1oYIuNP78KDugnkwthBO6iEcym16HhWV8RQ==} + engines: {node: '>=16.0.0'} + + '@smithy/chunked-blob-reader-native@3.0.0': + resolution: {integrity: sha512-VDkpCYW+peSuM4zJip5WDfqvg2Mo/e8yxOv3VF1m11y7B8KKMKVFtmZWDe36Fvk8rGuWrPZHHXZ7rR7uM5yWyg==} + + '@smithy/chunked-blob-reader@3.0.0': + resolution: {integrity: sha512-sbnURCwjF0gSToGlsBiAmd1lRCmSn72nu9axfJu5lIx6RUEgHu6GwTMbqCdhQSi0Pumcm5vFxsi9XWXb2mTaoA==} + + '@smithy/config-resolver@3.0.8': + resolution: {integrity: sha512-Tv1obAC18XOd2OnDAjSWmmthzx6Pdeh63FbLin8MlPiuJ2ATpKkq0NcNOJFr0dO+JmZXnwu8FQxKJ3TKJ3Hulw==} + engines: {node: '>=16.0.0'} + + '@smithy/core@2.4.3': + resolution: {integrity: sha512-4LTusLqFMRVQUfC3RNuTg6IzYTeJNpydRdTKq7J5wdEyIRQSu3rGIa3s80mgG2hhe6WOZl9IqTSo1pgbn6EHhA==} + engines: {node: '>=16.0.0'} + + '@smithy/credential-provider-imds@3.2.3': + resolution: {integrity: sha512-VoxMzSzdvkkjMJNE38yQgx4CfnmT+Z+5EUXkg4x7yag93eQkVQgZvN3XBSHC/ylfBbLbAtdu7flTCChX9I+mVg==} + engines: {node: '>=16.0.0'} + + '@smithy/eventstream-codec@3.1.5': + resolution: {integrity: sha512-6pu+PT2r+5ZnWEV3vLV1DzyrpJ0TmehQlniIDCSpZg6+Ji2SfOI38EqUyQ+O8lotVElCrfVc9chKtSMe9cmCZQ==} + + '@smithy/eventstream-serde-browser@3.0.9': + resolution: {integrity: sha512-PiQLo6OQmZAotJweIcObL1H44gkvuJACKMNqpBBe5Rf2Ax1DOcGi/28+feZI7yTe1ERHlQQaGnm8sSkyDUgsMg==} + engines: {node: '>=16.0.0'} + + '@smithy/eventstream-serde-config-resolver@3.0.6': + resolution: {integrity: sha512-iew15It+c7WfnVowWkt2a7cdPp533LFJnpjDQgfZQcxv2QiOcyEcea31mnrk5PVbgo0nNH3VbYGq7myw2q/F6A==} + engines: {node: '>=16.0.0'} + + '@smithy/eventstream-serde-node@3.0.8': + resolution: {integrity: sha512-6m+wI+fT0na+6oao6UqALVA38fsScCpoG5UO/A8ZSyGLnPM2i4MS1cFUhpuALgvLMxfYoTCh7qSeJa0aG4IWpQ==} + engines: {node: '>=16.0.0'} + + '@smithy/eventstream-serde-universal@3.0.8': + resolution: {integrity: sha512-09tqzIQ6e+7jLqGvRji1yJoDbL/zob0OFhq75edgStWErGLf16+yI5hRc/o9/YAybOhUZs/swpW2SPn892G5Gg==} + engines: {node: '>=16.0.0'} + + '@smithy/fetch-http-handler@3.2.7': + resolution: {integrity: sha512-Ra6IPI1spYLO+t62/3jQbodjOwAbto9wlpJdHZwkycm0Kit+GVpzHW/NMmSgY4rK1bjJ4qLAmCnaBzePO5Nkkg==} + + '@smithy/hash-blob-browser@3.1.5': + resolution: {integrity: sha512-Vi3eoNCmao4iKglS80ktYnBOIqZhjbDDwa1IIbF/VaJ8PsHnZTQ5wSicicPrU7nTI4JPFn92/txzWkh4GlK18Q==} + + '@smithy/hash-node@3.0.6': + resolution: {integrity: sha512-c/FHEdKK/7DU2z6ZE91L36ahyXWayR3B+FzELjnYq7wH5YqIseM24V+pWCS9kFn1Ln8OFGTf+pyYPiHZuX0s/Q==} + engines: {node: '>=16.0.0'} + + '@smithy/hash-stream-node@3.1.5': + resolution: {integrity: sha512-61CyFCzqN3VBfcnGX7mof/rkzLb8oHjm4Lr6ZwBIRpBssBb8d09ChrZAqinP2rUrA915BRNkq9NpJz18N7+3hQ==} + engines: {node: '>=16.0.0'} + + '@smithy/invalid-dependency@3.0.6': + resolution: {integrity: sha512-czM7Ioq3s8pIXht7oD+vmgy4Wfb4XavU/k/irO8NdXFFOx7YAlsCCcKOh/lJD1mJSYQqiR7NmpZ9JviryD/7AQ==} + + '@smithy/is-array-buffer@2.2.0': + resolution: {integrity: sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==} + engines: {node: '>=14.0.0'} + + '@smithy/is-array-buffer@3.0.0': + resolution: {integrity: sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ==} + engines: {node: '>=16.0.0'} + + '@smithy/md5-js@3.0.6': + resolution: {integrity: sha512-Ze690T8O3M5SVbb70WormwrKzVf9QQRtIuxtJDgpUQDkmt+PtdYDetBbyCbF9ryupxLw6tgzWKgwffAShhVIXQ==} + + '@smithy/middleware-content-length@3.0.8': + resolution: {integrity: sha512-VuyszlSO49WKh3H9/kIO2kf07VUwGV80QRiaDxUfP8P8UKlokz381ETJvwLhwuypBYhLymCYyNhB3fLAGBX2og==} + engines: {node: '>=16.0.0'} + + '@smithy/middleware-endpoint@3.1.3': + resolution: {integrity: sha512-KeM/OrK8MVFUsoJsmCN0MZMVPjKKLudn13xpgwIMpGTYpA8QZB2Xq5tJ+RE6iu3A6NhOI4VajDTwBsm8pwwrhg==} + engines: {node: '>=16.0.0'} + + '@smithy/middleware-retry@3.0.18': + resolution: {integrity: sha512-YU1o/vYob6vlqZdd97MN8cSXRToknLXhFBL3r+c9CZcnxkO/rgNZ++CfgX2vsmnEKvlqdi26+SRtSzlVp5z6Mg==} + engines: {node: '>=16.0.0'} + + '@smithy/middleware-serde@3.0.6': + resolution: {integrity: sha512-KKTUSl1MzOM0MAjGbudeaVNtIDo+PpekTBkCNwvfZlKndodrnvRo+00USatiyLOc0ujjO9UydMRu3O9dYML7ag==} + engines: {node: '>=16.0.0'} + + '@smithy/middleware-stack@3.0.6': + resolution: {integrity: sha512-2c0eSYhTQ8xQqHMcRxLMpadFbTXg6Zla5l0mwNftFCZMQmuhI7EbAJMx6R5eqfuV3YbJ3QGyS3d5uSmrHV8Khg==} + engines: {node: '>=16.0.0'} + + '@smithy/node-config-provider@3.1.7': + resolution: {integrity: sha512-g3mfnC3Oo8pOI0dYuPXLtdW1WGVb3bR2tkV21GNkm0ZvQjLTtamXAwCWt/FCb0HGvKt3gHHmF1XerG0ICfalOg==} + engines: {node: '>=16.0.0'} + + '@smithy/node-http-handler@3.2.2': + resolution: {integrity: sha512-42Cy4/oT2O+00aiG1iQ7Kd7rE6q8j7vI0gFfnMlUiATvyo8vefJkhb7O10qZY0jAqo5WZdUzfl9IV6wQ3iMBCg==} + engines: {node: '>=16.0.0'} + + '@smithy/property-provider@3.1.6': + resolution: {integrity: sha512-NK3y/T7Q/Bw+Z8vsVs9MYIQ5v7gOX7clyrXcwhhIBQhbPgRl6JDrZbusO9qWDhcEus75Tg+VCxtIRfo3H76fpw==} + engines: {node: '>=16.0.0'} + + '@smithy/protocol-http@4.1.3': + resolution: {integrity: sha512-GcbMmOYpH9iRqtC05RbRnc/0FssxSTHlmaNhYBTgSgNCYpdR3Kt88u5GAZTBmouzv+Zlj/VRv92J9ruuDeJuEw==} + engines: {node: '>=16.0.0'} + + '@smithy/querystring-builder@3.0.6': + resolution: {integrity: sha512-sQe08RunoObe+Usujn9+R2zrLuQERi3CWvRO3BvnoWSYUaIrLKuAIeY7cMeDax6xGyfIP3x/yFWbEKSXvOnvVg==} + engines: {node: '>=16.0.0'} + + '@smithy/querystring-parser@3.0.6': + resolution: {integrity: sha512-UJKw4LlEkytzz2Wq+uIdHf6qOtFfee/o7ruH0jF5I6UAuU+19r9QV7nU3P/uI0l6+oElRHmG/5cBBcGJrD7Ozg==} + engines: {node: '>=16.0.0'} + + '@smithy/service-error-classification@3.0.6': + resolution: {integrity: sha512-53SpchU3+DUZrN7J6sBx9tBiCVGzsib2e4sc512Q7K9fpC5zkJKs6Z9s+qbMxSYrkEkle6hnMtrts7XNkMJJMg==} + engines: {node: '>=16.0.0'} + + '@smithy/shared-ini-file-loader@3.1.7': + resolution: {integrity: sha512-IA4K2qTJYXkF5OfVN4vsY1hfnUZjaslEE8Fsr/gGFza4TAC2A9NfnZuSY2srQIbt9bwtjHiAayrRVgKse4Q7fA==} + engines: {node: '>=16.0.0'} + + '@smithy/signature-v4@4.1.3': + resolution: {integrity: sha512-YD2KYSCEEeFHcWZ1E3mLdAaHl8T/TANh6XwmocQ6nPcTdBfh4N5fusgnblnWDlnlU1/cUqEq3PiGi22GmT2Lkg==} + engines: {node: '>=16.0.0'} + + '@smithy/smithy-client@3.3.2': + resolution: {integrity: sha512-RKDfhF2MTwXl7jan5d7QfS9eCC6XJbO3H+EZAvLQN8A5in4ib2Ml4zoeLo57w9QrqFekBPcsoC2hW3Ekw4vQ9Q==} + engines: {node: '>=16.0.0'} + + '@smithy/types@3.4.2': + resolution: {integrity: sha512-tHiFcfcVedVBHpmHUEUHOCCih8iZbIAYn9NvPsNzaPm/237I3imdDdZoOC8c87H5HBAVEa06tTgb+OcSWV9g5w==} + engines: {node: '>=16.0.0'} + + '@smithy/url-parser@3.0.6': + resolution: {integrity: sha512-47Op/NU8Opt49KyGpHtVdnmmJMsp2hEwBdyjuFB9M2V5QVOwA7pBhhxKN5z6ztKGrMw76gd8MlbPuzzvaAncuQ==} + + '@smithy/util-base64@3.0.0': + resolution: {integrity: sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==} + engines: {node: '>=16.0.0'} + + '@smithy/util-body-length-browser@3.0.0': + resolution: {integrity: sha512-cbjJs2A1mLYmqmyVl80uoLTJhAcfzMOyPgjwAYusWKMdLeNtzmMz9YxNl3/jRLoxSS3wkqkf0jwNdtXWtyEBaQ==} + + '@smithy/util-body-length-node@3.0.0': + resolution: {integrity: sha512-Tj7pZ4bUloNUP6PzwhN7K386tmSmEET9QtQg0TgdNOnxhZvCssHji+oZTUIuzxECRfG8rdm2PMw2WCFs6eIYkA==} + engines: {node: '>=16.0.0'} + + '@smithy/util-buffer-from@2.2.0': + resolution: {integrity: sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==} + engines: {node: '>=14.0.0'} + + '@smithy/util-buffer-from@3.0.0': + resolution: {integrity: sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA==} + engines: {node: '>=16.0.0'} + + '@smithy/util-config-provider@3.0.0': + resolution: {integrity: sha512-pbjk4s0fwq3Di/ANL+rCvJMKM5bzAQdE5S/6RL5NXgMExFAi6UgQMPOm5yPaIWPpr+EOXKXRonJ3FoxKf4mCJQ==} + engines: {node: '>=16.0.0'} + + '@smithy/util-defaults-mode-browser@3.0.18': + resolution: {integrity: sha512-/eveCzU6Z6Yw8dlYQLA4rcK30XY0E4L3lD3QFHm59mzDaWYelrXE1rlynuT3J6qxv+5yNy3a1JuzhG5hk5hcmw==} + engines: {node: '>= 10.0.0'} + + '@smithy/util-defaults-mode-node@3.0.18': + resolution: {integrity: sha512-9cfzRjArtOFPlTYRREJk00suUxVXTgbrzVncOyMRTUeMKnecG/YentLF3cORa+R6mUOMSrMSnT18jos1PKqK6Q==} + engines: {node: '>= 10.0.0'} + + '@smithy/util-endpoints@2.1.2': + resolution: {integrity: sha512-FEISzffb4H8DLzGq1g4MuDpcv6CIG15fXoQzDH9SjpRJv6h7J++1STFWWinilG0tQh9H1v2UKWG19Jjr2B16zQ==} + 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.6': + resolution: {integrity: sha512-BxbX4aBhI1O9p87/xM+zWy0GzT3CEVcXFPBRDoHAM+pV0eSW156pR+PSYEz0DQHDMYDsYAflC2bQNz2uaDBUZQ==} + engines: {node: '>=16.0.0'} + + '@smithy/util-retry@3.0.6': + resolution: {integrity: sha512-BRZiuF7IwDntAbevqMco67an0Sr9oLQJqqRCsSPZZHYRnehS0LHDAkJk/pSmI7Z8c/1Vet294H7fY2fWUgB+Rg==} + engines: {node: '>=16.0.0'} + + '@smithy/util-stream@3.1.6': + resolution: {integrity: sha512-lQEUfTx1ht5CRdvIjdAN/gUL6vQt2wSARGGLaBHNe+iJSkRHlWzY+DOn0mFTmTgyU3jcI5n9DkT5gTzYuSOo6A==} + engines: {node: '>=16.0.0'} + + '@smithy/util-uri-escape@3.0.0': + resolution: {integrity: sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==} + engines: {node: '>=16.0.0'} + + '@smithy/util-utf8@2.3.0': + resolution: {integrity: sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==} + engines: {node: '>=14.0.0'} + + '@smithy/util-utf8@3.0.0': + resolution: {integrity: sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA==} + engines: {node: '>=16.0.0'} + + '@smithy/util-waiter@3.1.5': + resolution: {integrity: sha512-jYOSvM3H6sZe3CHjzD2VQNCjWBJs+4DbtwBMvUp9y5EnnwNa7NQxTeYeQw0CKCAdGGZ3QvVkyJmvbvs5M/B10A==} + engines: {node: '>=16.0.0'} + + '@tsconfig/node10@1.0.11': + resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} + + '@tsconfig/node12@1.0.11': + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + + '@tsconfig/node14@1.0.3': + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + + '@tsconfig/node16@1.0.4': + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + + '@types/body-parser@1.19.5': + resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} + + '@types/connect@3.4.38': + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + + '@types/estree@1.0.5': + resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + + '@types/express-serve-static-core@4.19.5': + resolution: {integrity: sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==} + + '@types/express@4.17.21': + resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==} + + '@types/hast@3.0.4': + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + + '@types/http-errors@2.0.4': + resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==} + + '@types/linkify-it@5.0.0': + resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==} + + '@types/markdown-it@14.1.2': + resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==} + + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + + '@types/mdurl@2.0.0': + resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==} + + '@types/mime@1.3.5': + resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} + + '@types/node@18.19.50': + resolution: {integrity: sha512-xonK+NRrMBRtkL1hVCc3G+uXtjh1Al4opBLjqVmipe5ZAaBYWW6cNAiBVZ1BvmkBhep698rP3UM3aRAdSALuhg==} + + '@types/nodemailer@6.4.15': + resolution: {integrity: sha512-0EBJxawVNjPkng1zm2vopRctuWVCxk34JcIlRuXSf54habUWdz1FB7wHDqOqvDa8Mtpt0Q3LTXQkAs2LNyK5jQ==} + + '@types/qs@6.9.16': + resolution: {integrity: sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A==} + + '@types/range-parser@1.2.7': + resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} + + '@types/send@0.17.4': + resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==} + + '@types/serve-static@1.15.7': + resolution: {integrity: sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==} + + '@types/strip-bom@3.0.0': + resolution: {integrity: sha512-xevGOReSYGM7g/kUBZzPqCrR/KYAo+F0yiPc85WFTJa0MSLtyFTVTU6cJu/aV4mid7IffDIWqo69THF2o4JiEQ==} + + '@types/strip-json-comments@0.0.30': + resolution: {integrity: sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==} + + '@types/triple-beam@1.3.5': + resolution: {integrity: sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==} + + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + + '@types/web-bluetooth@0.0.20': + resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==} + + '@typescript-eslint/eslint-plugin@8.6.0': + resolution: {integrity: sha512-UOaz/wFowmoh2G6Mr9gw60B1mm0MzUtm6Ic8G2yM1Le6gyj5Loi/N+O5mocugRGY+8OeeKmkMmbxNqUCq3B4Sg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/parser@8.6.0': + resolution: {integrity: sha512-eQcbCuA2Vmw45iGfcyG4y6rS7BhWfz9MQuk409WD47qMM+bKCGQWXxvoOs1DUp+T7UBMTtRTVT+kXr7Sh4O9Ow==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/scope-manager@8.6.0': + resolution: {integrity: sha512-ZuoutoS5y9UOxKvpc/GkvF4cuEmpokda4wRg64JEia27wX+PysIE9q+lzDtlHHgblwUWwo5/Qn+/WyTUvDwBHw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/type-utils@8.6.0': + resolution: {integrity: sha512-dtePl4gsuenXVwC7dVNlb4mGDcKjDT/Ropsk4za/ouMBPplCLyznIaR+W65mvCvsyS97dymoBRrioEXI7k0XIg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/types@8.6.0': + resolution: {integrity: sha512-rojqFZGd4MQxw33SrOy09qIDS8WEldM8JWtKQLAjf/X5mGSeEFh5ixQlxssMNyPslVIk9yzWqXCsV2eFhYrYUw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.6.0': + resolution: {integrity: sha512-MOVAzsKJIPIlLK239l5s06YXjNqpKTVhBVDnqUumQJja5+Y94V3+4VUFRA0G60y2jNnTVwRCkhyGQpavfsbq/g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/utils@8.6.0': + resolution: {integrity: sha512-eNp9cWnYf36NaOVjkEUznf6fEgVy1TWpE0o52e4wtojjBx7D1UV2WAWGzR+8Y5lVFtpMLPwNbC67T83DWSph4A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + + '@typescript-eslint/visitor-keys@8.6.0': + resolution: {integrity: sha512-wapVFfZg9H0qOYh4grNVQiMklJGluQrOUiOhYRrQWhx7BY/+I1IYb8BczWNbbUpO+pqy0rDciv3lQH5E1bCLrg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@ungap/structured-clone@1.2.0': + resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + + '@vitejs/plugin-vue@5.1.3': + resolution: {integrity: sha512-3xbWsKEKXYlmX82aOHufFQVnkbMC/v8fLpWwh6hWOUrK5fbbtBh9Q/WWse27BFgSy2/e2c0fz5Scgya9h2GLhw==} + engines: {node: ^18.0.0 || >=20.0.0} + peerDependencies: + vite: ^5.0.0 + vue: ^3.2.25 + + '@vue/compiler-core@3.5.6': + resolution: {integrity: sha512-r+gNu6K4lrvaQLQGmf+1gc41p3FO2OUJyWmNqaIITaJU6YFiV5PtQSFZt8jfztYyARwqhoCayjprC7KMvT3nRA==} + + '@vue/compiler-dom@3.5.6': + resolution: {integrity: sha512-xRXqxDrIqK8v8sSScpistyYH0qYqxakpsIvqMD2e5sV/PXQ1mTwtXp4k42yHK06KXxKSmitop9e45Ui/3BrTEw==} + + '@vue/compiler-sfc@3.5.6': + resolution: {integrity: sha512-pjWJ8Kj9TDHlbF5LywjVso+BIxCY5wVOLhkEXRhuCHDxPFIeX1zaFefKs8RYoHvkSMqRWt93a0f2gNJVJixHwg==} + + '@vue/compiler-ssr@3.5.6': + resolution: {integrity: sha512-VpWbaZrEOCqnmqjE83xdwegtr5qO/2OPUC6veWgvNqTJ3bYysz6vY3VqMuOijubuUYPRpG3OOKIh9TD0Stxb9A==} + + '@vue/devtools-api@7.4.5': + resolution: {integrity: sha512-PX9uXirHOY2P99kb1cP3DxWZojFW3acNMqd+l4i5nKcqY59trXTOfwDZXt2Qifu0OU1izAQb76Ur6NPVldF2KQ==} + + '@vue/devtools-kit@7.4.5': + resolution: {integrity: sha512-Uuki4Z6Bc/ExvtlPkeDNGSAe4580R+HPcVABfTE9TF7BTz3Nntk7vxIRUyWblZkUEcB/x+wn2uofyt5i2LaUew==} + + '@vue/devtools-shared@7.4.5': + resolution: {integrity: sha512-2XgUOkL/7QDmyYI9J7cm+rz/qBhcGv+W5+i1fhwdQ0HQ1RowhdK66F0QBuJSz/5k12opJY8eN6m03/XZMs7imQ==} + + '@vue/reactivity@3.5.6': + resolution: {integrity: sha512-shZ+KtBoHna5GyUxWfoFVBCVd7k56m6lGhk5e+J9AKjheHF6yob5eukssHRI+rzvHBiU1sWs/1ZhNbLExc5oYQ==} + + '@vue/runtime-core@3.5.6': + resolution: {integrity: sha512-FpFULR6+c2lI+m1fIGONLDqPQO34jxV8g6A4wBOgne8eSRHP6PQL27+kWFIx5wNhhjkO7B4rgtsHAmWv7qKvbg==} + + '@vue/runtime-dom@3.5.6': + resolution: {integrity: sha512-SDPseWre45G38ENH2zXRAHL1dw/rr5qp91lS4lt/nHvMr0MhsbCbihGAWLXNB/6VfFOJe2O+RBRkXU+CJF7/sw==} + + '@vue/server-renderer@3.5.6': + resolution: {integrity: sha512-zivnxQnOnwEXVaT9CstJ64rZFXMS5ZkKxCjDQKiMSvUhXRzFLWZVbaBiNF4HGDqGNNsTgmjcCSmU6TB/0OOxLA==} + peerDependencies: + vue: 3.5.6 + + '@vue/shared@3.5.6': + resolution: {integrity: sha512-eidH0HInnL39z6wAt6SFIwBrvGOpDWsDxlw3rCgo1B+CQ1781WzQUSU3YjxgdkcJo9Q8S6LmXTkvI+cLHGkQfA==} + + '@vueuse/core@11.1.0': + resolution: {integrity: sha512-P6dk79QYA6sKQnghrUz/1tHi0n9mrb/iO1WTMk/ElLmTyNqgDeSZ3wcDf6fRBGzRJbeG1dxzEOvLENMjr+E3fg==} + + '@vueuse/integrations@11.1.0': + resolution: {integrity: sha512-O2ZgrAGPy0qAjpoI2YR3egNgyEqwG85fxfwmA9BshRIGjV4G6yu6CfOPpMHAOoCD+UfsIl7Vb1bXJ6ifrHYDDA==} + peerDependencies: + async-validator: ^4 + axios: ^1 + change-case: ^5 + drauu: ^0.4 + focus-trap: ^7 + fuse.js: ^7 + idb-keyval: ^6 + jwt-decode: ^4 + nprogress: ^0.2 + qrcode: ^1.5 + sortablejs: ^1 + universal-cookie: ^7 + peerDependenciesMeta: + async-validator: + optional: true + axios: + optional: true + change-case: + optional: true + drauu: + optional: true + focus-trap: + optional: true + fuse.js: + optional: true + idb-keyval: + optional: true + jwt-decode: + optional: true + nprogress: + optional: true + qrcode: + optional: true + sortablejs: + optional: true + universal-cookie: + optional: true + + '@vueuse/metadata@11.1.0': + resolution: {integrity: sha512-l9Q502TBTaPYGanl1G+hPgd3QX5s4CGnpXriVBR5fEZ/goI6fvDaVmIl3Td8oKFurOxTmbXvBPSsgrd6eu6HYg==} + + '@vueuse/shared@11.1.0': + resolution: {integrity: sha512-YUtIpY122q7osj+zsNMFAfMTubGz0sn5QzE5gPzAIiCmtt2ha3uQUY1+JPyL4gRCTsLPX82Y9brNbo/aqlA91w==} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn-walk@8.3.4: + resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} + engines: {node: '>=0.4.0'} + + acorn@8.12.1: + resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==} + engines: {node: '>=0.4.0'} + hasBin: true + + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + + algoliasearch@4.24.0: + resolution: {integrity: sha512-bf0QV/9jVejssFBmz2HQLxUadxk574t4iwjCKp5E7NBzwKkrDEhKPISIIjAU/p6K5qDx3qoeh4+26zWN1jmw3g==} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + async@3.2.6: + resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + birpc@0.2.17: + resolution: {integrity: sha512-+hkTxhot+dWsLpp3gia5AkVHIsKlZybNT5gIYiDlNzJrmYPcTM9k5/w2uaj3IPpd7LlEYpmCj4Jj1nC41VhDFg==} + + bowser@2.11.0: + resolution: {integrity: sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + + character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + class-transformer@0.5.1: + resolution: {integrity: sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==} + + color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + + color@3.2.1: + resolution: {integrity: sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==} + + colorspace@1.1.4: + resolution: {integrity: sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==} + + comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + + commander@12.1.0: + resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} + engines: {node: '>=18'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + copy-anything@3.0.5: + resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==} + engines: {node: '>=12.13'} + + create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + + cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + debug@4.3.7: + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + + diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + + dynamic-dedupe@0.3.0: + resolution: {integrity: sha512-ssuANeD+z97meYOqd50e04Ze5qp4bPqo8cCkI4TRjZkzAUgIDTrXV1R8QCdINpiI+hw14+rYazvTRdQrz0/rFQ==} + + enabled@2.0.0: + resolution: {integrity: sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-scope@8.0.2: + resolution: {integrity: sha512-6E4xmrTw5wtxnLA5wYL3WDfhZ/1bUBGOXV0zQvVRDOtrR8D0p6W7fs3JweNYhwRYeGvd/1CKX2se0/2s7Q/nJA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.0.0: + resolution: {integrity: sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint@9.10.0: + resolution: {integrity: sha512-Y4D0IgtBZfOcOUAIQTSXBKoNGfY0REGqHJG6+Q81vNippW5YlKjHFj4soMxamKK1NXHUWuBZTLdU3Km+L/pcHw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@10.1.0: + resolution: {integrity: sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fast-xml-parser@4.4.1: + resolution: {integrity: sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==} + hasBin: true + + fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + + fecha@4.2.3: + resolution: {integrity: sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==} + + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + + flatted@3.3.1: + resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} + + fn.name@1.1.0: + resolution: {integrity: sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==} + + focus-trap@7.6.0: + resolution: {integrity: sha512-1td0l3pMkWJLFipobUcGaf+5DTY4PLDDrcqoSaKP8ediO/CoWCCYk/fT/Y2A4e6TNB+Sh6clRJCjOPPnKoNHnQ==} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported + + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + globals@15.9.0: + resolution: {integrity: sha512-SmSKyLLKFbSr6rptvP8izbyxJL4ILwqO9Jg23UA0sDlGlu58V59D1//I3vlc0KJphVdUR7vMjHIplYnzBxorQA==} + engines: {node: '>=18'} + + graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + hast-util-to-html@9.0.3: + resolution: {integrity: sha512-M17uBDzMJ9RPCqLMO92gNNUDuBSq10a25SDBI08iCCxmorf4Yy6sYHK57n9WAbRAAaU+DuR4W6GN9K4DFZesYg==} + + hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + + hookable@5.5.3: + resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} + + html-void-elements@3.0.0: + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + + husky@9.1.6: + resolution: {integrity: sha512-sqbjZKK7kf44hfdE94EoX8MZNk0n7HeW37O4YrVGCF4wzgQjp+akPAkfUK5LZ6KuR/6sqeAVuXHji+RzQgOn5A==} + engines: {node: '>=18'} + hasBin: true + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + is-arrayish@0.3.2: + resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-core-module@2.15.1: + resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==} + engines: {node: '>= 0.4'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + + is-what@4.1.16: + resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==} + engines: {node: '>=12.13'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + kuler@2.0.0: + resolution: {integrity: sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + logform@2.6.1: + resolution: {integrity: sha512-CdaO738xRapbKIMVn2m4F6KTj4j7ooJ8POVnebSgKo3KBz5axNXRAL7ZdRjIV6NOr2Uf4vjtRkxrFETOioCqSA==} + engines: {node: '>= 12.0.0'} + + magic-string@0.30.11: + resolution: {integrity: sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==} + + make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + + mark.js@8.11.1: + resolution: {integrity: sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==} + + mdast-util-to-hast@13.2.0: + resolution: {integrity: sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromark-util-character@2.1.0: + resolution: {integrity: sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==} + + micromark-util-encode@2.0.0: + resolution: {integrity: sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==} + + micromark-util-sanitize-uri@2.0.0: + resolution: {integrity: sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==} + + micromark-util-symbol@2.0.0: + resolution: {integrity: sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==} + + micromark-util-types@2.0.0: + resolution: {integrity: sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minisearch@7.1.0: + resolution: {integrity: sha512-tv7c/uefWdEhcu6hvrfTihflgeEi2tN6VV7HJnCjK6VxM75QQJh4t9FwJCsA2EsRS8LCnu3W87CuGPWMocOLCA==} + + mitt@3.0.1: + resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} + + mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + nodemailer@6.9.15: + resolution: {integrity: sha512-AHf04ySLC6CIfuRtRiEYtGEXgRfa6INgWGluDhnxTZhHSKvrBu7lc1VVchQ0d8nPc4cFaZoPq8vkyNoZr0TpGQ==} + engines: {node: '>=6.0.0'} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + one-time@1.0.0: + resolution: {integrity: sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==} + + oniguruma-to-js@0.4.3: + resolution: {integrity: sha512-X0jWUcAlxORhOqqBREgPMgnshB7ZGYszBNspP+tS9hPD3l13CdaXcHbgImoHUHlrvGx/7AvFEkTRhAGYh+jzjQ==} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + perfect-debounce@1.0.0: + resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} + + picocolors@1.1.0: + resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + postcss@8.4.47: + resolution: {integrity: sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==} + engines: {node: ^10 || ^12 || >=14} + + preact@10.24.0: + resolution: {integrity: sha512-aK8Cf+jkfyuZ0ZZRG9FbYqwmEiGQ4y/PUO4SuTWoyWL244nZZh7bd5h2APd4rSNDYTBNghg1L+5iJN3Skxtbsw==} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + property-information@6.5.0: + resolution: {integrity: sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + regex@4.3.2: + resolution: {integrity: sha512-kK/AA3A9K6q2js89+VMymcboLOlF5lZRCYJv3gzszXFHBr6kO6qLGzbm+UIugBEV8SMMKCTR59txoY6ctRHYVw==} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} + hasBin: true + + reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rfdc@1.4.1: + resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} + + rimraf@2.7.1: + resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + rollup@4.21.3: + resolution: {integrity: sha512-7sqRtBNnEbcBtMeRVc6VRsJMmpI+JU1z9VTvW8D4gXIYQFz0aLcsE6rRkyghZkLfEgUZgVvOG7A5CVz/VW5GIA==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safe-stable-stringify@2.5.0: + resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} + engines: {node: '>=10'} + + search-insights@2.17.2: + resolution: {integrity: sha512-zFNpOpUO+tY2D85KrxJ+aqwnIfdEGi06UH2+xEb+Bp9Mwznmauqc9djbnBibJO5mpfUPPa8st6Sx65+vbeO45g==} + + semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} + engines: {node: '>=10'} + hasBin: true + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + shiki@1.17.7: + resolution: {integrity: sha512-Zf6hNtWhFyF4XP5OOsXkBTEx9JFPiN0TQx4wSe+Vqeuczewgk2vT4IZhF4gka55uelm052BD5BaHavNqUNZd+A==} + + simple-swizzle@0.2.2: + resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} + + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + + speakingurl@14.0.1: + resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==} + engines: {node: '>=0.10.0'} + + stack-trace@0.0.10: + resolution: {integrity: sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + stringify-entities@4.0.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + strnum@1.0.5: + resolution: {integrity: sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==} + + superjson@2.2.1: + resolution: {integrity: sha512-8iGv75BYOa0xRJHK5vRLEjE2H/i4lulTjzpUXic3Eg8akftYjkmQDa8JARQ42rlczXyFR3IeRoeFCc7RxHsYZA==} + engines: {node: '>=16'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + tabbable@6.2.0: + resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} + + text-hex@1.0.0: + resolution: {integrity: sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==} + + text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + + to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + + trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + + triple-beam@1.4.1: + resolution: {integrity: sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==} + engines: {node: '>= 14.0.0'} + + ts-api-utils@1.3.0: + resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} + engines: {node: '>=16'} + peerDependencies: + typescript: '>=4.2.0' + + ts-node-dev@2.0.0: + resolution: {integrity: sha512-ywMrhCfH6M75yftYvrvNarLEY+SUXtUvU8/0Z6llrHQVBx12GiFk5sStF8UdfE/yfzk9IAq7O5EEbTQsxlBI8w==} + engines: {node: '>=0.8.0'} + hasBin: true + peerDependencies: + node-notifier: '*' + typescript: '*' + peerDependenciesMeta: + node-notifier: + optional: true + + ts-node@10.9.2: + resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + + tsconfig@7.0.0: + resolution: {integrity: sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==} + + tslib@2.7.0: + resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + typescript-eslint@8.6.0: + resolution: {integrity: sha512-eEhhlxCEpCd4helh3AO1hk0UP2MvbRi9CtIAJTVPQjuSXOOO2jsEacNi4UdcJzZJbeuVg1gMhtZ8UYb+NFYPrA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + typescript@5.6.2: + resolution: {integrity: sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==} + engines: {node: '>=14.17'} + hasBin: true + + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + + unist-util-is@6.0.0: + resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==} + + unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-parents@6.0.1: + resolution: {integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==} + + unist-util-visit@5.0.0: + resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + uuid@9.0.1: + resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + hasBin: true + + v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + + vfile-message@4.0.2: + resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==} + + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + + vite@5.4.6: + resolution: {integrity: sha512-IeL5f8OO5nylsgzd9tq4qD2QqI0k2CQLGrWD0rCN0EQJZpBK5vJAx0I+GDkMOXxQX/OfFHMuLIx6ddAxGX/k+Q==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + vitepress@1.3.4: + resolution: {integrity: sha512-I1/F6OW1xl3kW4PaIMC6snxjWgf3qfziq2aqsDoFc/Gt41WbcRv++z8zjw8qGRIJ+I4bUW7ZcKFDHHN/jkH9DQ==} + hasBin: true + peerDependencies: + markdown-it-mathjax3: ^4 + postcss: ^8 + peerDependenciesMeta: + markdown-it-mathjax3: + optional: true + postcss: + optional: true + + vue-demi@0.14.10: + resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==} + engines: {node: '>=12'} + hasBin: true + peerDependencies: + '@vue/composition-api': ^1.0.0-rc.1 + vue: ^3.0.0-0 || ^2.6.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + + vue@3.5.6: + resolution: {integrity: sha512-zv+20E2VIYbcJOzJPUWp03NOGFhMmpCKOfSxVTmCYyYFFko48H9tmuQFzYj7tu4qX1AeXlp9DmhIP89/sSxxhw==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + winston-transport@4.7.1: + resolution: {integrity: sha512-wQCXXVgfv/wUPOfb2x0ruxzwkcZfxcktz6JIMUaPLmcNhO4bZTwA/WtDWK74xV3F2dKu8YadrFv0qhwYjVEwhA==} + engines: {node: '>= 12.0.0'} + + winston@3.14.2: + resolution: {integrity: sha512-CO8cdpBB2yqzEf8v895L+GNKYJiEq8eKlHU38af3snQBQ+sdAIUepjMSguOIJC7ICbzm0ZI+Af2If4vIJrtmOg==} + engines: {node: '>= 12.0.0'} + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + + yaml@2.5.1: + resolution: {integrity: sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==} + engines: {node: '>= 14'} + hasBin: true + + yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + +snapshots: + + '@algolia/autocomplete-core@1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)(search-insights@2.17.2)': + dependencies: + '@algolia/autocomplete-plugin-algolia-insights': 1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)(search-insights@2.17.2) + '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0) + transitivePeerDependencies: + - '@algolia/client-search' + - algoliasearch + - search-insights + + '@algolia/autocomplete-plugin-algolia-insights@1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)(search-insights@2.17.2)': + dependencies: + '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0) + search-insights: 2.17.2 + transitivePeerDependencies: + - '@algolia/client-search' + - algoliasearch + + '@algolia/autocomplete-preset-algolia@1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)': + dependencies: + '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0) + '@algolia/client-search': 4.24.0 + algoliasearch: 4.24.0 + + '@algolia/autocomplete-shared@1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)': + dependencies: + '@algolia/client-search': 4.24.0 + algoliasearch: 4.24.0 + + '@algolia/cache-browser-local-storage@4.24.0': + dependencies: + '@algolia/cache-common': 4.24.0 + + '@algolia/cache-common@4.24.0': {} + + '@algolia/cache-in-memory@4.24.0': + dependencies: + '@algolia/cache-common': 4.24.0 + + '@algolia/client-account@4.24.0': + dependencies: + '@algolia/client-common': 4.24.0 + '@algolia/client-search': 4.24.0 + '@algolia/transporter': 4.24.0 + + '@algolia/client-analytics@4.24.0': + dependencies: + '@algolia/client-common': 4.24.0 + '@algolia/client-search': 4.24.0 + '@algolia/requester-common': 4.24.0 + '@algolia/transporter': 4.24.0 + + '@algolia/client-common@4.24.0': + dependencies: + '@algolia/requester-common': 4.24.0 + '@algolia/transporter': 4.24.0 + + '@algolia/client-personalization@4.24.0': + dependencies: + '@algolia/client-common': 4.24.0 + '@algolia/requester-common': 4.24.0 + '@algolia/transporter': 4.24.0 + + '@algolia/client-search@4.24.0': + dependencies: + '@algolia/client-common': 4.24.0 + '@algolia/requester-common': 4.24.0 + '@algolia/transporter': 4.24.0 + + '@algolia/logger-common@4.24.0': {} + + '@algolia/logger-console@4.24.0': + dependencies: + '@algolia/logger-common': 4.24.0 + + '@algolia/recommend@4.24.0': + dependencies: + '@algolia/cache-browser-local-storage': 4.24.0 + '@algolia/cache-common': 4.24.0 + '@algolia/cache-in-memory': 4.24.0 + '@algolia/client-common': 4.24.0 + '@algolia/client-search': 4.24.0 + '@algolia/logger-common': 4.24.0 + '@algolia/logger-console': 4.24.0 + '@algolia/requester-browser-xhr': 4.24.0 + '@algolia/requester-common': 4.24.0 + '@algolia/requester-node-http': 4.24.0 + '@algolia/transporter': 4.24.0 + + '@algolia/requester-browser-xhr@4.24.0': + dependencies: + '@algolia/requester-common': 4.24.0 + + '@algolia/requester-common@4.24.0': {} + + '@algolia/requester-node-http@4.24.0': + dependencies: + '@algolia/requester-common': 4.24.0 + + '@algolia/transporter@4.24.0': + dependencies: + '@algolia/cache-common': 4.24.0 + '@algolia/logger-common': 4.24.0 + '@algolia/requester-common': 4.24.0 + + '@aws-crypto/crc32@5.2.0': + dependencies: + '@aws-crypto/util': 5.2.0 + '@aws-sdk/types': 3.649.0 + tslib: 2.7.0 + + '@aws-crypto/crc32c@5.2.0': + dependencies: + '@aws-crypto/util': 5.2.0 + '@aws-sdk/types': 3.649.0 + tslib: 2.7.0 + + '@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.649.0 + '@aws-sdk/util-locate-window': 3.568.0 + '@smithy/util-utf8': 2.3.0 + tslib: 2.7.0 + + '@aws-crypto/sha256-browser@5.2.0': + dependencies: + '@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.649.0 + '@aws-sdk/util-locate-window': 3.568.0 + '@smithy/util-utf8': 2.3.0 + tslib: 2.7.0 + + '@aws-crypto/sha256-js@5.2.0': + dependencies: + '@aws-crypto/util': 5.2.0 + '@aws-sdk/types': 3.649.0 + tslib: 2.7.0 + + '@aws-crypto/supports-web-crypto@5.2.0': + dependencies: + tslib: 2.7.0 + + '@aws-crypto/util@5.2.0': + dependencies: + '@aws-sdk/types': 3.649.0 + '@smithy/util-utf8': 2.3.0 + tslib: 2.7.0 + + '@aws-sdk/client-s3@3.651.1': + 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.651.1(@aws-sdk/client-sts@3.651.1) + '@aws-sdk/client-sts': 3.651.1 + '@aws-sdk/core': 3.651.1 + '@aws-sdk/credential-provider-node': 3.651.1(@aws-sdk/client-sso-oidc@3.651.1(@aws-sdk/client-sts@3.651.1))(@aws-sdk/client-sts@3.651.1) + '@aws-sdk/middleware-bucket-endpoint': 3.649.0 + '@aws-sdk/middleware-expect-continue': 3.649.0 + '@aws-sdk/middleware-flexible-checksums': 3.651.1 + '@aws-sdk/middleware-host-header': 3.649.0 + '@aws-sdk/middleware-location-constraint': 3.649.0 + '@aws-sdk/middleware-logger': 3.649.0 + '@aws-sdk/middleware-recursion-detection': 3.649.0 + '@aws-sdk/middleware-sdk-s3': 3.651.1 + '@aws-sdk/middleware-ssec': 3.649.0 + '@aws-sdk/middleware-user-agent': 3.649.0 + '@aws-sdk/region-config-resolver': 3.649.0 + '@aws-sdk/signature-v4-multi-region': 3.651.1 + '@aws-sdk/types': 3.649.0 + '@aws-sdk/util-endpoints': 3.649.0 + '@aws-sdk/util-user-agent-browser': 3.649.0 + '@aws-sdk/util-user-agent-node': 3.649.0 + '@aws-sdk/xml-builder': 3.649.0 + '@smithy/config-resolver': 3.0.8 + '@smithy/core': 2.4.3 + '@smithy/eventstream-serde-browser': 3.0.9 + '@smithy/eventstream-serde-config-resolver': 3.0.6 + '@smithy/eventstream-serde-node': 3.0.8 + '@smithy/fetch-http-handler': 3.2.7 + '@smithy/hash-blob-browser': 3.1.5 + '@smithy/hash-node': 3.0.6 + '@smithy/hash-stream-node': 3.1.5 + '@smithy/invalid-dependency': 3.0.6 + '@smithy/md5-js': 3.0.6 + '@smithy/middleware-content-length': 3.0.8 + '@smithy/middleware-endpoint': 3.1.3 + '@smithy/middleware-retry': 3.0.18 + '@smithy/middleware-serde': 3.0.6 + '@smithy/middleware-stack': 3.0.6 + '@smithy/node-config-provider': 3.1.7 + '@smithy/node-http-handler': 3.2.2 + '@smithy/protocol-http': 4.1.3 + '@smithy/smithy-client': 3.3.2 + '@smithy/types': 3.4.2 + '@smithy/url-parser': 3.0.6 + '@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.18 + '@smithy/util-defaults-mode-node': 3.0.18 + '@smithy/util-endpoints': 2.1.2 + '@smithy/util-middleware': 3.0.6 + '@smithy/util-retry': 3.0.6 + '@smithy/util-stream': 3.1.6 + '@smithy/util-utf8': 3.0.0 + '@smithy/util-waiter': 3.1.5 + tslib: 2.7.0 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/client-sso-oidc@3.651.1(@aws-sdk/client-sts@3.651.1)': + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/client-sts': 3.651.1 + '@aws-sdk/core': 3.651.1 + '@aws-sdk/credential-provider-node': 3.651.1(@aws-sdk/client-sso-oidc@3.651.1(@aws-sdk/client-sts@3.651.1))(@aws-sdk/client-sts@3.651.1) + '@aws-sdk/middleware-host-header': 3.649.0 + '@aws-sdk/middleware-logger': 3.649.0 + '@aws-sdk/middleware-recursion-detection': 3.649.0 + '@aws-sdk/middleware-user-agent': 3.649.0 + '@aws-sdk/region-config-resolver': 3.649.0 + '@aws-sdk/types': 3.649.0 + '@aws-sdk/util-endpoints': 3.649.0 + '@aws-sdk/util-user-agent-browser': 3.649.0 + '@aws-sdk/util-user-agent-node': 3.649.0 + '@smithy/config-resolver': 3.0.8 + '@smithy/core': 2.4.3 + '@smithy/fetch-http-handler': 3.2.7 + '@smithy/hash-node': 3.0.6 + '@smithy/invalid-dependency': 3.0.6 + '@smithy/middleware-content-length': 3.0.8 + '@smithy/middleware-endpoint': 3.1.3 + '@smithy/middleware-retry': 3.0.18 + '@smithy/middleware-serde': 3.0.6 + '@smithy/middleware-stack': 3.0.6 + '@smithy/node-config-provider': 3.1.7 + '@smithy/node-http-handler': 3.2.2 + '@smithy/protocol-http': 4.1.3 + '@smithy/smithy-client': 3.3.2 + '@smithy/types': 3.4.2 + '@smithy/url-parser': 3.0.6 + '@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.18 + '@smithy/util-defaults-mode-node': 3.0.18 + '@smithy/util-endpoints': 2.1.2 + '@smithy/util-middleware': 3.0.6 + '@smithy/util-retry': 3.0.6 + '@smithy/util-utf8': 3.0.0 + tslib: 2.7.0 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/client-sso@3.651.1': + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/core': 3.651.1 + '@aws-sdk/middleware-host-header': 3.649.0 + '@aws-sdk/middleware-logger': 3.649.0 + '@aws-sdk/middleware-recursion-detection': 3.649.0 + '@aws-sdk/middleware-user-agent': 3.649.0 + '@aws-sdk/region-config-resolver': 3.649.0 + '@aws-sdk/types': 3.649.0 + '@aws-sdk/util-endpoints': 3.649.0 + '@aws-sdk/util-user-agent-browser': 3.649.0 + '@aws-sdk/util-user-agent-node': 3.649.0 + '@smithy/config-resolver': 3.0.8 + '@smithy/core': 2.4.3 + '@smithy/fetch-http-handler': 3.2.7 + '@smithy/hash-node': 3.0.6 + '@smithy/invalid-dependency': 3.0.6 + '@smithy/middleware-content-length': 3.0.8 + '@smithy/middleware-endpoint': 3.1.3 + '@smithy/middleware-retry': 3.0.18 + '@smithy/middleware-serde': 3.0.6 + '@smithy/middleware-stack': 3.0.6 + '@smithy/node-config-provider': 3.1.7 + '@smithy/node-http-handler': 3.2.2 + '@smithy/protocol-http': 4.1.3 + '@smithy/smithy-client': 3.3.2 + '@smithy/types': 3.4.2 + '@smithy/url-parser': 3.0.6 + '@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.18 + '@smithy/util-defaults-mode-node': 3.0.18 + '@smithy/util-endpoints': 2.1.2 + '@smithy/util-middleware': 3.0.6 + '@smithy/util-retry': 3.0.6 + '@smithy/util-utf8': 3.0.0 + tslib: 2.7.0 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/client-sts@3.651.1': + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/client-sso-oidc': 3.651.1(@aws-sdk/client-sts@3.651.1) + '@aws-sdk/core': 3.651.1 + '@aws-sdk/credential-provider-node': 3.651.1(@aws-sdk/client-sso-oidc@3.651.1(@aws-sdk/client-sts@3.651.1))(@aws-sdk/client-sts@3.651.1) + '@aws-sdk/middleware-host-header': 3.649.0 + '@aws-sdk/middleware-logger': 3.649.0 + '@aws-sdk/middleware-recursion-detection': 3.649.0 + '@aws-sdk/middleware-user-agent': 3.649.0 + '@aws-sdk/region-config-resolver': 3.649.0 + '@aws-sdk/types': 3.649.0 + '@aws-sdk/util-endpoints': 3.649.0 + '@aws-sdk/util-user-agent-browser': 3.649.0 + '@aws-sdk/util-user-agent-node': 3.649.0 + '@smithy/config-resolver': 3.0.8 + '@smithy/core': 2.4.3 + '@smithy/fetch-http-handler': 3.2.7 + '@smithy/hash-node': 3.0.6 + '@smithy/invalid-dependency': 3.0.6 + '@smithy/middleware-content-length': 3.0.8 + '@smithy/middleware-endpoint': 3.1.3 + '@smithy/middleware-retry': 3.0.18 + '@smithy/middleware-serde': 3.0.6 + '@smithy/middleware-stack': 3.0.6 + '@smithy/node-config-provider': 3.1.7 + '@smithy/node-http-handler': 3.2.2 + '@smithy/protocol-http': 4.1.3 + '@smithy/smithy-client': 3.3.2 + '@smithy/types': 3.4.2 + '@smithy/url-parser': 3.0.6 + '@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.18 + '@smithy/util-defaults-mode-node': 3.0.18 + '@smithy/util-endpoints': 2.1.2 + '@smithy/util-middleware': 3.0.6 + '@smithy/util-retry': 3.0.6 + '@smithy/util-utf8': 3.0.0 + tslib: 2.7.0 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/core@3.651.1': + dependencies: + '@smithy/core': 2.4.3 + '@smithy/node-config-provider': 3.1.7 + '@smithy/property-provider': 3.1.6 + '@smithy/protocol-http': 4.1.3 + '@smithy/signature-v4': 4.1.3 + '@smithy/smithy-client': 3.3.2 + '@smithy/types': 3.4.2 + '@smithy/util-middleware': 3.0.6 + fast-xml-parser: 4.4.1 + tslib: 2.7.0 + + '@aws-sdk/credential-provider-env@3.649.0': + dependencies: + '@aws-sdk/types': 3.649.0 + '@smithy/property-provider': 3.1.6 + '@smithy/types': 3.4.2 + tslib: 2.7.0 + + '@aws-sdk/credential-provider-http@3.649.0': + dependencies: + '@aws-sdk/types': 3.649.0 + '@smithy/fetch-http-handler': 3.2.7 + '@smithy/node-http-handler': 3.2.2 + '@smithy/property-provider': 3.1.6 + '@smithy/protocol-http': 4.1.3 + '@smithy/smithy-client': 3.3.2 + '@smithy/types': 3.4.2 + '@smithy/util-stream': 3.1.6 + tslib: 2.7.0 + + '@aws-sdk/credential-provider-ini@3.651.1(@aws-sdk/client-sso-oidc@3.651.1(@aws-sdk/client-sts@3.651.1))(@aws-sdk/client-sts@3.651.1)': + dependencies: + '@aws-sdk/client-sts': 3.651.1 + '@aws-sdk/credential-provider-env': 3.649.0 + '@aws-sdk/credential-provider-http': 3.649.0 + '@aws-sdk/credential-provider-process': 3.649.0 + '@aws-sdk/credential-provider-sso': 3.651.1(@aws-sdk/client-sso-oidc@3.651.1(@aws-sdk/client-sts@3.651.1)) + '@aws-sdk/credential-provider-web-identity': 3.649.0(@aws-sdk/client-sts@3.651.1) + '@aws-sdk/types': 3.649.0 + '@smithy/credential-provider-imds': 3.2.3 + '@smithy/property-provider': 3.1.6 + '@smithy/shared-ini-file-loader': 3.1.7 + '@smithy/types': 3.4.2 + tslib: 2.7.0 + transitivePeerDependencies: + - '@aws-sdk/client-sso-oidc' + - aws-crt + + '@aws-sdk/credential-provider-node@3.651.1(@aws-sdk/client-sso-oidc@3.651.1(@aws-sdk/client-sts@3.651.1))(@aws-sdk/client-sts@3.651.1)': + dependencies: + '@aws-sdk/credential-provider-env': 3.649.0 + '@aws-sdk/credential-provider-http': 3.649.0 + '@aws-sdk/credential-provider-ini': 3.651.1(@aws-sdk/client-sso-oidc@3.651.1(@aws-sdk/client-sts@3.651.1))(@aws-sdk/client-sts@3.651.1) + '@aws-sdk/credential-provider-process': 3.649.0 + '@aws-sdk/credential-provider-sso': 3.651.1(@aws-sdk/client-sso-oidc@3.651.1(@aws-sdk/client-sts@3.651.1)) + '@aws-sdk/credential-provider-web-identity': 3.649.0(@aws-sdk/client-sts@3.651.1) + '@aws-sdk/types': 3.649.0 + '@smithy/credential-provider-imds': 3.2.3 + '@smithy/property-provider': 3.1.6 + '@smithy/shared-ini-file-loader': 3.1.7 + '@smithy/types': 3.4.2 + tslib: 2.7.0 + transitivePeerDependencies: + - '@aws-sdk/client-sso-oidc' + - '@aws-sdk/client-sts' + - aws-crt + + '@aws-sdk/credential-provider-process@3.649.0': + dependencies: + '@aws-sdk/types': 3.649.0 + '@smithy/property-provider': 3.1.6 + '@smithy/shared-ini-file-loader': 3.1.7 + '@smithy/types': 3.4.2 + tslib: 2.7.0 + + '@aws-sdk/credential-provider-sso@3.651.1(@aws-sdk/client-sso-oidc@3.651.1(@aws-sdk/client-sts@3.651.1))': + dependencies: + '@aws-sdk/client-sso': 3.651.1 + '@aws-sdk/token-providers': 3.649.0(@aws-sdk/client-sso-oidc@3.651.1(@aws-sdk/client-sts@3.651.1)) + '@aws-sdk/types': 3.649.0 + '@smithy/property-provider': 3.1.6 + '@smithy/shared-ini-file-loader': 3.1.7 + '@smithy/types': 3.4.2 + tslib: 2.7.0 + transitivePeerDependencies: + - '@aws-sdk/client-sso-oidc' + - aws-crt + + '@aws-sdk/credential-provider-web-identity@3.649.0(@aws-sdk/client-sts@3.651.1)': + dependencies: + '@aws-sdk/client-sts': 3.651.1 + '@aws-sdk/types': 3.649.0 + '@smithy/property-provider': 3.1.6 + '@smithy/types': 3.4.2 + tslib: 2.7.0 + + '@aws-sdk/middleware-bucket-endpoint@3.649.0': + dependencies: + '@aws-sdk/types': 3.649.0 + '@aws-sdk/util-arn-parser': 3.568.0 + '@smithy/node-config-provider': 3.1.7 + '@smithy/protocol-http': 4.1.3 + '@smithy/types': 3.4.2 + '@smithy/util-config-provider': 3.0.0 + tslib: 2.7.0 + + '@aws-sdk/middleware-expect-continue@3.649.0': + dependencies: + '@aws-sdk/types': 3.649.0 + '@smithy/protocol-http': 4.1.3 + '@smithy/types': 3.4.2 + tslib: 2.7.0 + + '@aws-sdk/middleware-flexible-checksums@3.651.1': + dependencies: + '@aws-crypto/crc32': 5.2.0 + '@aws-crypto/crc32c': 5.2.0 + '@aws-sdk/types': 3.649.0 + '@smithy/is-array-buffer': 3.0.0 + '@smithy/node-config-provider': 3.1.7 + '@smithy/protocol-http': 4.1.3 + '@smithy/types': 3.4.2 + '@smithy/util-middleware': 3.0.6 + '@smithy/util-utf8': 3.0.0 + tslib: 2.7.0 + + '@aws-sdk/middleware-host-header@3.649.0': + dependencies: + '@aws-sdk/types': 3.649.0 + '@smithy/protocol-http': 4.1.3 + '@smithy/types': 3.4.2 + tslib: 2.7.0 + + '@aws-sdk/middleware-location-constraint@3.649.0': + dependencies: + '@aws-sdk/types': 3.649.0 + '@smithy/types': 3.4.2 + tslib: 2.7.0 + + '@aws-sdk/middleware-logger@3.649.0': + dependencies: + '@aws-sdk/types': 3.649.0 + '@smithy/types': 3.4.2 + tslib: 2.7.0 + + '@aws-sdk/middleware-recursion-detection@3.649.0': + dependencies: + '@aws-sdk/types': 3.649.0 + '@smithy/protocol-http': 4.1.3 + '@smithy/types': 3.4.2 + tslib: 2.7.0 + + '@aws-sdk/middleware-sdk-s3@3.651.1': + dependencies: + '@aws-sdk/core': 3.651.1 + '@aws-sdk/types': 3.649.0 + '@aws-sdk/util-arn-parser': 3.568.0 + '@smithy/core': 2.4.3 + '@smithy/node-config-provider': 3.1.7 + '@smithy/protocol-http': 4.1.3 + '@smithy/signature-v4': 4.1.3 + '@smithy/smithy-client': 3.3.2 + '@smithy/types': 3.4.2 + '@smithy/util-config-provider': 3.0.0 + '@smithy/util-middleware': 3.0.6 + '@smithy/util-stream': 3.1.6 + '@smithy/util-utf8': 3.0.0 + tslib: 2.7.0 + + '@aws-sdk/middleware-ssec@3.649.0': + dependencies: + '@aws-sdk/types': 3.649.0 + '@smithy/types': 3.4.2 + tslib: 2.7.0 + + '@aws-sdk/middleware-user-agent@3.649.0': + dependencies: + '@aws-sdk/types': 3.649.0 + '@aws-sdk/util-endpoints': 3.649.0 + '@smithy/protocol-http': 4.1.3 + '@smithy/types': 3.4.2 + tslib: 2.7.0 + + '@aws-sdk/region-config-resolver@3.649.0': + dependencies: + '@aws-sdk/types': 3.649.0 + '@smithy/node-config-provider': 3.1.7 + '@smithy/types': 3.4.2 + '@smithy/util-config-provider': 3.0.0 + '@smithy/util-middleware': 3.0.6 + tslib: 2.7.0 + + '@aws-sdk/signature-v4-multi-region@3.651.1': + dependencies: + '@aws-sdk/middleware-sdk-s3': 3.651.1 + '@aws-sdk/types': 3.649.0 + '@smithy/protocol-http': 4.1.3 + '@smithy/signature-v4': 4.1.3 + '@smithy/types': 3.4.2 + tslib: 2.7.0 + + '@aws-sdk/token-providers@3.649.0(@aws-sdk/client-sso-oidc@3.651.1(@aws-sdk/client-sts@3.651.1))': + dependencies: + '@aws-sdk/client-sso-oidc': 3.651.1(@aws-sdk/client-sts@3.651.1) + '@aws-sdk/types': 3.649.0 + '@smithy/property-provider': 3.1.6 + '@smithy/shared-ini-file-loader': 3.1.7 + '@smithy/types': 3.4.2 + tslib: 2.7.0 + + '@aws-sdk/types@3.649.0': + dependencies: + '@smithy/types': 3.4.2 + tslib: 2.7.0 + + '@aws-sdk/util-arn-parser@3.568.0': + dependencies: + tslib: 2.7.0 + + '@aws-sdk/util-endpoints@3.649.0': + dependencies: + '@aws-sdk/types': 3.649.0 + '@smithy/types': 3.4.2 + '@smithy/util-endpoints': 2.1.2 + tslib: 2.7.0 + + '@aws-sdk/util-locate-window@3.568.0': + dependencies: + tslib: 2.7.0 + + '@aws-sdk/util-user-agent-browser@3.649.0': + dependencies: + '@aws-sdk/types': 3.649.0 + '@smithy/types': 3.4.2 + bowser: 2.11.0 + tslib: 2.7.0 + + '@aws-sdk/util-user-agent-node@3.649.0': + dependencies: + '@aws-sdk/types': 3.649.0 + '@smithy/node-config-provider': 3.1.7 + '@smithy/types': 3.4.2 + tslib: 2.7.0 + + '@aws-sdk/xml-builder@3.649.0': + dependencies: + '@smithy/types': 3.4.2 + tslib: 2.7.0 + + '@babel/helper-string-parser@7.24.8': {} + + '@babel/helper-validator-identifier@7.24.7': {} + + '@babel/parser@7.25.6': + dependencies: + '@babel/types': 7.25.6 + + '@babel/types@7.25.6': + dependencies: + '@babel/helper-string-parser': 7.24.8 + '@babel/helper-validator-identifier': 7.24.7 + to-fast-properties: 2.0.0 + + '@clack/core@0.3.4': + dependencies: + picocolors: 1.1.0 + sisteransi: 1.0.5 + + '@clack/prompts@0.7.0': + dependencies: + '@clack/core': 0.3.4 + picocolors: 1.1.0 + sisteransi: 1.0.5 + + '@colors/colors@1.6.0': {} + + '@cspotcode/source-map-support@0.8.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + + '@dabh/diagnostics@2.0.3': + dependencies: + colorspace: 1.1.4 + enabled: 2.0.0 + kuler: 2.0.0 + + '@docsearch/css@3.6.1': {} + + '@docsearch/js@3.6.1(@algolia/client-search@4.24.0)(search-insights@2.17.2)': + dependencies: + '@docsearch/react': 3.6.1(@algolia/client-search@4.24.0)(search-insights@2.17.2) + preact: 10.24.0 + transitivePeerDependencies: + - '@algolia/client-search' + - '@types/react' + - react + - react-dom + - search-insights + + '@docsearch/react@3.6.1(@algolia/client-search@4.24.0)(search-insights@2.17.2)': + dependencies: + '@algolia/autocomplete-core': 1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)(search-insights@2.17.2) + '@algolia/autocomplete-preset-algolia': 1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0) + '@docsearch/css': 3.6.1 + algoliasearch: 4.24.0 + optionalDependencies: + search-insights: 2.17.2 + transitivePeerDependencies: + - '@algolia/client-search' + + '@esbuild/aix-ppc64@0.21.5': + optional: true + + '@esbuild/android-arm64@0.21.5': + optional: true + + '@esbuild/android-arm@0.21.5': + optional: true + + '@esbuild/android-x64@0.21.5': + optional: true + + '@esbuild/darwin-arm64@0.21.5': + optional: true + + '@esbuild/darwin-x64@0.21.5': + optional: true + + '@esbuild/freebsd-arm64@0.21.5': + optional: true + + '@esbuild/freebsd-x64@0.21.5': + optional: true + + '@esbuild/linux-arm64@0.21.5': + optional: true + + '@esbuild/linux-arm@0.21.5': + optional: true + + '@esbuild/linux-ia32@0.21.5': + optional: true + + '@esbuild/linux-loong64@0.21.5': + optional: true + + '@esbuild/linux-mips64el@0.21.5': + optional: true + + '@esbuild/linux-ppc64@0.21.5': + optional: true + + '@esbuild/linux-riscv64@0.21.5': + optional: true + + '@esbuild/linux-s390x@0.21.5': + optional: true + + '@esbuild/linux-x64@0.21.5': + optional: true + + '@esbuild/netbsd-x64@0.21.5': + optional: true + + '@esbuild/openbsd-x64@0.21.5': + optional: true + + '@esbuild/sunos-x64@0.21.5': + optional: true + + '@esbuild/win32-arm64@0.21.5': + optional: true + + '@esbuild/win32-ia32@0.21.5': + optional: true + + '@esbuild/win32-x64@0.21.5': + optional: true + + '@eslint-community/eslint-utils@4.4.0(eslint@9.10.0)': + dependencies: + eslint: 9.10.0 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.11.1': {} + + '@eslint/config-array@0.18.0': + dependencies: + '@eslint/object-schema': 2.1.4 + debug: 4.3.7 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@eslint/eslintrc@3.1.0': + dependencies: + ajv: 6.12.6 + debug: 4.3.7 + espree: 10.1.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@9.10.0': {} + + '@eslint/object-schema@2.1.4': {} + + '@eslint/plugin-kit@0.1.0': + dependencies: + levn: 0.4.1 + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.3.0': {} + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@jridgewell/trace-mapping@0.3.9': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.17.1 + + '@rollup/rollup-android-arm-eabi@4.21.3': + optional: true + + '@rollup/rollup-android-arm64@4.21.3': + optional: true + + '@rollup/rollup-darwin-arm64@4.21.3': + optional: true + + '@rollup/rollup-darwin-x64@4.21.3': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.21.3': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.21.3': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.21.3': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.21.3': + optional: true + + '@rollup/rollup-linux-powerpc64le-gnu@4.21.3': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.21.3': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.21.3': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.21.3': + optional: true + + '@rollup/rollup-linux-x64-musl@4.21.3': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.21.3': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.21.3': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.21.3': + optional: true + + '@shikijs/core@1.17.7': + dependencies: + '@shikijs/engine-javascript': 1.17.7 + '@shikijs/engine-oniguruma': 1.17.7 + '@shikijs/types': 1.17.7 + '@shikijs/vscode-textmate': 9.2.2 + '@types/hast': 3.0.4 + hast-util-to-html: 9.0.3 + + '@shikijs/engine-javascript@1.17.7': + dependencies: + '@shikijs/types': 1.17.7 + '@shikijs/vscode-textmate': 9.2.2 + oniguruma-to-js: 0.4.3 + + '@shikijs/engine-oniguruma@1.17.7': + dependencies: + '@shikijs/types': 1.17.7 + '@shikijs/vscode-textmate': 9.2.2 + + '@shikijs/transformers@1.17.7': + dependencies: + shiki: 1.17.7 + + '@shikijs/types@1.17.7': + dependencies: + '@shikijs/vscode-textmate': 9.2.2 + '@types/hast': 3.0.4 + + '@shikijs/vscode-textmate@9.2.2': {} + + '@smithy/abort-controller@3.1.4': + dependencies: + '@smithy/types': 3.4.2 + tslib: 2.7.0 + + '@smithy/chunked-blob-reader-native@3.0.0': + dependencies: + '@smithy/util-base64': 3.0.0 + tslib: 2.7.0 + + '@smithy/chunked-blob-reader@3.0.0': + dependencies: + tslib: 2.7.0 + + '@smithy/config-resolver@3.0.8': + dependencies: + '@smithy/node-config-provider': 3.1.7 + '@smithy/types': 3.4.2 + '@smithy/util-config-provider': 3.0.0 + '@smithy/util-middleware': 3.0.6 + tslib: 2.7.0 + + '@smithy/core@2.4.3': + dependencies: + '@smithy/middleware-endpoint': 3.1.3 + '@smithy/middleware-retry': 3.0.18 + '@smithy/middleware-serde': 3.0.6 + '@smithy/protocol-http': 4.1.3 + '@smithy/smithy-client': 3.3.2 + '@smithy/types': 3.4.2 + '@smithy/util-body-length-browser': 3.0.0 + '@smithy/util-middleware': 3.0.6 + '@smithy/util-utf8': 3.0.0 + tslib: 2.7.0 + + '@smithy/credential-provider-imds@3.2.3': + dependencies: + '@smithy/node-config-provider': 3.1.7 + '@smithy/property-provider': 3.1.6 + '@smithy/types': 3.4.2 + '@smithy/url-parser': 3.0.6 + tslib: 2.7.0 + + '@smithy/eventstream-codec@3.1.5': + dependencies: + '@aws-crypto/crc32': 5.2.0 + '@smithy/types': 3.4.2 + '@smithy/util-hex-encoding': 3.0.0 + tslib: 2.7.0 + + '@smithy/eventstream-serde-browser@3.0.9': + dependencies: + '@smithy/eventstream-serde-universal': 3.0.8 + '@smithy/types': 3.4.2 + tslib: 2.7.0 + + '@smithy/eventstream-serde-config-resolver@3.0.6': + dependencies: + '@smithy/types': 3.4.2 + tslib: 2.7.0 + + '@smithy/eventstream-serde-node@3.0.8': + dependencies: + '@smithy/eventstream-serde-universal': 3.0.8 + '@smithy/types': 3.4.2 + tslib: 2.7.0 + + '@smithy/eventstream-serde-universal@3.0.8': + dependencies: + '@smithy/eventstream-codec': 3.1.5 + '@smithy/types': 3.4.2 + tslib: 2.7.0 + + '@smithy/fetch-http-handler@3.2.7': + dependencies: + '@smithy/protocol-http': 4.1.3 + '@smithy/querystring-builder': 3.0.6 + '@smithy/types': 3.4.2 + '@smithy/util-base64': 3.0.0 + tslib: 2.7.0 + + '@smithy/hash-blob-browser@3.1.5': + dependencies: + '@smithy/chunked-blob-reader': 3.0.0 + '@smithy/chunked-blob-reader-native': 3.0.0 + '@smithy/types': 3.4.2 + tslib: 2.7.0 + + '@smithy/hash-node@3.0.6': + dependencies: + '@smithy/types': 3.4.2 + '@smithy/util-buffer-from': 3.0.0 + '@smithy/util-utf8': 3.0.0 + tslib: 2.7.0 + + '@smithy/hash-stream-node@3.1.5': + dependencies: + '@smithy/types': 3.4.2 + '@smithy/util-utf8': 3.0.0 + tslib: 2.7.0 + + '@smithy/invalid-dependency@3.0.6': + dependencies: + '@smithy/types': 3.4.2 + tslib: 2.7.0 + + '@smithy/is-array-buffer@2.2.0': + dependencies: + tslib: 2.7.0 + + '@smithy/is-array-buffer@3.0.0': + dependencies: + tslib: 2.7.0 + + '@smithy/md5-js@3.0.6': + dependencies: + '@smithy/types': 3.4.2 + '@smithy/util-utf8': 3.0.0 + tslib: 2.7.0 + + '@smithy/middleware-content-length@3.0.8': + dependencies: + '@smithy/protocol-http': 4.1.3 + '@smithy/types': 3.4.2 + tslib: 2.7.0 + + '@smithy/middleware-endpoint@3.1.3': + dependencies: + '@smithy/middleware-serde': 3.0.6 + '@smithy/node-config-provider': 3.1.7 + '@smithy/shared-ini-file-loader': 3.1.7 + '@smithy/types': 3.4.2 + '@smithy/url-parser': 3.0.6 + '@smithy/util-middleware': 3.0.6 + tslib: 2.7.0 + + '@smithy/middleware-retry@3.0.18': + dependencies: + '@smithy/node-config-provider': 3.1.7 + '@smithy/protocol-http': 4.1.3 + '@smithy/service-error-classification': 3.0.6 + '@smithy/smithy-client': 3.3.2 + '@smithy/types': 3.4.2 + '@smithy/util-middleware': 3.0.6 + '@smithy/util-retry': 3.0.6 + tslib: 2.7.0 + uuid: 9.0.1 + + '@smithy/middleware-serde@3.0.6': + dependencies: + '@smithy/types': 3.4.2 + tslib: 2.7.0 + + '@smithy/middleware-stack@3.0.6': + dependencies: + '@smithy/types': 3.4.2 + tslib: 2.7.0 + + '@smithy/node-config-provider@3.1.7': + dependencies: + '@smithy/property-provider': 3.1.6 + '@smithy/shared-ini-file-loader': 3.1.7 + '@smithy/types': 3.4.2 + tslib: 2.7.0 + + '@smithy/node-http-handler@3.2.2': + dependencies: + '@smithy/abort-controller': 3.1.4 + '@smithy/protocol-http': 4.1.3 + '@smithy/querystring-builder': 3.0.6 + '@smithy/types': 3.4.2 + tslib: 2.7.0 + + '@smithy/property-provider@3.1.6': + dependencies: + '@smithy/types': 3.4.2 + tslib: 2.7.0 + + '@smithy/protocol-http@4.1.3': + dependencies: + '@smithy/types': 3.4.2 + tslib: 2.7.0 + + '@smithy/querystring-builder@3.0.6': + dependencies: + '@smithy/types': 3.4.2 + '@smithy/util-uri-escape': 3.0.0 + tslib: 2.7.0 + + '@smithy/querystring-parser@3.0.6': + dependencies: + '@smithy/types': 3.4.2 + tslib: 2.7.0 + + '@smithy/service-error-classification@3.0.6': + dependencies: + '@smithy/types': 3.4.2 + + '@smithy/shared-ini-file-loader@3.1.7': + dependencies: + '@smithy/types': 3.4.2 + tslib: 2.7.0 + + '@smithy/signature-v4@4.1.3': + dependencies: + '@smithy/is-array-buffer': 3.0.0 + '@smithy/protocol-http': 4.1.3 + '@smithy/types': 3.4.2 + '@smithy/util-hex-encoding': 3.0.0 + '@smithy/util-middleware': 3.0.6 + '@smithy/util-uri-escape': 3.0.0 + '@smithy/util-utf8': 3.0.0 + tslib: 2.7.0 + + '@smithy/smithy-client@3.3.2': + dependencies: + '@smithy/middleware-endpoint': 3.1.3 + '@smithy/middleware-stack': 3.0.6 + '@smithy/protocol-http': 4.1.3 + '@smithy/types': 3.4.2 + '@smithy/util-stream': 3.1.6 + tslib: 2.7.0 + + '@smithy/types@3.4.2': + dependencies: + tslib: 2.7.0 + + '@smithy/url-parser@3.0.6': + dependencies: + '@smithy/querystring-parser': 3.0.6 + '@smithy/types': 3.4.2 + tslib: 2.7.0 + + '@smithy/util-base64@3.0.0': + dependencies: + '@smithy/util-buffer-from': 3.0.0 + '@smithy/util-utf8': 3.0.0 + tslib: 2.7.0 + + '@smithy/util-body-length-browser@3.0.0': + dependencies: + tslib: 2.7.0 + + '@smithy/util-body-length-node@3.0.0': + dependencies: + tslib: 2.7.0 + + '@smithy/util-buffer-from@2.2.0': + dependencies: + '@smithy/is-array-buffer': 2.2.0 + tslib: 2.7.0 + + '@smithy/util-buffer-from@3.0.0': + dependencies: + '@smithy/is-array-buffer': 3.0.0 + tslib: 2.7.0 + + '@smithy/util-config-provider@3.0.0': + dependencies: + tslib: 2.7.0 + + '@smithy/util-defaults-mode-browser@3.0.18': + dependencies: + '@smithy/property-provider': 3.1.6 + '@smithy/smithy-client': 3.3.2 + '@smithy/types': 3.4.2 + bowser: 2.11.0 + tslib: 2.7.0 + + '@smithy/util-defaults-mode-node@3.0.18': + dependencies: + '@smithy/config-resolver': 3.0.8 + '@smithy/credential-provider-imds': 3.2.3 + '@smithy/node-config-provider': 3.1.7 + '@smithy/property-provider': 3.1.6 + '@smithy/smithy-client': 3.3.2 + '@smithy/types': 3.4.2 + tslib: 2.7.0 + + '@smithy/util-endpoints@2.1.2': + dependencies: + '@smithy/node-config-provider': 3.1.7 + '@smithy/types': 3.4.2 + tslib: 2.7.0 + + '@smithy/util-hex-encoding@3.0.0': + dependencies: + tslib: 2.7.0 + + '@smithy/util-middleware@3.0.6': + dependencies: + '@smithy/types': 3.4.2 + tslib: 2.7.0 + + '@smithy/util-retry@3.0.6': + dependencies: + '@smithy/service-error-classification': 3.0.6 + '@smithy/types': 3.4.2 + tslib: 2.7.0 + + '@smithy/util-stream@3.1.6': + dependencies: + '@smithy/fetch-http-handler': 3.2.7 + '@smithy/node-http-handler': 3.2.2 + '@smithy/types': 3.4.2 + '@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 + tslib: 2.7.0 + + '@smithy/util-uri-escape@3.0.0': + dependencies: + tslib: 2.7.0 + + '@smithy/util-utf8@2.3.0': + dependencies: + '@smithy/util-buffer-from': 2.2.0 + tslib: 2.7.0 + + '@smithy/util-utf8@3.0.0': + dependencies: + '@smithy/util-buffer-from': 3.0.0 + tslib: 2.7.0 + + '@smithy/util-waiter@3.1.5': + dependencies: + '@smithy/abort-controller': 3.1.4 + '@smithy/types': 3.4.2 + tslib: 2.7.0 + + '@tsconfig/node10@1.0.11': {} + + '@tsconfig/node12@1.0.11': {} + + '@tsconfig/node14@1.0.3': {} + + '@tsconfig/node16@1.0.4': {} + + '@types/body-parser@1.19.5': + dependencies: + '@types/connect': 3.4.38 + '@types/node': 18.19.50 + + '@types/connect@3.4.38': + dependencies: + '@types/node': 18.19.50 + + '@types/estree@1.0.5': {} + + '@types/express-serve-static-core@4.19.5': + dependencies: + '@types/node': 18.19.50 + '@types/qs': 6.9.16 + '@types/range-parser': 1.2.7 + '@types/send': 0.17.4 + + '@types/express@4.17.21': + dependencies: + '@types/body-parser': 1.19.5 + '@types/express-serve-static-core': 4.19.5 + '@types/qs': 6.9.16 + '@types/serve-static': 1.15.7 + + '@types/hast@3.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/http-errors@2.0.4': {} + + '@types/linkify-it@5.0.0': {} + + '@types/markdown-it@14.1.2': + dependencies: + '@types/linkify-it': 5.0.0 + '@types/mdurl': 2.0.0 + + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/mdurl@2.0.0': {} + + '@types/mime@1.3.5': {} + + '@types/node@18.19.50': + dependencies: + undici-types: 5.26.5 + + '@types/nodemailer@6.4.15': + dependencies: + '@types/node': 18.19.50 + + '@types/qs@6.9.16': {} + + '@types/range-parser@1.2.7': {} + + '@types/send@0.17.4': + dependencies: + '@types/mime': 1.3.5 + '@types/node': 18.19.50 + + '@types/serve-static@1.15.7': + dependencies: + '@types/http-errors': 2.0.4 + '@types/node': 18.19.50 + '@types/send': 0.17.4 + + '@types/strip-bom@3.0.0': {} + + '@types/strip-json-comments@0.0.30': {} + + '@types/triple-beam@1.3.5': {} + + '@types/unist@3.0.3': {} + + '@types/web-bluetooth@0.0.20': {} + + '@typescript-eslint/eslint-plugin@8.6.0(@typescript-eslint/parser@8.6.0(eslint@9.10.0)(typescript@5.6.2))(eslint@9.10.0)(typescript@5.6.2)': + dependencies: + '@eslint-community/regexpp': 4.11.1 + '@typescript-eslint/parser': 8.6.0(eslint@9.10.0)(typescript@5.6.2) + '@typescript-eslint/scope-manager': 8.6.0 + '@typescript-eslint/type-utils': 8.6.0(eslint@9.10.0)(typescript@5.6.2) + '@typescript-eslint/utils': 8.6.0(eslint@9.10.0)(typescript@5.6.2) + '@typescript-eslint/visitor-keys': 8.6.0 + eslint: 9.10.0 + graphemer: 1.4.0 + ignore: 5.3.2 + natural-compare: 1.4.0 + ts-api-utils: 1.3.0(typescript@5.6.2) + optionalDependencies: + typescript: 5.6.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.6.0(eslint@9.10.0)(typescript@5.6.2)': + dependencies: + '@typescript-eslint/scope-manager': 8.6.0 + '@typescript-eslint/types': 8.6.0 + '@typescript-eslint/typescript-estree': 8.6.0(typescript@5.6.2) + '@typescript-eslint/visitor-keys': 8.6.0 + debug: 4.3.7 + eslint: 9.10.0 + optionalDependencies: + typescript: 5.6.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.6.0': + dependencies: + '@typescript-eslint/types': 8.6.0 + '@typescript-eslint/visitor-keys': 8.6.0 + + '@typescript-eslint/type-utils@8.6.0(eslint@9.10.0)(typescript@5.6.2)': + dependencies: + '@typescript-eslint/typescript-estree': 8.6.0(typescript@5.6.2) + '@typescript-eslint/utils': 8.6.0(eslint@9.10.0)(typescript@5.6.2) + debug: 4.3.7 + ts-api-utils: 1.3.0(typescript@5.6.2) + optionalDependencies: + typescript: 5.6.2 + transitivePeerDependencies: + - eslint + - supports-color + + '@typescript-eslint/types@8.6.0': {} + + '@typescript-eslint/typescript-estree@8.6.0(typescript@5.6.2)': + dependencies: + '@typescript-eslint/types': 8.6.0 + '@typescript-eslint/visitor-keys': 8.6.0 + debug: 4.3.7 + fast-glob: 3.3.2 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.6.3 + ts-api-utils: 1.3.0(typescript@5.6.2) + optionalDependencies: + typescript: 5.6.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.6.0(eslint@9.10.0)(typescript@5.6.2)': + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@9.10.0) + '@typescript-eslint/scope-manager': 8.6.0 + '@typescript-eslint/types': 8.6.0 + '@typescript-eslint/typescript-estree': 8.6.0(typescript@5.6.2) + eslint: 9.10.0 + transitivePeerDependencies: + - supports-color + - typescript + + '@typescript-eslint/visitor-keys@8.6.0': + dependencies: + '@typescript-eslint/types': 8.6.0 + eslint-visitor-keys: 3.4.3 + + '@ungap/structured-clone@1.2.0': {} + + '@vitejs/plugin-vue@5.1.3(vite@5.4.6(@types/node@18.19.50))(vue@3.5.6(typescript@5.6.2))': + dependencies: + vite: 5.4.6(@types/node@18.19.50) + vue: 3.5.6(typescript@5.6.2) + + '@vue/compiler-core@3.5.6': + dependencies: + '@babel/parser': 7.25.6 + '@vue/shared': 3.5.6 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + + '@vue/compiler-dom@3.5.6': + dependencies: + '@vue/compiler-core': 3.5.6 + '@vue/shared': 3.5.6 + + '@vue/compiler-sfc@3.5.6': + dependencies: + '@babel/parser': 7.25.6 + '@vue/compiler-core': 3.5.6 + '@vue/compiler-dom': 3.5.6 + '@vue/compiler-ssr': 3.5.6 + '@vue/shared': 3.5.6 + estree-walker: 2.0.2 + magic-string: 0.30.11 + postcss: 8.4.47 + source-map-js: 1.2.1 + + '@vue/compiler-ssr@3.5.6': + dependencies: + '@vue/compiler-dom': 3.5.6 + '@vue/shared': 3.5.6 + + '@vue/devtools-api@7.4.5': + dependencies: + '@vue/devtools-kit': 7.4.5 + + '@vue/devtools-kit@7.4.5': + dependencies: + '@vue/devtools-shared': 7.4.5 + birpc: 0.2.17 + hookable: 5.5.3 + mitt: 3.0.1 + perfect-debounce: 1.0.0 + speakingurl: 14.0.1 + superjson: 2.2.1 + + '@vue/devtools-shared@7.4.5': + dependencies: + rfdc: 1.4.1 + + '@vue/reactivity@3.5.6': + dependencies: + '@vue/shared': 3.5.6 + + '@vue/runtime-core@3.5.6': + dependencies: + '@vue/reactivity': 3.5.6 + '@vue/shared': 3.5.6 + + '@vue/runtime-dom@3.5.6': + dependencies: + '@vue/reactivity': 3.5.6 + '@vue/runtime-core': 3.5.6 + '@vue/shared': 3.5.6 + csstype: 3.1.3 + + '@vue/server-renderer@3.5.6(vue@3.5.6(typescript@5.6.2))': + dependencies: + '@vue/compiler-ssr': 3.5.6 + '@vue/shared': 3.5.6 + vue: 3.5.6(typescript@5.6.2) + + '@vue/shared@3.5.6': {} + + '@vueuse/core@11.1.0(vue@3.5.6(typescript@5.6.2))': + dependencies: + '@types/web-bluetooth': 0.0.20 + '@vueuse/metadata': 11.1.0 + '@vueuse/shared': 11.1.0(vue@3.5.6(typescript@5.6.2)) + vue-demi: 0.14.10(vue@3.5.6(typescript@5.6.2)) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + '@vueuse/integrations@11.1.0(focus-trap@7.6.0)(vue@3.5.6(typescript@5.6.2))': + dependencies: + '@vueuse/core': 11.1.0(vue@3.5.6(typescript@5.6.2)) + '@vueuse/shared': 11.1.0(vue@3.5.6(typescript@5.6.2)) + vue-demi: 0.14.10(vue@3.5.6(typescript@5.6.2)) + optionalDependencies: + focus-trap: 7.6.0 + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + '@vueuse/metadata@11.1.0': {} + + '@vueuse/shared@11.1.0(vue@3.5.6(typescript@5.6.2))': + dependencies: + vue-demi: 0.14.10(vue@3.5.6(typescript@5.6.2)) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + acorn-jsx@5.3.2(acorn@8.12.1): + dependencies: + acorn: 8.12.1 + + acorn-walk@8.3.4: + dependencies: + acorn: 8.12.1 + + acorn@8.12.1: {} + + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + algoliasearch@4.24.0: + dependencies: + '@algolia/cache-browser-local-storage': 4.24.0 + '@algolia/cache-common': 4.24.0 + '@algolia/cache-in-memory': 4.24.0 + '@algolia/client-account': 4.24.0 + '@algolia/client-analytics': 4.24.0 + '@algolia/client-common': 4.24.0 + '@algolia/client-personalization': 4.24.0 + '@algolia/client-search': 4.24.0 + '@algolia/logger-common': 4.24.0 + '@algolia/logger-console': 4.24.0 + '@algolia/recommend': 4.24.0 + '@algolia/requester-browser-xhr': 4.24.0 + '@algolia/requester-common': 4.24.0 + '@algolia/requester-node-http': 4.24.0 + '@algolia/transporter': 4.24.0 + + ansi-regex@5.0.1: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + arg@4.1.3: {} + + argparse@2.0.1: {} + + async@3.2.6: {} + + balanced-match@1.0.2: {} + + binary-extensions@2.3.0: {} + + birpc@0.2.17: {} + + bowser@2.11.0: {} + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + buffer-from@1.1.2: {} + + callsites@3.1.0: {} + + ccount@2.0.1: {} + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + character-entities-html4@2.1.0: {} + + character-entities-legacy@3.0.0: {} + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + class-transformer@0.5.1: {} + + color-convert@1.9.3: + dependencies: + color-name: 1.1.3 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.3: {} + + color-name@1.1.4: {} + + color-string@1.9.1: + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.2 + + color@3.2.1: + dependencies: + color-convert: 1.9.3 + color-string: 1.9.1 + + colorspace@1.1.4: + dependencies: + color: 3.2.1 + text-hex: 1.0.0 + + comma-separated-tokens@2.0.3: {} + + commander@12.1.0: {} + + concat-map@0.0.1: {} + + copy-anything@3.0.5: + dependencies: + is-what: 4.1.16 + + create-require@1.1.1: {} + + cross-spawn@7.0.3: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + csstype@3.1.3: {} + + debug@4.3.7: + dependencies: + ms: 2.1.3 + + deep-is@0.1.4: {} + + dequal@2.0.3: {} + + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + + diff@4.0.2: {} + + dynamic-dedupe@0.3.0: + dependencies: + xtend: 4.0.2 + + enabled@2.0.0: {} + + entities@4.5.0: {} + + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + + escape-string-regexp@4.0.0: {} + + eslint-scope@8.0.2: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.0.0: {} + + eslint@9.10.0: + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@9.10.0) + '@eslint-community/regexpp': 4.11.1 + '@eslint/config-array': 0.18.0 + '@eslint/eslintrc': 3.1.0 + '@eslint/js': 9.10.0 + '@eslint/plugin-kit': 0.1.0 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.3.0 + '@nodelib/fs.walk': 1.2.8 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.7 + escape-string-regexp: 4.0.0 + eslint-scope: 8.0.2 + eslint-visitor-keys: 4.0.0 + espree: 10.1.0 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + strip-ansi: 6.0.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + + espree@10.1.0: + dependencies: + acorn: 8.12.1 + acorn-jsx: 5.3.2(acorn@8.12.1) + eslint-visitor-keys: 4.0.0 + + esquery@1.6.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + estree-walker@2.0.2: {} + + esutils@2.0.3: {} + + fast-deep-equal@3.1.3: {} + + fast-glob@3.3.2: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fast-xml-parser@4.4.1: + dependencies: + strnum: 1.0.5 + + fastq@1.17.1: + dependencies: + reusify: 1.0.4 + + fecha@4.2.3: {} + + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@4.0.1: + dependencies: + flatted: 3.3.1 + keyv: 4.5.4 + + flatted@3.3.1: {} + + fn.name@1.1.0: {} + + focus-trap@7.6.0: + dependencies: + tabbable: 6.2.0 + + fs.realpath@1.0.0: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + globals@14.0.0: {} + + globals@15.9.0: {} + + graphemer@1.4.0: {} + + has-flag@4.0.0: {} + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + hast-util-to-html@9.0.3: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + comma-separated-tokens: 2.0.3 + hast-util-whitespace: 3.0.0 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.0 + property-information: 6.5.0 + space-separated-tokens: 2.0.2 + stringify-entities: 4.0.4 + zwitch: 2.0.4 + + hast-util-whitespace@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hookable@5.5.3: {} + + html-void-elements@3.0.0: {} + + husky@9.1.6: {} + + ignore@5.3.2: {} + + import-fresh@3.3.0: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + imurmurhash@0.1.4: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + is-arrayish@0.3.2: {} + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-core-module@2.15.1: + dependencies: + hasown: 2.0.2 + + is-extglob@2.1.1: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-number@7.0.0: {} + + is-path-inside@3.0.3: {} + + is-stream@2.0.1: {} + + is-what@4.1.16: {} + + isexe@2.0.0: {} + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + json-buffer@3.0.1: {} + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + kuler@2.0.0: {} + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.merge@4.6.2: {} + + logform@2.6.1: + dependencies: + '@colors/colors': 1.6.0 + '@types/triple-beam': 1.3.5 + fecha: 4.2.3 + ms: 2.1.3 + safe-stable-stringify: 2.5.0 + triple-beam: 1.4.1 + + magic-string@0.30.11: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + + make-error@1.3.6: {} + + mark.js@8.11.1: {} + + mdast-util-to-hast@13.2.0: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.2.0 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.0 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + + merge2@1.4.1: {} + + micromark-util-character@2.1.0: + dependencies: + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + + micromark-util-encode@2.0.0: {} + + micromark-util-sanitize-uri@2.0.0: + dependencies: + micromark-util-character: 2.1.0 + micromark-util-encode: 2.0.0 + micromark-util-symbol: 2.0.0 + + micromark-util-symbol@2.0.0: {} + + micromark-util-types@2.0.0: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + + minimist@1.2.8: {} + + minisearch@7.1.0: {} + + mitt@3.0.1: {} + + mkdirp@1.0.4: {} + + ms@2.1.3: {} + + nanoid@3.3.7: {} + + natural-compare@1.4.0: {} + + nodemailer@6.9.15: {} + + normalize-path@3.0.0: {} + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + one-time@1.0.0: + dependencies: + fn.name: 1.1.0 + + oniguruma-to-js@0.4.3: + dependencies: + regex: 4.3.2 + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + path-exists@4.0.0: {} + + path-is-absolute@1.0.1: {} + + path-key@3.1.1: {} + + path-parse@1.0.7: {} + + perfect-debounce@1.0.0: {} + + picocolors@1.1.0: {} + + picomatch@2.3.1: {} + + postcss@8.4.47: + dependencies: + nanoid: 3.3.7 + picocolors: 1.1.0 + source-map-js: 1.2.1 + + preact@10.24.0: {} + + prelude-ls@1.2.1: {} + + property-information@6.5.0: {} + + punycode@2.3.1: {} + + queue-microtask@1.2.3: {} + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + + regex@4.3.2: {} + + resolve-from@4.0.0: {} + + resolve@1.22.8: + dependencies: + is-core-module: 2.15.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + reusify@1.0.4: {} + + rfdc@1.4.1: {} + + rimraf@2.7.1: + dependencies: + glob: 7.2.3 + + rollup@4.21.3: + dependencies: + '@types/estree': 1.0.5 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.21.3 + '@rollup/rollup-android-arm64': 4.21.3 + '@rollup/rollup-darwin-arm64': 4.21.3 + '@rollup/rollup-darwin-x64': 4.21.3 + '@rollup/rollup-linux-arm-gnueabihf': 4.21.3 + '@rollup/rollup-linux-arm-musleabihf': 4.21.3 + '@rollup/rollup-linux-arm64-gnu': 4.21.3 + '@rollup/rollup-linux-arm64-musl': 4.21.3 + '@rollup/rollup-linux-powerpc64le-gnu': 4.21.3 + '@rollup/rollup-linux-riscv64-gnu': 4.21.3 + '@rollup/rollup-linux-s390x-gnu': 4.21.3 + '@rollup/rollup-linux-x64-gnu': 4.21.3 + '@rollup/rollup-linux-x64-musl': 4.21.3 + '@rollup/rollup-win32-arm64-msvc': 4.21.3 + '@rollup/rollup-win32-ia32-msvc': 4.21.3 + '@rollup/rollup-win32-x64-msvc': 4.21.3 + fsevents: 2.3.3 + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + safe-buffer@5.2.1: {} + + safe-stable-stringify@2.5.0: {} + + search-insights@2.17.2: {} + + semver@7.6.3: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + shiki@1.17.7: + dependencies: + '@shikijs/core': 1.17.7 + '@shikijs/engine-javascript': 1.17.7 + '@shikijs/engine-oniguruma': 1.17.7 + '@shikijs/types': 1.17.7 + '@shikijs/vscode-textmate': 9.2.2 + '@types/hast': 3.0.4 + + simple-swizzle@0.2.2: + dependencies: + is-arrayish: 0.3.2 + + sisteransi@1.0.5: {} + + source-map-js@1.2.1: {} + + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map@0.6.1: {} + + space-separated-tokens@2.0.2: {} + + speakingurl@14.0.1: {} + + stack-trace@0.0.10: {} + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + stringify-entities@4.0.4: + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-bom@3.0.0: {} + + strip-json-comments@2.0.1: {} + + strip-json-comments@3.1.1: {} + + strnum@1.0.5: {} + + superjson@2.2.1: + dependencies: + copy-anything: 3.0.5 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + tabbable@6.2.0: {} + + text-hex@1.0.0: {} + + text-table@0.2.0: {} + + to-fast-properties@2.0.0: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + tree-kill@1.2.2: {} + + trim-lines@3.0.1: {} + + triple-beam@1.4.1: {} + + ts-api-utils@1.3.0(typescript@5.6.2): + dependencies: + typescript: 5.6.2 + + ts-node-dev@2.0.0(@types/node@18.19.50)(typescript@5.6.2): + dependencies: + chokidar: 3.6.0 + dynamic-dedupe: 0.3.0 + minimist: 1.2.8 + mkdirp: 1.0.4 + resolve: 1.22.8 + rimraf: 2.7.1 + source-map-support: 0.5.21 + tree-kill: 1.2.2 + ts-node: 10.9.2(@types/node@18.19.50)(typescript@5.6.2) + tsconfig: 7.0.0 + typescript: 5.6.2 + transitivePeerDependencies: + - '@swc/core' + - '@swc/wasm' + - '@types/node' + + ts-node@10.9.2(@types/node@18.19.50)(typescript@5.6.2): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.11 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 18.19.50 + acorn: 8.12.1 + acorn-walk: 8.3.4 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.6.2 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + + tsconfig@7.0.0: + dependencies: + '@types/strip-bom': 3.0.0 + '@types/strip-json-comments': 0.0.30 + strip-bom: 3.0.0 + strip-json-comments: 2.0.1 + + tslib@2.7.0: {} + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + typescript-eslint@8.6.0(eslint@9.10.0)(typescript@5.6.2): + dependencies: + '@typescript-eslint/eslint-plugin': 8.6.0(@typescript-eslint/parser@8.6.0(eslint@9.10.0)(typescript@5.6.2))(eslint@9.10.0)(typescript@5.6.2) + '@typescript-eslint/parser': 8.6.0(eslint@9.10.0)(typescript@5.6.2) + '@typescript-eslint/utils': 8.6.0(eslint@9.10.0)(typescript@5.6.2) + optionalDependencies: + typescript: 5.6.2 + transitivePeerDependencies: + - eslint + - supports-color + + typescript@5.6.2: {} + + undici-types@5.26.5: {} + + unist-util-is@6.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-parents@6.0.1: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.0 + + unist-util-visit@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.0 + unist-util-visit-parents: 6.0.1 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + util-deprecate@1.0.2: {} + + uuid@9.0.1: {} + + v8-compile-cache-lib@3.0.1: {} + + vfile-message@4.0.2: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + + vfile@6.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.2 + + vite@5.4.6(@types/node@18.19.50): + dependencies: + esbuild: 0.21.5 + postcss: 8.4.47 + rollup: 4.21.3 + optionalDependencies: + '@types/node': 18.19.50 + fsevents: 2.3.3 + + vitepress@1.3.4(@algolia/client-search@4.24.0)(@types/node@18.19.50)(postcss@8.4.47)(search-insights@2.17.2)(typescript@5.6.2): + dependencies: + '@docsearch/css': 3.6.1 + '@docsearch/js': 3.6.1(@algolia/client-search@4.24.0)(search-insights@2.17.2) + '@shikijs/core': 1.17.7 + '@shikijs/transformers': 1.17.7 + '@types/markdown-it': 14.1.2 + '@vitejs/plugin-vue': 5.1.3(vite@5.4.6(@types/node@18.19.50))(vue@3.5.6(typescript@5.6.2)) + '@vue/devtools-api': 7.4.5 + '@vue/shared': 3.5.6 + '@vueuse/core': 11.1.0(vue@3.5.6(typescript@5.6.2)) + '@vueuse/integrations': 11.1.0(focus-trap@7.6.0)(vue@3.5.6(typescript@5.6.2)) + focus-trap: 7.6.0 + mark.js: 8.11.1 + minisearch: 7.1.0 + shiki: 1.17.7 + vite: 5.4.6(@types/node@18.19.50) + vue: 3.5.6(typescript@5.6.2) + optionalDependencies: + postcss: 8.4.47 + transitivePeerDependencies: + - '@algolia/client-search' + - '@types/node' + - '@types/react' + - '@vue/composition-api' + - async-validator + - axios + - change-case + - drauu + - fuse.js + - idb-keyval + - jwt-decode + - less + - lightningcss + - nprogress + - qrcode + - react + - react-dom + - sass + - sass-embedded + - search-insights + - sortablejs + - stylus + - sugarss + - terser + - typescript + - universal-cookie + + vue-demi@0.14.10(vue@3.5.6(typescript@5.6.2)): + dependencies: + vue: 3.5.6(typescript@5.6.2) + + vue@3.5.6(typescript@5.6.2): + dependencies: + '@vue/compiler-dom': 3.5.6 + '@vue/compiler-sfc': 3.5.6 + '@vue/runtime-dom': 3.5.6 + '@vue/server-renderer': 3.5.6(vue@3.5.6(typescript@5.6.2)) + '@vue/shared': 3.5.6 + optionalDependencies: + typescript: 5.6.2 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + winston-transport@4.7.1: + dependencies: + logform: 2.6.1 + readable-stream: 3.6.2 + triple-beam: 1.4.1 + + winston@3.14.2: + dependencies: + '@colors/colors': 1.6.0 + '@dabh/diagnostics': 2.0.3 + async: 3.2.6 + is-stream: 2.0.1 + logform: 2.6.1 + one-time: 1.0.0 + readable-stream: 3.6.2 + safe-stable-stringify: 2.5.0 + stack-trace: 0.0.10 + triple-beam: 1.4.1 + winston-transport: 4.7.1 + + word-wrap@1.2.5: {} + + wrappy@1.0.2: {} + + xtend@4.0.2: {} + + yaml@2.5.1: {} + + yn@3.1.1: {} + + yocto-queue@0.1.0: {} + + zwitch@2.0.4: {} From 2516a41d9997b75f90425e814d211693a9bca520 Mon Sep 17 00:00:00 2001 From: Anupam Bista Date: Tue, 17 Sep 2024 17:05:26 +0545 Subject: [PATCH 12/17] fixed base of vitepress --- README.md | 2 +- docs/.vitepress/config.mts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6200ef1..a6f411a 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Effortlessly manage your database backups at one go. This easy-to-use tool suppo ## Documentation -Check out the documentation at: (https://github.com/28softwares/backupdbee/tree/main/docs/guide/getting-started) +Check out the documentation at: [https://28softwares.github.com/BackupDBee](https://28softwares.github.com/BackupDBee) ## Feel Free To Contribute 👌 diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts index b559ce1..0aadf64 100644 --- a/docs/.vitepress/config.mts +++ b/docs/.vitepress/config.mts @@ -2,7 +2,7 @@ import { defineConfig, type DefaultTheme } from "vitepress"; // https://vitepress.dev/reference/site-config export default defineConfig({ - base: "/backupdbee/", + base: "/BackupDBee/", title: "BackupDBee 🐝", description: "Automatic CLI Based Advance DB Backup System", themeConfig: { From 629f4d3d652d7b6843500cbb7d719154327236f7 Mon Sep 17 00:00:00 2001 From: Anupam Bista Date: Wed, 18 Sep 2024 12:49:18 +0545 Subject: [PATCH 13/17] fixed issue caused due to dotenv and accessing config before creating backupdbee.yaml file --- package.json | 1 + pnpm-lock.yaml | 9 +++++++++ src/commands/install.ts | 14 ++++---------- src/utils/cli.utils.ts | 11 ++++++++++- 4 files changed, 24 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index 54c0323..561032a 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "chalk": "^4.1.2", "class-transformer": "^0.5.1", "commander": "^12.1.0", + "dotenv": "^16.4.5", "nodemailer": "^6.9.14", "ts-node": "^10.9.2", "winston": "^3.14.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9db82e2..af13e5f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -26,6 +26,9 @@ importers: commander: specifier: ^12.1.0 version: 12.1.0 + dotenv: + specifier: ^16.4.5 + version: 16.4.5 nodemailer: specifier: ^6.9.14 version: 6.9.15 @@ -1254,6 +1257,10 @@ packages: resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} engines: {node: '>=0.3.1'} + dotenv@16.4.5: + resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} + engines: {node: '>=12'} + dynamic-dedupe@0.3.0: resolution: {integrity: sha512-ssuANeD+z97meYOqd50e04Ze5qp4bPqo8cCkI4TRjZkzAUgIDTrXV1R8QCdINpiI+hw14+rYazvTRdQrz0/rFQ==} @@ -3655,6 +3662,8 @@ snapshots: diff@4.0.2: {} + dotenv@16.4.5: {} + dynamic-dedupe@0.3.0: dependencies: xtend: 4.0.2 diff --git a/src/commands/install.ts b/src/commands/install.ts index 934c31a..03d3718 100644 --- a/src/commands/install.ts +++ b/src/commands/install.ts @@ -1,4 +1,4 @@ -import { intro, confirm, spinner } from "@clack/prompts"; +import { confirm } from "@clack/prompts"; import * as fs from "fs"; import process from "process"; import chalk from "chalk"; @@ -16,9 +16,6 @@ import { destinationFile, sourceFile } from "../utils/cli.utils"; * @param destinationFile - The path to the destination file. */ const createBackupdbeeYaml = () => { - const s = spinner(); - s.start("Creating backupdbee.yaml file"); - fs.readFile(sourceFile, "utf8", (err, data) => { if (err) { console.error("Error reading the source file:", err); @@ -28,10 +25,10 @@ const createBackupdbeeYaml = () => { // Write the content to the destination file fs.writeFile(destinationFile, data, (err) => { if (err) { - s.stop(`Error writing to the destination file: ${err}`); + console.log(chalk.red(`Error writing to the destination file: ${err}`)); process.exit(0); } else { - s.stop(`File copied successfully to ${destinationFile}`); + console.log(`\nFile copied successfully to ${destinationFile}`); } }); }); @@ -47,7 +44,6 @@ const install = async (): Promise => { checkCommands(commands); console.log(); - intro(chalk.inverse("Installation")); try { // check if backupdbee.yaml file exists in root folder or not if (!fs.existsSync("backupdbee.yaml")) { @@ -65,9 +61,7 @@ const install = async (): Promise => { } console.log( - chalk.green( - "Next Step: Update the backupdbee.yaml file with your configurations." - ) + "\nNext Step: Update the backupdbee.yaml file with your configurations." ); } catch (err) { console.log(err); diff --git a/src/utils/cli.utils.ts b/src/utils/cli.utils.ts index 5f2f761..e53451d 100644 --- a/src/utils/cli.utils.ts +++ b/src/utils/cli.utils.ts @@ -1,6 +1,7 @@ import { readFileSync, writeFileSync } from "fs"; import path from "path"; import * as yaml from "yaml"; +import * as fs from "fs"; import { DataBeeConfig } from "../@types/config"; // eslint-disable-next-line no-undef @@ -19,4 +20,12 @@ export function saveConfig(config: DataBeeConfig) { writeFileSync(destinationFile, yamlString, "utf8"); } -export const config = parseConfigFile(); +function parseSampleFileBeforeInstall(): DataBeeConfig { + const configFile = readFileSync(sourceFile, "utf-8"); + const yamlConfig = yaml.parse(configFile) as DataBeeConfig; + return yamlConfig; +} + +export const config = fs.existsSync(destinationFile) + ? parseConfigFile() + : parseSampleFileBeforeInstall(); From 619bcfd20e5e9c41ebf8b08e0db5c61ca6706c45 Mon Sep 17 00:00:00 2001 From: Anupam Bista Date: Wed, 18 Sep 2024 13:54:20 +0545 Subject: [PATCH 14/17] fixed issue of showing multiple loader while database backup --- src/commands/database.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/commands/database.ts b/src/commands/database.ts index a7b9246..ae7616d 100644 --- a/src/commands/database.ts +++ b/src/commands/database.ts @@ -61,7 +61,7 @@ export const dbBackup = async (options: { name?: string }) => { if (db) { config.databases = [db]; const s = spinner(); - s.start(`Backing up database: ${options.name}\n`); + s.start(`Backing up database: ${options.name}`); await setupMainFunction(config); // Call main function to backup specific database s.stop(); } else { @@ -71,7 +71,7 @@ export const dbBackup = async (options: { name?: string }) => { } else { // Backup all databases const s = spinner(); - s.start("Backing up all databases\n"); + s.start("Backing up all databases"); await setupMainFunction(config); // Call main function to backup all databases s.stop(); } From 28584c2ad1744dbb83f1aa260f27f5209f5da761 Mon Sep 17 00:00:00 2001 From: Anupam Bista Date: Wed, 18 Sep 2024 19:24:46 +0545 Subject: [PATCH 15/17] multiple database can be provided with --name flag in db:backup command --- docs/guide/cli/db-backup.md | 14 ++++++++-- src/commands/database.ts | 56 +++++++++++++++++++++++++++---------- src/commands/general.ts | 16 ++++++----- 3 files changed, 61 insertions(+), 25 deletions(-) diff --git a/docs/guide/cli/db-backup.md b/docs/guide/cli/db-backup.md index e91af40..76b2070 100644 --- a/docs/guide/cli/db-backup.md +++ b/docs/guide/cli/db-backup.md @@ -1,6 +1,6 @@ # `db:backup` Command Documentation -The `db:backup` command is used to back up all databases defined in the YAML configuration, or a specific one using the `--name` flag. +The `db:backup` command is used to back up all databases defined in the YAML configuration or specific ones using the `--name` flag. You can pass multiple databases to `--name` flag by providing a comma-separated list of database names. ## Usage @@ -12,10 +12,18 @@ To back up all databases, simply run the following command: ts-node index.ts db:backup ``` -### Backup Specific Database +### Backup Specific Database(s) -To back up a specific database, use the `--name` flag followed by the name of the database. For example: +To back up one or more specific databases, use the `--name` flag followed by the database name(s). You can provide a single database name or multiple names separated by commas. + +#### Backup a Single Database: ```bash node index.ts db:backup --name ``` + +#### Backup Multiple Databases: + +```bash +ts-node index.ts db:backup --name ,, +``` diff --git a/src/commands/database.ts b/src/commands/database.ts index ae7616d..1a17cc2 100644 --- a/src/commands/database.ts +++ b/src/commands/database.ts @@ -39,33 +39,59 @@ const setupMainFunction = async (config: DataBeeConfig) => { }; /** - * Performs a database backup. + * Backs up databases based on the provided options. * - * @param options - An optional object containing the name of the specific database to backup. - * @param options.name - The name of the specific database to backup. + * @param options - An object containing optional parameters. + * @param options.name - A comma-separated string of database names to back up. If not provided, all databases will be backed up. * - * @remarks - * If the `options.name` parameter is provided, the function will backup only the specified database. - * If the `options.name` parameter is not provided, the function will backup all databases. + * The function performs the following steps: + * 1. If `options.name` is provided, it splits the name by commas to handle multiple databases. + * 2. It filters the databases to find those that match any of the provided names. + * 3. If matching databases are found, it updates the configuration to include only the selected databases and starts the backup process. + * 4. If no matching databases are found, it logs an error message and exits the process. + * 5. If `options.name` is not provided, it backs up all databases. + * 6. In case of any errors during the backup process, it logs the error and a failure message. * - * @throws {Error} If the backup fails. + * @throws Will log an error and exit the process if no matching databases are found. + * @throws Will log an error message if the backup process fails. */ export const dbBackup = async (options: { name?: string }) => { const databases = config.databases; try { if (options.name) { - // select specific database - const db = databases.find((db: Database) => db.name === options.name); - // update config with the specific database - if (db) { - config.databases = [db]; + // Split the name by commas to handle multiple databases + const dbNames = options.name.split(",").map((name) => name.trim()); + + // Find the databases that match any of the names + const selectedDatabases = databases.filter((db: Database) => + dbNames.includes(db.name) + ); + // Extracting the names of the selected databases and not found databases from dbNames + const selectedDatabaseNames = selectedDatabases.map( + (db: Database) => db.name + ); + const notFoundDatabases = dbNames.filter( + (name) => !selectedDatabaseNames.includes(name) + ); + + if (selectedDatabases.length) { + config.databases = selectedDatabases; const s = spinner(); - s.start(`Backing up database: ${options.name}`); - await setupMainFunction(config); // Call main function to backup specific database + if (notFoundDatabases.length) { + console.log( + chalk.yellow( + `No matching databases found for: ${notFoundDatabases.join(", ")}` + ) + ); + } + s.start(`Backing up databases: ${selectedDatabaseNames.join(", ")}`); + await setupMainFunction(config); // Call main function to backup selected databases s.stop(); } else { - console.log(chalk.red(`Database "${options.name}" not found.`)); + console.log( + chalk.red(`No matching databases found for: ${dbNames.join(", ")}`) + ); process.exit(1); } } else { diff --git a/src/commands/general.ts b/src/commands/general.ts index c113b98..c3ec0ad 100644 --- a/src/commands/general.ts +++ b/src/commands/general.ts @@ -6,7 +6,7 @@ const general = async (options: { backupLocation?: string; logLocation?: string; logLevel?: string; - retentionPolicy?: string; + retentionPolicy?: number; backupSchedule?: string; }) => { if (!Object.keys(options).length) { @@ -30,10 +30,12 @@ const general = async (options: { initialValue: config.general.log_level, }); - const retentionPolicy = (await promptWithCancel(text, { - message: "Enter retention policy (days)", - initialValue: String(config.general.retention_policy_days), - })) as unknown as number; + const retentionPolicy = Number( + await promptWithCancel(text, { + message: "Enter retention policy (days)", + initialValue: String(config.general.retention_policy_days), + }) + ); const backupSchedule = await promptWithCancel(text, { message: "Enter backup schedule (cron format)", @@ -43,7 +45,7 @@ const general = async (options: { config.general.backup_location = backupLocation as string; config.general.log_location = logLocation as string; config.general.log_level = logLevel as string; - config.general.retention_policy_days = Number(retentionPolicy); + config.general.retention_policy_days = retentionPolicy; config.general.backup_schedule = backupSchedule as string; } else { // If flags are provided, use them to update the config directly @@ -52,7 +54,7 @@ const general = async (options: { if (options.logLocation) config.general.log_location = options.logLocation; if (options.logLevel) config.general.log_level = options.logLevel; if (options.retentionPolicy) - config.general.retention_policy_days = Number(options.retentionPolicy); + config.general.retention_policy_days = options.retentionPolicy; if (options.backupSchedule) config.general.backup_schedule = options.backupSchedule; } From b03ed2b483570e54d8b287ddc7f9fcc84b3a49d7 Mon Sep 17 00:00:00 2001 From: Anupam Bista Date: Wed, 18 Sep 2024 19:46:46 +0545 Subject: [PATCH 16/17] added configuration documentation --- backupdbee.yaml.sample | 5 +- docs/.vitepress/config.mts | 1 + docs/guide/cli/db-backup.md | 2 +- docs/guide/configuration.md | 156 ++++++++++++++++++++++++++++++++++++ 4 files changed, 159 insertions(+), 5 deletions(-) create mode 100644 docs/guide/configuration.md diff --git a/backupdbee.yaml.sample b/backupdbee.yaml.sample index b0d312a..b0ab992 100644 --- a/backupdbee.yaml.sample +++ b/backupdbee.yaml.sample @@ -23,14 +23,11 @@ destinations: smtp_port: 587 smtp_username: smtp_password: - -notifications: - email: - enabled: false from: no-reply@backupbee.com to: - master@backupbee.com +notifications: slack: enabled: true webhook_url: https://hooks.slack.com/services/XXXXXXXXXXXXXXXXXXXXXXXX diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts index 0aadf64..4780b34 100644 --- a/docs/.vitepress/config.mts +++ b/docs/.vitepress/config.mts @@ -34,6 +34,7 @@ function sidebarGuide(): DefaultTheme.SidebarItem[] { items: [ { text: "What is backupdbee?", link: "what-is-backupdbee" }, { text: "Getting Started", link: "getting-started" }, + { text: "Configuration", link: "configuration" }, ], }, { diff --git a/docs/guide/cli/db-backup.md b/docs/guide/cli/db-backup.md index 76b2070..8181c33 100644 --- a/docs/guide/cli/db-backup.md +++ b/docs/guide/cli/db-backup.md @@ -19,7 +19,7 @@ To back up one or more specific databases, use the `--name` flag followed by the #### Backup a Single Database: ```bash -node index.ts db:backup --name +ts-node index.ts db:backup --name ``` #### Backup Multiple Databases: diff --git a/docs/guide/configuration.md b/docs/guide/configuration.md new file mode 100644 index 0000000..399bb64 --- /dev/null +++ b/docs/guide/configuration.md @@ -0,0 +1,156 @@ +# BackupBee Configuration + +This document provides a comprehensive guide to configuring BackupBee using the `backupdbee.yaml` file. + +## Table of Contents + +1. [General Configuration](#general-configuration) +2. [Destinations](#destinations) +3. [Notifications](#notifications) +4. [Databases](#databases) + +## General Configuration + +The `general` section contains global settings for BackupBee: + +```yaml +general: + backup_location: backups + log_location: logs + log_level: INFO + retention_policy_days: 7 + backup_schedule: "0 3 * * *" +``` + +- `backup_location`: Directory where backups are stored +- `log_location`: Directory for log files +- `log_level`: Logging verbosity (e.g., INFO, DEBUG, ERROR) +- `retention_policy_days`: Number of days to retain backups +- `backup_schedule`: Cron expression for backup schedule (default: 3 AM daily) + +## Destinations + +BackupBee supports multiple backup destinations: + +### Local Storage + +```yaml +destinations: + local: + enabled: true + path: backups +``` + +- `enabled`: Set to `true` to use local storage +- `path`: Directory path for local backups + +### Amazon S3 + +```yaml +s3: + enabled: false + bucket_name: backupbee + region: us-east-1 + access_key: XXXXXXXXXXX + secret_key: XXXXXXXXXXX +``` + +- `enabled`: Set to `true` to use S3 +- `bucket_name`: S3 bucket name +- `region`: AWS region +- `access_key`: AWS access key +- `secret_key`: AWS secret key + +### Email + +```yaml +email: + enabled: false + smtp_server: smtp.gmail.com + smtp_port: 587 + smtp_username: + smtp_password: + from: no-reply@backupbee.com + to: + - master@backupbee.com +``` + +- `enabled`: Set to `true` to send backups via email +- `smtp_server`: SMTP server address +- `smtp_port`: SMTP port +- `smtp_username`: SMTP username +- `smtp_password`: SMTP password +- `from`: Email address used for sending notifications +- `to`: List of email addresses to receive notifications + +## Notifications + +BackupBee can send notifications through various channels: + +### Slack Notifications + +```yaml +slack: + enabled: true + webhook_url: https://hooks.slack.com/services/XXXXXXXXXXXXXXXXXXXXXXXX +``` + +### Custom Webhook + +```yaml +custom: + enabled: false + web_url: https://backupbee.com/api/v1/backup +``` + +### Discord Notifications + +```yaml +discord: + enabled: false + webhook_url: https://discord.com/api/webhooks/XXXXXXXXX/XXXXXXXXX +``` + +### Telegram Notifications + +```yaml +telegram: + enabled: true + webhook_url: https://api.telegram.org/botXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/sendMessage + chatId: XXXXXXX +``` + +For required notification type, set `enabled` to `true` and provide the necessary credentials or webhook URLs. + +## Databases + +Configure the databases you want to back up: + +```yaml +databases: + - name: primary_db + type: postgres + host: localhost + port: 5432 + username: postgres + password: pass + database_name: asterconsult + backup_schedule: "0 3 * * *" +``` + +- `name`: A unique identifier for the database +- `type`: Database type (e.g., postgres, mysql) +- `host`: Database server hostname +- `port`: Database server port +- `username`: Database username +- `password`: Database password +- `database_name`: Name of the database to back up +- `backup_schedule`: Cron expression for this specific database's backup schedule + +You can add multiple database configurations by repeating this structure. + +To comment out a database configuration, use the `#` symbol at the beginning of each line, as shown in the example for `secondary_db`. + +--- + +Remember to keep your `backupdbee.yaml` file secure, as it contains sensitive information such as database credentials and API keys. From b110ef3b55cfb5c6093a71b9b0fd46886fc145bc Mon Sep 17 00:00:00 2001 From: Anupam Bista Date: Fri, 20 Sep 2024 09:26:28 +0545 Subject: [PATCH 17/17] removed package dotenv --- package.json | 1 - pnpm-lock.yaml | 9 --------- src/index.ts | 1 - 3 files changed, 11 deletions(-) diff --git a/package.json b/package.json index 561032a..54c0323 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,6 @@ "chalk": "^4.1.2", "class-transformer": "^0.5.1", "commander": "^12.1.0", - "dotenv": "^16.4.5", "nodemailer": "^6.9.14", "ts-node": "^10.9.2", "winston": "^3.14.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index af13e5f..9db82e2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -26,9 +26,6 @@ importers: commander: specifier: ^12.1.0 version: 12.1.0 - dotenv: - specifier: ^16.4.5 - version: 16.4.5 nodemailer: specifier: ^6.9.14 version: 6.9.15 @@ -1257,10 +1254,6 @@ packages: resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} engines: {node: '>=0.3.1'} - dotenv@16.4.5: - resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} - engines: {node: '>=12'} - dynamic-dedupe@0.3.0: resolution: {integrity: sha512-ssuANeD+z97meYOqd50e04Ze5qp4bPqo8cCkI4TRjZkzAUgIDTrXV1R8QCdINpiI+hw14+rYazvTRdQrz0/rFQ==} @@ -3662,8 +3655,6 @@ snapshots: diff@4.0.2: {} - dotenv@16.4.5: {} - dynamic-dedupe@0.3.0: dependencies: xtend: 4.0.2 diff --git a/src/index.ts b/src/index.ts index 131394f..68ca3ed 100755 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,3 @@ -import "dotenv/config"; import backupHelper from "./utils/backup.utils"; import { exec } from "child_process"; import { ConfigType } from "./@types/types";