{"version":3,"sources":["../src/index.ts","../src/lib/Schema.ts","../src/lib/FileUtils.ts","../src/lib/UIUtils.ts","../src/lib/CubeValidator.ts","../src/lib/DependencyResolver.ts"],"sourcesContent":["import { Schema } from './lib/Schema';\r\nimport { CubeValidator } from './lib/CubeValidator';\r\nimport { UIUtils } from './lib/UIUtils';\r\nimport { DependencyResolver } from './lib/DependencyResolver';\r\nimport { Engine, Config } from '@dbcube/core';\r\n\r\nexport default Schema;\r\nexport { Schema, CubeValidator, UIUtils, DependencyResolver, Engine, Config };","import fs from 'fs';\r\nimport { Engine, TableProcessor, Config as ConfigClass, EnvLoader } from \"@dbcube/core\";\r\nimport path from 'path';\r\nimport FileUtils from './FileUtils';\r\nimport chalk from 'chalk';\r\nimport { UIUtils, ProcessSummary, ProcessError } from './UIUtils';\r\nimport { CubeValidator } from './CubeValidator';\r\nimport { DependencyResolver } from './DependencyResolver';\r\nimport { createRequire } from 'module';\r\n\r\n/**\r\n * Main class to handle MySQL database connections and queries.\r\n * Implements the Singleton pattern to ensure a single instance of the connection pool.\r\n */\r\nclass Schema {\r\n    private name: string;\r\n    private engine: any;\r\n\r\n    constructor(name: string) {\r\n        this.name = name;\r\n        this.engine = new Engine(name);\r\n    }\r\n\r\n    /**\r\n     * Validates cube file comprehensively including syntax, database configuration, and structure\r\n     * @param filePath - Path to the cube file\r\n     * @returns validation result with any errors found\r\n     */\r\n    private validateDatabaseConfiguration(filePath: string): { isValid: boolean; error?: ProcessError } {\r\n        try {\r\n            // First, perform comprehensive cube file validation\r\n            const cubeValidator = new CubeValidator();\r\n            const cubeValidation = cubeValidator.validateCubeFile(filePath);\r\n\r\n            // If cube file has syntax errors, return the first one\r\n            if (!cubeValidation.isValid && cubeValidation.errors.length > 0) {\r\n                return {\r\n                    isValid: false,\r\n                    error: cubeValidation.errors[0] // Return the first error found\r\n                };\r\n            }\r\n\r\n            // Extract database name from cube file\r\n            const dbResult = FileUtils.extractDatabaseNameFromCube(filePath);\r\n            if (dbResult.status !== 200) {\r\n                return {\r\n                    isValid: false,\r\n                    error: {\r\n                        itemName: path.basename(filePath, path.extname(filePath)),\r\n                        error: `Error reading database directive: ${dbResult.message}`,\r\n                        filePath,\r\n                        lineNumber: this.findDatabaseLineNumber(filePath)\r\n                    }\r\n                };\r\n            }\r\n\r\n            const cubeDbName = dbResult.message;\r\n\r\n            // Get available configurations\r\n            const configInstance = new ConfigClass();\r\n            // Carga automática de .env (sin dotenv).\r\n            EnvLoader.load();\r\n            // En proyectos ESM, dbcube.config.cjs se carga con require() y el .js no.\r\n            const cjsPath = path.resolve(process.cwd(), 'dbcube.config.cjs');\r\n            const configFilePath = fs.existsSync(cjsPath)\r\n                ? cjsPath\r\n                : path.resolve(process.cwd(), 'dbcube.config.js');\r\n\r\n            // Use __filename for CJS, process.cwd() for ESM\r\n            const requireUrl = typeof __filename !== 'undefined' ? __filename : process.cwd();\r\n            const require = createRequire(requireUrl);\r\n            // Clear require cache to ensure fresh load\r\n            delete require.cache[require.resolve(configFilePath)];\r\n            const configModule = require(configFilePath);\r\n            const configFn = configModule.default || configModule;\r\n\r\n            if (typeof configFn === 'function') {\r\n                configFn(configInstance);\r\n            } else {\r\n                throw new Error('❌ The dbcube config file does not export a function.');\r\n            }\r\n\r\n            // Check if the database configuration exists\r\n            const dbConfig = configInstance.getDatabase(cubeDbName);\r\n            if (!dbConfig) {\r\n                // Lista REAL de bases configuradas (antes se adivinaban nombres\r\n                // comunes y casi siempre salía \"none found\" aunque hubiera config).\r\n                let availableDbs: string[] = [];\r\n                try {\r\n                    availableDbs = Object.keys(configInstance.getAllDatabases() || {});\r\n                } catch (e) {\r\n                    // Fallback si no se pueden determinar\r\n                }\r\n\r\n                const availableText = availableDbs.length > 0 ? availableDbs.join(', ') : 'none configured';\r\n                return {\r\n                    isValid: false,\r\n                    error: {\r\n                        itemName: path.basename(filePath, path.extname(filePath)),\r\n                        error: `Database configuration '${cubeDbName}' not found in dbcube.config.js. Available: ${availableText}`,\r\n                        filePath,\r\n                        lineNumber: this.findDatabaseLineNumber(filePath)\r\n                    }\r\n                };\r\n            }\r\n\r\n            return { isValid: true };\r\n\r\n        } catch (error: any) {\r\n            return {\r\n                isValid: false,\r\n                error: {\r\n                    itemName: path.basename(filePath, path.extname(filePath)),\r\n                    error: `Database configuration validation failed: ${error.message}`,\r\n                    filePath,\r\n                    lineNumber: this.findDatabaseLineNumber(filePath)\r\n                }\r\n            };\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Finds the line number where @database directive is located\r\n     */\r\n    private findDatabaseLineNumber(filePath: string): number {\r\n        try {\r\n            const content = fs.readFileSync(filePath, 'utf8');\r\n            const lines = content.split('\\n');\r\n            for (let i = 0; i < lines.length; i++) {\r\n                if (lines[i].includes('@database')) {\r\n                    return i + 1; // Line numbers start at 1\r\n                }\r\n            }\r\n            return 1;\r\n        } catch {\r\n            return 1;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Extracts foreign key dependencies from a cube file\r\n     */\r\n    private extractForeignKeyDependencies(filePath: string): string[] {\r\n        const dependencies: string[] = [];\r\n\r\n        try {\r\n            const content = fs.readFileSync(filePath, 'utf8');\r\n            const lines = content.split('\\n');\r\n\r\n            let insideForeignKey = false;\r\n            let braceCount = 0;\r\n\r\n            for (const line of lines) {\r\n                // Check for foreign key start\r\n                if (/foreign\\s*:\\s*\\{/.test(line)) {\r\n                    insideForeignKey = true;\r\n                    braceCount = 1;\r\n\r\n                    // Check if table is on the same line\r\n                    const sameLineMatch = line.match(/table\\s*:\\s*[\"']([^\"']+)[\"']/);\r\n                    if (sameLineMatch) {\r\n                        dependencies.push(sameLineMatch[1]);\r\n                        insideForeignKey = false;\r\n                        braceCount = 0;\r\n                    }\r\n                    continue;\r\n                }\r\n\r\n                if (insideForeignKey) {\r\n                    // Count braces to track if we're still inside the foreign object\r\n                    braceCount += (line.match(/\\{/g) || []).length;\r\n                    braceCount -= (line.match(/\\}/g) || []).length;\r\n\r\n                    // Look for table reference\r\n                    const tableMatch = line.match(/table\\s*:\\s*[\"']([^\"']+)[\"']/);\r\n                    if (tableMatch) {\r\n                        dependencies.push(tableMatch[1]);\r\n                    }\r\n\r\n                    // If braces are balanced, we're out of the foreign object\r\n                    if (braceCount === 0) {\r\n                        insideForeignKey = false;\r\n                    }\r\n                }\r\n            }\r\n        } catch (error) {\r\n            console.error(`Error reading dependencies from ${filePath}:`, error);\r\n        }\r\n\r\n        return dependencies;\r\n    }\r\n\r\n    /**\r\n     * Finds the line number where a foreign key table reference is located\r\n     */\r\n    private findForeignKeyLineNumber(filePath: string, tableName: string): number {\r\n        try {\r\n            const content = fs.readFileSync(filePath, 'utf8');\r\n            const lines = content.split('\\n');\r\n            for (let i = 0; i < lines.length; i++) {\r\n                if (lines[i].includes(`table: \"${tableName}\"`) || lines[i].includes(`table: '${tableName}'`)) {\r\n                    return i + 1; // Line numbers start at 1\r\n                }\r\n            }\r\n            return 1;\r\n        } catch {\r\n            return 1;\r\n        }\r\n    }\r\n\r\n    async createDatabase(): Promise<any> {\r\n        const startTime = Date.now();\r\n        const rootPath = path.resolve(process.cwd());\r\n\r\n        // Show header\r\n        UIUtils.showOperationHeader(' CREATING DATABASE', this.name, '🗄️');\r\n\r\n        // Show progress for database creation\r\n        await UIUtils.showItemProgress('Preparando e instalando base de datos', 1, 1);\r\n\r\n        try {\r\n            const response = await this.engine.run('schema_engine', [\r\n                '--action', 'create_database',\r\n                '--path', rootPath,\r\n            ]);\r\n\r\n            if (response.status != 200) {\r\n                returnFormattedError(response.status, response.message);\r\n            }\r\n\r\n            UIUtils.showItemSuccess('Database');\r\n\r\n            // Show final summary\r\n            const summary: ProcessSummary = {\r\n                startTime,\r\n                totalProcessed: 1,\r\n                successCount: 1,\r\n                errorCount: 0,\r\n                processedItems: [this.name],\r\n                operationName: 'create database',\r\n                databaseName: this.name,\r\n                errors: []\r\n            };\r\n            UIUtils.showOperationSummary(summary);\r\n\r\n            return response.data;\r\n\r\n        } catch (error: any) {\r\n            UIUtils.showItemError('Database', error.message);\r\n            const summary: ProcessSummary = {\r\n                startTime,\r\n                totalProcessed: 0,\r\n                successCount: 0,\r\n                errorCount: 1,\r\n                processedItems: [],\r\n                operationName: 'create database',\r\n                databaseName: this.name,\r\n                errors: []\r\n            };\r\n            UIUtils.showOperationSummary(summary);\r\n            throw error;\r\n        }\r\n    }\r\n\r\n    async refreshTables(): Promise<any> {\r\n        const startTime = Date.now();\r\n        const cubesDir = path.join(process.cwd(), 'dbcube');\r\n\r\n        // Verificar si la carpeta existe\r\n        if (!fs.existsSync(cubesDir)) {\r\n            throw new Error('❌ The cubes folder does not exist');\r\n        }\r\n\r\n        const cubeFiles = FileUtils.getCubeFilesRecursively('dbcube', '.table.cube');\r\n        if (cubeFiles.length === 0) {\r\n            throw new Error('❌ There are no cubes to execute');\r\n        }\r\n\r\n        // Resolve dependencies and create execution order\r\n        DependencyResolver.resolveDependencies(cubeFiles, 'table');\r\n\r\n        // Order files based on dependencies\r\n        const orderedCubeFiles = DependencyResolver.orderCubeFiles(cubeFiles, 'table');\r\n\r\n        // Show header\r\n        UIUtils.showOperationHeader('EXECUTING REFRESH TABLES', this.name, '🔄');\r\n\r\n        let totalTablesProcessed = 0;\r\n        let successCount = 0;\r\n        let errorCount = 0;\r\n        const processedTables: string[] = [];\r\n        const errors: ProcessError[] = [];\r\n        const failedTables = new Set<string>(); // Track failed table names\r\n\r\n        for (let index = 0; index < orderedCubeFiles.length; index++) {\r\n            const file = orderedCubeFiles[index];\r\n            const filePath = path.isAbsolute(file) ? file : path.join(cubesDir, file);\r\n            const stats = fs.statSync(filePath);\r\n\r\n            if (stats.isFile()) {\r\n                const getTableName = FileUtils.extracTableNameFromCube(filePath);\r\n                const tableName = getTableName.status === 200 ? getTableName.message : path.basename(file, '.table.cube');\r\n\r\n                // Show visual progress for each table\r\n                await UIUtils.showItemProgress(tableName, index + 1, orderedCubeFiles.length);\r\n\r\n                try {\r\n                    // Validate database configuration before processing\r\n                    const validation = this.validateDatabaseConfiguration(filePath);\r\n                    if (!validation.isValid && validation.error) {\r\n                        UIUtils.showItemError(tableName, validation.error.error);\r\n                        errors.push(validation.error);\r\n                        failedTables.add(tableName);\r\n                        errorCount++;\r\n                        continue;\r\n                    }\r\n\r\n                    // Check if any dependent tables failed\r\n                    const dependencies = this.extractForeignKeyDependencies(filePath);\r\n                    const missingDependencies = dependencies.filter(dep => failedTables.has(dep));\r\n\r\n                    if (missingDependencies.length > 0) {\r\n                        const dependencyError: ProcessError = {\r\n                            itemName: tableName,\r\n                            error: `Cannot refresh table '${tableName}' because it depends on failed table(s): ${missingDependencies.join(', ')}`,\r\n                            filePath,\r\n                            lineNumber: this.findForeignKeyLineNumber(filePath, missingDependencies[0])\r\n                        };\r\n                        UIUtils.showItemError(tableName, dependencyError.error);\r\n                        errors.push(dependencyError);\r\n                        failedTables.add(tableName);\r\n                        errorCount++;\r\n                        continue;\r\n                    }\r\n\r\n                    const dbResult = FileUtils.extractDatabaseNameFromCube(filePath);\r\n                    const cubeDbName = dbResult.status === 200 ? dbResult.message : this.name;\r\n                    if (cubeDbName !== this.name) { continue; }\r\n\r\n                    const dml = await this.engine.run('schema_engine', [\r\n                        '--action', 'parse_table',\r\n                        '--mode', 'refresh',\r\n                        '--schema-path', filePath,\r\n                    ]);\r\n                    if (dml.status != 200) {\r\n                        returnFormattedError(dml.status, dml.message);\r\n                        break;\r\n                    }\r\n                    const parseJson = JSON.stringify(dml.data.actions).replace(/[\\r\\n\\t]/g, '').replace(/\\\\[rnt]/g, '').replace(/\\s{2,}/g, ' ');\r\n\r\n                    const queries = await this.engine.run('schema_engine', [\r\n                        '--action', 'generate',\r\n                        '--mode', 'refresh',\r\n                        '--dml', parseJson,\r\n                    ]);\r\n                    if (queries.status != 200) {\r\n                        returnFormattedError(queries.status, queries.message);\r\n                        break;\r\n                    }\r\n                    const dbType = queries.data.database_type ?? this.engine.getConfig?.()?.type;\r\n                    delete queries.data.database_type;\r\n\r\n                    // Refresh no-destructivo: si la tabla ya tiene esquema registrado,\r\n                    // reemplazar el CREATE por las diferencias (ALTERs); si es nueva,\r\n                    // generateAlterQueries devuelve el CREATE tal cual.\r\n                    const generatedCreate = (queries.data.regular_queries ?? []).filter((q: string) => q.includes('CREATE'))[0];\r\n                    if (generatedCreate) {\r\n                        const diffQueries = await TableProcessor.generateAlterQueries(\r\n                            generatedCreate,\r\n                            dbType,\r\n                            dml.data.table,\r\n                            dml.data.database,\r\n                        );\r\n                        const nonCreate = (queries.data.regular_queries ?? []).filter((q: string) => !q.includes('CREATE'));\r\n                        queries.data.regular_queries = [...diffQueries, ...nonCreate];\r\n                    }\r\n\r\n                    const parseJsonQueries = JSON.stringify(queries.data);\r\n\r\n                    const response = await this.engine.run('schema_engine', [\r\n                        '--action', 'execute',\r\n                        '--mode', 'refresh',\r\n                        '--dml', parseJsonQueries,\r\n                    ]);\r\n\r\n                    if (response.status != 200) {\r\n                        returnFormattedError(response.status, response.message);\r\n                        break;\r\n                    }\r\n                    // Lo que se registra es el ESTADO DESEADO completo (el CREATE\r\n                    // que genero el engine), no lo que se acabo de ejecutar. En\r\n                    // refresh, regular_queries ya fue sustituido por los ALTERs del\r\n                    // diff, asi que filtrar \"CREATE\" aqui daba undefined en cuanto\r\n                    // la tabla ya existia: saveQuery borraba la fila y el INSERT\r\n                    // con struct NULL fallaba en silencio, dejando el registro vacio\r\n                    // y condenando al siguiente refresh a regenerar el CREATE entero.\r\n                    await TableProcessor.saveQuery(dml.data.table, dml.data.database, generatedCreate);\r\n\r\n                    UIUtils.showItemSuccess(tableName);\r\n                    successCount++;\r\n                    processedTables.push(tableName);\r\n                    totalTablesProcessed++;\r\n\r\n                } catch (error: any) {\r\n                    const processError: ProcessError = {\r\n                        itemName: tableName,\r\n                        error: error.message,\r\n                        filePath\r\n                    };\r\n                    UIUtils.showItemError(tableName, error.message);\r\n                    errors.push(processError);\r\n                    failedTables.add(tableName);\r\n                    errorCount++;\r\n                }\r\n            }\r\n        }\r\n\r\n        // Show final summary\r\n        const summary: ProcessSummary = {\r\n            startTime,\r\n            totalProcessed: totalTablesProcessed,\r\n            successCount,\r\n            errorCount,\r\n            processedItems: processedTables,\r\n            operationName: 'refresh tables',\r\n            databaseName: this.name,\r\n            errors\r\n        };\r\n        UIUtils.showOperationSummary(summary);\r\n\r\n        return totalTablesProcessed > 0 ? { processed: totalTablesProcessed, success: successCount, errors: errorCount } : null;\r\n    }\r\n\r\n    async freshTables(): Promise<any> {\r\n        const startTime = Date.now();\r\n        const cubesDir = path.join(process.cwd(), 'dbcube');\r\n\r\n        // Verificar si la carpeta existe\r\n        if (!fs.existsSync(cubesDir)) {\r\n            throw new Error('❌ The cubes folder does not exist');\r\n        }\r\n\r\n        const cubeFiles = FileUtils.getCubeFilesRecursively('dbcube', '.table.cube');\r\n        if (cubeFiles.length === 0) {\r\n            throw new Error('❌ There are no cubes to execute');\r\n        }\r\n\r\n        // Resolve dependencies and create execution order\r\n        DependencyResolver.resolveDependencies(cubeFiles, 'table');\r\n\r\n        // Order files based on dependencies\r\n        const orderedCubeFiles = DependencyResolver.orderCubeFiles(cubeFiles, 'table');\r\n\r\n        // Show header\r\n        UIUtils.showOperationHeader('EXECUTING FRESH TABLES', this.name);\r\n\r\n        let totalTablesProcessed = 0;\r\n        let successCount = 0;\r\n        let errorCount = 0;\r\n        const processedTables: string[] = [];\r\n        const errors: ProcessError[] = [];\r\n        const failedTables = new Set<string>(); // Track failed table names\r\n\r\n        for (let index = 0; index < orderedCubeFiles.length; index++) {\r\n            const file = orderedCubeFiles[index];\r\n            const filePath = path.isAbsolute(file) ? file : path.join(cubesDir, file);\r\n            const stats = fs.statSync(filePath);\r\n\r\n            if (stats.isFile()) {\r\n                const getTableName = FileUtils.extracTableNameFromCube(filePath);\r\n                const tableName = getTableName.status === 200 ? getTableName.message : path.basename(file, '.table.cube');\r\n\r\n                // Show visual progress for each table\r\n                await UIUtils.showItemProgress(tableName, index + 1, orderedCubeFiles.length);\r\n\r\n                try {\r\n                    // Validate database configuration before processing\r\n                    const validation = this.validateDatabaseConfiguration(filePath);\r\n                    if (!validation.isValid && validation.error) {\r\n                        UIUtils.showItemError(tableName, validation.error.error);\r\n                        errors.push(validation.error);\r\n                        failedTables.add(tableName);\r\n                        errorCount++;\r\n                        continue;\r\n                    }\r\n\r\n                    // Check if any dependent tables failed\r\n                    const dependencies = this.extractForeignKeyDependencies(filePath);\r\n                    const missingDependencies = dependencies.filter(dep => failedTables.has(dep));\r\n\r\n                    if (missingDependencies.length > 0) {\r\n                        const dependencyError: ProcessError = {\r\n                            itemName: tableName,\r\n                            error: `Cannot create table '${tableName}' because it depends on failed table(s): ${missingDependencies.join(', ')}`,\r\n                            filePath,\r\n                            lineNumber: this.findForeignKeyLineNumber(filePath, missingDependencies[0])\r\n                        };\r\n                        UIUtils.showItemError(tableName, dependencyError.error);\r\n                        errors.push(dependencyError);\r\n                        failedTables.add(tableName);\r\n                        errorCount++;\r\n                        continue;\r\n                    }\r\n\r\n                    const dbResult = FileUtils.extractDatabaseNameFromCube(filePath);\r\n                    const cubeDbName = dbResult.status === 200 ? dbResult.message : this.name;\r\n                    if (cubeDbName !== this.name) { continue; }\r\n\r\n                    const dml = await this.engine.run('schema_engine', [\r\n                        '--action', 'parse_table',\r\n                        '--schema-path', filePath,\r\n                        '--mode', 'fresh',\r\n                    ]);\r\n\r\n                    if (dml.status != 200) {\r\n                        returnFormattedError(dml.status, dml.message);\r\n                        break;\r\n                    }\r\n\r\n                    const parseJson = JSON.stringify(dml.data.actions).replace(/[\\r\\n\\t]/g, '').replace(/\\\\[rnt]/g, '').replace(/\\s{2,}/g, ' ');\r\n\r\n                    const queries = await this.engine.run('schema_engine', [\r\n                        '--action', 'generate',\r\n                        '--dml', parseJson,\r\n                    ]);\r\n\r\n                    if (queries.status != 200) {\r\n                        returnFormattedError(queries.status, queries.message);\r\n                        break;\r\n                    }\r\n\r\n                    delete queries.data._type;\r\n                    const createQuery = queries.data.regular_queries.filter((q: string) => q.includes(\"CREATE\"))[0];\r\n\r\n                    // For fresh mode, use the generated queries directly without alterations\r\n                    // generateAlterQueries is used for refresh mode, not fresh mode\r\n\r\n                    const parseJsonQueries = JSON.stringify(queries.data);\r\n\r\n                    const response = await this.engine.run('schema_engine', [\r\n                        '--action', 'execute',\r\n                        '--mode', 'fresh',\r\n                        '--dml', parseJsonQueries,\r\n                    ]);\r\n\r\n                    if (response.status != 200) {\r\n                        returnFormattedError(response.status, response.message);\r\n                        break;\r\n                    }\r\n\r\n                    await TableProcessor.saveQuery(dml.data.table, dml.data.database, createQuery);\r\n\r\n                    UIUtils.showItemSuccess(tableName);\r\n                    successCount++;\r\n                    processedTables.push(tableName);\r\n                    totalTablesProcessed++;\r\n\r\n                } catch (error: any) {\r\n                    const processError: ProcessError = {\r\n                        itemName: tableName,\r\n                        error: error.message,\r\n                        filePath\r\n                    };\r\n                    UIUtils.showItemError(tableName, error.message);\r\n                    errors.push(processError);\r\n                    failedTables.add(tableName);\r\n                    errorCount++;\r\n                }\r\n            }\r\n        }\r\n\r\n        // Show final summary\r\n        const summary: ProcessSummary = {\r\n            startTime,\r\n            totalProcessed: totalTablesProcessed,\r\n            successCount,\r\n            errorCount,\r\n            processedItems: processedTables,\r\n            operationName: 'fresh tables',\r\n            databaseName: this.name,\r\n            errors\r\n        };\r\n        UIUtils.showOperationSummary(summary);\r\n\r\n        return totalTablesProcessed > 0 ? { processed: totalTablesProcessed, success: successCount, errors: errorCount } : null;\r\n    }\r\n\r\n\r\n    async executeSeeders(filterName?: string): Promise<any> {\r\n        const startTime = Date.now();\r\n        const cubesDir = path.join(process.cwd(), 'dbcube');\r\n\r\n        // Verificar si la carpeta existe\r\n        if (!fs.existsSync(cubesDir)) {\r\n            throw new Error('❌ The cubes folder does not exist');\r\n        }\r\n\r\n        let cubeFiles = FileUtils.getCubeFilesRecursively('dbcube', '.seeder.cube');\r\n\r\n        if (cubeFiles.length === 0) {\r\n            throw new Error('❌ There are no cubes to execute');\r\n        }\r\n\r\n        if (filterName) {\r\n            const normalized = filterName.replace(/\\.seeder\\.cube$/, '').replace(/\\.seeder$/, '');\r\n            cubeFiles = cubeFiles.filter(file => path.basename(file, '.seeder.cube') === normalized);\r\n            if (cubeFiles.length === 0) {\r\n                throw new Error(`❌ Seeder '${filterName}' not found. Make sure the file '${normalized}.seeder.cube' exists in the dbcube folder.`);\r\n            }\r\n        }\r\n\r\n        // Use existing table dependency order for seeders\r\n        const orderedCubeFiles = DependencyResolver.orderCubeFiles(cubeFiles, 'seeder');\r\n\r\n        // Show header\r\n        UIUtils.showOperationHeader('EXECUTING SEEDERS', this.name, '🌱');\r\n\r\n        let totalSeedersProcessed = 0;\r\n        let successCount = 0;\r\n        let errorCount = 0;\r\n        const processedSeeders: string[] = [];\r\n        const errors: ProcessError[] = [];\r\n\r\n        for (let index = 0; index < orderedCubeFiles.length; index++) {\r\n            const file = orderedCubeFiles[index];\r\n            const filePath = path.isAbsolute(file) ? file : path.join(cubesDir, file);\r\n            const stats = fs.statSync(filePath);\r\n\r\n            if (stats.isFile()) {\r\n                const getSeederName = FileUtils.extracTableNameFromCube(filePath);\r\n                const seederName = getSeederName.status === 200 ? getSeederName.message : path.basename(file, '.seeder.cube');\r\n\r\n                // Show visual progress for each seeder\r\n                await UIUtils.showItemProgress(seederName, index + 1, orderedCubeFiles.length);\r\n\r\n                try {\r\n                    // Validate database configuration before processing\r\n                    const validation = this.validateDatabaseConfiguration(filePath);\r\n                    if (!validation.isValid && validation.error) {\r\n                        UIUtils.showItemError(seederName, validation.error.error);\r\n                        errors.push(validation.error);\r\n                        errorCount++;\r\n                        continue;\r\n                    }\r\n\r\n                    const dbResult = FileUtils.extractDatabaseNameFromCube(filePath);\r\n                    const cubeDbName = dbResult.status === 200 ? dbResult.message : this.name;\r\n                    if (cubeDbName !== this.name) { continue; }\r\n\r\n                    const response = await this.engine.run('schema_engine', [\r\n                        '--action', 'seeder',\r\n                        '--schema-path', filePath,\r\n                    ]);\r\n\r\n                    if (response.status != 200) {\r\n                        returnFormattedError(response.status, response.message);\r\n                        break;\r\n                    }\r\n\r\n                    UIUtils.showItemSuccess(seederName);\r\n                    successCount++;\r\n                    processedSeeders.push(seederName);\r\n                    totalSeedersProcessed++;\r\n\r\n                } catch (error: any) {\r\n                    const processError: ProcessError = {\r\n                        itemName: seederName,\r\n                        error: error.message,\r\n                        filePath\r\n                    };\r\n                    UIUtils.showItemError(seederName, error.message);\r\n                    errors.push(processError);\r\n                    errorCount++;\r\n                }\r\n            }\r\n        }\r\n\r\n        // Show final summary\r\n        const summary: ProcessSummary = {\r\n            startTime,\r\n            totalProcessed: totalSeedersProcessed,\r\n            successCount,\r\n            errorCount,\r\n            processedItems: processedSeeders,\r\n            operationName: 'seeders',\r\n            databaseName: this.name,\r\n            errors\r\n        };\r\n        UIUtils.showOperationSummary(summary);\r\n\r\n        return totalSeedersProcessed > 0 ? { processed: totalSeedersProcessed, success: successCount, errors: errorCount } : null;\r\n    }\r\n\r\n    async executeAlters(filterFiles?: string[] | null, options: { dryRun?: boolean } = {}): Promise<any> {\r\n        const startTime = Date.now();\r\n        const cubesDir = path.join(process.cwd(), 'dbcube');\r\n        const dryRun = options.dryRun === true;\r\n\r\n        if (!fs.existsSync(cubesDir)) {\r\n            throw new Error('❌ The cubes folder does not exist');\r\n        }\r\n\r\n        let cubeFiles = FileUtils.getCubeFilesRecursively('dbcube', '.alter.cube');\r\n\r\n        if (filterFiles && filterFiles.length > 0) {\r\n            const wanted = new Set(filterFiles.map(f => path.basename(f)));\r\n            cubeFiles = cubeFiles.filter((f: string) => wanted.has(path.basename(f)));\r\n        }\r\n\r\n        if (cubeFiles.length === 0) {\r\n            throw new Error('❌ There are no .alter.cube files to execute');\r\n        }\r\n\r\n        // Show header\r\n        UIUtils.showOperationHeader('EXECUTING ALTER TABLES', this.name, '🔧');\r\n\r\n        let totalAltersProcessed = 0;\r\n        let successCount = 0;\r\n        let errorCount = 0;\r\n        const processedAlters: string[] = [];\r\n        const errors: ProcessError[] = [];\r\n\r\n        for (let index = 0; index < cubeFiles.length; index++) {\r\n            const file = cubeFiles[index];\r\n            const filePath = path.isAbsolute(file) ? file : path.join(cubesDir, file);\r\n            const stats = fs.statSync(filePath);\r\n\r\n            if (stats.isFile()) {\r\n                const alterName = path.basename(file, '.alter.cube');\r\n\r\n                // Show visual progress\r\n                await UIUtils.showItemProgress(alterName, index + 1, cubeFiles.length);\r\n\r\n                try {\r\n                    // Validate database configuration before processing\r\n                    const validation = this.validateDatabaseConfiguration(filePath);\r\n                    if (!validation.isValid && validation.error) {\r\n                        UIUtils.showItemError(alterName, validation.error.error);\r\n                        errors.push(validation.error);\r\n                        errorCount++;\r\n                        continue;\r\n                    }\r\n\r\n                    const dbResult = FileUtils.extractDatabaseNameFromCube(filePath);\r\n                    const cubeDbName = dbResult.status === 200 ? dbResult.message : this.name;\r\n                    if (cubeDbName !== this.name) { continue; }\r\n\r\n                    // Parse the .alter.cube file\r\n                    const dml = await this.engine.run('schema_engine', [\r\n                        '--action', 'parse_alter',\r\n                        '--schema-path', filePath,\r\n                    ]);\r\n\r\n                    if (dml.status != 200) {\r\n                        returnFormattedError(dml.status, dml.message);\r\n                        break;\r\n                    }\r\n\r\n                    const parseJson = JSON.stringify(dml.data.actions)\r\n                        .replace(/[\\r\\n\\t]/g, '')\r\n                        .replace(/\\\\[rnt]/g, '')\r\n                        .replace(/\\s{2,}/g, ' ');\r\n\r\n                    // Generate SQL queries from DML\r\n                    const queries = await this.engine.run('schema_engine', [\r\n                        '--action', 'generate',\r\n                        '--mode', 'alter',\r\n                        '--dml', parseJson,\r\n                    ]);\r\n\r\n                    if (queries.status != 200) {\r\n                        returnFormattedError(queries.status, queries.message);\r\n                        break;\r\n                    }\r\n\r\n                    delete queries.data.database_type;\r\n                    const parseJsonQueries = JSON.stringify(queries.data);\r\n\r\n                    if (dryRun) {\r\n                        // Dry run: emite el SQL que SE EJECUTARÍA, sin tocar la base.\r\n                        const allQueries = [\r\n                            ...(queries.data.regular_queries ?? []),\r\n                            ...(queries.data.special_queries ?? []),\r\n                        ];\r\n                        for (const q of allQueries) {\r\n                            UIUtils.showRaw(q);\r\n                        }\r\n                        UIUtils.showItemSuccess(alterName + ' (dry-run)');\r\n                        successCount++;\r\n                        processedAlters.push(alterName);\r\n                        totalAltersProcessed++;\r\n                        continue;\r\n                    }\r\n\r\n                    // Execute the ALTER queries\r\n                    const response = await this.engine.run('schema_engine', [\r\n                        '--action', 'execute',\r\n                        '--mode', 'alter',\r\n                        '--dml', parseJsonQueries,\r\n                    ]);\r\n\r\n                    if (response.status != 200) {\r\n                        returnFormattedError(response.status, response.message);\r\n                        break;\r\n                    }\r\n\r\n                    UIUtils.showItemSuccess(alterName);\r\n                    successCount++;\r\n                    processedAlters.push(alterName);\r\n                    totalAltersProcessed++;\r\n\r\n                } catch (error: any) {\r\n                    const processError: ProcessError = {\r\n                        itemName: alterName,\r\n                        error: error.message,\r\n                        filePath\r\n                    };\r\n                    UIUtils.showItemError(alterName, error.message);\r\n                    errors.push(processError);\r\n                    errorCount++;\r\n                }\r\n            }\r\n        }\r\n\r\n        // Show final summary\r\n        const summary: ProcessSummary = {\r\n            startTime,\r\n            totalProcessed: totalAltersProcessed,\r\n            successCount,\r\n            errorCount,\r\n            processedItems: processedAlters,\r\n            operationName: 'alter tables',\r\n            databaseName: this.name,\r\n            errors\r\n        };\r\n        UIUtils.showOperationSummary(summary);\r\n\r\n        return totalAltersProcessed > 0 ? { processed: totalAltersProcessed, success: successCount, errors: errorCount } : null;\r\n    }\r\n\r\n    async executeTriggers(): Promise<any> {\r\n        const startTime = Date.now();\r\n        const cubesDir = path.join(process.cwd(), 'dbcube');\r\n        const triggersDirExit = path.join(process.cwd(), 'dbcube', 'triggers');\r\n\r\n        // Verificar si la carpeta existe\r\n        if (!fs.existsSync(cubesDir)) {\r\n            throw new Error('❌ The cubes folder does not exist');\r\n        }\r\n\r\n        const cubeFiles = FileUtils.getCubeFilesRecursively('dbcube', '.trigger.cube');\r\n\r\n        if (cubeFiles.length === 0) {\r\n            throw new Error('❌ There are no cubes to execute');\r\n        }\r\n\r\n        // Show header\r\n        UIUtils.showOperationHeader('EXECUTING TRIGGERS', this.name, '⚡');\r\n\r\n        let totalTriggersProcessed = 0;\r\n        let successCount = 0;\r\n        let errorCount = 0;\r\n        const processedTriggers: string[] = [];\r\n        const errors: ProcessError[] = [];\r\n\r\n        for (let index = 0; index < cubeFiles.length; index++) {\r\n            const file = cubeFiles[index];\r\n            const filePath = path.isAbsolute(file) ? file : path.join(cubesDir, file);\r\n            const stats = fs.statSync(filePath);\r\n\r\n            if (stats.isFile()) {\r\n                const getTriggerName = FileUtils.extracTableNameFromCube(filePath);\r\n                const triggerName = getTriggerName.status === 200 ? getTriggerName.message : path.basename(file, '.trigger.cube');\r\n\r\n                // Show visual progress for each trigger\r\n                await UIUtils.showItemProgress(triggerName, index + 1, cubeFiles.length);\r\n\r\n                try {\r\n                    // Validate database configuration before processing\r\n                    const validation = this.validateDatabaseConfiguration(filePath);\r\n                    if (!validation.isValid && validation.error) {\r\n                        UIUtils.showItemError(triggerName, validation.error.error);\r\n                        errors.push(validation.error);\r\n                        errorCount++;\r\n                        continue;\r\n                    }\r\n\r\n                    const dbResult = FileUtils.extractDatabaseNameFromCube(filePath);\r\n                    const cubeDbName = dbResult.status === 200 ? dbResult.message : this.name;\r\n                    if (cubeDbName !== this.name) { continue; }\r\n\r\n                    const response = await this.engine.run('schema_engine', [\r\n                        '--action', 'trigger',\r\n                        '--path-exit', triggersDirExit,\r\n                        '--schema-path', filePath,\r\n                    ]);\r\n\r\n                    if (response.status != 200) {\r\n                        returnFormattedError(response.status, response.message);\r\n                        break;\r\n                    }\r\n\r\n                    UIUtils.showItemSuccess(triggerName);\r\n                    successCount++;\r\n                    processedTriggers.push(triggerName);\r\n                    totalTriggersProcessed++;\r\n\r\n                } catch (error: any) {\r\n                    const processError: ProcessError = {\r\n                        itemName: triggerName,\r\n                        error: error.message,\r\n                        filePath\r\n                    };\r\n                    UIUtils.showItemError(triggerName, error.message);\r\n                    errors.push(processError);\r\n                    errorCount++;\r\n                }\r\n            }\r\n        }\r\n\r\n        // Show final summary\r\n        const summary: ProcessSummary = {\r\n            startTime,\r\n            totalProcessed: totalTriggersProcessed,\r\n            successCount,\r\n            errorCount,\r\n            processedItems: processedTriggers,\r\n            operationName: 'triggers',\r\n            databaseName: this.name,\r\n            errors\r\n        };\r\n        UIUtils.showOperationSummary(summary);\r\n\r\n        return totalTriggersProcessed > 0 ? { processed: totalTriggersProcessed, success: successCount, errors: errorCount } : null;\r\n    }\r\n}\r\n\r\n\r\n/**\r\n * Emite el error por el bus (UIUtils). No imprime: renderizar es trabajo del\r\n * CLI, que es quien tiene el idioma y el estilo.\r\n */\r\nfunction returnFormattedError(status: number, message: string) {\r\n    const err = new Error();\r\n    const stackLines = err.stack?.split('\\n') || [];\r\n\r\n    // Primera línea del stack fuera de node_modules: ubica el origen real.\r\n    const relevantStackLine = stackLines.find(line =>\r\n        line.includes('.js:') && !line.includes('node_modules')\r\n    );\r\n\r\n    let filePath: string | undefined;\r\n    let lineNumber: number | undefined;\r\n\r\n    if (relevantStackLine) {\r\n        const match = relevantStackLine.match(/\\((.*):(\\d+):(\\d+)\\)/) ||\r\n            relevantStackLine.match(/at (.*):(\\d+):(\\d+)/);\r\n\r\n        if (match) {\r\n            filePath = match[1];\r\n            lineNumber = parseInt(match[2], 10);\r\n        }\r\n    }\r\n\r\n    UIUtils.showFatal(message, filePath, lineNumber);\r\n}\r\n\r\nexport default Schema;\r\nexport { Schema };","import * as fs from 'fs';\r\nimport * as path from 'path';\r\n\r\nclass FileUtils {\r\n  /**\r\n   * Verifica si un archivo existe (asincrónico).\r\n   * @param filePath - Ruta del archivo.\r\n   * @returns True si el archivo existe, false si no.\r\n   */\r\n  static async fileExists(filePath: string): Promise<boolean> {\r\n    return new Promise((resolve) => {\r\n      fs.access(path.resolve(filePath), fs.constants.F_OK, (err) => {\r\n        resolve(!err);\r\n      });\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Verifica si un archivo existe (sincrónico).\r\n   * @param filePath - Ruta del archivo.\r\n   * @returns True si el archivo existe, false si no.\r\n   */\r\n  static fileExistsSync(filePath: string): boolean {\r\n    try {\r\n      fs.accessSync(path.resolve(filePath), fs.constants.F_OK);\r\n      return true;\r\n    } catch {\r\n      return false;\r\n    }\r\n  }\r\n\r\n  static extractDatabaseName(input: string): string | null {\r\n    const match = input.match(/@database\\([\"']?([\\w-]+)[\"']?\\)/);\r\n    return match ? match[1] : null;\r\n  }\r\n\r\n  /**\r\n   * Lee recursivamente archivos que terminan en un sufijo dado y los ordena numéricamente.\r\n   * @param dir - Directorio base (relativo o absoluto).\r\n   * @param suffix - Sufijo de archivo (como 'table.cube').\r\n   * @returns Rutas absolutas de los archivos encontrados y ordenados.\r\n   */\r\n  static getCubeFilesRecursively(dir: string, suffix: string): string[] {\r\n    const baseDir = path.resolve(dir); // ✅ Asegura que sea absoluto\r\n    const cubeFiles: string[] = [];\r\n\r\n    function recurse(currentDir: string): void {\r\n      const entries = fs.readdirSync(currentDir, { withFileTypes: true });\r\n\r\n      for (const entry of entries) {\r\n        const fullPath = path.join(currentDir, entry.name);\r\n\r\n        if (entry.isDirectory()) {\r\n          recurse(fullPath);\r\n        } else if (entry.isFile() && entry.name.endsWith(suffix)) {\r\n          cubeFiles.push(fullPath); // Ya es absoluta\r\n        }\r\n      }\r\n    }\r\n\r\n    recurse(baseDir);\r\n\r\n    // Ordenar por número si los archivos comienzan con un número\r\n    cubeFiles.sort((a, b) => {\r\n      const aNum = parseInt(path.basename(a));\r\n      const bNum = parseInt(path.basename(b));\r\n      return (isNaN(aNum) ? 0 : aNum) - (isNaN(bNum) ? 0 : bNum);\r\n    });\r\n\r\n    return cubeFiles;\r\n  }\r\n\r\n  /**\r\n   * Extracts database name from cube files\r\n   * @param filePath - Path to the .cube file\r\n   * @returns Object containing status and database name\r\n   */\r\n  static extractDatabaseNameFromCube(filePath: string) {\r\n    try {\r\n      const content = fs.readFileSync(filePath, 'utf8');\r\n      \r\n      // Pattern: @database(\"database_name\") or @database('database_name')\r\n      const databaseMatch = content.match(/@database\\s*\\(\\s*[\"']([^\"']+)[\"']\\s*\\)\\s*;?/);\r\n      if (databaseMatch) {\r\n        return {\r\n          status: 200,\r\n          message: databaseMatch[1]\r\n        };\r\n      }\r\n      \r\n      throw new Error(`No @database directive found in file ${filePath}`);\r\n      \r\n    } catch (error: unknown) {\r\n      if (error instanceof Error) {\r\n        return {\r\n          status: 500,\r\n          message: error.message\r\n        };\r\n      }\r\n      return {\r\n        status: 500,\r\n        message: String(error)\r\n      };\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Extrae nombres de tablas reales de archivos .cube\r\n   * @param {string} filePath - String ruta del archivo .cube\r\n   * @returns {object} - Objeto que contiene el estado y el mensaje con el nombre de la tabla\r\n  */\r\n  static extracTableNameFromCube(filePath: string) {\r\n    try {\r\n      const content = fs.readFileSync(filePath, 'utf8');\r\n\r\n      // Patrón principal: @meta({ name: \"nombre_tabla\"; }) o @meta({ name: 'nombre_tabla'; })\r\n      const metaMatch = content.match(/@meta\\s*\\(\\s*\\{\\s*name\\s*:\\s*[\"']([^\"']+)[\"']\\s*;\\s*[^}]*\\}\\s*\\)/s);\r\n      if (metaMatch) {\r\n        return {\r\n          status: 200,\r\n          message: metaMatch[1]\r\n        };\r\n      }\r\n\r\n      throw new Error(`Error to execute this file ${filePath} because no exist a name of table.`);\r\n\r\n    } catch (error: unknown) {\r\n      if (error instanceof Error) {\r\n        return {\r\n          status: 500,\r\n          message: error.message\r\n        };\r\n      }\r\n      return {\r\n        status: 500,\r\n        message: String(error)\r\n      };\r\n    }\r\n  }\r\n}\r\n\r\nexport default FileUtils;","import fs from 'fs';\n\nexport interface ProcessError {\n    itemName: string;\n    error: string;\n    filePath?: string;\n    lineNumber?: number;\n}\n\nexport interface ProcessSummary {\n    startTime: number;\n    totalProcessed: number;\n    successCount: number;\n    errorCount: number;\n    processedItems: string[];\n    operationName: string;\n    databaseName: string;\n    errors: ProcessError[];\n}\n\n/**\n * Reporter que recibe los eventos de una operación de schema.\n * Todos los métodos son opcionales: quien renderiza decide qué le interesa.\n */\nexport interface SchemaReporter {\n    operationStart?(op: { operation: string; database: string }): void;\n    itemStart?(item: { name: string; index: number; total: number }): void;\n    itemSuccess?(item: { name: string }): void;\n    itemError?(item: { name: string; error: string }): void;\n    operationEnd?(summary: ProcessSummary): void;\n    /** Error fatal fuera del ciclo de items (p. ej. fallo al crear la base). */\n    fatal?(err: { message: string; filePath?: string; lineNumber?: number }): void;\n    /** Salida cruda opcional (dry-run: sentencias SQL). */\n    raw?(line: string): void;\n}\n\n/**\n * UIUtils ya NO imprime: es un bus de eventos.\n *\n * Una librería no debe escribir en la consola del programa que la usa, y tener\n * dos renderers (este + el del CLI) era la causa de las salidas duplicadas y\n * las letras sobrepuestas. Ahora el CLI instala su renderer con\n * `UIUtils.setReporter(...)` y es el ÚNICO que dibuja. Sin reporter, silencio.\n *\n * Además, `showItemProgress` ya no anima puntos con un setInterval que se\n * esperaba ANTES de hacer el trabajo real (por eso \"la UI cargaba y luego\n * recién se ejecutaba\"): ahora sólo notifica el inicio del item y retorna.\n */\nexport class UIUtils {\n    private static reporter: SchemaReporter | null = null;\n\n    /** Instala el renderer (el CLI). Pasar null vuelve al modo silencioso. */\n    static setReporter(reporter: SchemaReporter | null): void {\n        UIUtils.reporter = reporter;\n    }\n\n    static getReporter(): SchemaReporter | null {\n        return UIUtils.reporter;\n    }\n\n    /** Notifica que empieza a procesarse un item. No bloquea ni anima. */\n    static async showItemProgress(itemName: string, current: number, total: number): Promise<void> {\n        UIUtils.reporter?.itemStart?.({ name: itemName, index: current, total });\n    }\n\n    static showItemSuccess(itemName: string): void {\n        UIUtils.reporter?.itemSuccess?.({ name: itemName });\n    }\n\n    static showItemError(itemName: string, error: string): void {\n        UIUtils.reporter?.itemError?.({ name: itemName, error });\n    }\n\n    /** `icon` se mantiene por compatibilidad de firma; ya no se usa. */\n    static showOperationHeader(operationName: string, databaseName: string, _icon?: string): void {\n        UIUtils.reporter?.operationStart?.({\n            operation: operationName.trim(),\n            database: databaseName,\n        });\n    }\n\n    static showOperationSummary(summary: ProcessSummary): void {\n        UIUtils.reporter?.operationEnd?.(summary);\n    }\n\n    /** Error fatal (fuera del ciclo de items). */\n    static showFatal(message: string, filePath?: string, lineNumber?: number): void {\n        UIUtils.reporter?.fatal?.({ message, filePath, lineNumber });\n    }\n\n    /** Línea cruda (dry-run). */\n    static showRaw(line: string): void {\n        UIUtils.reporter?.raw?.(line);\n    }\n\n    /**\n     * Lee el contexto de código alrededor de una línea. Devuelve las líneas en\n     * vez de imprimirlas: quien renderiza decide cómo mostrarlas.\n     */\n    static readCodeContext(\n        filePath: string,\n        lineNumber: number,\n        contextLines: number = 2\n    ): Array<{ line: number; text: string; isError: boolean }> {\n        try {\n            const lines = fs.readFileSync(filePath, 'utf8').split('\\n');\n            const start = Math.max(0, lineNumber - contextLines - 1);\n            const end = Math.min(lines.length, lineNumber + contextLines);\n\n            const out: Array<{ line: number; text: string; isError: boolean }> = [];\n            for (let i = start; i < end; i++) {\n                out.push({ line: i + 1, text: lines[i], isError: i + 1 === lineNumber });\n            }\n            return out;\n        } catch {\n            return [];\n        }\n    }\n}\n","import fs from 'fs';\r\nimport path from 'path';\r\nimport { ProcessError } from './UIUtils';\r\n\r\nexport interface ValidationResult {\r\n    isValid: boolean;\r\n    errors: ProcessError[];\r\n}\r\n\r\nexport class CubeValidator {\r\n    private validTypes = ['varchar', 'int', 'tinyint', 'bigint', 'string', 'text', 'boolean', 'date', 'datetime', 'timestamp', 'decimal', 'float', 'double', 'enum', 'json', 'vector', 'blob'];\r\n    private validOptions = ['not null', 'primary', 'autoincrement', 'unique', 'zerofill', 'index', 'required', 'unsigned'];\r\n    private validProperties = ['type', 'length', 'options', 'value', 'defaultValue', 'foreign', 'enumValues', 'description', 'dimension', 'metric', 'index', 'from', 'model', 'sync'];\r\n    private knownAnnotations = ['database', 'table', 'meta', 'columns', 'indexes', 'fields', 'dataset', 'beforeAdd', 'afterAdd', 'beforeUpdate', 'afterUpdate', 'beforeDelete', 'afterDelete', 'compute', 'column', 'changeName', 'addColumn', 'deleteColumn', 'renameColumn', 'changeType', 'changeLength', 'changeDefault', 'changeOptions', 'changeEnumValues'];\r\n\r\n    /**\r\n     * Validates a cube file comprehensively\r\n     */\r\n    validateCubeFile(filePath: string): ValidationResult {\r\n        const errors: ProcessError[] = [];\r\n        \r\n        try {\r\n            const content = fs.readFileSync(filePath, 'utf8');\r\n            const lines = content.split('\\n');\r\n            const fileName = path.basename(filePath, path.extname(filePath));\r\n\r\n            // Validate each line\r\n            for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {\r\n                const line = lines[lineIndex];\r\n                \r\n                // Skip empty lines and comments\r\n                if (line.trim() === '' || line.trim().startsWith('//')) {\r\n                    continue;\r\n                }\r\n\r\n                // Validate annotations\r\n                this.validateAnnotations(line, lineIndex + 1, filePath, fileName, errors);\r\n                \r\n                // Validate data types\r\n                this.validateDataTypes(line, lineIndex + 1, filePath, fileName, errors, content);\r\n                \r\n                // Validate column options\r\n                this.validateColumnOptions(line, lineIndex + 1, filePath, fileName, errors, lines);\r\n                \r\n                // Validate column properties\r\n                this.validateColumnProperties(line, lineIndex + 1, filePath, fileName, errors, content);\r\n                \r\n                // Validate required column properties\r\n                this.validateRequiredColumnProperties(lines, lineIndex + 1, filePath, fileName, errors);\r\n                \r\n                // Validate general syntax\r\n                this.validateGeneralSyntax(line, lineIndex + 1, filePath, fileName, errors);\r\n            }\r\n\r\n            // Validate overall structure\r\n            this.validateOverallStructure(content, filePath, fileName, errors);\r\n\r\n        } catch (error: any) {\r\n            errors.push({\r\n                itemName: path.basename(filePath, path.extname(filePath)),\r\n                error: `Failed to read cube file: ${error.message}`,\r\n                filePath,\r\n                lineNumber: 1\r\n            });\r\n        }\r\n\r\n        return {\r\n            isValid: errors.length === 0,\r\n            errors\r\n        };\r\n    }\r\n\r\n    private validateAnnotations(line: string, lineNumber: number, filePath: string, fileName: string, errors: ProcessError[]): void {\r\n        // Remove content inside strings to avoid false positives\r\n        const lineWithoutStrings = line.replace(/\"[^\"]*\"/g, '\"\"').replace(/'[^']*'/g, \"''\");\r\n        \r\n        const annotationRegex = /@(\\w+)/g;\r\n        let match;\r\n        \r\n        while ((match = annotationRegex.exec(lineWithoutStrings)) !== null) {\r\n            const annotation = match[1];\r\n            \r\n            if (!this.knownAnnotations.includes(annotation)) {\r\n                errors.push({\r\n                    itemName: fileName,\r\n                    error: `Unknown annotation '@${annotation}'. Valid annotations: ${this.knownAnnotations.join(', ')}`,\r\n                    filePath,\r\n                    lineNumber\r\n                });\r\n            }\r\n        }\r\n    }\r\n\r\n    private validateDataTypes(line: string, lineNumber: number, filePath: string, fileName: string, errors: ProcessError[], content: string): void {\r\n        const typeRegex = /type:\\s*[\"'](\\w+)[\"']/g;\r\n        let match;\r\n        \r\n        while ((match = typeRegex.exec(line)) !== null) {\r\n            const type = match[1];\r\n            \r\n            if (!this.validTypes.includes(type)) {\r\n                errors.push({\r\n                    itemName: fileName,\r\n                    error: `Invalid data type '${type}'. Valid types: ${this.validTypes.join(', ')}`,\r\n                    filePath,\r\n                    lineNumber\r\n                });\r\n            }\r\n        }\r\n\r\n        // Check for varchar without length\r\n        if (line.includes('type: \"varchar\"')) {\r\n            const lines = content.split('\\n');\r\n            const hasLengthNearby = lines.slice(Math.max(0, lineNumber - 1), Math.min(lineNumber + 4, lines.length))\r\n                .some(nextLine => nextLine.includes('length:'));\r\n            \r\n            if (!hasLengthNearby) {\r\n                errors.push({\r\n                    itemName: fileName,\r\n                    error: 'VARCHAR type requires a length specification',\r\n                    filePath,\r\n                    lineNumber\r\n                });\r\n            }\r\n        }\r\n\r\n        // Vector columns require a dimension (e.g. dimension: 1536).\r\n        if (line.includes('type: \"vector\"')) {\r\n            const lines = content.split('\\n');\r\n            const hasDimensionNearby = lines.slice(Math.max(0, lineNumber - 1), Math.min(lineNumber + 6, lines.length))\r\n                .some(nextLine => nextLine.includes('dimension:'));\r\n\r\n            if (!hasDimensionNearby) {\r\n                errors.push({\r\n                    itemName: fileName,\r\n                    error: 'VECTOR type requires a dimension (e.g. dimension: 1536)',\r\n                    filePath,\r\n                    lineNumber\r\n                });\r\n            }\r\n        }\r\n    }\r\n\r\n    private validateColumnOptions(line: string, lineNumber: number, filePath: string, fileName: string, errors: ProcessError[], lines: string[]): void {\r\n        const optionsMatch = line.match(/^\\s*options\\s*:\\s*\\[(.*)\\]\\s*;?\\s*$/);\r\n        if (!optionsMatch) return;\r\n\r\n        const optionsContent = optionsMatch[1].trim();\r\n        \r\n        // Check for invalid syntax (values without quotes)\r\n        const invalidSyntaxMatch = optionsContent.match(/[^\",\\s]+(?![^\"]*\")/);\r\n        if (invalidSyntaxMatch) {\r\n            errors.push({\r\n                itemName: fileName,\r\n                error: `Invalid syntax '${invalidSyntaxMatch[0]}' in options array. All values must be quoted strings`,\r\n                filePath,\r\n                lineNumber\r\n            });\r\n            return;\r\n        }\r\n\r\n        // Extract individual options\r\n        const optionMatches = optionsContent.match(/\"([^\"]*)\"/g);\r\n        if (optionMatches) {\r\n            // Get column type for compatibility checking\r\n            const columnType = this.getColumnTypeForOptions(lines, lineNumber - 1);\r\n            \r\n            optionMatches.forEach(optionMatch => {\r\n                const option = optionMatch.replace(/\"/g, '');\r\n                \r\n                if (option.trim() === '') {\r\n                    errors.push({\r\n                        itemName: fileName,\r\n                        error: 'Empty option found in options array. All options must have a value',\r\n                        filePath,\r\n                        lineNumber\r\n                    });\r\n                } else if (!this.validOptions.includes(option)) {\r\n                    errors.push({\r\n                        itemName: fileName,\r\n                        error: `Invalid option '${option}'. Valid options: ${this.validOptions.join(', ')}`,\r\n                        filePath,\r\n                        lineNumber\r\n                    });\r\n                } else if (columnType !== 'unknown' && !this.isOptionCompatibleWithType(option, columnType)) {\r\n                    errors.push({\r\n                        itemName: fileName,\r\n                        error: `Option '${option}' is not compatible with type '${columnType}'`,\r\n                        filePath,\r\n                        lineNumber\r\n                    });\r\n                }\r\n            });\r\n        }\r\n    }\r\n\r\n    private validateColumnProperties(line: string, lineNumber: number, filePath: string, fileName: string, errors: ProcessError[], content: string): void {\r\n        const propertyKeyRegex = /^\\s*([a-zA-Z_][a-zA-Z0-9_]*)\\s*:/;\r\n        const propMatch = propertyKeyRegex.exec(line);\r\n\r\n        if (!propMatch) return;\r\n\r\n        const propertyName = propMatch[1];\r\n\r\n        // Skip column/index definitions (they end with opening brace)\r\n        if (/^\\s*[a-zA-Z_][a-zA-Z0-9_]*\\s*:\\s*\\{/.test(line)) {\r\n            return;\r\n        }\r\n\r\n        // Skip if inside @indexes block (properties: columns, unique are valid there)\r\n        if (this.isInsideIndexesBlock(content, lineNumber - 1)) {\r\n            const validIndexProperties = ['columns', 'unique'];\r\n            if (!validIndexProperties.includes(propertyName)) {\r\n                errors.push({\r\n                    itemName: fileName,\r\n                    error: `Invalid index property '${propertyName}'. Valid index properties: ${validIndexProperties.join(', ')}`,\r\n                    filePath,\r\n                    lineNumber\r\n                });\r\n            }\r\n            return;\r\n        }\r\n\r\n        // Check if we're inside a foreign key object\r\n        if (this.isInsideForeignKeyObject(content, lineNumber - 1)) {\r\n            const validForeignKeyProperties = ['table', 'column'];\r\n            if (!validForeignKeyProperties.includes(propertyName)) {\r\n                errors.push({\r\n                    itemName: fileName,\r\n                    error: `Invalid foreign key property '${propertyName}'. Valid foreign key properties: ${validForeignKeyProperties.join(', ')}`,\r\n                    filePath,\r\n                    lineNumber\r\n                });\r\n            }\r\n            return;\r\n        }\r\n\r\n        // Check if we're inside a columns block and validate property\r\n        if (this.isInsideColumnsBlock(content, lineNumber - 1)) {\r\n            if (!this.validProperties.includes(propertyName)) {\r\n                errors.push({\r\n                    itemName: fileName,\r\n                    error: `Invalid property '${propertyName}'. Valid properties: ${this.validProperties.join(', ')}`,\r\n                    filePath,\r\n                    lineNumber\r\n                });\r\n            }\r\n        }\r\n\r\n        // Check for incomplete property declarations\r\n        if (/^\\s*([a-zA-Z_][a-zA-Z0-9_]*)\\s*:\\s*$/.test(line)) {\r\n            errors.push({\r\n                itemName: fileName,\r\n                error: `Property '${propertyName}' is missing a value`,\r\n                filePath,\r\n                lineNumber\r\n            });\r\n        }\r\n    }\r\n\r\n    private isInsideIndexesBlock(content: string, lineIndex: number): boolean {\r\n        const lines = content.split('\\n');\r\n        let indexesStartLine = -1;\r\n        let indexesEndLine = -1;\r\n\r\n        for (let i = 0; i < lines.length; i++) {\r\n            if (lines[i].includes('@indexes')) {\r\n                indexesStartLine = i;\r\n                let braceCount = 0;\r\n                for (let j = i; j < lines.length; j++) {\r\n                    braceCount += (lines[j].match(/\\{/g) || []).length;\r\n                    braceCount -= (lines[j].match(/\\}/g) || []).length;\r\n                    if (braceCount === 0 && j > i) {\r\n                        indexesEndLine = j;\r\n                        break;\r\n                    }\r\n                }\r\n                break;\r\n            }\r\n        }\r\n\r\n        return indexesStartLine !== -1 && indexesEndLine !== -1 &&\r\n               lineIndex > indexesStartLine && lineIndex < indexesEndLine;\r\n    }\r\n\r\n    private validateRequiredColumnProperties(lines: string[], lineNumber: number, filePath: string, fileName: string, errors: ProcessError[]): void {\r\n        const line = lines[lineNumber - 1];\r\n        \r\n        // Check if current line is the closing of a column definition\r\n        if (!/^\\s*\\}\\s*;?\\s*$/.test(line)) {\r\n            return;\r\n        }\r\n\r\n        // Find the start of this column definition\r\n        let columnStartLine = -1;\r\n        let columnName = '';\r\n        \r\n        for (let i = lineNumber - 2; i >= 0; i--) {\r\n            const currentLine = lines[i];\r\n            const columnDefMatch = currentLine.match(/^\\s*([a-zA-Z_][a-zA-Z0-9_]*)\\s*:\\s*\\{/);\r\n            \r\n            if (columnDefMatch) {\r\n                // Verify this is the matching opening brace\r\n                let openBraces = 0;\r\n                let closeBraces = 0;\r\n                \r\n                for (let j = i; j < lineNumber; j++) {\r\n                    openBraces += (lines[j].match(/\\{/g) || []).length;\r\n                    closeBraces += (lines[j].match(/\\}/g) || []).length;\r\n                }\r\n                \r\n                if (openBraces === closeBraces) {\r\n                    columnStartLine = i;\r\n                    columnName = columnDefMatch[1];\r\n                    break;\r\n                }\r\n            }\r\n        }\r\n\r\n        if (columnStartLine === -1 || !columnName) return;\r\n\r\n        // Check for missing 'type' property\r\n        let hasType = false;\r\n        \r\n        for (let i = columnStartLine + 1; i < lineNumber - 1; i++) {\r\n            if (lines[i].match(/^\\s*type\\s*:/)) {\r\n                hasType = true;\r\n                break;\r\n            }\r\n        }\r\n        \r\n        if (!hasType && columnName !== 'foreign' && columnName !== 'defaultValue') {\r\n            errors.push({\r\n                itemName: fileName,\r\n                error: `Column '${columnName}' is missing required 'type' property`,\r\n                filePath,\r\n                lineNumber: columnStartLine + 1\r\n            });\r\n        }\r\n    }\r\n\r\n    private validateGeneralSyntax(line: string, lineNumber: number, filePath: string, fileName: string, errors: ProcessError[]): void {\r\n        // Check for mismatched quotes\r\n        const quotes = line.match(/[\"']/g);\r\n        if (quotes && quotes.length % 2 !== 0) {\r\n            errors.push({\r\n                itemName: fileName,\r\n                error: 'Mismatched quotes detected',\r\n                filePath,\r\n                lineNumber\r\n            });\r\n        }\r\n\r\n        // Check for invalid annotation syntax\r\n        if (line.includes('@database') || line.includes('@table')) {\r\n            const stringAnnotationRegex = /@(database|table)\\s*\\(\\s*\"([^\"]*)\"\\s*\\)/;\r\n            if (!stringAnnotationRegex.test(line)) {\r\n                errors.push({\r\n                    itemName: fileName,\r\n                    error: 'Invalid annotation syntax. Expected format: @annotation(\"value\")',\r\n                    filePath,\r\n                    lineNumber\r\n                });\r\n            }\r\n        }\r\n\r\n        // Check for @meta annotation syntax\r\n        if (line.includes('@meta')) {\r\n            const metaObjectRegex = /@meta\\s*\\(\\s*\\{/;\r\n            if (!metaObjectRegex.test(line)) {\r\n                errors.push({\r\n                    itemName: fileName,\r\n                    error: 'Invalid @meta syntax. Expected format: @meta({ ... })',\r\n                    filePath,\r\n                    lineNumber\r\n                });\r\n            }\r\n        }\r\n    }\r\n\r\n    private validateOverallStructure(content: string, filePath: string, fileName: string, errors: ProcessError[]): void {\r\n        const lines = content.split('\\n');\r\n        \r\n        // Check for required @database annotation\r\n        const hasDatabase = lines.some(line => line.includes('@database'));\r\n        if (!hasDatabase) {\r\n            errors.push({\r\n                itemName: fileName,\r\n                error: 'Missing required @database annotation',\r\n                filePath,\r\n                lineNumber: 1\r\n            });\r\n        }\r\n\r\n        // For table.cube files, check for @columns\r\n        if (filePath.includes('.table.cube')) {\r\n            const hasColumns = lines.some(line => line.includes('@columns'));\r\n            if (!hasColumns) {\r\n                errors.push({\r\n                    itemName: fileName,\r\n                    error: 'Table cube files require @columns annotation',\r\n                    filePath,\r\n                    lineNumber: 1\r\n                });\r\n            }\r\n        }\r\n\r\n        // For alter.cube files, check for @table annotation\r\n        if (filePath.includes('.alter.cube')) {\r\n            const hasTable = lines.some(line => line.includes('@table'));\r\n            if (!hasTable) {\r\n                errors.push({\r\n                    itemName: fileName,\r\n                    error: 'Alter cube files require @table annotation specifying the target table',\r\n                    filePath,\r\n                    lineNumber: 1\r\n                });\r\n            }\r\n            const hasAlterDirective = lines.some(line =>\r\n                line.includes('@changeName') ||\r\n                line.includes('@addColumn') ||\r\n                line.includes('@deleteColumn') ||\r\n                line.includes('@renameColumn') ||\r\n                line.includes('@changeType') ||\r\n                line.includes('@changeLength') ||\r\n                line.includes('@changeDefault') ||\r\n                line.includes('@changeOptions') ||\r\n                line.includes('@changeEnumValues')\r\n            );\r\n            if (!hasAlterDirective) {\r\n                errors.push({\r\n                    itemName: fileName,\r\n                    error: 'Alter cube files must contain at least one alter directive (@changeName, @addColumn, @deleteColumn, @renameColumn, @changeType, @changeLength, @changeDefault, @changeOptions, or @changeEnumValues)',\r\n                    filePath,\r\n                    lineNumber: 1\r\n                });\r\n            }\r\n        }\r\n    }\r\n\r\n    private getColumnTypeForOptions(lines: string[], optionsLineIndex: number): string {\r\n        // Look backwards from options line to find the type\r\n        for (let i = optionsLineIndex - 1; i >= 0; i--) {\r\n            const line = lines[i];\r\n            const typeMatch = line.match(/^\\s*type\\s*:\\s*\"([^\"]+)\"/);\r\n            if (typeMatch) {\r\n                return typeMatch[1];\r\n            }\r\n            // Stop if we hit another column definition\r\n            if (/^\\s*[a-zA-Z_][a-zA-Z0-9_]*\\s*:\\s*\\{/.test(line)) {\r\n                break;\r\n            }\r\n        }\r\n        return 'unknown';\r\n    }\r\n\r\n    private isOptionCompatibleWithType(option: string, type: string): boolean {\r\n        const compatibilityRules: { [key: string]: string[] } = {\r\n            \"zerofill\": [\"int\", \"decimal\", \"float\", \"double\"],\r\n            \"unsigned\": [\"int\", \"decimal\", \"float\", \"double\"],\r\n            \"autoincrement\": [\"int\"],\r\n            \"primary\": [\"int\", \"varchar\", \"string\"],\r\n            \"not null\": [\"int\", \"varchar\", \"string\", \"text\", \"boolean\", \"date\", \"datetime\", \"timestamp\", \"decimal\", \"float\", \"double\"],\r\n            \"unique\": [\"int\", \"varchar\", \"string\", \"text\"],\r\n            \"index\": [\"int\", \"varchar\", \"string\", \"text\", \"date\", \"datetime\", \"timestamp\"],\r\n            \"required\": [\"int\", \"varchar\", \"string\", \"text\", \"boolean\", \"date\", \"datetime\", \"timestamp\", \"decimal\", \"float\", \"double\"]\r\n        };\r\n        \r\n        const compatibleTypes = compatibilityRules[option];\r\n        if (!compatibleTypes) {\r\n            return true; // If not in rules, allow it\r\n        }\r\n        \r\n        return compatibleTypes.includes(type);\r\n    }\r\n\r\n    private isInsideColumnsBlock(content: string, lineIndex: number): boolean {\r\n        const lines = content.split('\\n');\r\n        \r\n        // Find @columns block boundaries\r\n        let columnsStartLine = -1;\r\n        let columnsEndLine = -1;\r\n        \r\n        for (let i = 0; i < lines.length; i++) {\r\n            if (lines[i].includes('@columns')) {\r\n                columnsStartLine = i;\r\n                // Find the end of the @columns block\r\n                let braceCount = 0;\r\n                for (let j = i; j < lines.length; j++) {\r\n                    const currentLine = lines[j];\r\n                    braceCount += (currentLine.match(/\\{/g) || []).length;\r\n                    braceCount -= (currentLine.match(/\\}/g) || []).length;\r\n                    if (braceCount === 0 && j > i) {\r\n                        columnsEndLine = j;\r\n                        break;\r\n                    }\r\n                }\r\n                break;\r\n            }\r\n        }\r\n        \r\n        return columnsStartLine !== -1 && columnsEndLine !== -1 && \r\n               lineIndex > columnsStartLine && lineIndex < columnsEndLine;\r\n    }\r\n\r\n    private isInsideForeignKeyObject(content: string, lineIndex: number): boolean {\r\n        const lines = content.split('\\n');\r\n        \r\n        // Look backwards from current line to find if we're inside a foreign object\r\n        for (let i = lineIndex; i >= 0; i--) {\r\n            const line = lines[i];\r\n            \r\n            // If we find a foreign: { on this line or above\r\n            if (/foreign\\s*:\\s*\\{/.test(line)) {\r\n                // Count braces from the foreign line to current line to see if we're inside\r\n                let braceCount = 0;\r\n                \r\n                // Start from the foreign line\r\n                for (let j = i; j <= lineIndex; j++) {\r\n                    const currentLine = lines[j];\r\n                    \r\n                    // Count opening braces\r\n                    const openBraces = (currentLine.match(/\\{/g) || []).length;\r\n                    // Count closing braces\r\n                    const closeBraces = (currentLine.match(/\\}/g) || []).length;\r\n                    \r\n                    braceCount += openBraces - closeBraces;\r\n                    \r\n                    // If we've closed all braces, we're outside the foreign object\r\n                    if (braceCount === 0 && j > i) {\r\n                        return false;\r\n                    }\r\n                }\r\n                \r\n                // If we still have open braces, we're inside the foreign object\r\n                return braceCount > 0;\r\n            }\r\n            \r\n            // If we find a closing brace before finding a foreign declaration,\r\n            // we're not inside a foreign object\r\n            if (line.trim() === '}' || line.includes('};')) {\r\n                break;\r\n            }\r\n        }\r\n        \r\n        return false;\r\n    }\r\n}","import fs from 'fs';\r\nimport path from 'path';\r\nimport FileUtils from './FileUtils';\r\n\r\nexport interface TableDependency {\r\n    tableName: string;\r\n    filePath: string;\r\n    dependencies: string[];\r\n}\r\n\r\nexport interface ExecutionOrder {\r\n    tables: string[];\r\n    seeders: string[];\r\n    timestamp: string;\r\n}\r\n\r\nexport class DependencyResolver {\r\n    \r\n    /**\r\n     * Resolves table dependencies and creates execution order\r\n     */\r\n    static resolveDependencies(cubeFiles: string[], cubeType: 'table' | 'seeder' = 'table'): ExecutionOrder {\r\n        const tableDependencies = this.extractDependencies(cubeFiles, cubeType);\r\n        const orderedTables = this.topologicalSort(tableDependencies);\r\n        \r\n        const executionOrder: ExecutionOrder = {\r\n            tables: cubeType === 'table' ? orderedTables : [],\r\n            seeders: cubeType === 'seeder' ? orderedTables : [],\r\n            timestamp: new Date().toISOString()\r\n        };\r\n\r\n        // Save the execution order file\r\n        this.saveExecutionOrder(executionOrder);\r\n        \r\n        return executionOrder;\r\n    }\r\n\r\n    /**\r\n     * Extracts dependencies from cube files\r\n     */\r\n    private static extractDependencies(cubeFiles: string[], cubeType: 'table' | 'seeder'): TableDependency[] {\r\n        const dependencies: TableDependency[] = [];\r\n\r\n        for (const file of cubeFiles) {\r\n            // Handle absolute paths and relative paths correctly\r\n            let filePath: string;\r\n            if (path.isAbsolute(file)) {\r\n                filePath = file;\r\n            } else if (fs.existsSync(file)) {\r\n                // File exists in current directory\r\n                filePath = path.resolve(file);\r\n            } else {\r\n                // Try the standard dbcube directory (files are now directly in dbcube folder)\r\n                filePath = path.join(process.cwd(), 'dbcube', file);\r\n            }\r\n            \r\n            try {\r\n                // Extract table name\r\n                const tableNameResult = FileUtils.extracTableNameFromCube(filePath);\r\n                const tableName = tableNameResult.status === 200 ? tableNameResult.message : path.basename(file, `.${cubeType}.cube`);\r\n                \r\n                // Extract foreign key dependencies\r\n                const deps = this.extractForeignKeyReferences(filePath);\r\n                \r\n                dependencies.push({\r\n                    tableName,\r\n                    filePath,\r\n                    dependencies: deps\r\n                });\r\n            } catch (error) {\r\n                console.error(`Error processing ${filePath}:`, error);\r\n            }\r\n        }\r\n\r\n        return dependencies;\r\n    }\r\n\r\n    /**\r\n     * Extracts foreign key references from a cube file\r\n     */\r\n    private static extractForeignKeyReferences(filePath: string): string[] {\r\n        const dependencies: string[] = [];\r\n        \r\n        try {\r\n            const content = fs.readFileSync(filePath, 'utf8');\r\n            const lines = content.split('\\n');\r\n            \r\n            let insideForeignKey = false;\r\n            let braceCount = 0;\r\n            \r\n            for (const line of lines) {\r\n                // Check for foreign key start\r\n                if (/foreign\\s*:\\s*\\{/.test(line)) {\r\n                    insideForeignKey = true;\r\n                    braceCount = 1;\r\n                    \r\n                    // Check if table is on the same line\r\n                    const sameLineMatch = line.match(/table\\s*:\\s*[\"']([^\"']+)[\"']/);\r\n                    if (sameLineMatch) {\r\n                        dependencies.push(sameLineMatch[1]);\r\n                        insideForeignKey = false;\r\n                        braceCount = 0;\r\n                    }\r\n                    continue;\r\n                }\r\n                \r\n                if (insideForeignKey) {\r\n                    // Count braces to track if we're still inside the foreign object\r\n                    braceCount += (line.match(/\\{/g) || []).length;\r\n                    braceCount -= (line.match(/\\}/g) || []).length;\r\n                    \r\n                    // Look for table reference\r\n                    const tableMatch = line.match(/table\\s*:\\s*[\"']([^\"']+)[\"']/);\r\n                    if (tableMatch) {\r\n                        dependencies.push(tableMatch[1]);\r\n                    }\r\n                    \r\n                    // If braces are balanced, we're out of the foreign object\r\n                    if (braceCount === 0) {\r\n                        insideForeignKey = false;\r\n                    }\r\n                }\r\n            }\r\n        } catch (error) {\r\n            console.error(`Error reading file ${filePath}:`, error);\r\n        }\r\n        \r\n        return dependencies;\r\n    }\r\n\r\n    /**\r\n     * Performs topological sort to determine execution order\r\n     */\r\n    private static topologicalSort(dependencies: TableDependency[]): string[] {\r\n        const graph = new Map<string, string[]>();\r\n        const inDegree = new Map<string, number>();\r\n        const tableMap = new Map<string, TableDependency>();\r\n\r\n        // Initialize graph and in-degree for all tables\r\n        for (const dep of dependencies) {\r\n            if (!graph.has(dep.tableName)) {\r\n                graph.set(dep.tableName, []);\r\n            }\r\n            inDegree.set(dep.tableName, 0);\r\n            tableMap.set(dep.tableName, dep);\r\n        }\r\n\r\n        // Build reverse graph: for each table that A depends on, add A as a dependent of that table\r\n        // This allows Kahn's algorithm to work: when we process a table, we can reduce\r\n        // the in-degree of all tables that depend on it\r\n        for (const dep of dependencies) {\r\n            for (const dependency of dep.dependencies) {\r\n                // Una FK a la PROPIA tabla (jerarquias: parent_id -> id) no es una\r\n                // dependencia de ORDEN: la tabla se crea en una sola sentencia y la\r\n                // restriccion se satisface sola. Contarla como arista entrante hacia\r\n                // si misma hacia que su grado nunca llegase a 0, de modo que Kahn no\r\n                // la procesaba NUNCA y caia en la rama de respaldo — arrastrando ahi\r\n                // a todas las tablas que dependian de ella, que acababan creandose\r\n                // ANTES que ella y fallando por FK.\r\n                if (dependency === dep.tableName) continue;\r\n                // If dependency exists in our table list, add edge: dependency -> dep.tableName\r\n                if (inDegree.has(dependency)) {\r\n                    if (!graph.has(dependency)) {\r\n                        graph.set(dependency, []);\r\n                    }\r\n                    graph.get(dependency)!.push(dep.tableName);\r\n                    // Increase in-degree of the table that has the dependency\r\n                    inDegree.set(dep.tableName, (inDegree.get(dep.tableName) || 0) + 1);\r\n                }\r\n            }\r\n        }\r\n        \r\n        // Kahn's algorithm for topological sorting\r\n        const queue: string[] = [];\r\n        const result: string[] = [];\r\n        \r\n        // Find all nodes with no incoming edges\r\n        for (const [table, degree] of inDegree) {\r\n            if (degree === 0) {\r\n                queue.push(table);\r\n            }\r\n        }\r\n        \r\n        while (queue.length > 0) {\r\n            const current = queue.shift()!;\r\n            result.push(current);\r\n            \r\n            const currentDeps = graph.get(current) || [];\r\n            \r\n            // For each neighbor, reduce in-degree\r\n            for (const neighbor of currentDeps) {\r\n                if (inDegree.has(neighbor)) {\r\n                    const newDegree = (inDegree.get(neighbor) || 0) - 1;\r\n                    inDegree.set(neighbor, newDegree);\r\n                    \r\n                    if (newDegree === 0) {\r\n                        queue.push(neighbor);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n        \r\n        // Check for circular dependencies\r\n        if (result.length !== dependencies.length) {\r\n            // Add remaining tables that weren't processed due to circular dependencies\r\n            for (const dep of dependencies) {\r\n                if (!result.includes(dep.tableName)) {\r\n                    result.push(dep.tableName);\r\n                }\r\n            }\r\n        }\r\n        \r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Saves the execution order to .dbcube/orderexecute.json\r\n     */\r\n    private static saveExecutionOrder(order: ExecutionOrder): void {\r\n        try {\r\n            const projectRoot = process.cwd();\r\n            const dbcubeDir = path.join(projectRoot, '.dbcube');\r\n            const orderFile = path.join(dbcubeDir, 'orderexecute.json');\r\n            \r\n            // Create .dbcube directory if it doesn't exist\r\n            if (!fs.existsSync(dbcubeDir)) {\r\n                fs.mkdirSync(dbcubeDir, { recursive: true });\r\n            }\r\n            \r\n            // Save the order file\r\n            fs.writeFileSync(orderFile, JSON.stringify(order, null, 2), 'utf8');\r\n            \r\n            // Execution order saved silently\r\n        } catch (error) {\r\n            console.error('❌ Failed to save execution order:', error);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Loads the execution order from .dbcube/orderexecute.json\r\n     */\r\n    static loadExecutionOrder(): ExecutionOrder | null {\r\n        try {\r\n            const projectRoot = process.cwd();\r\n            const orderFile = path.join(projectRoot, '.dbcube', 'orderexecute.json');\r\n            \r\n            if (!fs.existsSync(orderFile)) {\r\n                return null;\r\n            }\r\n            \r\n            const content = fs.readFileSync(orderFile, 'utf8');\r\n            return JSON.parse(content);\r\n        } catch (error) {\r\n            console.error('❌ Failed to load execution order:', error);\r\n            return null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Orders cube files based on saved execution order\r\n     */\r\n    static orderCubeFiles(cubeFiles: string[], cubeType: 'table' | 'seeder'): string[] {\r\n        const executionOrder = this.loadExecutionOrder();\r\n\r\n        if (!executionOrder) {\r\n            return cubeFiles;\r\n        }\r\n\r\n        // IMPORTANTE: Los seeders SIEMPRE usan el orden de las tablas\r\n        // porque deben insertar datos respetando las foreign keys\r\n        const orderList = executionOrder.tables;\r\n        const orderedFiles: string[] = [];\r\n        const fileMap = new Map<string, string>();\r\n\r\n        // Create a map of table names to file paths\r\n        for (const file of cubeFiles) {\r\n            const filePath = path.isAbsolute(file) ? file : path.join(process.cwd(), 'dbcube', file);\r\n            const tableNameResult = FileUtils.extracTableNameFromCube(filePath);\r\n            const tableName = tableNameResult.status === 200 ? tableNameResult.message : path.basename(file, `.${cubeType}.cube`);\r\n            fileMap.set(tableName, file);\r\n        }\r\n\r\n        // Order files according to execution order (using table order)\r\n        for (const tableName of orderList) {\r\n            if (fileMap.has(tableName)) {\r\n                orderedFiles.push(fileMap.get(tableName)!);\r\n                fileMap.delete(tableName);\r\n            }\r\n        }\r\n\r\n        // Add any remaining files that weren't in the order\r\n        for (const [, file] of fileMap) {\r\n            orderedFiles.push(file);\r\n        }\r\n\r\n        // Using dependency order silently\r\n\r\n        return orderedFiles;\r\n    }\r\n}"],"mappings":"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","names":["import_fs","import_path","resolve","fs","import_fs","fs","path","import_fs","import_path","path","fs","path","ConfigClass","fs","require","import_core"]}