{"version":3,"sources":["../src/index.ts","../src/lib/Database.ts","../src/lib/Trigger.ts"],"sourcesContent":["import { Table, Database } from './lib/Database';\nimport type {\n    ComputedFieldConfig,\n    DatabaseRecord,\n    MutationInfo,\n    PaginatedResult,\n    RelationOptions,\n    TriggerConfig,\n    WhereCallback,\n} from './@types/Database';\n\nexport default Database;\nexport {\n    Table,\n    Database,\n    type ComputedFieldConfig,\n    type DatabaseRecord,\n    type MutationInfo,\n    type PaginatedResult,\n    type RelationOptions,\n    type TriggerConfig,\n    type WhereCallback\n};\n","import fs from 'fs';\r\nimport path from 'path';\r\nimport { randomUUID } from 'crypto';\r\nimport { QueryEngine, ComputedFieldProcessor, TriggerProcessor } from \"@dbcube/core\";\r\nimport { ComputedFieldConfig, DatabaseRecord, DML, MutationInfo, PaginatedResult, RelationOptions, TriggerConfig, WhereCallback, WhereCondition } from \"../@types/Database\";\r\nimport { Trigger } from './Trigger';\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\nexport class Database {\r\n    private name: string;\r\n    private engine: QueryEngine;\r\n    private computedFields: ComputedFieldConfig[];\r\n    private triggers: TriggerConfig[];\r\n    private txId: string | null = null;\r\n\r\n    constructor(name: string) {\r\n        this.name = name;\r\n        const engine = new QueryEngine(name);\r\n        this.engine = engine;\r\n        this.computedFields = [];\r\n        this.triggers = [];\r\n    }\r\n\r\n    /**\r\n     * Executes raw SQL (MySQL/PostgreSQL/SQLite) or a raw command document (MongoDB)\r\n     * with bound parameters. The escape hatch for anything the builder doesn't cover.\r\n     *\r\n     * @example\r\n     * const rows = await db.raw('SELECT * FROM users WHERE age > ?', [25]);\r\n     * await db.raw('CREATE INDEX idx_users_email ON users(email)');\r\n     */\r\n    async raw<R = DatabaseRecord>(query: string, params: unknown[] = []): Promise<R[]> {\r\n        const response = await this.engine.rawQuery(query, params, this.txId ?? undefined);\r\n        if (response.status != 200) {\r\n            returnFormattedError(response.status, response.message);\r\n            throw new Error(response.message);\r\n        }\r\n        return response.data;\r\n    }\r\n\r\n    /**\r\n     * Runs a callback inside a database transaction. Everything executed through\r\n     * the received connection is committed atomically; any thrown error rolls\r\n     * the whole transaction back.\r\n     *\r\n     * Requires daemon mode (enabled by default with an up-to-date query-engine).\r\n     *\r\n     * @example\r\n     * await db.transaction(async (trx) => {\r\n     *     await trx.table('accounts').where('id', '=', 1).update({ balance: 50 });\r\n     *     await trx.table('accounts').where('id', '=', 2).update({ balance: 150 });\r\n     * });\r\n     */\r\n    async transaction<T>(callback: (trx: Database) => Promise<T>): Promise<T> {\r\n        const txId: string = await this.engine.beginTransaction();\r\n\r\n        const trx = new Database(this.name);\r\n        trx.engine = this.engine;\r\n        trx.computedFields = this.computedFields;\r\n        trx.triggers = this.triggers;\r\n        trx.txId = txId;\r\n\r\n        try {\r\n            const result = await callback(trx);\r\n            await this.engine.commitTransaction(txId);\r\n            return result;\r\n        } catch (error) {\r\n            try {\r\n                await this.engine.rollbackTransaction(txId);\r\n            } catch (rollbackError: any) {\r\n                // El error original manda, pero un rollback fallido no puede\r\n                // pasar en silencio: la transacción puede seguir reteniendo\r\n                // locks hasta que el daemon la expire por inactividad.\r\n                console.error(\r\n                    `[dbcube] Rollback of transaction ${txId} failed: ${rollbackError?.message ?? rollbackError}`\r\n                );\r\n            }\r\n            throw error;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Atomic batch: every write queued in the callback runs inside ONE\r\n     * transaction with a SINGLE engine round-trip (begin/commit included).\r\n     * The callback is synchronous — writes are collected, not awaited.\r\n     * Any failure rolls back everything.\r\n     *\r\n     * This is the fastest way to run a sequence of writes atomically.\r\n     * For transactions that need to READ intermediate results, use\r\n     * `transaction()` (interactive) instead. Triggers/computed fields do\r\n     * not run in batch mode.\r\n     *\r\n     * @example\r\n     * await db.batch(b => {\r\n     *     b.table('accounts').where('id', '=', 1).decrement('balance', 200);\r\n     *     b.table('accounts').where('id', '=', 2).increment('balance', 200);\r\n     * });\r\n     */\r\n    async batch(builder: (b: Database) => void): Promise<MutationInfo[][]> {\r\n        const ops: DML[] = [];\r\n        const collector = new Database(this.name);\r\n        collector.engine = this.engine;\r\n        collector.computedFields = this.computedFields;\r\n        collector.triggers = this.triggers;\r\n        (collector as any)._collectInto = ops;\r\n        builder(collector);\r\n        if (ops.length === 0) return [];\r\n\r\n        const response = await this.engine.executeBatch(ops);\r\n        if (response.status !== 200) {\r\n            returnFormattedError(response.status, response.message);\r\n            throw new Error(String(response.message));\r\n        }\r\n        return response.data as MutationInfo[][];\r\n    }\r\n\r\n    async useComputes(): Promise<Database> {\r\n        const newDatabase = new Database(this.name); \r\n        const arrayComputedFields = await ComputedFieldProcessor.getComputedFields(this.name);\r\n        newDatabase.setComputedFields(arrayComputedFields);\r\n        return newDatabase;\r\n    }\r\n\r\n    async useTriggers(): Promise<Database> {\r\n        const newDatabase = new Database(this.name); \r\n        const arrayTriggers = await TriggerProcessor.getTriggers(this.name);\r\n        newDatabase.setTriggers(arrayTriggers);\r\n        return newDatabase;\r\n    }\r\n\r\n    async connect(): Promise<void> {\r\n        const response = await this.engine.run('query_engine', [\r\n            '--action', 'connect',\r\n        ]);\r\n        if (response.status != 200) {\r\n            returnFormattedError(response.status, response.message);\r\n        }\r\n    }\r\n\r\n    async disconnect(): Promise<void> {\r\n        await this.engine.run('query_engine', [\r\n            '--action', 'disconnect',\r\n        ]);\r\n    }\r\n\r\n    /**\r\n     * Creates and returns a new instance of `Table` for the specified table.\r\n     * This method is used to start building queries for a specific table.\r\n     * It provides a fluent interface for common database operations like select, insert, update, and delete.\r\n     *\r\n     * @param {string} tableName - The name of the table to query.\r\n     * @returns {Table} - Returns a new instance of `Table` for the specified table.\r\n     *\r\n     * @example\r\n     * // Select all records from a table\r\n     * const users = await db.table('users').get();\r\n     * \r\n     * // Select records with conditions\r\n     * const activeUsers = await db.table('users')\r\n     *     .where('status', '=', 'active')\r\n     *     .orderBy('created_at', 'DESC')\r\n     *     .limit(10)\r\n     *     .get();\r\n     * \r\n     * // Insert records\r\n     * await db.table('users').insert([\r\n     *     { name: 'John', email: 'john@example.com', age: 30 }\r\n     * ]);\r\n     * \r\n     * // Update records\r\n     * await db.table('users')\r\n     *     .where('id', '=', 1)\r\n     *     .update({ status: 'inactive' });\r\n     * \r\n     * // Delete records\r\n     * await db.table('users')\r\n     *     .where('status', '=', 'deleted')\r\n     *     .delete();\r\n     * \r\n     * // Access column management\r\n     * const columns = await db.table('users').columns().get();\r\n     */\r\n    table<T extends DatabaseRecord = DatabaseRecord>(tableName: string): Table<T> {\r\n        const t = new Table<T>(this, this.name, tableName, this.engine, this.computedFields, this.triggers, this.txId);\r\n        const sink = (this as any)._collectInto;\r\n        if (sink) t._batchSink = sink;\r\n        return t;\r\n    }\r\n\r\n    private setComputedFields(computedFields: ComputedFieldConfig[]){\r\n        this.computedFields = computedFields;\r\n    }\r\n\r\n    private setTriggers(triggers: TriggerConfig[]){\r\n        this.triggers = triggers;\r\n    }\r\n}\r\n\r\n/**\r\n * Class to build and execute SQL queries for a specific table.\r\n * Supports operations like SELECT, INSERT, UPDATE, DELETE, and more.\r\n *\r\n * Generic over the row shape: `db.table<User>('users').get()` resolves to\r\n * `Promise<User[]>`. Pair it with the interfaces emitted by `dbcube generate`.\r\n */\r\nexport class Table<T extends DatabaseRecord = DatabaseRecord> {\r\n    private engine: QueryEngine;\r\n    private nextType: 'AND' | 'OR' = 'AND';\r\n    private dml: DML;\r\n    private computedFields: ComputedFieldConfig[] = [];\r\n    private trigger: Trigger;\r\n    private triggers: TriggerConfig[];\r\n    private txId: string | null = null;\r\n    private relations: { name: string; options: RelationOptions }[] = [];\r\n    /** Builders de grupo mutan en sitio (ver clone()) */\r\n    private _mutable = false;\r\n    /** En modo batch (db.batch) las escrituras se encolan aquí en vez de\r\n     *  ejecutarse: toda la transacción viaja al engine en UN solo cruce. */\r\n    _batchSink: DML[] | null = null;\r\n\r\n    private instance: Database;\r\n\r\n    constructor(instance: Database, databaseName: string, tableName: string, engine: QueryEngine, computedFields: ComputedFieldConfig[] = [], triggers: TriggerConfig[] = [], txId: string | null = null) {\r\n        this.engine = engine;\r\n        this.instance = instance;\r\n        this.computedFields = computedFields;\r\n        this.triggers = triggers;\r\n        // Lazy: sin triggers configurados (el caso común) no se construye el\r\n        // runner — db.table() está en el hot path de cada query\r\n        this.trigger = triggers.length > 0 ? new Trigger(instance, databaseName, triggers) : (null as any);\r\n        this.nextType = 'AND';\r\n        this.txId = txId;\r\n\r\n        this.dml = {\r\n            type: 'select',\r\n            database: databaseName,\r\n            table: tableName,\r\n            columns: ['*'],\r\n            distinct: false,\r\n            joins: [],\r\n            where: [],\r\n            orderBy: [],\r\n            groupBy: [],\r\n            limit: null,\r\n            offset: null,\r\n            data: null,\r\n            aggregation: null,\r\n            having: []\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Specifies the columns to select in a SELECT query.\r\n     *\r\n     * @param {string[]} fields - Array of column names to select. If empty, selects all columns.\r\n     * @returns {Table} - Returns the current instance of Table for method chaining.\r\n     *\r\n     * @example\r\n     * const users = await db.table('users').select(['id', 'name']).get();\r\n     * console.log(users); // [{ id: 1, name: 'John' }, { id: 2, name: 'Jane' }]\r\n     */\r\n    select(fields: string[] = []): Table<T> {\r\n        const clone = this.clone();\r\n        clone.dml.type = 'select';\r\n        clone.dml.columns = fields.length > 0 ? fields : ['*'];\r\n        clone.dml.aggregation = null;\r\n        return clone;\r\n    }\r\n\r\n    /**\r\n     * Adds a WHERE condition to the query.\r\n     *\r\n     * @param {string} column - The column to filter by.\r\n     * @param {string} operator - The comparison operator (e.g., '=', '>', '<', 'IS NULL', 'IS NOT NULL').\r\n     * @param {any} value - The value to compare against (optional for IS NULL/IS NOT NULL).\r\n     * @returns {Table} - Returns the current instance of Table for method chaining.\r\n     *\r\n     * @example\r\n     * const users = await db.table('users').where('age', '>', 25).get();\r\n     * const nullUsers = await db.table('users').where('email', 'IS NULL').get();\r\n     * console.log(users); // [{ id: 1, name: 'John', age: 30 }]\r\n     */\r\n    where(column: string, operator: 'IS NULL' | 'IS NOT NULL'): Table<T>;\r\n    where(column: string, operator: '=' | '!=' | '<>' | '>' | '<' | '>=' | '<=' | 'LIKE' | 'NOT LIKE' | 'IN' | 'NOT IN' | 'BETWEEN' | 'NOT BETWEEN', value: any): Table<T>;\r\n    where(column: string, operator: string, value?: any): Table<T> {\r\n        const clone = this.clone();\r\n        clone.dml.where.push({\r\n            column,\r\n            operator,\r\n            value,\r\n            type: clone.nextType,\r\n            isGroup: false\r\n        });\r\n        clone.nextType = 'AND';\r\n        return clone;\r\n    }\r\n\r\n    /**\r\n     * Adds an OR WHERE condition to the query.\r\n     *\r\n     * @param {string} column - The column to filter by.\r\n     * @param {string} operator - The comparison operator (e.g., '=', '>', '<', 'IS NULL', 'IS NOT NULL').\r\n     * @param {any} value - The value to compare against (optional for IS NULL/IS NOT NULL).\r\n     * @returns {Table} - Returns the current instance of Table for method chaining.\r\n     *\r\n     * @example\r\n     * const users = await db.table('users').where('age', '>', 25).orWhere('name', '=', 'Jane').get();\r\n     * const nullUsers = await db.table('users').where('active', '=', true).orWhere('email', 'IS NULL').get();\r\n     * console.log(users); // [{ id: 1, name: 'John', age: 30 }, { id: 2, name: 'Jane', age: 25 }]\r\n     */\r\n    orWhere(column: string, operator: 'IS NULL' | 'IS NOT NULL'): Table<T>;\r\n    orWhere(column: string, operator: '=' | '!=' | '<>' | '>' | '<' | '>=' | '<=' | 'LIKE' | 'NOT LIKE' | 'IN' | 'NOT IN' | 'BETWEEN' | 'NOT BETWEEN', value: any): Table<T>;\r\n    orWhere(column: string, operator: string, value?: any): Table<T> {\r\n        const clone = this.clone();\r\n        clone.dml.where.push({\r\n            column,\r\n            operator,\r\n            value,\r\n            type: 'OR',\r\n            isGroup: false\r\n        });\r\n        return clone;\r\n    }\r\n\r\n    /**\r\n     * Adds a grouped WHERE condition to the query.\r\n     *\r\n     * @param {WhereCallback} callback - A callback function that receives a new Table instance to build the grouped conditions.\r\n     * @returns {Table} - Returns the current instance of Table for method chaining.\r\n     *\r\n     * @example\r\n     * const users = await db.table('users').whereGroup(query => {\r\n     *     query.where('age', '>', 25).orWhere('name', '=', 'Jane');\r\n     * }).get();\r\n     * console.log(users); // [{ id: 1, name: 'John', age: 30 }, { id: 2, name: 'Jane', age: 25 }]\r\n     */\r\n    whereGroup(callback: WhereCallback): Table<T> {\r\n        const clone = this.clone();\r\n        const groupQuery = new Table(this.instance, clone.dml.database, clone.dml.table, clone.engine);\r\n        // El callback encadena sin usar el valor de retorno; el builder del\r\n        // grupo debe mutar en sitio o las condiciones se perderían en clones\r\n        groupQuery._mutable = true;\r\n        callback(groupQuery);\r\n\r\n        clone.dml.where.push({\r\n            type: clone.nextType,\r\n            isGroup: true,\r\n            conditions: groupQuery.dml.where as WhereCondition[]\r\n        });\r\n        clone.nextType = 'AND';\r\n        return clone;\r\n    }\r\n\r\n    or(): Table<T> {\r\n        const clone = this.clone();\r\n        clone.nextType = 'OR';\r\n        return clone;\r\n    }\r\n\r\n    and(): Table<T> {\r\n        const clone = this.clone();\r\n        clone.nextType = 'AND';\r\n        return clone;\r\n    }\r\n\r\n    /**\r\n     * Adds a WHERE BETWEEN condition to the query.\r\n     *\r\n     * @param {string} column - The column to filter by.\r\n     * @param {[any, any]} values - A tuple with two values representing the range.\r\n     * @returns {Table} - Returns the current instance of Table for method chaining.\r\n     *\r\n     * @example\r\n     * const users = await db.table('users').whereBetween('age', [20, 30]).get();\r\n     * console.log(users); // [{ id: 1, name: 'John', age: 30 }, { id: 2, name: 'Jane', age: 25 }]\r\n     */\r\n    whereBetween(column: string, values: [any, any]): Table<T> {\r\n        const clone = this.clone();\r\n        const [value1, value2] = values;\r\n        if (value1 !== undefined && value2 !== undefined) {\r\n            clone.dml.where.push({\r\n                column,\r\n                operator: 'BETWEEN',\r\n                value: [value1, value2],\r\n                type: clone.nextType,\r\n                isGroup: false\r\n            });\r\n            clone.nextType = 'AND';\r\n        }\r\n        return clone;\r\n    }\r\n\r\n    /**\r\n     * Adds a WHERE IN condition to the query.\r\n     *\r\n     * @param {string} column - The column to filter by.\r\n     * @param {any[]} values - An array of values to match.\r\n     * @returns {Table} - Returns the current instance of Table for method chaining.\r\n     *\r\n     * @example\r\n     * const users = await db.table('users').whereIn('id', [1, 2]).get();\r\n     * console.log(users); // [{ id: 1, name: 'John' }, { id: 2, name: 'Jane' }]\r\n     */\r\n    whereIn(column: string, values: any[]): Table<T> {\r\n        const clone = this.clone();\r\n        if (Array.isArray(values) && values.length > 0) {\r\n            clone.dml.where.push({\r\n                column,\r\n                operator: 'IN',\r\n                value: values,\r\n                type: clone.nextType,\r\n                isGroup: false\r\n            });\r\n            clone.nextType = 'AND';\r\n        }\r\n        return clone;\r\n    }\r\n\r\n    /**\r\n    * Adds a WHERE IS NULL condition to the query.\r\n    *\r\n    * @param {string} column - The column to filter by.\r\n    * @returns {Table} - Returns the current instance of Table for method chaining.\r\n    *\r\n    * @example\r\n    * const users = await db.table('users').whereNull('email').get();\r\n    * console.log(users); // [{ id: 3, name: 'Alice', email: null }]\r\n    */\r\n    whereNull(column: string): Table<T> {\r\n        const clone = this.clone();\r\n        clone.dml.where.push({\r\n            column,\r\n            operator: 'IS NULL',\r\n            type: clone.nextType,\r\n            isGroup: false\r\n        });\r\n        clone.nextType = 'AND';\r\n        return clone;\r\n    }\r\n\r\n    /**\r\n     * Adds a WHERE IS NOT NULL condition to the query.\r\n     *\r\n     * @param {string} column - The column to filter by.\r\n     * @returns {Table} - Returns the current instance of Table for method chaining.\r\n     *\r\n     * @example\r\n     * const users = await db.table('users').whereNotNull('email').get();\r\n     * console.log(users); // [{ id: 1, name: 'John', email: 'john@example.com' }]\r\n     */\r\n    whereNotNull(column: string): Table<T> {\r\n        const clone = this.clone();\r\n        clone.dml.where.push({\r\n            column,\r\n            operator: 'IS NOT NULL',\r\n            type: clone.nextType,\r\n            isGroup: false\r\n        });\r\n        clone.nextType = 'AND';\r\n        return clone;\r\n    }\r\n\r\n    /**\r\n     * Adds a JOIN clause to the query.\r\n     *\r\n     * @param {string} table - The table to join.\r\n     * @param {string} column1 - The column from the current table.\r\n     * @param {string} operator - The comparison operator (e.g., '=', '>', '<').\r\n     * @param {string} column2 - The column from the joined table.\r\n     * @returns {Table} - Returns the current instance of Table for method chaining.\r\n     *\r\n     * @example\r\n     * const users = await db.table('users').join('orders', 'users.id', '=', 'orders.user_id').get();\r\n     * console.log(users); // [{ id: 1, name: 'John', order_id: 101 }]\r\n     */\r\n    join(table: string, column1: string, operator: string, column2: string): Table<T> {\r\n        const clone = this.clone();\r\n        clone.dml.joins.push({\r\n            type: 'INNER',\r\n            table,\r\n            on: {\r\n                column1,\r\n                operator,\r\n                column2\r\n            }\r\n        });\r\n        return clone;\r\n    }\r\n\r\n    /**\r\n     * Adds a LEFT JOIN clause to the query.\r\n     *\r\n     * @param {string} table - The table to join.\r\n     * @param {string} column1 - The column from the current table.\r\n     * @param {string} operator - The comparison operator (e.g., '=', '>', '<').\r\n     * @param {string} column2 - The column from the joined table.\r\n     * @returns {Table} - Returns the current instance of Table for method chaining.\r\n     *\r\n     * @example\r\n     * const users = await db.table('users').leftJoin('orders', 'users.id', '=', 'orders.user_id').get();\r\n     * console.log(users); // [{ id: 1, name: 'John', order_id: 101 }, { id: 2, name: 'Jane', order_id: null }]\r\n     */\r\n    leftJoin(table: string, column1: string, operator: string, column2: string): Table<T> {\r\n        const clone = this.clone();\r\n        clone.dml.joins.push({\r\n            type: 'LEFT',\r\n            table,\r\n            on: {\r\n                column1,\r\n                operator,\r\n                column2\r\n            }\r\n        });\r\n        return clone;\r\n    }\r\n\r\n    /**\r\n     * Adds a RIGHT JOIN clause to the query.\r\n     *\r\n     * @param {string} table - The table to join.\r\n     * @param {string} column1 - The column from the current table.\r\n     * @param {string} operator - The comparison operator (e.g., '=', '>', '<').\r\n     * @param {string} column2 - The column from the joined table.\r\n     * @returns {Table} - Returns the current instance of Table for method chaining.\r\n     *\r\n     * @example\r\n     * const users = await db.table('users').rightJoin('orders', 'users.id', '=', 'orders.user_id').get();\r\n     * console.log(users); // [{ id: 1, name: 'John', order_id: 101 }, { id: null, name: null, order_id: 102 }]\r\n     */\r\n    rightJoin(table: string, column1: string, operator: string, column2: string): Table<T> {\r\n        const clone = this.clone();\r\n        clone.dml.joins.push({\r\n            type: 'RIGHT',\r\n            table,\r\n            on: {\r\n                column1,\r\n                operator,\r\n                column2\r\n            }\r\n        });\r\n        return clone;\r\n    }\r\n\r\n    /**\r\n     * Adds an ORDER BY clause to the query.\r\n     *\r\n     * @param {string} column - The column to order by.\r\n     * @param {'ASC' | 'DESC'} direction - The sorting direction ('ASC' or 'DESC').\r\n     * @returns {Table} - Returns the current instance of Table for method chaining.\r\n     *\r\n     * @example\r\n     * const users = await db.table('users').orderBy('name', 'ASC').get();\r\n     * console.log(users); // [{ id: 2, name: 'Jane' }, { id: 1, name: 'John' }]\r\n     */\r\n    orderBy(column: string, direction: 'ASC' | 'DESC' = 'ASC'): Table<T> {\r\n        const clone = this.clone();\r\n        const validDirections: ('ASC' | 'DESC')[] = ['ASC', 'DESC'];\r\n        if (validDirections.includes(direction.toUpperCase() as 'ASC' | 'DESC')) {\r\n            clone.dml.orderBy.push({\r\n                column,\r\n                direction: direction.toUpperCase() as 'ASC' | 'DESC'\r\n            });\r\n        } else {\r\n            throw new Error(`Invalid direction: ${direction}. Use 'ASC' or 'DESC'.`);\r\n        }\r\n        return clone;\r\n    }\r\n\r\n    /**\r\n     * Adds a GROUP BY clause to the query.\r\n     *\r\n     * @param {string} column - The column to group by.\r\n     * @returns {Table} - Returns the current instance of Table for method chaining.\r\n     *\r\n     * @example\r\n     * const users = await db.table('users').groupBy('age').get();\r\n     * console.log(users); // [{ age: 30, count: 1 }, { age: 25, count: 1 }]\r\n     */\r\n    groupBy(column: string): Table<T> {\r\n        const clone = this.clone();\r\n        clone.dml.groupBy.push(column);\r\n        return clone;\r\n    }\r\n\r\n    /**\r\n     * Adds a DISTINCT clause to the query.\r\n     *\r\n     * @returns {Table} - Returns the current instance of Table for method chaining.\r\n     *\r\n     * @example\r\n     * const users = await db.table('users').distinct().select(['name']).get();\r\n     * console.log(users); // [{ name: 'John' }, { name: 'Jane' }]\r\n     */\r\n    distinct(): Table<T> {\r\n        const clone = this.clone();\r\n        clone.dml.distinct = true;\r\n        return clone;\r\n    }\r\n\r\n    /**\r\n     * Adds a COUNT clause to the query.\r\n     *\r\n     * @param {string} column - The column to count (default is '*').\r\n     * @returns {Table} - Returns the current instance of Table for method chaining.\r\n     *\r\n     * @example\r\n     * const count = await db.table('users').count().first();\r\n     * console.log(count); // { count: 2 }\r\n     */\r\n    async count(column: string = '*'): Promise<number> {\r\n        const clone = this.clone();\r\n        clone.dml.type = 'select';\r\n        clone.dml.aggregation = {\r\n            type: 'COUNT',\r\n            column,\r\n            alias: 'count'\r\n        }\r\n        \r\n        clone.dml.orderBy = [];  // un agregado escalar no ordena; Postgres rechaza ORDER BY de columnas no agrupadas\r\nclone.dml.columns = [`COUNT(${column}) AS count`];\r\n        clone.dml.data = null;\r\n        clone.dml.limit = null;  // Remover limit para contar todos\r\n        clone.dml.offset = null;  // Remover offset también\r\n        try {\r\n            const result = await clone.getResponse();\r\n            const res = result[0] || null;\r\n            if (res) {\r\n                return res.count;\r\n            }\r\n            return 0;\r\n        }\r\n        catch (error) {\r\n            throw error;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Adds a SUM clause to the query.\r\n     *\r\n     * @param {string} column - The column to sum.\r\n     * @returns {Table} - Returns the current instance of Table for method chaining.\r\n     *\r\n     * @example\r\n     * const totalAge = await db.table('users').sum('age').first();\r\n     * console.log(totalAge); // { sum: 55 }\r\n     */\r\n    async sum(column: string): Promise<number> {\r\n        const clone = this.clone();\r\n        clone.dml.type = 'select';\r\n        clone.dml.aggregation = {\r\n            type: 'SUM',\r\n            column,\r\n            alias: 'sum'\r\n        }\r\n        \r\n        clone.dml.orderBy = [];  // un agregado escalar no ordena; Postgres rechaza ORDER BY de columnas no agrupadas\r\nclone.dml.columns = [`SUM(${column}) AS sum`];\r\n        clone.dml.data = null;\r\n        clone.dml.limit = 1;\r\n        try {\r\n            const result = await clone.getResponse();\r\n            const res = result[0] || null;\r\n            if (res) {\r\n                return res.sum;\r\n            }\r\n            return 0;\r\n        }\r\n        catch (error) {\r\n            throw error;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Adds an AVG clause to the query.\r\n     *\r\n     * @param {string} column - The column to calculate the average.\r\n     * @returns {Table} - Returns the current instance of Table for method chaining.\r\n     *\r\n     * @example\r\n     * const avgAge = await db.table('users').avg('age').first();\r\n     * console.log(avgAge); // { avg: 27.5 }\r\n     */\r\n    async avg(column: string): Promise<number> {\r\n        const clone = this.clone();\r\n        clone.dml.type = 'select';\r\n        clone.dml.aggregation = {\r\n            type: 'AVG',\r\n            column,\r\n            alias: 'avg'\r\n        }\r\n        \r\n        clone.dml.orderBy = [];  // un agregado escalar no ordena; Postgres rechaza ORDER BY de columnas no agrupadas\r\nclone.dml.columns = [`AVG(${column}) AS avg`];\r\n        clone.dml.data = null;\r\n        clone.dml.limit = 1;\r\n        try {\r\n            const result = await clone.getResponse();\r\n            const res = result[0] || null;\r\n            if (res) {\r\n                return res.avg;\r\n            }\r\n            return 0;\r\n        }\r\n        catch (error) {\r\n            throw error;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Adds a MAX clause to the query.\r\n     *\r\n     * @param {string} column - The column to find the maximum value.\r\n     * @returns {Table} - Returns the current instance of Table for method chaining.\r\n     *\r\n     * @example\r\n     * const maxAge = await db.table('users').max('age').first();\r\n     * console.log(maxAge); // { max: 30 }\r\n     */\r\n    async max(column: string): Promise<number> {\r\n        const clone = this.clone();\r\n        clone.dml.type = 'select';\r\n        clone.dml.aggregation = {\r\n            type: 'MAX',\r\n            column,\r\n            alias: 'max'\r\n        }\r\n        \r\n        clone.dml.orderBy = [];  // un agregado escalar no ordena; Postgres rechaza ORDER BY de columnas no agrupadas\r\nclone.dml.columns = [`MAX(${column}) AS max`];\r\n        clone.dml.data = null;\r\n        clone.dml.limit = 1;\r\n        try {\r\n            const result = await clone.getResponse();\r\n            const res = result[0] || null;\r\n            if (res) {\r\n                return res.max;\r\n            }\r\n            return 0;\r\n        }\r\n        catch (error) {\r\n            throw error;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Adds a MIN clause to the query.\r\n     *\r\n     * @param {string} column - The column to find the minimum value.\r\n     * @returns {Table} - Returns the current instance of Table for method chaining.\r\n     *\r\n     * @example\r\n     * const minAge = await db.table('users').min('age').first();\r\n     * console.log(minAge); // { min: 25 }\r\n     */\r\n    async min(column: string): Promise<number> {\r\n        const clone = this.clone();\r\n        clone.dml.type = 'select';\r\n        clone.dml.aggregation = {\r\n            type: 'MIN',\r\n            column,\r\n            alias: 'min'\r\n        }\r\n        \r\n        clone.dml.orderBy = [];  // un agregado escalar no ordena; Postgres rechaza ORDER BY de columnas no agrupadas\r\nclone.dml.columns = [`MIN(${column}) AS min`];\r\n        clone.dml.data = null;\r\n        clone.dml.limit = 1;\r\n        try {\r\n            const result = await clone.getResponse();\r\n            const res = result[0] || null;\r\n            if (res) {\r\n                return res.min;\r\n            }\r\n            return 0;\r\n        }\r\n        catch (error) {\r\n            throw error;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Gets the column names of the table.\r\n     * For SQL databases (MySQL, PostgreSQL, SQLite), returns a simple array of column names.\r\n     * For MongoDB, returns a hierarchical structure with nested documents.\r\n     *\r\n     * @returns {Promise<string[] | any>} - Returns an array of column names for SQL databases,\r\n     *                                      or a hierarchical structure for MongoDB.\r\n     *\r\n     * @example\r\n     * // SQL databases (MySQL, PostgreSQL, SQLite)\r\n     * const columns = await db.table('users').columns();\r\n     * console.log(columns); // ['id', 'name', 'email', 'age', 'created_at']\r\n     *\r\n     * @example\r\n     * // MongoDB\r\n     * const structure = await db.table('users').columns();\r\n     * console.log(structure);\r\n     * // {\r\n     * //   columns: ['id', 'name', 'profile'],\r\n     * //   submenu: {\r\n     * //     profile: {\r\n     * //       columns: ['age', 'city'],\r\n     * //       submenu: {}\r\n     * //     }\r\n     * //   }\r\n     * // }\r\n     */\r\n    async columns(): Promise<string[] | any> {\r\n        const clone = this.clone();\r\n        clone.dml.type = 'columns';\r\n        clone.dml.columns = [];\r\n        clone.dml.where = [];\r\n        clone.dml.orderBy = [];\r\n        clone.dml.groupBy = [];\r\n        clone.dml.limit = null;\r\n        clone.dml.offset = null;\r\n        clone.dml.data = null;\r\n        clone.dml.aggregation = null;\r\n\r\n        try {\r\n            const result = await clone.getResponse();\r\n\r\n            if (Array.isArray(result) && result.length > 0) {\r\n                // Verificar si es MongoDB (estructura jerárquica)\r\n                if (result[0].columns && result[0].submenu !== undefined) {\r\n                    // MongoDB: devolver la estructura completa\r\n                    return result[0];\r\n                }\r\n\r\n                // SQL databases: transformar a array simple de strings\r\n                return result.map((row: any) => row.column_name || row.Field || row.name);\r\n            }\r\n\r\n            return [];\r\n        } catch (error) {\r\n            throw error;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Adds a LIMIT clause to the query.\r\n     *\r\n     * @param {number} number - The maximum number of rows to return.\r\n     * @returns {Table} - Returns the current instance of Table for method chaining.\r\n     *\r\n     * @example\r\n     * const users = await db.table('users').limit(1).get();\r\n     * console.log(users); // [{ id: 1, name: 'John', age: 30 }]\r\n     */\r\n    limit(number: number): Table<T> {\r\n        const clone = this.clone();\r\n        clone.dml.limit = Number(number);\r\n        return clone;\r\n    }\r\n\r\n    /**\r\n     * Adds pagination to the query using LIMIT and OFFSET.\r\n     *\r\n     * @param {number} number - The page number (starting from 1).\r\n     * @returns {Table} - Returns the current instance of Table for method chaining.\r\n     *\r\n     * @example\r\n     * const users = await db.table('users').limit(1).page(2).get();\r\n     * console.log(users); // [{ id: 2, name: 'Jane', age: 25 }]\r\n     */\r\n    page(number: number): Table<T> {\r\n        const clone = this.clone();\r\n        const pageNum = Number(number);\r\n        if (clone.dml.limit) {\r\n            clone.dml.offset = (pageNum - 1) * clone.dml.limit;\r\n        }\r\n        return clone;\r\n    }\r\n\r\n    /**\r\n    * Executes the query and returns all matching rows.\r\n    *\r\n    * @returns {Promise<DatabaseRecord[]>} - Returns an array of rows.\r\n    *\r\n    * @example\r\n    * const users = await db.table('users').get();\r\n    * console.log(users); // [{ id: 1, name: 'John' }, { id: 2, name: 'Jane' }]\r\n    */\r\n    async get(): Promise<T[]> {\r\n        try {\r\n            const clone = this.clone();\r\n            clone.dml.type = 'select';\r\n            clone.dml.data = null;\r\n            clone.dml.aggregation = null;\r\n            const result = await clone.getResponse();\r\n            if (this.relations.length > 0 && Array.isArray(result)) {\r\n                return await this.attachRelations(result) as T[];\r\n            }\r\n            return result as T[];\r\n        }\r\n        catch (error) {\r\n            throw error;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Executes the query and returns the first matching row.\r\n     *\r\n     * @returns {Promise<DatabaseRecord | null>} - Returns the first row or null if no rows match.\r\n     *\r\n     * @example\r\n     * const user = await db.table('users').first();\r\n     * console.log(user); // { id: 1, name: 'John' }\r\n     */\r\n    async first(): Promise<T | null> {\r\n        const clone = this.clone();\r\n        clone.dml.type = 'select';\r\n        clone.dml.data = null;\r\n        clone.dml.aggregation = null;\r\n        clone.dml.limit = 1;\r\n        try {\r\n            const result = await clone.getResponse();\r\n            return result[0] || null;\r\n        }\r\n        catch (error) {\r\n            throw error;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Finds a row by a specific column value.\r\n     *\r\n     * @param {any} value - The value to search for.\r\n     * @param {string} column - The column to search in (default is 'id').\r\n     * @returns {Promise<DatabaseRecord | null>} - Returns the first matching row or null if no rows match.\r\n     *\r\n     * @example\r\n     * const user = await db.table('users').find(1);\r\n     * console.log(user); // { id: 1, name: 'John' }\r\n     */\r\n    async find(value: string | number, column: string = 'id'): Promise<T | null> {\r\n        // Hot path: la query más frecuente de cualquier app. Sin computed\r\n        // fields, triggers ni relaciones pendientes no hay nada que preparar —\r\n        // un DML literal evita la cadena de clones (~0.3-0.5ms por llamada).\r\n        if (this.computedFields.length === 0 && this.relations.length === 0 && !this._mutable) {\r\n            const dml: DML = {\r\n                type: 'select',\r\n                database: this.dml.database,\r\n                table: this.dml.table,\r\n                columns: ['*'],\r\n                distinct: false,\r\n                joins: [],\r\n                where: [{ column, operator: '=', value, type: 'AND', isGroup: false }],\r\n                orderBy: [],\r\n                groupBy: [],\r\n                limit: 1,\r\n                offset: null,\r\n                data: null,\r\n                aggregation: null,\r\n                having: [],\r\n            };\r\n            const response = await this.engine.executeDml(dml, this.txId ?? undefined);\r\n            if (response.status != 200) {\r\n                returnFormattedError(response.status, response.message);\r\n                throw new Error(String(response.message));\r\n            }\r\n            return (response.data?.[0] as T) || null;\r\n        }\r\n\r\n        // where() is immutable: reassign the clone or the condition is lost\r\n        const clone = this.clone().where(column, '=', value);\r\n        clone.dml.type = 'select';\r\n        clone.dml.data = null;\r\n        clone.dml.aggregation = null;\r\n        clone.dml.limit = 1;\r\n        try {\r\n            const result = await clone.getResponse();\r\n            return result[0] || null;\r\n        }\r\n        catch (error) {\r\n            throw error;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Inserts one or more rows into the table.\r\n     *\r\n     * @param {DatabaseRecord[]} data - An array of objects representing the rows to insert.\r\n     * @returns {Promise<DatabaseRecord[]>} - Returns an array of the inserted rows.\r\n     *\r\n     * @example\r\n     * const newUsers = await db.table('users').insert([\r\n     *     { name: 'Alice', age: 28 },\r\n     *     { name: 'Bob', age: 32 }\r\n     * ]);\r\n     * console.log(newUsers); // [{ id: 3, name: 'Alice', age: 28 }, { id: 4, name: 'Bob', age: 32 }]\r\n     */\r\n    async insert(data: Partial<T>[]): Promise<T[]> {\r\n        if (!Array.isArray(data)) {\r\n            throw new Error('The insert method requires an array of objects with key-value pairs.');\r\n        }\r\n\r\n        if (!data.every(item => typeof item === 'object' && item !== null)) {\r\n            throw new Error('The array must contain only valid objects.');\r\n        }\r\n\r\n        // Modo batch: encolar y salir (los triggers/computes no aplican en batch)\r\n        if (this._batchSink) {\r\n            this._batchSink.push({ ...this.dml, type: 'insert', data });\r\n            return undefined as any;\r\n        }\r\n\r\n        // Hot path: sin triggers ni computed fields no hay nada que orquestar —\r\n        // ejecutar directo sin la cadena de clones ni getResponse\r\n        if (this.triggers.length === 0 && this.computedFields.length === 0) {\r\n            const dml: DML = { ...this.dml, type: 'insert', data };\r\n            const response = await this.engine.executeDml(dml, this.txId ?? undefined);\r\n            if (response.status != 200) {\r\n                returnFormattedError(response.status, response.message);\r\n                throw new Error(String(response.message));\r\n            }\r\n            return (response.data ?? data) as T[];\r\n        }\r\n\r\n        const clone = this.clone();\r\n        clone.dml.type = 'insert';\r\n        clone.dml.data = data;\r\n\r\n        const result = await clone.getResponse(clone.dml, 'Add');\r\n\r\n        return result ?? data;\r\n    }\r\n\r\n    /**\r\n     * Updates rows in the table based on the defined conditions.\r\n     *\r\n     * @param {DatabaseRecord} data - An object with key-value pairs representing the fields to update.\r\n     * @returns {Promise<any>} - Returns the result of the update operation.\r\n     *\r\n     * @example\r\n     * const result = await db.table('users')\r\n     *     .where('id', '=', 1)\r\n     *     .update({ name: 'John Updated', age: 31 });\r\n     * console.log(result); // { affectedRows: 1 }\r\n     */\r\n    async update(data: Partial<T>): Promise<MutationInfo[]> {\r\n        if (typeof data !== 'object' || Array.isArray(data)) {\r\n            throw new Error('The update method requires an object with key-value pairs.');\r\n        }\r\n\r\n        if (this.dml.where.length === 0) {\r\n            throw new Error('You must specify at least one WHERE condition to perform an update.');\r\n        }\r\n\r\n        if (this._batchSink) {\r\n            this._batchSink.push({ ...this.dml, type: 'update', data });\r\n            return undefined as any;\r\n        }\r\n\r\n        if (this.triggers.length === 0 && this.computedFields.length === 0) {\r\n            const dml: DML = { ...this.dml, type: 'update', data };\r\n            const response = await this.engine.executeDml(dml, this.txId ?? undefined);\r\n            if (response.status != 200) {\r\n                returnFormattedError(response.status, response.message);\r\n                throw new Error(String(response.message));\r\n            }\r\n            return response.data as MutationInfo[];\r\n        }\r\n\r\n        const clone = this.clone();\r\n        clone.dml.type = 'update';\r\n        clone.dml.data = data;\r\n\r\n        return clone.getResponse(clone.dml, 'Update');\r\n    }\r\n\r\n    /**\r\n     * Deletes rows from the table based on the defined conditions.\r\n     *\r\n     * @returns {Promise<any>} - Returns the result of the delete operation.\r\n     *\r\n     * @example\r\n     * const result = await db.table('users').where('id', '=', 1).delete();\r\n     * console.log(result); // { affectedRows: 1 }\r\n     */\r\n    async delete(): Promise<MutationInfo[]> {\r\n        if (this.dml.where.length === 0) {\r\n            throw new Error('You must specify at least one WHERE condition to perform a delete.');\r\n        }\r\n\r\n        if (this._batchSink) {\r\n            this._batchSink.push({ ...this.dml, type: 'delete', data: null });\r\n            return undefined as any;\r\n        }\r\n\r\n        if (this.triggers.length === 0 && this.computedFields.length === 0) {\r\n            const dml: DML = { ...this.dml, type: 'delete', data: null };\r\n            const response = await this.engine.executeDml(dml, this.txId ?? undefined);\r\n            if (response.status != 200) {\r\n                returnFormattedError(response.status, response.message);\r\n                throw new Error(String(response.message));\r\n            }\r\n            return response.data as MutationInfo[];\r\n        }\r\n\r\n        const clone = this.clone();\r\n        clone.dml.type = 'delete';\r\n\r\n        const deleteData = await clone.getResponse(clone.dml, 'Delete');\r\n        return deleteData;\r\n    }\r\n\r\n    /**\r\n     * Adds a WHERE NOT IN condition to the query.\r\n     *\r\n     * @example\r\n     * const users = await db.table('users').whereNotIn('status', ['banned', 'deleted']).get();\r\n     */\r\n    whereNotIn(column: string, values: any[]): Table<T> {\r\n        const clone = this.clone();\r\n        if (Array.isArray(values) && values.length > 0) {\r\n            clone.dml.where.push({\r\n                column,\r\n                operator: 'NOT IN',\r\n                value: values,\r\n                type: clone.nextType,\r\n                isGroup: false\r\n            });\r\n            clone.nextType = 'AND';\r\n        }\r\n        return clone;\r\n    }\r\n\r\n    /**\r\n     * Sets an explicit OFFSET for the query (alternative to page()).\r\n     *\r\n     * @example\r\n     * const rows = await db.table('logs').orderBy('id', 'ASC').limit(50).offset(100).get();\r\n     */\r\n    offset(number: number): Table<T> {\r\n        const clone = this.clone();\r\n        clone.dml.offset = Number(number);\r\n        return clone;\r\n    }\r\n\r\n    /**\r\n     * Appends raw expressions to the SELECT list (aggregates, functions, aliases).\r\n     * Combine with groupBy() and having() for per-group metrics.\r\n     *\r\n     * @example\r\n     * const stats = await db.table('orders')\r\n     *     .select(['user_id'])\r\n     *     .selectRaw(['COUNT(*) AS order_count', 'SUM(amount) AS total'])\r\n     *     .groupBy('user_id')\r\n     *     .having('order_count', '>', 5)\r\n     *     .get();\r\n     */\r\n    selectRaw(expressions: string[]): Table<T> {\r\n        const clone = this.clone();\r\n        if (clone.dml.columns.length === 1 && clone.dml.columns[0] === '*') {\r\n            clone.dml.columns = [...expressions];\r\n        } else {\r\n            clone.dml.columns = [...clone.dml.columns, ...expressions];\r\n        }\r\n        return clone;\r\n    }\r\n\r\n    /**\r\n     * Adds a HAVING condition (filters grouped results).\r\n     *\r\n     * @example\r\n     * .groupBy('user_id').having('COUNT(*)', '>', 5)\r\n     */\r\n    having(column: string, operator: string, value?: any): Table<T> {\r\n        const clone = this.clone();\r\n        clone.dml.having = clone.dml.having ?? [];\r\n        clone.dml.having.push({\r\n            column,\r\n            operator,\r\n            value,\r\n            type: 'AND',\r\n            isGroup: false\r\n        });\r\n        return clone;\r\n    }\r\n\r\n    /**\r\n     * Checks if at least one row matches the current conditions.\r\n     * Cheaper than first(): selects a constant with LIMIT 1.\r\n     *\r\n     * @example\r\n     * const taken = await db.table('users').where('email', '=', email).exists();\r\n     */\r\n    async exists(): Promise<boolean> {\r\n        const clone = this.clone();\r\n        clone.dml.type = 'select';\r\n        clone.dml.columns = ['1 AS dbcube_exists'];\r\n        clone.dml.data = null;\r\n        clone.dml.aggregation = null;\r\n        clone.dml.limit = 1;\r\n        clone.dml.offset = null;\r\n        const result = await clone.getResponse();\r\n        return Array.isArray(result) && result.length > 0;\r\n    }\r\n\r\n    /**\r\n     * Fetches one page of results plus pagination metadata in a single call.\r\n     * Runs the page query and the total count with the same conditions.\r\n     *\r\n     * @example\r\n     * const { items, total, totalPages, hasNext } = await db.table('products')\r\n     *     .where('published', '=', true)\r\n     *     .orderBy('id', 'ASC')\r\n     *     .paginate(2, 25);\r\n     */\r\n    async paginate(page: number = 1, perPage: number = 20): Promise<PaginatedResult<T>> {\r\n        const pageNum = Math.max(1, Number(page));\r\n        const size = Math.max(1, Number(perPage));\r\n\r\n        const itemsQuery = this.limit(size).page(pageNum);\r\n        const [items, total] = await Promise.all([\r\n            itemsQuery.get(),\r\n            this.count()\r\n        ]);\r\n\r\n        const totalNum = Number(total);\r\n        const totalPages = Math.ceil(totalNum / size);\r\n        return {\r\n            items,\r\n            page: pageNum,\r\n            perPage: size,\r\n            total: totalNum,\r\n            totalPages,\r\n            hasNext: pageNum < totalPages,\r\n            hasPrev: pageNum > 1,\r\n        };\r\n    }\r\n\r\n    /**\r\n     * Processes all matching rows in batches of `size`, keeping memory flat.\r\n     * Return `false` from the callback to stop early.\r\n     *\r\n     * @example\r\n     * await db.table('logs').orderBy('id', 'ASC').chunk(500, async (rows) => {\r\n     *     await processBatch(rows);\r\n     * });\r\n     */\r\n    async chunk(size: number, callback: (rows: T[], page: number) => Promise<void | boolean> | void | boolean): Promise<void> {\r\n        const batchSize = Math.max(1, Number(size));\r\n        let page = 1;\r\n        while (true) {\r\n            const rows = await this.limit(batchSize).page(page).get();\r\n            if (rows.length === 0) break;\r\n            const result = await callback(rows, page);\r\n            if (result === false) break;\r\n            if (rows.length < batchSize) break;\r\n            page++;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Atomically increments a numeric column: `SET col = col + amount`.\r\n     * Requires at least one WHERE condition. Extra fields can be updated in the same statement.\r\n     *\r\n     * @example\r\n     * await db.table('products').where('id', '=', 5).increment('stock', 3);\r\n     * await db.table('posts').where('id', '=', 1).increment('views', 1, { last_viewed_at: new Date().toISOString() });\r\n     */\r\n    async increment(column: string, amount: number = 1, extra: Partial<T> = {}): Promise<MutationInfo[]> {\r\n        if (this.dml.where.length === 0) {\r\n            throw new Error('You must specify at least one WHERE condition to perform an increment.');\r\n        }\r\n        const data = { ...extra, [column]: { $inc: Number(amount) } };\r\n\r\n        if (this._batchSink) {\r\n            this._batchSink.push({ ...this.dml, type: 'update', data });\r\n            return undefined as any;\r\n        }\r\n\r\n        if (this.triggers.length === 0 && this.computedFields.length === 0) {\r\n            const dml: DML = { ...this.dml, type: 'update', data };\r\n            const response = await this.engine.executeDml(dml, this.txId ?? undefined);\r\n            if (response.status != 200) {\r\n                returnFormattedError(response.status, response.message);\r\n                throw new Error(String(response.message));\r\n            }\r\n            return response.data as MutationInfo[];\r\n        }\r\n\r\n        const clone = this.clone();\r\n        clone.dml.type = 'update';\r\n        clone.dml.data = data;\r\n        return clone.getResponse();\r\n    }\r\n\r\n    /**\r\n     * Atomically decrements a numeric column: `SET col = col - amount`.\r\n     *\r\n     * @example\r\n     * await db.table('products').where('id', '=', 5).decrement('stock', 1);\r\n     */\r\n    async decrement(column: string, amount: number = 1, extra: Partial<T> = {}): Promise<MutationInfo[]> {\r\n        return this.increment(column, -Math.abs(Number(amount)), extra);\r\n    }\r\n\r\n    /**\r\n     * Deletes ALL rows from the table. The only write operation allowed\r\n     * without a WHERE — the destructive intent is explicit in the name.\r\n     *\r\n     * @example\r\n     * await db.table('temp_imports').truncate();\r\n     */\r\n    async truncate(): Promise<MutationInfo[]> {\r\n        const clone = this.clone();\r\n        clone.dml.type = 'delete';\r\n        clone.dml.where = [];\r\n        return clone.getResponse();\r\n    }\r\n\r\n    /**\r\n     * Inserts rows, updating them instead when a conflict occurs on the given keys.\r\n     * MySQL → ON DUPLICATE KEY UPDATE · PostgreSQL/SQLite → ON CONFLICT ... DO UPDATE.\r\n     *\r\n     * @param data Rows to insert.\r\n     * @param conflictKeys Column(s) with the UNIQUE/PK constraint that triggers the update.\r\n     * @param updateColumns Columns to overwrite on conflict (defaults to every non-conflict column).\r\n     *\r\n     * @example\r\n     * await db.table('settings').upsert(\r\n     *     [{ key: 'theme', value: 'dark' }],\r\n     *     ['key']\r\n     * );\r\n     */\r\n    async upsert(data: Partial<T>[], conflictKeys: string[], updateColumns?: string[]): Promise<MutationInfo[]> {\r\n        if (!Array.isArray(data) || data.length === 0) {\r\n            throw new Error('The upsert method requires a non-empty array of objects.');\r\n        }\r\n        if (!Array.isArray(conflictKeys) || conflictKeys.length === 0) {\r\n            throw new Error('The upsert method requires at least one conflict key column.');\r\n        }\r\n\r\n        const motor: string = this.engine?.getConfig?.()?.type ?? 'mysql';\r\n\r\n        const table = this.dml.table;\r\n        const columns = Object.keys(data[0]);\r\n        const targets = updateColumns ?? columns.filter(c => !conflictKeys.includes(c));\r\n\r\n        // Único método que arma la operación en JS: validar identificadores\r\n        // porque las claves de los objetos pueden venir de input externo\r\n        assertValidIdentifier(table, 'table');\r\n        for (const c of columns) assertValidIdentifier(c, 'column');\r\n        for (const c of conflictKeys) assertValidIdentifier(c, 'conflict key');\r\n        for (const c of targets) assertValidIdentifier(c, 'update column');\r\n\r\n        if (motor === 'mongodb') {\r\n            // Comando `update` nativo con upsert:true por fila — misma semántica\r\n            // que ON CONFLICT: matchea por conflictKeys, actualiza solo targets,\r\n            // y al insertar escribe la fila completa.\r\n            const updates = data.map(row => {\r\n                const q: Record<string, unknown> = {};\r\n                for (const k of conflictKeys) q[k] = row[k];\r\n\r\n                const set: Record<string, unknown> = {};\r\n                for (const c of targets) if (c in row) set[c] = row[c];\r\n\r\n                const setOnInsert: Record<string, unknown> = {};\r\n                for (const c of columns) {\r\n                    if (!targets.includes(c) && !conflictKeys.includes(c)) setOnInsert[c] = row[c];\r\n                }\r\n                if (!('uuid' in row)) setOnInsert['uuid'] = randomUUID();\r\n\r\n                const u: Record<string, unknown> = {};\r\n                if (Object.keys(set).length) u['$set'] = set;\r\n                if (Object.keys(setOnInsert).length) u['$setOnInsert'] = setOnInsert;\r\n\r\n                return { q, u, upsert: true, multi: false };\r\n            });\r\n\r\n            const command = JSON.stringify({ update: table, updates });\r\n            const response = await this.engine.rawQuery(command, [], this.txId ?? undefined);\r\n            if (response.status != 200) {\r\n                returnFormattedError(response.status, response.message);\r\n                throw new Error(response.message);\r\n            }\r\n            return response.data;\r\n        }\r\n\r\n        const quote = (id: string) => motor === 'mysql' ? `\\`${id}\\`` : `\"${id}\"`;\r\n\r\n        const params: any[] = [];\r\n        const placeholder = () => motor === 'postgres' || motor === 'postgresql'\r\n            ? `$${params.length}`\r\n            : '?';\r\n\r\n        const rowsSql = data.map(row => {\r\n            const cells = columns.map(col => {\r\n                params.push(row[col] === undefined ? null : row[col]);\r\n                return placeholder();\r\n            });\r\n            return `(${cells.join(', ')})`;\r\n        }).join(', ');\r\n\r\n        const colsSql = columns.map(quote).join(', ');\r\n        let sql: string;\r\n\r\n        if (motor === 'mysql') {\r\n            const updates = targets.map(c => `${quote(c)} = VALUES(${quote(c)})`).join(', ');\r\n            sql = `INSERT INTO ${quote(table)} (${colsSql}) VALUES ${rowsSql} ON DUPLICATE KEY UPDATE ${updates}`;\r\n        } else {\r\n            const conflict = conflictKeys.map(quote).join(', ');\r\n            const updates = targets.map(c => `${quote(c)} = excluded.${quote(c)}`).join(', ');\r\n            sql = `INSERT INTO ${quote(table)} (${colsSql}) VALUES ${rowsSql} ON CONFLICT (${conflict}) DO UPDATE SET ${updates}`;\r\n        }\r\n\r\n        if (motor === 'sqlite') {\r\n            // SQLite pool schema sync: ensure every pooled connection sees constraints\r\n            // created moments ago (e.g. a UNIQUE index added right before this upsert).\r\n            await this.engine.rawQuery('SELECT name FROM sqlite_master LIMIT 1', [], this.txId ?? undefined);\r\n        }\r\n        const response = await this.engine.rawQuery(sql, params, this.txId ?? undefined);\r\n        if (response.status != 200) {\r\n            returnFormattedError(response.status, response.message);\r\n            throw new Error(response.message);\r\n        }\r\n        return response.data;\r\n    }\r\n\r\n    /**\r\n     * Declares a relation to eager-load with the results of get().\r\n     * Relations are resolved from `foreign` definitions in your .cube files,\r\n     * or explicitly via options. Loads each relation with ONE batched query\r\n     * (whereIn) — no N+1.\r\n     *\r\n     * @example\r\n     * // hasMany: orders.user_id → users.id (auto-detected from orders.table.cube)\r\n     * const users = await db.table('users').with('orders').get();\r\n     * // users[0].orders === [{...}, {...}]\r\n     *\r\n     * // belongsTo: posts.author_id → users.id, attached as a single object\r\n     * const posts = await db.table('posts')\r\n     *     .with('author', { table: 'users', foreignKey: 'author_id', type: 'one' })\r\n     *     .get();\r\n     */\r\n    with(relation: string, options: RelationOptions = {}): Table<T> {\r\n        const clone = this.clone();\r\n        clone.relations.push({ name: relation, options });\r\n        return clone;\r\n    }\r\n\r\n    private async attachRelations(rows: DatabaseRecord[]): Promise<DatabaseRecord[]> {\r\n        if (rows.length === 0 || this.relations.length === 0) return rows;\r\n\r\n        for (const { name, options } of this.relations) {\r\n            const relatedTable = options.table ?? name;\r\n            const cubeMeta = loadCubeRelations();\r\n\r\n            // Detect direction + keys from .cube foreign metadata when not explicit\r\n            let type = options.type;\r\n            let foreignKey = options.foreignKey;\r\n            let localKey = options.localKey ?? 'id';\r\n\r\n            if (!foreignKey || !type) {\r\n                const childFks = cubeMeta[relatedTable]?.foreigns ?? [];\r\n                const ownFks = cubeMeta[this.dml.table]?.foreigns ?? [];\r\n                const childToParent = childFks.find(fk => fk.table === this.dml.table);\r\n                const parentToChild = ownFks.find(fk => fk.table === relatedTable);\r\n\r\n                if (childToParent) {\r\n                    // hasMany: the related table points at us\r\n                    type = type ?? 'many';\r\n                    foreignKey = foreignKey ?? childToParent.column_name;\r\n                    localKey = options.localKey ?? childToParent.column;\r\n                } else if (parentToChild) {\r\n                    // belongsTo: we point at the related table\r\n                    type = type ?? 'one';\r\n                    foreignKey = foreignKey ?? parentToChild.column_name;\r\n                    localKey = options.localKey ?? parentToChild.column;\r\n                } else {\r\n                    // Heuristic fallback: <singular-parent>_id on the child table\r\n                    type = type ?? 'many';\r\n                    foreignKey = foreignKey ?? `${singularize(this.dml.table)}_id`;\r\n                }\r\n            }\r\n\r\n            const relatedQuery = new Table(this.instance, this.dml.database, relatedTable, this.engine, this.computedFields, this.triggers, this.txId);\r\n\r\n            if (type === 'one') {\r\n                // belongsTo: FK lives on THIS table, match related.localKey\r\n                const fkValues = [...new Set(rows.map(r => r[foreignKey!]).filter(v => v !== null && v !== undefined))];\r\n                const related = fkValues.length > 0\r\n                    ? await relatedQuery.whereIn(localKey, fkValues).get()\r\n                    : [];\r\n                const index = new Map(related.map(r => [r[localKey], r]));\r\n                for (const row of rows) {\r\n                    row[name] = index.get(row[foreignKey!]) ?? null;\r\n                }\r\n            } else {\r\n                // hasMany: FK lives on the RELATED table, match this.localKey\r\n                const ids = [...new Set(rows.map(r => r[localKey]).filter(v => v !== null && v !== undefined))];\r\n                const related = ids.length > 0\r\n                    ? await relatedQuery.whereIn(foreignKey!, ids).get()\r\n                    : [];\r\n                const groups = new Map<any, DatabaseRecord[]>();\r\n                for (const rel of related) {\r\n                    const key = rel[foreignKey!];\r\n                    if (!groups.has(key)) groups.set(key, []);\r\n                    groups.get(key)!.push(rel);\r\n                }\r\n                for (const row of rows) {\r\n                    row[name] = groups.get(row[localKey]) ?? [];\r\n                }\r\n            }\r\n        }\r\n        return rows;\r\n    }\r\n\r\n    private async getResponse(dml: any = null, type: any = null): Promise<any> {\r\n        const localDML = dml ? dml : this.dml;\r\n        const computedFieldsNeeded: any[] = [];\r\n        let dependeciesArrray: any[] = [];\r\n        // Columnas pedidas por el usuario ANTES de inyectar dependencias de\r\n        // computed fields: las dependencias solo se eliminan del resultado si\r\n        // el usuario NO las pidió explícitamente\r\n        const requestedColumns = new Set<string>(localDML.columns ?? []);\r\n\r\n        if (this.computedFields.length > 0) {\r\n            let columns = localDML.columns;\r\n\r\n            for (const field of localDML.columns) {\r\n                const computedField = this.computedFields.find(cf => cf.column === field);\r\n\r\n                if (computedField) {\r\n                    computedFieldsNeeded.push(computedField);\r\n                    // Add dependencies to real fields\r\n                    const dependencies = ComputedFieldProcessor.extractDependencies(computedField.instruction);\r\n                    dependeciesArrray = [...dependeciesArrray, ...dependencies];\r\n                    columns = Array.from(new Set([...columns, ...dependencies]));\r\n                    columns = columns.filter((col: string) => col != field);\r\n                }\r\n            }\r\n            localDML.columns = columns;\r\n        }\r\n\r\n        let arrayResult = [];\r\n        if (type) {\r\n            const beffore = this.trigger ? this.trigger.get('before' + type) : undefined;\r\n            const after = this.trigger ? this.trigger.get('after' + type) : undefined;\r\n            if (this.triggers.length > 0 && (beffore || after)) {\r\n                const dataset = localDML.data;\r\n                for (let index = 0; index < dataset.length; index++) {\r\n                    const data = dataset[index];\r\n                    const newDML = { ...localDML, data: [data] };\r\n                    if (beffore) {\r\n                        const interceptor = await this.trigger.execute('before' + type, data);\r\n                        const response = await this.engine.executeDml(newDML, this.txId ?? undefined);\r\n\r\n                        if (response.status != 200) {\r\n                            interceptor?.discard();\r\n                            returnFormattedError(response.status, response.message);\r\n                            // Un fallo del engine DEBE propagarse: resolver en\r\n                            // silencio haría creer al caller que la escritura\r\n                            // ocurrió (pérdida de datos invisible)\r\n                            throw new Error(String(response.message));\r\n                        }\r\n                        await interceptor?.commit();\r\n                        arrayResult = response.data;\r\n                    }\r\n                    if (after) {\r\n\r\n                        const response = await this.engine.executeDml(newDML, this.txId ?? undefined);\r\n\r\n                        if (response.status != 200) {\r\n                            returnFormattedError(response.status, response.message);\r\n                            throw new Error(String(response.message));\r\n                        }\r\n                        const interceptor = await this.trigger.execute('after' + type, data);\r\n                        await interceptor?.commit();\r\n                    }\r\n                }\r\n            } else {\r\n                const response = await this.engine.executeDml(localDML, this.txId ?? undefined);\r\n\r\n                if (response.status != 200) {\r\n                    returnFormattedError(response.status, response.message);\r\n                    throw new Error(String(response.message));\r\n                }\r\n\r\n                arrayResult = response.data;\r\n            }\r\n        } else {\r\n            const response = await this.engine.executeDml(localDML, this.txId ?? undefined);\r\n\r\n            if (response.status != 200) {\r\n                returnFormattedError(response.status, response.message);\r\n                throw new Error(String(response.message));\r\n            }\r\n\r\n            arrayResult = response.data;\r\n        }\r\n\r\n        if (computedFieldsNeeded.length > 0) {\r\n            let newDataset: any = ComputedFieldProcessor.computedFields(arrayResult, computedFieldsNeeded);\r\n            const toRemove = dependeciesArrray.filter(key => !requestedColumns.has(key));\r\n            const result = newDataset.map((obj: any) => {\r\n                const newObj = { ...obj };\r\n                toRemove.forEach(key => delete newObj[key]);\r\n                return newObj;\r\n            });\r\n            return result;\r\n        }\r\n        return arrayResult;\r\n    }\r\n\r\n    private clone(): Table<T> {\r\n        // Los builders de grupo (whereGroup) son mutables: el callback encadena\r\n        // sin usar el valor de retorno, así que clonar perdería las condiciones\r\n        if (this._mutable) return this;\r\n        const cloned = Object.create(Object.getPrototypeOf(this));\r\n        cloned.engine = this.engine;\r\n        cloned.instance = this.instance;\r\n        cloned._batchSink = this._batchSink; // el modo batch sobrevive a la cadena de where()\r\n        cloned.nextType = this.nextType;\r\n        cloned.computedFields = this.computedFields;\r\n        cloned.trigger = this.trigger;\r\n        cloned.triggers = this.triggers;\r\n        cloned.txId = this.txId;\r\n        cloned.relations = [...this.relations];\r\n\r\n        cloned.dml = {\r\n            ...this.dml,\r\n            columns: [...this.dml.columns],\r\n            joins: [...this.dml.joins],\r\n            where: [...this.dml.where],\r\n            orderBy: [...this.dml.orderBy],\r\n            groupBy: [...this.dml.groupBy],\r\n            having: [...(this.dml.having ?? [])],\r\n            // Clonar propiedades que faltaban para evitar mutación compartida\r\n            data: this.dml.data ? (Array.isArray(this.dml.data) ? [...this.dml.data] : { ...this.dml.data }) : null,\r\n            aggregation: this.dml.aggregation ? { ...this.dml.aggregation } : null\r\n        };\r\n        return cloned;\r\n    }\r\n\r\n}\r\n\r\n// ---- Cube relation metadata (cached scan of dbcube/*.table.cube) ----\r\n\r\ninterface CubeForeign {\r\n    column_name: string;   // FK column on the owning table\r\n    table: string;         // referenced table\r\n    column: string;        // referenced column\r\n}\r\n\r\nlet cubeRelationsCache: Record<string, { foreigns: CubeForeign[] }> | null = null;\r\n\r\nfunction loadCubeRelations(): Record<string, { foreigns: CubeForeign[] }> {\r\n    if (cubeRelationsCache) return cubeRelationsCache;\r\n    const result: Record<string, { foreigns: CubeForeign[] }> = {};\r\n\r\n    const scanDir = (dir: string) => {\r\n        let entries: fs.Dirent[];\r\n        try {\r\n            entries = fs.readdirSync(dir, { withFileTypes: true });\r\n        } catch {\r\n            return;\r\n        }\r\n        for (const entry of entries) {\r\n            const full = path.join(dir, entry.name);\r\n            if (entry.isDirectory()) {\r\n                if (entry.name !== 'node_modules' && entry.name !== 'triggers' && entry.name !== 'logs') {\r\n                    scanDir(full);\r\n                }\r\n            } else if (entry.name.endsWith('.table.cube')) {\r\n                try {\r\n                    const content = fs.readFileSync(full, 'utf8');\r\n                    const nameMatch = content.match(/@meta\\s*\\(\\s*\\{[\\s\\S]*?name\\s*:\\s*\"([^\"]+)\"/);\r\n                    const tableName = nameMatch ? nameMatch[1] : path.basename(entry.name, '.table.cube');\r\n\r\n                    const foreigns: CubeForeign[] = [];\r\n                    const colRegex = /(\\w+)\\s*:\\s*\\{(?:[^{}]|\\{[^{}]*\\})*?foreign\\s*:\\s*\\{([^}]*)\\}/g;\r\n                    let m: RegExpExecArray | null;\r\n                    while ((m = colRegex.exec(content)) !== null) {\r\n                        const fkTable = m[2].match(/table\\s*:\\s*\"([^\"]+)\"/);\r\n                        const fkColumn = m[2].match(/column\\s*:\\s*\"([^\"]+)\"/);\r\n                        if (fkTable) {\r\n                            foreigns.push({\r\n                                column_name: m[1],\r\n                                table: fkTable[1],\r\n                                column: fkColumn ? fkColumn[1] : 'id',\r\n                            });\r\n                        }\r\n                    }\r\n                    result[tableName] = { foreigns };\r\n                } catch { /* unreadable cube — skip */ }\r\n            }\r\n        }\r\n    };\r\n\r\n    scanDir(path.join(process.cwd(), 'dbcube'));\r\n    cubeRelationsCache = result;\r\n    return result;\r\n}\r\n\r\nfunction assertValidIdentifier(name: string, kind: string): void {\r\n    if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(name)) {\r\n        throw new Error(`Invalid ${kind} name: '${name}'. Only letters, numbers and underscore are allowed.`);\r\n    }\r\n}\r\n\r\nfunction singularize(word: string): string {\r\n    if (word.endsWith('ies')) return word.slice(0, -3) + 'y';\r\n    if (word.endsWith('ses')) return word.slice(0, -2);\r\n    if (word.endsWith('s') && !word.endsWith('ss')) return word.slice(0, -1);\r\n    return word;\r\n}\r\n\r\nfunction returnFormattedError(status: number, message: string) {\r\n    const RESET = '\\x1b[0m';\r\n    const RED = '\\x1b[31m';\r\n    const YELLOW = '\\x1b[33m';\r\n    const BOLD = '\\x1b[1m';\r\n    const CYAN = '\\x1b[36m';\r\n    const GRAY = '\\x1b[90m';\r\n    const UNDERLINE = '\\x1b[4m';\r\n    const MAGENTA = '\\x1b[35m';\r\n\r\n    let output = '';\r\n    let help = '';\r\n    const color = status === 600 ? YELLOW : RED;\r\n\r\n\r\n    if (message.includes(\"[help]\")) {\r\n        const parts = message.split(\"[help]\");\r\n        output += `\\n${RED}${BOLD}${parts[0]}${RESET}`;\r\n        help += `\\n${MAGENTA}${BOLD}[help]${RESET} ${GRAY}${parts[1]}${RESET}\\n`;\r\n    } else {\r\n        output += `\\n${color}${BOLD}${message}${RESET}\\n`;\r\n    }\r\n\r\n    const err = new Error();\r\n    const stackLines = err.stack?.split('\\n') || [];\r\n\r\n    // Buscamos la primera línea del stack fuera de node_modules\r\n    const relevantStackLine = stackLines.find(line =>\r\n        line.includes('.js:') && !line.includes('node_modules')\r\n    );\r\n\r\n    if (relevantStackLine) {\r\n        // Los frames pueden venir como `at (path:line:col)` o, en código async,\r\n        // como `at async path:line:col` (sin paréntesis). El `(?:async )?` evita\r\n        // que el \"async \" quede pegado al path y rompa la lectura del archivo.\r\n        const match = relevantStackLine.match(/\\((.*):(\\d+):(\\d+)\\)/) ||\r\n            relevantStackLine.match(/at (?:async )?(.*):(\\d+):(\\d+)/);\r\n\r\n        if (match) {\r\n            const [, filePath, lineStr, columnStr] = match;\r\n            const lineNum = parseInt(lineStr, 10);\r\n            const errorLocation = `${filePath}:${lineStr}:${columnStr}`;\r\n\r\n            // Leemos el archivo y sacamos las líneas relevantes\r\n            try {\r\n                const codeLines = fs.readFileSync(filePath, 'utf-8').split('\\n');\r\n                const start = Math.max(0, lineNum - 3);\r\n                const end = Math.min(codeLines.length, lineNum + 2);\r\n\r\n                output += `\\n${CYAN}${BOLD}[code] ${RESET}${YELLOW} ${UNDERLINE}${errorLocation}${RESET}\\n`;\r\n\r\n                for (let i = start; i < end; i++) {\r\n                    const line = codeLines[i];\r\n                    const lineLabel = `${i + 1}`.padStart(4, ' ');\r\n                    const pointer = i + 1 === lineNum ? `${RED}<-${RESET}` : '  ';\r\n                    output += `${GRAY}${lineLabel}${RESET} ${pointer} ${line}\\n`;\r\n                }\r\n            } catch (err) {\r\n                output += `${YELLOW}⚠️ No se pudo leer el archivo de origen: ${filePath}${RESET}\\n`;\r\n                output += `\\n${CYAN}${BOLD}Stack Trace:${RESET}\\n${stackLines.slice(2).join('\\n')}\\n`;\r\n            }\r\n        }\r\n    }\r\n    output += help;\r\n    console.error(output);\r\n}\r\n\r\nexport default Database;\r\n","import path from \"path\";\nimport { FileLogger, InterceptController } from \"@dbcube/core\";\nimport { createRequire } from 'module';\nimport type { TriggerConfig } from \"../@types/Database\";\n\n/**\n * Runtime triggers: user-defined JS functions (from .trigger.cube files) that\n * run in the application process around each write. Because they execute in\n * the write-path (not as DB-side triggers), they behave identically across\n * MySQL, PostgreSQL, SQLite and MongoDB, and fire exactly once per operation\n * regardless of how many service instances share the database.\n */\nexport class Trigger {\n    private triggers: TriggerConfig[];\n    private databaseName: string;\n    private instance: unknown;\n\n    constructor(instance: unknown, databaseName: string, metadata: TriggerConfig[]) {\n        this.triggers = metadata;\n        this.databaseName = databaseName;\n        this.instance = instance;\n    }\n\n    get(type: string): TriggerConfig | undefined {\n        return this.triggers.find((tr) => tr.type === type);\n    }\n\n    async execute(type: string, row: Record<string, unknown>): Promise<InterceptController | null> {\n        const trigger = this.triggers.find((tr) => tr.type === type);\n        if (trigger) {\n            const logFilePath = path.resolve(\n                process.cwd(),\n                'dbcube',\n                'logs',\n                'triggers',\n                this.databaseName,\n                `${trigger.table_ref}_${trigger.type}.log`\n            );\n\n            const interceptor = FileLogger.interceptConsole(logFilePath, {\n                keepOriginal: false,\n                useBuffer: true\n            });\n            const pathFile = path.resolve(process.cwd(), 'dbcube', 'triggers', `${trigger.database_ref}_${trigger.table_ref}_${trigger.type}.js`);\n            // Use __filename for CJS, process.cwd() for ESM\n            const requireUrl = typeof __filename !== 'undefined' ? __filename : process.cwd();\n            const require = createRequire(requireUrl);\n            // Clear require cache to ensure fresh load\n            try {\n                delete require.cache[require.resolve(pathFile)];\n            } catch { /* bundled environments may not expose a resolvable cache */ }\n            try {\n                const triggerModule = require(pathFile);\n                const dataProcess = triggerModule.default || triggerModule;\n                await dataProcess({ db: this.instance, oldData: row, newData: row });\n            } finally {\n                // Sin esto, un trigger que lanza deja el console secuestrado\n                // para SIEMPRE y el error se vuelve invisible para la app\n                interceptor.restore();\n            }\n            return interceptor;\n        }\n        return null;\n    }\n}\n"],"mappings":"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","names":["import_path","import_core","path","require","response","fs","path","err"]}