UNPKG

appwrite-utils-cli

Version:

Appwrite Utility Functions to help with database management, data conversion, data import, migrations, and much more. Meant to be used as a CLI tool, I do not recommend installing this in frontend environments.

153 lines (152 loc) 7.11 kB
import chalk from "chalk"; import { logger } from "./logging.js"; export class MessageFormatter { static success(message, options = {}) { const formatted = `${chalk.green("✅")} ${options.prefix ? `${options.prefix}: ` : ""}${message}`; console.log(formatted); if (!options.skipLogging) { logger.info(`SUCCESS: ${options.prefix ? `${options.prefix}: ` : ""}${message}`); } } static error(message, error, options = {}) { const errorDetails = error instanceof Error ? error.message : error; const formatted = `${chalk.red("❌")} ${options.prefix ? `${options.prefix}: ` : ""}${message}${errorDetails ? `\n ${chalk.gray(errorDetails)}` : ""}`; console.error(formatted); if (!options.skipLogging) { logger.error(`ERROR: ${options.prefix ? `${options.prefix}: ` : ""}${message}`, { error: errorDetails, stack: error instanceof Error ? error.stack : undefined, }); } } static warning(message, options = {}) { const formatted = `${chalk.yellow("⚠️")} ${options.prefix ? `${options.prefix}: ` : ""}${message}`; console.log(formatted); if (!options.skipLogging) { logger.warn(`WARNING: ${options.prefix ? `${options.prefix}: ` : ""}${message}`); } } static info(message, options = {}) { const formatted = `${chalk.blue("ℹ️")} ${options.prefix ? `${options.prefix}: ` : ""}${message}`; console.log(formatted); if (!options.skipLogging) { logger.info(`INFO: ${options.prefix ? `${options.prefix}: ` : ""}${message}`); } } static step(step, total, message, options = {}) { const formatted = `${chalk.cyan(`[${step}/${total}]`)} ${options.prefix ? `${options.prefix}: ` : ""}${message}`; console.log(formatted); if (!options.skipLogging) { logger.info(`STEP ${step}/${total}: ${options.prefix ? `${options.prefix}: ` : ""}${message}`); } } static progress(message, options = {}) { const formatted = `${chalk.gray("⏳")} ${options.prefix ? `${options.prefix}: ` : ""}${message}`; console.log(formatted); if (!options.skipLogging) { logger.debug(`PROGRESS: ${options.prefix ? `${options.prefix}: ` : ""}${message}`); } } static debug(message, data, options = {}) { if (process.env.NODE_ENV === "development" || process.env.DEBUG) { const formatted = `${chalk.magenta("🔍")} ${options.prefix ? `${options.prefix}: ` : ""}${message}`; console.log(formatted); if (data) { console.log(chalk.gray(JSON.stringify(data, null, 2))); } } if (!options.skipLogging) { logger.debug(`DEBUG: ${options.prefix ? `${options.prefix}: ` : ""}${message}`, data); } } static banner(title, subtitle) { const divider = chalk.cyan("═".repeat(60)); console.log(`\n${divider}`); console.log(chalk.cyan.bold(` ${title}`)); if (subtitle) { console.log(chalk.gray(` ${subtitle}`)); } console.log(`${divider}\n`); } static section(title) { console.log(`\n${chalk.bold.underline(title)}`); } static list(items, title) { if (title) { console.log(chalk.bold(title)); } items.forEach((item, index) => { console.log(`${chalk.gray(` ${index + 1}.`)} ${item}`); }); } static table(data, headers) { if (data.length === 0) return; const keys = headers || Object.keys(data[0]); const maxWidths = keys.map(key => Math.max(key.length, ...data.map(row => String(row[key]).length))); // Header const headerRow = keys.map((key, i) => chalk.bold(key.padEnd(maxWidths[i]))).join(" │ "); console.log(`┌─${keys.map((_, i) => "─".repeat(maxWidths[i])).join("─┼─")}─┐`); console.log(`│ ${headerRow} │`); console.log(`├─${keys.map((_, i) => "─".repeat(maxWidths[i])).join("─┼─")}─┤`); // Rows data.forEach(row => { const dataRow = keys.map((key, i) => String(row[key]).padEnd(maxWidths[i])).join(" │ "); console.log(`│ ${dataRow} │`); }); console.log(`└─${keys.map((_, i) => "─".repeat(maxWidths[i])).join("─┴─")}─┘`); } static operationSummary(title, stats, duration) { this.section(`${title} Summary`); Object.entries(stats).forEach(([key, value]) => { const formattedKey = key.replace(/([A-Z])/g, ' $1').replace(/^./, str => str.toUpperCase()); console.log(`${chalk.gray("●")} ${formattedKey}: ${chalk.cyan(String(value))}`); }); if (duration) { console.log(`${chalk.gray("●")} Duration: ${chalk.cyan(this.formatDuration(duration))}`); } console.log(); } static formatBytes(bytes) { const units = ['B', 'KB', 'MB', 'GB', 'TB']; let size = bytes; let unitIndex = 0; while (size >= 1024 && unitIndex < units.length - 1) { size /= 1024; unitIndex++; } return `${size.toFixed(1)} ${units[unitIndex]}`; } static formatDuration(ms) { const seconds = Math.floor(ms / 1000); const minutes = Math.floor(seconds / 60); const hours = Math.floor(minutes / 60); if (hours > 0) { return `${hours}h ${minutes % 60}m ${seconds % 60}s`; } else if (minutes > 0) { return `${minutes}m ${seconds % 60}s`; } else { return `${seconds}s`; } } static formatNumber(num) { return num.toLocaleString(); } } export const Messages = { CONFIG_NOT_FOUND: "Appwrite configuration not found. Run 'appwrite-migrate setup' first.", CONFIG_LOADED: (type, path) => `Loaded ${type} configuration from ${path}`, DATABASE_CONNECTION_FAILED: "Failed to connect to Appwrite. Check your endpoint and API key.", OPERATION_CANCELLED: "Operation cancelled by user.", OPERATION_COMPLETED: (operation) => `${operation} completed successfully`, BACKUP_STARTED: (database) => `Starting backup for database: ${database}`, BACKUP_COMPLETED: (database, size) => `Backup completed for ${database} (${MessageFormatter.formatBytes(size)})`, IMPORT_STARTED: (collections) => `Starting import process for ${collections} collection(s)`, IMPORT_COMPLETED: (documents) => `Import completed. Processed ${MessageFormatter.formatNumber(documents)} documents`, FUNCTION_DEPLOYED: (name) => `Function '${name}' deployed successfully`, FUNCTION_DEPLOYMENT_FAILED: (name, error) => `Function '${name}' deployment failed: ${error}`, TRANSFER_STARTED: (source, target) => `Starting transfer from ${source} to ${target}`, TRANSFER_COMPLETED: (items) => `Transfer completed. Moved ${MessageFormatter.formatNumber(items)} items`, };