@laiyon/create-wasapi
Version:
CLI to create WhatsApp bot projects with Wasapi and BuilderBot
168 lines (167 loc) • 6.49 kB
JavaScript
import inquirer from "inquirer";
import { MySQLProvider } from "./providers/MySQLProvider.js";
import { PostgreSQLProvider } from "./providers/PostgreSQLProvider.js";
import { MongoDBProvider } from "./providers/MongoDBProvider.js";
import chalk from "chalk";
import ora from "ora";
export class DatabaseConfigService {
// Method to generate cache key
static getCacheKey(dbType, config) {
return `${dbType}:${config.host}:${config.port}:${config.user}:${config.database}`;
}
// Method to check if a configuration is cached and valid
static isConfigCached(dbType, config) {
const cacheKey = this.getCacheKey(dbType, config);
const cached = this.configCache.get(cacheKey);
if (cached && (Date.now() - cached.timestamp) < this.CACHE_TTL) {
return true;
}
// Clean expired entry
if (cached) {
this.configCache.delete(cacheKey);
}
return false;
}
// Method to save configuration in cache
static cacheConfig(dbType, config) {
const cacheKey = this.getCacheKey(dbType, config);
this.configCache.set(cacheKey, {
config: { ...config },
timestamp: Date.now()
});
}
static async configureDatabase(dbType) {
const provider = this.providers.get(dbType);
if (!provider) {
throw new Error(`Unsupported database provider: ${dbType}`);
}
const requiredVars = provider.getRequiredEnvVars();
const config = {};
console.log(chalk.bgCyan.black(` 🗄️ ${dbType.toUpperCase()} CONFIGURATION `));
console.log("");
console.log(chalk.cyan(` Configuring connection to ${dbType.toUpperCase()}...`));
console.log("");
// Request configuration based on database type
if (dbType === "mysql" || dbType === "postgresql") {
console.log(chalk.gray(" 📝 Enter connection details:"));
console.log("");
const answers = await inquirer.prompt([
{
type: "input",
name: "host",
message: chalk.blue("🏠 Database host:"),
default: "localhost"
},
{
type: "input",
name: "port",
message: chalk.blue("🔌 Port:"),
default: dbType === "mysql" ? "3306" : "5432"
},
{
type: "input",
name: "user",
message: chalk.blue("👤 Username:"),
default: "root"
},
{
type: "password",
name: "password",
message: chalk.blue("🔒 Password:")
},
{
type: "input",
name: "database",
message: chalk.blue("📁 Database name:"),
default: "wasabot_db"
}
]);
config.host = answers.host;
config.port = parseInt(answers.port);
config.user = answers.user;
config.password = answers.password;
config.database = answers.database;
}
else if (dbType === "mongodb") {
console.log(chalk.gray(" 📝 Enter connection URL:"));
console.log("");
const answers = await inquirer.prompt([
{
type: "input",
name: "url",
message: chalk.blue("🔗 MongoDB connection URL:"),
default: "mongodb://localhost:27017/wasabot_db"
}
]);
config.url = answers.url;
}
// Validate configuration
if (!provider.validateConfig(config)) {
throw new Error("Invalid database configuration");
}
return config;
}
// Optimized method for quick connection validation with improved UI
static async validateDatabaseConnection(dbType, config) {
// Check cache first
if (this.isConfigCached(dbType, config)) {
console.log(chalk.green(" ✅ Connection validated (cached)"));
return true;
}
const provider = this.providers.get(dbType);
if (!provider) {
return false;
}
console.log("");
console.log(chalk.yellow(" 🔄 Validating database connection..."));
console.log("");
// Spinner to show progress
const spinner = ora({
text: chalk.blue(" Connecting to database..."),
color: "blue"
}).start();
let isValid = false;
try {
// Use optimized validation method if available
if ('validateConnection' in provider && typeof provider.validateConnection === 'function') {
isValid = await provider.validateConnection(config);
}
else {
// Fallback: create temporary instance to validate
const db = provider.createDatabase(config);
await db.connect();
await db.disconnect();
isValid = true;
}
if (isValid) {
spinner.succeed(chalk.green(" ✅ Connection successful"));
console.log(chalk.green(` 🗄️ ${dbType.toUpperCase()} database configured successfully`));
// Save to cache if validation was successful
this.cacheConfig(dbType, config);
}
else {
spinner.fail(chalk.red(" ❌ Connection failed"));
}
}
catch (error) {
spinner.fail(chalk.red(" ❌ Connection error"));
console.log(chalk.red(` 💡 Error: ${error}`));
}
console.log("");
return isValid;
}
static getProvider(dbType) {
return this.providers.get(dbType);
}
static getSupportedDatabases() {
return Array.from(this.providers.keys());
}
}
DatabaseConfigService.providers = new Map([
["mysql", new MySQLProvider()],
["postgresql", new PostgreSQLProvider()],
["mongodb", new MongoDBProvider()],
]);
// Simple cache for validated configurations during session
DatabaseConfigService.configCache = new Map();
DatabaseConfigService.CACHE_TTL = 5 * 60 * 1000; // 5 minutes