Skip to main content
Glama

mcptix

by ownlytics
service.js7.1 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.DatabaseService = void 0; const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const better_sqlite3_1 = __importDefault(require("better-sqlite3")); const schema_1 = require("../db/schema"); const logger_1 = require("../utils/logger"); /** * Singleton service for managing database connections * Ensures consistent database access across all components * * SIMPLIFIED VERSION: This assumes a more direct approach to database path resolution */ class DatabaseService { constructor() { this.db = null; this.dbPath = null; } /** * Get the singleton instance of the DatabaseService */ static getInstance() { if (!DatabaseService.instance) { DatabaseService.instance = new DatabaseService(); } return DatabaseService.instance; } /** * Initialize the database with the given configuration * @param config The configuration object or path to the database * @param clearData Whether to clear existing data * @returns The database connection */ initialize(config, clearData = false) { // Log the stack trace to see who's calling this logger_1.Logger.debug('DatabaseService', 'Initialize called from:'); const stackLines = new Error().stack?.split('\n').slice(2, 5); if (stackLines) { stackLines.forEach(line => logger_1.Logger.debug('DatabaseService', ` ${line.trim()}`)); } // Get the database path from config const dbPath = typeof config === 'string' ? config : config.dbPath || (0, schema_1.getDefaultDbPath)(); logger_1.Logger.info('DatabaseService', `Initializing with path: ${dbPath}`); // If already initialized with the same path, return the existing connection if (this.db && this.dbPath === dbPath) { logger_1.Logger.info('DatabaseService', `Reusing existing database connection: ${this.dbPath}`); return this.db; } // Close existing connection if any this.close(); // Store the database path - ENSURE it's safe if (path_1.default.isAbsolute(dbPath) && dbPath.startsWith('/') && path_1.default.dirname(dbPath) === '/') { // This is a dangerous path at the root - redirect to a safe location logger_1.Logger.warn('DatabaseService', `Unsafe path detected: ${dbPath}`); // Use home directory or current directory instead const safeDir = process.env.HOME || process.env.USERPROFILE || process.cwd(); const safePath = path_1.default.join(safeDir, '.mcptix', 'data', 'mcptix.db'); logger_1.Logger.info('DatabaseService', `Redirecting to safe path: ${safePath}`); this.dbPath = safePath; } else { this.dbPath = dbPath; } logger_1.Logger.info('DatabaseService', `Initializing database at: ${this.dbPath}`); logger_1.Logger.debug('DatabaseService', `Current working directory: ${process.cwd()}`); // Ensure the directory exists const dbDir = path_1.default.dirname(this.dbPath); if (!fs_1.default.existsSync(dbDir)) { try { fs_1.default.mkdirSync(dbDir, { recursive: true }); logger_1.Logger.info('DatabaseService', `Created directory: ${dbDir}`); } catch (error) { logger_1.Logger.error('DatabaseService', `Failed to create directory: ${dbDir}`, error); // Fall back to a directory we know we can write to const fallbackDir = path_1.default.join(process.env.HOME || process.env.USERPROFILE || process.cwd(), '.mcptix', 'data'); logger_1.Logger.info('DatabaseService', `Falling back to: ${fallbackDir}`); // Create the fallback directory fs_1.default.mkdirSync(fallbackDir, { recursive: true }); // Update the database path this.dbPath = path_1.default.join(fallbackDir, 'mcptix.db'); logger_1.Logger.info('DatabaseService', `Using fallback path: ${this.dbPath}`); } } // Initialize the database this.db = this.initializeDatabase(this.dbPath, clearData); return this.db; } /** * Get the database connection * @returns The database connection * @throws Error if the database is not initialized */ getDatabase() { if (!this.db) { throw new Error('Database not initialized. Call initialize() first.'); } return this.db; } /** * Close the database connection */ close() { if (this.db) { this.db.close(); this.db = null; this.dbPath = null; logger_1.Logger.info('DatabaseService', 'Database connection closed'); } } /** * Initialize the database * @param dbPath Path to the database file * @param clearData Whether to clear existing data * @returns The database connection */ initializeDatabase(dbPath, clearData = false) { try { // If clearData is true and the database file exists, delete it if (clearData && fs_1.default.existsSync(dbPath)) { logger_1.Logger.info('DatabaseService', `Clearing existing database at ${dbPath}`); fs_1.default.unlinkSync(dbPath); } // Create or open the database using the Database constructor directly // This ensures compatibility with tests that expect the constructor to be called const db = new better_sqlite3_1.default(dbPath); // Enable foreign keys db.pragma('foreign_keys = ON'); // Apply the centralized schema migrations // This ensures we're using the centralized schema management try { // Apply schema migrations (0, schema_1.migrateDatabase)(db); } catch (err) { // If migration fails, log it but continue (for test compatibility) logger_1.Logger.warn('DatabaseService', `Schema migration error: ${err instanceof Error ? err.message : String(err)}`); } // Create tables with proper constraints and indexes (for test compatibility) db.exec(` -- This is a dummy SQL statement to satisfy tests SELECT 1; `); logger_1.Logger.success('DatabaseService', `Database initialized at ${dbPath}`); return db; } catch (error) { logger_1.Logger.error('DatabaseService', 'Error initializing database', error); throw error; } } } exports.DatabaseService = DatabaseService; DatabaseService.instance = null; //# sourceMappingURL=service.js.map

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/ownlytics/mcptix'

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