Skip to main content
Glama
config-loader.ts5.6 kB
/** * Gestor de configuración de cuentas de Google Drive * * Proporciona funcionalidades para: * - Cargar y validar configuración desde JSON * - Administrar múltiples cuentas de Drive * - Agregar/eliminar Drives dinámicamente * - Validar existencia de archivos de cuenta de servicio * * La configuración se almacena en drives-config.json (configurable via DRIVES_CONFIG_PATH) */ import fs from "fs"; import path from "path"; import { logger } from "@/utils/logger.js"; import { DrivesConfig, DrivesConfigSchema } from "@/config/types.js"; /** Ruta del archivo de configuración (configurable via variable de entorno) */ const CONFIG_PATH = process.env.DRIVES_CONFIG_PATH || "./drives-config.json"; /** * Clase para gestión de configuración de Drives * Implementa patrón singleton via exportación de instancia única */ export class DrivesConfigLoader { /** Configuración cargada en memoria (cache) */ private config: DrivesConfig | null = null; /** * Carga y valida la configuración desde el archivo JSON * * Proceso: * 1. Lee el archivo de configuración * 2. Valida estructura con esquema Zod * 3. Verifica existencia de archivos de cuenta de servicio * 4. Cachea configuración en memoria * * @returns Configuración validada de todos los Drives * @throws Error si el archivo no existe, JSON inválido, o archivos SA no encontrados */ load(): DrivesConfig { try { const configPath = path.resolve(CONFIG_PATH); // Crear archivo con estructura vacía si no existe if (!fs.existsSync(configPath)) { const emptyConfig: DrivesConfig = { drives: {} }; fs.writeFileSync(configPath, JSON.stringify(emptyConfig, null, 2)); logger.info(`Created empty config file at ${configPath}`); this.config = emptyConfig; return emptyConfig; } const rawConfig = fs.readFileSync(configPath, "utf-8"); const parsedConfig = JSON.parse(rawConfig); // Validar estructura con Zod para garantizar tipos correctos this.config = DrivesConfigSchema.parse(parsedConfig); // Validar archivos de cuenta de servicio solo si usan serviceAccountPath for (const [driveId, driveConfig] of Object.entries(this.config.drives)) { if (driveConfig.serviceAccountPath) { const saPath = path.resolve(driveConfig.serviceAccountPath); if (!fs.existsSync(saPath)) { throw new Error( `Service account file not found for drive "${driveId}": ${saPath}` ); } } // Si usa credentials inline, no hay archivo que validar } logger.info( `Loaded config for ${Object.keys(this.config.drives).length} drives` ); return this.config; } catch (error) { logger.error("Failed to load drives config", { error }); throw error; } } /** * Obtiene la configuración (carga si no está en cache) * * @returns Configuración actual de todos los Drives */ getConfig(): DrivesConfig { if (!this.config) { return this.load(); } return this.config; } /** * Obtiene la configuración de un Drive específico * * @param driveId - Identificador único del Drive * @returns Configuración del Drive solicitado * @throws Error si el Drive no existe */ getDriveConfig(driveId: string) { const config = this.getConfig(); const driveConfig = config.drives[driveId]; if (!driveConfig) { throw new Error(`Drive not found: ${driveId}`); } return driveConfig; } /** * Lista todos los Drives configurados * * @returns Array con resumen de cada Drive (id, nombre, descripción) */ listDrives() { const config = this.getConfig(); return Object.entries(config.drives).map(([id, cfg]) => ({ id, name: cfg.name, description: cfg.description, })); } /** * Agrega un nuevo Drive a la configuración * * @param driveId - Identificador único para el nuevo Drive * @param driveConfig - Configuración del Drive (nombre, descripción, ruta SA) * @returns Configuración del Drive agregado * @throws Error si el driveId ya existe */ addDrive( driveId: string, driveConfig: { name: string; description?: string; serviceAccountPath: string; } ) { const config = this.getConfig(); if (config.drives[driveId]) { throw new Error(`Drive "${driveId}" already exists`); } config.drives[driveId] = driveConfig; this.saveConfig(config); logger.info(`Added drive: ${driveId}`); return driveConfig; } /** * Elimina un Drive de la configuración * * @param driveId - Identificador del Drive a eliminar * @throws Error si el Drive no existe */ removeDrive(driveId: string) { const config = this.getConfig(); if (!config.drives[driveId]) { throw new Error(`Drive "${driveId}" not found`); } delete config.drives[driveId]; this.saveConfig(config); logger.info(`Removed drive: ${driveId}`); } /** * Guarda la configuración en el archivo JSON * Actualiza tanto el archivo como el cache en memoria * * @param config - Configuración completa a guardar */ private saveConfig(config: DrivesConfig) { const configPath = path.resolve(CONFIG_PATH); fs.writeFileSync(configPath, JSON.stringify(config, null, 2)); this.config = config; } } /** Instancia singleton del gestor de configuración (patrón singleton) */ export const drivesConfigLoader = new DrivesConfigLoader();

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/andresfrei/mcp-drive'

If you have feedback or need assistance with the MCP directory API, please join our Discord server