@plyaz/db 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/migrations/generateDownMigration.ts","../../src/utils/databaseResultHelpers.ts","../../src/migrations/MigrationManager.ts","../../src/seeds/SeedManager.ts","../../src/utils/typeGuards.ts","../../src/service/EventEmitter.ts","../../src/utils/normalizeDetails.ts","../../src/service/HealthManager.ts","../../src/utils/ConfigMerger.ts","../../src/service/DatabaseService.ts","../../src/utils/pagination.ts","../../src/utils/regex.ts","../../src/adapters/drizzle/DrizzleAdapter.ts","../../src/adapters/supabase/SupabaseAdapter.ts","../../src/adapters/sql/SQLAdapter.ts","../../src/adapters/mock/MockAdapter.ts","../../src/factory/AdapterFactory.ts","../../src/extensions/SoftDeleteExtension.ts","../../src/extensions/AuditExtension.ts","../../src/extensions/EncryptionExtension.ts","../../src/extensions/CachingAdapter.ts","../../src/extensions/ReadReplicaAdapter.ts","../../src/factory/createDatabaseService.ts","../../src/cli/index.ts"],"names":["fs3","path3","path","fs","sql","DESCRIPTION_MAX_LENGTH","FALLBACK_DESCRIPTION_LENGTH","PROGRESS_LOG_INTERVAL","ERROR_MESSAGE_MAX_LENGTH","path2","DatabaseError","DATABASE_ERROR_CODES","fs2","idColumn","result","NUMERIX","Pool","resolve","ADAPTERS","logger","processDirectory"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Utility to help generate DOWN migrations from SQL files\n *\n * This is a helper script to analyze SQL migrations and suggest\n * appropriate DOWN statements for rollback support.\n */\n\nimport * as fs from \"fs\";\nimport * as path from \"path\";\n\n/** Maximum characters to show in TODO comments for unhandled statements */\nconst TODO_PREVIEW_LENGTH = 50;\n/** Width of separator lines in output */\nconst SEPARATOR_LINE_WIDTH = 60;\n/** CLI arguments slice start index */\nconst CLI_ARGS_START = 2;\n\ninterface DownSuggestion {\n file: string;\n upStatements: string[];\n downSuggestions: string[];\n}\n\n/** Handler function for generating DOWN statement from a SQL statement */\ntype StatementHandler = (statement: string) => string | null;\n\n/**\n * Pattern handlers for generating DOWN statements\n */\nconst STATEMENT_HANDLERS: Array<{\n pattern: RegExp;\n handler: StatementHandler;\n}> = [\n {\n pattern: /CREATE\\s+TABLE\\s+(?:IF\\s+NOT\\s+EXISTS\\s+)?(\\w+)/i,\n handler: (statement) => {\n const match = statement.match(\n /CREATE\\s+TABLE\\s+(?:IF\\s+NOT\\s+EXISTS\\s+)?(\\w+)/i,\n );\n return match ? `DROP TABLE IF EXISTS ${match[1]} CASCADE` : null;\n },\n },\n {\n pattern: /CREATE\\s+(?:UNIQUE\\s+)?INDEX\\s+(?:IF\\s+NOT\\s+EXISTS\\s+)?(\\w+)/i,\n handler: (statement) => {\n const match = statement.match(\n /CREATE\\s+(?:UNIQUE\\s+)?INDEX\\s+(?:IF\\s+NOT\\s+EXISTS\\s+)?(\\w+)/i,\n );\n return match ? `DROP INDEX IF EXISTS ${match[1]}` : null;\n },\n },\n {\n pattern: /CREATE\\s+TYPE\\s+(\\w+)/i,\n handler: (statement) => {\n const match = statement.match(/CREATE\\s+TYPE\\s+(\\w+)/i);\n return match ? `DROP TYPE IF EXISTS ${match[1]} CASCADE` : null;\n },\n },\n {\n pattern: /CREATE\\s+EXTENSION\\s+(?:IF\\s+NOT\\s+EXISTS\\s+)?\"?(\\w+)\"?/i,\n handler: (statement) => {\n const match = statement.match(\n /CREATE\\s+EXTENSION\\s+(?:IF\\s+NOT\\s+EXISTS\\s+)?\"?(\\w+)\"?/i,\n );\n return match ? `DROP EXTENSION IF EXISTS \"${match[1]}\"` : null;\n },\n },\n {\n pattern: /ALTER\\s+TABLE\\s+(\\w+)\\s+ADD\\s+COLUMN/i,\n handler: (statement) => {\n const match = statement.match(\n /ALTER\\s+TABLE\\s+(\\w+)\\s+ADD\\s+COLUMN\\s+(\\w+)/i,\n );\n return match\n ? `ALTER TABLE ${match[1]} DROP COLUMN IF EXISTS ${match[2]}`\n : null;\n },\n },\n {\n pattern: /CREATE\\s+(?:OR\\s+REPLACE\\s+)?FUNCTION\\s+(\\w+)/i,\n handler: (statement) => {\n const match = statement.match(\n /CREATE\\s+(?:OR\\s+REPLACE\\s+)?FUNCTION\\s+(\\w+)/i,\n );\n return match ? `DROP FUNCTION IF EXISTS ${match[1]}` : null;\n },\n },\n {\n pattern:\n /CREATE\\s+(?:OR\\s+REPLACE\\s+)?TRIGGER\\s+(\\w+)\\s+(?:BEFORE|AFTER)\\s+(?:INSERT|UPDATE|DELETE).*?ON\\s+(\\w+)/i,\n handler: (statement) => {\n const match = statement.match(\n /CREATE\\s+(?:OR\\s+REPLACE\\s+)?TRIGGER\\s+(\\w+)\\s+(?:BEFORE|AFTER)\\s+(?:INSERT|UPDATE|DELETE).*?ON\\s+(\\w+)/i,\n );\n return match ? `DROP TRIGGER IF EXISTS ${match[1]} ON ${match[2]}` : null;\n },\n },\n];\n\n/**\n * Generate a DOWN statement for a single SQL statement\n */\nfunction generateDownStatement(statement: string): string {\n for (const { pattern, handler } of STATEMENT_HANDLERS) {\n if (statement.match(pattern)) {\n const result = handler(statement);\n if (result) return result;\n }\n }\n // Unknown statement type - suggest manual review\n return `-- TODO: Add DOWN statement for: ${statement.substring(0, TODO_PREVIEW_LENGTH)}...`;\n}\n\n/**\n * Parse SQL migration and suggest DOWN statements\n */\nexport function suggestDownMigration(\n sqlContent: string,\n filename: string,\n): DownSuggestion {\n const upStatements: string[] = [];\n const downSuggestions: string[] = [];\n\n // Split by semicolons to get individual statements\n const statements = sqlContent\n .split(\";\")\n .map((s) => s.trim())\n .filter((s) => s.length > 0 && !s.startsWith(\"--\"));\n\n for (const statement of statements) {\n upStatements.push(statement);\n downSuggestions.push(generateDownStatement(statement));\n }\n\n // Reverse the order for DOWN migration (undo in reverse order)\n downSuggestions.reverse();\n\n return {\n file: filename,\n upStatements,\n downSuggestions,\n };\n}\n\n/**\n * Add DOWN section to a migration file\n */\nexport function addDownSection(filePath: string): string {\n const content = fs.readFileSync(filePath, \"utf-8\");\n\n // Check if already has DOWN section\n if (content.includes(\"-- DOWN\")) {\n return content; // Already has DOWN section\n }\n\n const suggestion = suggestDownMigration(content, path.basename(filePath));\n\n // Build the new content with DOWN section\n const downSection =\n \"\\n\\n-- DOWN\\n\" + suggestion.downSuggestions.join(\";\\n\\n\") + \";\\n\";\n\n return content + downSection;\n}\n\n/**\n * Process all migrations in a directory and add DOWN sections\n */\nexport function processDirectory(migrationsPath: string, dryRun = true): void {\n if (!fs.existsSync(migrationsPath)) {\n console.error(`Migration directory not found: ${migrationsPath}`);\n return;\n }\n\n const files = fs\n .readdirSync(migrationsPath)\n .filter((f) => f.endsWith(\".sql\"));\n\n console.log(`Found ${files.length} SQL migration files\\n`);\n\n for (const file of files) {\n const filePath = path.join(migrationsPath, file);\n const content = fs.readFileSync(filePath, \"utf-8\");\n\n if (content.includes(\"-- DOWN\")) {\n console.log(`āœ“ ${file} - Already has DOWN section`);\n continue;\n }\n\n const newContent = addDownSection(filePath);\n\n if (dryRun) {\n console.log(`\\nšŸ“„ ${file}`);\n console.log(\"─\".repeat(SEPARATOR_LINE_WIDTH));\n console.log(\"Suggested DOWN section:\");\n const downSection = newContent.split(\"-- DOWN\")[1];\n console.log(downSection);\n } else {\n fs.writeFileSync(filePath, newContent, \"utf-8\");\n console.log(`āœ“ ${file} - Added DOWN section`);\n }\n }\n\n if (dryRun) {\n console.log(\"\\n\" + \"=\".repeat(SEPARATOR_LINE_WIDTH));\n console.log(\"āš ļø DRY RUN MODE - No files were modified\");\n console.log(\"Run with --write to apply changes\");\n }\n}\n\n// CLI usage\nif (globalThis.require.main === globalThis.module) {\n const args = process.argv.slice(CLI_ARGS_START);\n const migrationsPath = args[0] || \"./migrations\";\n const dryRun = !args.includes(\"--write\");\n\n console.log(\"šŸ” Analyzing migrations for DOWN section generation\\n\");\n processDirectory(migrationsPath, dryRun);\n}\n","/**\n * @fileoverview Database Result Helper Functions for @plyaz/db package\n *\n * This module provides utility functions for creating standardized DatabaseResult objects\n * used throughout the @plyaz/db package. These helpers ensure consistent result formatting\n * across all database operations and adapters.\n *\n * Part of the @plyaz/db package - a TypeScript database abstraction layer with\n * support for multiple adapters (Drizzle, Supabase, SQL), extensions (audit, encryption,\n * soft delete), and advanced features (caching, read replicas, multi-tenancy).\n *\n */\n\nimport type { DatabaseResult } from \"@plyaz/types/db\";\n\n/**\n * Creates a successful DatabaseResult wrapper for operation results\n *\n * Used throughout all database adapters and extensions to wrap successful operation results\n * in a consistent format. This enables standardized error handling and result processing\n * across the entire @plyaz/db package.\n *\n * **Used by:**\n * - All database adapters (DrizzleAdapter, SupabaseAdapter, SQLAdapter)\n * - All extensions (AuditAdapter, EncryptionAdapter, SoftDeleteAdapter, etc.)\n * - DatabaseService for operation results\n * - Repository layer for consistent return types\n *\n * @template T - The type of the successful result value\n * @param {T} value - The successful result value to wrap\n * @returns {DatabaseResult<T>} A success result object with the value\n *\n * @example\n * ```typescript\n * import { success } from '@plyaz/db/utils';\n *\n * // In adapter methods\n * async findById<T>(table: string, id: string): Promise<DatabaseResult<T | null>> {\n * try {\n * const record = await this.db.select().from(table).where(eq(id));\n * return success(record[0] || null); // Wrap successful result\n * } catch (error) {\n * return failure(new DatabaseError('FIND_FAILED', error.message));\n * }\n * }\n *\n * // In service methods\n * const userResult = await userRepository.findById('user-123');\n * if (userResult.success) {\n * console.log('Found user:', userResult.value.name);\n * }\n * ```\n *\n */\nexport function success<T = null>(value: T = null as T): DatabaseResult<T> {\n return { success: true, value };\n}\n\n/**\n * Creates a failed DatabaseResult wrapper for operation errors\n * \n * Used throughout all database adapters and extensions to wrap error results\n * in a consistent format. This enables standardized error handling and result processing\n * across the entire @plyaz/db package.\n * \n * **Used by:**\n * - All database adapters for error cases\n * - All extensions for error propagation\n * - DatabaseService for operation failures\n * - Repository layer for consistent error handling\n * \n * @template T - The type that would have been returned on success\n * @param {Error} error - The error that occurred during the operation\n * @returns {DatabaseResult<T>} A failure result object with the error\n * \n * @example\n * ```typescript\n * import { failure } from '@plyaz/db/utils';\n * import { DatabaseError } from '@plyaz/errors';\nimport { DATABASE_ERROR_CODES } from '@plyaz/types/errors';\n * \n * // In adapter methods\n * async create<T>(table: string, data: T): Promise<DatabaseResult<T>> {\n * try {\n * const result = await this.db.insert(table).values(data).returning();\n * return success(result[0]);\n * } catch (error) {\n * return failure(new DatabaseError(\n * `Failed to create record: ${error.message}`));\n * }\n * }\n * \n * // In service layer error handling\n * const createResult = await userRepository.create(userData);\n * if (!createResult.success) {\n * logger.error('User creation failed:', createResult.error.message);\n * throw createResult.error;\n * }\n * ```\n * \n */\nexport function failure<T>(error: Error): DatabaseResult<T> {\n return { success: false, error };\n}\n","/**\n * MigrationManager - Database schema migrations with version control\n *\n * Manages database schema migrations with support for versioning,\n * rollback, and migration history tracking. Automatically discovers\n * migration files from a specified directory and applies them in order.\n *\n * @example\n * ```typescript\n * const migrationManager = new MigrationManager({\n * adapter: sqlAdapter,\n * migrationsPath: './migrations', // default\n * tableName: 'schema_migrations' // default\n * });\n *\n * // Run all pending migrations\n * await migrationManager.up();\n *\n * // Rollback last migration\n * await migrationManager.down();\n *\n * // Get migration status\n * const status = await migrationManager.status();\n * ```\n */\n\nimport type {\n DatabaseAdapterType,\n DatabaseResult,\n Migration,\n MigrationFile,\n MigrationRecord,\n MigrationManagerConfig,\n MigrationStatus,\n} from \"@plyaz/types/db\";\nimport { success, failure } from \"../utils/databaseResultHelpers\";\nimport { DatabaseError } from \"@plyaz/errors\";\nimport { DATABASE_ERROR_CODES } from \"@plyaz/types/errors\";\nimport * as fs from \"fs\";\nimport * as path from \"path\";\n\n/** Constants for statement description extraction */\nconst DESCRIPTION_MAX_LENGTH = 60;\nconst FALLBACK_DESCRIPTION_LENGTH = 50;\n\n/** Constants for progress logging */\nconst PROGRESS_LOG_INTERVAL = 10;\n\n/** Constants for error message truncation */\nconst ERROR_MESSAGE_MAX_LENGTH = 300;\n\n/**\n * MigrationManager - Handles database schema migrations\n *\n * Discovers migration files, tracks migration history, and applies\n * migrations in order with support for rollback.\n */\nexport class MigrationManager {\n private adapter: DatabaseAdapterType;\n private migrationsPath: string;\n private tableName: string;\n private schema: string;\n\n constructor(config: MigrationManagerConfig) {\n this.adapter = config.adapter;\n this.migrationsPath = path.resolve(config.migrationsPath ?? \"./migrations\");\n this.schema = config.schema ?? \"public\";\n // Prefix table name with schema if not 'public'\n this.tableName =\n this.schema !== \"public\"\n ? `${this.schema}.${config.tableName ?? \"schema_migrations\"}`\n : (config.tableName ?? \"schema_migrations\");\n }\n\n /**\n * Initialize migrations table if it doesn't exist\n */\n async initialize(): Promise<DatabaseResult<void>> {\n try {\n // Create migrations tracking table with file_path for traceability\n const createTableSQL = `\n CREATE TABLE IF NOT EXISTS ${this.tableName} (\n version VARCHAR(255) PRIMARY KEY,\n name VARCHAR(255) NOT NULL,\n file_path VARCHAR(500),\n applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n execution_time INTEGER NOT NULL\n )\n `;\n\n // Execute using adapter's raw query if available\n if (typeof this.adapter.query === \"function\") {\n await this.adapter.query(createTableSQL);\n\n // Add file_path column if it doesn't exist (for existing tables)\n await this.adapter\n .query(\n `\n DO $$\n BEGIN\n IF NOT EXISTS (\n SELECT 1 FROM information_schema.columns\n WHERE table_name = '${this.tableName.split(\".\").pop()}'\n AND column_name = 'file_path'\n ) THEN\n ALTER TABLE ${this.tableName} ADD COLUMN file_path VARCHAR(500);\n END IF;\n END $$;\n `,\n )\n .catch(() => {\n // Ignore if column already exists or syntax not supported\n });\n }\n\n return success();\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to initialize migrations table: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.INIT_FAILED,\n { cause: error as Error },\n ),\n );\n }\n }\n\n /**\n * Discover migration files from migrations directory (including subdirectories)\n */\n private async discoverMigrations(): Promise<MigrationFile[]> {\n if (!fs.existsSync(this.migrationsPath)) {\n return [];\n }\n\n const migrations: MigrationFile[] = [];\n\n const scanDirectory = (dir: string): void => {\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n\n if (entry.isDirectory()) {\n // Recursively scan subdirectories\n scanDirectory(fullPath);\n } else if (entry.isFile()) {\n // Match migration file pattern: {version}_{name}.{ts|js|sql}\n // Examples: 001_initial_schema.sql, 20231124_add_users_table.ts\n const match = entry.name.match(/^(\\d+)_(.+)\\.(ts|js|sql)$/);\n if (match) {\n const [, version, name] = match;\n migrations.push({\n filePath: fullPath,\n version,\n name: name.replace(/_/g, \" \"),\n });\n }\n }\n }\n };\n\n scanDirectory(this.migrationsPath);\n\n // Sort by version\n return migrations.sort((a, b) => a.version.localeCompare(b.version));\n }\n\n /**\n * Parse SQL content to extract UP and DOWN sections\n */\n private parseSqlSections(sql: string): {\n upSQL: string;\n downSQL: string | null;\n } {\n const hasUpMarker = sql.includes(\"-- UP\");\n const hasDownMarker = sql.includes(\"-- DOWN\");\n\n if (hasUpMarker && hasDownMarker) {\n const parts = sql.split(\"-- DOWN\");\n return {\n upSQL: parts[0].replace(\"-- UP\", \"\").trim(),\n downSQL: parts[1].trim(),\n };\n }\n\n if (hasDownMarker) {\n const parts = sql.split(\"-- DOWN\");\n return {\n upSQL: parts[0].trim(),\n downSQL: parts[1].trim(),\n };\n }\n\n return { upSQL: sql.trim(), downSQL: null };\n }\n\n /**\n * Process dollar-quoted string delimiters ($$ or $tag$)\n * Returns updated state for tracking if we're inside a dollar block\n */\n private processDollarDelimiters(\n line: string,\n inDollarBlock: boolean,\n dollarTag: string,\n ): { inDollarBlock: boolean; dollarTag: string } {\n const dollarMatch = line.match(/\\$([a-zA-Z_]*)\\$/g);\n if (!dollarMatch) return { inDollarBlock, dollarTag };\n\n let currentInBlock = inDollarBlock;\n let currentTag = dollarTag;\n\n for (const match of dollarMatch) {\n if (!currentInBlock) {\n currentInBlock = true;\n currentTag = match;\n } else if (match === currentTag) {\n currentInBlock = false;\n currentTag = \"\";\n }\n }\n\n return { inDollarBlock: currentInBlock, dollarTag: currentTag };\n }\n\n /**\n * Filter out comment-only statements\n */\n private isNonCommentStatement(statement: string): boolean {\n const withoutComments = statement.replace(/--.*$/gm, \"\").trim();\n return withoutComments.length > 0;\n }\n\n /**\n * Split SQL into individual statements for better error reporting\n * Handles $$ delimited blocks (functions, triggers) correctly\n */\n private splitSqlStatements(sql: string): string[] {\n const statements: string[] = [];\n let current = \"\";\n let inDollarBlock = false;\n let dollarTag = \"\";\n\n for (const line of sql.split(\"\\n\")) {\n const trimmedLine = line.trim();\n const isEmptyOrComment =\n trimmedLine === \"\" || trimmedLine.startsWith(\"--\");\n\n // Always append line to current statement\n current += line + \"\\n\";\n\n // Skip processing for empty lines and comments\n if (isEmptyOrComment) continue;\n\n // Update dollar block tracking\n const dollarState = this.processDollarDelimiters(\n line,\n inDollarBlock,\n dollarTag,\n );\n inDollarBlock = dollarState.inDollarBlock;\n dollarTag = dollarState.dollarTag;\n\n // Check for end of statement\n const isEndOfStatement = !inDollarBlock && trimmedLine.endsWith(\";\");\n if (isEndOfStatement && current.trim()) {\n statements.push(current.trim());\n current = \"\";\n }\n }\n\n // Add any remaining content\n if (current.trim()) {\n statements.push(current.trim());\n }\n\n return statements.filter((s) => this.isNonCommentStatement(s));\n }\n\n /**\n * Extract a short description from a SQL statement for logging\n */\n private getStatementDescription(statement: string): string {\n const firstLine =\n statement\n .split(\"\\n\")\n .find((l) => l.trim() && !l.trim().startsWith(\"--\"))\n ?.trim() ?? \"\";\n\n // Extract the type and name of the object being created/modified\n const patterns = [\n /^(CREATE\\s+(?:OR\\s+REPLACE\\s+)?(?:TABLE|INDEX|UNIQUE\\s+INDEX|TYPE|FUNCTION|TRIGGER|EXTENSION|SCHEMA|VIEW|POLICY))\\s+(?:IF\\s+NOT\\s+EXISTS\\s+)?([^\\s(]+)/i,\n /^(ALTER\\s+TABLE)\\s+([^\\s]+)/i,\n /^(DROP\\s+(?:TABLE|INDEX|TYPE|FUNCTION|TRIGGER|EXTENSION|SCHEMA|VIEW|POLICY))\\s+(?:IF\\s+EXISTS\\s+)?([^\\s(;]+)/i,\n /^(INSERT\\s+INTO)\\s+([^\\s(]+)/i,\n /^(COMMENT\\s+ON\\s+(?:TABLE|COLUMN|INDEX|FUNCTION|TYPE))\\s+([^\\s]+)/i,\n /^(GRANT|REVOKE)\\s+.+\\s+ON\\s+([^\\s]+)/i,\n ];\n\n for (const pattern of patterns) {\n const match = firstLine.match(pattern);\n if (match) {\n return `${match[1]} ${match[2]}`.slice(0, DESCRIPTION_MAX_LENGTH);\n }\n }\n\n const truncated = firstLine.slice(0, FALLBACK_DESCRIPTION_LENGTH);\n const suffix = firstLine.length > FALLBACK_DESCRIPTION_LENGTH ? \"...\" : \"\";\n return truncated + suffix;\n }\n\n /**\n * Execute SQL statements individually with better error reporting\n */\n private async executeSqlStatements(\n adapter: DatabaseAdapterType,\n sql: string,\n migrationVersion: string,\n ): Promise<void> {\n const statements = this.splitSqlStatements(sql);\n const total = statements.length;\n\n console.log(` → ${total} statements to execute`);\n\n for (let i = 0; i < statements.length; i++) {\n const statement = statements[i];\n const description = this.getStatementDescription(statement);\n\n try {\n await adapter.query!(statement);\n // Show progress at intervals or for significant operations\n const isInterval = (i + 1) % PROGRESS_LOG_INTERVAL === 0;\n const isLast = i === total - 1;\n const isSignificant = Boolean(\n description.match(/^(CREATE TABLE|CREATE FUNCTION|CREATE TRIGGER)/i),\n );\n if (isInterval || isLast || isSignificant) {\n console.log(` āœ“ [${i + 1}/${total}] ${description}`);\n }\n } catch (error) {\n console.log(` āœ— [${i + 1}/${total}] ${description}`);\n\n // Extract clean error message\n const rawMessage = (error as Error).message;\n const errorMessage = rawMessage\n .replace(/^SQL Error:\\s*/i, \"\")\n .replace(/^Failed to execute query:.*?-\\s*/i, \"\")\n .slice(0, ERROR_MESSAGE_MAX_LENGTH);\n\n throw new DatabaseError(\n `Migration ${migrationVersion} failed at statement ${i + 1}/${total}:\\n` +\n ` Statement: ${description}\\n` +\n ` Error: ${errorMessage}`,\n DATABASE_ERROR_CODES.QUERY_FAILED,\n { cause: error as Error },\n );\n }\n }\n }\n\n /**\n * Load SQL migration from file\n */\n private loadSqlMigration(migrationFile: MigrationFile): Migration {\n const sql = fs.readFileSync(migrationFile.filePath, \"utf-8\");\n const { upSQL, downSQL } = this.parseSqlSections(sql);\n\n return {\n version: migrationFile.version,\n name: migrationFile.name,\n up: async (adapter: DatabaseAdapterType) => {\n if (typeof adapter.query === \"function\") {\n await this.executeSqlStatements(\n adapter,\n upSQL,\n migrationFile.version,\n );\n }\n },\n down: async (adapter: DatabaseAdapterType) => {\n if (downSQL && typeof adapter.query === \"function\") {\n await this.executeSqlStatements(\n adapter,\n downSQL,\n migrationFile.version,\n );\n } else {\n console.warn(\n `[Migrations] No DOWN migration for ${migrationFile.version}`,\n );\n }\n },\n };\n }\n\n /**\n * Load TypeScript/JavaScript migration from file\n */\n private async loadJsMigration(\n migrationFile: MigrationFile,\n ): Promise<Migration> {\n const importPath = migrationFile.filePath.startsWith(\"/\")\n ? migrationFile.filePath\n : new URL(`file:///${migrationFile.filePath.replace(/\\\\/g, \"/\")}`).href;\n\n const migrationModule = await import(importPath);\n return {\n version: migrationFile.version,\n name: migrationFile.name,\n up: migrationModule.up ?? migrationModule.default?.up,\n down: migrationModule.down ?? migrationModule.default?.down,\n };\n }\n\n /**\n * Load migration from file\n */\n private async loadMigration(\n migrationFile: MigrationFile,\n ): Promise<Migration> {\n const ext = path.extname(migrationFile.filePath);\n\n switch (ext) {\n case \".sql\":\n return this.loadSqlMigration(migrationFile);\n case \".ts\":\n case \".js\":\n return this.loadJsMigration(migrationFile);\n default:\n throw new DatabaseError(\n `Unsupported migration file extension: ${ext}`,\n DATABASE_ERROR_CODES.INVALID_PARAMETERS,\n { cause: new Error(`Unsupported extension: ${ext}`) },\n );\n }\n }\n\n /**\n * Get applied migrations from database\n */\n private async getAppliedMigrations(): Promise<MigrationRecord[]> {\n try {\n if (typeof this.adapter.query === \"function\") {\n const result = await this.adapter.query<MigrationRecord>(\n `SELECT * FROM ${this.tableName} ORDER BY version ASC`,\n );\n // Handle both array results and postgres-style { rows: [] } results\n return Array.isArray(result)\n ? result\n : (result as unknown as { rows: MigrationRecord[] }).rows || [];\n }\n return [];\n } catch {\n // Table might not exist yet\n return [];\n }\n }\n\n /**\n * Record migration as applied\n */\n private async recordMigration(\n version: string,\n name: string,\n executionTime: number,\n filePath?: string,\n ): Promise<void> {\n if (typeof this.adapter.query === \"function\") {\n // Store relative path from migrations directory for portability\n const relativePath = filePath\n ? path.relative(this.migrationsPath, filePath)\n : null;\n\n await this.adapter.query(\n `INSERT INTO ${this.tableName} (version, name, file_path, execution_time) VALUES ($1, $2, $3, $4)`,\n [version, name, relativePath, executionTime],\n );\n }\n }\n\n /**\n * Remove migration record (for rollback)\n */\n private async unrecordMigration(version: string): Promise<void> {\n if (typeof this.adapter.query === \"function\") {\n await this.adapter.query(\n `DELETE FROM ${this.tableName} WHERE version = $1`,\n [version],\n );\n }\n }\n\n /**\n * Get migration status (applied and pending)\n */\n async status(): Promise<DatabaseResult<MigrationStatus>> {\n try {\n await this.initialize();\n\n const allMigrations = await this.discoverMigrations();\n const appliedMigrations = await this.getAppliedMigrations();\n const appliedVersions = new Set(appliedMigrations.map((m) => m.version));\n\n const pending = allMigrations\n .filter((m) => !appliedVersions.has(m.version))\n .map((m) => `${m.version}_${m.name}`);\n\n return success({\n applied: appliedMigrations,\n pending,\n });\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to get migration status: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.QUERY_FAILED,\n { cause: error as Error },\n ),\n );\n }\n }\n\n /**\n * Run all pending migrations\n */\n /* eslint-disable max-depth, complexity */\n async up(targetVersion?: string): Promise<DatabaseResult<number>> {\n try {\n await this.initialize();\n\n const allMigrations = await this.discoverMigrations();\n const appliedMigrations = await this.getAppliedMigrations();\n const appliedVersions = new Set(appliedMigrations.map((m) => m.version));\n\n let applied = 0;\n\n for (const migrationFile of allMigrations) {\n // Skip if already applied\n if (appliedVersions.has(migrationFile.version)) {\n continue;\n }\n\n // Stop if we've reached target version\n if (targetVersion && migrationFile.version > targetVersion) {\n break;\n }\n\n console.log(\n `[Migrations] Applying ${migrationFile.version}_${migrationFile.name}...`,\n );\n\n const migration = await this.loadMigration(migrationFile);\n const startTime = Date.now();\n\n // Run migration in transaction if possible\n if (typeof this.adapter.transaction === \"function\") {\n const txResult = await this.adapter.transaction(async () => {\n await migration.up(this.adapter);\n });\n // Check transaction result - transaction() returns failure() instead of throwing\n if (!txResult.success) {\n throw (\n txResult.error ??\n new DatabaseError(\n `Migration ${migration.version} failed`,\n DATABASE_ERROR_CODES.QUERY_FAILED,\n )\n );\n }\n } else {\n await migration.up(this.adapter);\n }\n\n const executionTime = Date.now() - startTime;\n\n // Record migration with file path for traceability\n await this.recordMigration(\n migration.version,\n migration.name,\n executionTime,\n migrationFile.filePath,\n );\n\n console.log(\n `[Migrations] Applied ${migration.version} in ${executionTime}ms`,\n );\n applied++;\n }\n\n return success(applied);\n } catch (error) {\n return failure(\n new DatabaseError(\n `Migration failed: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.QUERY_FAILED,\n { cause: error as Error },\n ),\n );\n }\n }\n\n /**\n * Rollback last migration or rollback to specific version\n */\n async down(steps: number = 1): Promise<DatabaseResult<number>> {\n try {\n const appliedMigrations = await this.getAppliedMigrations();\n\n if (appliedMigrations.length === 0) {\n return success(0);\n }\n\n // Get migrations to rollback (in reverse order)\n const toRollback = appliedMigrations.slice(-steps).reverse();\n let rolledBack = 0;\n\n for (const appliedMigration of toRollback) {\n console.log(\n `[Migrations] Rolling back ${appliedMigration.version}_${appliedMigration.name}...`,\n );\n\n // Find migration file\n const allMigrations = await this.discoverMigrations();\n const migrationFile = allMigrations.find(\n (m) => m.version === appliedMigration.version,\n );\n\n if (!migrationFile) {\n console.warn(\n `[Migrations] Migration file not found for version ${appliedMigration.version}`,\n );\n continue;\n }\n\n const migration = await this.loadMigration(migrationFile);\n const startTime = Date.now();\n\n // Run rollback in transaction if possible\n if (typeof this.adapter.transaction === \"function\") {\n const txResult = await this.adapter.transaction(async () => {\n await migration.down(this.adapter);\n });\n // Check transaction result - transaction() returns failure() instead of throwing\n if (!txResult.success) {\n throw (\n txResult.error ??\n new DatabaseError(\n `Rollback ${appliedMigration.version} failed`,\n DATABASE_ERROR_CODES.QUERY_FAILED,\n )\n );\n }\n } else {\n await migration.down(this.adapter);\n }\n\n const executionTime = Date.now() - startTime;\n\n // Remove migration record\n await this.unrecordMigration(appliedMigration.version);\n\n console.log(\n `[Migrations] Rolled back ${appliedMigration.version} in ${executionTime}ms`,\n );\n rolledBack++;\n }\n\n return success(rolledBack);\n } catch (error) {\n return failure(\n new DatabaseError(\n `Rollback failed: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.QUERY_FAILED,\n { cause: error as Error },\n ),\n );\n }\n }\n\n /**\n * Reset database (rollback all migrations)\n */\n async reset(): Promise<DatabaseResult<number>> {\n const appliedMigrations = await this.getAppliedMigrations();\n return this.down(appliedMigrations.length);\n }\n\n /**\n * Clear migration history (delete all records from tracking table)\n *\n * Use this to force fresh migrations in test/development environments\n * without rolling back actual database changes.\n *\n * @example\n * ```typescript\n * // Clear history and re-run all migrations\n * await migrationManager.clearHistory();\n * await migrationManager.up();\n * ```\n */\n async clearHistory(): Promise<DatabaseResult<void>> {\n try {\n if (typeof this.adapter.query === \"function\") {\n await this.adapter.query(`DELETE FROM ${this.tableName}`);\n }\n return success();\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to clear migration history: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.QUERY_FAILED,\n { cause: error as Error },\n ),\n );\n }\n }\n}\n","/**\n * SeedManager - Database seeding for development and testing\n *\n * Manages database seeding with support for ordered execution,\n * seed history tracking, and idempotent seed operations.\n * Automatically discovers seed files from a specified directory.\n *\n * @example\n * ```typescript\n * const seedManager = new SeedManager({\n * adapter: sqlAdapter,\n * seedsPath: './seeds', // default\n * tableName: 'seed_history' // default\n * });\n *\n * // Run all seeds\n * await seedManager.run();\n *\n * // Run specific seed\n * await seedManager.run('users');\n *\n * // Clear all data (for testing)\n * await seedManager.reset();\n * ```\n */\n\nimport type {\n DatabaseAdapterType,\n DatabaseResult,\n Seed,\n SeedFile,\n SeedRecord,\n SeedManagerConfig,\n} from \"@plyaz/types/db\";\nimport { success, failure } from \"../utils/databaseResultHelpers\";\nimport { DatabaseError } from \"@plyaz/errors\";\nimport { DATABASE_ERROR_CODES } from \"@plyaz/types/errors\";\nimport * as fs from \"fs\";\nimport * as path from \"path\";\n\n/** Constants for statement description extraction */\nconst DESCRIPTION_MAX_LENGTH = 60;\nconst FALLBACK_DESCRIPTION_LENGTH = 50;\n\n/** Constants for progress logging */\nconst PROGRESS_LOG_INTERVAL = 10;\n\n/** Constants for error message truncation */\nconst ERROR_MESSAGE_MAX_LENGTH = 300;\n\n/**\n * SeedManager - Handles database seeding operations\n *\n * Discovers seed files, tracks seed history, and executes\n * seeds in order with support for cleanup and reset.\n */\nexport class SeedManager {\n private adapter: DatabaseAdapterType;\n private seedsPath: string;\n private tableName: string;\n private schema: string;\n private skipExisting: boolean;\n\n constructor(config: SeedManagerConfig) {\n this.adapter = config.adapter;\n this.seedsPath = path.resolve(config.seedsPath ?? \"./seeds\");\n this.schema = config.schema ?? \"public\";\n // Prefix table name with schema if not 'public'\n this.tableName =\n this.schema !== \"public\"\n ? `${this.schema}.${config.tableName ?? \"seed_history\"}`\n : (config.tableName ?? \"seed_history\");\n this.skipExisting = config.skipExisting ?? false;\n }\n\n /**\n * Initialize seeds tracking table if it doesn't exist\n */\n async initialize(): Promise<DatabaseResult<void>> {\n try {\n // Create seeds tracking table with file_path for traceability\n const createTableSQL = `\n CREATE TABLE IF NOT EXISTS ${this.tableName} (\n name VARCHAR(255) PRIMARY KEY,\n file_path VARCHAR(500),\n run_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n execution_time INTEGER NOT NULL\n )\n `;\n\n // Execute using adapter's raw query if available\n if (typeof this.adapter.query === \"function\") {\n await this.adapter.query(createTableSQL);\n\n // Add file_path column if it doesn't exist (for existing tables)\n await this.adapter\n .query(\n `\n DO $$\n BEGIN\n IF NOT EXISTS (\n SELECT 1 FROM information_schema.columns\n WHERE table_name = '${this.tableName.split(\".\").pop()}'\n AND column_name = 'file_path'\n ) THEN\n ALTER TABLE ${this.tableName} ADD COLUMN file_path VARCHAR(500);\n END IF;\n END $$;\n `,\n )\n .catch(() => {\n // Ignore if column already exists or syntax not supported\n });\n }\n\n return success();\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to initialize seeds table: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.INIT_FAILED,\n { cause: error as Error },\n ),\n );\n }\n }\n\n /**\n * Discover seed files from seeds directory\n */\n private async discoverSeeds(): Promise<SeedFile[]> {\n if (!fs.existsSync(this.seedsPath)) {\n return [];\n }\n\n const files = fs.readdirSync(this.seedsPath);\n const seeds: SeedFile[] = [];\n\n for (const file of files) {\n // Match seed file pattern: {order}_{name}.{ts|js|sql}\n // Examples: 001_users.ts, 002_campaigns.js, 003_data.sql\n const match = file.match(/^(\\d+)_(.+)\\.(ts|js|sql)$/);\n if (match) {\n const [, order, name] = match;\n seeds.push({\n filePath: path.join(this.seedsPath, file),\n order: Number.parseInt(order, 10),\n name,\n });\n }\n }\n\n // Sort by order\n return seeds.sort((a, b) => a.order - b.order);\n }\n\n /**\n * Process dollar-quoted string delimiters ($$ or $tag$)\n */\n private processDollarDelimiters(\n line: string,\n inDollarBlock: boolean,\n dollarTag: string,\n ): { inDollarBlock: boolean; dollarTag: string } {\n const dollarMatch = line.match(/\\$([a-zA-Z_]*)\\$/g);\n if (!dollarMatch) return { inDollarBlock, dollarTag };\n\n let currentInBlock = inDollarBlock;\n let currentTag = dollarTag;\n\n for (const match of dollarMatch) {\n if (!currentInBlock) {\n currentInBlock = true;\n currentTag = match;\n } else if (match === currentTag) {\n currentInBlock = false;\n currentTag = \"\";\n }\n }\n\n return { inDollarBlock: currentInBlock, dollarTag: currentTag };\n }\n\n /**\n * Filter out comment-only statements\n */\n private isNonCommentStatement(statement: string): boolean {\n const withoutComments = statement.replace(/--.*$/gm, \"\").trim();\n return withoutComments.length > 0;\n }\n\n /**\n * Split SQL into individual statements for better error reporting\n */\n private splitSqlStatements(sql: string): string[] {\n const statements: string[] = [];\n let current = \"\";\n let inDollarBlock = false;\n let dollarTag = \"\";\n\n for (const line of sql.split(\"\\n\")) {\n const trimmedLine = line.trim();\n const isEmptyOrComment =\n trimmedLine === \"\" || trimmedLine.startsWith(\"--\");\n\n current += line + \"\\n\";\n if (isEmptyOrComment) continue;\n\n const dollarState = this.processDollarDelimiters(\n line,\n inDollarBlock,\n dollarTag,\n );\n inDollarBlock = dollarState.inDollarBlock;\n dollarTag = dollarState.dollarTag;\n\n if (!inDollarBlock && trimmedLine.endsWith(\";\") && current.trim()) {\n statements.push(current.trim());\n current = \"\";\n }\n }\n\n if (current.trim()) {\n statements.push(current.trim());\n }\n\n return statements.filter((s) => this.isNonCommentStatement(s));\n }\n\n /**\n * Extract a short description from a SQL statement for logging\n */\n private getStatementDescription(statement: string): string {\n const firstLine =\n statement\n .split(\"\\n\")\n .find((l) => l.trim() && !l.trim().startsWith(\"--\"))\n ?.trim() ?? \"\";\n\n const patterns = [\n /^(CREATE\\s+(?:OR\\s+REPLACE\\s+)?(?:TABLE|INDEX|UNIQUE\\s+INDEX|TYPE|FUNCTION|TRIGGER|EXTENSION|SCHEMA|VIEW|POLICY))\\s+(?:IF\\s+NOT\\s+EXISTS\\s+)?([^\\s(]+)/i,\n /^(ALTER\\s+TABLE)\\s+([^\\s]+)/i,\n /^(DROP\\s+(?:TABLE|INDEX|TYPE|FUNCTION|TRIGGER|EXTENSION|SCHEMA|VIEW|POLICY))\\s+(?:IF\\s+EXISTS\\s+)?([^\\s(;]+)/i,\n /^(INSERT\\s+INTO)\\s+([^\\s(]+)/i,\n /^(COMMENT\\s+ON\\s+(?:TABLE|COLUMN|INDEX|FUNCTION|TYPE))\\s+([^\\s]+)/i,\n /^(GRANT|REVOKE)\\s+.+\\s+ON\\s+([^\\s]+)/i,\n ];\n\n for (const pattern of patterns) {\n const match = firstLine.match(pattern);\n if (match) {\n return `${match[1]} ${match[2]}`.slice(0, DESCRIPTION_MAX_LENGTH);\n }\n }\n\n const truncated = firstLine.slice(0, FALLBACK_DESCRIPTION_LENGTH);\n const suffix = firstLine.length > FALLBACK_DESCRIPTION_LENGTH ? \"...\" : \"\";\n return truncated + suffix;\n }\n\n /**\n * Execute SQL statements individually with better error reporting\n */\n private async executeSqlStatements(\n sql: string,\n seedName: string,\n ): Promise<void> {\n const statements = this.splitSqlStatements(sql);\n const total = statements.length;\n\n console.log(` → ${total} statements to execute`);\n\n for (let i = 0; i < statements.length; i++) {\n const statement = statements[i];\n const description = this.getStatementDescription(statement);\n\n try {\n await this.adapter.query!(statement);\n const isInterval = (i + 1) % PROGRESS_LOG_INTERVAL === 0;\n const isLast = i === total - 1;\n const isSignificant = Boolean(description.match(/^(INSERT INTO)/i));\n if (isInterval || isLast || isSignificant) {\n console.log(` āœ“ [${i + 1}/${total}] ${description}`);\n }\n } catch (error) {\n console.log(` āœ— [${i + 1}/${total}] ${description}`);\n\n const rawMessage = (error as Error).message;\n const errorMessage = rawMessage\n .replace(/^SQL Error:\\s*/i, \"\")\n .replace(/^Failed to execute query:.*?-\\s*/i, \"\")\n .slice(0, ERROR_MESSAGE_MAX_LENGTH);\n\n throw new DatabaseError(\n `Seed \"${seedName}\" failed at statement ${i + 1}/${total}:\\n` +\n ` Statement: ${description}\\n` +\n ` Error: ${errorMessage}`,\n DATABASE_ERROR_CODES.QUERY_FAILED,\n { cause: error as Error },\n );\n }\n }\n }\n\n /**\n * Load SQL seed from file\n */\n private loadSqlSeed(seedFile: SeedFile): Seed {\n const sql = fs.readFileSync(seedFile.filePath, \"utf-8\");\n\n return {\n name: seedFile.name,\n run: async () => {\n if (typeof this.adapter.query === \"function\") {\n await this.executeSqlStatements(sql, seedFile.name);\n }\n },\n // SQL seeds don't have cleanup by default\n cleanup: undefined,\n };\n }\n\n /**\n * Load seed from file (supports .ts, .js, and .sql)\n */\n // eslint-disable-next-line complexity\n private async loadSeed(seedFile: SeedFile): Promise<Seed> {\n const ext = path.extname(seedFile.filePath);\n\n // Handle SQL seeds\n if (ext === \".sql\") {\n return this.loadSqlSeed(seedFile);\n }\n\n // Handle JS/TS seeds\n // Convert Windows paths to file:// URLs for ESM imports\n const importPath = seedFile.filePath.startsWith(\"/\")\n ? seedFile.filePath\n : new URL(`file:///${seedFile.filePath.replace(/\\\\/g, \"/\")}`).href;\n\n const seedModule = await import(importPath);\n return {\n name: seedFile.name,\n run:\n seedModule.run ??\n seedModule.default?.run ??\n seedModule.seed ??\n seedModule.default,\n cleanup: seedModule.cleanup ?? seedModule.default?.cleanup,\n };\n }\n\n /**\n * Get executed seeds from database\n */\n private async getExecutedSeeds(): Promise<SeedRecord[]> {\n try {\n if (typeof this.adapter.query === \"function\") {\n const result = await this.adapter.query<SeedRecord>(\n `SELECT * FROM ${this.tableName} ORDER BY run_at ASC`,\n );\n // Handle both array results and postgres-style { rows: [] } results\n return Array.isArray(result)\n ? result\n : (result as unknown as { rows: SeedRecord[] }).rows || [];\n }\n return [];\n } catch {\n // Table might not exist yet\n return [];\n }\n }\n\n /**\n * Record seed as executed\n */\n private async recordSeed(\n name: string,\n executionTime: number,\n filePath?: string,\n ): Promise<void> {\n if (typeof this.adapter.query === \"function\") {\n // Store relative path from seeds directory for portability\n const relativePath = filePath\n ? path.relative(this.seedsPath, filePath)\n : null;\n\n await this.adapter.query(\n `INSERT INTO ${this.tableName} (name, file_path, execution_time) VALUES ($1, $2, $3)\n ON CONFLICT (name) DO UPDATE SET run_at = CURRENT_TIMESTAMP, file_path = $2, execution_time = $3`,\n [name, relativePath, executionTime],\n );\n }\n }\n\n /**\n * Remove seed record (for reset)\n */\n private async unrecordSeed(name: string): Promise<void> {\n if (typeof this.adapter.query === \"function\") {\n await this.adapter.query(\n `DELETE FROM ${this.tableName} WHERE name = $1`,\n [name],\n );\n }\n }\n\n /**\n * Execute a seed function with optional transaction support\n */\n private async executeSeed(seed: Seed): Promise<void> {\n if (typeof this.adapter.transaction === \"function\") {\n const txResult = await this.adapter.transaction(async () => {\n await seed.run(this.adapter);\n });\n // Check transaction result - transaction() returns failure() instead of throwing\n if (!txResult.success) {\n throw (\n txResult.error ??\n new DatabaseError(\n `Seed ${seed.name} failed`,\n DATABASE_ERROR_CODES.QUERY_FAILED,\n )\n );\n }\n } else {\n await seed.run(this.adapter);\n }\n }\n\n /**\n * Check if a seed should be skipped and log if applicable\n */\n private shouldSkipSeed(\n seedFile: SeedFile,\n seedName: string | undefined,\n executedNames: Set<string>,\n ): boolean {\n if (seedName && seedFile.name !== seedName) return true;\n\n if (this.skipExisting && executedNames.has(seedFile.name)) {\n console.log(`[Seeds] Skipping ${seedFile.name} (already executed)`);\n return true;\n }\n\n return false;\n }\n\n /**\n * Run all seeds or a specific seed\n */\n async run(seedName?: string): Promise<DatabaseResult<number>> {\n try {\n await this.initialize();\n\n const allSeeds = await this.discoverSeeds();\n const executedSeeds = await this.getExecutedSeeds();\n const executedNames = new Set(executedSeeds.map((s) => s.name));\n\n let executed = 0;\n\n for (const seedFile of allSeeds) {\n if (this.shouldSkipSeed(seedFile, seedName, executedNames)) {\n continue;\n }\n\n console.log(`[Seeds] Running ${seedFile.name}...`);\n\n const seed = await this.loadSeed(seedFile);\n const startTime = Date.now();\n\n await this.executeSeed(seed);\n\n const executionTime = Date.now() - startTime;\n await this.recordSeed(seed.name, executionTime, seedFile.filePath);\n\n console.log(`[Seeds] Executed ${seed.name} in ${executionTime}ms`);\n executed++;\n\n if (seedName) break;\n }\n\n return success(executed);\n } catch (error) {\n return failure(\n new DatabaseError(\n `Seed execution failed: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.QUERY_FAILED,\n { cause: error as Error },\n ),\n );\n }\n }\n\n /**\n * Execute cleanup function with optional transaction support\n */\n private async executeCleanup(seed: Seed): Promise<void> {\n if (!seed.cleanup) return;\n\n if (typeof this.adapter.transaction === \"function\") {\n const txResult = await this.adapter.transaction(async () => {\n await seed.cleanup!(this.adapter);\n });\n // Check transaction result - transaction() returns failure() instead of throwing\n if (!txResult.success) {\n throw (\n txResult.error ??\n new DatabaseError(\n `Seed cleanup for ${seed.name} failed`,\n DATABASE_ERROR_CODES.QUERY_FAILED,\n )\n );\n }\n } else {\n await seed.cleanup(this.adapter);\n }\n }\n\n /**\n * Reset all seeds (run cleanup functions)\n */\n async reset(): Promise<DatabaseResult<number>> {\n try {\n const allSeeds = await this.discoverSeeds();\n let cleaned = 0;\n\n // Run cleanup in reverse order\n for (const seedFile of allSeeds.reverse()) {\n console.log(`[Seeds] Cleaning up ${seedFile.name}...`);\n\n const seed = await this.loadSeed(seedFile);\n\n if (!seed.cleanup) {\n console.warn(`[Seeds] No cleanup function for ${seed.name}`);\n continue;\n }\n\n const startTime = Date.now();\n await this.executeCleanup(seed);\n const executionTime = Date.now() - startTime;\n\n await this.unrecordSeed(seed.name);\n\n console.log(`[Seeds] Cleaned ${seed.name} in ${executionTime}ms`);\n cleaned++;\n }\n\n return success(cleaned);\n } catch (error) {\n return failure(\n new DatabaseError(\n `Seed cleanup failed: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.QUERY_FAILED,\n { cause: error as Error },\n ),\n );\n }\n }\n\n /**\n * Get seed execution status\n */\n async status(): Promise<\n DatabaseResult<{ executed: SeedRecord[]; pending: string[] }>\n > {\n try {\n await this.initialize();\n\n const allSeeds = await this.discoverSeeds();\n const executedSeeds = await this.getExecutedSeeds();\n const executedNames = new Set(executedSeeds.map((s) => s.name));\n\n const pending = allSeeds\n .filter((s) => !executedNames.has(s.name))\n .map((s) => s.name);\n\n return success({\n executed: executedSeeds,\n pending,\n });\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to get seed status: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.QUERY_FAILED,\n { cause: error as Error },\n ),\n );\n }\n }\n\n /**\n * Clear seed history (doesn't clean data, just removes tracking records)\n */\n async clearHistory(): Promise<DatabaseResult<void>> {\n try {\n if (typeof this.adapter.query === \"function\") {\n await this.adapter.query(`DELETE FROM ${this.tableName}`);\n }\n return success();\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to clear seed history: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.QUERY_FAILED,\n { cause: error as Error },\n ),\n );\n }\n }\n}\n","/**\n * @fileoverview Type Guard Utilities for @plyaz/db package\n *\n * This module provides type guard functions for runtime type checking throughout\n * the @plyaz/db package. These utilities replace direct typeof checks with\n * consistent, reusable type validation functions.\n *\n */\n\n/**\n * Type guard to check if a value is a string\n *\n * @param {unknown} value - The value to check\n * @returns {value is string} True if value is a string, false otherwise\n *\n * @example\n * ```typescript\n * import { isString } from '@plyaz/db/utils';\n *\n * if (isString(userInput)) {\n * // userInput is now typed as string\n * console.log(userInput.toLowerCase());\n * }\n * ```\n */\nexport function isString(value: unknown): value is string {\n return typeof value === \"string\";\n}\n\n/**\n * Type guard to check if a value is a non-empty string\n *\n * @param {unknown} value - The value to check\n * @returns {value is string} True if value is a non-empty string, false otherwise\n *\n * @example\n * ```typescript\n * import { isNonEmptyString } from '@plyaz/db/utils';\n *\n * if (isNonEmptyString(tableName)) {\n * // tableName is guaranteed to be a non-empty string\n * const query = `SELECT * FROM ${tableName}`;\n * }\n * ```\n */\nexport function isNonEmptyString(value: unknown): value is string {\n return isString(value) && value.length > 0;\n}\n\n/**\n * Type guard to check if a value is a number\n *\n * @param {unknown} value - The value to check\n * @returns {value is number} True if value is a number, false otherwise\n */\nexport function isNumber(value: unknown): value is number {\n return typeof value === \"number\";\n}\n\n/**\n * Type guard to check if a value is an object (not null, not array)\n *\n * @param {unknown} value - The value to check\n * @returns {value is object} True if value is an object, false otherwise\n */\nexport function isObject(value: unknown): value is object {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n","/**\n * @fileoverview DatabaseEventEmitter - Event management for database operations\n *\n * Provides a comprehensive event system for monitoring and reacting to database\n * operations. The DatabaseEventEmitter implements the Observer pattern to enable\n * decoupled monitoring of database activities, allowing multiple components to\n * subscribe to and react to various database events.\n *\n * **Application Flow Context:**\n * ```\n * Database Operations → DatabaseEventEmitter → Event Handlers\n * ↓ ↓ ↓\n * Query Execution → Event Emission → Logging\n * Transaction → Handler Dispatch → Monitoring\n * Health Changes → Error Handling → Alerting\n * ```\n *\n * **Supported Events:**\n * - **BeforeQuery**: Emitted before database queries\n * - **AfterQuery**: Emitted after successful queries\n * - **QueryError**: Emitted when queries fail\n * - **BeforeTransaction**: Emitted before transactions start\n * - **AfterTransaction**: Emitted after transactions complete\n * - **TransactionRollback**: Emitted when transactions rollback\n * - **HealthChange**: Emitted when database health status changes\n *\n * @example\n * ```typescript\n * // Event emitter setup\n * const eventEmitter = new DatabaseEventEmitter('drizzle');\n *\n * // Subscribe to query events\n * eventEmitter.on('BeforeQuery', (event) => {\n * console.log(`Executing ${event.operation} on ${event.table}`);\n * });\n *\n * eventEmitter.on('QueryError', (event) => {\n * console.error(`Query failed: ${event.error.message}`);\n * });\n *\n * // Emit events during database operations\n * eventEmitter.emitBeforeQuery('users', 'SELECT', { id: '123' });\n * ```\n *\n */\n\nimport type {\n AfterQueryEvent,\n AfterTransactionEvent,\n BeforeQueryEvent,\n BeforeTransactionEvent,\n DatabaseEvent,\n DatabaseOperationType,\n DBEventHandler,\n HealthChangeEvent,\n QueryErrorEvent,\n TransactionRollbackEvent,\n} from \"@plyaz/types\";\nimport type {\n EmitQueryErrorOptions,\n DatabaseExecutionContext,\n} from \"@plyaz/types/db\";\nimport { DATABASE_EVENT_TYPE } from \"@plyaz/types\";\nimport type { ADAPTERS } from \"@plyaz/types\";\nimport { logger } from \"@plyaz/logger\";\nimport { isString, isObject } from \"@utils/typeGuards\";\nimport { DatabaseError } from \"@plyaz/errors\";\nimport { DATABASE_ERROR_CODES } from \"@plyaz/types/errors\";\n\n/**\n * Event emitter for database events that implements the observer pattern.\n * This class manages event subscriptions and emissions for various database operations,\n * allowing decoupled monitoring of database activities.\n *\n * @class\n * @implements {DatabaseEventEmitter}\n */\nexport class DatabaseEventEmitter implements DatabaseEventEmitter {\n private readonly eventHandlers: Map<string, DBEventHandler<DatabaseEvent>[]> =\n new Map();\n\n constructor(private readonly adapter: ADAPTERS) {\n if (!adapter) {\n throw new DatabaseError(\n \"Database adapter is required for event emitter\",\n DATABASE_ERROR_CODES.CONFIG_REQUIRED,\n {\n context: { source: \"DatabaseEventEmitter.constructor\" },\n cause: new Error(\"Database adapter is required for event emitter\"),\n },\n );\n }\n }\n\n /**\n * Register an event handler for a specific event type\n */\n on<T extends DatabaseEvent>(\n eventType: T[\"type\"],\n handler: DBEventHandler<T>,\n ): void {\n try {\n if (!isString(eventType)) {\n throw new DatabaseError(\n \"Invalid event type\",\n DATABASE_ERROR_CODES.INVALID_PARAMETERS,\n {\n context: { source: \"on\" },\n cause: new Error(\"Invalid event type\"),\n },\n );\n }\n\n if (!handler || typeof handler !== \"function\") {\n throw new DatabaseError(\n \"Invalid event handler\",\n DATABASE_ERROR_CODES.INVALID_PARAMETERS,\n {\n context: { source: \"on\" },\n cause: new Error(\"Invalid event handler\"),\n },\n );\n }\n\n if (!this.eventHandlers.has(eventType)) {\n this.eventHandlers.set(eventType, []);\n }\n\n const handlers = this.eventHandlers.get(eventType);\n if (handlers) {\n handlers.push(handler as DBEventHandler<DatabaseEvent>);\n }\n } catch (error) {\n logger.error(\n `Failed to register event handler: ${(error as Error).message}`,\n );\n }\n }\n\n /**\n * Remove an event handler for a specific event type\n */\n off<T extends DatabaseEvent>(\n eventType: T[\"type\"],\n handler: DBEventHandler<T>,\n ): void {\n const handlers = this.eventHandlers.get(eventType);\n if (handlers) {\n const index = handlers.indexOf(handler as DBEventHandler<DatabaseEvent>);\n if (index !== -1) handlers.splice(index, 1);\n }\n }\n\n /**\n * Emit an event to all registered handlers\n */\n emit(event: DatabaseEvent): void {\n try {\n if (!isObject(event) || !event.type) {\n logger.error(\"Invalid event object\");\n return;\n }\n\n const handlers = this.eventHandlers.get(event.type as string);\n if (!handlers || handlers.length === 0) return;\n\n handlers.forEach((handler) => {\n try {\n const result = handler(event);\n if (result instanceof Promise) {\n result.catch((error) => {\n logger.error(\n `Async event handler error: ${(error as Error).message}`,\n );\n });\n }\n } catch (error) {\n logger.error(`Event handler error: ${(error as Error).message}`);\n }\n });\n } catch (error) {\n logger.error(`Failed to emit event: ${(error as Error).message}`);\n }\n }\n\n /**\n * Emit a before query event\n */\n emitBeforeQuery(\n table: string,\n operation: DatabaseOperationType,\n params?: Record<string, object>,\n context?: DatabaseExecutionContext,\n ): void {\n const event: BeforeQueryEvent = {\n type: DATABASE_EVENT_TYPE.BeforeQuery,\n timestamp: new Date(),\n adapter: this.adapter.toString(),\n table,\n operation,\n params,\n context,\n };\n this.emit(event);\n }\n\n /**\n * Emit an after query event\n */\n emitAfterQuery(\n table: string,\n operation: DatabaseOperationType,\n duration: number,\n affectedRows?: number,\n ): void {\n const event: AfterQueryEvent = {\n type: DATABASE_EVENT_TYPE.AfterQuery,\n timestamp: new Date(),\n adapter: this.adapter.toString(),\n table,\n operation,\n duration,\n affectedRows,\n };\n this.emit(event);\n }\n\n emitQueryError(options: EmitQueryErrorOptions): void {\n try {\n if (!isObject(options)) {\n logger.error(\"Invalid options for emitQueryError\");\n return;\n }\n\n const { table, operation, error, params, context } = options;\n\n if (!table || !operation || !error) {\n logger.error(\"Missing required fields for query error event\");\n return;\n }\n\n const event: QueryErrorEvent = {\n type: DATABASE_EVENT_TYPE.QueryError,\n timestamp: new Date(),\n adapter: this.adapter.toString(),\n table,\n operation,\n error,\n params,\n context,\n };\n\n this.emit(event);\n } catch (emitError) {\n logger.error(\n `Failed to emit query error event: ${(emitError as Error).message}`,\n );\n }\n }\n\n /**\n * Emit a before transaction event\n */\n emitBeforeTransaction(\n transactionId: string,\n context?: DatabaseExecutionContext,\n ): void {\n const event: BeforeTransactionEvent = {\n type: DATABASE_EVENT_TYPE.BeforeTransaction,\n timestamp: new Date(),\n adapter: this.adapter.toString(),\n transactionId,\n context,\n };\n this.emit(event);\n }\n\n /**\n * Emit an after transaction event\n */\n emitAfterTransaction(transactionId: string, duration: number): void {\n const event: AfterTransactionEvent = {\n type: DATABASE_EVENT_TYPE.AfterTransaction,\n timestamp: new Date(),\n adapter: this.adapter.toString(),\n transactionId,\n duration,\n };\n this.emit(event);\n }\n\n /**\n * Emit a transaction rollback event\n */\n emitTransactionRollback(transactionId: string, error?: Error): void {\n const event: TransactionRollbackEvent = {\n type: DATABASE_EVENT_TYPE.TransactionRollback,\n timestamp: new Date(),\n adapter: this.adapter.toString(),\n transactionId,\n error,\n };\n this.emit(event);\n }\n\n /**\n * Emit a health change event\n */\n emitHealthChange(\n previousStatus: boolean,\n currentStatus: boolean,\n details?: Record<string, string | number | boolean>,\n ): void {\n const event: HealthChangeEvent = {\n type: DATABASE_EVENT_TYPE.HealthChange,\n timestamp: new Date(),\n adapter: this.adapter.toString(),\n previousStatus,\n currentStatus,\n details,\n };\n this.emit(event as DatabaseEvent);\n }\n}\n","/**\n * @fileoverview Detail Normalization Utilities for @plyaz/db package\n *\n * This module provides utilities for normalizing various data types into consistent\n * string-based record formats. Used throughout the @plyaz/db package for standardizing\n * error details, health status information, and event metadata.\n *\n * Part of the @plyaz/db package - a TypeScript database abstraction layer with\n * support for multiple adapters (Drizzle, Supabase, SQL), extensions (audit, encryption,\n * soft delete), and advanced features (caching, read replicas, multi-tenancy).\n *\n */\n\nimport { isObject } from \"./typeGuards\";\n\n/**\n * Normalizes any input into a standardized Record<string, string> format\n *\n * Converts various data types into a consistent string-based record format\n * for use in error details, health status information, and event metadata.\n * Provides safe handling of different input types with fallback strategies.\n *\n * **Normalization Rules:**\n * - Objects: Converts all property values to strings while preserving keys\n * - Primitives: Wraps in { info: stringValue } format\n * - null/undefined: Returns undefined (no details)\n * - Arrays: Converts to { info: stringified array }\n * - Errors: Safely handles conversion failures\n *\n * **Used by:**\n * - HealthManager for health status details\n * - DatabaseEventEmitter for event metadata\n * - Error handling throughout adapter chain\n * - Audit logging for consistent detail formatting\n *\n * @param {unknown} details - Input details of any type to normalize\n * @returns {Record<string, string> | undefined} Normalized details as string record or undefined\n *\n * @example\n * ```typescript\n * import { normalizeDetails } from '@plyaz/db/utils';\n *\n * // Object normalization\n * const objDetails = normalizeDetails({\n * count: 42,\n * active: true,\n * name: 'test'\n * });\n * console.log(objDetails);\n * // { count: \"42\", active: \"true\", name: \"test\" }\n *\n * // Primitive normalization\n * const stringDetails = normalizeDetails(\"Connection timeout\");\n * console.log(stringDetails);\n * // { info: \"Connection timeout\" }\n *\n * // Number normalization\n * const numberDetails = normalizeDetails(404);\n * console.log(numberDetails);\n * // { info: \"404\" }\n *\n * // Null/undefined handling\n * const nullDetails = normalizeDetails(null);\n * console.log(nullDetails);\n * // undefined\n *\n * // Array normalization\n * const arrayDetails = normalizeDetails(['error1', 'error2']);\n * console.log(arrayDetails);\n * // { info: \"error1,error2\" }\n *\n * // Error object normalization\n * const errorDetails = normalizeDetails(new Error('Database error'));\n * console.log(errorDetails);\n * // { info: \"Error: Database error\" }\n * ```\n *\n * @example\n * ### Usage in Health Status\n * ```typescript\n * // In HealthManager.checkHealth()\n * const healthStatus = {\n * isHealthy: true,\n * responseTime: 150,\n * details: normalizeDetails({\n * adapter: 'drizzle',\n * connections: 5,\n * lastQuery: new Date()\n * })\n * };\n * // details: { adapter: \"drizzle\", connections: \"5\", lastQuery: \"2024-01-01T10:00:00.000Z\" }\n * ```\n *\n * @example\n * ### Usage in Error Handling\n * ```typescript\n * // In adapter error handling\n * catch (error) {\n * return failure(new DatabaseError(\n * 'QUERY_FAILED',\n * HTTP_STATUS.INTERNAL_SERVER_ERROR,\n * 'Query execution failed',\n * normalizeDetails({\n * query: sql,\n * params: queryParams,\n * originalError: error.message\n * })\n * ));\n * }\n * ```\n *\n */\nexport function normalizeDetails(\n details: unknown,\n): Record<string, string> | undefined {\n try {\n // Handle null, undefined, or falsy values\n // Return undefined to indicate no details available\n if (!details) return undefined;\n\n // Handle object types (but not arrays)\n // Convert all object property values to strings while preserving keys\n if (isObject(details)) {\n const mapped: Record<string, string> = {};\n\n // Iterate through object entries and convert values to strings\n for (const [key, value] of Object.entries(details)) {\n // Use String() for safe conversion of any value type\n mapped[key] = String(value);\n }\n return mapped;\n }\n\n // Handle primitives, arrays, and other non-object types\n // Wrap in standardized { info: value } format\n return { info: String(details) };\n } catch (error) {\n // Fallback error handling for extreme cases\n // Return error information if normalization fails\n return {\n error: \"Failed to normalize details\",\n reason: (error as Error).message,\n };\n }\n}\n","/**\n * @fileoverview Health Manager for @plyaz/db package\n *\n * This module provides the HealthManager class responsible for monitoring database\n * connection health, performing periodic health checks, and managing the lifecycle\n * of database connections. It provides a centralized way to track database status.\n *\n * Part of the @plyaz/db package - a TypeScript database abstraction layer with\n * support for multiple adapters (Drizzle, Supabase, SQL), extensions (audit, encryption,\n * soft delete), and advanced features (caching, read replicas, multi-tenancy).\n *\n */\n\nimport type {\n DatabaseAdapterType,\n DatabaseHealthStatus,\n DatabaseResult,\n HealthManagerConfig,\n} from \"@plyaz/types/db\";\nimport { success, failure } from \"@utils/databaseResultHelpers\";\nimport { normalizeDetails } from \"@utils/normalizeDetails\";\nimport { DatabaseError } from \"@plyaz/errors\";\nimport { DATABASE_ERROR_CODES } from \"@plyaz/types/errors\";\n\n/** Default number of consecutive failures before triggering failover */\nconst DEFAULT_FAILOVER_THRESHOLD = 3;\n\n/**\n * šŸŒ”ļø HEALTH MANAGER - Database Health Monitoring\n *\n * Manages database health checks and monitoring functionality for all database adapters.\n * This class is responsible for performing health checks on the database connection,\n * storing the last known health status, and providing methods to quickly check\n * the current health state of the database.\n *\n * **Application Flow Position:**\n * DatabaseService → **HealthManager** → Adapter.healthCheck() → Database\n *\n * **What this class does:**\n * 1. Initializes database connections on startup\n * 2. Performs periodic health checks via adapter.healthCheck()\n * 3. Caches last known health status for quick access\n * 4. Normalizes health details across different adapters\n * 5. Manages connection lifecycle (connect/disconnect)\n *\n * **Called by:** DatabaseService.healthCheck(), application health endpoints\n * **Calls:** DatabaseAdapter.healthCheck(), DatabaseAdapter.connect/disconnect\n * **Used for:** Application health monitoring, load balancer health checks\n *\n * @example\n * ```typescript\n * // Create health manager with adapter\n * const healthManager = new HealthManager(drizzleAdapter);\n *\n * // Initialize connection and perform initial health check\n * await healthManager.init();\n *\n * // Perform health check\n * const healthResult = await healthManager.checkHealth();\n * if (healthResult.success) {\n * console.log('Database is healthy:', healthResult.value);\n * }\n *\n * // Quick health status check (uses cached result)\n * const isHealthy = healthManager.isHealthy();\n *\n * // Get last known status without new check\n * const lastStatus = healthManager.getLastHealthStatus();\n *\n * // Cleanup on shutdown\n * await healthManager.shutdown();\n * ```\n *\n */\nexport class HealthManager {\n private lastHealthStatus: DatabaseHealthStatus | null = null;\n private initialized = false;\n private currentAdapter: DatabaseAdapterType;\n private primaryAdapter: DatabaseAdapterType;\n private backupAdapters: DatabaseAdapterType[];\n private consecutiveFailures = 0;\n private healthCheckInterval?: number;\n private failoverThreshold: number;\n private autoFailover: boolean;\n private healthCheckTimer?: globalThis.NodeJS.Timeout;\n\n constructor(config: DatabaseAdapterType | HealthManagerConfig) {\n // Support both old (single adapter) and new (config) constructors\n if (\"primary\" in config) {\n this.primaryAdapter = config.primary;\n this.currentAdapter = config.primary;\n this.backupAdapters = config.backups ?? [];\n this.healthCheckInterval = config.healthCheckInterval;\n this.failoverThreshold =\n config.failoverThreshold ?? DEFAULT_FAILOVER_THRESHOLD;\n this.autoFailover = config.autoFailover ?? false;\n } else {\n this.primaryAdapter = config;\n this.currentAdapter = config;\n this.backupAdapters = [];\n this.failoverThreshold = DEFAULT_FAILOVER_THRESHOLD;\n this.autoFailover = false;\n }\n }\n\n /**\n * Initializes the health manager by establishing database connection and performing initial health check\n *\n * Sets up the database connection and performs an initial health check to establish\n * baseline health status. This method should be called during application startup\n * to ensure the database is ready for operations.\n *\n * **Initialization Process:**\n * 1. Checks if already initialized (prevents double initialization)\n * 2. Calls adapter.connect() if available (establishes connection)\n * 3. Performs initial health check via checkHealth()\n * 4. Sets initialized flag to prevent re-initialization\n *\n * @returns {Promise<void>} Promise that resolves when initialization is complete\n *\n * @example\n * ```typescript\n * const healthManager = new HealthManager(adapter);\n *\n * // Initialize during application startup\n * await healthManager.init();\n * console.log('Health manager initialized');\n *\n * // Subsequent calls are no-ops\n * await healthManager.init(); // Does nothing, already initialized\n * ```\n *\n */\n async init(): Promise<void> {\n // Prevent double initialization\n if (this.initialized) return;\n\n // Establish database connection if adapter supports it\n if (typeof this.currentAdapter.initialize === \"function\") {\n await this.currentAdapter.initialize();\n }\n\n // Perform initial health check to establish baseline status\n await this.checkHealth();\n this.initialized = true;\n\n // Start periodic health checks if configured\n if (this.healthCheckInterval && this.healthCheckInterval > 0) {\n this.startPeriodicHealthChecks();\n }\n }\n\n /**\n * Performs a comprehensive health check on the database connection\n *\n * Executes a health check via the database adapter and normalizes the results\n * into a standardized health status format. Measures response time and handles\n * both successful and failed health checks gracefully.\n *\n * **Health Check Process:**\n * 1. Records start time for response time measurement\n * 2. Calls adapter.healthCheck() to test database connectivity\n * 3. Normalizes adapter-specific response into standard format\n * 4. Caches result as lastHealthStatus for quick access\n * 5. Returns standardized DatabaseResult with health information\n *\n * **Health Status Fields:**\n * - isHealthy: Boolean indicating if database is operational\n * - responseTime: Time in milliseconds for health check to complete\n * - details: Normalized adapter-specific details (connection info, errors, etc.)\n *\n * @returns {Promise<DatabaseResult<DatabaseHealthStatus>>} Promise resolving to health status result\n *\n * @example\n * ```typescript\n * // Perform health check\n * const healthResult = await healthManager.checkHealth();\n *\n * if (healthResult.success) {\n * const status = healthResult.value;\n * console.log(`Database healthy: ${status.isHealthy}`);\n * console.log(`Response time: ${status.responseTime}ms`);\n * console.log('Details:', status.details);\n * } else {\n * console.error('Health check failed:', healthResult.error.message);\n * }\n *\n * // Example healthy response:\n * // {\n * // success: true,\n * // value: {\n * // isHealthy: true,\n * // responseTime: 45,\n * // details: { adapter: \"drizzle\", connections: \"5\" }\n * // }\n * // }\n *\n * // Example unhealthy response:\n * // {\n * // success: true,\n * // value: {\n * // isHealthy: false,\n * // responseTime: 5000,\n * // details: { error: \"Connection timeout\" }\n * // }\n * // }\n * ```\n *\n */\n /**\n * Handle health check result and update internal state\n */\n private async handleHealthResult(isSuccess: boolean): Promise<void> {\n if (isSuccess) {\n this.consecutiveFailures = 0;\n return;\n }\n\n this.consecutiveFailures++;\n if (\n this.autoFailover &&\n this.consecutiveFailures >= this.failoverThreshold\n ) {\n await this.performFailover();\n }\n }\n\n /**\n * Create health status from check result\n */\n private createHealthStatus(\n result: DatabaseResult<DatabaseHealthStatus>,\n responseTime: number,\n ): DatabaseHealthStatus {\n return {\n isHealthy: result.success,\n responseTime,\n details: result.success\n ? normalizeDetails(result.value)\n : { error: result.error?.message ?? \"Unknown error\" },\n };\n }\n\n async checkHealth(): Promise<DatabaseResult<DatabaseHealthStatus>> {\n const startTime = Date.now();\n\n try {\n const result = await this.currentAdapter.healthCheck();\n const responseTime = Date.now() - startTime;\n\n const status = this.createHealthStatus(result, responseTime);\n this.lastHealthStatus = status;\n\n await this.handleHealthResult(result.success);\n\n return success(status);\n } catch (error) {\n const status: DatabaseHealthStatus = {\n isHealthy: false,\n responseTime: Date.now() - startTime,\n details: { error: (error as Error).message },\n };\n\n this.lastHealthStatus = status;\n await this.handleHealthResult(false);\n\n return failure(\n new DatabaseError(\n `Health check failed: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.FETCH_FAILED,\n {\n context: { source: \"checkHealth\" },\n cause: error as Error,\n },\n ),\n );\n }\n }\n /**\n * Get the last known health status\n */\n getLastHealthStatus(): DatabaseHealthStatus | null {\n return this.lastHealthStatus;\n }\n\n /**\n * Check if the database is currently healthy\n */\n isHealthy(): boolean {\n return this.lastHealthStatus?.isHealthy ?? false;\n }\n\n /**\n * Get the current active adapter\n */\n getCurrentAdapter(): DatabaseAdapterType {\n return this.currentAdapter;\n }\n\n /**\n * Try to initialize and verify health of a backup adapter\n */\n private async tryBackupAdapter(\n backup: DatabaseAdapterType,\n ): Promise<boolean> {\n if (typeof backup.initialize === \"function\") {\n const initResult = await backup.initialize();\n if (!initResult.success) return false;\n }\n\n const healthResult = await backup.healthCheck();\n return healthResult.success && (healthResult.value?.isHealthy ?? false);\n }\n\n /**\n * Switch to a healthy backup adapter\n */\n private async switchToBackup(backup: DatabaseAdapterType): Promise<void> {\n await this.currentAdapter.close();\n this.currentAdapter = backup;\n this.consecutiveFailures = 0;\n console.log(\"[HealthManager] Failover successful to backup adapter\");\n }\n\n /**\n * Perform failover to next available backup adapter\n */\n private async performFailover(): Promise<void> {\n if (this.backupAdapters.length === 0) {\n console.warn(\"[HealthManager] No backup adapters available for failover\");\n return;\n }\n\n for (const backup of this.backupAdapters) {\n try {\n const isHealthy = await this.tryBackupAdapter(backup);\n if (isHealthy) {\n await this.switchToBackup(backup);\n return;\n }\n } catch (error) {\n console.error(\n \"[HealthManager] Backup adapter health check failed:\",\n error,\n );\n }\n }\n\n console.error(\n \"[HealthManager] All backup adapters failed, staying with current adapter\",\n );\n }\n\n /**\n * Start periodic health checks\n */\n private startPeriodicHealthChecks(): void {\n if (this.healthCheckTimer) return;\n\n this.healthCheckTimer = setInterval(async () => {\n await this.checkHealth();\n }, this.healthCheckInterval);\n }\n\n /**\n * Stop periodic health checks\n */\n private stopPeriodicHealthChecks(): void {\n if (this.healthCheckTimer) {\n clearInterval(this.healthCheckTimer);\n this.healthCheckTimer = undefined;\n }\n }\n\n /**\n * Gracefully shut down the health manager\n */\n async shutdown(): Promise<void> {\n this.stopPeriodicHealthChecks();\n\n await this.currentAdapter.close();\n\n this.initialized = false;\n this.lastHealthStatus = null;\n }\n}\n","/**\n * @fileoverview Configuration Merger for @plyaz/db package\n *\n * This module provides the ConfigMerger utility class responsible for deep merging\n * database configurations. It handles merging global database service configuration\n * with per-operation overrides to create resolved configurations for the adapter chain.\n *\n * Part of the @plyaz/db package - a TypeScript database abstraction layer with\n * support for multiple adapters (Drizzle, Supabase, SQL), extensions (audit, encryption,\n * soft delete), and advanced features (caching, read replicas, multi-tenancy).\n */\n\nimport { NUMERIX } from \"@plyaz/config\";\nimport type {\n DatabaseServiceConfig,\n DBCacheConfig,\n DBEncryptionConfig,\n OperationConfig,\n ResolvedOperationConfig,\n SoftDeleteConfig,\n TimestampsConfig,\n} from \"@plyaz/types/db\";\n\n/**\n * CONFIG MERGER - Configuration Resolution Engine\n *\n * Utility class for deep merging database configurations.\n * Handles merging global database service configuration with per-operation overrides\n *\n * Application Flow Position:**\n * DatabaseService → **ConfigMerger** → Resolved Config → Adapter Chain\n *\n * **What this class does:**\n * 1. Receives global config (from createDatabaseService) and operation config (from method calls)\n * 2. Deep merges nested objects (encryption, softDelete, cache, etc.)\n * 3. Operation config takes precedence over global config\n * 4. Returns resolved configuration for adapter chain\n *\n * **Called by:** DatabaseService methods (get, create, update, delete, etc.)\n * **Calls:** Internal merge methods for each config section\n * **Returns to:** DatabaseService for delegation to adapter chain\n *\n * **Merge Strategy:**\n * - Operation config overrides global config\n * - Nested objects are deep merged (not replaced)\n * - Arrays use replace strategy for fields, concat for others\n * - Undefined values in operation config fall back to global defaults\n *\n * @example\n * ### Configuration Merging Flow\n * ```typescript\n * // Global config (from createDatabaseService)\n * const globalConfig = {\n * softDelete: { enabled: true, field: 'deletedAt' },\n * cache: { enabled: true, ttl: 300 }\n * };\n *\n * // Operation config (from method call)\n * const operationConfig = {\n * cache: { enabled: false },\n * includeSoftDeleted: true\n * };\n *\n * // ConfigMerger.mergeConfigs() produces:\n * const resolved = {\n * softDelete: { enabled: true, field: 'deletedAt' }, // From global\n * cache: { enabled: false, ttl: 300 }, // Merged\n * includeSoftDeleted: true, // From operation\n * skipAudit: false // Default\n * };\n * ```\n */\nexport class ConfigMerger {\n /**\n * Merges global database configuration with operation-specific overrides\n *\n * This is the main entry point for configuration resolution in the DatabaseService.\n * It performs deep merging of nested configuration objects while preserving type safety\n * and applying proper precedence rules.\n *\n * **Merge Precedence (highest to lowest):**\n * 1. Operation-specific config (method-level overrides)\n * 2. Global service config (from createDatabaseService)\n * 3. Default values (built-in fallbacks)\n *\n * **Configuration Sections Merged:**\n * - softDelete: Logical deletion settings\n * - encryption: Field-level encryption settings\n * - cache: Caching behavior and TTL\n * - timestamps: Automatic timestamp management\n * - Operation flags: skipAudit, includeSoftDeleted, etc.\n *\n * @param {DatabaseServiceConfig} global - Global database service configuration from createDatabaseService()\n * @param {OperationConfig} [operation] - Optional operation-specific configuration overrides\n * @returns {ResolvedOperationConfig} Fully resolved configuration with all defaults applied\n *\n * @example\n * ```typescript\n * // In DatabaseService.get() method\n * const resolvedConfig = ConfigMerger.mergeConfigs(\n * this.globalConfig, // From createDatabaseService\n * operationConfig // From method parameter\n * );\n *\n * // Example global config\n * const globalConfig = {\n * softDelete: { enabled: true, field: 'deletedAt' },\n * encryption: { enabled: true, fields: { users: ['ssn'] } },\n * cache: { enabled: true, ttl: 300 }\n * };\n *\n * // Example operation config (disable cache for this operation)\n * const operationConfig = {\n * cache: { enabled: false },\n * skipAudit: true\n * };\n *\n * // Resulting merged config\n * const result = {\n * softDelete: { enabled: true, field: 'deletedAt' }, // From global\n * encryption: { enabled: true, fields: { users: ['ssn'] } }, // From global\n * cache: { enabled: false, ttl: 300 }, // Merged (enabled overridden)\n * timestamps: undefined, // Not specified\n * skipAudit: true, // From operation\n * includeSoftDeleted: false, // Default\n * forceAdapter: undefined, // Not specified\n * timeout: 30000 // Default\n * };\n * ```\n *\n */\n static mergeConfigs(\n global: DatabaseServiceConfig,\n operation?: OperationConfig,\n ): ResolvedOperationConfig {\n if (!operation) {\n return this.convertGlobalToResolved(global);\n }\n\n return {\n softDelete: this.mergeSoftDeleteConfig(\n global.softDelete,\n operation.softDelete,\n ),\n encryption: this.mergeEncryptionConfig(\n global.encryption,\n operation.encryption,\n ),\n cache: this.mergeCacheConfig(global.cache, operation.cache),\n timestamps: this.mergeTimestampsConfig(\n global.timestamps,\n operation.timestamps,\n ),\n skipAudit: operation.skipAudit ?? false,\n includeSoftDeleted: operation.includeSoftDeleted ?? false,\n forceAdapter: operation.forceAdapter,\n timeout: operation.timeout ?? NUMERIX.THIRTY_THOUSAND,\n };\n }\n\n /**\n * Merges soft delete configuration with operation-specific overrides\n *\n * Handles deep merging of soft delete settings, allowing operation-level\n * overrides while preserving base configuration values.\n *\n * @private\n * @param {SoftDeleteConfig} [base] - Base soft delete configuration from global config\n * @param {Partial<SoftDeleteConfig>} [override] - Operation-specific soft delete overrides\n * @returns {SoftDeleteConfig | undefined} Merged soft delete configuration or undefined if neither provided\n *\n * @example\n * ```typescript\n * // Base config: { enabled: true, field: 'deletedAt', excludeTables: ['logs'] }\n * // Override: { enabled: false }\n * // Result: { enabled: false, field: 'deletedAt', excludeTables: ['logs'] }\n * ```\n *\n */\n private static mergeSoftDeleteConfig(\n base?: SoftDeleteConfig,\n override?: Partial<SoftDeleteConfig>,\n ): SoftDeleteConfig | undefined {\n // Return undefined if neither base nor override provided\n if (!base && !override) return undefined;\n // Return base config if no override provided\n if (!override) return base;\n // Return override as complete config if no base provided\n if (!base) return override as SoftDeleteConfig;\n\n // Deep merge: override takes precedence, base provides fallbacks\n return {\n enabled: override.enabled ?? base.enabled,\n field: override.field ?? base.field,\n excludeTables: override.excludeTables ?? base.excludeTables,\n };\n }\n\n /**\n * Merges encryption configuration with operation-specific overrides\n *\n * Handles deep merging of field-level encryption settings, allowing operation-level\n * overrides for encryption behavior while preserving base configuration.\n *\n * @private\n * @param {DBEncryptionConfig} [base] - Base encryption configuration from global config\n * @param {Partial<DBEncryptionConfig>} [override] - Operation-specific encryption overrides\n * @returns {DBEncryptionConfig | undefined} Merged encryption configuration or undefined if neither provided\n *\n * @example\n * ```typescript\n * // Base config: { enabled: true, key: 'base64key', fields: { users: ['ssn'] } }\n * // Override: { enabled: false }\n * // Result: { enabled: false, key: 'base64key', fields: { users: ['ssn'] } }\n * ```\n *\n */\n // eslint-disable-next-line complexity\n private static mergeEncryptionConfig(\n base?: DBEncryptionConfig,\n override?: Partial<DBEncryptionConfig>,\n ): DBEncryptionConfig | undefined {\n // Return undefined if neither base nor override provided\n if (!base && !override) return undefined;\n // Return base config if no override provided\n if (!override) return base;\n // Return override as complete config if no base provided\n if (!base) return override as DBEncryptionConfig;\n\n // Deep merge: override takes precedence, base provides fallbacks\n return {\n enabled: override.enabled ?? base.enabled,\n key: override.key ?? base.key,\n fields: override.fields ?? base.fields,\n algorithm: override.algorithm ?? base.algorithm,\n useDatabaseNative: override.useDatabaseNative ?? base.useDatabaseNative,\n };\n }\n\n /**\n * Merges cache configuration with operation-specific overrides\n * \n * Handles deep merging of caching settings, allowing operation-level\n * overrides for cache behavior (enable/disable, TTL changes, etc.).\n * \n * @private\n * @param {DBCacheConfig} [base] - Base cache configuration from global config\n * @param {Partial<DBCacheConfig>} [override] - Operation-specific cache overrides\n * @returns {DBCacheConfig | undefined} Merged cache configuration or undefined if neither provided\n * \n * @example\n * ```typescript\n * // Base config: { enabled: true, ttl: 300, provider: 'redis' }\n * // Override: { enabled: false }\n * // Result: { enabled: false, ttl: 300, provider: 'redis' }\n * ```\n * \n\n */\n // eslint-disable-next-line complexity\n private static mergeCacheConfig(\n base?: DBCacheConfig,\n override?: Partial<DBCacheConfig>,\n ): DBCacheConfig | undefined {\n // Return undefined if neither base nor override provided\n if (!base && !override) return undefined;\n // Return base config if no override provided\n if (!override) return base;\n // Return override as complete config if no base provided\n if (!base) return override as DBCacheConfig;\n\n // Deep merge: override takes precedence, base provides fallbacks\n return {\n enabled: override.enabled ?? base.enabled,\n ttl: override.ttl ?? base.ttl,\n provider: override.provider ?? base.provider,\n invalidation: override.invalidation ?? base.invalidation,\n };\n }\n\n /**\n * Merges timestamps configuration with operation-specific overrides\n *\n * Handles deep merging of automatic timestamp settings, allowing operation-level\n * overrides for timestamp field names and auto-update behavior.\n *\n * @private\n * @param {TimestampsConfig} [base] - Base timestamps configuration from global config\n * @param {Partial<TimestampsConfig>} [override] - Operation-specific timestamp overrides\n * @returns {TimestampsConfig | undefined} Merged timestamps configuration or undefined if neither provided\n *\n * @example\n * ```typescript\n * // Base config: { enabled: true, createdAtField: 'createdAt', updatedAtField: 'updatedAt' }\n * // Override: { autoUpdate: false }\n * // Result: { enabled: true, createdAtField: 'createdAt', updatedAtField: 'updatedAt', autoUpdate: false }\n * ```\n */\n // eslint-disable-next-line complexity\n private static mergeTimestampsConfig(\n base?: TimestampsConfig,\n override?: Partial<TimestampsConfig>,\n ): TimestampsConfig | undefined {\n // Return undefined if neither base nor override provided\n if (!base && !override) return undefined;\n // Return base config if no override provided\n if (!override) return base;\n // Return override as complete config if no base provided\n if (!base) return override as TimestampsConfig;\n\n // Deep merge: override takes precedence, base provides fallbacks\n return {\n enabled: override.enabled ?? base.enabled,\n createdAtField: override.createdAtField ?? base.createdAtField,\n updatedAtField: override.updatedAtField ?? base.updatedAtField,\n autoUpdate: override.autoUpdate ?? base.autoUpdate,\n };\n }\n\n /**\n * Converts global database service configuration to resolved operation configuration\n *\n * Used when no operation-specific overrides are provided. Applies default values\n * for operation-specific flags while preserving global configuration settings.\n *\n * @private\n * @param {DatabaseServiceConfig} global - Global database service configuration\n * @returns {ResolvedOperationConfig} Resolved configuration with defaults applied\n *\n * @example\n * ```typescript\n * // Global config: { softDelete: { enabled: true }, cache: { enabled: true, ttl: 300 } }\n * // Result: {\n * // softDelete: { enabled: true },\n * // cache: { enabled: true, ttl: 300 },\n * // skipAudit: false, // Default\n * // includeSoftDeleted: false, // Default\n * // timeout: 30000 // Default\n * // }\n * ```\n *\n */\n private static convertGlobalToResolved(\n global: DatabaseServiceConfig,\n ): ResolvedOperationConfig {\n return {\n // Preserve global configuration sections as-is\n softDelete: global?.softDelete,\n encryption: global?.encryption,\n cache: global?.cache,\n timestamps: global?.timestamps,\n // Apply default values for operation-specific flags\n skipAudit: false, // Default: enable audit logging\n includeSoftDeleted: false, // Default: exclude soft-deleted records\n timeout: NUMERIX.THIRTY_THOUSAND, // Default: 30 second timeout\n };\n }\n}\n","/**\n * @fileoverview Internal Database Service Implementation for @plyaz/db package\n *\n * This module provides the internal DatabaseService class that orchestrates all database\n * operations. It is NOT exported and is created internally by the createDatabaseService() factory.\n *\n * Part of the @plyaz/db package - a TypeScript database abstraction layer with\n * support for multiple adapters (Drizzle, Supabase, SQL), extensions (audit, encryption,\n * soft delete), and advanced features (caching, read replicas, multi-tenancy).\n *\n */\n\nimport { DatabaseEventEmitter } from \"./EventEmitter\";\nimport { HealthManager } from \"./HealthManager\";\nimport { ConfigMerger } from \"@utils/ConfigMerger\";\nimport { DatabaseError } from \"@plyaz/errors\";\nimport { DATABASE_ERROR_CODES } from \"@plyaz/types/errors\";\nimport type {\n AuditContext,\n BatchUpdate,\n CreateInput,\n DatabaseAdapterType,\n DatabaseEvent,\n DatabaseEvents,\n DatabaseHealthStatus,\n DatabaseResult,\n DatabaseServiceConfig,\n DatabaseServiceInterface,\n Filter,\n OperationConfig,\n PaginatedResult,\n QueryOptions,\n ServiceStatus,\n TableName,\n TransactionFn,\n UpdateInput,\n} from \"@plyaz/types/db\";\nimport { ADAPTERS } from \"@plyaz/types/db\";\nimport { failure, success } from \"@utils/databaseResultHelpers\";\n\n/**\n * šŸ› ļø DATABASE SERVICE - Internal Service Layer\n *\n * Core service implementation that orchestrates all database operations.\n * NOT EXPORTED - created internally by createDatabaseService() factory.\n *\n * **Application Flow Position:**\n * createDatabaseService() → **DatabaseService** → Adapter Chain → Database\n *\n * **What this class does:**\n * 1. Stores global configuration from createDatabaseService()\n * 2. Receives calls from repositories via IDatabaseService interface\n * 3. Merges per-operation config with global config using ConfigMerger\n * 4. Fires before/after events (onBeforeWrite, onAfterWrite, etc.)\n * 5. Delegates to adapter chain with resolved configuration\n * 6. Returns results back to repositories\n *\n * **Called by:** Repository layer (BaseRepository, UserRepository, etc.)\n * **Calls:** ConfigMerger.mergeConfigs(), adapter chain methods, event handlers\n * **Delegates to:** Final wrapped adapter (ReadReplicaAdapter → AuditAdapter → ... → BaseAdapter)\n *\n * **Key Responsibilities:**\n * - Configuration merging and resolution\n * - Event system orchestration\n * - Audit context management\n * - Error handling and propagation\n * - Service status tracking\n *\n * @internal This class is not part of the public API\n */\nexport class DatabaseService implements DatabaseServiceInterface {\n private readonly globalConfig: DatabaseServiceConfig;\n public readonly adapter: DatabaseAdapterType;\n private readonly eventHandlers: DatabaseEvents | undefined;\n private readonly eventEmitter: DatabaseEventEmitter;\n private readonly healthManager: HealthManager;\n private readonly startTime: Date;\n private auditContext: AuditContext = {};\n\n constructor(config: {\n adapter: DatabaseAdapterType;\n globalConfig: DatabaseServiceConfig;\n eventHandlers?: DatabaseEvents;\n }) {\n this.globalConfig = config.globalConfig;\n this.adapter = config.adapter;\n this.eventHandlers = config.eventHandlers;\n this.startTime = new Date();\n\n const adapterType =\n (config.adapter?.constructor?.name?.toLowerCase() as ADAPTERS) ??\n ADAPTERS.SQL;\n this.eventEmitter = new DatabaseEventEmitter(adapterType);\n this.healthManager = new HealthManager(config.adapter);\n\n console.log(`DatabaseService initialized with ${adapterType} adapter`);\n }\n\n /**\n * šŸ”§ Prepare table name and configuration for operation\n *\n * Handles per-operation overrides for:\n * 1. Schema - prepends schema to table name (e.g., \"audit.logs\")\n * 2. ID Column - temporarily registers table with custom ID column\n *\n * Priority order:\n * - Operation config (highest) - per-query override\n * - TABLE_REGISTRY - global registration\n * - Default (lowest) - 'id' column, 'public' schema\n *\n * @param table Base table name\n * @param operationConfig Optional operation configuration with idColumn/schema\n * @returns Final table name to use (with schema prefix if applicable)\n *\n * @example\n * ```typescript\n * // With schema override\n * const tableName = this.prepareTable('logs', { schema: 'audit' });\n * // Returns: 'audit.logs'\n *\n * // With ID column override\n * const tableName = this.prepareTable('feature_flags', { idColumn: 'key' });\n * // Registers table with 'key' as ID column, returns: 'feature_flags'\n *\n * // With both\n * const tableName = this.prepareTable('users', { schema: 'backoffice', idColumn: 'user_id' });\n * // Returns: 'backoffice.users' with 'user_id' as ID column\n * ```\n */\n private prepareTable(\n table: TableName,\n operationConfig?: OperationConfig,\n ): string {\n let finalTableName = table;\n\n // Handle schema override\n if (operationConfig?.schema) {\n // If table already has schema prefix, replace it\n const tableWithoutSchema = table.includes(\".\")\n ? table.split(\".\")[1]\n : table;\n finalTableName = `${operationConfig.schema}.${tableWithoutSchema}`;\n }\n\n // Handle custom ID column override\n if (operationConfig?.idColumn) {\n // Temporarily register the table with the custom ID column\n // This allows the adapter to use the correct ID column for this operation\n this.adapter.registerTable(\n finalTableName,\n finalTableName,\n operationConfig.idColumn,\n );\n }\n\n return finalTableName;\n }\n\n /**\n * šŸ” Get a single record by ID\n *\n * **Flow:** Repository.findById() → **DatabaseService.get()** → ConfigMerger → Adapter Chain → Database\n *\n * **What happens:**\n * 1. Merges operation config with global config using ConfigMerger\n * 2. Fires onBeforeRead event (if configured)\n * 3. Delegates to adapter chain: ReadReplica → Audit → Cache → SoftDelete → Encryption → Base\n * 4. Fires onAfterRead event on success\n * 5. Returns result to repository\n *\n * **Called by:** BaseRepository.findById(), custom repository methods\n * **Calls:** ConfigMerger.mergeConfigs(), this.adapter.findById(), event handlers\n *\n * @param table Table name (from Tables enum)\n * @param id Record ID to retrieve\n * @param operationConfig Optional per-operation configuration overrides\n * @returns Promise resolving to the record or null if not found\n *\n * @example\n * ```typescript\n * // Called by UserRepository.findById()\n * const user = await this.db.get(Tables.USERS, 'user-123');\n *\n * // With operation config override\n * const user = await this.db.get(Tables.USERS, 'user-123', {\n * forceAdapter: 'primary', // Force primary DB\n * cache: { enabled: false } // Skip cache\n * });\n *\n * // With custom ID column (per-query override)\n * const flag = await this.db.get('feature_flags', 'my-flag-key', {\n * idColumn: 'key' // Use 'key' instead of 'id' as primary key\n * });\n *\n * // With custom schema\n * const auditLog = await this.db.get('logs', '123', {\n * schema: 'audit' // Query from audit.logs table\n * });\n *\n * // Combining multiple overrides\n * const backofficeUser = await this.db.get('users', 'admin-456', {\n * schema: 'backoffice',\n * idColumn: 'user_id',\n * forceAdapter: 'primary'\n * });\n * ```\n */\n async get<T extends Record<string, unknown>>(\n table: TableName,\n id: string,\n operationConfig?: OperationConfig,\n ): Promise<DatabaseResult<T | null>> {\n // Merge configs - operation config takes precedence\n ConfigMerger.mergeConfigs(this.globalConfig, operationConfig);\n\n // Prepare table with schema and ID column overrides\n const finalTable = this.prepareTable(table, operationConfig);\n\n try {\n // Fire before-read event if configured\n if (this.eventHandlers?.onBeforeRead) {\n await this.eventHandlers.onBeforeRead({\n type: \"beforeRead\",\n operation: \"READ\",\n table,\n timestamp: new Date(),\n });\n }\n\n // Delegate to adapter with resolved config\n const result = await this.adapter.findById<T>(finalTable, id);\n\n // Fire after-read event if configured and successful\n if (result.success && this.eventHandlers?.onAfterRead) {\n await this.eventHandlers.onAfterRead({\n type: \"afterRead\",\n operation: \"READ\",\n table,\n result: (result.value ?? {}) as Record<\n string,\n string | number | boolean | Date\n >,\n duration: 0, // TODO: Track duration\n timestamp: new Date(),\n });\n }\n\n return result;\n } catch (error) {\n return failure(\n new DatabaseError(\n `Get operation failed: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.QUERY_FAILED,\n {\n context: { source: \"get\" },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * List records with optional filtering, sorting, and pagination\n * Merges operation config with global config before delegating\n */\n async list<T extends Record<string, unknown>>(\n table: TableName,\n options?: QueryOptions<T>,\n operationConfig?: OperationConfig,\n ): Promise<DatabaseResult<PaginatedResult<T>>> {\n ConfigMerger.mergeConfigs(this.globalConfig, operationConfig);\n\n if (this.eventHandlers?.onBeforeRead) {\n await this.eventHandlers.onBeforeRead({\n type: \"beforeRead\",\n operation: \"READ\",\n table,\n timestamp: new Date(),\n });\n }\n\n const result = await this.adapter.findMany<T>(table, options);\n\n if (result.success && this.eventHandlers?.onAfterRead) {\n await this.eventHandlers.onAfterRead({\n type: \"afterRead\",\n operation: \"READ\",\n table,\n result: (result.value ?? {}) as Record<\n string,\n string | number | boolean | Date\n >,\n duration: 0,\n timestamp: new Date(),\n });\n }\n\n return result;\n }\n\n /**\n * Create a new record\n * Merges operation config with global config before delegating\n */\n async create<T extends Record<string, unknown>>(\n table: TableName,\n input: CreateInput<T>,\n operationConfig?: OperationConfig,\n ): Promise<DatabaseResult<T>> {\n ConfigMerger.mergeConfigs(this.globalConfig, operationConfig);\n\n // Prepare table with schema and ID column overrides\n const finalTable = this.prepareTable(table, operationConfig);\n\n if (this.eventHandlers?.onBeforeWrite) {\n await this.eventHandlers.onBeforeWrite({\n type: \"beforeWrite\",\n operation: \"CREATE\",\n table,\n data: input as Record<string, string | number | boolean | Date>,\n timestamp: new Date(),\n });\n }\n\n const result = await this.adapter.create<T>(finalTable, input as T);\n\n if (result.success && this.eventHandlers?.onAfterWrite) {\n await this.eventHandlers.onAfterWrite({\n type: \"afterWrite\",\n operation: \"CREATE\",\n table,\n result: result.value as Record<\n string,\n string | number | boolean | Date\n >,\n duration: 0,\n timestamp: new Date(),\n });\n }\n\n return result;\n }\n\n /**\n * Update an existing record\n * Merges operation config with global config before delegating\n */\n async update<T extends Record<string, unknown>>(\n table: TableName,\n id: string,\n input: UpdateInput<T>,\n operationConfig?: OperationConfig,\n ): Promise<DatabaseResult<T>> {\n ConfigMerger.mergeConfigs(this.globalConfig, operationConfig);\n\n // Prepare table with schema and ID column overrides\n const finalTable = this.prepareTable(table, operationConfig);\n\n if (this.eventHandlers?.onBeforeWrite) {\n await this.eventHandlers.onBeforeWrite({\n type: \"beforeWrite\",\n operation: \"UPDATE\",\n table,\n data: input as Record<string, string | number | boolean | Date>,\n timestamp: new Date(),\n });\n }\n\n const result = await this.adapter.update<T>(\n finalTable,\n id,\n input as Partial<T>,\n );\n\n if (result.success && this.eventHandlers?.onAfterWrite) {\n await this.eventHandlers.onAfterWrite({\n type: \"afterWrite\",\n operation: \"UPDATE\",\n table,\n result: result.value as Record<\n string,\n string | number | boolean | Date\n >,\n duration: 0,\n timestamp: new Date(),\n });\n }\n\n return result;\n }\n\n /**\n * Delete a record\n * Merges operation config with global config before delegating\n */\n async delete(\n table: TableName,\n id: string,\n operationConfig?: OperationConfig,\n ): Promise<DatabaseResult<void>> {\n ConfigMerger.mergeConfigs(this.globalConfig, operationConfig);\n\n // Prepare table with schema and ID column overrides\n const finalTable = this.prepareTable(table, operationConfig);\n\n if (this.eventHandlers?.onBeforeWrite) {\n await this.eventHandlers.onBeforeWrite({\n type: \"beforeWrite\",\n operation: \"DELETE\",\n table,\n data: { id },\n timestamp: new Date(),\n });\n }\n\n const result = await this.adapter.delete(finalTable, id);\n\n if (result.success && this.eventHandlers?.onAfterWrite) {\n await this.eventHandlers.onAfterWrite({\n type: \"afterWrite\",\n operation: \"DELETE\",\n table,\n result: {},\n duration: 0,\n timestamp: new Date(),\n });\n }\n\n return result;\n }\n\n // Batch Operations\n async batchCreate<T extends Record<string, unknown>>(\n table: TableName,\n inputs: CreateInput<T>[],\n operationConfig?: OperationConfig,\n ): Promise<DatabaseResult<T[]>> {\n // TODO: Implement batch operations\n const results: T[] = [];\n for (const input of inputs) {\n const result = await this.create<T>(table, input, operationConfig);\n if (result.success && result.value) {\n results.push(result.value);\n } else {\n return failure(\n result.error ??\n new DatabaseError(\n \"Batch create failed\",\n DATABASE_ERROR_CODES.CREATE_FAILED,\n {\n context: { source: \"batchCreate\" },\n cause: new Error(\"Batch create failed\"),\n },\n ),\n );\n }\n }\n return success(results);\n }\n\n async batchUpdate<T extends Record<string, unknown>>(\n table: TableName,\n updates: BatchUpdate<T>[],\n operationConfig?: OperationConfig,\n ): Promise<DatabaseResult<T[]>> {\n const results: T[] = [];\n for (const update of updates) {\n const result = await this.update<T>(\n table,\n update.id,\n update.data,\n operationConfig,\n );\n if (result.success && result.value) {\n results.push(result.value);\n } else {\n return failure(\n result.error ??\n new DatabaseError(\n \"Batch update failed\",\n DATABASE_ERROR_CODES.UPDATE_FAILED,\n {\n context: { source: \"batchUpdate\" },\n cause: new Error(\"Batch update failed\"),\n },\n ),\n );\n }\n }\n return success(results);\n }\n\n async batchDelete(\n table: TableName,\n ids: string[],\n operationConfig?: OperationConfig,\n ): Promise<DatabaseResult<void>> {\n for (const id of ids) {\n const result = await this.delete(table, id, operationConfig);\n if (!result.success) {\n return failure(\n result.error ??\n new DatabaseError(\n \"Batch delete failed\",\n DATABASE_ERROR_CODES.DELETE_FAILED,\n {\n context: { source: \"batchDelete\" },\n cause: new Error(\"Batch delete failed\"),\n },\n ),\n );\n }\n }\n return success();\n }\n\n // Query Operations\n async query<T extends Record<string, unknown>>(\n table: TableName,\n query: QueryOptions<T>,\n operationConfig?: OperationConfig,\n ): Promise<DatabaseResult<PaginatedResult<T>>> {\n return this.list<T>(table, query, operationConfig);\n }\n\n async count<T extends Record<string, unknown> = Record<string, unknown>>(\n table: TableName,\n filter?: Filter<T>,\n operationConfig?: OperationConfig,\n ): Promise<DatabaseResult<number>> {\n ConfigMerger.mergeConfigs(this.globalConfig, operationConfig);\n return this.adapter.count(table, filter);\n }\n\n // Transactions\n async transaction<T>(fn: TransactionFn<T>): Promise<DatabaseResult<T>> {\n return this.adapter.transaction(fn);\n }\n\n // Audit Context\n async setAuditContext(context: AuditContext): Promise<DatabaseResult<void>> {\n this.auditContext = { ...this.auditContext, ...context };\n return success();\n }\n\n // Event System\n on<T extends DatabaseEvent[\"type\"]>(\n event: T,\n handler: (\n event: Extract<DatabaseEvent, { type: T }>,\n ) => void | Promise<void>,\n ): void {\n this.eventEmitter.on(event, handler);\n }\n\n off<T extends DatabaseEvent[\"type\"]>(\n event: T,\n handler: (\n event: Extract<DatabaseEvent, { type: T }>,\n ) => void | Promise<void>,\n ): void {\n this.eventEmitter.off(event, handler);\n }\n\n // Health & Status\n async healthCheck(): Promise<DatabaseResult<DatabaseHealthStatus>> {\n return this.healthManager.checkHealth();\n }\n\n getStatus(): ServiceStatus {\n const uptime = Date.now() - this.startTime.getTime();\n return {\n isHealthy: true, // TODO: Get actual health status\n adapter: this.adapter.constructor.name,\n uptime,\n lastHealthCheck: new Date(),\n };\n }\n\n // Legacy methods for backward compatibility\n async findById<T extends Record<string, unknown>>(\n table: string,\n id: string,\n ): Promise<DatabaseResult<T | null>> {\n return this.get<T>(table, id);\n }\n\n async findMany<T extends Record<string, unknown>>(\n table: string,\n options?: QueryOptions<T>,\n ): Promise<DatabaseResult<PaginatedResult<T>>> {\n return this.list<T>(table, options);\n }\n\n async initialize(): Promise<DatabaseResult<void>> {\n return success();\n }\n\n /**\n * Registers a table with the underlying adapter.\n *\n * @param name - Logical table name (e.g., 'users')\n * @param table - Physical table name or Drizzle table object\n * @param idColumn - ID column name (defaults to 'id')\n *\n * @example SQL Adapter\n * ```typescript\n * db.registerTable('users', 'users', 'id');\n * db.registerTable('feature_flags', 'feature_flags', 'key');\n * ```\n *\n * @example Drizzle Adapter (requires PgTable objects)\n * ```typescript\n * db.registerTable('users', usersTable, usersTable.id);\n * ```\n */\n registerTable<TTable = string, TIdColumn = string>(\n name: string,\n table?: TTable,\n idColumn?: TIdColumn,\n ): void {\n // Delegate to the adapter's registerTable method\n if (this.adapter && typeof this.adapter.registerTable === \"function\") {\n // For SQL adapter: if table is not provided, use name as table name\n const tableValue = table ?? name;\n this.adapter.registerTable(name, tableValue, idColumn);\n }\n }\n\n async exists(table: string, id: string): Promise<DatabaseResult<boolean>> {\n const result = await this.get(table, id);\n return success(result.success && result.value !== null);\n }\n\n private async fireBeforeReadEvent(table: TableName): Promise<void> {\n if (this.eventHandlers?.onBeforeRead) {\n await this.eventHandlers.onBeforeRead({\n type: \"beforeRead\",\n operation: \"READ\",\n table,\n timestamp: new Date(),\n });\n }\n }\n\n private async fireAfterReadEvent<T>(\n table: TableName,\n record: T | null,\n ): Promise<void> {\n if (this.eventHandlers?.onAfterRead) {\n await this.eventHandlers.onAfterRead({\n type: \"afterRead\",\n operation: \"READ\",\n table,\n result:\n (record as Record<string, string | number | boolean | Date>) ?? {},\n duration: 0,\n timestamp: new Date(),\n });\n }\n }\n\n async findOne<T extends Record<string, unknown>>(\n table: TableName,\n filter: Filter<T>,\n operationConfig?: OperationConfig,\n ): Promise<DatabaseResult<T | null>> {\n ConfigMerger.mergeConfigs(this.globalConfig, operationConfig);\n\n try {\n await this.fireBeforeReadEvent(table);\n\n const result = await this.adapter.findMany<T>(table, {\n filter,\n pagination: { limit: 1, offset: 0 },\n });\n\n if (!result.success) {\n return { success: false, error: result.error };\n }\n\n const firstRecord = result.value?.data[0] ?? null;\n await this.fireAfterReadEvent(table, firstRecord);\n\n return { success: true, value: firstRecord };\n } catch (error) {\n return failure(\n new DatabaseError(\n `Find one operation failed: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.QUERY_FAILED,\n {\n context: { source: \"findOne\" },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n async softDelete(\n table: TableName,\n id: string,\n operationConfig?: OperationConfig,\n ): Promise<DatabaseResult<void>> {\n ConfigMerger.mergeConfigs(this.globalConfig, {\n ...operationConfig,\n softDelete: { enabled: true },\n });\n\n try {\n if (this.eventHandlers?.onBeforeWrite) {\n await this.eventHandlers.onBeforeWrite({\n type: \"beforeWrite\",\n operation: \"DELETE\",\n table,\n data: { id, softDelete: true },\n timestamp: new Date(),\n });\n }\n\n const result = await this.adapter.delete(table, id);\n\n if (result.success && this.eventHandlers?.onAfterWrite) {\n await this.eventHandlers.onAfterWrite({\n type: \"afterWrite\",\n operation: \"DELETE\",\n table,\n result: { softDeleted: true },\n duration: 0,\n timestamp: new Date(),\n });\n }\n\n return result;\n } catch (error) {\n return failure(\n new DatabaseError(\n `Soft delete operation failed: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.DELETE_FAILED,\n {\n context: { source: \"softDelete\" },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n get events(): DatabaseEventEmitter {\n return this.eventEmitter;\n }\n\n /**\n * šŸ”Œ Close the database connection\n *\n * Gracefully shuts down the database connection and releases all resources.\n * Should be called when the service is no longer needed.\n *\n * @returns Promise resolving to DatabaseResult indicating success or failure\n */\n async close(): Promise<DatabaseResult<void>> {\n try {\n if (this.adapter.close) {\n return await this.adapter.close();\n }\n return success();\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to close database connection: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.DISCONNECT_FAILED,\n {\n context: { source: \"close\" },\n cause: error as Error,\n },\n ),\n );\n }\n }\n}\n","/**\n * @fileoverview Pagination Utilities for @plyaz/db package\n *\n * This module provides pagination calculation utilities used across all database adapters\n * to generate consistent pagination metadata for query results. Supports offset-based\n * pagination with page calculation and validation.\n *\n * Part of the @plyaz/db package - a TypeScript database abstraction layer with\n * support for multiple adapters (Drizzle, Supabase, SQL), extensions (audit, encryption,\n * soft delete), and advanced features (caching, read replicas, multi-tenancy).\n *\n * @module pagination\n */\n\nimport type { PaginationInfo, PaginationOptions } from \"@plyaz/types\";\nimport { isNumber } from \"./typeGuards\";\nimport { DatabaseError } from \"@plyaz/errors\";\nimport { DATABASE_ERROR_CODES } from \"@plyaz/types/errors\";\n\n/**\n * Validates pagination input parameters for safety and consistency\n *\n * Performs comprehensive validation of pagination parameters to prevent invalid\n * calculations and ensure consistent behavior across all database adapters.\n *\n * **Validation Rules:**\n * - Total must be a non-negative number (>= 0)\n * - Limit must be a positive number (> 0) if provided\n * - Offset must be a non-negative number (>= 0)\n *\n * @private\n * @param {number} total - Total number of items in the dataset\n * @param {number} [limit] - Optional maximum number of items per page\n * @param {number} [offset] - Optional number of items to skip (default: 0)\n * @throws {Error} If any parameter fails validation\n *\n * @example\n * ```typescript\n * // Valid inputs\n * validatePaginationInputs(100, 20, 0); // āœ“ Valid\n * validatePaginationInputs(0, 10, 0); // āœ“ Valid (empty dataset)\n * validatePaginationInputs(50); // āœ“ Valid (no pagination)\n *\n * // Invalid inputs\n * validatePaginationInputs(-1, 10, 0); // āœ— Throws: negative total\n * validatePaginationInputs(100, 0, 0); // āœ— Throws: zero limit\n * validatePaginationInputs(100, 10, -5); // āœ— Throws: negative offset\n * ```\n *\n */\nfunction validatePaginationInputs(\n total: number,\n limit?: number,\n offset?: number,\n): void {\n // Total count validation\n // Must be non-negative to represent valid dataset size\n if (!isNumber(total) || total < 0) {\n throw new DatabaseError(\n \"Total must be a non-negative number\",\n DATABASE_ERROR_CODES.INVALID_PARAMETERS,\n {\n context: { source: \"validatePaginationInputs\" },\n cause: new Error(\"Total must be a non-negative number\"),\n },\n );\n }\n\n // Limit validation (if provided)\n // Must be positive to create meaningful pages\n if (limit !== undefined && (!isNumber(limit) || limit <= 0)) {\n throw new DatabaseError(\n \"Limit must be a positive number\",\n DATABASE_ERROR_CODES.INVALID_PARAMETERS,\n {\n context: { source: \"validatePaginationInputs\" },\n cause: new Error(\"Limit must be a positive number\"),\n },\n );\n }\n\n // Offset validation\n // Must be non-negative to represent valid starting position\n if (!isNumber(offset) || offset < 0) {\n throw new DatabaseError(\n \"Offset must be a non-negative number\",\n DATABASE_ERROR_CODES.INVALID_PARAMETERS,\n {\n context: { source: \"validatePaginationInputs\" },\n cause: new Error(\"Offset must be a non-negative number\"),\n },\n );\n }\n}\n\n/**\n * Calculates comprehensive pagination metadata for database query results\n *\n * Generates pagination information used by all database adapters to provide\n * consistent pagination metadata in query results. Supports both paginated\n * and non-paginated queries with automatic page calculation.\n *\n * **Used by:**\n * - DrizzleAdapter.findMany() for ORM-based pagination\n * - SupabaseAdapter.findMany() for Supabase pagination\n * - SQLAdapter.findMany() for raw SQL pagination\n * - All repository methods that return paginated results\n *\n * **Calculation Logic:**\n * - Page numbers are 1-based (first page = 1)\n * - Current page = floor(offset / limit) + 1\n * - Total pages = ceil(total / limit)\n * - Handles edge cases (no limit, empty results, etc.)\n *\n * @param {number} total - Total number of items matching the query\n * @param {PaginationOptions} [options] - Optional pagination configuration\n * @param {number} [options.limit] - Maximum items per page\n * @param {number} [options.offset] - Number of items to skip (default: 0)\n * @returns {PaginationInfo} Complete pagination metadata object\n *\n * @example\n * ```typescript\n * import { calculatePagination } from '@plyaz/db/utils';\n *\n * // Standard pagination (page 2 of 20 items per page)\n * const pagination1 = calculatePagination(100, { limit: 20, offset: 20 });\n * console.log(pagination1);\n * // {\n * // page: 2,\n * // limit: 20,\n * // offset: 20,\n * // totalPages: 5\n * // }\n *\n * // First page\n * const pagination2 = calculatePagination(100, { limit: 20, offset: 0 });\n * console.log(pagination2);\n * // {\n * // page: 1,\n * // limit: 20,\n * // offset: 0,\n * // totalPages: 5\n * // }\n *\n * // No pagination (return all results)\n * const pagination3 = calculatePagination(100);\n * console.log(pagination3);\n * // {\n * // page: undefined,\n * // limit: undefined,\n * // offset: 0,\n * // totalPages: undefined\n * // }\n * ```\n *\n */\nexport function calculatePagination(\n total: number,\n options?: PaginationOptions,\n): PaginationInfo {\n const limit = options?.limit;\n const offset = options?.offset ?? 0;\n\n // Validate all inputs before calculation\n validatePaginationInputs(total, limit, offset);\n\n // Calculate current page (1-based indexing)\n // Only calculate if limit is provided and positive\n // Formula: floor(offset / limit) + 1\n // Example: offset=20, limit=10 → floor(20/10) + 1 = 3 (page 3)\n const page = limit && limit > 0 ? Math.floor(offset / limit) + 1 : undefined;\n\n // Calculate total number of pages\n // Only calculate if limit is provided and positive\n // Formula: ceil(total / limit)\n // Example: total=95, limit=10 → ceil(95/10) = 10 pages\n const totalPages = limit && limit > 0 ? Math.ceil(total / limit) : undefined;\n\n return {\n page,\n limit,\n offset,\n totalPages,\n };\n}\n","/**\n * @fileoverview Centralized Regex Patterns for @plyaz/db package\n *\n * This module contains all regex patterns used throughout the database package.\n * Centralizing regex patterns improves maintainability, reusability, and consistency.\n *\n * Part of the @plyaz/db package - a TypeScript database abstraction layer with\n * support for multiple adapters (Drizzle, Supabase, SQL), extensions (audit, encryption,\n * soft delete), and advanced features (caching, read replicas, multi-tenancy).\n *\n */\n\n/**\n * Database field and table name validation patterns\n * Used for SQL injection prevention and database identifier validation\n */\nexport const DATABASE_PATTERNS = {\n /**\n * Validates database field names (columns)\n * - Must start with letter (a-z, A-Z) or underscore (_)\n * - Can contain letters, numbers, and underscores\n * - Prevents SQL injection through field names\n *\n * Used in: validation.ts, sql.ts, DrizzleAdapter.ts, SQLAdapter.ts\n */\n FIELD_NAME: /^[a-zA-Z_][a-zA-Z0-9_]*$/,\n\n /**\n * Validates database table names\n * - Same rules as field names for consistency\n * - Follows SQL identifier naming conventions\n *\n * Used in: validation.ts, CacheEvict.decorator.ts\n */\n TABLE_NAME: /^[a-zA-Z_][a-zA-Z0-9_]*$/,\n} as const;\n\n/**\n * Cache key validation patterns\n * Used for validating cache keys and patterns in caching system\n */\nexport const CACHE_PATTERNS = {\n /**\n * Validates cache keys\n * - Allows letters, numbers, colons, underscores, and hyphens\n * - Used for Redis cache key validation\n *\n * Used in: CacheEvict.decorator.ts\n */\n CACHE_KEY: /^[a-zA-Z0-9:_-]+$/,\n\n /**\n * Validates cache patterns (with wildcards)\n * - Same as cache key but allows asterisk (*) for wildcards\n * - Used for cache pattern matching and eviction\n *\n * Used in: CacheEvict.decorator.ts\n */\n CACHE_PATTERN: /^[a-zA-Z0-9:_*-]+$/,\n} as const;\n\n/**\n * SQL query sanitization patterns\n * Used for cleaning and normalizing SQL queries for metrics and logging\n */\nexport const SQL_PATTERNS = {\n /**\n * Matches PostgreSQL parameter placeholders ($1, $2, etc.)\n * - Used to normalize parameterized queries for metrics\n *\n * Used in: MetricsCollector.ts\n */\n POSTGRES_PARAMS: /\\$\\d+/g,\n\n /**\n * Matches numeric values in SQL queries\n * - Used to replace numbers with placeholders for query normalization\n *\n * Used in: MetricsCollector.ts\n */\n NUMERIC_VALUES: /\\d+/g,\n\n /**\n * Matches string literals in SQL queries (single quotes)\n * - Used to replace string values with placeholders\n *\n * Used in: MetricsCollector.ts\n */\n STRING_LITERALS: /'[^']*'/g,\n} as const;\n\n/**\n * Input sanitization patterns\n * Used for cleaning user input and preventing injection attacks\n */\nexport const SANITIZATION_PATTERNS = {\n /**\n * Matches dangerous characters for SQL injection prevention\n * - Null byte, backspace, tab, newline, carriage return\n * - Single and double quotes, backslashes, percent signs\n *\n * Used in: validation.ts (sanitizeInput function)\n */\n DANGEROUS_CHARS: /[\\0\\b\\t\\n\\r\"'\\\\%]/g,\n\n /**\n * Matches shell metacharacters for command injection prevention\n * - Semicolon, ampersand, pipe, backtick, dollar, parentheses, etc.\n *\n * Used in: BackupService.ts (sanitizeCommand function)\n */\n SHELL_METACHARACTERS: /[;&|`$(){}[\\]<>\"'\\\\]/g,\n\n /**\n * Matches multiple whitespace characters\n * - Used to normalize whitespace in sanitized input\n *\n * Used in: BackupService.ts\n */\n MULTIPLE_WHITESPACE: /\\s+/g,\n\n /**\n * Matches line breaks and tabs\n * - Used to replace line breaks with spaces\n *\n * Used in: BackupService.ts\n */\n LINE_BREAKS_TABS: /[\\r\\n\\t]/g,\n\n /**\n * Matches Unicode control characters\n * - Uses Unicode property escape to match all control characters\n *\n * Used in: BackupService.ts\n */\n CONTROL_CHARACTERS: /[\\p{Cc}]/gu,\n} as const;\n\n/**\n * File and path patterns\n * Used for file operations and path validation\n */\nexport const FILE_PATTERNS = {\n /**\n * Matches colon and dot characters in timestamps\n * - Used to create filesystem-safe timestamps\n *\n * Used in: BackupService.ts (timestamp generation)\n */\n TIMESTAMP_CHARS: /[:.]/g,\n} as const;\n\n/**\n * Utility functions for common regex operations\n */\nexport const DB_REGEX = {\n /**\n * Tests if a string matches the database field name pattern\n * @param fieldName - The field name to validate\n * @returns True if valid database field name\n */\n isValidFieldName: (fieldName: string): boolean => {\n return DATABASE_PATTERNS.FIELD_NAME.test(fieldName);\n },\n\n /**\n * Tests if a string matches the database table name pattern\n * @param tableName - The table name to validate\n * @returns True if valid database table name\n */\n isValidTableName: (tableName: string): boolean => {\n return DATABASE_PATTERNS.TABLE_NAME.test(tableName);\n },\n\n /**\n * Tests if a string matches the cache key pattern\n * @param cacheKey - The cache key to validate\n * @returns True if valid cache key\n */\n isValidCacheKey: (cacheKey: string): boolean => {\n return CACHE_PATTERNS.CACHE_KEY.test(cacheKey);\n },\n\n /**\n * Tests if a string matches the cache pattern (with wildcards)\n * @param cachePattern - The cache pattern to validate\n * @returns True if valid cache pattern\n */\n isValidCachePattern: (cachePattern: string): boolean => {\n return CACHE_PATTERNS.CACHE_PATTERN.test(cachePattern);\n },\n\n /**\n * Normalizes SQL query by replacing parameters and values with placeholders\n * @param query - The SQL query to normalize\n * @returns Normalized query string\n */\n normalizeSqlQuery: (query: string): string => {\n return query\n .replace(SQL_PATTERNS.POSTGRES_PARAMS, \"?\")\n .replace(SQL_PATTERNS.NUMERIC_VALUES, \"?\")\n .replace(SQL_PATTERNS.STRING_LITERALS, \"?\");\n },\n\n /**\n * Sanitizes input by escaping dangerous characters\n * @param input - The input string to sanitize\n * @param escapeMap - Map of characters to their escaped equivalents\n * @returns Sanitized string\n */\n sanitizeDangerousChars: (\n input: string,\n escapeMap: Record<string, string>,\n ): string => {\n return input.replace(\n SANITIZATION_PATTERNS.DANGEROUS_CHARS,\n (char) => escapeMap[char] || char,\n );\n },\n\n /**\n * Creates filesystem-safe timestamp string\n * @param timestamp - ISO timestamp string\n * @returns Filesystem-safe timestamp\n */\n createSafeTimestamp: (timestamp: string): string => {\n return timestamp.replace(FILE_PATTERNS.TIMESTAMP_CHARS, \"-\");\n },\n\n /**\n * Sanitizes command string by removing shell metacharacters\n * @param command - Command string to sanitize\n * @returns Sanitized command string\n */\n sanitizeCommand: (command: string): string => {\n return command\n .replace(SANITIZATION_PATTERNS.SHELL_METACHARACTERS, \"\")\n .replace(SANITIZATION_PATTERNS.MULTIPLE_WHITESPACE, \" \")\n .trim();\n },\n\n /**\n * Sanitizes log message by normalizing whitespace and removing control characters\n * @param message - Log message to sanitize\n * @returns Sanitized log message\n */\n sanitizeLogMessage: (message: string): string => {\n return message\n .replace(SANITIZATION_PATTERNS.LINE_BREAKS_TABS, \" \")\n .replace(SANITIZATION_PATTERNS.CONTROL_CHARACTERS, \"\")\n .trim();\n },\n} as const;\n","import { drizzle } from \"drizzle-orm/node-postgres\";\nimport type { PoolClient } from \"pg\";\nimport { Pool } from \"pg\";\nimport type {\n Column,\n ColumnBaseConfig,\n ColumnDataType,\n SQL,\n SQLWrapper,\n} from \"drizzle-orm\";\nimport {\n eq,\n not,\n gte,\n gt,\n lte,\n lt,\n inArray,\n like,\n between,\n isNull,\n isNotNull,\n asc,\n desc,\n sql,\n} from \"drizzle-orm\";\nimport type { PgTable, PgSelectBase } from \"drizzle-orm/pg-core\";\nimport { PgColumn } from \"drizzle-orm/pg-core\";\nimport { calculatePagination } from \"@utils/pagination\";\nimport type {\n DrizzleAdapterConfig,\n DatabaseAdapterType,\n DatabaseResult,\n PaginatedResult,\n QueryOptions,\n DatabaseHealthStatus,\n Filter,\n Transaction,\n SortOptions,\n} from \"@plyaz/types/db\";\nimport { failure, success } from \"@utils/databaseResultHelpers\";\nimport { DatabaseError } from \"@plyaz/errors\";\nimport { isNonEmptyString, isObject } from \"@utils/typeGuards\";\nimport { DATABASE_ERROR_CODES, type ErrorCodeValue } from \"@plyaz/types/errors\";\nimport { DB_REGEX } from \"@utils/regex\";\nimport type { BuildWhereClauseOptions } from \"@plyaz/types/db\";\n\n/** Minimum elements required for BETWEEN clause */\nconst BETWEEN_MIN_ELEMENTS = 2;\n\n/**\n * @class DrizzleAdapter\n * @implements {DatabaseAdapterType}\n * @classdesc\n * A PostgreSQL database adapter built on top of Drizzle ORM.\n * Provides generic CRUD operations, pagination, filtering, sorting,\n * and transactional support with a consistent result structure.\n */\nexport class DrizzleAdapter implements DatabaseAdapterType {\n private db: ReturnType<typeof drizzle>;\n private pool: Pool;\n private config: DrizzleAdapterConfig;\n private tableMap: Map<string, PgTable> = new Map();\n private idColumnMap: Map<string, PgColumn> = new Map();\n // String-based table registry for auto-registration (fallback when no PgTable schema)\n private stringTableMap: Map<string, string> = new Map();\n private stringIdColumnMap: Map<string, string> = new Map();\n private configIdColumns: Record<string, string>;\n\n /**\n * Creates a new DrizzleAdapter instance.\n * @param {DrizzleAdapterConfig} config - Configuration object for Drizzle and PostgreSQL connection.\n * @description\n * Initializes the adapter with the provided configuration, setting up the connection pool\n * and creating a Drizzle ORM instance. The configuration should include a connection string\n * and optional pool settings such as min/max connections and idle timeout.\n */\n constructor(config: DrizzleAdapterConfig) {\n this.config = config;\n this.pool = new Pool({\n connectionString: config.connectionString,\n ...config.pool,\n });\n this.db = drizzle(this.pool);\n // Store custom ID column mappings from config\n this.configIdColumns = config.tableIdColumns ?? {};\n }\n\n /**\n * Initializes the adapter by verifying database connectivity.\n * @returns {Promise<DatabaseResult<void>>} Success or failure result.\n * @description\n * Attempts to establish a connection to the database to verify that the adapter\n * can communicate with the database. This is typically called during application startup\n * to ensure the database is accessible before performing any operations.\n * Returns a success result if the connection is established, or a failure result with an error\n * if the connection cannot be established.\n */\n async initialize(): Promise<DatabaseResult<void>> {\n let client;\n try {\n client = await this.pool.connect();\n return success();\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to initialize Drizzle adapter: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.INIT_FAILED,\n {\n context: {\n source: \"DrizzleAdapter.initialize\",\n },\n cause: error as Error,\n },\n ),\n );\n } finally {\n if (client) {\n client.release();\n }\n }\n }\n\n /**\n * Opens a new connection to the database.\n * @returns {Promise<void>}\n * @description\n * Establishes a connection to the PostgreSQL database using the connection pool.\n * This method is called to ensure that a connection is available before performing database operations.\n * The connection pool manages the connections efficiently, reusing them when possible.\n */\n async connect(): Promise<void> {\n try {\n const client = await this.pool.connect();\n client.release();\n } catch (error) {\n throw new DatabaseError(\n `Failed to connect to database: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.CONNECT_FAILED,\n {\n context: {\n source: \"DrizzleAdapter.connect\",\n },\n cause: error as Error,\n },\n );\n }\n }\n\n /**\n * Closes all open connections and shuts down the connection pool.\n * @returns {Promise<void>}\n * @description\n * Gracefully shuts down the connection pool, closing all active connections.\n * This method should be called when the adapter is no longer needed, typically during\n * application shutdown, to free up database resources and prevent connection leaks.\n */\n async disconnect(): Promise<void> {\n try {\n await this.pool.end();\n } catch (error) {\n throw new DatabaseError(\n `Failed to disconnect from database: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.DISCONNECT_FAILED,\n {\n context: {\n source: \"DrizzleAdapter.disconnect\",\n },\n cause: error as Error,\n },\n );\n }\n }\n\n /**\n * Closes the database connection and cleanup resources.\n * @returns Promise resolving to DatabaseResult indicating success or failure.\n */\n async close(): Promise<DatabaseResult<void>> {\n try {\n await this.disconnect();\n return success();\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to close connection: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.DISCONNECT_FAILED,\n ),\n );\n }\n }\n\n /**\n * Gets the underlying Drizzle client instance.\n * @returns {TClient} The internal Drizzle client.\n * @description\n * This method exposes the internal Drizzle client instance. Direct access is discouraged\n * to maintain abstraction and ensure all database operations go through the adapter’s\n * interface for error handling, logging, and event emission.\n */\n getClient<TClient extends object = object>(): TClient {\n return this.db as TClient;\n }\n\n /**\n * Executes a raw SQL query.\n * @template T - The expected type of the query result rows.\n * @param {string} sql - Raw SQL query string.\n * @param {T[]} [params] - Optional query parameters.\n * @returns {Promise<T[]>} Array of query result rows.\n * @throws {DatabaseError} When query execution fails.\n * @description\n * Executes a raw SQL query against the database, with optional parameterization.\n * This method is useful for complex queries that cannot be easily expressed using the ORM\n * or for database-specific operations. The method uses parameterized queries to prevent\n * SQL injection attacks. If the query execution fails, a DatabaseError is thrown.\n */\n async query<T>(sql: string, params?: T[]): Promise<T[]> {\n try {\n // Validate SQL to prevent injection\n if (!isNonEmptyString(sql)) {\n throw new DatabaseError(\n \"Invalid SQL query\",\n DATABASE_ERROR_CODES.INVALID_SQL,\n );\n }\n\n const result = await this.pool.query(sql, params);\n return result.rows as T[];\n } catch (error) {\n throw new DatabaseError(\n `Failed to execute query: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.QUERY_FAILED,\n {\n context: {\n source: \"DrizzleAdapter.query\",\n },\n cause: error as Error,\n },\n );\n }\n }\n\n /**\n * Registers a table and optional ID column for ORM operations.\n * @template TTable - Type representing the table structure (PgTable or string).\n * @template TIdColumn - Type representing the ID column (PgColumn or string).\n * @param {string} name - Logical name of the table.\n * @param {TTable} table - Drizzle table object (PgTable) or string table name.\n * @param {TIdColumn} [idColumn] - Optional primary key column (PgColumn or string).\n * @description\n * Registers a table with the adapter, allowing it to be referenced by a logical name\n * in subsequent operations. This is necessary for the adapter to perform ORM operations\n * on the table. The ID column can also be specified if it differs from the default 'id'.\n *\n * **Supports two modes:**\n * 1. **PgTable mode**: Pass Drizzle schema objects for type-safe ORM operations\n * 2. **String mode**: Pass string table names for raw SQL fallback (auto-registration)\n *\n * This registration enables the adapter to map logical table names to actual table objects\n * and ID columns, providing a layer of abstraction between the application and the database schema.\n */\n registerTable<TTable, TIdColumn>(\n name: string,\n table: TTable,\n idColumn?: TIdColumn,\n ): void {\n try {\n if (!isNonEmptyString(name)) {\n throw new DatabaseError(\n \"Invalid table name\",\n DATABASE_ERROR_CODES.INVALID_TABLE_NAME,\n );\n }\n\n // Check if table is a PgTable (Drizzle schema) or a string (raw SQL mode)\n if (typeof table === \"string\") {\n // String mode: register for raw SQL operations\n this.stringTableMap.set(name, table);\n if (idColumn && typeof idColumn === \"string\") {\n this.stringIdColumnMap.set(name, idColumn);\n }\n } else {\n // PgTable mode: register for Drizzle ORM operations\n this.tableMap.set(name, table as PgTable);\n if (idColumn) {\n this.idColumnMap.set(name, idColumn as TIdColumn as PgColumn);\n }\n }\n } catch (error) {\n throw new DatabaseError(\n `Failed to register table: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.TABLE_REGISTRATION_FAILED,\n {\n context: {\n source: \"DrizzleAdapter.registerTable\",\n },\n cause: error as Error,\n },\n );\n }\n }\n\n /**\n * Execute raw SQL findById query\n */\n private async rawSqlFindById<T>(\n table: string,\n id: string,\n ): Promise<T | null> {\n const tableName = this.getStringTableName(table);\n const idColumn = this.getStringIdColumn(table);\n const sqlQuery = `SELECT * FROM \"${tableName}\" WHERE \"${idColumn}\" = $1 LIMIT 1`;\n const result = await this.pool.query(sqlQuery, [id]);\n return (result.rows[0] as T) || null;\n }\n\n /**\n * Finds a record by its primary ID.\n * @template T - The expected type of the record.\n * @param {string} table - Table name.\n * @param {string} id - Record ID.\n * @returns {Promise<DatabaseResult<T | null>>} Found record or null.\n * @description\n * Retrieves a single record from the specified table using its primary ID.\n * The method uses the registered table and ID column to construct the query.\n * If the record is found, it is returned in a success result. If no record is found,\n * null is returned in a success result. If an error occurs during the operation,\n * a failure result with an error message is returned.\n *\n * **Auto-registers tables**: If table is not registered with PgTable schema,\n * falls back to raw SQL mode (same behavior as SQLAdapter).\n */\n async findById<T>(\n table: string,\n id: string,\n ): Promise<DatabaseResult<T | null>> {\n try {\n // Check if we should use raw SQL mode\n if (this.isStringMode(table)) {\n return success(await this.rawSqlFindById<T>(table, id));\n }\n\n // Use Drizzle ORM mode\n const tableObj = this.getTable(table);\n const idColumn = this.getIdColumn(table);\n const result = await this.db\n .select()\n .from(tableObj)\n .where(eq(idColumn, id))\n .limit(1);\n return success((result[0] as T) || null);\n } catch (error) {\n // If error is USE_STRING_MODE, retry with raw SQL\n if (\n error instanceof DatabaseError &&\n error.message === \"USE_STRING_MODE\"\n ) {\n return this.handleStringModeFallback<T | null>(\n () => this.rawSqlFindById<T>(table, id),\n table,\n \"DrizzleAdapter.findById\",\n DATABASE_ERROR_CODES.FIND_BY_ID_FAILED,\n );\n }\n return failure(\n new DatabaseError(\n `Failed to find by id in table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.FIND_BY_ID_FAILED,\n {\n context: { source: \"DrizzleAdapter.findById\" },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Handle USE_STRING_MODE fallback with error wrapping\n */\n private async handleStringModeFallback<T>(\n operation: () => Promise<T>,\n table: string,\n source: string,\n errorCode: ErrorCodeValue,\n ): Promise<DatabaseResult<T>> {\n try {\n return success(await operation());\n } catch (sqlError) {\n return failure(\n new DatabaseError(\n `Failed operation on table ${table}: ${(sqlError as Error).message}`,\n errorCode,\n {\n context: { source },\n cause: sqlError as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Retrieves multiple records with optional filtering, sorting, and pagination.\n * @template T - The expected type of the records.\n * @param {string} table - Table name.\n * @param {QueryOptions} [options] - Optional filter, sort, and pagination options.\n * @returns {Promise<DatabaseResult<PaginatedResult<T>>>} Paginated result set.\n * @description\n * Retrieves multiple records from the specified table with support for filtering,\n * sorting, and pagination. The method first applies any filters to narrow down the result set,\n * then applies sorting to order the results, and finally applies pagination to limit the number\n * of records returned. The result includes the data array, total count of matching records,\n * and pagination metadata such as current page, total pages, and next/previous cursors.\n * If an error occurs during the operation, a failure result with an error message is returned.\n *\n * **Auto-registers tables**: If table is not registered with PgTable schema,\n * falls back to raw SQL mode (same behavior as SQLAdapter).\n */\n\n // eslint-disable-next-line complexity\n async findMany<T extends Record<string, unknown>>(\n table: string,\n options?: QueryOptions<T>,\n ): Promise<DatabaseResult<PaginatedResult<T>>> {\n try {\n // Check if we should use raw SQL mode\n if (this.isStringMode(table)) {\n return this.findManyRawSql<T>(table, options);\n }\n\n const tableObj = this.getTable(table);\n\n let query: PgSelectBase<\n string,\n Record<string, PgColumn>,\n \"single\",\n Record<string, \"not-null\">,\n false\n > = this.db.select().from(tableObj);\n\n // Apply sorting\n if (options?.sort) {\n query = this.applySorting(query as never, options.sort, tableObj);\n }\n // Apply filters\n if (options?.filter) {\n const whereClause = this.buildWhereClause(options.filter, tableObj);\n if (whereClause) {\n query = query.where(whereClause) as typeof query;\n }\n }\n\n // Get total count\n let countQuery = this.db\n .select({ count: sql<number>`count(*)::int`.as(\"count\") })\n .from(tableObj);\n if (options?.filter) {\n const whereClause = this.buildWhereClause(options.filter, tableObj);\n if (whereClause)\n countQuery = countQuery.where(whereClause) as typeof countQuery;\n }\n\n const countResult = await countQuery;\n const total = Number(countResult[0].count);\n\n // Apply pagination\n if (options?.pagination) {\n if (options.pagination.offset !== undefined) {\n query = query.offset(options.pagination.offset) as typeof query;\n }\n if (options.pagination.limit !== undefined) {\n query = query.limit(options.pagination.limit) as typeof query;\n }\n }\n\n const data = await query;\n return success({\n data: data as T[],\n total,\n pagination: calculatePagination(total, options?.pagination),\n });\n } catch (error) {\n // If error is USE_STRING_MODE, retry with raw SQL\n if (\n error instanceof DatabaseError &&\n error.message === \"USE_STRING_MODE\"\n ) {\n return this.findManyRawSql<T>(table, options);\n }\n return failure(\n new DatabaseError(\n `Failed to find many in table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.FIND_MANY_FAILED,\n {\n context: {\n source: \"DrizzleAdapter.findMany\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Raw SQL fallback for findMany when no PgTable schema is registered.\n * @private\n */\n // eslint-disable-next-line complexity\n private async findManyRawSql<T extends Record<string, unknown>>(\n table: string,\n options?: QueryOptions<T>,\n ): Promise<DatabaseResult<PaginatedResult<T>>> {\n try {\n const tableName = this.getStringTableName(table);\n const params: unknown[] = [];\n let whereClause = \"\";\n let paramIndex = 1;\n\n // Build WHERE clause\n if (options?.filter) {\n const { field, operator, value } = options.filter;\n whereClause = this.buildSqlWhereClause({\n field,\n operator,\n value,\n params,\n startIndex: paramIndex,\n });\n paramIndex = params.length + 1;\n }\n\n // Count total\n const countSql = `SELECT COUNT(*) as total FROM \"${tableName}\"${whereClause}`;\n const countResult = await this.pool.query(countSql, params);\n const total = Number.parseInt(countResult.rows[0].total);\n\n // ORDER BY clause\n let orderClause = \"\";\n if (options?.sort?.length) {\n orderClause =\n \" ORDER BY \" +\n options.sort\n .map((s) => `\"${s.field}\" ${s.direction.toUpperCase()}`)\n .join(\", \");\n }\n\n // Build main query params (need to copy for separate query)\n const queryParams = [...params];\n\n // LIMIT & OFFSET\n let limitClause = \"\";\n if (options?.pagination?.limit) {\n limitClause += ` LIMIT $${paramIndex++}`;\n queryParams.push(options.pagination.limit);\n }\n if (options?.pagination?.offset) {\n limitClause += ` OFFSET $${paramIndex++}`;\n queryParams.push(options.pagination.offset);\n }\n\n // Final query\n const sqlQuery = `SELECT * FROM \"${tableName}\"${whereClause}${orderClause}${limitClause}`;\n const result = await this.pool.query(sqlQuery, queryParams);\n\n return success({\n data: result.rows as T[],\n total,\n pagination: calculatePagination(total, options?.pagination),\n });\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to find many in table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.FIND_MANY_FAILED,\n {\n context: {\n source: \"DrizzleAdapter.findManyRawSql\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Builds a SQL WHERE clause string for raw SQL queries.\n * @private\n */\n // eslint-disable-next-line complexity\n private buildSqlWhereClause(options: BuildWhereClauseOptions): string {\n const { field, operator, value, params, startIndex } = options;\n let clause = \"\";\n\n switch (operator) {\n case \"eq\":\n clause = ` WHERE \"${field}\" = $${startIndex}`;\n params.push(value);\n break;\n case \"ne\":\n clause = ` WHERE \"${field}\" != $${startIndex}`;\n params.push(value);\n break;\n case \"gt\":\n clause = ` WHERE \"${field}\" > $${startIndex}`;\n params.push(value);\n break;\n case \"gte\":\n clause = ` WHERE \"${field}\" >= $${startIndex}`;\n params.push(value);\n break;\n case \"lt\":\n clause = ` WHERE \"${field}\" < $${startIndex}`;\n params.push(value);\n break;\n case \"lte\":\n clause = ` WHERE \"${field}\" <= $${startIndex}`;\n params.push(value);\n break;\n case \"in\":\n if (Array.isArray(value)) {\n const placeholders = value\n .map((_, i) => `$${startIndex + i}`)\n .join(\", \");\n clause = ` WHERE \"${field}\" IN (${placeholders})`;\n params.push(...value);\n }\n break;\n case \"like\":\n clause = ` WHERE \"${field}\" LIKE $${startIndex}`;\n params.push(value);\n break;\n case \"between\":\n if (Array.isArray(value) && value.length >= BETWEEN_MIN_ELEMENTS) {\n clause = ` WHERE \"${field}\" BETWEEN $${startIndex} AND $${startIndex + 1}`;\n params.push(value[0], value[1]);\n }\n break;\n case \"isNull\":\n clause = ` WHERE \"${field}\" IS NULL`;\n break;\n case \"isNotNull\":\n clause = ` WHERE \"${field}\" IS NOT NULL`;\n break;\n default:\n break;\n }\n\n return clause;\n }\n\n /**\n * Inserts a new record into the specified table.\n * @template T - The expected type of the record.\n * @param {string} table - Table name.\n * @param {T} data - Record to insert.\n * @returns {Promise<DatabaseResult<T>>} Inserted record.\n * @description\n * Inserts a new record into the specified table using the provided data.\n * The method uses the registered table to construct the insert query.\n * After insertion, it returns the inserted record with any auto-generated fields\n * (like IDs) populated. If an error occurs during the operation,\n * a failure result with an error message is returned.\n *\n * **Auto-registers tables**: If table is not registered with PgTable schema,\n * falls back to raw SQL mode (same behavior as SQLAdapter).\n */\n async create<T>(table: string, data: T): Promise<DatabaseResult<T>> {\n try {\n // Check if we should use raw SQL mode\n if (this.isStringMode(table)) {\n return this.createRawSql<T>(table, data);\n }\n\n const tableObj = this.getTable(table);\n const result = await this.db\n .insert(tableObj)\n .values(data as Record<string, T>)\n .returning();\n return success(result[0] as T);\n } catch (error) {\n // If error is USE_STRING_MODE, retry with raw SQL\n if (\n error instanceof DatabaseError &&\n error.message === \"USE_STRING_MODE\"\n ) {\n return this.createRawSql<T>(table, data);\n }\n return failure(\n new DatabaseError(\n `Failed to create in table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.CREATE_FAILED,\n {\n context: {\n source: \"DrizzleAdapter.create\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Raw SQL fallback for create when no PgTable schema is registered.\n * @private\n */\n private async createRawSql<T>(\n table: string,\n data: T,\n ): Promise<DatabaseResult<T>> {\n try {\n const tableName = this.getStringTableName(table);\n const keys = Object.keys(data as Record<string, unknown>);\n const values = Object.values(data as Record<string, unknown>);\n const placeholders = values.map((_, i) => `$${i + 1}`).join(\", \");\n const escapedKeys = keys.map((k) => `\"${k}\"`).join(\", \");\n\n const sqlQuery = `INSERT INTO \"${tableName}\" (${escapedKeys}) VALUES (${placeholders}) RETURNING *`;\n const result = await this.pool.query(sqlQuery, values);\n\n return success(result.rows[0] as T);\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to create in table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.CREATE_FAILED,\n {\n context: {\n source: \"DrizzleAdapter.createRawSql\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Updates an existing record by ID.\n * @template T - The expected type of the record.\n * @param {string} table - Table name.\n * @param {string} id - Record ID.\n * @param {Partial<T>} data - Partial object containing fields to update.\n * @returns {Promise<DatabaseResult<T>>} Updated record.\n * @description\n * Updates an existing record in the specified table using its primary ID.\n * Only the fields provided in the data object are updated, allowing for partial updates.\n * The method uses the registered table and ID column to construct the update query.\n * After updating, it returns the updated record. If an error occurs during the operation,\n * a failure result with an error message is returned.\n *\n * **Auto-registers tables**: If table is not registered with PgTable schema,\n * falls back to raw SQL mode (same behavior as SQLAdapter).\n */\n async update<T>(\n table: string,\n id: string,\n data: Partial<T>,\n ): Promise<DatabaseResult<T>> {\n try {\n // Check if we should use raw SQL mode\n if (this.isStringMode(table)) {\n return this.updateRawSql<T>(table, id, data);\n }\n\n const tableObj = this.getTable(table);\n const idColumn = this.getIdColumn(table);\n const result = await this.db\n .update(tableObj)\n .set(data as Record<string, T>)\n .where(eq(idColumn, id))\n .returning();\n return success(result[0] as T);\n } catch (error) {\n // If error is USE_STRING_MODE, retry with raw SQL\n if (\n error instanceof DatabaseError &&\n error.message === \"USE_STRING_MODE\"\n ) {\n return this.updateRawSql<T>(table, id, data);\n }\n return failure(\n new DatabaseError(\n `Failed to update in table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.UPDATE_FAILED,\n {\n context: {\n source: \"DrizzleAdapter.update\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Raw SQL fallback for update when no PgTable schema is registered.\n * @private\n */\n private async updateRawSql<T>(\n table: string,\n id: string,\n data: Partial<T>,\n ): Promise<DatabaseResult<T>> {\n try {\n const tableName = this.getStringTableName(table);\n const idColumn = this.getStringIdColumn(table);\n const keys = Object.keys(data as Record<string, unknown>);\n const values = Object.values(data as Record<string, unknown>);\n const setClause = keys.map((key, i) => `\"${key}\" = $${i + 1}`).join(\", \");\n\n const sqlQuery = `UPDATE \"${tableName}\" SET ${setClause} WHERE \"${idColumn}\" = $${keys.length + 1} RETURNING *`;\n const result = await this.pool.query(sqlQuery, [...values, id]);\n\n return success(result.rows[0] as T);\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to update in table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.UPDATE_FAILED,\n {\n context: {\n source: \"DrizzleAdapter.updateRawSql\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Deletes a record by ID.\n * @param {string} table - Table name.\n * @param {string} id - Record ID.\n * @returns {Promise<DatabaseResult<void>>}\n * @description\n * Deletes a record from the specified table using its primary ID.\n * The method uses the registered table and ID column to construct the delete query.\n * If the operation is successful, it returns a success result with no value.\n * If an error occurs during the operation, a failure result with an error message is returned.\n *\n * **Auto-registers tables**: If table is not registered with PgTable schema,\n * falls back to raw SQL mode (same behavior as SQLAdapter).\n */\n async delete(table: string, id: string): Promise<DatabaseResult<void>> {\n try {\n // Check if we should use raw SQL mode\n if (this.isStringMode(table)) {\n return this.deleteRawSql(table, id);\n }\n\n const tableObj = this.getTable(table);\n const idColumn = this.getIdColumn(table);\n await this.db.delete(tableObj).where(eq(idColumn, id));\n return success();\n } catch (error) {\n // If error is USE_STRING_MODE, retry with raw SQL\n if (\n error instanceof DatabaseError &&\n error.message === \"USE_STRING_MODE\"\n ) {\n return this.deleteRawSql(table, id);\n }\n return failure(\n new DatabaseError(\n `Failed to delete from table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.DELETE_FAILED,\n {\n context: {\n source: \"DrizzleAdapter.delete\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Raw SQL fallback for delete when no PgTable schema is registered.\n * @private\n */\n private async deleteRawSql(\n table: string,\n id: string,\n ): Promise<DatabaseResult<void>> {\n try {\n const tableName = this.getStringTableName(table);\n const idColumn = this.getStringIdColumn(table);\n const sqlQuery = `DELETE FROM \"${tableName}\" WHERE \"${idColumn}\" = $1`;\n await this.pool.query(sqlQuery, [id]);\n return success();\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to delete from table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.DELETE_FAILED,\n {\n context: {\n source: \"DrizzleAdapter.deleteRawSql\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Executes a transactional operation with rollback on failure.\n * @template T - The expected type of the transaction result.\n * @param {(trx: Transaction) => Promise<T>} callback - Function executed within a transaction.\n * @returns {Promise<DatabaseResult<T>>} Transaction result.\n * @description\n * Executes a callback function within a database transaction, providing atomicity.\n * If the callback function executes successfully, the transaction is committed.\n * If an error occurs during the execution of the callback function, the transaction\n * is rolled back, ensuring that no partial changes are applied to the database.\n * The method returns the result of the callback function if successful,\n * or a failure result with an error message if an error occurs.\n *\n * **Auto-registers tables**: Transaction operations use raw SQL mode for unregistered tables.\n */\n async transaction<T>(\n callback: (trx: Transaction) => Promise<T>,\n ): Promise<DatabaseResult<T>> {\n const client: PoolClient = await this.pool.connect();\n try {\n await client.query(\"BEGIN\");\n const trxDb = drizzle(client);\n\n // Transaction operations that support both PgTable and raw SQL modes\n const trx: Transaction = {\n findById: async <T>(table: string, id: string) => {\n // Use raw SQL for unregistered tables\n if (this.isStringMode(table)) {\n const tableName = this.getStringTableName(table);\n const idColumn = this.getStringIdColumn(table);\n const sqlQuery = `SELECT * FROM \"${tableName}\" WHERE \"${idColumn}\" = $1 LIMIT 1`;\n const result = await client.query(sqlQuery, [id]);\n return success((result.rows[0] as T) || null);\n }\n const tableObj = this.getTable(table);\n const idColumn = this.getIdColumn(table);\n const result = await trxDb\n .select()\n .from(tableObj)\n .where(eq(idColumn, id))\n .limit(1);\n return success((result[0] as T) || null);\n },\n create: async <T>(table: string, data: T) => {\n // Use raw SQL for unregistered tables\n if (this.isStringMode(table)) {\n const tableName = this.getStringTableName(table);\n const keys = Object.keys(data as Record<string, unknown>);\n const values = Object.values(data as Record<string, unknown>);\n const placeholders = values.map((_, i) => `$${i + 1}`).join(\", \");\n const escapedKeys = keys.map((k) => `\"${k}\"`).join(\", \");\n const sqlQuery = `INSERT INTO \"${tableName}\" (${escapedKeys}) VALUES (${placeholders}) RETURNING *`;\n const result = await client.query(sqlQuery, values);\n return success(result.rows[0] as T);\n }\n const tableObj = this.getTable(table);\n const result = await trxDb\n .insert(tableObj)\n .values(data as Record<string, T>)\n .returning();\n return success(result[0] as T);\n },\n update: async <T>(table: string, id: string, data: Partial<T>) => {\n // Use raw SQL for unregistered tables\n if (this.isStringMode(table)) {\n const tableName = this.getStringTableName(table);\n const idColumn = this.getStringIdColumn(table);\n const keys = Object.keys(data as Record<string, unknown>);\n const values = Object.values(data as Record<string, unknown>);\n const setClause = keys\n .map((key, i) => `\"${key}\" = $${i + 1}`)\n .join(\", \");\n const sqlQuery = `UPDATE \"${tableName}\" SET ${setClause} WHERE \"${idColumn}\" = $${keys.length + 1} RETURNING *`;\n const result = await client.query(sqlQuery, [...values, id]);\n return success(result.rows[0] as T);\n }\n const tableObj = this.getTable(table);\n const idColumn = this.getIdColumn(table);\n const result = await trxDb\n .update(tableObj)\n .set(data as Record<string, T>)\n .where(eq(idColumn, id))\n .returning();\n return success(result[0] as T);\n },\n delete: async (table: string, id: string) => {\n // Use raw SQL for unregistered tables\n if (this.isStringMode(table)) {\n const tableName = this.getStringTableName(table);\n const idColumn = this.getStringIdColumn(table);\n const sqlQuery = `DELETE FROM \"${tableName}\" WHERE \"${idColumn}\" = $1`;\n await client.query(sqlQuery, [id]);\n return success();\n }\n const tableObj = this.getTable(table);\n const idColumn = this.getIdColumn(table);\n await trxDb.delete(tableObj).where(eq(idColumn, id));\n return success();\n },\n commit: async () => {\n await client.query(\"COMMIT\");\n },\n rollback: async () => {\n await client.query(\"ROLLBACK\");\n },\n };\n\n const result = await callback(trx);\n await trx.commit();\n return success(result);\n } catch (error) {\n await client.query(\"ROLLBACK\");\n return failure(\n new DatabaseError(\n `Transaction failed: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.TRANSACTION_FAILED,\n {\n context: {\n source: \"DrizzleAdapter.transaction\",\n },\n cause: error as Error,\n },\n ),\n );\n } finally {\n client.release();\n }\n }\n\n /**\n * Checks if a record exists by ID.\n * @param {string} table - Table name.\n * @param {string} id - Record ID.\n * @returns {Promise<DatabaseResult<boolean>>} True if exists, otherwise false.\n * @description\n * Checks if a record with the specified ID exists in the table.\n * The method uses the registered table and ID column to construct the query.\n * It returns a success result with a boolean value indicating whether the record exists.\n * If an error occurs during the operation, a failure result with an error message is returned.\n *\n * **Auto-registers tables**: If table is not registered with PgTable schema,\n * falls back to raw SQL mode (same behavior as SQLAdapter).\n */\n async exists(table: string, id: string): Promise<DatabaseResult<boolean>> {\n try {\n // Check if we should use raw SQL mode\n if (this.isStringMode(table)) {\n const tableName = this.getStringTableName(table);\n const idColumn = this.getStringIdColumn(table);\n const sqlQuery = `SELECT 1 FROM \"${tableName}\" WHERE \"${idColumn}\" = $1 LIMIT 1`;\n const result = await this.pool.query(sqlQuery, [id]);\n return success(result.rows.length > 0);\n }\n\n const tableObj = this.getTable(table);\n const idColumn = this.getIdColumn(table);\n const result = await this.db\n .select({ exists: sql`1` })\n .from(tableObj)\n .where(eq(idColumn, id))\n .limit(1);\n return success(!!result.length);\n } catch (error) {\n // If error is USE_STRING_MODE, retry with raw SQL\n if (\n error instanceof DatabaseError &&\n error.message === \"USE_STRING_MODE\"\n ) {\n const tableName = this.getStringTableName(table);\n const idColumn = this.getStringIdColumn(table);\n const sqlQuery = `SELECT 1 FROM \"${tableName}\" WHERE \"${idColumn}\" = $1 LIMIT 1`;\n const result = await this.pool.query(sqlQuery, [id]);\n return success(result.rows.length > 0);\n }\n return failure(\n new DatabaseError(\n `Failed to check existence in table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.EXISTS_FAILED,\n {\n context: {\n source: \"DrizzleAdapter.exists\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Counts records matching an optional filter.\n * @param {string} table - Table name.\n * @param {Filter} [filter] - Optional filter object.\n * @returns {Promise<DatabaseResult<number>>} Total count of matching records.\n * @description\n * Counts the number of records in the specified table that match the optional filter.\n * The method uses the registered table to construct the count query.\n * If a filter is provided, it is applied to narrow down the count to matching records.\n * It returns a success result with the count of matching records.\n * If an error occurs during the operation, a failure result with an error message is returned.\n *\n * **Auto-registers tables**: If table is not registered with PgTable schema,\n * falls back to raw SQL mode (same behavior as SQLAdapter).\n */\n async count<T extends Record<string, unknown> = Record<string, unknown>>(\n table: string,\n filter?: Filter<T>,\n ): Promise<DatabaseResult<number>> {\n try {\n // Check if we should use raw SQL mode\n if (this.isStringMode(table)) {\n return this.countRawSql(table, filter);\n }\n\n const tableObj = this.getTable(table);\n\n const baseQuery = this.db\n .select({ count: sql<number>`count(*)::int` })\n .from(tableObj);\n\n const query =\n filter && this.buildWhereClause(filter, tableObj)\n ? baseQuery.where(this.buildWhereClause(filter, tableObj) as SQL)\n : baseQuery;\n\n const result = await query;\n const countValue = result.length > 0 ? result[0].count : 0;\n\n return success(Number(countValue));\n } catch (error) {\n // If error is USE_STRING_MODE, retry with raw SQL\n if (\n error instanceof DatabaseError &&\n error.message === \"USE_STRING_MODE\"\n ) {\n return this.countRawSql(table, filter);\n }\n return failure(\n new DatabaseError(\n `Failed to count in table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.COUNT_FAILED,\n {\n context: {\n source: \"DrizzleAdapter.count\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Raw SQL fallback for count when no PgTable schema is registered.\n * @private\n */\n private async countRawSql<T extends Record<string, unknown>>(\n table: string,\n filter?: Filter<T>,\n ): Promise<DatabaseResult<number>> {\n try {\n const tableName = this.getStringTableName(table);\n const params: unknown[] = [];\n let whereClause = \"\";\n\n if (filter) {\n const { field, operator, value } = filter;\n whereClause = this.buildSqlWhereClause({\n field,\n operator,\n value,\n params,\n startIndex: 1,\n });\n }\n\n const sqlQuery = `SELECT COUNT(*) as count FROM \"${tableName}\"${whereClause}`;\n const result = await this.pool.query(sqlQuery, params);\n const rowCount = Number.parseInt(result.rows[0].count);\n return success(Number(rowCount));\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to count in table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.COUNT_FAILED,\n {\n context: {\n source: \"DrizzleAdapter.countRawSql\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Performs a health check on the database connection.\n * @returns {Promise<DatabaseResult<DatabaseHealthStatus>>} Health status with response time.\n * @description\n * Checks the health of the database connection by executing a simple query.\n * The method measures the response time of the query to determine the health status.\n * It returns a success result with a HealthStatus object indicating whether the database is healthy,\n * the response time of the health check, and any additional details.\n * If an error occurs during the operation, a failure result with an error message is returned.\n */\n async healthCheck(): Promise<DatabaseResult<DatabaseHealthStatus>> {\n const startTime = Date.now();\n try {\n await this.pool.query(\"SELECT 1\");\n const responseTime = Date.now() - startTime;\n return success({\n isHealthy: true,\n responseTime,\n details: { adapter: \"drizzle\" } as DatabaseHealthStatus[\"details\"],\n });\n } catch (error) {\n const responseTime = Date.now() - startTime;\n return success({\n isHealthy: false,\n responseTime,\n details: {\n adapter: \"drizzle\",\n error: (error as Error).message,\n } as DatabaseHealthStatus[\"details\"],\n });\n }\n }\n\n // --- Private Helpers ---\n\n /**\n * Checks if a table is registered in string mode (raw SQL fallback).\n * @private\n * @param {string} name - Table name.\n * @returns {boolean} True if table is registered in string mode.\n */\n private isStringMode(name: string): boolean {\n return this.stringTableMap.has(name) || !this.tableMap.has(name);\n }\n\n /**\n * Retrieves a registered table by name.\n * @private\n * @param {string} name - Table name.\n * @returns {PgTable} Table object.\n * @throws {DatabaseError} If table is not registered and cannot be auto-registered.\n * @description\n * Retrieves a table object that has been previously registered with the adapter.\n * If the table is not found in PgTable mode, it auto-registers in string mode\n * for raw SQL operations (same behavior as SQLAdapter).\n */\n private getTable(name: string): PgTable {\n try {\n if (!isNonEmptyString(name)) {\n throw new DatabaseError(\n \"Invalid table name\",\n DATABASE_ERROR_CODES.INVALID_TABLE_NAME,\n );\n }\n\n const table = this.tableMap.get(name);\n if (!table) {\n // Auto-register in string mode for raw SQL fallback\n if (!this.stringTableMap.has(name)) {\n this.stringTableMap.set(name, name);\n }\n // Return a placeholder - actual operations will use raw SQL\n throw new DatabaseError(\n \"USE_STRING_MODE\",\n DATABASE_ERROR_CODES.TABLE_NOT_REGISTERED,\n );\n }\n return table;\n } catch (error) {\n throw error instanceof DatabaseError\n ? error\n : new DatabaseError(\n \"Failed to get table\",\n DATABASE_ERROR_CODES.GET_TABLE_FAILED,\n );\n }\n }\n\n /**\n * Gets the string table name for raw SQL operations.\n * @private\n * @param {string} name - Logical table name.\n * @returns {string} Physical table name.\n */\n private getStringTableName(name: string): string {\n let tableName = this.stringTableMap.get(name);\n if (!tableName) {\n // Auto-register table with same name and check for custom ID column from config\n const customIdColumn = this.configIdColumns[name];\n if (customIdColumn) {\n this.stringIdColumnMap.set(name, customIdColumn);\n }\n this.stringTableMap.set(name, name);\n tableName = name;\n }\n return tableName;\n }\n\n /**\n * Gets the string ID column for raw SQL operations.\n * @private\n * @param {string} name - Logical table name.\n * @returns {string} ID column name (defaults to 'id').\n * @description\n * Retrieves the ID column for a table. Checks in this order:\n * 1. Runtime registered ID column (from registerTable calls)\n * 2. Config-provided ID column (from tableIdColumns in config)\n * 3. Default 'id' column\n */\n private getStringIdColumn(name: string): string {\n // Check runtime registered first\n const runtimeIdColumn = this.stringIdColumnMap.get(name);\n if (runtimeIdColumn) {\n return runtimeIdColumn;\n }\n\n // Check config-provided ID columns\n const configIdColumn = this.configIdColumns[name];\n if (configIdColumn) {\n return configIdColumn;\n }\n\n // Default to 'id'\n return \"id\";\n }\n\n /**\n * Retrieves the registered ID column for a table.\n * @private\n * @param {string} name - Table name.\n * @returns {PgColumn} ID column.\n * @throws {DatabaseError} If ID column is not registered.\n * @description\n * Retrieves the ID column that has been previously registered for a table.\n * This method is used internally by other methods to ensure that operations that require\n * the ID column can access it. If the ID column is not found, it throws a DatabaseError.\n */\n private getIdColumn(name: string): PgColumn {\n try {\n if (!isNonEmptyString(name)) {\n throw new DatabaseError(\n \"Invalid table name\",\n DATABASE_ERROR_CODES.INVALID_TABLE_NAME,\n );\n }\n\n const idColumn = this.idColumnMap.get(name);\n if (!idColumn) {\n throw new DatabaseError(\n \"ID column is not registered with the adapter\",\n DATABASE_ERROR_CODES.ID_COLUMN_NOT_REGISTERED,\n );\n }\n return idColumn;\n } catch (error) {\n throw error instanceof DatabaseError\n ? error\n : new DatabaseError(\n \"Failed to get ID column\",\n DATABASE_ERROR_CODES.GET_ID_COLUMN_FAILED,\n );\n }\n }\n\n /**\n * Builds a SQL `WHERE` clause based on filter operators.\n * @private\n * @param {Filter} filter - Filter definition.\n * @param {PgTable} table - Table to apply filter on.\n * @returns {SQL | undefined} SQL condition object.\n * @throws {DatabaseError} If column or operator is invalid.\n * @description\n * Builds a SQL WHERE clause based on the provided filter definition.\n * It supports various operators like equality, comparison, and null checks.\n * If the column specified in the filter does not exist in the table, or if the operator\n * is not supported, it throws a DatabaseError. The method returns an SQL object that\n * can be used in queries, or undefined if no valid clause can be constructed.\n */\n // eslint-disable-next-line complexity\n private buildWhereClause<T extends Record<string, unknown>>(\n filter: Filter<T>,\n table: PgTable,\n ): SQL | undefined {\n try {\n if (!isObject(filter)) {\n return undefined;\n }\n\n const { field, operator, value } = filter;\n\n // Validate field name\n if (!isNonEmptyString(field) || !DB_REGEX.isValidFieldName(field)) {\n throw new DatabaseError(\n \"Invalid field name\",\n DATABASE_ERROR_CODES.INVALID_FIELD_NAME,\n );\n }\n\n // Access column from table - field is validated at runtime\n const column = table[field as keyof typeof table] as Column<\n ColumnBaseConfig<ColumnDataType, string>\n >;\n if (!column) {\n throw new DatabaseError(\n \"Column does not exist in table\",\n DATABASE_ERROR_CODES.COLUMN_NOT_EXISTS,\n );\n }\n\n // Drizzle operators work with the column types directly\n switch (operator) {\n case \"eq\":\n return eq(column, value);\n case \"ne\":\n return not(eq(column, value));\n case \"gt\":\n return gt(column, value);\n case \"gte\":\n return gte(column, value);\n case \"lt\":\n return lt(column, value);\n case \"lte\":\n return lte(column, value);\n case \"in\":\n return inArray(column, value as unknown[]);\n case \"notIn\":\n return not(inArray(column, value as unknown[]));\n case \"like\":\n return like(column, value as string);\n case \"between\":\n return between(\n column,\n (value as [unknown, unknown])[0],\n (value as [unknown, unknown])[1],\n );\n case \"isNull\":\n return isNull(column);\n case \"isNotNull\":\n return isNotNull(column);\n default:\n throw new DatabaseError(\n \"Unsupported operator\",\n DATABASE_ERROR_CODES.UNSUPPORTED_OPERATOR,\n );\n }\n } catch (error) {\n throw new DatabaseError(\n \"Failed to build WHERE clause\",\n DATABASE_ERROR_CODES.BUILD_WHERE_FAILED,\n {\n context: {\n source: \"DrizzleAdapter.buildWhereClause\",\n },\n cause: error as Error,\n },\n );\n }\n }\n\n /**\n * Applies sorting to a query using provided field and direction.\n * @private\n * @template TQuery - Type of the query builder.\n * @template TTable - Type of the table.\n * @param {TQuery} query - Drizzle query builder.\n * @param {SortOptions[]} sort - Array of sort conditions.\n * @param {TTable} table - Target table.\n * @returns {TQuery} Modified query with applied sorting.\n * @throws {DatabaseError} If field is invalid or missing.\n * @description\n * Applies sorting to a Drizzle query based on the provided sort options.\n * It supports sorting by multiple fields in ascending or descending order.\n * If a field specified in the sort options does not exist in the table, or is not a valid column,\n * it throws a DatabaseError. The method returns the modified query with the sorting applied.\n */\n private applySorting<\n T extends Record<string, unknown>,\n TQuery extends {\n orderBy: (...columns: (SQL | SQLWrapper | PgColumn)[]) => TQuery;\n },\n TTable extends PgTable,\n >(query: TQuery, sort: SortOptions<T>[], table: TTable): TQuery {\n return sort.reduce((q, { field, direction }) => {\n if (!Object.prototype.hasOwnProperty.call(table, field)) {\n throw new DatabaseError(\n `Column ${field} does not exist in table`,\n DATABASE_ERROR_CODES.COLUMN_NOT_EXISTS,\n );\n }\n\n const key = field as keyof TTable;\n const column = table[key];\n\n if (!(column instanceof PgColumn)) {\n throw new DatabaseError(\n `Field ${field} is not a valid column`,\n DATABASE_ERROR_CODES.INVALID_COLUMN,\n );\n }\n\n return direction === \"asc\"\n ? q.orderBy(asc(column))\n : q.orderBy(desc(column));\n }, query);\n }\n}\n","import type {\n DatabaseAdapterType,\n DatabaseResult,\n PaginatedResult,\n QueryOptions,\n Filter,\n DatabaseHealthStatus,\n Transaction,\n SupabaseAdapterConfig,\n} from \"@plyaz/types/db\";\nimport type { SupabaseClient } from \"@supabase/supabase-js\";\nimport { createClient } from \"@supabase/supabase-js\";\nimport { failure, success } from \"@utils/databaseResultHelpers\";\nimport { DatabaseError } from \"@plyaz/errors\";\nimport { DATABASE_ERROR_CODES } from \"@plyaz/types/errors\";\n\nimport { calculatePagination } from \"@utils/pagination\";\nimport { NUMERIX } from \"@plyaz/config\";\n\n/**\n * @class SupabaseAdapter\n * @implements {DatabaseAdapterType}\n * @classdesc\n * Supabase adapter implementation for database operations.\n *\n * This adapter provides an interface to interact with Supabase databases,\n * supporting CRUD operations, transactions, and health checks. It leverages\n * the Supabase JavaScript client to communicate with PostgreSQL databases through\n * Supabase's API. The adapter provides a consistent interface while abstracting\n * away the specifics of Supabase's API calls.\n */\nexport class SupabaseAdapter implements DatabaseAdapterType {\n private client: SupabaseClient;\n private config: SupabaseAdapterConfig;\n private tableMap: Map<string, string> = new Map();\n private idColumnMap: Map<string, string> = new Map();\n private configIdColumns: Record<string, string>;\n\n /**\n * Creates a new SupabaseAdapter instance.\n * @param {SupabaseAdapterConfig} config - Configuration for the Supabase adapter.\n * @description\n * Initializes the adapter with the provided configuration, setting up the Supabase client.\n * The configuration must include a Supabase URL and either a service key or an anonymous key.\n * The adapter maintains internal maps for table names and ID columns to provide a level of\n * abstraction over the database schema. If required configuration values are missing,\n * the constructor throws a DatabaseError.\n * @throws {DatabaseError} If Supabase URL or key is not provided in the configuration.\n */\n constructor(config: SupabaseAdapterConfig) {\n this.config = config;\n // Store custom ID column mappings from config\n this.configIdColumns = config.tableIdColumns ?? {};\n\n if (!config.supabaseUrl) {\n throw new DatabaseError(\n \"Supabase URL is required for Supabase adapter\",\n DATABASE_ERROR_CODES.CONFIG_REQUIRED,\n );\n }\n\n const key = config.supabaseServiceKey ?? config.supabaseAnonKey;\n\n if (!key) {\n throw new DatabaseError(\n \"Supabase key is required for Supabase adapter\",\n DATABASE_ERROR_CODES.CONFIG_REQUIRED,\n );\n }\n\n this.client = createClient(config.supabaseUrl, key, {\n auth: {\n persistSession: false,\n autoRefreshToken: false,\n },\n db: {\n schema: (config.schema ?? \"public\") as \"public\",\n },\n });\n }\n\n /**\n * Initializes the Supabase database adapter.\n * @returns {Promise<DatabaseResult<void>>} A promise resolving to a DatabaseResult indicating\n * whether the initialization was successful or failed.\n * @description\n * Validates the Supabase database connection by invoking a simple predefined RPC function (`version`).\n * This method is typically executed during application startup to ensure the adapter can\n * successfully communicate with the database before performing any operations.\n *\n * The method calls the `version` RPC to confirm connectivity. If the RPC function is not defined,\n * it is treated as a non-critical error and the connection is still considered valid. Any other\n * errors are reported as initialization failures.\n */\n async initialize(): Promise<DatabaseResult<void>> {\n try {\n // Verify the database connection by invoking the predefined `version` RPC function.\n const { error } = await this.client.rpc(\"version\");\n\n // If the `version` RPC function does not exist, consider it non-critical — connection is verified.\n if (\n error &&\n !error.message.includes('function \"version\" does not exist')\n ) {\n return failure(\n new DatabaseError(\n `Failed to initialize Supabase adapter: ${error.message}`,\n DATABASE_ERROR_CODES.INIT_FAILED,\n {\n context: {\n source: \"SupabaseAdapter.initialize\",\n },\n cause: error,\n },\n ),\n );\n }\n\n return success();\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to initialize Supabase adapter: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.INIT_FAILED,\n {\n context: {\n source: \"SupabaseAdapter.initialize\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Connect to the database.\n * @returns {Promise<void>} Promise that resolves when connected.\n * @description\n * Supabase handles connections automatically, so this method is a no-op.\n * The Supabase client manages connections internally, establishing them as needed\n * and handling connection pooling. This method is included for interface compatibility\n * but does not perform any connection operations.\n */\n async connect(): Promise<void> {\n // Supabase handles connections automatically\n }\n\n /**\n * Disconnect from the database.\n * @returns {Promise<void>} Promise that resolves when disconnected.\n * @description\n * Supabase handles disconnections automatically, so this method is a no-op.\n * The Supabase client manages connections internally, closing them when appropriate.\n * This method is included for interface compatibility but does not perform any\n * disconnection operations.\n */\n async disconnect(): Promise<void> {\n // Supabase handles disconnections automatically\n }\n\n /**\n * Closes the database connection and cleanup resources.\n * Supabase handles connections automatically, so this just returns success.\n * @returns Promise resolving to DatabaseResult indicating success.\n */\n async close(): Promise<DatabaseResult<void>> {\n await this.disconnect();\n return success();\n }\n\n /**\n * Gets the underlying Supabase client instance.\n * @template TClient - The type of the Supabase client to return.\n * @returns {TClient} The Supabase client instance cast to the specified client type.\n * @description\n * This method provides access to the underlying Supabase client.\n * Although direct access is technically possible, it is discouraged to maintain\n * abstraction and ensure that all database operations go through the adapter’s\n * interface for consistent error handling, logging, and event management.\n */\n getClient<TClient extends object = object>(): TClient {\n return this.client as TClient;\n }\n\n /**\n * Execute a raw SQL query.\n * @template T - The expected type of the query result rows.\n * @param {string} sql - SQL query string.\n * @param {T[]} [params] - Query parameters.\n * @returns {Promise<T[]>} Promise resolving to query results.\n * @description\n * Executes a raw SQL query against the database using Supabase's RPC function.\n * This method is useful for complex queries that cannot be easily expressed using the adapter's\n * built-in methods or for database-specific operations. The method uses parameterized queries\n * to prevent SQL injection attacks. If the query execution fails, a DatabaseError is thrown.\n * Note that this requires a custom RPC function named 'exec_sql' to be set up in your Supabase project.\n */\n async query<T>(sql: string, params?: T[]): Promise<T[]> {\n try {\n const { data, error } = await this.client.rpc(\"exec_sql\", {\n sql,\n params,\n });\n if (error)\n throw new DatabaseError(\n `Failed to execute query: ${sql} - ${error.message}`,\n DATABASE_ERROR_CODES.QUERY_FAILED,\n {\n context: {\n source: \"SupabaseAdapter.query\",\n },\n cause: error,\n },\n );\n return data as T[];\n } catch (error) {\n throw new DatabaseError(\n `Failed to execute query: ${sql} - ${(error as Error).message}`,\n DATABASE_ERROR_CODES.QUERY_FAILED,\n {\n context: {\n source: \"SupabaseAdapter.query\",\n },\n cause: error as Error,\n },\n );\n }\n }\n\n /**\n * Register a table with the adapter.\n * @template TTable - Type representing the table structure.\n * @template TIdColumn - Type representing the ID column.\n * @param {string} name - Logical name for the table.\n * @param {TTable} [table] - Actual table name (defaults to logical name if not provided).\n * @param {TIdColumn} [idColumn] - Optional ID column name.\n * @description\n * Registers a table with the adapter, allowing it to be referenced by a logical name\n * in subsequent operations. This is necessary for the adapter to perform operations\n * on the table. The ID column can also be specified if it differs from the default 'id'.\n * This registration enables the adapter to map logical table names to actual table names\n * and ID columns, providing a layer of abstraction between the application and the database schema.\n * If no table name is provided, the logical name is used as the actual table name.\n */\n registerTable<TTable, TIdColumn>(\n name: string,\n table?: TTable,\n idColumn?: TIdColumn,\n ): void {\n this.tableMap.set(name, (table as string) || name);\n if (idColumn) {\n this.idColumnMap.set(name, idColumn as string);\n }\n }\n\n /**\n * Find a single record by ID.\n * @template T - The expected type of the record.\n * @param {string} table - Table name.\n * @param {string} id - Record ID.\n * @returns {Promise<DatabaseResult<T | null>>} Promise resolving to DatabaseResult containing the record or null.\n * @description\n * Retrieves a single record from the specified table using its primary ID.\n * The method uses Supabase's select method with a filter for the ID column and\n * the single() method to retrieve exactly one record. If the record is found,\n * it is returned in a success result. If no record is found (indicated by error code PGRST116),\n * null is returned in a success result. If an error occurs during the operation,\n * a failure result with an error message is returned.\n */\n async findById<T>(\n table: string,\n id: string,\n ): Promise<DatabaseResult<T | null>> {\n try {\n const tableName = this.getTableName(table);\n const idColumn = this.idColumnMap.get(table) ?? \"id\";\n const { data, error } = await this.client\n .from(tableName)\n .select(\"*\")\n .eq(idColumn, id)\n .single();\n\n if (error) {\n if (error.code === \"PGRST116\") {\n return success();\n }\n return failure(\n new DatabaseError(\n `Failed to find by id in table ${table}: ${error.message}`,\n DATABASE_ERROR_CODES.FIND_BY_ID_FAILED,\n {\n context: {\n source: \"SupabaseAdapter.findById\",\n },\n cause: error,\n },\n ),\n );\n }\n\n return success(data as T);\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to find by id in table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.FIND_BY_ID_FAILED,\n {\n context: {\n source: \"SupabaseAdapter.findById\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Find multiple records with filtering and pagination.\n * @template T - The expected type of the records.\n * @param {string} table - Table name.\n * @param {QueryOptions} [options] - Query options including filters, sorting, and pagination.\n * @returns {Promise<DatabaseResult<PaginatedResult<T>>>} Promise resolving to DatabaseResult containing paginated data.\n * @description\n * Retrieves multiple records from the specified table with support for filtering,\n * sorting, and pagination. The method first executes a count query to get the\n * total number of matching records, then executes the main query with the applied filters,\n * sorting, and pagination. The result includes the data array, total count of matching records,\n * and pagination metadata such as current page, total pages, and limit.\n * If an error occurs during the operation, a failure result with an error message is returned.\n */\n // eslint-disable-next-line complexity\n async findMany<T extends Record<string, unknown>>(\n table: string,\n options?: QueryOptions<T>,\n ): Promise<DatabaseResult<PaginatedResult<T>>> {\n try {\n const tableName = this.getTableName(table);\n let query = this.client.from(tableName).select(\"*\");\n\n // Apply filters if provided\n if (options?.filter) {\n query = this.applyFilter(query, options.filter);\n }\n\n // Get total count for pagination\n let countQuery = this.client\n .from(tableName)\n .select(\"*\", { count: \"exact\", head: true });\n if (options?.filter) {\n countQuery = this.applyFilter(countQuery, options.filter);\n }\n const { count, error: countError } = await countQuery;\n\n if (countError) {\n return failure(\n new DatabaseError(\n `Failed to count records in table ${table}: ${countError.message}`,\n DATABASE_ERROR_CODES.COUNT_FAILED,\n {\n context: {\n source: \"SupabaseAdapter.findMany\",\n },\n cause: countError,\n },\n ),\n );\n }\n\n // Apply sorting if provided\n if (options?.sort) {\n options.sort.forEach((sortOption) => {\n query = query.order(sortOption.field, {\n ascending: sortOption.direction === \"asc\",\n });\n });\n }\n\n // Apply pagination if provided\n if (options?.pagination) {\n if (options.pagination.offset !== undefined) {\n query = query.range(\n options.pagination.offset,\n options.pagination.offset +\n (options.pagination.limit ?? NUMERIX.TEN) -\n 1,\n );\n } else if (options.pagination.limit !== undefined) {\n query = query.limit(options.pagination.limit);\n }\n }\n\n const { data, error } = await query;\n\n if (error) {\n return failure(\n new DatabaseError(\n `Failed to find many in table ${table}: ${error.message}`,\n DATABASE_ERROR_CODES.FIND_MANY_FAILED,\n {\n context: {\n source: \"SupabaseAdapter.findMany\",\n },\n cause: error,\n },\n ),\n );\n }\n\n const total = count ?? 0;\n\n return success({\n data: data as T[],\n total,\n pagination: calculatePagination(total, options?.pagination),\n });\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to find many in table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.FIND_MANY_FAILED,\n {\n context: {\n source: \"SupabaseAdapter.findMany\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Create a new record.\n * @template T - The expected type of the record.\n * @param {string} table - Table name.\n * @param {T} data - Record data to create.\n * @returns {Promise<DatabaseResult<T>>} Promise resolving to DatabaseResult containing the created record.\n * @description\n * Inserts a new record into the specified table using the provided data.\n * The method uses Supabase's insert method with the data and then chains a select()\n * and single() call to retrieve the inserted record with any auto-generated fields\n * (like IDs) populated. If the operation is successful, it returns the created record.\n * If an error occurs during the operation, a failure result with an error message is returned.\n */\n async create<T>(table: string, data: T): Promise<DatabaseResult<T>> {\n try {\n const tableName = this.getTableName(table);\n const { data: result, error } = await this.client\n .from(tableName)\n .insert(data)\n .select()\n .single();\n\n if (error) {\n return failure(\n new DatabaseError(\n `Failed to create in table ${table}: ${error.message}`,\n DATABASE_ERROR_CODES.CREATE_FAILED,\n {\n context: {\n source: \"SupabaseAdapter.create\",\n },\n cause: error,\n },\n ),\n );\n }\n\n return success(result as T);\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to create in table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.CREATE_FAILED,\n {\n context: {\n source: \"SupabaseAdapter.create\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Update an existing record.\n * @template T - The expected type of the record.\n * @param {string} table - Table name.\n * @param {string} id - Record ID.\n * @param {Partial<T>} data - Partial record data to update.\n * @returns {Promise<DatabaseResult<T>>} Promise resolving to DatabaseResult containing the updated record.\n * @description\n * Updates an existing record in the specified table using its primary ID.\n * Only the fields provided in the data object are updated, allowing for partial updates.\n * The method uses Supabase's update method with the data and a filter for the ID column,\n * then chains a select() and single() call to retrieve the updated record. If the operation\n * is successful, it returns the updated record. If an error occurs during the operation,\n * a failure result with an error message is returned.\n */\n async update<T>(\n table: string,\n id: string,\n data: Partial<T>,\n ): Promise<DatabaseResult<T>> {\n try {\n const tableName = this.getTableName(table);\n const idColumn = this.idColumnMap.get(table) ?? \"id\";\n const { data: result, error } = await this.client\n .from(tableName)\n .update(data)\n .eq(idColumn, id)\n .select()\n .single();\n\n if (error) {\n return failure(\n new DatabaseError(\n `Failed to update in table ${table}: ${error.message}`,\n DATABASE_ERROR_CODES.UPDATE_FAILED,\n {\n context: {\n source: \"SupabaseAdapter.update\",\n },\n cause: error,\n },\n ),\n );\n }\n\n return success(result as T);\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to update in table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.UPDATE_FAILED,\n {\n context: {\n source: \"SupabaseAdapter.update\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Delete a record.\n * @param {string} table - Table name.\n * @param {string} id - Record ID.\n * @returns {Promise<DatabaseResult<void>>} Promise resolving to DatabaseResult indicating success or failure.\n * @description\n * Deletes a record from the specified table using its primary ID.\n * The method uses Supabase's delete method with a filter for the ID column.\n * If the operation is successful, it returns a success result with no value.\n * If an error occurs during the operation, a failure result with an error message is returned.\n */\n async delete(table: string, id: string): Promise<DatabaseResult<void>> {\n try {\n const tableName = this.getTableName(table);\n const idColumn = this.idColumnMap.get(table) ?? \"id\";\n const { error } = await this.client\n .from(tableName)\n .delete()\n .eq(idColumn, id);\n\n if (error) {\n return failure(\n new DatabaseError(\n `Failed to delete from table ${table}: ${error.message}`,\n DATABASE_ERROR_CODES.DELETE_FAILED,\n {\n context: {\n source: \"SupabaseAdapter.delete\",\n },\n cause: error,\n },\n ),\n );\n }\n\n return success();\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to delete from table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.DELETE_FAILED,\n {\n context: {\n source: \"SupabaseAdapter.delete\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Execute a transaction.\n * @template T - The expected type of the transaction result.\n * @param {(trx: Transaction) => Promise<T>} callback - Function containing transaction operations.\n * @returns {Promise<DatabaseResult<T>>} Promise resolving to DatabaseResult containing the transaction result.\n * @description\n * Executes a callback function within a database transaction, providing atomicity.\n * Note that Supabase doesn't support traditional multi-statement transactions in the same way\n * as direct database connections. This adapter simulates transactional behavior by executing\n * all operations through the same client, but does not provide true rollback capabilities.\n * If the callback function executes successfully, the transaction is considered committed.\n * If an error occurs during the execution of the callback function, a failure result with\n * an error message is returned, but any successful operations within the callback will not\n * be rolled back.\n */\n async transaction<T>(\n callback: (trx: Transaction) => Promise<T>,\n ): Promise<DatabaseResult<T>> {\n try {\n // Create a transaction object that uses the same client\n const trx: Transaction = {\n findById: async <T>(table: string, id: string) => {\n return this.findById<T>(table, id);\n },\n create: async <T>(table: string, data: T) => {\n return this.create<T>(table, data);\n },\n update: async <T>(table: string, id: string, data: Partial<T>) => {\n return this.update<T>(table, id, data);\n },\n delete: async (table: string, id: string) => {\n return this.delete(table, id);\n },\n commit: async () => {\n // No-op for Supabase\n },\n rollback: async () => {\n // No-op for Supabase\n },\n };\n\n const result = await callback(trx);\n return success(result);\n } catch (error) {\n return failure(\n new DatabaseError(\n `Transaction failed: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.TRANSACTION_FAILED,\n {\n context: {\n source: \"SupabaseAdapter.transaction\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Check if a record exists.\n * @param {string} table - Table name.\n * @param {string} id - Record ID.\n * @returns {Promise<DatabaseResult<boolean>>} Promise resolving to DatabaseResult containing boolean indicating existence.\n * @description\n * Checks if a record with the specified ID exists in the table.\n * The method constructs a SELECT query with a WHERE clause for the ID column\n * and a LIMIT of 1. It returns a success result with a boolean value indicating\n * whether the record exists. If an error occurs during the operation, a failure result\n * with an error message is returned.\n */\n async exists(table: string, id: string): Promise<DatabaseResult<boolean>> {\n try {\n const tableName = this.getTableName(table);\n const idColumn = this.idColumnMap.get(table) ?? \"id\";\n const { data, error } = await this.client\n .from(tableName)\n .select(idColumn)\n .eq(idColumn, id)\n .limit(1);\n\n if (error) {\n return failure(\n new DatabaseError(\n `Failed to check existence in table ${table}: ${error.message}`,\n DATABASE_ERROR_CODES.EXISTS_FAILED,\n {\n context: {\n source: \"SupabaseAdapter.exists\",\n },\n cause: error,\n },\n ),\n );\n }\n return success((data && data.length > 0) || false);\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to check existence in table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.EXISTS_FAILED,\n {\n context: {\n source: \"SupabaseAdapter.exists\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Count records matching a filter.\n * @param {string} table - Table name.\n * @param {Filter} [filter] - Filter conditions.\n * @returns {Promise<DatabaseResult<number>>} Promise resolving to DatabaseResult containing the count.\n * @description\n * Counts the number of records in the specified table that match the optional filter.\n * The method uses Supabase's select method with the count option set to 'exact'\n * and head set to true to return only the count. If a filter is provided,\n * it is applied to narrow down the count to matching records. It returns a success\n * result with the count of matching records. If an error occurs during the operation,\n * a failure result with an error message is returned.\n */\n async count<T extends Record<string, unknown> = Record<string, unknown>>(\n table: string,\n filter?: Filter<T>,\n ): Promise<DatabaseResult<number>> {\n try {\n const tableName = this.getTableName(table);\n let query = this.client\n .from(tableName)\n .select(\"*\", { count: \"exact\", head: true });\n\n if (filter) {\n query = this.applyFilter(query, filter);\n }\n\n const { count, error } = await query;\n\n if (error) {\n return failure(\n new DatabaseError(\n `Failed to count in table ${table}: ${error.message}`,\n DATABASE_ERROR_CODES.COUNT_FAILED,\n {\n context: {\n source: \"SupabaseAdapter.count\",\n },\n cause: error,\n },\n ),\n );\n }\n return success(count ?? 0);\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to count in table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.COUNT_FAILED,\n {\n context: {\n source: \"SupabaseAdapter.count\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Perform health check.\n * @returns {Promise<DatabaseResult<DatabaseHealthStatus>>} Promise resolving to DatabaseResult containing health status.\n * @description\n * Checks the health of the database connection by executing a simple RPC call.\n * The method measures the response time of the query to determine the health status.\n * It attempts to call a 'version' RPC function, ignoring errors related to the function\n * not existing but reporting other errors. It returns a success result with a DatabaseHealthStatus\n * object indicating whether the database is healthy, the response time of the health check,\n * and any additional details. If an error occurs during the operation, a failure result\n * with an error message is returned.\n */\n async healthCheck(): Promise<DatabaseResult<DatabaseHealthStatus>> {\n const startTime = Date.now();\n try {\n const { error } = await this.client.rpc(\"version\");\n const responseTime = Date.now() - startTime;\n\n if (\n error &&\n !error.message.includes('function \"version\" does not exist')\n ) {\n return success({\n isHealthy: false,\n responseTime,\n details: { adapter: \"supabase\", error: error.message },\n });\n }\n return success({\n isHealthy: true,\n responseTime,\n details: { adapter: \"supabase\" },\n });\n } catch (error) {\n const responseTime = Date.now() - startTime;\n return success({\n isHealthy: false,\n responseTime,\n details: { adapter: \"supabase\", error: (error as Error).message },\n });\n }\n }\n\n /**\n * Get the actual table name from the mapped table name.\n * @private\n * @param {string} name - Logical table name.\n * @returns {string} Actual table name.\n * @description\n * Retrieves the actual table name. If not registered, auto-registers it.\n * This enables seamless table operations without manual registration.\n */\n private getTableName(name: string): string {\n let tableName = this.tableMap.get(name);\n if (!tableName) {\n // Auto-register table with same name\n // Only set ID column from config if not already registered (runtime override takes precedence)\n const hasRuntimeIdColumn = this.idColumnMap.has(name);\n const customIdColumn = hasRuntimeIdColumn\n ? undefined\n : this.configIdColumns[name];\n this.registerTable(name, name, customIdColumn);\n tableName = name;\n }\n return tableName;\n }\n\n /**\n * Applies filter conditions to a Supabase query with comprehensive operator support\n *\n * Transforms generic Filter objects into Supabase-specific query methods while maintaining\n * type safety and preventing SQL injection through operator validation.\n *\n * **Supported Operators:**\n * - Equality: eq, ne (not equal)\n * - Comparison: gt, gte, lt, lte\n * - Pattern: like (with % wildcards)\n * - Membership: in, notIn (array values)\n * - Range: between (two-element array)\n * - Null checks: isNull, isNotNull\n *\n * **Security Features:**\n * - Validates field names against regex: /^[a-zA-Z_][a-zA-Z0-9_]*$/\n * - Validates operator against whitelist\n * - Type-checks array values for 'in', 'notIn', 'between' operators\n *\n * @private\n * @template Q - Type of the Supabase query builder\n * @param {Q} query - Supabase query builder instance to apply filters to\n * @param {Filter} filter - Filter conditions with field, operator, and value\n * @returns {Q} Modified query builder with filter conditions applied\n *\n * @throws {BaseError} SUPABASE_INVALID_FILTER - If 'in'/'notIn' value is not an array\n * @throws {BaseError} SUPABASE_INVALID_FILTER - If 'between' value is not a 2-element array\n * @throws {BaseError} SUPABASE_UNSUPPORTED_OPERATOR - If operator is not in whitelist\n *\n * @example\n * ```typescript\n * // Equality filter\n * const query1 = this.applyFilter(baseQuery, {\n * field: 'status',\n * operator: 'eq',\n * value: 'active'\n * });\n * // Generates: query.eq('status', 'active')\n *\n * // Range filter\n * const query2 = this.applyFilter(baseQuery, {\n * field: 'age',\n * operator: 'between',\n * value: [18, 65]\n * });\n * // Generates: query.gte('age', 18).lte('age', 65)\n *\n * // Array membership filter\n * const query3 = this.applyFilter(baseQuery, {\n * field: 'category',\n * operator: 'in',\n * value: ['tech', 'science', 'business']\n * });\n * // Generates: query.in('category', ['tech', 'science', 'business'])\n * ```\n *\n */\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private applyFilter<T extends object = object>(q: any, f: Filter<T>): any {\n const { field, operator, value } = f;\n\n const ops: Record<string, Function> = {\n eq: () => q.eq(field, value),\n ne: () => q.neq(field, value),\n gt: () => q.gt(field, value),\n gte: () => q.gte(field, value),\n lt: () => q.lt(field, value),\n lte: () => q.lte(field, value),\n like: () => q.like(field, value),\n isNull: () => q.is(field, null),\n isNotNull: () => q.isNot(field, null),\n in: () => {\n if (!Array.isArray(value))\n throw new DatabaseError(\n `'in' requires array`,\n DATABASE_ERROR_CODES.INVALID_FILTER,\n );\n return q.in(field, value);\n },\n notIn: () => {\n if (!Array.isArray(value))\n throw new DatabaseError(\n `'notIn' requires array`,\n DATABASE_ERROR_CODES.INVALID_FILTER,\n );\n return q.notIn(field, value);\n },\n between: () => {\n if (!Array.isArray(value) || value.length !== NUMERIX.TWO)\n throw new DatabaseError(\n `'between' requires [min,max]`,\n DATABASE_ERROR_CODES.INVALID_FILTER,\n );\n return q.gte(field, value[0]).lte(field, value[1]);\n },\n };\n\n if (!ops[operator])\n throw new DatabaseError(\n `Unsupported operator: ${operator}`,\n DATABASE_ERROR_CODES.UNSUPPORTED_OPERATOR,\n );\n return ops[operator]();\n }\n}\n","import type { PoolClient } from \"pg\";\nimport { Pool } from \"pg\";\nimport type {\n SQLAdapterConfig,\n Transaction,\n DatabaseResult,\n PaginatedResult,\n QueryOptions,\n DatabaseHealthStatus,\n Filter,\n DatabaseAdapterType,\n} from \"@plyaz/types/db\";\nimport { failure, success } from \"@utils/databaseResultHelpers\";\nimport { DatabaseError } from \"@plyaz/errors\";\nimport { DATABASE_ERROR_CODES } from \"@plyaz/types/errors\";\nimport { calculatePagination } from \"@utils/pagination\";\nimport { isNonEmptyString, isObject } from \"@utils/typeGuards\";\nimport { DB_REGEX } from \"@utils/regex\";\n\n/** Maximum characters of SQL to include in error messages */\nconst SQL_ERROR_TRUNCATE_LENGTH = 500;\n\n/**\n * @class SQLAdapter\n * @implements {DatabaseAdapterType}\n * @classdesc\n * Plain SQL adapter implementation for raw SQL queries.\n *\n * This adapter provides an interface to interact with SQL databases using raw SQL queries,\n * supporting CRUD operations, transactions, and health checks. It uses PostgreSQL's node-pg\n * driver for database connectivity and provides a simple, direct SQL interface without\n * ORM abstractions. This adapter is ideal for applications that require direct control\n * over SQL queries or need to leverage database-specific features.\n */\nexport class SQLAdapter implements DatabaseAdapterType {\n private pool: Pool;\n private config: SQLAdapterConfig;\n private tableMap: Map<string, string> = new Map();\n private idColumnMap: Map<string, string> = new Map();\n private configIdColumns: Record<string, string>;\n private defaultSchema: string;\n private showSqlInErrors: boolean;\n\n /**\n * Creates a new SQLAdapter instance.\n * @param {SQLAdapterConfig} config - Configuration for the SQL adapter.\n * @description\n * Initializes the adapter with the provided configuration, setting up the connection pool\n * for PostgreSQL database connections. The configuration should include a connection string\n * and optional pool settings such as min/max connections and idle timeout. The adapter\n * maintains internal maps for table names and ID columns to provide a level of abstraction\n * over the raw database schema.\n */\n constructor(config: SQLAdapterConfig) {\n this.config = config;\n this.defaultSchema = config.schema ?? \"public\";\n this.showSqlInErrors = config.showSqlInErrors ?? true;\n this.pool = new Pool({\n connectionString: config.connectionString,\n ...config.pool,\n });\n // Store custom ID column mappings from config\n this.configIdColumns = config.tableIdColumns ?? {};\n }\n\n /**\n * Get fully-qualified table name with schema\n */\n private getQualifiedTableName(table: string, schema?: string): string {\n const targetSchema = schema ?? this.defaultSchema;\n\n // If table already has schema prefix (e.g., \"tenant_acme.users\"), use as-is\n if (table.includes(\".\")) {\n return table;\n }\n\n // Apply schema prefix\n return `${targetSchema}.${table}`;\n }\n\n /**\n * Initialize the adapter.\n * @returns {Promise<DatabaseResult<void>>} Promise resolving to DatabaseResult indicating success or failure.\n * @description\n * Tests the database connection by attempting to establish a connection to the database.\n * This method is typically called during application startup to verify that the adapter\n * can communicate with the database before performing any operations. Returns a success\n * result if the connection is established, or a failure result with an error if the\n * connection cannot be established.\n */\n async initialize(): Promise<DatabaseResult<void>> {\n try {\n const client = await this.pool.connect();\n\n // Set search_path for the connection if schema is configured\n if (this.defaultSchema && this.defaultSchema !== \"public\") {\n await client.query(`SET search_path TO ${this.defaultSchema}, public`);\n }\n\n client.release();\n return success();\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to initialize PlainSQL adapter: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.INIT_FAILED,\n {\n context: {\n source: \"SQLAdapter.initialize\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Connect to the database.\n * @returns {Promise<void>} Promise that resolves when connected.\n * @description\n * Establishes a connection to the PostgreSQL database using the connection pool.\n * This method is called to ensure that a connection is available before performing database operations.\n * The connection pool manages the connections efficiently, reusing them when possible.\n */\n async connect(): Promise<void> {\n await this.pool.connect();\n }\n\n /**\n * Disconnect from the database.\n * @returns {Promise<void>} Promise that resolves when disconnected.\n * @description\n * Gracefully shuts down the connection pool, closing all active connections.\n * This method should be called when the adapter is no longer needed, typically during\n * application shutdown, to free up database resources and prevent connection leaks.\n */\n async disconnect(): Promise<void> {\n await this.pool.end();\n }\n\n /**\n * Closes the database connection and cleanup resources.\n * @returns Promise resolving to DatabaseResult indicating success or failure.\n */\n async close(): Promise<DatabaseResult<void>> {\n try {\n await this.disconnect();\n return success();\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to close connection: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.DISCONNECT_FAILED,\n ),\n );\n }\n }\n\n /**\n * Gets the underlying PostgreSQL client instance.\n * @template TClient - The type of the database client to return.\n * @returns {TClient} The PostgreSQL pool instance cast to the specified client type.\n * @description\n * This method provides access to the underlying PostgreSQL connection pool.\n * While direct access is technically possible, it is generally discouraged to\n * preserve abstraction and ensure all database operations go through the adapter’s\n * interface for consistent error handling, logging, and event management.\n */\n getClient<TClient extends object = object>(): TClient {\n return this.pool as TClient;\n }\n\n /**\n * Execute a raw SQL query.\n * @template T - The expected type of the query result rows.\n * @param {string} sql - SQL query string.\n * @param {T[]} [params] - Query parameters.\n * @returns {Promise<T[]>} Promise resolving to query results.\n * @description\n * Executes a raw SQL query against the database, with optional parameterization.\n * This method is useful for complex queries that cannot be easily expressed using the adapter's\n * built-in methods or for database-specific operations. The method uses parameterized queries\n * to prevent SQL injection attacks. If the query execution fails, a DatabaseError is thrown.\n */\n async query<T>(sql: string, params?: T[]): Promise<T[]> {\n try {\n const result = await this.pool.query(sql, params);\n return result.rows as T[];\n } catch (error) {\n // Optionally include SQL in error message for debugging (default: true)\n const truncatedSql = sql.slice(0, SQL_ERROR_TRUNCATE_LENGTH);\n const sqlSuffix = sql.length > SQL_ERROR_TRUNCATE_LENGTH ? \"...\" : \"\";\n const errorMessage = this.showSqlInErrors\n ? `SQL Error: ${(error as Error).message}\\n Query: ${truncatedSql}${sqlSuffix}`\n : `SQL Error: ${(error as Error).message}`;\n\n throw new DatabaseError(errorMessage, DATABASE_ERROR_CODES.QUERY_FAILED, {\n context: {\n source: \"SQLAdapter.query\",\n },\n cause: error as Error,\n });\n }\n }\n\n /**\n * Register a table with the adapter.\n * @template TTable - Type representing the table structure.\n * @template TIdColumn - Type representing the ID column.\n * @param {string} name - Logical name for the table.\n * @param {TTable} [table] - Table name or object.\n * @param {TIdColumn} [idColumn] - Optional ID column name.\n * @description\n * Registers a table with the adapter, allowing it to be referenced by a logical name\n * in subsequent operations. This is necessary for the adapter to perform operations\n * on the table. The ID column can also be specified if it differs from the default 'id'.\n * This registration enables the adapter to map logical table names to actual table names\n * and ID columns, providing a layer of abstraction between the application and the database schema.\n */\n registerTable<TTable, TIdColumn>(\n name: string,\n table?: TTable,\n idColumn?: TIdColumn,\n ): void {\n this.tableMap.set(name, table as string);\n\n if (idColumn) {\n this.idColumnMap.set(name, idColumn as string);\n }\n }\n\n /**\n * Find a single record by ID.\n * @template T - The expected type of the record.\n * @param {string} table - Table name.\n * @param {string} id - Record ID.\n * @returns {Promise<DatabaseResult<T | null>>} Promise resolving to DatabaseResult containing the record or null.\n * @description\n * Retrieves a single record from the specified table using its primary ID.\n * The method constructs a SELECT query with a WHERE clause for the ID column.\n * If the record is found, it is returned in a success result. If no record is found,\n * null is returned in a success result. If an error occurs during the operation,\n * a failure result with an error message is returned.\n */\n async findById<T>(\n table: string,\n id: string,\n ): Promise<DatabaseResult<T | null>> {\n try {\n const validationError = this.validateBasicParams(table, id);\n if (validationError) return failure(validationError);\n\n const tableName = this.getTableName(table);\n const qualifiedTable = this.getQualifiedTableName(tableName);\n const idColumn = this.getIdColumn(table);\n const sql = `SELECT * FROM ${qualifiedTable} WHERE \"${idColumn}\" = $1`;\n const result = await this.pool.query(sql, [id]);\n\n if (!result?.rows) {\n return failure(\n new DatabaseError(\n \"Invalid query result\",\n DATABASE_ERROR_CODES.INVALID_RESULT,\n ),\n );\n }\n\n return success((result.rows?.[0] as T) ?? null);\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to find record: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.FIND_BY_ID_FAILED,\n {\n context: {\n source: \"SQLAdapter.findById\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Find multiple records with filtering and pagination.\n * @template T - The expected type of the records.\n * @param {string} table - Table name.\n * @param {QueryOptions} [options] - Query options including filters, sorting, and pagination.\n * @returns {Promise<DatabaseResult<PaginatedResult<object>>>} Promise resolving to DatabaseResult containing paginated data.\n * @description\n * Retrieves multiple records from the specified table with support for filtering,\n * sorting, and pagination. The method constructs a SELECT query with optional WHERE,\n * ORDER BY, LIMIT, and OFFSET clauses. It first executes a COUNT query to get the\n * total number of matching records, then executes the main query with the applied filters,\n * sorting, and pagination. The result includes the data array, total count of matching records,\n * and pagination metadata such as current page, total pages, and offset.\n * If an error occurs during the operation, a failure result with an error message is returned.\n */\n /**\n * Finds multiple records from the specified table with optional filtering, sorting, and pagination.\n * @template TRecord - Type representing the shape of records returned.\n * @template TOptions - Query options type.\n * @template TParam - Type of query parameters (primitives).\n * @param {string} table - Name of the table to query.\n * @param {TOptions} [options] - Optional query options for filtering, sorting, and pagination.\n * @returns {Promise<DatabaseResult<PaginatedResult<TRecord>>>} - A promise resolving to a paginated result.\n * @throws {DatabaseError} - When query execution or initialization fails.\n */\n /**\n * Finds multiple records from the specified table with optional filtering, sorting, and pagination.\n * @template T - Type representing the shape of records returned.\n * @param {string} table - Name of the table to query.\n * @param {QueryOptions<object>} [options] - Optional query options for filtering, sorting, and pagination.\n * @returns {Promise<DatabaseResult<PaginatedResult<T>>>} - A promise resolving to a paginated result.\n * @throws {DatabaseError} - When query execution or initialization fails.\n */\n // eslint-disable-next-line complexity\n async findMany<T extends Record<string, unknown>>(\n table: string,\n options?: QueryOptions<T>,\n ): Promise<DatabaseResult<PaginatedResult<T>>> {\n try {\n const tableName = this.getTableName(table);\n const qualifiedTable = this.getQualifiedTableName(tableName);\n const params: Object[] = [];\n let whereClause = \"\";\n let paramIndex = 1;\n\n // Build WHERE clause\n if (options?.filter) {\n whereClause = this.buildWhereClause(options.filter, params, paramIndex);\n paramIndex += params.length;\n }\n\n // Count total\n const countSql = `SELECT COUNT(*) as total FROM ${qualifiedTable}${whereClause}`;\n const countResult = await this.pool.query(countSql, params);\n\n if (!countResult.rows || countResult.rows.length === 0) {\n throw new DatabaseError(\n \"Count query returned no results\",\n DATABASE_ERROR_CODES.COUNT_NO_RESULTS,\n );\n }\n\n const total = Number.parseInt(countResult.rows[0].total);\n if (isNaN(total) || total < 0) {\n throw new DatabaseError(\n \"Invalid count result\",\n DATABASE_ERROR_CODES.INVALID_COUNT,\n );\n }\n\n // ORDER BY clause\n let orderClause = \"\";\n if (options?.sort?.length) {\n orderClause =\n \" ORDER BY \" +\n options.sort\n .map((s) => `${s.field} ${s.direction.toUpperCase()}`)\n .join(\", \");\n }\n\n // LIMIT & OFFSET\n let limitClause = \"\";\n if (options?.pagination?.limit) {\n limitClause += ` LIMIT $${paramIndex++}`;\n params.push(options.pagination.limit);\n }\n if (options?.pagination?.offset) {\n limitClause += ` OFFSET $${paramIndex++}`;\n params.push(options.pagination.offset);\n }\n\n // Final query\n const sql = `SELECT * FROM ${qualifiedTable}${whereClause}${orderClause}${limitClause}`;\n const result = await this.pool.query(sql, params);\n\n return success({\n data: result.rows as T[],\n total,\n pagination: calculatePagination(total, options?.pagination),\n });\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to find many in table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.FIND_MANY_FAILED,\n {\n context: {\n source: \"SQLAdapter.findMany\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Create a new record.\n * @template T - The expected type of the record.\n * @param {string} table - Table name.\n * @param {T} data - Record data to create.\n * @returns {Promise<DatabaseResult<T>>} Promise resolving to DatabaseResult containing the created record.\n * @description\n * Inserts a new record into the specified table using the provided data.\n * The method constructs an INSERT query with column names and parameter placeholders\n * for the values. After insertion, it returns the inserted record with any auto-generated\n * fields (like IDs) populated using the RETURNING clause. If an error occurs during the operation,\n * a failure result with an error message is returned.\n */\n async create<T>(table: string, data: T): Promise<DatabaseResult<T>> {\n try {\n const validationError = this.validateCreateParams(table, data);\n if (validationError) return failure(validationError);\n\n const tableName = this.getTableName(table);\n const qualifiedTable = this.getQualifiedTableName(tableName);\n const keys = Object.keys(data as Record<string, T>);\n const values = Object.values(data as Record<string, T>);\n const placeholders = values.map((_, i) => `$${i + 1}`).join(\", \");\n const escapedKeys = keys.map((k) => `\"${k}\"`).join(\", \");\n\n const sql = `INSERT INTO ${qualifiedTable} (${escapedKeys}) VALUES (${placeholders}) RETURNING *`;\n const result = await this.pool.query(sql, values);\n\n if (!result?.rows?.length) {\n return failure(\n new DatabaseError(\n \"Insert operation failed\",\n DATABASE_ERROR_CODES.INSERT_FAILED,\n ),\n );\n }\n\n return success(result.rows[0] as T);\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to create record: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.CREATE_FAILED,\n {\n context: {\n source: \"SQLAdapter.create\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Update an existing record.\n * @template T - The expected type of the record.\n * @param {string} table - Table name.\n * @param {string} id - Record ID.\n * @param {Partial<T>} data - Partial record data to update.\n * @returns {Promise<DatabaseResult<T>>} Promise resolving to DatabaseResult containing the updated record.\n * @description\n * Updates an existing record in the specified table using its primary ID.\n * Only the fields provided in the data object are updated, allowing for partial updates.\n * The method constructs an UPDATE query with a SET clause for the fields to update\n * and a WHERE clause for the ID. After updating, it returns the updated record using\n * the RETURNING clause. If an error occurs during the operation, a failure result with\n * an error message is returned.\n */\n async update<T>(\n table: string,\n id: string,\n data: Partial<T>,\n ): Promise<DatabaseResult<T>> {\n try {\n const validationError = this.validateUpdateParams(table, id, data);\n if (validationError) return failure(validationError);\n\n const tableName = this.getTableName(table);\n const qualifiedTable = this.getQualifiedTableName(tableName);\n const keys = Object.keys(data as Record<string, T>);\n const values = Object.values(data as Record<string, T>);\n const setClause = keys.map((key, i) => `\"${key}\" = $${i + 1}`).join(\", \");\n const idColumn = this.getIdColumn(table);\n\n const sql = `UPDATE ${qualifiedTable} SET ${setClause} WHERE \"${idColumn}\" = $${keys.length + 1} RETURNING *`;\n const result = await this.pool.query(sql, [...values, id]);\n\n if (!result.rows?.length) {\n return failure(\n new DatabaseError(\n \"Record not found or no changes made\",\n DATABASE_ERROR_CODES.UPDATE_NO_CHANGES,\n ),\n );\n }\n\n return success(result.rows[0] as T);\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to update record: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.UPDATE_FAILED,\n {\n context: {\n source: \"SQLAdapter.update\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Delete a record.\n * @param {string} table - Table name.\n * @param {string} id - Record ID.\n * @returns {Promise<DatabaseResult<void>>} Promise resolving to DatabaseResult indicating success or failure.\n * @description\n * Deletes a record from the specified table using its primary ID.\n * The method constructs a DELETE query with a WHERE clause for the ID column.\n * If the operation is successful, it returns a success result with no value.\n * If an error occurs during the operation, a failure result with an error message is returned.\n */\n async delete(table: string, id: string): Promise<DatabaseResult<void>> {\n try {\n if (!table || !id) {\n return failure(\n new DatabaseError(\n \"Invalid parameters\",\n DATABASE_ERROR_CODES.INVALID_PARAMS,\n ),\n );\n }\n\n const tableName = this.getTableName(table);\n const qualifiedTable = this.getQualifiedTableName(tableName);\n const idColumn = this.getIdColumn(table);\n const sql = `DELETE FROM ${qualifiedTable} WHERE \"${idColumn}\" = $1`;\n const result = await this.pool.query(sql, [id]);\n\n if (!result) {\n return failure(\n new DatabaseError(\n \"Delete operation failed\",\n DATABASE_ERROR_CODES.DELETE_FAILED,\n ),\n );\n }\n\n return success();\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to delete record: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.DELETE_FAILED,\n {\n context: {\n source: \"SQLAdapter.delete\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Execute a transaction.\n * @template T - The expected type of the transaction result.\n * @param {(trx: Transaction) => Promise<T>} callback - Function containing transaction operations.\n * @returns {Promise<DatabaseResult<T>>} Promise resolving to DatabaseResult containing the transaction result.\n * @description\n * Executes a callback function within a database transaction, providing atomicity.\n * If the callback function executes successfully, the transaction is committed.\n * If an error occurs during the execution of the callback function, the transaction\n * is rolled back, ensuring that no partial changes are applied to the database.\n * The method returns the result of the callback function if successful,\n * or a failure result with an error message if an error occurs.\n * The transaction object passed to the callback provides methods for performing\n * database operations within the transaction.\n */\n async transaction<T>(\n callback: (trx: Transaction) => Promise<T>,\n ): Promise<DatabaseResult<T>> {\n const client: PoolClient = await this.pool.connect();\n try {\n await client.query(\"BEGIN\");\n\n const trx: Transaction = {\n findById: async <T>(table: string, id: string) => {\n const tableName = this.getTableName(table);\n const qualifiedTable = this.getQualifiedTableName(tableName);\n const idColumn = this.getIdColumn(table);\n const sql = `SELECT * FROM ${qualifiedTable} WHERE \"${idColumn}\" = $1`;\n const result = await client.query(sql, [id]);\n return success((result.rows[0] as T) ?? null);\n },\n create: async <T>(table: string, data: T) => {\n const tableName = this.getTableName(table);\n const qualifiedTable = this.getQualifiedTableName(tableName);\n const keys = Object.keys(data as Record<string, T>);\n const values = Object.values(data as Record<string, T>);\n const placeholders = values.map((_, i) => `$${i + 1}`).join(\", \");\n const escapedKeys = keys.map((k) => `\"${k}\"`).join(\", \");\n\n const sql = `INSERT INTO ${qualifiedTable} (${escapedKeys}) VALUES (${placeholders}) RETURNING *`;\n const result = await client.query(sql, values);\n return success(result.rows[0] as T);\n },\n update: async <T>(table: string, id: string, data: Partial<T>) => {\n const tableName = this.getTableName(table);\n const qualifiedTable = this.getQualifiedTableName(tableName);\n const keys = Object.keys(data as Record<string, T>);\n const values = Object.values(data as Record<string, T>);\n const setClause = keys\n .map((key, i) => `\"${key}\" = $${i + 1}`)\n .join(\", \");\n const idColumn = this.getIdColumn(table);\n\n const sql = `UPDATE ${qualifiedTable} SET ${setClause} WHERE \"${idColumn}\" = $${keys.length + 1} RETURNING *`;\n const result = await client.query(sql, [...values, id]);\n return success(result.rows[0] as T);\n },\n delete: async (table: string, id: string) => {\n const tableName = this.getTableName(table);\n const qualifiedTable = this.getQualifiedTableName(tableName);\n const idColumn = this.getIdColumn(table);\n const sql = `DELETE FROM ${qualifiedTable} WHERE \"${idColumn}\" = $1`;\n await client.query(sql, [id]);\n return success();\n },\n commit: async () => {\n await client.query(\"COMMIT\");\n },\n rollback: async () => {\n await client.query(\"ROLLBACK\");\n },\n };\n\n const result = await callback(trx);\n await trx.commit();\n return success(result);\n } catch (error) {\n await client.query(\"ROLLBACK\");\n return failure(\n new DatabaseError(\n `Transaction failed: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.TRANSACTION_FAILED,\n {\n context: {\n source: \"SQLAdapter.transaction\",\n },\n cause: error as Error,\n },\n ),\n );\n } finally {\n client.release();\n }\n }\n\n /**\n * Check if a record exists.\n * @param {string} table - Table name.\n * @param {string} id - Record ID.\n * @returns {Promise<DatabaseResult<boolean>>} Promise resolving to DatabaseResult containing boolean indicating existence.\n * @description\n * Checks if a record with the specified ID exists in the table.\n * The method constructs a SELECT query with a WHERE clause for the ID column\n * and a LIMIT of 1. It returns a success result with a boolean value indicating\n * whether the record exists. If an error occurs during the operation, a failure result\n * with an error message is returned.\n */\n async exists(table: string, id: string): Promise<DatabaseResult<boolean>> {\n try {\n const tableName = this.getTableName(table);\n const qualifiedTable = this.getQualifiedTableName(tableName);\n const idColumn = this.getIdColumn(table);\n const sql = `SELECT 1 FROM ${qualifiedTable} WHERE \"${idColumn}\" = $1 LIMIT 1`;\n const result = await this.pool.query(sql, [id]);\n return success(result.rows.length > 0);\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to check existence in table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.EXISTS_FAILED,\n {\n context: {\n source: \"SQLAdapter.exists\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Count records matching a filter.\n * @param {string} table - Table name.\n * @param {Filter} [filter] - Filter conditions.\n * @returns {Promise<DatabaseResult<number>>} Promise resolving to DatabaseResult containing the count.\n * @description\n * Counts the number of records in the specified table that match the optional filter.\n * The method constructs a COUNT query with an optional WHERE clause based on the filter.\n * It returns a success result with the count of matching records.\n * If an error occurs during the operation, a failure result with an error message is returned.\n */\n async count<T extends Record<string, unknown> = Record<string, unknown>>(\n table: string,\n filter?: Filter<T>,\n ): Promise<DatabaseResult<number>> {\n try {\n const tableName = this.getTableName(table);\n const qualifiedTable = this.getQualifiedTableName(tableName);\n let whereClause = \"\";\n let params: object[] = [];\n\n if (filter) {\n whereClause = this.buildWhereClause(filter, params, 1);\n }\n\n const sql = `SELECT COUNT(*) as count FROM ${qualifiedTable}${whereClause}`;\n const result = await this.pool.query(sql, params);\n const rowCount = Number.parseInt(result.rows[0].count);\n return success(Number(rowCount));\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to count in table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.COUNT_FAILED,\n {\n context: {\n source: \"SQLAdapter.count\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Perform health check.\n * @returns {Promise<DatabaseResult<DatabaseHealthStatus>>} Promise resolving to DatabaseResult containing health status.\n * @description\n * Checks the health of the database connection by executing a simple query.\n * The method measures the response time of the query to determine the health status.\n * It returns a success result with a HealthStatus object indicating whether the database is healthy,\n * the response time of the health check, and any additional details.\n * If an error occurs during the operation, a failure result with an error message is returned.\n */\n async healthCheck(): Promise<DatabaseResult<DatabaseHealthStatus>> {\n const startTime = Date.now();\n try {\n await this.pool.query(\"SELECT 1\");\n const responseTime = Date.now() - startTime;\n return success({\n isHealthy: true,\n responseTime,\n details: { adapter: \"sql\" },\n });\n } catch (error) {\n const responseTime = Date.now() - startTime;\n return success({\n isHealthy: false,\n responseTime,\n details: { adapter: \"sql\", error: (error as Error).message },\n });\n }\n }\n\n /**\n * Get the actual table name from the mapped table name.\n * @private\n * @param {string} name - Logical table name.\n * @returns {string} Actual table name.\n * @description\n * Retrieves the actual table name. If not registered, auto-registers it with\n * the same logical name as the physical table name. This enables seamless\n * table operations without manual registration (matching Supabase adapter behavior).\n */\n private getTableName(name: string): string {\n let tableName = this.tableMap.get(name);\n if (!tableName) {\n // Auto-register table with same name\n // Only set ID column from config if not already registered (runtime override takes precedence)\n const hasRuntimeIdColumn = this.idColumnMap.has(name);\n const customIdColumn = hasRuntimeIdColumn\n ? undefined\n : this.configIdColumns[name];\n this.registerTable(name, name, customIdColumn);\n tableName = name;\n }\n return tableName;\n }\n\n /**\n * Get the ID column for a table.\n * @private\n * @param {string} table - Logical table name.\n * @returns {string} ID column name (defaults to 'id').\n * @description\n * Retrieves the ID column for a table. Checks in this order:\n * 1. Runtime registered ID column (from registerTable calls)\n * 2. Config-provided ID column (from tableIdColumns in config)\n * 3. Default 'id' column\n */\n private getIdColumn(table: string): string {\n // Check runtime registered first\n const runtimeIdColumn = this.idColumnMap.get(table);\n if (runtimeIdColumn) {\n return runtimeIdColumn;\n }\n\n // Check config-provided ID columns\n const configIdColumn = this.configIdColumns[table];\n if (configIdColumn) {\n return configIdColumn;\n }\n\n // Default to 'id'\n return \"id\";\n }\n\n private validateBasicParams(table: string, id: string): DatabaseError | null {\n if (!table || !id) {\n return new DatabaseError(\n \"Invalid parameters\",\n DATABASE_ERROR_CODES.INVALID_PARAMS,\n );\n }\n return null;\n }\n\n private validateCreateParams<T>(\n table: string,\n data: T,\n ): DatabaseError | null {\n if (!isNonEmptyString(table) || !isObject(data)) {\n return new DatabaseError(\n \"Invalid parameters\",\n DATABASE_ERROR_CODES.INVALID_PARAMS,\n );\n }\n\n const keys = Object.keys(data as Record<string, T>);\n if (keys.length === 0) {\n return new DatabaseError(\n \"No data to insert\",\n DATABASE_ERROR_CODES.NO_DATA,\n );\n }\n\n for (const key of keys) {\n if (!DB_REGEX.isValidFieldName(key)) {\n return new DatabaseError(\n \"Invalid field name\",\n DATABASE_ERROR_CODES.INVALID_FIELD_NAME,\n );\n }\n }\n return null;\n }\n\n private validateUpdateParams<T>(\n table: string,\n id: string,\n data: Partial<T>,\n ): DatabaseError | null {\n if (!isNonEmptyString(table) || !isNonEmptyString(id) || !isObject(data)) {\n return new DatabaseError(\n \"Invalid parameters for update operation\",\n DATABASE_ERROR_CODES.INVALID_UPDATE_PARAMS,\n );\n }\n\n const keys = Object.keys(data as Record<string, T>);\n if (keys.length === 0) {\n return new DatabaseError(\n \"No fields to update\",\n DATABASE_ERROR_CODES.NO_UPDATE_FIELDS,\n );\n }\n\n for (const key of keys) {\n if (!DB_REGEX.isValidFieldName(key)) {\n return new DatabaseError(\n \"Invalid field name\",\n DATABASE_ERROR_CODES.INVALID_FIELD_NAME,\n );\n }\n }\n return null;\n }\n\n /**\n * Builds a SQL WHERE clause string from a provided filter definition.\n *\n * @private\n * @template TParams - Tuple type representing the parameter array.\n * @param {Filter} filter - The filter condition containing the field, operator, and value.\n * @param {TParams} params - Mutable array to collect SQL parameter values.\n * @param {number} startIndex - The starting index for SQL parameter placeholders (e.g., $1, $2, ...).\n * @returns {string} The constructed SQL WHERE clause string.\n * @throws {DatabaseError} If an unsupported operator is encountered or if the filter value type is invalid.\n *\n * @description\n * This method dynamically builds a SQL WHERE clause based on the provided `filter` object.\n * It supports operators such as:\n * - `eq`, `ne` (equality and inequality)\n * - `gt`, `gte`, `lt`, `lte` (comparison)\n * - `in` (membership in a list)\n * - `like` (pattern matching)\n * - `between` (range)\n * - `isNull`, `isNotNull` (null checks)\n *\n * The function safely constructs parameterized queries by adding each value\n * into the `params` array and referencing it via `$<index>` placeholders,\n * helping to prevent SQL injection attacks.\n */\n\n // eslint-disable-next-line complexity\n private buildWhereClause<\n T extends Record<string, unknown>,\n TParams extends object[],\n >(filter: Filter<T>, params: unknown[], startIndex: number): string {\n const { field, operator, value } = filter;\n let clause = \"\";\n\n switch (operator) {\n case \"eq\":\n clause = ` WHERE ${field} = $${startIndex}`;\n params.push(value);\n break;\n\n case \"ne\":\n clause = ` WHERE ${field} != $${startIndex}`;\n params.push(value);\n break;\n\n case \"gt\":\n clause = ` WHERE ${field} > $${startIndex}`;\n params.push(value);\n break;\n\n case \"gte\":\n clause = ` WHERE ${field} >= $${startIndex}`;\n params.push(value);\n break;\n\n case \"lt\":\n clause = ` WHERE ${field} < $${startIndex}`;\n params.push(value);\n break;\n\n case \"lte\":\n clause = ` WHERE ${field} <= $${startIndex}`;\n params.push(value);\n break;\n\n case \"in\": {\n if (Array.isArray(value)) {\n const arr = value as readonly TParams[];\n const placeholders = arr\n .map((_, i: number) => `$${startIndex + i}`)\n .join(\", \");\n clause = ` WHERE ${field} IN (${placeholders})`;\n params.push(...arr);\n } else {\n throw new DatabaseError(\n `Operator \"in\" requires an array value.`,\n DATABASE_ERROR_CODES.INVALID_IN_OPERATOR,\n );\n }\n break;\n }\n\n case \"like\":\n clause = ` WHERE ${field} LIKE $${startIndex}`;\n params.push(value as TParams);\n break;\n\n case \"between\": {\n if (Array.isArray(value)) {\n const [min, max] = value as [TParams[number], TParams[number]];\n clause = ` WHERE ${field} BETWEEN $${startIndex} AND $${startIndex + 1}`;\n params.push(min, max);\n } else {\n throw new DatabaseError(\n `Operator \"between\" requires a two-element array.`,\n DATABASE_ERROR_CODES.INVALID_BETWEEN_OPERATOR,\n );\n }\n break;\n }\n\n case \"isNull\":\n clause = ` WHERE ${field} IS NULL`;\n break;\n\n case \"isNotNull\":\n clause = ` WHERE ${field} IS NOT NULL`;\n break;\n\n default:\n throw new DatabaseError(\n `Unsupported operator: ${operator}`,\n DATABASE_ERROR_CODES.UNSUPPORTED_OPERATOR,\n );\n }\n\n return clause;\n }\n}\n","/**\n * MockAdapter - In-Memory Database Adapter for Testing\n *\n * Provides a lightweight, in-memory database adapter that mimics\n * the behavior of real database adapters without requiring an actual\n * database connection. Perfect for unit tests and integration tests.\n *\n * @example\n * ```typescript\n * const db = await createDatabaseService({\n * adapter: 'mock',\n * config: {\n * initialData: {\n * users: [{ id: '1', name: 'Test User', email: 'test@example.com' }],\n * campaigns: [{ id: '1', title: 'Test Campaign', creator_id: '1' }]\n * },\n * autoGenerateIds: true\n * }\n * });\n * ```\n */\n\nimport type {\n DatabaseAdapterType,\n DatabaseResult,\n PaginatedResult,\n QueryOptions,\n Transaction,\n DatabaseHealthStatus,\n Filter,\n DbMockAdapterConfig,\n} from \"@plyaz/types/db\";\n\nimport { success, failure } from \"../../utils/databaseResultHelpers\";\nimport { DatabaseError } from \"@plyaz/errors\";\nimport { DATABASE_ERROR_CODES } from \"@plyaz/types/errors\";\nimport { calculatePagination } from \"../../utils/pagination\";\n\n/** Default pagination limit */\nconst DEFAULT_PAGINATION_LIMIT = 50;\n/** Base for random string generation */\nconst RANDOM_STRING_BASE = 36;\n/** Start index for substring in ID generation */\nconst ID_SUBSTRING_START = 2;\n/** End index for substring in ID generation */\nconst ID_SUBSTRING_END = 9;\n/** Required length for between filter values */\nconst BETWEEN_VALUES_LENGTH = 2;\n\n/** Type for table data storage */\ntype TableDataMap = Map<string, Record<string, unknown>>;\n\n/** Filter operator handler type */\ntype FilterOperatorHandler = (\n fieldValue: unknown,\n filterValue: unknown,\n) => boolean;\n\n/** Lookup map for filter operators */\nconst FILTER_OPERATORS: Record<string, FilterOperatorHandler> = {\n eq: (fieldValue, value) => fieldValue === value,\n ne: (fieldValue, value) => fieldValue !== value,\n gt: (fieldValue, value) => (fieldValue as number) > (value as number),\n gte: (fieldValue, value) => (fieldValue as number) >= (value as number),\n lt: (fieldValue, value) => (fieldValue as number) < (value as number),\n lte: (fieldValue, value) => (fieldValue as number) <= (value as number),\n in: (fieldValue, value) =>\n Array.isArray(value) && (value as unknown[]).includes(fieldValue),\n like: (fieldValue, value) =>\n String(fieldValue).toLowerCase().includes(String(value).toLowerCase()),\n between: (fieldValue, value) => {\n const betweenValues = value as [number, number];\n return (\n Array.isArray(betweenValues) &&\n betweenValues.length === BETWEEN_VALUES_LENGTH &&\n (fieldValue as number) >= betweenValues[0] &&\n (fieldValue as number) <= betweenValues[1]\n );\n },\n isNull: (fieldValue) => fieldValue === null || fieldValue === undefined,\n isNotNull: (fieldValue) => fieldValue !== null && fieldValue !== undefined,\n};\n\n/**\n * MockAdapter - In-memory database adapter for testing\n */\nexport class MockAdapter implements DatabaseAdapterType {\n private data: Map<string, Map<string, Record<string, unknown>>> = new Map();\n private config: DbMockAdapterConfig;\n private tableIdColumns: Map<string, string> = new Map();\n private defaultSchema: string;\n private isInitialized = false;\n private transactionDepth = 0;\n private transactionData: Map<\n string,\n Map<string, Record<string, unknown>>\n > | null = null;\n\n constructor(config: Partial<DbMockAdapterConfig> = {}) {\n this.config = {\n autoGenerateIds: true,\n latency: 0,\n failRate: 0,\n ...config,\n } as DbMockAdapterConfig;\n this.defaultSchema = config.schema ?? \"public\";\n\n // Initialize with provided data\n if (config.initialData) {\n this.initializeTableData(config.initialData);\n }\n\n // Register custom ID columns\n if (config.tableIdColumns) {\n for (const [table, idColumn] of Object.entries(config.tableIdColumns)) {\n this.tableIdColumns.set(table, idColumn);\n }\n }\n }\n\n async initialize(): Promise<DatabaseResult<void>> {\n await this.simulateLatency();\n if (this.shouldFail()) {\n return failure(\n new DatabaseError(\n \"Mock initialization failed\",\n DATABASE_ERROR_CODES.INIT_FAILED,\n ),\n );\n }\n\n this.isInitialized = true;\n return success();\n }\n\n async close(): Promise<DatabaseResult<void>> {\n await this.simulateLatency();\n this.data.clear();\n this.isInitialized = false;\n return success();\n }\n\n registerTable<TTable = string, TIdColumn = string>(\n name: string,\n table?: TTable,\n idColumn?: TIdColumn,\n ): void {\n if (idColumn && typeof idColumn === \"string\") {\n this.tableIdColumns.set(name, idColumn);\n }\n\n // Ensure table exists\n if (!this.data.has(name)) {\n this.data.set(name, new Map());\n }\n }\n\n async findById<T>(\n table: string,\n id: string,\n ): Promise<DatabaseResult<T | null>> {\n await this.simulateLatency();\n if (this.shouldFail()) {\n return failure(\n new DatabaseError(\n \"Mock findById failed\",\n DATABASE_ERROR_CODES.FIND_BY_ID_FAILED,\n ),\n );\n }\n\n const tableData = this.getTableData(table);\n const record = tableData.get(id);\n\n return success(record ? ({ ...record } as T) : null);\n }\n\n /**\n * Apply query options (filter, sort) to records\n */\n private applyQueryOptions<T extends Record<string, unknown>>(\n records: Record<string, unknown>[],\n options?: QueryOptions<T>,\n ): Record<string, unknown>[] {\n let result = records;\n if (options?.filter) {\n result = this.applyFilter(result, options.filter);\n }\n if (options?.sort) {\n result = this.applySort(result, options.sort);\n }\n return result;\n }\n\n /**\n * Get pagination params with defaults\n */\n private getPaginationParams<T extends object>(\n options?: QueryOptions<T>,\n ): {\n offset: number;\n limit: number;\n } {\n return {\n offset: options?.pagination?.offset ?? 0,\n limit: options?.pagination?.limit ?? DEFAULT_PAGINATION_LIMIT,\n };\n }\n\n /**\n * Apply pagination to records\n */\n private applyPagination(\n records: Record<string, unknown>[],\n offset: number,\n limit: number,\n ): Record<string, unknown>[] {\n return records.slice(offset, offset + limit);\n }\n\n async findMany<T extends Record<string, unknown>>(\n table: string,\n options?: QueryOptions<T>,\n ): Promise<DatabaseResult<PaginatedResult<T>>> {\n await this.simulateLatency();\n if (this.shouldFail()) {\n return failure(\n new DatabaseError(\n \"Mock findMany failed\",\n DATABASE_ERROR_CODES.FIND_MANY_FAILED,\n ),\n );\n }\n\n const tableData = this.getTableData(table);\n const allRecords = Array.from(tableData.values());\n const filteredRecords = this.applyQueryOptions(allRecords, options);\n const total = filteredRecords.length;\n const { offset, limit } = this.getPaginationParams(options);\n const paginatedRecords = this.applyPagination(\n filteredRecords,\n offset,\n limit,\n );\n\n return success({\n data: paginatedRecords as T[],\n total,\n pagination: calculatePagination(total, options?.pagination),\n });\n }\n\n async create<T>(table: string, data: T): Promise<DatabaseResult<T>> {\n await this.simulateLatency();\n if (this.shouldFail()) {\n return failure(\n new DatabaseError(\n \"Mock create failed\",\n DATABASE_ERROR_CODES.CREATE_FAILED,\n ),\n );\n }\n\n const tableData = this.getTableData(table);\n const idColumn = this.getIdColumn(table);\n const record = { ...(data as Record<string, unknown>) };\n\n // Generate ID if needed\n if (!record[idColumn] && this.config.autoGenerateIds) {\n record[idColumn] = this.generateId();\n }\n\n const id = record[idColumn];\n if (!id) {\n return failure(\n new DatabaseError(\n \"Record must have an ID\",\n DATABASE_ERROR_CODES.CREATE_FAILED,\n ),\n );\n }\n\n // Add timestamps\n const now = new Date().toISOString();\n record.created_at ??= now;\n record.updated_at ??= now;\n\n tableData.set(String(id), record);\n\n return success(record as T);\n }\n\n async update<T>(\n table: string,\n id: string,\n data: Partial<T>,\n ): Promise<DatabaseResult<T>> {\n await this.simulateLatency();\n if (this.shouldFail()) {\n return failure(\n new DatabaseError(\n \"Mock update failed\",\n DATABASE_ERROR_CODES.UPDATE_FAILED,\n ),\n );\n }\n\n const tableData = this.getTableData(table);\n const existing = tableData.get(id);\n\n if (!existing) {\n return failure(\n new DatabaseError(\n \"Record not found\",\n DATABASE_ERROR_CODES.RECORD_NOT_FOUND,\n ),\n );\n }\n\n const updated = {\n ...existing,\n ...data,\n updated_at: new Date().toISOString(),\n };\n\n tableData.set(id, updated);\n\n return success(updated as T);\n }\n\n async delete(table: string, id: string): Promise<DatabaseResult<void>> {\n await this.simulateLatency();\n if (this.shouldFail()) {\n return failure(\n new DatabaseError(\n \"Mock delete failed\",\n DATABASE_ERROR_CODES.DELETE_FAILED,\n ),\n );\n }\n\n const tableData = this.getTableData(table);\n const existed = tableData.delete(id);\n\n if (!existed) {\n return failure(\n new DatabaseError(\n \"Record not found\",\n DATABASE_ERROR_CODES.RECORD_NOT_FOUND,\n ),\n );\n }\n\n return success();\n }\n\n async transaction<T>(\n callback: (trx: Transaction) => Promise<T>,\n ): Promise<DatabaseResult<T>> {\n await this.simulateLatency();\n\n // Create a snapshot of current data\n const snapshot = new Map<string, TableDataMap>();\n for (const [table, tableData] of this.data.entries()) {\n snapshot.set(table, new Map(tableData));\n }\n\n this.transactionDepth++;\n this.transactionData = snapshot;\n\n try {\n const trx: Transaction = {\n findById: async <T>(table: string, id: string) =>\n this.findById<T>(table, id),\n create: async <T>(table: string, data: T) =>\n this.create<T>(table, data),\n update: async <T>(table: string, id: string, data: Partial<T>) =>\n this.update<T>(table, id, data),\n delete: async (table: string, id: string) => this.delete(table, id),\n commit: async () => {\n /* no-op, auto-committed */\n },\n rollback: async () => {\n // Restore snapshot\n this.data = snapshot;\n },\n };\n\n const result = await callback(trx);\n\n // Transaction succeeded - commit is implicit\n this.transactionDepth--;\n this.transactionData = null;\n\n return success(result);\n } catch (error) {\n // Rollback on error\n this.data = snapshot;\n this.transactionDepth--;\n this.transactionData = null;\n\n return failure(\n new DatabaseError(\n `Transaction failed: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.TRANSACTION_FAILED,\n { cause: error as Error },\n ),\n );\n }\n }\n\n async exists(table: string, id: string): Promise<DatabaseResult<boolean>> {\n await this.simulateLatency();\n const tableData = this.getTableData(table);\n return success(tableData.has(id));\n }\n\n async count<T extends Record<string, unknown> = Record<string, unknown>>(\n table: string,\n filter?: Filter<T>,\n ): Promise<DatabaseResult<number>> {\n await this.simulateLatency();\n const tableData = this.getTableData(table);\n let records = Array.from(tableData.values());\n\n if (filter) {\n records = this.applyFilter(records, filter);\n }\n\n return success(records.length);\n }\n\n async healthCheck(): Promise<DatabaseResult<DatabaseHealthStatus>> {\n await this.simulateLatency();\n\n return success({\n isHealthy: this.isInitialized,\n responseTime: this.config.latency ?? 0,\n details: {\n adapter: \"mock\",\n tables: this.data.size,\n totalRecords: Array.from(this.data.values()).reduce(\n (sum, table) => sum + table.size,\n 0,\n ),\n } as DatabaseHealthStatus[\"details\"],\n });\n }\n\n // DatabaseAdapterType required methods\n\n async connect(): Promise<void> {\n await this.simulateLatency();\n // Mock adapter doesn't need actual connection\n }\n\n async disconnect(): Promise<void> {\n await this.close();\n }\n\n getClient(): object {\n return {\n type: \"mock\",\n data: this.data,\n config: this.config,\n };\n }\n\n async query<T>(): Promise<T[]> {\n await this.simulateLatency();\n // Mock adapter doesn't execute real SQL\n // This is a stub for compatibility\n return [] as T[];\n }\n\n // Utility methods\n\n /**\n * Get fully-qualified table name with schema\n */\n private getQualifiedTableName(table: string, schema?: string): string {\n const targetSchema = schema ?? this.defaultSchema;\n\n // If table already has schema prefix (e.g., \"tenant_acme.users\"), use as-is\n if (table.includes(\".\")) {\n return table;\n }\n\n // For 'public' schema or non-qualified tables, return table name as-is for simplicity\n // This maintains backwards compatibility with existing tests\n if (targetSchema === \"public\") {\n return table;\n }\n\n // Apply schema prefix for non-public schemas\n return `${targetSchema}.${table}`;\n }\n\n private initializeTableData(\n initialData: Record<string, Record<string, unknown>[]>,\n ): void {\n for (const [table, records] of Object.entries(initialData)) {\n const tableData = new Map<string, Record<string, unknown>>();\n const idColumn = this.getIdColumn(table);\n\n for (const record of records) {\n const id = record[idColumn];\n if (id) {\n tableData.set(String(id), { ...record });\n }\n }\n\n this.data.set(table, tableData);\n }\n }\n\n private getTableData(table: string): TableDataMap {\n // Handle schema-qualified table names\n const qualifiedTable = this.getQualifiedTableName(table);\n\n if (!this.data.has(qualifiedTable)) {\n this.data.set(qualifiedTable, new Map());\n }\n return this.data.get(qualifiedTable)!;\n }\n\n private getIdColumn(table: string): string {\n // Strip schema prefix if present to get base table name for ID column lookup\n const baseTable = table.includes(\".\") ? table.split(\".\")[1] : table;\n return this.tableIdColumns.get(baseTable) ?? \"id\";\n }\n\n private generateId(): string {\n return `mock-${Date.now()}-${Math.random().toString(RANDOM_STRING_BASE).substring(ID_SUBSTRING_START, ID_SUBSTRING_END)}`;\n }\n\n private async simulateLatency(): Promise<void> {\n if (this.config.latency && this.config.latency > 0) {\n await new Promise((resolve) => setTimeout(resolve, this.config.latency));\n }\n }\n\n private shouldFail(): boolean {\n if (!this.config.failRate || this.config.failRate <= 0) return false;\n return Math.random() < this.config.failRate;\n }\n\n private applyFilter<T extends Record<string, unknown>>(\n records: Record<string, unknown>[],\n filter: Filter<T>,\n ): Record<string, unknown>[] {\n const { field, operator, value } = filter;\n const handler = FILTER_OPERATORS[operator];\n\n return records.filter((record: Record<string, unknown>) => {\n const fieldValue = record[field];\n return handler ? handler(fieldValue, value) : true;\n });\n }\n\n private applySort(\n records: Record<string, unknown>[],\n sort: Array<{ field: string; direction: \"asc\" | \"desc\" }>,\n ): Record<string, unknown>[] {\n return records.sort((a, b) => {\n for (const { field, direction } of sort) {\n const aVal = a[field];\n const bVal = b[field];\n\n if (aVal === bVal) continue;\n\n const comparison =\n (aVal as string | number) < (bVal as string | number) ? -1 : 1;\n return direction === \"asc\" ? comparison : -comparison;\n }\n return 0;\n });\n }\n\n /**\n * Test utility: Clear all data\n */\n clearAll(): void {\n this.data.clear();\n }\n\n /**\n * Test utility: Get current data for inspection\n */\n getData(\n table?: string,\n ): Record<string, unknown>[] | Record<string, Record<string, unknown>[]> {\n if (table) {\n return Array.from(this.getTableData(table).values());\n }\n\n const result: Record<string, Record<string, unknown>[]> = {};\n for (const [tableName, tableData] of this.data.entries()) {\n result[tableName] = Array.from(tableData.values());\n }\n return result;\n }\n\n /**\n * Test utility: Set data directly\n */\n setData(table: string, records: Record<string, unknown>[]): void {\n const tableData = new Map<string, Record<string, unknown>>();\n const idColumn = this.getIdColumn(table);\n\n for (const record of records) {\n const id = record[idColumn];\n if (id) {\n tableData.set(String(id), { ...record });\n }\n }\n\n this.data.set(table, tableData);\n }\n}\n","/**\n * @fileoverview Adapter Factory for @plyaz/db package\n *\n * This module provides the AdapterFactory class responsible for creating database adapter instances\n * based on configuration. Supports multiple database adapters including Drizzle ORM, Supabase,\n * and raw SQL adapters.\n *\n * Part of the @plyaz/db package factory system that creates the complete adapter chain:\n * AdapterFactory → Base Adapter → Extension Wrappers → Final Adapter Chain\n *\n */\n\nimport { DrizzleAdapter } from \"@adapters/drizzle/DrizzleAdapter\";\nimport { SupabaseAdapter } from \"@adapters/supabase/SupabaseAdapter\";\nimport { SQLAdapter } from \"@adapters/sql/SQLAdapter\";\nimport { MockAdapter } from \"@adapters/mock/MockAdapter\";\nimport type {\n DatabaseAdapterType,\n DatabaseConfig,\n DrizzleAdapterConfig,\n SQLAdapterConfig,\n SupabaseAdapterConfig,\n DbMockAdapterConfig,\n} from \"@plyaz/types/db\";\nimport { ADAPTERS } from \"@plyaz/types/db\";\nimport { DatabaseError } from \"@plyaz/errors\";\nimport { DATABASE_ERROR_CODES } from \"@plyaz/types/errors\";\n\n/**\n * ADAPTER FACTORY - Database Adapter Creation\n *\n * Factory class responsible for creating database adapter instances based on configuration.\n * This is the first step in the adapter chain creation process.\n *\n * **Factory Pattern Implementation:**\n * - Takes adapter type and configuration as input\n * - Returns appropriate DatabaseAdapterType implementation\n * - Handles type safety and error cases\n * - Supports all available database adapters\n *\n * **Supported Adapters:**\n * - DrizzleAdapter: For Drizzle ORM integration\n * - SupabaseAdapter: For Supabase database integration\n * - SQLAdapter: For raw SQL database operations\n *\n * **Usage Flow:**\n * createDatabaseService() → **AdapterFactory.create()** → Base Adapter → Extension Wrappers\n *\n * @example\n * ```typescript\n * // Create Drizzle adapter\n * const drizzleAdapter = AdapterFactory.create(ADAPTERS.DRIZZLE, {\n * adapter: ADAPTERS.DRIZZLE,\n * connection: { host: 'localhost', port: 5432 },\n * database: 'myapp'\n * });\n *\n * // Create Supabase adapter\n * const supabaseAdapter = AdapterFactory.create(ADAPTERS.SUPABASE, {\n * adapter: ADAPTERS.SUPABASE,\n * url: 'https://project.supabase.co',\n * key: 'your-anon-key'\n * });\n * ```\n *\n */\nexport class AdapterFactory {\n /**\n * Creates a new database adapter instance based on the configuration\n *\n * This is the core factory method that instantiates the appropriate database adapter\n * based on the provided type and configuration. Uses TypeScript generics to ensure\n * type safety between adapter type and configuration.\n *\n * **Creation Process:**\n * 1. Validates input parameters (type and config)\n * 2. Uses switch statement to match adapter type\n * 3. Instantiates appropriate adapter class with type-safe config\n * 4. Returns DatabaseAdapterType interface implementation\n *\n * **Type Safety:**\n * - Generic T extends DatabaseConfig ensures config matches adapter type\n * - Type assertions (as DrizzleAdapterConfig) provide compile-time safety\n * - Runtime validation prevents invalid configurations\n *\n * @template T - Database configuration type that extends DatabaseConfig\n * @param {T[\"adapter\"]} type - Adapter type from ADAPTERS enum (drizzle, supabase, sql)\n * @param {T} config - Database configuration object matching the adapter type\n * @returns {DatabaseAdapterType} The appropriate adapter implementation\n *\n * @throws {Error} If adapter type is not provided\n * @throws {Error} If adapter configuration is not provided\n * @throws {Error} If unsupported adapter type is specified\n * @throws {Error} If adapter instantiation fails\n *\n * @example\n * ```typescript\n * // Create Drizzle adapter with PostgreSQL\n * const drizzleAdapter = AdapterFactory.create(ADAPTERS.DRIZZLE, {\n * adapter: ADAPTERS.DRIZZLE,\n * connection: {\n * host: 'localhost',\n * port: 5432,\n * database: 'myapp',\n * user: 'postgres',\n * password: 'password'\n * }\n * });\n *\n * // Create Supabase adapter\n * const supabaseAdapter = AdapterFactory.create(ADAPTERS.SUPABASE, {\n * adapter: ADAPTERS.SUPABASE,\n * url: 'https://xyzcompany.supabase.co',\n * key: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'\n * });\n *\n * // Create SQL adapter for custom database\n * const sqlAdapter = AdapterFactory.create(ADAPTERS.SQL, {\n * adapter: ADAPTERS.SQL,\n * connectionString: 'postgresql://user:pass@localhost:5432/db'\n * });\n * ```\n *\n */\n static create<T extends DatabaseConfig>(\n type: T[\"adapter\"],\n config: T,\n ): DatabaseAdapterType {\n try {\n // Input validation - ensure required parameters are provided\n // This prevents runtime errors from missing configuration\n if (!type) {\n throw new DatabaseError(\n \"Adapter type is required\",\n DATABASE_ERROR_CODES.CONFIG_REQUIRED,\n {\n context: { source: \"AdapterFactory.create\" },\n cause: new Error(\"Adapter type is required\"),\n },\n );\n }\n\n if (!config) {\n throw new DatabaseError(\n \"Adapter configuration is required\",\n DATABASE_ERROR_CODES.CONFIG_REQUIRED,\n {\n context: { source: \"AdapterFactory.create\" },\n cause: new Error(\"Adapter configuration is required\"),\n },\n );\n }\n\n // Adapter instantiation using switch statement for type safety\n // Each case handles a specific adapter type with appropriate configuration casting\n switch (type) {\n // Drizzle ORM adapter - for type-safe database operations\n case ADAPTERS.DRIZZLE:\n return new DrizzleAdapter(config as DrizzleAdapterConfig);\n\n // Supabase adapter - for Supabase backend-as-a-service integration\n case ADAPTERS.SUPABASE:\n return new SupabaseAdapter(config as SupabaseAdapterConfig);\n\n // SQL adapter - for raw SQL operations and custom database integrations\n case ADAPTERS.SQL:\n return new SQLAdapter(config as SQLAdapterConfig);\n\n // Mock adapter - for in-memory testing without real database\n case ADAPTERS.MOCK:\n return new MockAdapter(config as DbMockAdapterConfig);\n\n // Default case - handles unsupported or invalid adapter types\n default:\n throw new DatabaseError(\n `Unsupported adapter type: ${type}`,\n DATABASE_ERROR_CODES.INVALID_PARAMETERS,\n {\n context: { source: \"AdapterFactory.create\" },\n cause: new Error(`Unsupported adapter type: ${type}`),\n },\n );\n }\n } catch (error) {\n // Error handling with context preservation\n // Wraps any instantiation errors with factory-specific context\n throw new DatabaseError(\n `Failed to create adapter: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.INIT_FAILED,\n {\n context: { source: \"AdapterFactory.create\" },\n cause: error as Error,\n },\n );\n }\n }\n}\n","/**\n * @fileoverview Soft Delete Extension for @plyaz/db package\n *\n * This module provides the SoftDeleteAdapter extension that implements logical deletion\n * instead of physical record removal. It automatically intercepts delete operations\n * and converts them to timestamp updates, while filtering queries to exclude soft-deleted records.\n *\n * Part of the @plyaz/db package - a TypeScript database abstraction layer with\n * support for multiple adapters (Drizzle, Supabase, SQL), extensions (audit, encryption,\n * soft delete), and advanced features (caching, read replicas, multi-tenancy).\n *\n */\n\nimport { logger } from \"@plyaz/logger\";\nimport type {\n DatabaseAdapterType,\n DatabaseResult,\n PaginatedResult,\n QueryOptions,\n Filter,\n DatabaseHealthStatus,\n Transaction,\n} from \"@plyaz/types/db\";\nimport { failure, success } from \"@utils/databaseResultHelpers\";\nimport { DatabaseError } from \"@plyaz/errors\";\nimport { DATABASE_ERROR_CODES } from \"@plyaz/types/errors\";\n\n/**\n * SOFT DELETE ADAPTER - Logical Deletion Layer\n *\n * Soft delete extension that implements logical deletion instead of physical removal.\n * Third layer in the adapter chain.\n *\n * **Adapter Chain Position:**\n * ReadReplica -> Audit -> Cache -> **SoftDelete** -> Encryption -> Base Adapter\n *\n * **What this adapter does:**\n * 1. Intercepts delete() operations sets deletedAt timestamp instead of removing\n * 2. Intercepts query/list operations adds \"WHERE deletedAt IS NULL\" filter\n * 3. Provides restore() method to undelete records\n * 4. Honors includeSoftDeleted flag from operation config\n *\n * **Called by:** CachingAdapter (or AuditAdapter if no caching)\n * **Calls:** EncryptionAdapter (or base adapter if no encryption)\n * **Provides:** restore(), permanentDelete() methods\n *\n * **Soft Delete Flow:**\n * - **Delete:** Sets deletedAt = NOW() instead of removing record\n * - **Queries:** Automatically filters WHERE deletedAt IS NULL\n * - **Restore:** Sets deletedAt = NULL to undelete\n *\n * @example\n * ### Configuration\n * ```typescript\n * softDelete: {\n * enabled: true,\n * field: 'deletedAt', // Custom field name\n * excludeTables: ['audit_logs'] // Tables that use hard delete\n * }\n * ```\n *\n * @example\n * ### Usage Flow\n * ```typescript\n * // Normal delete - sets deletedAt timestamp\n * await db.delete(Tables.USERS, 'user-123');\n *\n * // Query automatically excludes soft-deleted records\n * const activeUsers = await db.query(Tables.USERS, {});\n *\n * // Include soft-deleted records with operation config\n * const allUsers = await db.query(Tables.USERS, {}, {\n * includeSoftDeleted: true\n * });\n *\n * // Restore soft-deleted record\n * await db.restore(Tables.USERS, 'user-123');\n * ```\n */\nexport class SoftDeleteAdapter implements DatabaseAdapterType {\n /**\n * Creates a new SoftDeleteAdapter instance.\n *\n * **RESPONSIBILITY:** Wraps base adapter with soft delete functionality\n * **CONFIGURATION:** Sets up deletion field name and excluded tables\n *\n * @param baseAdapter - The underlying database adapter to wrap\n * @param config - Soft delete configuration options\n *\n * @example\n * ```typescript\n * const softDeleteAdapter = new SoftDeleteAdapter(baseAdapter, {\n * enabled: true,\n * field: 'deletedAt',\n * excludeTables: ['audit_logs', 'system_events']\n * });\n * ```\n */\n constructor(\n public baseAdapter: DatabaseAdapterType,\n private config: {\n enabled: boolean;\n field?: string;\n excludeTables?: string[];\n },\n ) {}\n\n /**\n * Initializes the soft delete adapter and underlying adapter.\n *\n * **RESPONSIBILITY:** Passes initialization to base adapter\n * **BEHAVIOR:** No additional initialization needed for soft delete\n *\n * @returns Promise resolving to initialization result\n *\n * @example\n * ```typescript\n * const result = await softDeleteAdapter.initialize();\n * if (result.success) {\n * console.log('Soft delete adapter initialized');\n * }\n * ```\n */\n async initialize(): Promise<DatabaseResult<void>> {\n return this.baseAdapter.initialize();\n }\n\n /**\n * Establishes database connection through base adapter.\n *\n * **RESPONSIBILITY:** Delegates connection to underlying adapter\n * **BEHAVIOR:** No additional connection logic needed\n *\n * @example\n * ```typescript\n * await softDeleteAdapter.connect();\n * console.log('Connected with soft delete support');\n * ```\n */\n async connect(): Promise<void> {\n return this.baseAdapter.connect();\n }\n\n /**\n * Closes database connection through base adapter.\n *\n * **RESPONSIBILITY:** Delegates disconnection to underlying adapter\n * **BEHAVIOR:** No additional cleanup needed for soft delete\n *\n * @example\n * ```typescript\n * await softDeleteAdapter.disconnect();\n * console.log('Disconnected gracefully');\n * ```\n */\n async disconnect(): Promise<void> {\n return this.baseAdapter.disconnect();\n }\n\n async close(): Promise<DatabaseResult<void>> {\n return this.baseAdapter.close();\n }\n\n /**\n * Gets the underlying database client.\n *\n * **RESPONSIBILITY:** Provides access to raw database client\n * **USE CASE:** For operations that bypass soft delete logic\n *\n * @returns Database client object\n *\n * @example\n * ```typescript\n * const client = softDeleteAdapter.getClient();\n * // Use for direct database operations if needed\n * ```\n */\n getClient(): object {\n return this.baseAdapter.getClient();\n }\n\n /**\n * Executes raw SQL query through base adapter.\n *\n * **RESPONSIBILITY:** Passes raw SQL to base adapter without modification\n * **BEHAVIOR:** Does not apply soft delete filtering to raw SQL\n * **NOTE:** Use findMany() for automatic soft delete filtering\n *\n * @param sql - SQL query string\n * @param params - Query parameters\n * @returns Query results\n *\n * @example\n * ```typescript\n * // Raw SQL bypasses soft delete filtering\n * const allUsers = await adapter.query(\n * 'SELECT * FROM users', // Includes soft-deleted records\n * []\n * );\n *\n * // Use findMany for automatic filtering\n * const activeUsers = await adapter.findMany('users'); // Excludes soft-deleted\n * ```\n */\n async query<T>(sql: string, params?: T[]): Promise<T[]> {\n return this.baseAdapter.query(sql, params);\n }\n\n /**\n * Registers a table schema with the base adapter.\n *\n * **RESPONSIBILITY:** Passes table registration to base adapter\n * **BEHAVIOR:** No additional registration logic needed\n *\n * @param name - Table name\n * @param table - Table schema\n * @param idColumn - Primary key column\n *\n * @example\n * ```typescript\n * softDeleteAdapter.registerTable('users', userSchema, 'id');\n * // Table now supports soft delete operations\n * ```\n */\n registerTable<T, U>(name: string, table: T, idColumn?: U): void {\n this.baseAdapter.registerTable(name, table, idColumn);\n }\n\n /**\n * Finds a record by ID with automatic soft delete filtering.\n *\n * **RESPONSIBILITY:** Retrieves single record, excluding soft-deleted by default\n * **FILTERING:** Automatically excludes records where deletedAt IS NOT NULL\n * **OVERRIDE:** Can include soft-deleted records with operation config\n *\n * @param table - Table name\n * @param id - Record ID\n * @returns Found record or null\n *\n * @example\n * ```typescript\n * // Excludes soft-deleted records by default\n * const user = await adapter.findById('users', 'user-123');\n * if (!user.value) {\n * console.log('User not found or soft-deleted');\n * }\n *\n * // Include soft-deleted records with config\n * const userIncludingDeleted = await adapter.findById('users', 'user-123', {\n * includeSoftDeleted: true\n * });\n * ```\n */\n async findById<T>(\n table: string,\n id: string,\n ): Promise<DatabaseResult<T | null>> {\n return this.baseAdapter.findById<T>(table, id);\n }\n\n async findMany<T extends Record<string, unknown>>(\n table: string,\n options?: QueryOptions<T>,\n ): Promise<DatabaseResult<PaginatedResult<T>>> {\n if (!this.config.enabled || this.isExcluded(table)) {\n return this.baseAdapter.findMany<T>(table, options);\n }\n\n // Add soft delete filter unless includeSoftDeleted is true\n const modifiedOptions: QueryOptions<T> = { ...options };\n modifiedOptions.filter ??= {\n field: this.config.field ?? \"deletedAt\",\n operator: \"isNull\",\n value: null,\n } as Filter<T>;\n\n return this.baseAdapter.findMany<T>(table, modifiedOptions);\n }\n\n /**\n * Creates a new record through base adapter.\n *\n * **RESPONSIBILITY:** Passes creation to base adapter without modification\n * **BEHAVIOR:** New records have deletedAt = NULL by default\n *\n * @param table - Table name\n * @param data - Record data\n * @returns Created record\n *\n * @example\n * ```typescript\n * const result = await adapter.create('users', {\n * name: 'John Doe',\n * email: 'john@example.com'\n * // deletedAt will be NULL (not soft-deleted)\n * });\n *\n * if (result.success) {\n * console.log('User created:', result.value.id);\n * }\n * ```\n */\n async create<T extends Record<string, unknown>>(\n table: string,\n data: T,\n ): Promise<DatabaseResult<T>> {\n return this.baseAdapter.create<T>(table, data);\n }\n\n /**\n * Updates an existing record through base adapter.\n *\n * **RESPONSIBILITY:** Passes update to base adapter without modification\n * **BEHAVIOR:** Can update soft-deleted records (they remain soft-deleted)\n * **NOTE:** Use restore() to undelete records\n *\n * @param table - Table name\n * @param id - Record ID\n * @param data - Partial record data\n * @returns Updated record\n *\n * @example\n * ```typescript\n * // Update active record\n * const result = await adapter.update('users', 'user-123', {\n * name: 'Jane Doe'\n * });\n *\n * // Can also update soft-deleted records\n * const softDeletedUpdate = await adapter.update('users', 'deleted-user', {\n * email: 'newemail@example.com'\n * // Record remains soft-deleted after update\n * });\n * ```\n */\n async update<T>(\n table: string,\n id: string,\n data: Partial<T>,\n ): Promise<DatabaseResult<T>> {\n return this.baseAdapter.update<T>(table, id, data);\n }\n\n async delete(table: string, id: string): Promise<DatabaseResult<void>> {\n if (!this.config.enabled || this.isExcluded(table)) {\n return this.baseAdapter.delete(table, id);\n }\n\n // Soft delete: set deletedAt field\n const deleteField = this.config.field ?? \"deletedAt\";\n const updateData = { [deleteField]: new Date().toISOString() };\n\n try {\n logger.debug(`Soft deleting record ${id} from table ${table}`);\n await this.baseAdapter.update(table, id, updateData);\n return success();\n } catch (error) {\n logger.error(`Soft delete failed for ${table}:${id}`);\n return failure(\n new DatabaseError(\n `Soft delete failed: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.DELETE_FAILED,\n {\n context: { source: \"delete\" },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Executes operations within a transaction.\n *\n * **RESPONSIBILITY:** Passes transaction to base adapter\n * **BEHAVIOR:** Soft delete operations within transaction are atomic\n * **ROLLBACK:** Failed transactions rollback soft delete operations\n *\n * @param callback - Transaction callback function\n * @returns Transaction result\n *\n * @example\n * ```typescript\n * const result = await adapter.transaction(async (trx) => {\n * // Create user\n * const user = await trx.create('users', { name: 'John' });\n *\n * // Soft delete old user (sets deletedAt)\n * await trx.delete('users', 'old-user-id');\n *\n * return user;\n * });\n *\n * // If transaction fails, both operations are rolled back\n * ```\n */\n async transaction<T>(\n callback: (trx: Transaction) => Promise<T>,\n ): Promise<DatabaseResult<T>> {\n return this.baseAdapter.transaction(callback);\n }\n\n /**\n * Checks if a record exists, excluding soft-deleted records.\n *\n * **RESPONSIBILITY:** Verifies record existence with soft delete filtering\n * **BEHAVIOR:** Returns false for soft-deleted records by default\n * **FILTERING:** Automatically excludes records where deletedAt IS NOT NULL\n *\n * @param table - Table name\n * @param id - Record ID\n * @returns True if record exists and is not soft-deleted\n *\n * @example\n * ```typescript\n * // Check if active user exists\n * const userExists = await adapter.exists('users', 'user-123');\n * if (userExists.value) {\n * console.log('User exists and is active');\n * } else {\n * console.log('User not found or soft-deleted');\n * }\n *\n * // Soft-deleted records return false\n * await adapter.delete('users', 'user-123'); // Soft delete\n * const stillExists = await adapter.exists('users', 'user-123'); // false\n * ```\n */\n async exists(table: string, id: string): Promise<DatabaseResult<boolean>> {\n return this.baseAdapter.exists(table, id);\n }\n\n /**\n * Counts records in a table, excluding soft-deleted records.\n *\n * **RESPONSIBILITY:** Counts records with automatic soft delete filtering\n * **BEHAVIOR:** Excludes soft-deleted records from count by default\n * **FILTERING:** Automatically adds deletedAt IS NULL filter\n *\n * @param table - Table name\n * @param filter - Optional filter conditions\n * @returns Count of non-soft-deleted records\n *\n * @example\n * ```typescript\n * // Count active users only\n * const activeCount = await adapter.count('users');\n * console.log('Active users:', activeCount.value);\n *\n * // Count with additional filter\n * const premiumActiveUsers = await adapter.count('users', {\n * field: 'plan',\n * operator: 'eq',\n * value: 'premium'\n * });\n * // Returns count of premium users that are NOT soft-deleted\n * ```\n */\n async count<T extends Record<string, unknown> = Record<string, unknown>>(\n table: string,\n filter?: Filter<T>,\n ): Promise<DatabaseResult<number>> {\n return this.baseAdapter.count<T>(table, filter);\n }\n\n /**\n * Performs health check through base adapter.\n *\n * **RESPONSIBILITY:** Delegates health check to underlying adapter\n * **BEHAVIOR:** No additional health metrics for soft delete\n *\n * @returns Health status from base adapter\n *\n * @example\n * ```typescript\n * const health = await adapter.healthCheck();\n * if (health.success && health.value?.isHealthy) {\n * console.log('Database healthy with soft delete support');\n * }\n * ```\n */\n async healthCheck(): Promise<DatabaseResult<DatabaseHealthStatus>> {\n return this.baseAdapter.healthCheck();\n }\n\n /**\n * Restores a previously soft-deleted record by clearing the deletion timestamp\n *\n * Undeletes a record by setting the soft delete field (typically 'deletedAt') to null,\n * making it visible in queries again. This operation is only available when soft delete\n * is enabled in the configuration.\n *\n * **Restore Process:**\n * 1. Validates that soft delete is enabled\n * 2. Sets the deletion field to null via update operation\n * 3. Logs the restoration for audit purposes\n * 4. Returns success or failure result\n *\n * @param {string} table - Name of the table containing the record to restore\n * @param {string} id - Primary key ID of the record to restore\n * @returns {Promise<DatabaseResult<void>>} Promise resolving to success/failure result\n *\n * @example\n * ```typescript\n * // Restore a soft-deleted user\n * const restoreResult = await softDeleteAdapter.restore('users', 'user-123');\n * if (restoreResult.success) {\n * console.log('User restored successfully');\n * } else {\n * console.error('Restore failed:', restoreResult.error.message);\n * }\n *\n * // After restoration, the record will appear in queries again\n * const user = await adapter.findById('users', 'user-123');\n * // user will now be found (not null)\n * ```\n *\n * @throws {DatabaseError} SOFT_DELETE_NOT_ENABLED - If soft delete is not enabled in configuration\n * @throws {DatabaseError} SOFT_DELETE_RESTORE_FAILED - If the restore operation fails\n *\n */\n async restore(table: string, id: string): Promise<DatabaseResult<void>> {\n // Validate that soft delete is enabled before attempting restore\n if (!this.config.enabled) {\n return failure(\n new DatabaseError(\n \"Soft delete not enabled\",\n DATABASE_ERROR_CODES.CONFIG_REQUIRED,\n {\n context: { source: \"restore\" },\n cause: new Error(\"Soft delete not enabled\"),\n },\n ),\n );\n }\n\n // Get the configured deletion field name (default: 'deletedAt')\n const deleteField = this.config.field ?? \"deletedAt\";\n // Create update data to clear the deletion timestamp\n const updateData = { [deleteField]: null };\n\n try {\n // Update the record to clear the deletion timestamp\n await this.baseAdapter.update(table, id, updateData);\n logger.info(`Record restored successfully: ${table}:${id}`);\n return success();\n } catch (error) {\n logger.error(`Restore failed for ${table}:${id}`);\n return failure(\n new DatabaseError(\n `Restore failed: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.UPDATE_FAILED,\n {\n context: { source: \"restore\" },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Checks if a table is excluded from soft delete functionality.\n * \n * **RESPONSIBILITY:** Determines if table should use hard delete instead\n * **CONFIGURATION:** Based on excludeTables array in config\n * **USE CASE:** Some tables like audit logs need permanent deletion\n * \n * @private\n * @param table - Name of the table to check\n * @returns True if table is excluded from soft delete\n * \n * @example\n * ```typescript\n * // Configuration: { excludeTables: ['audit_logs', 'temp_data'] }\n * \n * this.isExcluded('users'); // false - uses soft delete\n * this.isExcluded('audit_logs'); // true - uses hard delete\n * this.isExcluded('t\n private isExcluded(table: string): boolean {\n return this.config.excludeTables?.includes(table) ?? false;\n }emp_data'); // true - uses hard delete\n * ```\n * \n */\n private isExcluded(table: string): boolean {\n // Check if table is in the excludeTables array, default to false if not configured\n return this.config.excludeTables?.includes(table) ?? false;\n }\n}\n","import { DatabaseError } from \"@plyaz/errors\";\nimport { DATABASE_ERROR_CODES } from \"@plyaz/types/errors\";\nimport { logger } from \"@plyaz/logger\";\nimport type {\n DatabaseAdapterType,\n DatabaseResult,\n Filter,\n DatabaseHealthStatus,\n PaginatedResult,\n QueryOptions,\n Transaction,\n AuditContext,\n AuditEvent,\n} from \"@plyaz/types/db\";\nimport { AUDIT_OPERATION, EXTENSION_SOURCE } from \"@plyaz/types/db\";\n\n/** Minimum width for padded date parts (month, day) */\nconst DATE_PART_MIN_WIDTH = 2;\n\n/** Error source patterns for context-based matching */\nconst CONTEXT_SOURCE_PATTERNS: Array<{\n patterns: string[];\n source: EXTENSION_SOURCE;\n}> = [\n { patterns: [\"encrypt\"], source: EXTENSION_SOURCE.Encryption },\n {\n patterns: [\"softdelete\", \"soft_delete\"],\n source: EXTENSION_SOURCE.SoftDelete,\n },\n { patterns: [\"cach\"], source: EXTENSION_SOURCE.Caching },\n { patterns: [\"audit\"], source: EXTENSION_SOURCE.Audit },\n {\n patterns: [\"replica\", \"read_replica\"],\n source: EXTENSION_SOURCE.ReadReplica,\n },\n {\n patterns: [\"multi_write\", \"multiwrite\"],\n source: EXTENSION_SOURCE.MultiWrite,\n },\n];\n\n/** Error source patterns for message-based matching */\nconst MESSAGE_SOURCE_PATTERNS: Array<{\n patterns: string[];\n source: EXTENSION_SOURCE;\n}> = [\n { patterns: [\"encrypt\"], source: EXTENSION_SOURCE.Encryption },\n {\n patterns: [\"soft delete\", \"softdelete\"],\n source: EXTENSION_SOURCE.SoftDelete,\n },\n { patterns: [\"cache\", \"caching\"], source: EXTENSION_SOURCE.Caching },\n {\n patterns: [\"replica\", \"read replica\"],\n source: EXTENSION_SOURCE.ReadReplica,\n },\n {\n patterns: [\"multi-write\", \"multiwrite\"],\n source: EXTENSION_SOURCE.MultiWrite,\n },\n];\n\n/**\n * AUDIT ADAPTER - Compliance Logging Layer\n *\n * Audit extension that automatically logs all database operations for compliance.\n * Fifth layer in the adapter chain (second from outermost).\n *\n * **Adapter Chain Position:**\n * ReadReplica ļæ½ **Audit** ļæ½ Cache ļæ½ SoftDelete ļæ½ Encryption ļæ½ Base Adapter\n *\n * **What this adapter does:**\n * 1. Captures before-state for update/delete operations\n * 2. Delegates to next adapter in chain\n * 3. Captures after-state and writes audit record to daily audit tables\n * 4. Calls onAuditAfterWrite event handler (if configured)\n * 5. Honors skipAudit flag from operation config\n *\n * **Called by:** ReadReplicaAdapter (or DatabaseService if no read replicas)\n * **Calls:** CachingAdapter (or next adapter in chain)\n * **Writes to:** Daily partitioned audit tables ({schema}.audit_log_yyyy_mm_dd)\n *\n * **Audit Flow:**\n * 1. **CREATE:** Records after-state only\n * 2. **UPDATE:** Records before-state, after-state, and changed fields\n * 3. **DELETE:** Records before-state only\n * 4. **SOFT_DELETE:** Records before/after state with deletedAt change\n *\n * **Audit Context:** Uses context from DatabaseService.setAuditContext()\n * - userId, requestId, ipAddress, userAgent\n *\n * @example\n * ### Configuration\n * ```typescript\n * audit: {\n * enabled: true,\n * retentionDays: 90,\n * excludeFields: ['password', 'token'],\n * excludeTables: ['temp_data'],\n * onAuditAfterWrite: async (event) => {\n * await complianceService.recordAudit(event);\n * }\n * }\n * ```\n *\n * @example\n * ### Audit Record Structure\n * ```typescript\n * // Written to audit_20241201 table\n * {\n * operation: 'UPDATE',\n * table: 'users',\n * recordId: 'user-123',\n * userId: 'admin-456',\n * requestId: 'req-789',\n * changes: {\n * before: { name: 'John Doe', email: 'john@old.com' },\n * after: { name: 'John Smith', email: 'john@new.com' },\n * fields: ['name', 'email']\n * },\n * timestamp: '2024-12-01T10:30:00Z',\n * ipAddress: '192.168.1.1',\n * userAgent: 'Mozilla/5.0...'\n * }\n * ```\n */\nexport class AuditAdapter implements DatabaseAdapterType {\n private auditContext: AuditContext = {};\n // Using shared logger instance from @plyaz/logger\n\n /** Cached schema-qualified table name */\n private auditSchema: string;\n /** Whether to use daily partitioned tables */\n private usePartitionedTables: boolean;\n\n /**\n * Creates a new AuditAdapter instance.\n *\n * **RESPONSIBILITY:** Wraps base adapter with audit logging functionality\n * **CONFIGURATION:** Sets up audit rules, retention, and event handlers\n *\n * @param baseAdapter - The underlying database adapter to wrap\n * @param config - Audit configuration options\n *\n * @example\n * ```typescript\n * const auditAdapter = new AuditAdapter(baseAdapter, {\n * enabled: true,\n * retentionDays: 180,\n * excludeFields: ['password', 'token'],\n * excludeTables: ['temp_data'],\n * schema: 'audit',\n * usePartitionedTables: true,\n * onAuditAfterWrite: async (event) => {\n * await complianceService.recordAudit(event);\n * }\n * });\n * ```\n */\n constructor(\n public baseAdapter: DatabaseAdapterType,\n private config: {\n enabled: boolean;\n retentionDays?: number;\n excludeFields?: string[];\n excludeTables?: string[];\n /** Database schema for audit tables (default: 'audit') */\n schema?: string;\n /** Use daily partitioned tables (audit_log_yyyy_mm_dd format) (default: true) */\n usePartitionedTables?: boolean;\n onAuditAfterWrite?: (event: AuditEvent) => void | Promise<void>;\n /** Encrypted fields config from encryption extension (for audit metadata) */\n encryptedFields?: Record<string, string[]>;\n },\n ) {\n this.auditSchema = config.schema ?? \"audit\";\n this.usePartitionedTables = config.usePartitionedTables ?? true;\n }\n\n /**\n * Initializes the audit adapter and underlying adapter.\n *\n * **RESPONSIBILITY:** Passes initialization to base adapter\n * **BEHAVIOR:** No additional initialization needed for audit\n *\n * @returns Promise resolving to initialization result\n *\n * @example\n * ```typescript\n * const result = await auditAdapter.initialize();\n * if (result.success) {\n * console.log('Audit adapter initialized');\n * }\n * ```\n */\n async initialize(): Promise<DatabaseResult<void>> {\n return this.baseAdapter.initialize();\n }\n\n /**\n * Establishes database connection through base adapter.\n *\n * **RESPONSIBILITY:** Delegates connection to underlying adapter\n * **BEHAVIOR:** No additional connection logic needed\n *\n * @example\n * ```typescript\n * await auditAdapter.connect();\n * console.log('Connected with audit support');\n * ```\n */\n async connect(): Promise<void> {\n return this.baseAdapter.connect();\n }\n\n /**\n * Closes database connection through base adapter.\n *\n * **RESPONSIBILITY:** Delegates disconnection to underlying adapter\n * **BEHAVIOR:** No additional cleanup needed for audit\n *\n * @example\n * ```typescript\n * await auditAdapter.disconnect();\n * console.log('Disconnected gracefully');\n * ```\n */\n async disconnect(): Promise<void> {\n return this.baseAdapter.disconnect();\n }\n\n async close(): Promise<DatabaseResult<void>> {\n return this.baseAdapter.close();\n }\n\n /**\n * Gets the underlying database client.\n *\n * **RESPONSIBILITY:** Provides access to raw database client\n * **USE CASE:** For operations that bypass audit logging\n *\n * @returns Database client object\n *\n * @example\n * ```typescript\n * const client = auditAdapter.getClient();\n * // Use for direct database operations if needed\n * ```\n */\n getClient(): object {\n return this.baseAdapter.getClient();\n }\n\n /**\n * Executes raw SQL query through base adapter.\n *\n * **RESPONSIBILITY:** Passes raw SQL to base adapter without audit logging\n * **BEHAVIOR:** Does not audit raw SQL operations\n * **NOTE:** Use CRUD methods for automatic audit logging\n *\n * @param sql - SQL query string\n * @param params - Query parameters\n * @returns Query results\n *\n * @example\n * ```typescript\n * // Raw SQL bypasses audit logging\n * const results = await adapter.query(\n * 'SELECT * FROM users WHERE status = $1',\n * ['active']\n * );\n *\n * // Use findMany for automatic audit logging\n * const users = await adapter.findMany('users', { filter: ... });\n * ```\n */\n async query<T>(sql: string, params?: T[]): Promise<T[]> {\n return this.baseAdapter.query(sql, params);\n }\n\n /**\n * Registers a table schema with the base adapter.\n *\n * **RESPONSIBILITY:** Passes table registration to base adapter\n * **BEHAVIOR:** No additional registration logic needed\n *\n * @param name - Table name\n * @param table - Table schema\n * @param idColumn - Primary key column\n *\n * @example\n * ```typescript\n * auditAdapter.registerTable('users', userSchema, 'id');\n * // Table now supports audited operations\n * ```\n */\n registerTable<T, U>(name: string, table: T, idColumn?: U): void {\n this.baseAdapter.registerTable(name, table, idColumn);\n }\n\n /**\n * Sets audit context for tracking user actions.\n *\n * **RESPONSIBILITY:** Stores context information for audit records\n * **CONTEXT:** userId, requestId, ipAddress, userAgent\n * **USAGE:** Called by DatabaseService.setAuditContext()\n *\n * @param context - Audit context information\n *\n * @example\n * ```typescript\n * // Usually called by middleware\n * auditAdapter.setAuditContext({\n * userId: 'user-123',\n * requestId: 'req-456',\n * ipAddress: '192.168.1.1',\n * userAgent: 'Mozilla/5.0...'\n * });\n *\n * // Subsequent operations will include this context in audit logs\n * await adapter.create('users', userData); // Audited with context\n * ```\n */\n setAuditContext(context: AuditContext): void {\n this.auditContext = { ...this.auditContext, ...context };\n }\n\n /**\n * Finds a record by ID without audit logging.\n *\n * **RESPONSIBILITY:** Retrieves single record without creating audit trail\n * **BEHAVIOR:** Read operations are not audited by default\n * **PERFORMANCE:** No audit overhead for read operations\n *\n * @param table - Table name\n * @param id - Record ID\n * @returns Found record or null\n *\n * @example\n * ```typescript\n * // Read operations don't create audit records\n * const user = await adapter.findById('users', 'user-123');\n * if (user.success && user.value) {\n * console.log('User found:', user.value.name);\n * }\n * ```\n */\n async findById<T>(\n table: string,\n id: string,\n ): Promise<DatabaseResult<T | null>> {\n return this.baseAdapter.findById<T>(table, id);\n }\n\n /**\n * Finds multiple records without audit logging.\n *\n * **RESPONSIBILITY:** Retrieves multiple records without creating audit trail\n * **BEHAVIOR:** Read operations are not audited by default\n * **PERFORMANCE:** No audit overhead for read operations\n *\n * @param table - Table name\n * @param options - Query options\n * @returns Paginated results\n *\n * @example\n * ```typescript\n * // Read operations don't create audit records\n * const users = await adapter.findMany('users', {\n * filter: { field: 'status', operator: 'eq', value: 'active' },\n * pagination: { page: 1, limit: 10 }\n * });\n *\n * console.log('Found users:', users.value?.data.length);\n * ```\n */\n async findMany<T extends Record<string, unknown>>(\n table: string,\n options?: QueryOptions<T>,\n ): Promise<DatabaseResult<PaginatedResult<T>>> {\n return this.baseAdapter.findMany<T>(table, options);\n }\n\n async create<T extends Record<string, unknown>>(\n table: string,\n data: T,\n ): Promise<DatabaseResult<T>> {\n this.validateCreateParams(table, data);\n\n try {\n const result = await this.baseAdapter.create<T>(table, data);\n\n if (result.success && this.shouldAudit(table)) {\n await this.logAudit({\n operation: AUDIT_OPERATION.Create,\n table,\n recordId: (result.value as Record<string, string>)?.id,\n changes: {\n after: result.value as Record<\n string,\n string | number | boolean | Date\n >,\n encryptedFields: this.getEncryptedFields(table),\n },\n userId: this.auditContext.userId,\n requestId: this.auditContext.requestId,\n timestamp: new Date(),\n ipAddress: this.auditContext.ipAddress,\n userAgent: this.auditContext.userAgent,\n });\n }\n\n return result;\n } catch (error) {\n // Log the failure to audit before re-throwing\n if (this.shouldAudit(table)) {\n await this.logOperationFailure({\n operation: AUDIT_OPERATION.Create,\n table,\n data,\n error: error as Error,\n });\n }\n throw error;\n }\n }\n\n private validateCreateParams<T>(table: string, data: T): void {\n if (!table || !data) {\n throw new DatabaseError(\n \"Invalid parameters for create operation\",\n DATABASE_ERROR_CODES.INVALID_PARAMETERS,\n {\n context: { source: \"validateCreateParams\" },\n cause: new Error(\"Invalid parameters for create operation\"),\n },\n );\n }\n }\n\n async update<T>(\n table: string,\n id: string,\n data: Partial<T>,\n ): Promise<DatabaseResult<T>> {\n // Get before state for audit (before any operation)\n const before = await this.baseAdapter.findById(table, id);\n\n try {\n const result = await this.baseAdapter.update<T>(table, id, data);\n\n if (result.success && this.shouldAudit(table)) {\n await this.logAudit({\n operation: AUDIT_OPERATION.Update,\n table,\n recordId: id,\n changes: {\n before: before.success\n ? (before.value as Record<\n string,\n string | number | boolean | Date\n >)\n : undefined,\n after: result.value as Record<\n string,\n string | number | boolean | Date\n >,\n fields: Object.keys(data),\n encryptedFields: this.getEncryptedFields(table),\n },\n userId: this.auditContext.userId,\n requestId: this.auditContext.requestId,\n timestamp: new Date(),\n ipAddress: this.auditContext.ipAddress,\n userAgent: this.auditContext.userAgent,\n });\n }\n\n return result;\n } catch (error) {\n // Log the failure to audit before re-throwing\n if (this.shouldAudit(table)) {\n await this.logOperationFailure({\n operation: AUDIT_OPERATION.Update,\n table,\n data,\n error: error as Error,\n recordId: id,\n beforeState: before.value,\n });\n }\n throw error;\n }\n }\n\n async delete(table: string, id: string): Promise<DatabaseResult<void>> {\n // Get before state for audit\n const before = await this.baseAdapter.findById(table, id);\n\n try {\n const result = await this.baseAdapter.delete(table, id);\n\n if (result.success && this.shouldAudit(table)) {\n await this.logAudit({\n operation: AUDIT_OPERATION.Delete,\n table,\n recordId: id,\n changes: {\n before: before.success\n ? (before.value as Record<\n string,\n string | number | boolean | Date\n >)\n : undefined,\n },\n userId: this.auditContext.userId,\n requestId: this.auditContext.requestId,\n timestamp: new Date(),\n ipAddress: this.auditContext.ipAddress,\n userAgent: this.auditContext.userAgent,\n });\n }\n\n return result;\n } catch (error) {\n // Log the failure to audit before re-throwing\n if (this.shouldAudit(table)) {\n await this.logOperationFailure({\n operation: AUDIT_OPERATION.Delete,\n table,\n data: null,\n error: error as Error,\n recordId: id,\n beforeState: before.value,\n });\n }\n throw error;\n }\n }\n\n /**\n * Logs operation failures to audit for compliance tracking.\n * Captures the before state, attempted changes, and error details.\n */\n private async logOperationFailure<T>(options: {\n operation: AUDIT_OPERATION;\n table: string;\n data: T | null;\n error: Error;\n recordId?: string;\n beforeState?: unknown;\n }): Promise<void> {\n const { operation, table, data, error, recordId, beforeState } = options;\n\n try {\n // Determine error source (which extension failed)\n const errorSource = this.getErrorSource(error);\n\n // Map operation to failed operation\n const failedOperation = this.getFailedOperation(operation);\n\n await this.logAudit({\n operation: failedOperation,\n table,\n recordId: recordId ?? (data as Record<string, string>)?.id,\n changes: {\n before: beforeState as\n | Record<string, string | number | boolean | Date>\n | undefined,\n attempted: data as\n | Record<string, string | number | boolean | Date>\n | undefined,\n failure: {\n source: errorSource,\n error_type: error.name,\n error_message: error.message,\n error_code: (error as DatabaseError).errorCode,\n },\n },\n userId: this.auditContext.userId,\n requestId: this.auditContext.requestId,\n timestamp: new Date(),\n ipAddress: this.auditContext.ipAddress,\n userAgent: this.auditContext.userAgent,\n });\n } catch (auditError) {\n // Log to console if audit write fails - don't suppress the original error\n logger.error(\n `Failed to log operation failure to audit: ${(auditError as Error).message}`,\n );\n }\n }\n\n /**\n * Maps a successful operation to its failed counterpart.\n */\n private getFailedOperation(operation: AUDIT_OPERATION): AUDIT_OPERATION {\n switch (operation) {\n case AUDIT_OPERATION.Create:\n return AUDIT_OPERATION.CreateFailed;\n case AUDIT_OPERATION.Update:\n return AUDIT_OPERATION.UpdateFailed;\n case AUDIT_OPERATION.Delete:\n return AUDIT_OPERATION.DeleteFailed;\n default:\n return operation;\n }\n }\n\n /**\n * Determines which extension/layer caused the error based on error details.\n */\n private getErrorSource(error: Error): EXTENSION_SOURCE {\n const errorMessage = error.message.toLowerCase();\n const dbError = error as DatabaseError;\n const errorContext = (\n dbError.context as { source?: string }\n )?.source?.toLowerCase();\n\n // Check error context first (most reliable)\n if (errorContext) {\n const contextSource = this.matchPatterns(\n errorContext,\n CONTEXT_SOURCE_PATTERNS,\n );\n if (contextSource) return contextSource;\n }\n\n // Fallback to error message analysis\n const messageSource = this.matchPatterns(\n errorMessage,\n MESSAGE_SOURCE_PATTERNS,\n );\n if (messageSource) return messageSource;\n\n return EXTENSION_SOURCE.DatabaseAdapter;\n }\n\n /**\n * Matches a text against a list of pattern groups.\n */\n private matchPatterns(\n text: string,\n patternGroups: Array<{ patterns: string[]; source: EXTENSION_SOURCE }>,\n ): EXTENSION_SOURCE | null {\n for (const { patterns, source } of patternGroups) {\n if (patterns.some((pattern) => text.includes(pattern))) {\n return source;\n }\n }\n return null;\n }\n\n /**\n * Gets the list of encrypted fields for a table.\n * Returns undefined if no fields are encrypted for this table.\n */\n private getEncryptedFields(table: string): string[] | undefined {\n return this.config.encryptedFields?.[table];\n }\n\n /**\n * Executes operations within a transaction with audit logging.\n *\n * **RESPONSIBILITY:** Passes transaction to base adapter\n * **BEHAVIOR:** Individual operations within transaction are audited\n * **ATOMICITY:** Audit records are part of the transaction\n *\n * @param callback - Transaction callback function\n * @returns Transaction result\n *\n * @example\n * ```typescript\n * const result = await adapter.transaction(async (trx) => {\n * // Each operation creates audit record within transaction\n * const user = await trx.create('users', { name: 'John' });\n * await trx.update('profiles', 'profile-1', { userId: user.id });\n * return user;\n * });\n *\n * // If transaction fails, audit records are also rolled back\n * ```\n */\n async transaction<T>(\n callback: (trx: Transaction) => Promise<T>,\n ): Promise<DatabaseResult<T>> {\n return this.baseAdapter.transaction(callback);\n }\n\n /**\n * Checks if a record exists without audit logging.\n *\n * **RESPONSIBILITY:** Verifies record existence without creating audit trail\n * **BEHAVIOR:** Read operations are not audited by default\n * **PERFORMANCE:** No audit overhead for existence checks\n *\n * @param table - Table name\n * @param id - Record ID\n * @returns True if record exists\n *\n * @example\n * ```typescript\n * // Existence checks don't create audit records\n * const userExists = await adapter.exists('users', 'user-123');\n * if (userExists.value) {\n * console.log('User exists');\n * }\n * ```\n */\n async exists(table: string, id: string): Promise<DatabaseResult<boolean>> {\n return this.baseAdapter.exists(table, id);\n }\n\n /**\n * Counts records without audit logging.\n *\n * **RESPONSIBILITY:** Counts records without creating audit trail\n * **BEHAVIOR:** Read operations are not audited by default\n * **PERFORMANCE:** No audit overhead for counting operations\n *\n * @param table - Table name\n * @param filter - Optional filter conditions\n * @returns Count of records\n *\n * @example\n * ```typescript\n * // Count operations don't create audit records\n * const activeUsers = await adapter.count('users', {\n * field: 'status',\n * operator: 'eq',\n * value: 'active'\n * });\n *\n * console.log('Active users:', activeUsers.value);\n * ```\n */\n async count<T extends Record<string, unknown> = Record<string, unknown>>(\n table: string,\n filter?: Filter<T>,\n ): Promise<DatabaseResult<number>> {\n return this.baseAdapter.count<T>(table, filter);\n }\n\n /**\n * Performs health check through base adapter.\n *\n * **RESPONSIBILITY:** Delegates health check to underlying adapter\n * **BEHAVIOR:** No additional health metrics for audit\n *\n * @returns Health status from base adapter\n *\n * @example\n * ```typescript\n * const health = await adapter.healthCheck();\n * if (health.success && health.value?.isHealthy) {\n * console.log('Database healthy with audit support');\n * }\n * ```\n */\n async healthCheck(): Promise<DatabaseResult<DatabaseHealthStatus>> {\n return this.baseAdapter.healthCheck();\n }\n\n /**\n * Determines if a table should be audited.\n *\n * **RESPONSIBILITY:** Checks if table is enabled for audit logging\n * **CONFIGURATION:** Based on enabled flag and excludeTables array\n *\n * @private\n * @param table - Table name to check\n * @returns True if table should be audited\n *\n * @example\n * ```typescript\n * // Configuration: { enabled: true, excludeTables: ['temp_data'] }\n *\n * this.shouldAudit('users'); // true - will be audited\n * this.shouldAudit('temp_data'); // false - excluded from audit\n * ```\n */\n private shouldAudit(table: string): boolean {\n if (!this.config.enabled) return false;\n return !(this.config.excludeTables?.includes(table) ?? false);\n }\n\n /**\n * Logs an audit event to the audit table and executes custom handlers.\n *\n * **RESPONSIBILITY:** Orchestrates audit record creation and event handling\n * **PROCESS:** Validates event → Writes to audit table → Executes custom handler\n *\n * @private\n * @param event - Audit event to log\n *\n * @example\n * ```typescript\n * // Internal usage after successful operation\n * await this.logAudit({\n * operation: 'CREATE',\n * table: 'users',\n * recordId: 'user-123',\n * changes: { after: userData },\n * userId: 'admin-456',\n * timestamp: new Date()\n * });\n * ```\n */\n private async logAudit(event: AuditEvent): Promise<void> {\n this.validateAuditEvent(event);\n\n await this.writeAuditRecord(event);\n await this.executeCustomHandler(event);\n }\n\n /**\n * Validates audit event has required fields.\n *\n * **RESPONSIBILITY:** Ensures audit event is properly formed\n * **VALIDATION:** Checks for required operation and table fields\n *\n * @private\n * @param event - Audit event to validate\n * @throws {DatabaseError} When event is invalid\n *\n * @example\n * ```typescript\n * // Internal validation before logging\n * this.validateAuditEvent({\n * operation: 'CREATE', // Required\n * table: 'users', // Required\n * recordId: 'user-123'\n * });\n * ```\n */\n private validateAuditEvent(event: AuditEvent): void {\n if (!event?.operation || !event?.table) {\n throw new DatabaseError(\n \"Invalid audit event\",\n DATABASE_ERROR_CODES.INVALID_PARAMETERS,\n {\n context: { source: \"validateAuditEvent\" },\n cause: new Error(\"Invalid audit event\"),\n },\n );\n }\n }\n\n /**\n * Generates the audit table name based on configuration.\n *\n * **RESPONSIBILITY:** Determines the correct table name for audit records\n * **TABLE NAMING:**\n * - Partitioned: `{schema}.audit_log_yyyy_mm_dd` (e.g., audit.audit_log_2024_12_01)\n * - Non-partitioned: `{schema}.audit_logs` (e.g., audit.audit_logs)\n *\n * @private\n * @param timestamp - Timestamp to use for partition date\n * @returns Schema-qualified table name\n */\n private getAuditTableName(timestamp: Date): string {\n if (this.usePartitionedTables) {\n const year = timestamp.getFullYear();\n const month = String(timestamp.getMonth() + 1).padStart(\n DATE_PART_MIN_WIDTH,\n \"0\",\n );\n const day = String(timestamp.getDate()).padStart(\n DATE_PART_MIN_WIDTH,\n \"0\",\n );\n return `${this.auditSchema}.audit_log_${year}_${month}_${day}`;\n }\n return `${this.auditSchema}.audit_logs`;\n }\n\n /**\n * Writes audit record to daily audit table.\n *\n * **RESPONSIBILITY:** Persists audit event to database\n * **TABLE NAMING:** Uses daily partitioned tables (audit.audit_log_yyyy_mm_dd) by default\n * **STRUCTURE:** Converts event to database record format\n *\n * @private\n * @param event - Audit event to write\n * @throws {DatabaseError} When write operation fails\n *\n * @example\n * ```typescript\n * // Internal usage - writes to audit.audit_log_2024_12_01 table\n * await this.writeAuditRecord({\n * operation: 'UPDATE',\n * table: 'users',\n * recordId: 'user-123',\n * changes: { before: {...}, after: {...} },\n * timestamp: new Date('2024-12-01')\n * });\n * ```\n */\n private async writeAuditRecord(event: AuditEvent): Promise<void> {\n const tableName = this.getAuditTableName(event.timestamp);\n try {\n const auditResult = await this.baseAdapter.create(tableName, {\n operation: event.operation,\n table_name: event.table,\n record_id: event.recordId,\n user_id: event.userId,\n request_id: event.requestId,\n changes: event.changes,\n ip_address: event.ipAddress,\n user_agent: event.userAgent,\n timestamp: event.timestamp,\n });\n\n if (!auditResult.success) {\n throw new DatabaseError(\n \"Failed to write audit record\",\n DATABASE_ERROR_CODES.CREATE_FAILED,\n {\n context: { source: \"writeAuditRecord\" },\n cause:\n auditResult.error ?? new Error(\"Failed to write audit record\"),\n },\n );\n }\n } catch (error) {\n logger.error(`Audit write failed: ${(error as Error).message}`);\n throw new DatabaseError(\n \"Failed to write audit record\",\n DATABASE_ERROR_CODES.CREATE_FAILED,\n {\n context: { source: \"writeAuditRecord\" },\n cause: error as Error,\n },\n );\n }\n }\n\n /**\n * Executes custom audit event handler if configured.\n *\n * **RESPONSIBILITY:** Calls user-defined audit event handler\n * **ERROR HANDLING:** Logs handler errors without failing the operation\n * **USE CASE:** Integration with compliance systems, notifications\n *\n * @private\n * @param event - Audit event to handle\n *\n * @example\n * ```typescript\n * // Configuration with custom handler\n * {\n * onAuditAfterWrite: async (event) => {\n * await complianceService.recordAudit(event);\n * await notificationService.sendAuditAlert(event);\n * }\n * }\n *\n * // Handler is called after successful audit record write\n * ```\n */\n private async executeCustomHandler(event: AuditEvent): Promise<void> {\n if (this.config.onAuditAfterWrite) {\n try {\n await this.config.onAuditAfterWrite(event);\n } catch (handlerError) {\n logger.error(\n `Custom audit handler failed: ${(handlerError as Error).message}`,\n );\n }\n }\n }\n}\n","import { createCipheriv, createDecipheriv, randomBytes } from \"crypto\";\nimport {\n type DatabaseAdapterType,\n type DatabaseResult,\n type QueryOptions,\n type PaginatedResult,\n type Transaction,\n type Filter,\n type DatabaseHealthStatus,\n ENCRYPTION_DEFAULTS,\n} from \"@plyaz/types/db\";\nimport { isString, isObject } from \"@utils/typeGuards\";\nimport { DatabaseError } from \"@plyaz/errors\";\nimport { DATABASE_ERROR_CODES } from \"@plyaz/types/errors\";\n\n/**\n * ENCRYPTION ADAPTER — Field-Level Encryption Layer\n *\n * Encryption extension that automatically encrypts/decrypts specified fields.\n * Second layer in the adapter chain (after the base adapter).\n *\n * **Adapter Chain Position:**\n * ReadReplica → Audit → Cache → SoftDelete → **Encryption** → Base Adapter\n *\n * **What this adapter does:**\n * 1. Receives operations from SoftDeleteAdapter (or the next layer)\n * 2. Encrypts sensitive fields before write operations (create, update)\n * 3. Delegates to the base adapter with encrypted data\n * 4. Decrypts fields in response data after read operations\n * 5. Passes results back up the chain\n *\n * **Called by:** SoftDeleteAdapter (or CachingAdapter if no soft delete)\n * **Calls:** Base adapter methods (DrizzleAdapter, SupabaseAdapter, etc.)\n * **Wraps:** Base database adapter with transparent encryption\n *\n * **Encryption Flow:**\n * - **Writes:** Plain data → Encrypt fields → Store encrypted → Return decrypted\n * - **Reads:** Retrieve encrypted → Decrypt fields → Return plain data\n *\n * @example\n * ### Configuration\n * ```typescript\n * encryption: {\n * enabled: true,\n * key: process.env.ENCRYPTION_KEY,\n * fields: {\n * [Tables.USERS]: ['ssn', 'taxId'],\n * [Tables.PAYMENTS]: ['cardNumber', 'cvv']\n * }\n * }\n * ```\n *\n * @example\n * ### Transparent Usage\n * ```typescript\n * // Application code — encryption is transparent\n * await db.create(Tables.USERS, {\n * name: 'John Doe',\n * ssn: '123-45-6789' // Automatically encrypted before storage\n * });\n *\n * // Retrieved data is automatically decrypted\n * const user = await db.get(Tables.USERS, userId);\n * console.log(user.value.ssn); // '123-45-6789' (decrypted)\n * ```\n */\n\nexport class EncryptionAdapter implements DatabaseAdapterType {\n // Using shared logger instance from @plyaz/logger\n\n constructor(\n public baseAdapter: DatabaseAdapterType,\n private config: {\n enabled: boolean;\n key: string;\n fields: Record<string, string[]>;\n algorithm?: string;\n },\n ) {}\n\n async initialize(): Promise<DatabaseResult<void>> {\n return this.baseAdapter.initialize();\n }\n\n async connect(): Promise<void> {\n return this.baseAdapter.connect();\n }\n\n async disconnect(): Promise<void> {\n return this.baseAdapter.disconnect();\n }\n\n async close(): Promise<DatabaseResult<void>> {\n return this.baseAdapter.close();\n }\n\n getClient(): object {\n return this.baseAdapter.getClient();\n }\n\n async query<T>(sql: string, params?: T[]): Promise<T[]> {\n return this.baseAdapter.query(sql, params);\n }\n\n registerTable<T, U>(name: string, table: T, idColumn?: U): void {\n this.baseAdapter.registerTable(name, table, idColumn);\n }\n\n async findById<T>(\n table: string,\n id: string,\n ): Promise<DatabaseResult<T | null>> {\n const result = await this.baseAdapter.findById<T>(table, id);\n if (result.success && result.value) {\n result.value = this.decryptFields(table, result.value);\n }\n return result;\n }\n\n async findMany<T extends Record<string, unknown>>(\n table: string,\n options?: QueryOptions<T>,\n ): Promise<DatabaseResult<PaginatedResult<T>>> {\n const result = await this.baseAdapter.findMany<T>(table, options);\n if (result.success && result.value) {\n result.value.data = result.value.data.map((item) =>\n this.decryptFields(table, item),\n );\n }\n return result;\n }\n\n async create<T extends Record<string, unknown>>(\n table: string,\n data: T,\n ): Promise<DatabaseResult<T>> {\n // Encryption is critical for compliance - fail if encryption fails\n // AuditAdapter (outer layer) will catch and log the failure\n const encryptedData = this.encryptFields(table, data);\n const result = await this.baseAdapter.create<T>(table, encryptedData);\n if (result.success && result.value) {\n result.value = this.decryptFields(table, result.value);\n }\n return result;\n }\n\n async update<T>(\n table: string,\n id: string,\n data: Partial<T>,\n ): Promise<DatabaseResult<T>> {\n // Encryption is critical for compliance - fail if encryption fails\n // AuditAdapter (outer layer) will catch and log the failure\n const encryptedData = this.encryptFields(table, data);\n const result = await this.baseAdapter.update<T>(table, id, encryptedData);\n if (result.success && result.value) {\n result.value = this.decryptFields(table, result.value);\n }\n return result;\n }\n\n async delete(table: string, id: string): Promise<DatabaseResult<void>> {\n return this.baseAdapter.delete(table, id);\n }\n\n async transaction<T>(\n callback: (trx: Transaction) => Promise<T>,\n ): Promise<DatabaseResult<T>> {\n return this.baseAdapter.transaction(callback);\n }\n\n async exists(table: string, id: string): Promise<DatabaseResult<boolean>> {\n return this.baseAdapter.exists(table, id);\n }\n\n async count<T extends Record<string, unknown> = Record<string, unknown>>(\n table: string,\n filter?: Filter<T>,\n ): Promise<DatabaseResult<number>> {\n return this.baseAdapter.count<T>(table, filter);\n }\n\n async healthCheck(): Promise<DatabaseResult<DatabaseHealthStatus>> {\n return this.baseAdapter.healthCheck();\n }\n\n private encryptFields<T extends Record<string, unknown>>(\n table: string,\n data: T,\n ): T {\n if (!this.shouldProcessFields(data, table)) return data;\n\n const fieldsToEncrypt = this.config.fields[table];\n const result = { ...data } as T;\n\n for (const field of fieldsToEncrypt) {\n this.encryptSingleField(result, field);\n }\n\n return result as T;\n }\n\n private shouldProcessFields<T>(data: T, table: string): boolean {\n return (\n this.config.enabled &&\n isObject(data) &&\n Boolean(this.config.fields[table])\n );\n }\n\n private encryptSingleField<T extends Record<string, unknown>>(\n result: T,\n field: string,\n ): void {\n if (result[field as keyof T]) {\n result[field as keyof T] = this.encrypt(\n String(result[field as keyof T]),\n ) as T[keyof T];\n }\n }\n\n private decryptFields<T extends Record<string, unknown>>(\n table: string,\n data: T,\n ): T {\n if (!this.shouldProcessFields(data, table)) return data;\n\n const fieldsToDecrypt = this.config.fields[table];\n const result = { ...data } as T;\n\n for (const field of fieldsToDecrypt) {\n this.decryptSingleField(result, field);\n }\n\n return result as T;\n }\n\n private decryptSingleField<T extends Record<string, unknown>>(\n result: T,\n field: string,\n ): void {\n if (result[field as keyof T]) {\n const fieldValue = String(result[field as keyof T]);\n // Check if the field value is encrypted (contains colons)\n // If not encrypted, return as-is (backwards compatibility with old data)\n if (this.isEncryptedValue(fieldValue)) {\n try {\n result[field as keyof T] = this.decrypt(fieldValue) as T[keyof T];\n } catch (error) {\n // Decryption failed - might be corrupted data or wrong key\n console.warn(\n `Failed to decrypt field ${field}, returning as-is:`,\n (error as Error).message,\n );\n }\n }\n }\n }\n\n private encrypt(text: string): string {\n this.validateEncryptionInput(text);\n\n const { iv, cipher } = this.createCipher();\n const encrypted = this.performEncryption(cipher, text);\n const authTag =\n (cipher as { getAuthTag?: () => Buffer }).getAuthTag?.() ??\n Buffer.alloc(0);\n\n return iv.toString(\"hex\") + \":\" + authTag.toString(\"hex\") + \":\" + encrypted;\n }\n\n private validateEncryptionInput(text: string): void {\n if (!isString(text)) {\n throw new DatabaseError(\n \"Invalid text for encryption\",\n DATABASE_ERROR_CODES.INVALID_PARAMETERS,\n {\n context: { source: \"validateEncryptionInput\" },\n cause: new Error(\"Invalid text for encryption\"),\n },\n );\n }\n if (!this.config.key) {\n throw new DatabaseError(\n \"Encryption key is required\",\n DATABASE_ERROR_CODES.CONFIG_REQUIRED,\n {\n context: { source: \"validateEncryptionInput\" },\n cause: new Error(\"Encryption key is required\"),\n },\n );\n }\n }\n\n private createCipher(): {\n iv: Buffer;\n cipher: ReturnType<typeof createCipheriv>;\n } {\n const algorithm = this.config.algorithm ?? ENCRYPTION_DEFAULTS.ALGORITHM;\n const key = this.getKeyBuffer();\n const iv = randomBytes(ENCRYPTION_DEFAULTS.IV_LENGTH);\n const cipher = createCipheriv(algorithm, key, iv);\n return { iv, cipher };\n }\n\n private performEncryption(\n cipher: ReturnType<typeof createCipheriv>,\n text: string,\n ): string {\n let encrypted = cipher.update(text, \"utf8\", \"hex\");\n encrypted += cipher.final(\"hex\");\n return encrypted;\n }\n\n private decrypt(encryptedText: string): string {\n this.validateDecryptionInput(encryptedText);\n\n const parts = this.parseEncryptedText(encryptedText);\n const { iv, authTag, encrypted } = this.extractDecryptionParts(parts);\n const decipher = this.createDecipher(iv, authTag);\n\n return this.performDecryption(decipher, encrypted);\n }\n\n private validateDecryptionInput(encryptedText: string): void {\n if (!isString(encryptedText)) {\n throw new DatabaseError(\n \"Invalid encrypted text for decryption\",\n DATABASE_ERROR_CODES.INVALID_PARAMETERS,\n {\n context: { source: \"validateDecryptionInput\" },\n cause: new Error(\"Invalid encrypted text for decryption\"),\n },\n );\n }\n if (!this.config.key) {\n throw new DatabaseError(\n \"Encryption key is required\",\n DATABASE_ERROR_CODES.CONFIG_REQUIRED,\n {\n context: { source: \"validateDecryptionInput\" },\n cause: new Error(\"Encryption key is required\"),\n },\n );\n }\n }\n\n private parseEncryptedText(encryptedText: string): string[] {\n const parts = encryptedText.split(\":\");\n if (parts.length !== ENCRYPTION_DEFAULTS.ENCRYPTED_PARTS_COUNT) {\n throw new DatabaseError(\n \"Invalid encrypted text format\",\n DATABASE_ERROR_CODES.INVALID_PARAMETERS,\n {\n context: { source: \"parseEncryptedText\" },\n cause: new Error(\"Invalid encrypted text format\"),\n },\n );\n }\n return parts;\n }\n\n private extractDecryptionParts(parts: string[]): {\n iv: Buffer;\n authTag: Buffer;\n encrypted: string;\n } {\n const iv = Buffer.from(parts[0], \"hex\");\n const authTag = Buffer.from(parts[1], \"hex\");\n const encrypted = parts[2];\n return { iv, authTag, encrypted };\n }\n\n private createDecipher(\n iv: Buffer,\n authTag: Buffer,\n ): ReturnType<typeof createDecipheriv> {\n const algorithm = this.config.algorithm ?? ENCRYPTION_DEFAULTS.ALGORITHM;\n const key = this.getKeyBuffer();\n const decipher = createDecipheriv(algorithm, key, iv);\n\n if (authTag.length > 0) {\n (decipher as { setAuthTag?: (tag: Buffer) => void }).setAuthTag?.(\n authTag,\n );\n }\n\n return decipher;\n }\n\n private performDecryption(\n decipher: ReturnType<typeof createDecipheriv>,\n encrypted: string,\n ): string {\n let decrypted = decipher.update(encrypted, \"hex\", \"utf8\");\n decrypted += decipher.final(\"utf8\");\n return decrypted;\n }\n\n private isEncryptedValue(value: string): boolean {\n // Encrypted values have format: iv:authTag:encrypted (3 parts separated by colons)\n const parts = value.split(\":\");\n return parts.length === ENCRYPTION_DEFAULTS.ENCRYPTED_PARTS_COUNT;\n }\n\n private getKeyBuffer(): Buffer {\n // AES-256-GCM requires 32-byte key\n const AES_256_KEY_LENGTH = 32;\n const keyBuffer = Buffer.from(this.config.key, \"utf8\");\n\n if (keyBuffer.length !== AES_256_KEY_LENGTH) {\n throw new DatabaseError(\n `Encryption key must be exactly ${AES_256_KEY_LENGTH} bytes for AES-256, got ${keyBuffer.length}`,\n DATABASE_ERROR_CODES.CONFIG_REQUIRED,\n {\n context: { source: \"getKeyBuffer\" },\n cause: new Error(\"Invalid key length\"),\n },\n );\n }\n\n return keyBuffer;\n }\n}\n","import { NUMERIX } from \"@plyaz/config\";\nimport { logger } from \"@plyaz/logger\";\nimport type {\n DatabaseAdapterType,\n DatabaseResult,\n DBCacheConfig,\n Filter,\n DatabaseHealthStatus,\n PaginatedResult,\n QueryOptions,\n Transaction,\n} from \"@plyaz/types/db\";\n/**\n * CACHING ADAPTER - Query Result Caching Layer\n *\n * Caching extension that stores query results in memory for improved performance.\n * Third layer in the adapter chain.\n *\n * **Adapter Chain Position:**\n * ReadReplica → Audit → **Cache** → SoftDelete → Encryption → Base Adapter\n *\n * **What this adapter does:**\n * 1. Intercepts findById() operations → checks cache first, stores results\n * 2. Intercepts write operations → invalidates related cache entries\n * 3. Manages TTL-based cache expiration\n * 4. Honors cache configuration (enabled, ttl, invalidation strategy)\n *\n * **Called by:** AuditAdapter (or ReadReplicaAdapter if no audit)\n * **Calls:** SoftDeleteAdapter (or next adapter in chain)\n * **Cache Strategy:** In-memory Map with TTL expiration\n *\n * **Cache Flow:**\n * - **READ:** Check cache → Return if hit → Query DB → Cache result\n * - **WRITE:** Execute operation → Invalidate related cache entries\n *\n * @example\n * ### Configuration\n * ```typescript\n * cache: {\n * enabled: true,\n * ttl: 300, // 5 minutes\n * invalidation: 'write', // Invalidate on writes\n * maxSize: 1000 // Max cache entries\n * }\n * ```\n *\n * @example\n * ### Cache Behavior\n * ```typescript\n * // First call - cache miss, queries database\n * const user1 = await db.findById('users', 'user-123'); // DB query\n *\n * // Second call - cache hit, returns from memory\n * const user2 = await db.findById('users', 'user-123'); // Cache hit\n *\n * // Write operation invalidates cache\n * await db.update('users', 'user-123', { name: 'New Name' });\n *\n * // Next read - cache miss again, queries database\n * const user3 = await db.findById('users', 'user-123'); // DB query\n * ```\n */\nexport class CachingAdapter implements DatabaseAdapterType {\n private cache = new Map<\n string,\n {\n value:\n | Record<string, string | number | boolean | Date>\n | Record<string, string | number | boolean | Date>[];\n expiry: number;\n }\n >();\n\n /**\n * Creates a new CachingAdapter instance.\n *\n * **RESPONSIBILITY:** Wraps base adapter with caching functionality\n * **CONFIGURATION:** Sets up cache TTL, invalidation strategy, and size limits\n *\n * @param baseAdapter - The underlying database adapter to wrap\n * @param config - Cache configuration options\n *\n * @example\n * ```typescript\n * const cachingAdapter = new CachingAdapter(baseAdapter, {\n * enabled: true,\n * ttl: 300, // 5 minutes\n * invalidation: 'write', // Invalidate on writes\n * maxSize: 1000 // Max entries\n * });\n * ```\n */\n constructor(\n public baseAdapter: DatabaseAdapterType,\n private config: DBCacheConfig,\n ) {}\n\n /**\n * Initializes the caching adapter and underlying adapter.\n *\n * **RESPONSIBILITY:** Passes initialization to base adapter\n * **BEHAVIOR:** No additional initialization needed for caching\n *\n * @returns Promise resolving to initialization result\n *\n * @example\n * ```typescript\n * const result = await cachingAdapter.initialize();\n * if (result.success) {\n * console.log('Caching adapter initialized');\n * }\n * ```\n */\n async initialize(): Promise<DatabaseResult<void>> {\n return this.baseAdapter.initialize();\n }\n\n /**\n * Establishes database connection through base adapter.\n *\n * **RESPONSIBILITY:** Delegates connection to underlying adapter\n * **BEHAVIOR:** No additional connection logic needed\n *\n * @example\n * ```typescript\n * await cachingAdapter.connect();\n * console.log('Connected with caching support');\n * ```\n */\n async connect(): Promise<void> {\n return this.baseAdapter.connect();\n }\n\n /**\n * Closes database connection through base adapter.\n *\n * **RESPONSIBILITY:** Delegates disconnection to underlying adapter\n * **BEHAVIOR:** Cache is cleared on disconnect\n *\n * @example\n * ```typescript\n * await cachingAdapter.disconnect();\n * console.log('Disconnected and cache cleared');\n * ```\n */\n async disconnect(): Promise<void> {\n return this.baseAdapter.disconnect();\n }\n\n async close(): Promise<DatabaseResult<void>> {\n return this.baseAdapter.close();\n }\n\n /**\n * Gets the underlying database client.\n *\n * **RESPONSIBILITY:** Provides access to raw database client\n * **USE CASE:** For operations that bypass caching\n *\n * @returns Database client object\n *\n * @example\n * ```typescript\n * const client = cachingAdapter.getClient();\n * // Use for direct database operations if needed\n * ```\n */\n getClient(): object {\n return this.baseAdapter.getClient();\n }\n\n /**\n * Executes raw SQL query through base adapter.\n *\n * **RESPONSIBILITY:** Passes raw SQL to base adapter without caching\n * **BEHAVIOR:** Does not cache raw SQL results\n * **NOTE:** Use findById/findMany for automatic caching\n *\n * @param sql - SQL query string\n * @param params - Query parameters\n * @returns Query results\n *\n * @example\n * ```typescript\n * // Raw SQL bypasses caching\n * const results = await adapter.query(\n * 'SELECT * FROM users WHERE status = $1',\n * ['active']\n * );\n *\n * // Use findMany for automatic caching\n * const users = await adapter.findMany('users', { filter: ... });\n * ```\n */\n async query<T>(sql: string, params?: T[]): Promise<T[]> {\n return this.baseAdapter.query(sql, params);\n }\n\n /**\n * Registers a table schema with the base adapter.\n *\n * **RESPONSIBILITY:** Passes table registration to base adapter\n * **BEHAVIOR:** No additional registration logic needed\n *\n * @param name - Table name\n * @param table - Table schema\n * @param idColumn - Primary key column\n *\n * @example\n * ```typescript\n * cachingAdapter.registerTable('users', userSchema, 'id');\n * // Table now supports cached operations\n * ```\n */\n registerTable<T, U>(name: string, table: T, idColumn?: U): void {\n this.baseAdapter.registerTable(name, table, idColumn);\n }\n\n async findById<T>(\n table: string,\n id: string,\n ): Promise<DatabaseResult<T | null>> {\n if (!this.config.enabled) {\n return this.baseAdapter.findById<T>(table, id);\n }\n\n const cacheKey = `${table}:${id}`;\n const cached = this.getFromCache<T>(cacheKey);\n\n if (cached !== null) {\n logger.debug(`Cache hit for ${table}:${id}`);\n return { success: true, value: cached };\n }\n\n const result = await this.baseAdapter.findById<T>(table, id);\n\n if (result.success && result.value) {\n this.setCache(cacheKey, result.value);\n logger.debug(`Cache set for ${table}:${id}`);\n }\n\n return result;\n }\n\n /**\n * Finds multiple records without caching.\n *\n * **RESPONSIBILITY:** Retrieves multiple records, bypassing cache\n * **BEHAVIOR:** Complex queries are not cached currently\n * **FUTURE:** Could implement query result caching with cache keys\n *\n * @param table - Table name\n * @param options - Query options\n * @returns Paginated results\n *\n * @example\n * ```typescript\n * // Complex queries bypass cache (for now)\n * const users = await adapter.findMany('users', {\n * filter: { field: 'status', operator: 'eq', value: 'active' },\n * pagination: { page: 1, limit: 10 },\n * sort: { field: 'name', direction: 'asc' }\n * });\n *\n * // Always queries database directly\n * ```\n */\n async findMany<T extends Record<string, unknown>>(\n table: string,\n options?: QueryOptions<T>,\n ): Promise<DatabaseResult<PaginatedResult<T>>> {\n // For now, skip caching for complex queries\n return this.baseAdapter.findMany<T>(table, options);\n }\n\n /**\n * Creates a new record with cache invalidation.\n *\n * **RESPONSIBILITY:** Creates record and invalidates related cache entries\n * **INVALIDATION:** Clears table cache on successful write\n * **STRATEGY:** Based on config.invalidation setting\n *\n * @param table - Table name\n * @param data - Record data\n * @returns Created record\n *\n * @example\n * ```typescript\n * // Create user - invalidates users table cache\n * const result = await adapter.create('users', {\n * name: 'John Doe',\n * email: 'john@example.com'\n * });\n *\n * if (result.success) {\n * console.log('User created:', result.value.id);\n * // All cached users:* entries are now invalid\n * }\n * ```\n */\n async create<T extends Record<string, unknown>>(\n table: string,\n data: T,\n ): Promise<DatabaseResult<T>> {\n const result = await this.baseAdapter.create<T>(table, data);\n\n if (result.success && this.config.invalidation === \"write\") {\n this.invalidateTable(table);\n }\n\n return result;\n }\n\n /**\n * Updates an existing record with cache invalidation.\n *\n * **RESPONSIBILITY:** Updates record and invalidates related cache entries\n * **INVALIDATION:** Clears specific record and table cache\n * **STRATEGY:** Invalidates both table:id and table:* patterns\n *\n * @param table - Table name\n * @param id - Record ID\n * @param data - Partial record data\n * @returns Updated record\n *\n * @example\n * ```typescript\n * // Update user - invalidates specific cache entry\n * const result = await adapter.update('users', 'user-123', {\n * name: 'Jane Doe'\n * });\n *\n * if (result.success) {\n * console.log('User updated:', result.value.name);\n * // Cache entries users:user-123 and users:* are invalidated\n * }\n * ```\n */\n async update<T>(\n table: string,\n id: string,\n data: Partial<T>,\n ): Promise<DatabaseResult<T>> {\n const result = await this.baseAdapter.update<T>(table, id, data);\n\n if (result.success && this.config.invalidation === \"write\") {\n this.invalidateTable(table);\n this.invalidateKey(`${table}:${id}`);\n }\n\n return result;\n }\n\n /**\n * Deletes a record with cache invalidation.\n *\n * **RESPONSIBILITY:** Deletes record and invalidates related cache entries\n * **INVALIDATION:** Clears specific record and table cache\n * **STRATEGY:** Removes both table:id and table:* patterns\n *\n * @param table - Table name\n * @param id - Record ID\n * @returns Deletion result\n *\n * @example\n * ```typescript\n * // Delete user - invalidates cache entries\n * const result = await adapter.delete('users', 'user-123');\n *\n * if (result.success) {\n * console.log('User deleted successfully');\n * // Cache entries users:user-123 and users:* are invalidated\n * }\n * ```\n */\n async delete(table: string, id: string): Promise<DatabaseResult<void>> {\n const result = await this.baseAdapter.delete(table, id);\n\n if (result.success && this.config.invalidation === \"write\") {\n this.invalidateTable(table);\n this.invalidateKey(`${table}:${id}`);\n }\n\n return result;\n }\n\n /**\n * Executes operations within a transaction.\n *\n * **RESPONSIBILITY:** Passes transaction to base adapter\n * **BEHAVIOR:** Cache invalidation happens per operation within transaction\n * **ATOMICITY:** Cache invalidation is not rolled back if transaction fails\n *\n * @param callback - Transaction callback function\n * @returns Transaction result\n *\n * @example\n * ```typescript\n * const result = await adapter.transaction(async (trx) => {\n * // Each operation invalidates cache independently\n * const user = await trx.create('users', { name: 'John' });\n * await trx.update('profiles', 'profile-1', { userId: user.id });\n * return user;\n * });\n *\n * // Cache invalidation happens even if transaction fails\n * ```\n */\n async transaction<T>(\n callback: (trx: Transaction) => Promise<T>,\n ): Promise<DatabaseResult<T>> {\n return this.baseAdapter.transaction(callback);\n }\n\n /**\n * Checks if a record exists without caching.\n *\n * **RESPONSIBILITY:** Verifies record existence, bypassing cache\n * **BEHAVIOR:** Existence checks are not cached currently\n * **PERFORMANCE:** Always queries database for existence\n *\n * @param table - Table name\n * @param id - Record ID\n * @returns True if record exists\n *\n * @example\n * ```typescript\n * // Existence checks bypass cache\n * const userExists = await adapter.exists('users', 'user-123');\n * if (userExists.value) {\n * console.log('User exists');\n * }\n *\n * // Always queries database directly\n * ```\n */\n async exists(table: string, id: string): Promise<DatabaseResult<boolean>> {\n return this.baseAdapter.exists(table, id);\n }\n\n /**\n * Counts records without caching.\n *\n * **RESPONSIBILITY:** Counts records, bypassing cache\n * **BEHAVIOR:** Count operations are not cached currently\n * **PERFORMANCE:** Always queries database for counts\n *\n * @param table - Table name\n * @param filter - Optional filter conditions\n * @returns Count of records\n *\n * @example\n * ```typescript\n * // Count operations bypass cache\n * const activeUsers = await adapter.count('users', {\n * field: 'status',\n * operator: 'eq',\n * value: 'active'\n * });\n *\n * console.log('Active users:', activeUsers.value);\n * // Always queries database directly\n * ```\n */\n async count<T extends Record<string, unknown> = Record<string, unknown>>(\n table: string,\n filter?: Filter<T>,\n ): Promise<DatabaseResult<number>> {\n return this.baseAdapter.count<T>(table, filter);\n }\n\n /**\n * Performs health check through base adapter.\n *\n * **RESPONSIBILITY:** Delegates health check to underlying adapter\n * **BEHAVIOR:** No additional health metrics for cache\n *\n * @returns Health status from base adapter\n *\n * @example\n * ```typescript\n * const health = await adapter.healthCheck();\n * if (health.success && health.value?.isHealthy) {\n * console.log('Database healthy with caching support');\n * }\n * ```\n */\n async healthCheck(): Promise<DatabaseResult<DatabaseHealthStatus>> {\n return this.baseAdapter.healthCheck();\n }\n\n /**\n * Retrieves value from cache with TTL validation.\n *\n * **RESPONSIBILITY:** Gets cached value and validates expiration\n * **TTL HANDLING:** Removes expired entries automatically\n * **RETURN:** Cached value or null if not found/expired\n *\n * @private\n * @param key - Cache key to retrieve\n * @returns Cached value or null\n *\n * @example\n * ```typescript\n * // Internal usage\n * const user = this.getFromCache<User>('users:user-123');\n * if (user) {\n * console.log('Cache hit:', user.name);\n * } else {\n * console.log('Cache miss or expired');\n * }\n * ```\n */\n private getFromCache<T>(key: string): T | null {\n const cached = this.cache.get(key);\n if (!cached) return null;\n\n if (Date.now() > cached.expiry) {\n this.cache.delete(key);\n return null;\n }\n\n return cached.value as T;\n }\n\n /**\n * Stores value in cache with TTL expiration.\n *\n * **RESPONSIBILITY:** Caches value with calculated expiration time\n * **TTL:** Uses config.ttl or default 5 minutes (300 seconds)\n * **EXPIRY:** Calculates absolute expiration timestamp\n *\n * @private\n * @param key - Cache key to store\n * @param value - Value to cache\n *\n * @example\n * ```typescript\n * // Internal usage after database query\n * this.setCache('users:user-123', userData);\n *\n * // Value will expire after TTL seconds\n * // Default: 5 minutes from now\n * ```\n */\n private setCache(\n key: string,\n value:\n | Record<string, string | number | boolean | Date>\n | Record<string, string | number | boolean | Date>[],\n ): void {\n const ttl = this.config.ttl ?? NUMERIX.THREE_HUNDERD; // Default 5 minutes\n const expiry = Date.now() + ttl * NUMERIX.THOUSAND;\n this.cache.set(key, { value, expiry });\n }\n\n /**\n * Removes specific key from cache.\n *\n * **RESPONSIBILITY:** Invalidates single cache entry\n * **USE CASE:** Called after record updates/deletes\n * **PATTERN:** Removes exact key match\n *\n * @private\n * @param key - Cache key to invalidate\n *\n * @example\n * ```typescript\n * // Internal usage after record update\n * this.invalidateKey('users:user-123');\n *\n * // Only users:user-123 is removed from cache\n * // Other users:* entries remain cached\n * ```\n */\n private invalidateKey(key: string): void {\n this.cache.delete(key);\n }\n\n /**\n * Removes all cache entries for a table.\n *\n * **RESPONSIBILITY:** Invalidates all entries matching table pattern\n * **USE CASE:** Called after any write operation to table\n * **PATTERN:** Removes all keys starting with 'table:'\n *\n * @private\n * @param table - Table name to invalidate\n *\n * @example\n * ```typescript\n * // Internal usage after any write to users table\n * this.invalidateTable('users');\n *\n * // Removes all cache entries:\n * // - users:user-123\n * // - users:user-456\n * // - users:admin-789\n * // But keeps: profiles:profile-1, posts:post-1, etc.\n * ```\n */\n private invalidateTable(table: string): void {\n for (const key of this.cache.keys()) {\n if (key.startsWith(`${table}:`)) {\n this.cache.delete(key);\n }\n }\n }\n}\n","import type {\n DatabaseAdapterType,\n DatabaseResult,\n QueryOptions,\n PaginatedResult,\n Transaction,\n Filter,\n DatabaseHealthStatus,\n ReadReplicaConfig,\n} from \"@plyaz/types/db\";\n\n/**\n * Read replica extension that routes read operations to replicas\n * This is the outermost wrapper in the adapter chain\n */\nexport class ReadReplicaAdapter implements DatabaseAdapterType {\n private currentReplicaIndex = 0;\n\n constructor(\n private primaryAdapter: DatabaseAdapterType,\n private config: ReadReplicaConfig,\n ) {}\n\n async initialize(): Promise<DatabaseResult<void>> {\n return this.primaryAdapter.initialize();\n }\n\n async connect(): Promise<void> {\n return this.primaryAdapter.connect();\n }\n\n async disconnect(): Promise<void> {\n return this.primaryAdapter.disconnect();\n }\n\n async close(): Promise<DatabaseResult<void>> {\n return this.primaryAdapter.close();\n }\n\n getClient(): object {\n return this.primaryAdapter.getClient();\n }\n\n async query<T>(sql: string, params?: T[]): Promise<T[]> {\n return this.primaryAdapter.query(sql, params);\n }\n\n registerTable<T, U>(name: string, table: T, idColumn?: U): void {\n this.primaryAdapter.registerTable(name, table, idColumn);\n }\n\n async findById<T>(\n table: string,\n id: string,\n ): Promise<DatabaseResult<T | null>> {\n // Route reads to replicas if available\n const adapter = this.getReadAdapter();\n return adapter.findById<T>(table, id);\n }\n\n async findMany<T extends Record<string, unknown>>(\n table: string,\n options?: QueryOptions<T>,\n ): Promise<DatabaseResult<PaginatedResult<T>>> {\n // Route reads to replicas if available\n const adapter = this.getReadAdapter();\n return adapter.findMany<T>(table, options);\n }\n\n async create<T extends Record<string, unknown>>(\n table: string,\n data: T,\n ): Promise<DatabaseResult<T>> {\n // Always route writes to primary\n return this.primaryAdapter.create<T>(table, data);\n }\n\n async update<T>(\n table: string,\n id: string,\n data: Partial<T>,\n ): Promise<DatabaseResult<T>> {\n // Always route writes to primary\n return this.primaryAdapter.update<T>(table, id, data);\n }\n\n async delete(table: string, id: string): Promise<DatabaseResult<void>> {\n // Always route writes to primary\n return this.primaryAdapter.delete(table, id);\n }\n\n async transaction<T>(\n callback: (trx: Transaction) => Promise<T>,\n ): Promise<DatabaseResult<T>> {\n // Always route transactions to primary\n return this.primaryAdapter.transaction(callback);\n }\n\n async exists(table: string, id: string): Promise<DatabaseResult<boolean>> {\n // Route reads to replicas if available\n const adapter = this.getReadAdapter();\n return adapter.exists(table, id);\n }\n\n async count<T extends Record<string, unknown> = Record<string, unknown>>(\n table: string,\n filter?: Filter<T>,\n ): Promise<DatabaseResult<number>> {\n // Route reads to replicas if available\n const adapter = this.getReadAdapter();\n return adapter.count<T>(table, filter);\n }\n\n async healthCheck(): Promise<DatabaseResult<DatabaseHealthStatus>> {\n return this.primaryAdapter.healthCheck();\n }\n\n /**\n * Get the appropriate adapter for read operations\n * Routes to replicas using the configured strategy\n */\n private getReadAdapter(): DatabaseAdapterType {\n if (!this.config.enabled || this.config.replicas.length === 0) {\n return this.primaryAdapter;\n }\n\n switch (this.config.strategy) {\n case \"round-robin\": {\n const replica = this.config.replicas[this.currentReplicaIndex];\n this.currentReplicaIndex =\n (this.currentReplicaIndex + 1) % this.config.replicas.length;\n return replica;\n }\n\n case \"random\": {\n const randomIndex = Math.floor(\n Math.random() * this.config.replicas.length,\n );\n return this.config.replicas[randomIndex];\n }\n\n default:\n // Default to first replica\n return this.config.replicas[0];\n }\n }\n}\n","/**\n * DATABASE SERVICE FACTORY - Main Entry Point\n *\n * This file is responsible for creating fully configured database services with extension chains.\n * It implements the decorator pattern to wrap base adapters with feature extensions.\n *\n * **RESPONSIBILITIES:**\n * 1. Config Validation - Ensures valid configuration before proceeding\n * 2. Base Adapter Creation - Creates core database adapters (Drizzle/Supabase/SQL)\n * 3. Adapter Chain Building - Wraps adapters with extensions in correct order\n * 4. Service Assembly - Creates final DatabaseService with all components\n * 5. Initialization - Establishes database connections and readiness\n *\n * **ADAPTER CHAIN ORDER:**\n * Base → Encryption → SoftDelete → Caching → Audit → ReadReplica\n * (innermost to outermost - each wraps the previous)\n */\n\n// Core service and interfaces - Main building blocks\nimport { DatabaseService } from \"@service/DatabaseService\"; // Main service implementation\n\n// Factory and adapters - Core creation logic\nimport { AdapterFactory } from \"./AdapterFactory\"; // Creates base adapters\n\n// Extension adapters - Feature layers (imported in chain order)\nimport { SoftDeleteAdapter } from \"../extensions/SoftDeleteExtension\"; // Logical deletion (layer 2)\nimport { AuditAdapter } from \"../extensions/AuditExtension\"; // Operation logging (layer 4)\nimport { EncryptionAdapter } from \"../extensions/EncryptionExtension\"; // Data encryption (layer 1)\nimport { CachingAdapter } from \"../extensions/CachingAdapter\"; // Query caching (layer 3)\nimport { ReadReplicaAdapter } from \"../extensions/ReadReplicaAdapter\"; // Read/write splitting (layer 5)\n\n// External dependencies - Error handling and constants\nimport { DatabaseError } from \"@plyaz/errors\"; // Error classes\nimport { DATABASE_ERROR_CODES } from \"@plyaz/types/errors\";\nimport { ADAPTER_TYPES, ADAPTERS } from \"@plyaz/types/db\";\nimport type {\n DatabaseServiceInterface,\n SqlConfig,\n SupabaseConfig,\n DatabaseAdapterType,\n DatabaseConfig,\n DatabaseServiceConfig,\n DrizzleConfig,\n} from \"@plyaz/types/db\";\n\n/**\n * ADAPTER CHAIN BUILDER - Decorator Pattern Implementation\n *\n * **RESPONSIBILITY:** Wraps base adapter with extension layers in correct order\n * **PATTERN:** Decorator - each adapter wraps the previous, adding functionality\n * **ORDER:** Base → Encryption → SoftDelete → Caching → Audit → ReadReplica\n *\n * **WHY THIS ORDER:**\n * 1. Encryption (innermost) - Encrypts data before storage, decrypts after retrieval\n * 2. SoftDelete - Handles logical deletion, works on encrypted data\n * 3. Caching - Caches processed data (after encryption/soft-delete logic)\n * 4. Audit - Logs final operations (after all data processing)\n * 5. ReadReplica (outermost) - Routes requests to appropriate database\n *\n * @param baseAdapter - The core database adapter (Drizzle/Supabase/SQL)\n * @param config - Configuration specifying which extensions to enable\n * @returns Fully wrapped adapter with all enabled extensions\n *\n * @example\n * ```typescript\n * // Creates: AuditAdapter(CachingAdapter(EncryptionAdapter(DrizzleAdapter)))\n * const wrappedAdapter = buildAdapterChain(baseAdapter, {\n * encryption: { enabled: true, key: 'secret', fields: { users: ['ssn'] } },\n * softDelete: { enabled: true, field: 'deletedAt' },\n * audit: { enabled: true, retentionDays: 90 }\n * });\n * ```\n */\n// eslint-disable-next-line complexity\nfunction buildAdapterChain(\n baseAdapter: DatabaseAdapterType,\n config: DatabaseServiceConfig,\n): DatabaseAdapterType {\n let adapter: DatabaseAdapterType = baseAdapter;\n\n // Layer 1: Encryption (innermost after base)\n // RESPONSIBILITY: Encrypts sensitive fields before storage, decrypts on retrieval\n // WHEN: Always applied first to ensure data is encrypted at rest\n if (config.encryption?.enabled) {\n adapter = new EncryptionAdapter(adapter, config.encryption);\n }\n\n // Layer 2: Soft Delete\n // RESPONSIBILITY: Converts DELETE operations to UPDATE (sets deletedAt), filters soft-deleted records\n // WHEN: Applied after encryption so deletion logic works on encrypted data\n if (config.softDelete?.enabled) {\n adapter = new SoftDeleteAdapter(adapter, config.softDelete);\n }\n\n // Layer 3: Caching\n // RESPONSIBILITY: Stores query results in memory/Redis, invalidates on writes\n // WHEN: Applied after data processing to cache final processed results\n if (config.cache?.enabled) {\n adapter = new CachingAdapter(adapter, config.cache);\n }\n\n // Layer 4: Audit\n // RESPONSIBILITY: Logs all database operations for compliance and tracking\n // WHEN: Applied late in chain to capture final operation details\n if (config.audit?.enabled) {\n adapter = new AuditAdapter(adapter, {\n ...config.audit,\n // Pass encrypted fields config so audit can log which fields are encrypted at rest\n encryptedFields: config.encryption?.enabled\n ? config.encryption.fields\n : undefined,\n });\n }\n\n // Layer 5: Read Replica (outermost wrapper)\n // RESPONSIBILITY: Routes reads to replicas, writes to primary database\n // WHEN: Applied last to handle request routing before any processing\n if (config.readReplica?.enabled) {\n adapter = new ReadReplicaAdapter(adapter, {\n enabled: true,\n replicas: [], // TODO: Create replica adapters from config\n strategy: config.readReplica.strategy,\n fallbackToPrimary: config.readReplica.fallbackToPrimary,\n });\n }\n\n return adapter;\n}\n\n/**\n * CONFIG TRANSFORMER - Converts External to Internal Format\n *\n * **RESPONSIBILITY:** Transforms user-friendly config into internal adapter factory format\n * **WHY NEEDED:** External config is user-friendly, internal config is adapter-specific\n *\n * **TRANSFORMATIONS:**\n * - Maps adapter names to internal constants\n * - Extracts connection details from nested config\n * - Normalizes different config formats (connectionString vs url)\n * - Sets up adapter-specific options (pool, SSL, etc.)\n *\n * @param config - User-provided database service configuration\n * @returns Normalized configuration for AdapterFactory.create()\n */\nfunction createAdapterConfig(config: DatabaseServiceConfig): DatabaseConfig {\n // Drizzle Adapter Config - PostgreSQL with Drizzle ORM\n if (config.adapter === ADAPTER_TYPES.DRIZZLE) {\n const drizzleConfig = config.config as DrizzleConfig;\n return {\n adapter: ADAPTERS.DRIZZLE,\n // orm: ADAPTERS.SUPABASE,\n connectionString: drizzleConfig.connectionString ?? drizzleConfig.url, // Support both formats\n pool: drizzleConfig.poolSize\n ? { max: drizzleConfig.poolSize }\n : undefined, // Optional connection pooling\n tableIdColumns: drizzleConfig.tableIdColumns, // Custom ID column mappings\n };\n }\n\n // Supabase Adapter Config - Supabase API integration\n if (config.adapter === ADAPTER_TYPES.SUPABASE) {\n const supabaseConfig = config.config as SupabaseConfig;\n return {\n adapter: ADAPTERS.SUPABASE,\n // orm: ADAPTERS.SUPABASE, // Optional ORM choice\n supabaseUrl: supabaseConfig.supabaseUrl, // Supabase project URL\n supabaseAnonKey: supabaseConfig.supabaseAnonKey, // Public API key\n supabaseServiceKey: supabaseConfig.supabaseServiceKey, // Service role key (admin)\n schema: supabaseConfig.schema, // Database schema\n tableIdColumns: supabaseConfig.tableIdColumns, // Custom ID column mappings\n };\n }\n\n // Mock Adapter Config - In-memory testing database\n if (config.adapter === ADAPTER_TYPES.MOCK) {\n return {\n adapter: ADAPTERS.MOCK,\n ...config.config, // Pass through all mock config options\n };\n }\n\n // šŸ”§ Raw SQL Adapter Config - Direct SQL database connection\n const sqlConfig = config.config as SqlConfig;\n return {\n adapter: ADAPTERS.SQL,\n connectionString: sqlConfig.connectionString ?? sqlConfig.url, // Support both formats\n schema: sqlConfig.schema, // Default schema for all tables\n tableIdColumns: sqlConfig.tableIdColumns, // Custom ID column mappings\n };\n}\n\n/**\n * CONFIG VALIDATOR - Ensures Configuration Integrity\n *\n * **RESPONSIBILITY:** Validates user configuration before processing\n * **PREVENTS:** Runtime errors from invalid/missing configuration\n * **THROWS:** Descriptive validation errors for debugging\n *\n * **VALIDATION CHECKS:**\n * 1. Config object exists\n * 2. Adapter type is specified\n * 3. Adapter configuration is provided\n *\n * @param config - User-provided configuration to validate\n * @throws {DatabaseError} When configuration is invalid or incomplete\n */\nfunction validateConfig(config: DatabaseServiceConfig): void {\n // Check: Configuration object exists\n if (!config) {\n throw new DatabaseError(\n \"Database configuration is required\",\n DATABASE_ERROR_CODES.CONFIG_REQUIRED,\n {\n context: { source: \"validateConfig\" },\n cause: new Error(\"Database configuration is required\"),\n },\n );\n }\n\n // Check: Adapter type specified (drizzle/supabase/sql)\n if (!config.adapter) {\n throw new DatabaseError(\n \"Database adapter type is required\",\n DATABASE_ERROR_CODES.CONFIG_REQUIRED,\n {\n context: { source: \"validateConfig\" },\n cause: new Error(\"Database adapter type is required\"),\n },\n );\n }\n\n // Check: Adapter-specific configuration provided\n if (!config.config) {\n throw new DatabaseError(\n \"Adapter configuration is required\",\n DATABASE_ERROR_CODES.CONFIG_REQUIRED,\n {\n context: { source: \"validateConfig\" },\n cause: new Error(\"Adapter configuration is required\"),\n },\n );\n }\n}\n\n/**\n * MAIN FACTORY - Application Entry Point\n *\n * Creates a fully configured database service with extension chain.\n * This is the ONLY way applications should create database services.\n *\n * **Application Flow:**\n * 1. App calls createDatabaseService() at startup\n * 2. Factory validates config and creates base adapter (Drizzle/Supabase/etc.)\n * 3. Factory builds 6-layer adapter chain: Base → Encryption → SoftDelete → Cache → Audit → ReadReplica\n * 4. Factory creates DatabaseService with final wrapped adapter\n * 5. App uses returned DatabaseServiceInterface in repositories/services\n *\n * **What this function does:**\n * - Validates configuration using validateConfig()\n * - Creates base adapter via AdapterFactory.create()\n * - Builds decorator chain via buildAdapterChain()\n * - Initializes database connection\n * - Returns configured DatabaseService instance\n *\n * **Called by:** Application startup code (app.ts, main.ts)\n * **Calls:** validateConfig(), AdapterFactory.create(), buildAdapterChain(), DatabaseService constructor\n * **Returns to:** Application layer for injection into repositories\n *\n * @param config Complete database service configuration including adapter and extensions\n * @returns Promise resolving to configured DatabaseServiceInterface instance\n *\n * @throws {BaseError} When configuration is invalid or initialization fails\n *\n * @example\n * ### Basic Setup (app.ts)\n * ```typescript\n * import { createDatabaseService, Tables } from '@plyaz/db';\n *\n * // Called once at application startup\n * const db = await createDatabaseService({\n * adapter: 'drizzle',\n * config: { connectionString: process.env.DATABASE_URL }\n * });\n *\n * // Inject into services\n * const userService = new UserService(db);\n * ```\n *\n * @example\n * ### Production Configuration\n * ```typescript\n * const db = await createDatabaseService({\n * adapter: 'drizzle',\n * config: {\n * connectionString: process.env.DATABASE_URL,\n * poolSize: 20\n * },\n *\n * // Extensions applied in order: Base → Encryption → SoftDelete → Cache → Audit → ReadReplica\n * encryption: {\n * enabled: true,\n * key: process.env.ENCRYPTION_KEY,\n * fields: {\n * [Tables.USERS]: ['ssn', 'taxId'],\n * [Tables.PAYMENTS]: ['cardNumber', 'cvv']\n * }\n * },\n *\n * softDelete: {\n * enabled: true,\n * field: 'deletedAt'\n * },\n *\n * audit: {\n * enabled: true,\n * retentionDays: 90,\n * onAuditAfterWrite: async (event) => {\n * await complianceService.recordAudit(event);\n * }\n * },\n *\n * cache: {\n * enabled: true,\n * ttl: 300,\n * invalidation: 'write'\n * },\n *\n * events: {\n * onAfterWrite: async (event) => {\n * await notificationService.send(event);\n * }\n * }\n * });\n * ```\n *\n * @example\n * ### Testing Setup\n * ```typescript\n * // Use mock adapter for tests\n * const db = await createDatabaseService({\n * adapter: 'mock',\n * config: { logging: true }\n * });\n * ```\n */\nexport async function createDatabaseService(\n config: DatabaseServiceConfig,\n): Promise<DatabaseServiceInterface> {\n try {\n // STEP 1: Validate Configuration\n // RESPONSIBILITY: Ensure config is complete and valid before proceeding\n validateConfig(config);\n\n // STEP 2: Create Base Adapter\n // RESPONSIBILITY: Transform config and create core database adapter (Drizzle/Supabase/SQL)\n const adapterConfig = createAdapterConfig(config); // Transform to internal format\n const baseAdapter = AdapterFactory.create(\n adapterConfig.adapter,\n adapterConfig,\n ); // Create adapter\n\n // STEP 3: Build Adapter Chain\n // RESPONSIBILITY: Wrap base adapter with enabled extensions in correct order\n const finalAdapter = buildAdapterChain(baseAdapter, config);\n\n // STEP 4: Create Database Service\n // RESPONSIBILITY: Assemble final service with wrapped adapter and configuration\n const service = new DatabaseService({\n adapter: finalAdapter, // Fully wrapped adapter chain\n globalConfig: config, // Original configuration for reference\n eventHandlers: config.events, // Event handlers for notifications\n });\n\n // STEP 5: Initialize Database Connection\n // RESPONSIBILITY: Establish database connection and verify readiness\n const initResult = await baseAdapter.initialize();\n if (!initResult.success) {\n throw new DatabaseError(\n `Failed to initialize adapter: ${initResult.error?.message ?? \"Unknown error\"}`,\n DATABASE_ERROR_CODES.INIT_FAILED,\n {\n context: { source: \"createDatabaseService\" },\n cause: initResult.error ?? new Error(\"Failed to initialize adapter\"),\n },\n );\n }\n\n return service; // Return fully configured and initialized service\n } catch (error) {\n throw new DatabaseError(\n `Failed to create database service: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.INIT_FAILED,\n {\n context: { source: \"createDatabaseService\" },\n cause: error as Error,\n },\n );\n }\n}\n","/**\n * @plyaz/db CLI - Database management commands\n *\n * Commands:\n * - db:migrate [up|down|status|reset] - Run migrations\n * - db:seed [run|reset|status] - Run seeds\n * - db:clear - Clear all database data\n * - db:drop - Drop all tables\n * - db:health - Check database health\n *\n * @example\n * ```bash\n * # Run migrations\n * npx @plyaz/db migrate up\n *\n * # Rollback last migration\n * npx @plyaz/db migrate down\n *\n * # Run seeds\n * npx @plyaz/db seed run\n *\n * # Clear all data\n * npx @plyaz/db clear --confirm\n * ```\n */\n\n/* eslint-disable n/no-process-exit */\n// CLI tools use process.exit() for proper exit codes - this is expected behavior\n\nimport { Command } from \"commander\";\nimport { MigrationManager } from \"../migrations/MigrationManager\";\nimport { SeedManager } from \"../seeds/SeedManager\";\nimport { createDatabaseService } from \"../factory/createDatabaseService\";\nimport type { DatabaseAdapterType, DatabaseCLIConfig } from \"@plyaz/types/db\";\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport * as readline from \"readline\";\nimport { randomUUID } from \"crypto\";\nimport { pathToFileURL, fileURLToPath } from \"url\";\nimport { execSync } from \"child_process\";\n\n/** JSON indentation spaces for pretty printing */\nconst JSON_INDENT_SPACES = 2;\n\n/** Number of digits for version/order padding (e.g., 001, 002) */\nconst VERSION_PAD_LENGTH = 3;\n\n/** Radix for parsing integers */\nconst DECIMAL_RADIX = 10;\n\n/** Width of separator lines in interactive mode */\nconst SEPARATOR_WIDTH = 50;\n\n/** Valid migration file types */\nconst VALID_MIGRATION_TYPES = [\"sql\", \"ts\"] as const;\ntype MigrationType = (typeof VALID_MIGRATION_TYPES)[number];\n\n/** Valid seed file types */\nconst VALID_SEED_TYPES = [\"ts\", \"sql\", \"csv\"] as const;\ntype SeedType = (typeof VALID_SEED_TYPES)[number];\n\n/** Minimum steps for rollback */\nconst MIN_ROLLBACK_STEPS = 1;\n\n/**\n * Validate migration/seed name\n * Must contain at least one letter and only alphanumeric, underscore, hyphen\n */\nfunction validateName(name: string, type: \"migration\" | \"seed\"): void {\n if (!name || name.trim() === \"\") {\n console.error(`āŒ ${type} name cannot be empty`);\n process.exit(1);\n }\n\n if (!/[a-zA-Z]/.test(name)) {\n console.error(`āŒ ${type} name must contain at least one letter`);\n process.exit(1);\n }\n\n if (!/^[a-zA-Z0-9_-]+$/.test(name)) {\n console.error(\n `āŒ ${type} name can only contain letters, numbers, underscores, and hyphens`,\n );\n process.exit(1);\n }\n}\n\n/**\n * Validate migration type option\n */\nfunction validateMigrationType(type: string): MigrationType {\n if (!VALID_MIGRATION_TYPES.includes(type as MigrationType)) {\n console.warn(\n `⚠ Invalid type \"${type}\". Valid options: ${VALID_MIGRATION_TYPES.join(\", \")}. Using default: sql`,\n );\n return \"sql\";\n }\n return type as MigrationType;\n}\n\n/**\n * Validate seed type option\n */\nfunction validateSeedType(type: string): SeedType {\n if (!VALID_SEED_TYPES.includes(type as SeedType)) {\n console.warn(\n `⚠ Invalid type \"${type}\". Valid options: ${VALID_SEED_TYPES.join(\", \")}. Using default: ts`,\n );\n return \"ts\";\n }\n return type as SeedType;\n}\n\n/**\n * Validate rollback steps parameter\n */\nfunction validateSteps(stepsStr: string): number {\n const steps = Number.parseInt(stepsStr, DECIMAL_RADIX);\n\n if (Number.isNaN(steps)) {\n console.error(`āŒ Steps must be a number, got: \"${stepsStr}\"`);\n process.exit(1);\n }\n\n if (steps < MIN_ROLLBACK_STEPS) {\n console.error(\n `āŒ Steps must be at least ${MIN_ROLLBACK_STEPS}, got: ${steps}`,\n );\n process.exit(1);\n }\n\n return steps;\n}\n\n/**\n * Validate schema name (basic SQL injection prevention)\n */\nfunction validateSchemaName(schema: string): void {\n if (!schema || schema.trim() === \"\") {\n console.error(\"āŒ Schema name cannot be empty\");\n process.exit(1);\n }\n\n if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(schema)) {\n console.error(\n \"āŒ Invalid schema name. Must start with letter or underscore, contain only alphanumeric and underscores\",\n );\n process.exit(1);\n }\n}\n\n/**\n * Get all user schemas from database\n * Uses INFORMATION_SCHEMA (SQL standard) for portability across databases\n * Note: Some databases (MySQL) call schemas \"databases\"\n */\nasync function getUserSchemas(adapter: DatabaseAdapterType): Promise<string[]> {\n // Use INFORMATION_SCHEMA.SCHEMATA (SQL standard - works on PostgreSQL, MySQL, SQL Server)\n const result = await adapter.query?.(`\n SELECT schema_name FROM information_schema.schemata\n WHERE schema_name NOT IN ('pg_catalog', 'information_schema', 'pg_toast', 'mysql', 'sys', 'performance_schema')\n AND schema_name NOT LIKE 'pg_%'\n AND schema_name NOT LIKE 'pg_temp_%'\n AND schema_name NOT LIKE 'pg_toast_temp_%'\n `);\n\n const schemas = Array.isArray(result)\n ? result\n : (result as unknown as { rows: { schema_name: string }[] }).rows || [];\n\n return (schemas as { schema_name: string }[]).map((s) => s.schema_name);\n}\n\n/**\n * Get list of tables from specified schemas\n * Uses INFORMATION_SCHEMA.TABLES (SQL standard) for portability\n */\nasync function getTablesFromSchemas(\n adapter: DatabaseAdapterType,\n schemas: string[],\n): Promise<{ schema: string; table: string }[]> {\n const tables: { schema: string; table: string }[] = [];\n\n for (const schema of schemas) {\n // Use INFORMATION_SCHEMA.TABLES (SQL standard)\n const result = await adapter.query?.(\n `\n SELECT table_name FROM information_schema.tables\n WHERE table_schema = $1\n AND table_type = 'BASE TABLE'\n AND table_name NOT IN ('schema_migrations', 'seed_history')\n `,\n [schema],\n );\n\n const schemaResult = Array.isArray(result)\n ? result\n : (result as unknown as { rows: { table_name: string }[] }).rows || [];\n\n for (const row of schemaResult as { table_name: string }[]) {\n tables.push({ schema, table: row.table_name });\n }\n }\n\n return tables;\n}\n\n/**\n * Clear specified tables from database\n * Note: TRUNCATE CASCADE is PostgreSQL-specific. Other databases may need different syntax.\n */\nasync function clearTables(\n adapter: DatabaseAdapterType,\n tables: { schema: string; table: string }[],\n): Promise<void> {\n let currentSchema = \"\";\n for (const { schema, table } of tables) {\n if (schema !== currentSchema) {\n console.log(`\\nšŸ“ Schema: ${schema}`);\n currentSchema = schema;\n }\n // Standard SQL uses quoted identifiers; CASCADE is PostgreSQL-specific\n // For other databases, adapter may need to handle this differently\n await adapter.query?.(`TRUNCATE TABLE \"${schema}\".\"${table}\" CASCADE`);\n console.log(` āœ“ Cleared ${schema}.${table}`);\n }\n}\n\n/**\n * Parse a single env line into key-value pair\n */\nfunction parseEnvLine(line: string): { key: string; value: string } | null {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) return null;\n\n const eqIndex = trimmed.indexOf(\"=\");\n if (eqIndex <= 0) return null;\n\n const key = trimmed.slice(0, eqIndex).trim();\n let value = trimmed.slice(eqIndex + 1).trim();\n\n // Remove surrounding quotes\n const isQuoted =\n (value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"));\n if (isQuoted) {\n value = value.slice(1, -1);\n }\n\n return { key, value };\n}\n\n/**\n * Load environment variables from a .env file\n */\nfunction loadEnvFile(envFilePath: string): void {\n if (!fs.existsSync(envFilePath)) return;\n\n const envContent = fs.readFileSync(envFilePath, \"utf-8\");\n for (const line of envContent.split(\"\\n\")) {\n const parsed = parseEnvLine(line);\n if (parsed) {\n process.env[parsed.key] ??= parsed.value;\n }\n }\n}\n\nconst program = new Command();\n\n// Global options (can be set via flags)\nlet globalConfigPath: string | undefined;\nlet globalEnvPath: string | undefined;\n\n/**\n * Convert a file path to a URL that can be used with dynamic import\n * On Windows, absolute paths must be file:// URLs for ESM imports\n */\nfunction toImportPath(filePath: string): string {\n return pathToFileURL(filePath).href;\n}\n\n/** Config file search paths */\nconst CONFIG_PATHS = [\n \"db.config.mjs\",\n \"db.config.js\",\n \".db.config.mjs\",\n \".db.config.js\",\n];\n\n/** TypeScript config paths to check for warnings */\nconst TS_CONFIG_PATHS = [\"db.config.ts\", \".db.config.ts\"];\n\n/**\n * Load config from a specific file path\n */\nasync function loadConfigFromPath(\n filePath: string,\n): Promise<DatabaseCLIConfig> {\n const importPath = toImportPath(filePath);\n const config = await import(importPath);\n console.log(`šŸ“ Using config: ${filePath}`);\n return config.default ?? config;\n}\n\n/**\n * Find and load config from standard locations\n */\nasync function findAndLoadConfig(): Promise<DatabaseCLIConfig | null> {\n for (const configName of CONFIG_PATHS) {\n const configFilePath = path.join(process.cwd(), configName);\n if (fs.existsSync(configFilePath)) {\n return loadConfigFromPath(configFilePath);\n }\n }\n return null;\n}\n\n/**\n * Warn about TypeScript config files that can't be imported directly\n */\nfunction warnAboutTypeScriptConfigs(): void {\n for (const tsName of TS_CONFIG_PATHS) {\n const tsPath = path.join(process.cwd(), tsName);\n if (fs.existsSync(tsPath)) {\n console.warn(\n `āš ļø Found ${path.basename(tsPath)} but cannot import TypeScript files directly.`,\n );\n console.warn(` Options:`);\n console.warn(` 1. Rename to db.config.mjs (recommended)`);\n console.warn(\n ` 2. Run with tsx: npx tsx node_modules/.bin/plyaz-db migrate status`,\n );\n console.warn(` 3. Use environment variables instead\\n`);\n }\n }\n}\n\n/**\n * Get fallback config from environment variables\n */\nfunction getEnvFallbackConfig(): DatabaseCLIConfig {\n if (!process.env.DATABASE_URL) {\n console.warn(\"āš ļø No db.config.mjs found and DATABASE_URL not set\");\n console.warn(\n \" Create db.config.mjs or set DATABASE_URL environment variable\\n\",\n );\n }\n\n const adapterType = (process.env.DB_ADAPTER ??\n \"sql\") as DatabaseCLIConfig[\"adapter\"];\n\n return {\n adapter: adapterType,\n config: {\n connectionString: process.env.DATABASE_URL,\n },\n };\n}\n\n/**\n * Load database configuration from file or environment\n * @param configPath - Optional explicit path to config file\n */\nasync function loadConfig(configPath?: string): Promise<DatabaseCLIConfig> {\n // If explicit config path provided, use it\n const explicitPath = configPath ?? globalConfigPath;\n if (explicitPath) {\n const resolvedPath = path.resolve(process.cwd(), explicitPath);\n if (fs.existsSync(resolvedPath)) {\n return loadConfigFromPath(resolvedPath);\n }\n console.error(`āŒ Config file not found: ${resolvedPath}`);\n process.exit(1);\n }\n\n // Try standard config locations\n const config = await findAndLoadConfig();\n if (config) return config;\n\n // Warn about TypeScript configs and fall back to env\n warnAboutTypeScriptConfigs();\n return getEnvFallbackConfig();\n}\n\n/** Pool settings optimized for long-running migrations/seeds */\nconst MIGRATION_POOL_SETTINGS = {\n max: 3, // Fewer connections, more stable\n idleTimeoutMillis: 0, // Never timeout idle connections during migrations\n connectionTimeoutMillis: 30000, // 30s to establish connection\n keepAlive: true,\n keepAliveInitialDelayMillis: 5000, // Start keepalive after 5s\n allowExitOnIdle: false, // Don't exit while migrations running\n};\n\n/**\n * Initialize database service\n * @param configPath - Optional explicit path to config file\n * @param forMigration - Use migration-optimized pool settings\n */\nasync function initDatabase(\n configPath?: string,\n forMigration = false,\n): Promise<{\n db: Awaited<ReturnType<typeof createDatabaseService>>;\n adapter: DatabaseAdapterType;\n config: DatabaseCLIConfig;\n}> {\n const config = await loadConfig(configPath);\n\n // Override pool settings for migrations/seeds\n if (forMigration && config.config) {\n config.pool = {\n ...MIGRATION_POOL_SETTINGS,\n ...config.pool, // User config can still override\n };\n }\n\n const db = await createDatabaseService(config);\n\n // Get the base adapter (unwrap extensions if any)\n // CLI needs access to underlying adapter for raw SQL operations\n let adapter = db.adapter;\n while (adapter.baseAdapter) {\n adapter = adapter.baseAdapter;\n }\n\n return { db, adapter, config };\n}\n\nprogram\n .name(\"plyaz-db\")\n .description(\"Database management CLI for @plyaz/db\")\n .version(\"1.1.0\")\n .option(\"-c, --config <path>\", \"Path to db.config.mjs file\")\n .option(\n \"-e, --env <path>\",\n \"Path to .env file (default: .env in current directory)\",\n )\n .hook(\"preAction\", (thisCommand) => {\n const opts = thisCommand.opts();\n\n // Load env file first (before config, so config can use env vars)\n if (opts.env) {\n globalEnvPath = path.resolve(process.cwd(), opts.env);\n loadEnvFile(globalEnvPath);\n console.log(`šŸ“ Using env: ${globalEnvPath}`);\n } else {\n // Default: load .env from current directory\n loadEnvFile(path.join(process.cwd(), \".env\"));\n }\n\n if (opts.config) {\n globalConfigPath = opts.config;\n }\n });\n\n// ============================================================================\n// MIGRATION COMMANDS\n// ============================================================================\n\nconst migrateCommand = program\n .command(\"migrate\")\n .description(\"Database migration commands\");\n\nmigrateCommand\n .command(\"up\")\n .description(\"Run pending migrations\")\n .option(\"-t, --target <version>\", \"Target migration version\")\n .action(async (options) => {\n try {\n const { adapter, config } = await initDatabase(undefined, true);\n\n const migrationManager = new MigrationManager({\n adapter,\n migrationsPath: config.migrationsPath ?? \"./migrations\",\n tableName: config.migrationsTable ?? \"schema_migrations\",\n });\n\n console.log(\"šŸ”„ Running migrations...\");\n const result = await migrationManager.up(options.target);\n\n if (result.success) {\n console.log(`āœ… Applied ${result.value} migration(s)`);\n process.exit(0);\n } else {\n console.error(\"āŒ Migration failed:\", result.error?.message);\n process.exit(1);\n }\n } catch (error) {\n console.error(\"āŒ Error:\", (error as Error).message);\n process.exit(1);\n }\n });\n\nmigrateCommand\n .command(\"down\")\n .description(\"Rollback migrations\")\n .option(\"-s, --steps <number>\", \"Number of migrations to rollback\", \"1\")\n .action(async (options) => {\n try {\n // Validate steps parameter\n const steps = validateSteps(options.steps);\n\n const { adapter, config } = await initDatabase(undefined, true);\n\n const migrationManager = new MigrationManager({\n adapter,\n migrationsPath: config.migrationsPath ?? \"./migrations\",\n tableName: config.migrationsTable ?? \"schema_migrations\",\n });\n\n console.log(`šŸ”„ Rolling back ${steps} migration(s)...`);\n const result = await migrationManager.down(steps);\n\n if (result.success) {\n console.log(`āœ… Rolled back ${result.value} migration(s)`);\n process.exit(0);\n } else {\n console.error(\"āŒ Rollback failed:\", result.error?.message);\n process.exit(1);\n }\n } catch (error) {\n console.error(\"āŒ Error:\", (error as Error).message);\n process.exit(1);\n }\n });\n\nmigrateCommand\n .command(\"status\")\n .description(\"Show migration status\")\n .action(async () => {\n try {\n const { adapter, config } = await initDatabase();\n\n const migrationManager = new MigrationManager({\n adapter,\n migrationsPath: config.migrationsPath ?? \"./migrations\",\n tableName: config.migrationsTable ?? \"schema_migrations\",\n });\n\n const result = await migrationManager.status();\n\n if (result.success && result.value) {\n const { applied, pending } = result.value;\n\n console.log(\"\\nšŸ“Š Migration Status\\n\");\n console.log(`āœ… Applied: ${applied.length}`);\n applied.forEach(\n (m: { version: string; name: string; applied_at: string }) => {\n console.log(\n ` - ${m.version} ${m.name} (${new Date(m.applied_at).toLocaleDateString()})`,\n );\n },\n );\n\n console.log(`\\nā³ Pending: ${pending.length}`);\n pending.forEach((m: string) => {\n console.log(` - ${m}`);\n });\n\n process.exit(0);\n } else {\n console.error(\"āŒ Failed to get status:\", result.error?.message);\n process.exit(1);\n }\n } catch (error) {\n console.error(\"āŒ Error:\", (error as Error).message);\n process.exit(1);\n }\n });\n\nmigrateCommand\n .command(\"reset\")\n .description(\"Rollback all migrations\")\n .option(\"--confirm\", \"Confirm reset operation\")\n .action(async (options) => {\n if (!options.confirm) {\n console.error(\"āŒ Please use --confirm flag to confirm reset operation\");\n process.exit(1);\n }\n\n try {\n const { adapter, config } = await initDatabase(undefined, true);\n\n const migrationManager = new MigrationManager({\n adapter,\n migrationsPath: config.migrationsPath ?? \"./migrations\",\n tableName: config.migrationsTable ?? \"schema_migrations\",\n });\n\n console.log(\"šŸ”„ Resetting database (rolling back all migrations)...\");\n const result = await migrationManager.reset();\n\n if (result.success) {\n console.log(\n `āœ… Reset complete. Rolled back ${result.value} migration(s)`,\n );\n process.exit(0);\n } else {\n console.error(\"āŒ Reset failed:\", result.error?.message);\n process.exit(1);\n }\n } catch (error) {\n console.error(\"āŒ Error:\", (error as Error).message);\n process.exit(1);\n }\n });\n\nmigrateCommand\n .command(\"generate-down\")\n .description(\"Generate DOWN sections for SQL migrations\")\n .option(\"--write\", \"Write changes to files (default: dry run)\")\n .action(async (options) => {\n try {\n const config = await loadConfig();\n const migrationsPath = config.migrationsPath ?? \"./migrations\";\n\n // Dynamic import for the generate-down module\n const generateDownModule = await import(\n \"../migrations/generateDownMigration\"\n );\n const { processDirectory } = generateDownModule;\n\n if (!processDirectory) {\n console.error(\"āŒ generateDownMigration module not found\");\n process.exit(1);\n }\n\n console.log(\"šŸ” Analyzing migrations for DOWN section generation\\n\");\n processDirectory(migrationsPath, !options.write);\n\n process.exit(0);\n } catch (error) {\n console.error(\"āŒ Error:\", (error as Error).message);\n process.exit(1);\n }\n });\n\n// ============================================================================\n// SEED COMMANDS\n// ============================================================================\n\nconst seedCommand = program\n .command(\"seed\")\n .description(\"Database seeding commands\");\n\nseedCommand\n .command(\"run\")\n .description(\"Run seeds\")\n .option(\"-n, --name <name>\", \"Specific seed to run\")\n .option(\"--skip-existing\", \"Skip seeds that have already been run\")\n .action(async (options) => {\n try {\n const { adapter, config } = await initDatabase(undefined, true);\n\n const seedManager = new SeedManager({\n adapter,\n seedsPath: config.seedsPath ?? \"./seeds\",\n tableName: config.seedsTable ?? \"seed_history\",\n skipExisting: options.skipExisting ?? false,\n });\n\n console.log(\"🌱 Running seeds...\");\n const result = await seedManager.run(options.name);\n\n if (result.success) {\n console.log(`āœ… Executed ${result.value} seed(s)`);\n process.exit(0);\n } else {\n console.error(\"āŒ Seeding failed:\", result.error?.message);\n process.exit(1);\n }\n } catch (error) {\n console.error(\"āŒ Error:\", (error as Error).message);\n process.exit(1);\n }\n });\n\nseedCommand\n .command(\"status\")\n .description(\"Show seed status\")\n .action(async () => {\n try {\n const { adapter, config } = await initDatabase();\n\n const seedManager = new SeedManager({\n adapter,\n seedsPath: config.seedsPath ?? \"./seeds\",\n tableName: config.seedsTable ?? \"seed_history\",\n });\n\n const result = await seedManager.status();\n\n if (result.success && result.value) {\n const { executed, pending } = result.value;\n\n console.log(\"\\n🌱 Seed Status\\n\");\n console.log(`āœ… Executed: ${executed.length}`);\n executed.forEach((s: { name: string; run_at: string }) => {\n console.log(\n ` - ${s.name} (${new Date(s.run_at).toLocaleDateString()})`,\n );\n });\n\n console.log(`\\nā³ Pending: ${pending.length}`);\n pending.forEach((s: string) => {\n console.log(` - ${s}`);\n });\n\n process.exit(0);\n } else {\n console.error(\"āŒ Failed to get status:\", result.error?.message);\n process.exit(1);\n }\n } catch (error) {\n console.error(\"āŒ Error:\", (error as Error).message);\n process.exit(1);\n }\n });\n\nseedCommand\n .command(\"reset\")\n .description(\"Reset seeds (run cleanup functions)\")\n .option(\"--confirm\", \"Confirm reset operation\")\n .action(async (options) => {\n if (!options.confirm) {\n console.error(\"āŒ Please use --confirm flag to confirm reset operation\");\n process.exit(1);\n }\n\n try {\n const { adapter, config } = await initDatabase(undefined, true);\n\n const seedManager = new SeedManager({\n adapter,\n seedsPath: config.seedsPath ?? \"./seeds\",\n tableName: config.seedsTable ?? \"seed_history\",\n });\n\n console.log(\"šŸ”„ Resetting seeds...\");\n const result = await seedManager.reset();\n\n if (result.success) {\n console.log(`āœ… Reset ${result.value} seed(s)`);\n process.exit(0);\n } else {\n console.error(\"āŒ Reset failed:\", result.error?.message);\n process.exit(1);\n }\n } catch (error) {\n console.error(\"āŒ Error:\", (error as Error).message);\n process.exit(1);\n }\n });\n\n// ============================================================================\n// DATABASE COMMANDS\n// ============================================================================\n\nprogram\n .command(\"clear\")\n .description(\"Clear all data from database (keep schema)\")\n .option(\"--confirm\", \"Confirm clear operation\")\n .option(\n \"-t, --tables <tables>\",\n \"Comma-separated list of tables to clear (format: schema.table or just table for public)\",\n )\n .option(\n \"-s, --schemas <schemas>\",\n \"Comma-separated list of schemas to clear (default: all user schemas)\",\n )\n .action(async (options) => {\n if (!options.confirm) {\n console.error(\"āŒ Please use --confirm flag to confirm clear operation\");\n process.exit(1);\n }\n\n try {\n const { adapter } = await initDatabase();\n\n console.log(\"šŸ”„ Clearing database data...\");\n\n if (typeof adapter.query !== \"function\") {\n console.error(\"āŒ Clear operation not supported by this adapter\");\n process.exit(1);\n }\n\n let tablesToClear: { schema: string; table: string }[];\n\n if (options.tables) {\n // Parse table list (supports schema.table or just table for public)\n tablesToClear = options.tables.split(\",\").map((t: string) => {\n const trimmed = t.trim();\n if (trimmed.includes(\".\")) {\n const [schema, table] = trimmed.split(\".\");\n return { schema, table };\n }\n return { schema: \"public\", table: trimmed };\n });\n } else {\n // Get all tables from specified schemas or all user schemas\n const schemas = options.schemas\n ? options.schemas.split(\",\").map((s: string) => s.trim())\n : await getUserSchemas(adapter);\n tablesToClear = await getTablesFromSchemas(adapter, schemas);\n }\n\n await clearTables(adapter, tablesToClear);\n\n console.log(`\\nāœ… Cleared ${tablesToClear.length} tables`);\n process.exit(0);\n } catch (error) {\n console.error(\"āŒ Error:\", (error as Error).message);\n process.exit(1);\n }\n });\n\nprogram\n .command(\"drop\")\n .description(\"Drop all tables from database (all schemas)\")\n .option(\"--confirm\", \"Confirm drop operation\")\n .option(\n \"-s, --schemas <schemas>\",\n \"Comma-separated list of schemas to drop from (default: all user schemas)\",\n )\n .option(\n \"--all\",\n \"Drop everything: tables, types, functions, views (not just tables)\",\n )\n .option(\"--drop-schemas\", \"Also drop the schemas themselves (except public)\")\n /* eslint-disable max-lines-per-function, complexity, max-depth, @typescript-eslint/naming-convention */\n .action(async (options) => {\n if (!options.confirm) {\n console.error(\"āŒ Please use --confirm flag to confirm drop operation\");\n process.exit(1);\n }\n\n try {\n const { adapter } = await initDatabase();\n\n console.log(\"šŸ”„ Dropping all tables...\");\n\n if (typeof adapter.query !== \"function\") {\n console.error(\"āŒ Drop operation not supported by this adapter\");\n process.exit(1);\n }\n\n // Get schemas to process (uses INFORMATION_SCHEMA for portability)\n const schemas = options.schemas\n ? options.schemas.split(\",\").map((s: string) => s.trim())\n : await getUserSchemas(adapter);\n\n let totalDropped = 0;\n\n // Drop tables from each schema (uses INFORMATION_SCHEMA for portability)\n for (const schema of schemas) {\n const result = await adapter.query(\n `\n SELECT table_name FROM information_schema.tables\n WHERE table_schema = $1\n AND table_type = 'BASE TABLE'\n `,\n [schema],\n );\n\n const tables = Array.isArray(result)\n ? result\n : (result as unknown as { rows: { table_name: string }[] }).rows ||\n [];\n\n if (tables.length === 0) continue;\n\n console.log(`\\nšŸ“ Schema: ${schema}`);\n for (const { table_name } of tables as { table_name: string }[]) {\n // DROP TABLE CASCADE is PostgreSQL-specific; other databases may need different syntax\n await adapter.query(\n `DROP TABLE IF EXISTS \"${schema}\".\"${table_name}\" CASCADE`,\n );\n console.log(` āœ“ Dropped ${schema}.${table_name}`);\n totalDropped++;\n }\n }\n\n // Drop types, functions, views, triggers, sequences if --all flag is set\n if (options.all) {\n // Drop views (uses INFORMATION_SCHEMA - portable)\n console.log(\"\\nšŸ—‘ļø Dropping views...\");\n for (const schema of schemas) {\n const viewResult = await adapter.query(\n `\n SELECT table_name FROM information_schema.views\n WHERE table_schema = $1\n `,\n [schema],\n );\n const views = Array.isArray(viewResult)\n ? viewResult\n : (viewResult as unknown as { rows: { table_name: string }[] })\n .rows || [];\n for (const { table_name } of views as { table_name: string }[]) {\n try {\n await adapter.query(\n `DROP VIEW IF EXISTS \"${schema}\".\"${table_name}\" CASCADE`,\n );\n console.log(` āœ“ Dropped view ${schema}.${table_name}`);\n } catch {\n // View might already be dropped via CASCADE\n }\n }\n }\n\n // Drop triggers (PostgreSQL-specific, uses information_schema.triggers)\n console.log(\"\\nšŸ—‘ļø Dropping triggers...\");\n for (const schema of schemas) {\n try {\n const triggerResult = await adapter.query(\n `\n SELECT DISTINCT trigger_name, event_object_table\n FROM information_schema.triggers\n WHERE trigger_schema = $1\n `,\n [schema],\n );\n const triggers = Array.isArray(triggerResult)\n ? triggerResult\n : (\n triggerResult as unknown as {\n rows: {\n trigger_name: string;\n event_object_table: string;\n }[];\n }\n ).rows || [];\n for (const { trigger_name, event_object_table } of triggers as {\n trigger_name: string;\n event_object_table: string;\n }[]) {\n try {\n await adapter.query(\n `DROP TRIGGER IF EXISTS \"${trigger_name}\" ON \"${schema}\".\"${event_object_table}\" CASCADE`,\n );\n console.log(` āœ“ Dropped trigger ${schema}.${trigger_name}`);\n } catch {\n // Trigger might already be dropped with table\n }\n }\n } catch {\n // Triggers might already be dropped with tables\n }\n }\n\n // Drop functions (PostgreSQL-specific, uses pg_proc)\n console.log(\"\\nšŸ—‘ļø Dropping functions...\");\n for (const schema of schemas) {\n try {\n const funcResult = await adapter.query(\n `\n SELECT p.proname, pg_get_function_identity_arguments(p.oid) as args\n FROM pg_proc p\n JOIN pg_namespace n ON p.pronamespace = n.oid\n WHERE n.nspname = $1\n AND p.prokind = 'f'\n `,\n [schema],\n );\n const funcs = Array.isArray(funcResult)\n ? funcResult\n : (\n funcResult as unknown as {\n rows: { proname: string; args: string }[];\n }\n ).rows || [];\n for (const { proname, args } of funcs as {\n proname: string;\n args: string;\n }[]) {\n try {\n await adapter.query(\n `DROP FUNCTION IF EXISTS \"${schema}\".\"${proname}\"(${args}) CASCADE`,\n );\n console.log(` āœ“ Dropped function ${schema}.${proname}`);\n } catch {\n // Function might already be dropped\n }\n }\n } catch {\n // pg_proc not available (non-PostgreSQL database)\n console.log(\n ` ⚠ Function dropping not supported for this database`,\n );\n break;\n }\n }\n\n // Drop procedures (PostgreSQL 11+, uses pg_proc)\n console.log(\"\\nšŸ—‘ļø Dropping procedures...\");\n for (const schema of schemas) {\n try {\n const procResult = await adapter.query(\n `\n SELECT p.proname, pg_get_function_identity_arguments(p.oid) as args\n FROM pg_proc p\n JOIN pg_namespace n ON p.pronamespace = n.oid\n WHERE n.nspname = $1\n AND p.prokind = 'p'\n `,\n [schema],\n );\n const procs = Array.isArray(procResult)\n ? procResult\n : (\n procResult as unknown as {\n rows: { proname: string; args: string }[];\n }\n ).rows || [];\n for (const { proname, args } of procs as {\n proname: string;\n args: string;\n }[]) {\n try {\n await adapter.query(\n `DROP PROCEDURE IF EXISTS \"${schema}\".\"${proname}\"(${args}) CASCADE`,\n );\n console.log(` āœ“ Dropped procedure ${schema}.${proname}`);\n } catch {\n // Procedure might already be dropped\n }\n }\n } catch {\n // Procedures not supported or already dropped\n }\n }\n\n // Drop sequences (uses INFORMATION_SCHEMA - portable)\n console.log(\"\\nšŸ—‘ļø Dropping sequences...\");\n for (const schema of schemas) {\n try {\n const seqResult = await adapter.query(\n `\n SELECT sequence_name FROM information_schema.sequences\n WHERE sequence_schema = $1\n `,\n [schema],\n );\n const sequences = Array.isArray(seqResult)\n ? seqResult\n : (seqResult as unknown as { rows: { sequence_name: string }[] })\n .rows || [];\n for (const { sequence_name } of sequences as {\n sequence_name: string;\n }[]) {\n try {\n await adapter.query(\n `DROP SEQUENCE IF EXISTS \"${schema}\".\"${sequence_name}\" CASCADE`,\n );\n console.log(` āœ“ Dropped sequence ${schema}.${sequence_name}`);\n } catch {\n // Sequence might already be dropped with table\n }\n }\n } catch {\n // Sequences might not be supported\n }\n }\n\n // Drop types/enums (PostgreSQL-specific, uses pg_type)\n console.log(\"\\nšŸ—‘ļø Dropping types...\");\n for (const schema of schemas) {\n try {\n const typeResult = await adapter.query(\n `\n SELECT t.typname\n FROM pg_type t\n JOIN pg_namespace n ON t.typnamespace = n.oid\n WHERE n.nspname = $1\n AND t.typtype = 'e'\n `,\n [schema],\n );\n const types = Array.isArray(typeResult)\n ? typeResult\n : (typeResult as unknown as { rows: { typname: string }[] })\n .rows || [];\n for (const { typname } of types as { typname: string }[]) {\n try {\n await adapter.query(\n `DROP TYPE IF EXISTS \"${schema}\".\"${typname}\" CASCADE`,\n );\n console.log(` āœ“ Dropped type ${schema}.${typname}`);\n } catch {\n // Type might already be dropped\n }\n }\n } catch {\n // pg_type not available (non-PostgreSQL database)\n console.log(` ⚠ Type dropping not supported for this database`);\n break;\n }\n }\n\n // Drop domains (PostgreSQL-specific)\n console.log(\"\\nšŸ—‘ļø Dropping domains...\");\n for (const schema of schemas) {\n try {\n const domainResult = await adapter.query(\n `\n SELECT domain_name FROM information_schema.domains\n WHERE domain_schema = $1\n `,\n [schema],\n );\n const domains = Array.isArray(domainResult)\n ? domainResult\n : (domainResult as unknown as { rows: { domain_name: string }[] })\n .rows || [];\n for (const { domain_name } of domains as {\n domain_name: string;\n }[]) {\n try {\n await adapter.query(\n `DROP DOMAIN IF EXISTS \"${schema}\".\"${domain_name}\" CASCADE`,\n );\n console.log(` āœ“ Dropped domain ${schema}.${domain_name}`);\n } catch {\n // Domain might already be dropped\n }\n }\n } catch {\n // Domains might not be supported\n }\n }\n }\n\n // Optionally drop schemas (except public)\n if (options.dropSchemas) {\n console.log(\"\\nšŸ—‘ļø Dropping schemas...\");\n for (const schema of schemas) {\n if (schema === \"public\") continue;\n try {\n await adapter.query(`DROP SCHEMA IF EXISTS \"${schema}\" CASCADE`);\n console.log(` āœ“ Dropped schema ${schema}`);\n } catch {\n console.log(` ⚠ Could not drop schema ${schema}`);\n }\n }\n }\n\n console.log(\n `\\nāœ… Dropped ${totalDropped} tables${options.all ? \" + types, functions, views\" : \"\"}`,\n );\n process.exit(0);\n } catch (error) {\n console.error(\"āŒ Error:\", (error as Error).message);\n process.exit(1);\n }\n });\n/* eslint-enable max-lines-per-function, complexity, max-depth, @typescript-eslint/naming-convention */\n\nprogram\n .command(\"health\")\n .description(\"Check database health\")\n .action(async () => {\n try {\n const { db } = await initDatabase();\n\n const result = await db.healthCheck();\n\n if (result.success && result.value) {\n if (result.value.isHealthy) {\n console.log(\"āœ… Database is healthy\");\n console.log(` Response time: ${result.value.responseTime}ms`);\n console.log(\n \" Details:\",\n JSON.stringify(result.value.details, null, JSON_INDENT_SPACES),\n );\n process.exit(0);\n } else {\n console.error(\"āŒ Database is unhealthy\");\n console.log(\n \" Details:\",\n JSON.stringify(result.value.details, null, JSON_INDENT_SPACES),\n );\n process.exit(1);\n }\n } else {\n console.error(\"āŒ Health check failed\");\n process.exit(1);\n }\n } catch (error) {\n console.error(\"āŒ Error:\", (error as Error).message);\n process.exit(1);\n }\n });\n\n// ============================================================================\n// RESET COMMAND - Full database reset (drop all + optionally migrate)\n// ============================================================================\n\n/**\n * Drop all database objects from specified schemas\n */\n/* eslint-disable max-lines-per-function, complexity, max-depth, @typescript-eslint/naming-convention */\nasync function dropAllObjects(\n adapter: DatabaseAdapterType,\n schemas: string[],\n dropSchemas: boolean,\n): Promise<{ tables: number; objects: number }> {\n let totalTables = 0;\n let totalObjects = 0;\n\n // Drop tables first\n console.log(\"\\nšŸ—‘ļø Dropping tables...\");\n for (const schema of schemas) {\n const result = await adapter.query!(\n `\n SELECT table_name FROM information_schema.tables\n WHERE table_schema = $1\n AND table_type = 'BASE TABLE'\n `,\n [schema],\n );\n\n const tables = Array.isArray(result)\n ? result\n : (result as unknown as { rows: { table_name: string }[] }).rows || [];\n\n if (tables.length === 0) continue;\n\n console.log(`\\nšŸ“ Schema: ${schema}`);\n for (const { table_name } of tables as { table_name: string }[]) {\n await adapter.query!(\n `DROP TABLE IF EXISTS \"${schema}\".\"${table_name}\" CASCADE`,\n );\n console.log(` āœ“ Dropped table ${schema}.${table_name}`);\n totalTables++;\n }\n }\n\n // Drop views\n console.log(\"\\nšŸ—‘ļø Dropping views...\");\n for (const schema of schemas) {\n const viewResult = await adapter.query!(\n `SELECT table_name FROM information_schema.views WHERE table_schema = $1`,\n [schema],\n );\n const views = Array.isArray(viewResult)\n ? viewResult\n : (viewResult as unknown as { rows: { table_name: string }[] }).rows ||\n [];\n for (const { table_name } of views as { table_name: string }[]) {\n try {\n await adapter.query!(\n `DROP VIEW IF EXISTS \"${schema}\".\"${table_name}\" CASCADE`,\n );\n console.log(` āœ“ Dropped view ${schema}.${table_name}`);\n totalObjects++;\n } catch {\n // Already dropped\n }\n }\n }\n\n // Drop triggers\n console.log(\"\\nšŸ—‘ļø Dropping triggers...\");\n for (const schema of schemas) {\n try {\n const triggerResult = await adapter.query!(\n `SELECT DISTINCT trigger_name, event_object_table FROM information_schema.triggers WHERE trigger_schema = $1`,\n [schema],\n );\n const triggers = Array.isArray(triggerResult)\n ? triggerResult\n : (\n triggerResult as unknown as {\n rows: { trigger_name: string; event_object_table: string }[];\n }\n ).rows || [];\n for (const { trigger_name, event_object_table } of triggers as {\n trigger_name: string;\n event_object_table: string;\n }[]) {\n try {\n await adapter.query!(\n `DROP TRIGGER IF EXISTS \"${trigger_name}\" ON \"${schema}\".\"${event_object_table}\" CASCADE`,\n );\n console.log(` āœ“ Dropped trigger ${schema}.${trigger_name}`);\n totalObjects++;\n } catch {\n // Already dropped\n }\n }\n } catch {\n // Triggers already dropped with tables\n }\n }\n\n // Drop functions\n console.log(\"\\nšŸ—‘ļø Dropping functions...\");\n for (const schema of schemas) {\n try {\n const funcResult = await adapter.query!(\n `SELECT p.proname, pg_get_function_identity_arguments(p.oid) as args\n FROM pg_proc p JOIN pg_namespace n ON p.pronamespace = n.oid\n WHERE n.nspname = $1 AND p.prokind = 'f'`,\n [schema],\n );\n const funcs = Array.isArray(funcResult)\n ? funcResult\n : (\n funcResult as unknown as {\n rows: { proname: string; args: string }[];\n }\n ).rows || [];\n for (const { proname, args } of funcs as {\n proname: string;\n args: string;\n }[]) {\n try {\n await adapter.query!(\n `DROP FUNCTION IF EXISTS \"${schema}\".\"${proname}\"(${args}) CASCADE`,\n );\n console.log(` āœ“ Dropped function ${schema}.${proname}`);\n totalObjects++;\n } catch {\n // Already dropped\n }\n }\n } catch {\n // pg_proc not available\n }\n }\n\n // Drop procedures\n console.log(\"\\nšŸ—‘ļø Dropping procedures...\");\n for (const schema of schemas) {\n try {\n const procResult = await adapter.query!(\n `SELECT p.proname, pg_get_function_identity_arguments(p.oid) as args\n FROM pg_proc p JOIN pg_namespace n ON p.pronamespace = n.oid\n WHERE n.nspname = $1 AND p.prokind = 'p'`,\n [schema],\n );\n const procs = Array.isArray(procResult)\n ? procResult\n : (\n procResult as unknown as {\n rows: { proname: string; args: string }[];\n }\n ).rows || [];\n for (const { proname, args } of procs as {\n proname: string;\n args: string;\n }[]) {\n try {\n await adapter.query!(\n `DROP PROCEDURE IF EXISTS \"${schema}\".\"${proname}\"(${args}) CASCADE`,\n );\n console.log(` āœ“ Dropped procedure ${schema}.${proname}`);\n totalObjects++;\n } catch {\n // Already dropped\n }\n }\n } catch {\n // Procedures not supported\n }\n }\n\n // Drop sequences\n console.log(\"\\nšŸ—‘ļø Dropping sequences...\");\n for (const schema of schemas) {\n try {\n const seqResult = await adapter.query!(\n `SELECT sequence_name FROM information_schema.sequences WHERE sequence_schema = $1`,\n [schema],\n );\n const sequences = Array.isArray(seqResult)\n ? seqResult\n : (seqResult as unknown as { rows: { sequence_name: string }[] })\n .rows || [];\n for (const { sequence_name } of sequences as {\n sequence_name: string;\n }[]) {\n try {\n await adapter.query!(\n `DROP SEQUENCE IF EXISTS \"${schema}\".\"${sequence_name}\" CASCADE`,\n );\n console.log(` āœ“ Dropped sequence ${schema}.${sequence_name}`);\n totalObjects++;\n } catch {\n // Already dropped\n }\n }\n } catch {\n // Sequences not supported\n }\n }\n\n // Drop types/enums\n console.log(\"\\nšŸ—‘ļø Dropping types...\");\n for (const schema of schemas) {\n try {\n const typeResult = await adapter.query!(\n `SELECT t.typname FROM pg_type t\n JOIN pg_namespace n ON t.typnamespace = n.oid\n WHERE n.nspname = $1 AND t.typtype = 'e'`,\n [schema],\n );\n const types = Array.isArray(typeResult)\n ? typeResult\n : (typeResult as unknown as { rows: { typname: string }[] }).rows || [];\n for (const { typname } of types as { typname: string }[]) {\n try {\n await adapter.query!(\n `DROP TYPE IF EXISTS \"${schema}\".\"${typname}\" CASCADE`,\n );\n console.log(` āœ“ Dropped type ${schema}.${typname}`);\n totalObjects++;\n } catch {\n // Already dropped\n }\n }\n } catch {\n // pg_type not available\n }\n }\n\n // Drop domains\n console.log(\"\\nšŸ—‘ļø Dropping domains...\");\n for (const schema of schemas) {\n try {\n const domainResult = await adapter.query!(\n `SELECT domain_name FROM information_schema.domains WHERE domain_schema = $1`,\n [schema],\n );\n const domains = Array.isArray(domainResult)\n ? domainResult\n : (domainResult as unknown as { rows: { domain_name: string }[] })\n .rows || [];\n for (const { domain_name } of domains as { domain_name: string }[]) {\n try {\n await adapter.query!(\n `DROP DOMAIN IF EXISTS \"${schema}\".\"${domain_name}\" CASCADE`,\n );\n console.log(` āœ“ Dropped domain ${schema}.${domain_name}`);\n totalObjects++;\n } catch {\n // Already dropped\n }\n }\n } catch {\n // Domains not supported\n }\n }\n\n // Drop schemas if requested\n if (dropSchemas) {\n console.log(\"\\nšŸ—‘ļø Dropping schemas...\");\n for (const schema of schemas) {\n if (schema === \"public\") continue;\n try {\n await adapter.query!(`DROP SCHEMA IF EXISTS \"${schema}\" CASCADE`);\n console.log(` āœ“ Dropped schema ${schema}`);\n } catch {\n console.log(` ⚠ Could not drop schema ${schema}`);\n }\n }\n }\n\n return { tables: totalTables, objects: totalObjects };\n}\n/* eslint-enable max-lines-per-function, complexity, max-depth, @typescript-eslint/naming-convention */\n\nprogram\n .command(\"reset\")\n .description(\n \"Full database reset: drop all objects from all schemas, optionally run migrations\",\n )\n .option(\"--confirm\", \"Confirm reset operation\")\n .option(\n \"-s, --schemas <schemas>\",\n \"Comma-separated list of schemas (default: all user schemas)\",\n )\n .option(\"--drop-schemas\", \"Also drop schemas themselves (except public)\")\n .option(\"--migrate\", \"Run migrations after reset\")\n /* eslint-disable complexity */\n .action(async (options) => {\n if (!options.confirm) {\n console.error(\"āŒ Please use --confirm flag to confirm reset operation\");\n console.error(\n \" This will DROP ALL database objects (tables, types, functions, etc.)\",\n );\n process.exit(1);\n }\n\n try {\n const { adapter, config } = await initDatabase();\n\n if (typeof adapter.query !== \"function\") {\n console.error(\"āŒ Reset operation not supported by this adapter\");\n process.exit(1);\n }\n\n console.log(\"šŸ”„ Resetting database (dropping all objects)...\");\n\n // Get schemas\n const schemas = options.schemas\n ? options.schemas.split(\",\").map((s: string) => s.trim())\n : await getUserSchemas(adapter);\n\n // Drop all objects\n const { tables, objects } = await dropAllObjects(\n adapter,\n schemas,\n options.dropSchemas ?? false,\n );\n\n console.log(\n `\\nāœ… Reset complete: dropped ${tables} tables, ${objects} other objects`,\n );\n\n // Optionally run migrations\n if (options.migrate) {\n console.log(\"\\nšŸ”„ Running migrations...\");\n\n const migrationManager = new MigrationManager({\n adapter,\n migrationsPath: config.migrationsPath ?? \"./migrations\",\n tableName: config.migrationsTable ?? \"schema_migrations\",\n });\n\n const result = await migrationManager.up();\n\n if (result.success) {\n console.log(`āœ… Applied ${result.value} migration(s)`);\n } else {\n console.error(\"āŒ Migration failed:\", result.error?.message);\n process.exit(1);\n }\n }\n\n process.exit(0);\n } catch (error) {\n console.error(\"āŒ Error:\", (error as Error).message);\n process.exit(1);\n }\n });\n\n// ============================================================================\n// INTERACTIVE PROMPTS - For interactive mode\n// ============================================================================\n\n/**\n * Create readline interface for user prompts\n */\nfunction createReadlineInterface(): readline.Interface {\n return readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n}\n\n/**\n * Prompt user for text input\n */\nasync function promptInput(\n message: string,\n defaultValue?: string,\n): Promise<string> {\n const rl = createReadlineInterface();\n const prompt = defaultValue\n ? `${message} (${defaultValue}): `\n : `${message}: `;\n\n return new Promise((resolve) => {\n rl.question(prompt, (answer) => {\n rl.close();\n const trimmed = answer.trim();\n resolve(trimmed !== \"\" ? trimmed : (defaultValue ?? \"\"));\n });\n });\n}\n\n/**\n * Prompt user to select from options\n */\nasync function promptSelect(\n message: string,\n options: string[],\n): Promise<string> {\n const rl = createReadlineInterface();\n\n console.log(message);\n options.forEach((opt, i) => console.log(` ${i + 1}) ${opt}`));\n\n return new Promise((resolve) => {\n rl.question(\"Select (number): \", (answer) => {\n rl.close();\n const index = Number.parseInt(answer, DECIMAL_RADIX) - 1;\n resolve(options[index] ?? options[0]);\n });\n });\n}\n\n/**\n * Prompt user for yes/no confirmation\n */\nasync function promptConfirm(message: string): Promise<boolean> {\n const rl = createReadlineInterface();\n\n return new Promise((resolve) => {\n rl.question(`${message} (y/N): `, (answer) => {\n rl.close();\n resolve(answer.toLowerCase() === \"y\" || answer.toLowerCase() === \"yes\");\n });\n });\n}\n\n/**\n * Run interactive migration creation\n */\nasync function runInteractiveMigration(\n config: DatabaseCLIConfig,\n): Promise<void> {\n console.log();\n console.log(\"šŸ“¦ Create Migration - Interactive Mode\");\n console.log(\"─\".repeat(SEPARATOR_WIDTH));\n console.log();\n\n // Get migration name\n const name = await promptInput(\"Migration name (e.g., add_users_table)\");\n if (!name) {\n console.error(\"āŒ Migration name is required\");\n process.exit(1);\n }\n\n // Validate name\n validateName(name, \"migration\");\n\n // Get table name\n const snakeName = toSnakeCase(name);\n const tableName = await promptInput(\"Table name\", snakeName);\n\n // Get schema\n const schema = await promptInput(\"Database schema\", \"public\");\n validateSchemaName(schema);\n\n // Get type\n const typeChoice = await promptSelect(\"File type:\", [\n \"SQL (.sql)\",\n \"TypeScript (.ts)\",\n ]);\n const type: MigrationType = typeChoice.includes(\"TypeScript\") ? \"ts\" : \"sql\";\n\n // Get author\n const gitUser = getGitUsername();\n const includeAuthor = gitUser\n ? await promptConfirm(`Include author (${gitUser})?`)\n : false;\n const author = includeAuthor ? gitUser : \"\";\n\n // Show summary\n console.log();\n console.log(\"─\".repeat(SEPARATOR_WIDTH));\n console.log(`Migration: ${name}`);\n console.log(`Table: ${schema}.${tableName}`);\n console.log(`Type: ${type.toUpperCase()}`);\n if (author) console.log(`Author: ${author}`);\n console.log(\"─\".repeat(SEPARATOR_WIDTH));\n\n const confirm = await promptConfirm(\"Create migration?\");\n if (!confirm) {\n console.log(\"Cancelled.\");\n process.exit(0);\n }\n\n // Create the migration\n const migrationsPath = config.migrationsPath ?? \"./migrations\";\n if (!fs.existsSync(migrationsPath)) {\n fs.mkdirSync(migrationsPath, { recursive: true });\n console.log(`šŸ“ Created directory: ${migrationsPath}`);\n }\n\n const version = getNextMigrationVersion(migrationsPath);\n const filename = `${version}_${snakeName}.${type}`;\n const filepath = path.join(migrationsPath, filename);\n\n // Check if file exists\n if (fs.existsSync(filepath)) {\n const overwrite = await promptConfirm(\n `File exists. Overwrite ${filename}?`,\n );\n if (!overwrite) {\n console.log(\"Cancelled.\");\n process.exit(0);\n }\n }\n\n const content = getMigrationTemplate({\n name,\n version,\n tableName,\n schema,\n author,\n type,\n });\n\n fs.writeFileSync(filepath, content, \"utf-8\");\n\n console.log();\n console.log(`āœ… Created migration: ${filename}`);\n console.log(` Path: ${filepath}`);\n console.log(` Type: ${type.toUpperCase()}`);\n console.log(` Table: ${schema}.${tableName}`);\n if (author) {\n console.log(` Author: ${author}`);\n }\n console.log(\"\");\n console.log(\"šŸ“ Next steps:\");\n console.log(` 1. Edit the migration file to add your schema changes`);\n console.log(` 2. Run 'plyaz-db migrate up' to apply the migration`);\n console.log(\n ` 3. Test rollback with 'plyaz-db migrate down' before deploying`,\n );\n}\n\n/**\n * Run interactive seed creation\n */\nasync function runInteractiveSeed(config: DatabaseCLIConfig): Promise<void> {\n console.log();\n console.log(\"🌱 Create Seed - Interactive Mode\");\n console.log(\"─\".repeat(SEPARATOR_WIDTH));\n console.log();\n\n // Get seed name\n const name = await promptInput(\"Seed name (e.g., admin_users)\");\n if (!name) {\n console.error(\"āŒ Seed name is required\");\n process.exit(1);\n }\n\n // Validate name\n validateName(name, \"seed\");\n\n // Get table name\n const snakeName = toSnakeCase(name);\n const tableName = await promptInput(\"Table name\", snakeName);\n\n // Get schema\n const schema = await promptInput(\"Database schema\", \"public\");\n validateSchemaName(schema);\n\n // Get type\n const typeChoice = await promptSelect(\"File type:\", [\n \"TypeScript (.ts)\",\n \"SQL (.sql)\",\n \"CSV (.csv)\",\n ]);\n const typeMap: Record<string, SeedType> = {\n \"TypeScript (.ts)\": \"ts\",\n \"SQL (.sql)\": \"sql\",\n \"CSV (.csv)\": \"csv\",\n };\n const type: SeedType = typeMap[typeChoice] ?? \"ts\";\n\n // Get author (not for CSV)\n let author = \"\";\n if (type !== \"csv\") {\n const gitUser = getGitUsername();\n const includeAuthor = gitUser\n ? await promptConfirm(`Include author (${gitUser})?`)\n : false;\n author = includeAuthor ? gitUser : \"\";\n }\n\n // Show summary\n console.log();\n console.log(\"─\".repeat(SEPARATOR_WIDTH));\n console.log(`Seed: ${name}`);\n console.log(`Table: ${schema}.${tableName}`);\n console.log(`Type: ${type.toUpperCase()}`);\n if (author) console.log(`Author: ${author}`);\n console.log(\"─\".repeat(SEPARATOR_WIDTH));\n\n const confirm = await promptConfirm(\"Create seed?\");\n if (!confirm) {\n console.log(\"Cancelled.\");\n process.exit(0);\n }\n\n // Create the seed\n const seedsPath = config.seedsPath ?? \"./seeds\";\n if (!fs.existsSync(seedsPath)) {\n fs.mkdirSync(seedsPath, { recursive: true });\n console.log(`šŸ“ Created directory: ${seedsPath}`);\n }\n\n const order = getNextSeedOrder(seedsPath);\n const filename = `${order}_${snakeName}.${type}`;\n const filepath = path.join(seedsPath, filename);\n\n // Check if file exists\n if (fs.existsSync(filepath)) {\n const overwrite = await promptConfirm(\n `File exists. Overwrite ${filename}?`,\n );\n if (!overwrite) {\n console.log(\"Cancelled.\");\n process.exit(0);\n }\n }\n\n let content: string;\n if (type === \"csv\") {\n content = getCsvSeedTemplate({ name, tableName, schema });\n } else {\n content = getSeedTemplate({\n name,\n order,\n tableName,\n schema,\n author,\n type,\n });\n }\n\n fs.writeFileSync(filepath, content, \"utf-8\");\n\n console.log();\n console.log(`āœ… Created seed: ${filename}`);\n console.log(` Path: ${filepath}`);\n console.log(` Type: ${type.toUpperCase()}`);\n console.log(` Table: ${schema}.${tableName}`);\n if (author && type !== \"csv\") {\n console.log(` Author: ${author}`);\n }\n console.log(\"\");\n console.log(\"šŸ“ Next steps:\");\n console.log(` 1. Edit the seed file to add your data`);\n console.log(` 2. Run 'plyaz-db seed run' to execute seeds`);\n console.log(` 3. Use 'plyaz-db seed status' to check seed status`);\n}\n\n// ============================================================================\n// CREATE COMMANDS - Generate new migration or seed files\n// ============================================================================\n\n/**\n * Generate migration version number based on existing files\n */\nfunction getNextMigrationVersion(migrationsPath: string): string {\n if (!fs.existsSync(migrationsPath)) {\n return \"001\";\n }\n\n const files = fs.readdirSync(migrationsPath);\n const versions = files\n .map((f) => {\n const match = f.match(/^(\\d+)_/);\n return match ? Number.parseInt(match[1], DECIMAL_RADIX) : 0;\n })\n .filter((v) => v > 0);\n\n const maxVersion = versions.length > 0 ? Math.max(...versions) : 0;\n return String(maxVersion + 1).padStart(VERSION_PAD_LENGTH, \"0\");\n}\n\n/**\n * Generate seed order number based on existing files\n */\nfunction getNextSeedOrder(seedsPath: string): string {\n if (!fs.existsSync(seedsPath)) {\n return \"001\";\n }\n\n const files = fs.readdirSync(seedsPath);\n const orders = files\n .map((f) => {\n const match = f.match(/^(\\d+)_/);\n return match ? Number.parseInt(match[1], DECIMAL_RADIX) : 0;\n })\n .filter((v) => v > 0);\n\n const maxOrder = orders.length > 0 ? Math.max(...orders) : 0;\n return String(maxOrder + 1).padStart(VERSION_PAD_LENGTH, \"0\");\n}\n\n/**\n * Convert name to snake_case filename\n */\nfunction toSnakeCase(name: string): string {\n return name\n .replace(/([A-Z])/g, \"_$1\")\n .toLowerCase()\n .replace(/^_/, \"\")\n .replace(/[^a-z0-9_]/g, \"_\")\n .replace(/_+/g, \"_\");\n}\n\n/**\n * Convert name to PascalCase for descriptions\n */\nfunction toPascalCase(name: string): string {\n return name\n .split(/[_\\s-]+/)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(\" \");\n}\n\n/**\n * Template variables interface\n */\ninterface TemplateVars {\n VERSION?: string;\n ORDER?: string;\n DESCRIPTION: string;\n TABLE_NAME: string;\n SCHEMA: string;\n CREATED_DATE: string;\n AUTHOR: string;\n UUID_1?: string;\n UUID_2?: string;\n UUID_3?: string;\n}\n\n/**\n * Get the template directory path\n */\nfunction getTemplateDir(): string {\n // Templates are in the package's template directory\n // Use import.meta.url for ESM compatibility\n const currentFile = fileURLToPath(import.meta.url);\n const currentDir = path.dirname(currentFile);\n const packageRoot = path.resolve(currentDir, \"..\", \"..\");\n return path.join(packageRoot, \"template\");\n}\n\n/**\n * Read and process a template file\n */\nfunction loadTemplate(templatePath: string, vars: TemplateVars): string {\n const fullPath = path.join(getTemplateDir(), templatePath);\n\n if (!fs.existsSync(fullPath)) {\n throw new Error(`Template not found: ${fullPath}`);\n }\n\n let content = fs.readFileSync(fullPath, \"utf-8\");\n\n // Replace all template variables\n for (const [key, value] of Object.entries(vars)) {\n const regex = new RegExp(`\\\\{\\\\{${key}\\\\}\\\\}`, \"g\");\n content = content.replace(regex, value ?? \"\");\n }\n\n return content;\n}\n\n/**\n * Get git username for author field\n */\nfunction getGitUsername(): string {\n try {\n return execSync(\"git config user.name\", { encoding: \"utf-8\" }).trim();\n } catch {\n return \"\";\n }\n}\n\n/**\n * Options for generating migration template\n */\ninterface MigrationTemplateOptions {\n name: string;\n version: string;\n tableName: string;\n schema: string;\n author: string;\n type: \"sql\" | \"ts\";\n}\n\n/**\n * Options for generating seed template\n */\ninterface SeedTemplateOptions {\n name: string;\n order: string;\n tableName: string;\n schema: string;\n author: string;\n type: \"sql\" | \"ts\";\n}\n\n/**\n * Get migration template content from external template file\n */\nfunction getMigrationTemplate(options: MigrationTemplateOptions): string {\n const { name, version, tableName, schema, author, type } = options;\n const description = toPascalCase(name);\n const date = new Date().toISOString().split(\"T\")[0];\n\n const vars: TemplateVars = {\n VERSION: version,\n DESCRIPTION: description,\n TABLE_NAME: tableName,\n SCHEMA: schema,\n CREATED_DATE: date,\n AUTHOR: author,\n };\n\n const templateFile =\n type === \"ts\"\n ? \"migrations/migration.ts.template\"\n : \"migrations/migration.sql.template\";\n\n return loadTemplate(templateFile, vars);\n}\n\n/**\n * Get seed template content from external template file\n */\nfunction getSeedTemplate(options: SeedTemplateOptions): string {\n const { name, order, tableName, schema, author, type } = options;\n const description = toPascalCase(name);\n const date = new Date().toISOString().split(\"T\")[0];\n\n const vars: TemplateVars = {\n ORDER: order,\n DESCRIPTION: description,\n TABLE_NAME: tableName,\n SCHEMA: schema,\n CREATED_DATE: date,\n AUTHOR: author,\n UUID_1: randomUUID(),\n UUID_2: randomUUID(),\n UUID_3: randomUUID(),\n };\n\n const templateFile =\n type === \"ts\" ? \"seeds/seed.ts.template\" : \"seeds/seed.sql.template\";\n\n return loadTemplate(templateFile, vars);\n}\n\n/**\n * Options for generating CSV seed template\n */\ninterface CsvSeedTemplateOptions {\n name: string;\n tableName: string;\n schema: string;\n}\n\n/**\n * Get CSV seed template content from external template file\n */\nfunction getCsvSeedTemplate(options: CsvSeedTemplateOptions): string {\n const { name, tableName, schema } = options;\n const description = toPascalCase(name);\n const date = new Date().toISOString().split(\"T\")[0];\n\n const vars: TemplateVars = {\n DESCRIPTION: description,\n TABLE_NAME: tableName,\n SCHEMA: schema,\n CREATED_DATE: date,\n AUTHOR: \"\",\n UUID_1: randomUUID(),\n UUID_2: randomUUID(),\n UUID_3: randomUUID(),\n };\n\n try {\n return loadTemplate(\"seeds/seed.csv.template\", vars);\n } catch {\n // Fallback to basic CSV structure if template not found\n return `id,name,created_at\n${randomUUID()},Example 1,${new Date().toISOString()}\n${randomUUID()},Example 2,${new Date().toISOString()}\n`;\n }\n}\n\n// Create command group\nconst createCommand = program\n .command(\"create\")\n .description(\"Create new migration or seed files\");\n\ncreateCommand\n .command(\"migration\")\n .description(\"Create a new migration file (interactive if no name provided)\")\n .argument(\"[name]\", \"Migration name (e.g., add_users_table)\")\n .option(\"-t, --type <type>\", \"File type: {sql, ts} (default: sql)\", \"sql\")\n .option(\n \"-T, --table <table>\",\n \"Table name (default: derived from migration name)\",\n )\n .option(\n \"-s, --schema <schema>\",\n \"Database schema (default: public)\",\n \"public\",\n )\n .option(\"--no-author\", \"Skip adding git username as author\")\n .option(\"-i, --interactive\", \"Force interactive mode\")\n .option(\n \"-d, --dry-run\",\n \"Preview what would be created without writing files\",\n )\n .option(\"-f, --force\", \"Overwrite existing file if it exists\")\n .action(\n async (\n name: string | undefined,\n options: {\n type: string;\n table?: string;\n schema: string;\n author: boolean;\n interactive?: boolean;\n dryRun?: boolean;\n force?: boolean;\n },\n ) => {\n try {\n const config = await loadConfig();\n\n // Run interactive mode if no name provided or -i flag\n if (!name || options.interactive) {\n await runInteractiveMigration(config);\n process.exit(0);\n }\n\n // Validate inputs\n validateName(name, \"migration\");\n validateSchemaName(options.schema);\n const fileType = validateMigrationType(options.type);\n\n const migrationsPath = config.migrationsPath ?? \"./migrations\";\n\n // Ensure directory exists (unless dry-run)\n if (!options.dryRun && !fs.existsSync(migrationsPath)) {\n fs.mkdirSync(migrationsPath, { recursive: true });\n console.log(`šŸ“ Created directory: ${migrationsPath}`);\n }\n\n const version = getNextMigrationVersion(migrationsPath);\n const snakeName = toSnakeCase(name);\n const tableName = options.table ?? snakeName;\n const schema = options.schema;\n const author = options.author ? getGitUsername() : \"\";\n const filename = `${version}_${snakeName}.${fileType}`;\n const filepath = path.join(migrationsPath, filename);\n\n // Check if file already exists\n if (fs.existsSync(filepath) && !options.force) {\n console.error(`āŒ File already exists: ${filepath}`);\n console.error(\" Use --force to overwrite\");\n process.exit(1);\n }\n\n // Generate content from template\n const content = getMigrationTemplate({\n name,\n version,\n tableName,\n schema,\n author,\n type: fileType,\n });\n\n // Dry-run mode - show preview\n if (options.dryRun) {\n console.log(\"šŸ” Dry-run mode - no files will be created\\n\");\n console.log(`Would create: ${filename}`);\n console.log(` Path: ${filepath}`);\n console.log(` Type: ${fileType.toUpperCase()}`);\n console.log(` Table: ${schema}.${tableName}`);\n if (author) {\n console.log(` Author: ${author}`);\n }\n console.log(\"\\nšŸ“„ File content preview:\");\n console.log(\"─\".repeat(SEPARATOR_WIDTH));\n console.log(content);\n console.log(\"─\".repeat(SEPARATOR_WIDTH));\n process.exit(0);\n }\n\n // Write file\n fs.writeFileSync(filepath, content, \"utf-8\");\n\n console.log(`āœ… Created migration: ${filename}`);\n console.log(` Path: ${filepath}`);\n console.log(` Type: ${fileType.toUpperCase()}`);\n console.log(` Table: ${schema}.${tableName}`);\n if (author) {\n console.log(` Author: ${author}`);\n }\n console.log(\"\");\n console.log(\"šŸ“ Next steps:\");\n console.log(` 1. Edit the migration file to add your schema changes`);\n console.log(` 2. Run 'plyaz-db migrate up' to apply the migration`);\n console.log(\n ` 3. Test rollback with 'plyaz-db migrate down' before deploying`,\n );\n\n process.exit(0);\n } catch (error) {\n console.error(\"āŒ Error:\", (error as Error).message);\n process.exit(1);\n }\n },\n );\n\ncreateCommand\n .command(\"seed\")\n .description(\"Create a new seed file (interactive if no name provided)\")\n .argument(\"[name]\", \"Seed name (e.g., admin_users)\")\n .option(\"-t, --type <type>\", \"File type: {ts, sql, csv} (default: ts)\", \"ts\")\n .option(\"-T, --table <table>\", \"Table name (default: derived from seed name)\")\n .option(\n \"-s, --schema <schema>\",\n \"Database schema (default: public)\",\n \"public\",\n )\n .option(\"--no-author\", \"Skip adding git username as author\")\n .option(\"-i, --interactive\", \"Force interactive mode\")\n .option(\n \"-d, --dry-run\",\n \"Preview what would be created without writing files\",\n )\n .option(\"-f, --force\", \"Overwrite existing file if it exists\")\n .action(\n async (\n name: string | undefined,\n options: {\n type: string;\n table?: string;\n schema: string;\n author: boolean;\n interactive?: boolean;\n dryRun?: boolean;\n force?: boolean;\n },\n ) => {\n try {\n const config = await loadConfig();\n\n // Run interactive mode if no name provided or -i flag\n if (!name || options.interactive) {\n await runInteractiveSeed(config);\n process.exit(0);\n }\n\n // Validate inputs\n validateName(name, \"seed\");\n validateSchemaName(options.schema);\n const fileType = validateSeedType(options.type);\n\n const seedsPath = config.seedsPath ?? \"./seeds\";\n\n // Ensure directory exists (unless dry-run)\n if (!options.dryRun && !fs.existsSync(seedsPath)) {\n fs.mkdirSync(seedsPath, { recursive: true });\n console.log(`šŸ“ Created directory: ${seedsPath}`);\n }\n\n const order = getNextSeedOrder(seedsPath);\n const snakeName = toSnakeCase(name);\n const tableName = options.table ?? snakeName;\n const schema = options.schema;\n const author = options.author ? getGitUsername() : \"\";\n\n const filename = `${order}_${snakeName}.${fileType}`;\n const filepath = path.join(seedsPath, filename);\n\n // Check if file already exists\n if (fs.existsSync(filepath) && !options.force) {\n console.error(`āŒ File already exists: ${filepath}`);\n console.error(\" Use --force to overwrite\");\n process.exit(1);\n }\n\n // Generate content from template\n let content: string;\n if (fileType === \"csv\") {\n content = getCsvSeedTemplate({ name, tableName, schema });\n } else {\n content = getSeedTemplate({\n name,\n order,\n tableName,\n schema,\n author,\n type: fileType,\n });\n }\n\n // Dry-run mode - show preview\n if (options.dryRun) {\n console.log(\"šŸ” Dry-run mode - no files will be created\\n\");\n console.log(`Would create: ${filename}`);\n console.log(` Path: ${filepath}`);\n console.log(` Type: ${fileType.toUpperCase()}`);\n console.log(` Table: ${schema}.${tableName}`);\n if (author && fileType !== \"csv\") {\n console.log(` Author: ${author}`);\n }\n console.log(\"\\nšŸ“„ File content preview:\");\n console.log(\"─\".repeat(SEPARATOR_WIDTH));\n console.log(content);\n console.log(\"─\".repeat(SEPARATOR_WIDTH));\n process.exit(0);\n }\n\n // Write file\n fs.writeFileSync(filepath, content, \"utf-8\");\n\n console.log(`āœ… Created seed: ${filename}`);\n console.log(` Path: ${filepath}`);\n console.log(` Type: ${fileType.toUpperCase()}`);\n console.log(` Table: ${schema}.${tableName}`);\n if (author && fileType !== \"csv\") {\n console.log(` Author: ${author}`);\n }\n console.log(\"\");\n console.log(\"šŸ“ Next steps:\");\n console.log(` 1. Edit the seed file to add your data`);\n console.log(` 2. Run 'plyaz-db seed run' to execute seeds`);\n console.log(` 3. Use 'plyaz-db seed status' to check seed status`);\n\n process.exit(0);\n } catch (error) {\n console.error(\"āŒ Error:\", (error as Error).message);\n process.exit(1);\n }\n },\n );\n\n// Parse arguments\nprogram.parse();\n"]}
1
+ {"version":3,"sources":["../../src/migrations/generateDownMigration.ts","../../src/utils/databaseResultHelpers.ts","../../src/migrations/MigrationManager.ts","../../src/seeds/SeedManager.ts","../../src/utils/typeGuards.ts","../../src/service/EventEmitter.ts","../../src/utils/normalizeDetails.ts","../../src/service/HealthManager.ts","../../src/utils/ConfigMerger.ts","../../src/service/DatabaseService.ts","../../src/utils/pagination.ts","../../src/utils/regex.ts","../../src/adapters/drizzle/DrizzleAdapter.ts","../../src/adapters/supabase/SupabaseAdapter.ts","../../src/adapters/sql/SQLAdapter.ts","../../src/adapters/mock/MockAdapter.ts","../../src/factory/AdapterFactory.ts","../../src/extensions/SoftDeleteExtension.ts","../../src/extensions/AuditExtension.ts","../../src/extensions/EncryptionExtension.ts","../../src/extensions/CachingAdapter.ts","../../src/extensions/ReadReplicaAdapter.ts","../../src/factory/createDatabaseService.ts","../../src/cli/index.ts"],"names":["fs3","path3","path","fs","sql","DESCRIPTION_MAX_LENGTH","FALLBACK_DESCRIPTION_LENGTH","PROGRESS_LOG_INTERVAL","ERROR_MESSAGE_MAX_LENGTH","path2","DatabaseError","DATABASE_ERROR_CODES","fs2","idColumn","result","NUMERIX","Pool","resolve","ADAPTERS","logger","processDirectory"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Utility to help generate DOWN migrations from SQL files\n *\n * This is a helper script to analyze SQL migrations and suggest\n * appropriate DOWN statements for rollback support.\n */\n\nimport * as fs from \"fs\";\nimport * as path from \"path\";\n\n/** Maximum characters to show in TODO comments for unhandled statements */\nconst TODO_PREVIEW_LENGTH = 50;\n/** Width of separator lines in output */\nconst SEPARATOR_LINE_WIDTH = 60;\n/** CLI arguments slice start index */\nconst CLI_ARGS_START = 2;\n\ninterface DownSuggestion {\n file: string;\n upStatements: string[];\n downSuggestions: string[];\n}\n\n/** Handler function for generating DOWN statement from a SQL statement */\ntype StatementHandler = (statement: string) => string | null;\n\n/**\n * Pattern handlers for generating DOWN statements\n */\nconst STATEMENT_HANDLERS: Array<{\n pattern: RegExp;\n handler: StatementHandler;\n}> = [\n {\n pattern: /CREATE\\s+TABLE\\s+(?:IF\\s+NOT\\s+EXISTS\\s+)?(\\w+)/i,\n handler: (statement) => {\n const match = statement.match(\n /CREATE\\s+TABLE\\s+(?:IF\\s+NOT\\s+EXISTS\\s+)?(\\w+)/i,\n );\n return match ? `DROP TABLE IF EXISTS ${match[1]} CASCADE` : null;\n },\n },\n {\n pattern: /CREATE\\s+(?:UNIQUE\\s+)?INDEX\\s+(?:IF\\s+NOT\\s+EXISTS\\s+)?(\\w+)/i,\n handler: (statement) => {\n const match = statement.match(\n /CREATE\\s+(?:UNIQUE\\s+)?INDEX\\s+(?:IF\\s+NOT\\s+EXISTS\\s+)?(\\w+)/i,\n );\n return match ? `DROP INDEX IF EXISTS ${match[1]}` : null;\n },\n },\n {\n pattern: /CREATE\\s+TYPE\\s+(\\w+)/i,\n handler: (statement) => {\n const match = statement.match(/CREATE\\s+TYPE\\s+(\\w+)/i);\n return match ? `DROP TYPE IF EXISTS ${match[1]} CASCADE` : null;\n },\n },\n {\n pattern: /CREATE\\s+EXTENSION\\s+(?:IF\\s+NOT\\s+EXISTS\\s+)?\"?(\\w+)\"?/i,\n handler: (statement) => {\n const match = statement.match(\n /CREATE\\s+EXTENSION\\s+(?:IF\\s+NOT\\s+EXISTS\\s+)?\"?(\\w+)\"?/i,\n );\n return match ? `DROP EXTENSION IF EXISTS \"${match[1]}\"` : null;\n },\n },\n {\n pattern: /ALTER\\s+TABLE\\s+(\\w+)\\s+ADD\\s+COLUMN/i,\n handler: (statement) => {\n const match = statement.match(\n /ALTER\\s+TABLE\\s+(\\w+)\\s+ADD\\s+COLUMN\\s+(\\w+)/i,\n );\n return match\n ? `ALTER TABLE ${match[1]} DROP COLUMN IF EXISTS ${match[2]}`\n : null;\n },\n },\n {\n pattern: /CREATE\\s+(?:OR\\s+REPLACE\\s+)?FUNCTION\\s+(\\w+)/i,\n handler: (statement) => {\n const match = statement.match(\n /CREATE\\s+(?:OR\\s+REPLACE\\s+)?FUNCTION\\s+(\\w+)/i,\n );\n return match ? `DROP FUNCTION IF EXISTS ${match[1]}` : null;\n },\n },\n {\n pattern:\n /CREATE\\s+(?:OR\\s+REPLACE\\s+)?TRIGGER\\s+(\\w+)\\s+(?:BEFORE|AFTER)\\s+(?:INSERT|UPDATE|DELETE).*?ON\\s+(\\w+)/i,\n handler: (statement) => {\n const match = statement.match(\n /CREATE\\s+(?:OR\\s+REPLACE\\s+)?TRIGGER\\s+(\\w+)\\s+(?:BEFORE|AFTER)\\s+(?:INSERT|UPDATE|DELETE).*?ON\\s+(\\w+)/i,\n );\n return match ? `DROP TRIGGER IF EXISTS ${match[1]} ON ${match[2]}` : null;\n },\n },\n];\n\n/**\n * Generate a DOWN statement for a single SQL statement\n */\nfunction generateDownStatement(statement: string): string {\n for (const { pattern, handler } of STATEMENT_HANDLERS) {\n if (statement.match(pattern)) {\n const result = handler(statement);\n if (result) return result;\n }\n }\n // Unknown statement type - suggest manual review\n return `-- TODO: Add DOWN statement for: ${statement.substring(0, TODO_PREVIEW_LENGTH)}...`;\n}\n\n/**\n * Parse SQL migration and suggest DOWN statements\n */\nexport function suggestDownMigration(\n sqlContent: string,\n filename: string,\n): DownSuggestion {\n const upStatements: string[] = [];\n const downSuggestions: string[] = [];\n\n // Split by semicolons to get individual statements\n const statements = sqlContent\n .split(\";\")\n .map((s) => s.trim())\n .filter((s) => s.length > 0 && !s.startsWith(\"--\"));\n\n for (const statement of statements) {\n upStatements.push(statement);\n downSuggestions.push(generateDownStatement(statement));\n }\n\n // Reverse the order for DOWN migration (undo in reverse order)\n downSuggestions.reverse();\n\n return {\n file: filename,\n upStatements,\n downSuggestions,\n };\n}\n\n/**\n * Add DOWN section to a migration file\n */\nexport function addDownSection(filePath: string): string {\n const content = fs.readFileSync(filePath, \"utf-8\");\n\n // Check if already has DOWN section\n if (content.includes(\"-- DOWN\")) {\n return content; // Already has DOWN section\n }\n\n const suggestion = suggestDownMigration(content, path.basename(filePath));\n\n // Build the new content with DOWN section\n const downSection =\n \"\\n\\n-- DOWN\\n\" + suggestion.downSuggestions.join(\";\\n\\n\") + \";\\n\";\n\n return content + downSection;\n}\n\n/**\n * Process all migrations in a directory and add DOWN sections\n */\nexport function processDirectory(migrationsPath: string, dryRun = true): void {\n if (!fs.existsSync(migrationsPath)) {\n console.error(`Migration directory not found: ${migrationsPath}`);\n return;\n }\n\n const files = fs\n .readdirSync(migrationsPath)\n .filter((f) => f.endsWith(\".sql\"));\n\n console.log(`Found ${files.length} SQL migration files\\n`);\n\n for (const file of files) {\n const filePath = path.join(migrationsPath, file);\n const content = fs.readFileSync(filePath, \"utf-8\");\n\n if (content.includes(\"-- DOWN\")) {\n console.log(`āœ“ ${file} - Already has DOWN section`);\n continue;\n }\n\n const newContent = addDownSection(filePath);\n\n if (dryRun) {\n console.log(`\\nšŸ“„ ${file}`);\n console.log(\"─\".repeat(SEPARATOR_LINE_WIDTH));\n console.log(\"Suggested DOWN section:\");\n const downSection = newContent.split(\"-- DOWN\")[1];\n console.log(downSection);\n } else {\n fs.writeFileSync(filePath, newContent, \"utf-8\");\n console.log(`āœ“ ${file} - Added DOWN section`);\n }\n }\n\n if (dryRun) {\n console.log(\"\\n\" + \"=\".repeat(SEPARATOR_LINE_WIDTH));\n console.log(\"āš ļø DRY RUN MODE - No files were modified\");\n console.log(\"Run with --write to apply changes\");\n }\n}\n\n// CLI usage\nif (globalThis.require.main === globalThis.module) {\n const args = process.argv.slice(CLI_ARGS_START);\n const migrationsPath = args[0] || \"./migrations\";\n const dryRun = !args.includes(\"--write\");\n\n console.log(\"šŸ” Analyzing migrations for DOWN section generation\\n\");\n processDirectory(migrationsPath, dryRun);\n}\n","/**\n * @fileoverview Database Result Helper Functions for @plyaz/db package\n *\n * This module provides utility functions for creating standardized DatabaseResult objects\n * used throughout the @plyaz/db package. These helpers ensure consistent result formatting\n * across all database operations and adapters.\n *\n * Part of the @plyaz/db package - a TypeScript database abstraction layer with\n * support for multiple adapters (Drizzle, Supabase, SQL), extensions (audit, encryption,\n * soft delete), and advanced features (caching, read replicas, multi-tenancy).\n *\n */\n\nimport type { DatabaseResult } from \"@plyaz/types/db\";\n\n/**\n * Creates a successful DatabaseResult wrapper for operation results\n *\n * Used throughout all database adapters and extensions to wrap successful operation results\n * in a consistent format. This enables standardized error handling and result processing\n * across the entire @plyaz/db package.\n *\n * **Used by:**\n * - All database adapters (DrizzleAdapter, SupabaseAdapter, SQLAdapter)\n * - All extensions (AuditAdapter, EncryptionAdapter, SoftDeleteAdapter, etc.)\n * - DatabaseService for operation results\n * - Repository layer for consistent return types\n *\n * @template T - The type of the successful result value\n * @param {T} value - The successful result value to wrap\n * @returns {DatabaseResult<T>} A success result object with the value\n *\n * @example\n * ```typescript\n * import { success } from '@plyaz/db/utils';\n *\n * // In adapter methods\n * async findById<T>(table: string, id: string): Promise<DatabaseResult<T | null>> {\n * try {\n * const record = await this.db.select().from(table).where(eq(id));\n * return success(record[0] || null); // Wrap successful result\n * } catch (error) {\n * return failure(new DatabaseError('FIND_FAILED', error.message));\n * }\n * }\n *\n * // In service methods\n * const userResult = await userRepository.findById('user-123');\n * if (userResult.success) {\n * console.log('Found user:', userResult.value.name);\n * }\n * ```\n *\n */\nexport function success<T = null>(value: T = null as T): DatabaseResult<T> {\n return { success: true, value };\n}\n\n/**\n * Creates a failed DatabaseResult wrapper for operation errors\n * \n * Used throughout all database adapters and extensions to wrap error results\n * in a consistent format. This enables standardized error handling and result processing\n * across the entire @plyaz/db package.\n * \n * **Used by:**\n * - All database adapters for error cases\n * - All extensions for error propagation\n * - DatabaseService for operation failures\n * - Repository layer for consistent error handling\n * \n * @template T - The type that would have been returned on success\n * @param {Error} error - The error that occurred during the operation\n * @returns {DatabaseResult<T>} A failure result object with the error\n * \n * @example\n * ```typescript\n * import { failure } from '@plyaz/db/utils';\n * import { DatabaseError } from '@plyaz/errors';\nimport { DATABASE_ERROR_CODES } from '@plyaz/types/errors';\n * \n * // In adapter methods\n * async create<T>(table: string, data: T): Promise<DatabaseResult<T>> {\n * try {\n * const result = await this.db.insert(table).values(data).returning();\n * return success(result[0]);\n * } catch (error) {\n * return failure(new DatabaseError(\n * `Failed to create record: ${error.message}`));\n * }\n * }\n * \n * // In service layer error handling\n * const createResult = await userRepository.create(userData);\n * if (!createResult.success) {\n * logger.error('User creation failed:', createResult.error.message);\n * throw createResult.error;\n * }\n * ```\n * \n */\nexport function failure<T>(error: Error): DatabaseResult<T> {\n return { success: false, error };\n}\n","/**\n * MigrationManager - Database schema migrations with version control\n *\n * Manages database schema migrations with support for versioning,\n * rollback, and migration history tracking. Automatically discovers\n * migration files from a specified directory and applies them in order.\n *\n * @example\n * ```typescript\n * const migrationManager = new MigrationManager({\n * adapter: sqlAdapter,\n * migrationsPath: './migrations', // default\n * tableName: 'schema_migrations' // default\n * });\n *\n * // Run all pending migrations\n * await migrationManager.up();\n *\n * // Rollback last migration\n * await migrationManager.down();\n *\n * // Get migration status\n * const status = await migrationManager.status();\n * ```\n */\n\nimport type {\n DatabaseAdapterType,\n DatabaseResult,\n Migration,\n MigrationFile,\n MigrationRecord,\n MigrationManagerConfig,\n MigrationStatus,\n} from \"@plyaz/types/db\";\nimport { success, failure } from \"../utils/databaseResultHelpers\";\nimport { DatabaseError } from \"@plyaz/errors\";\nimport { DATABASE_ERROR_CODES } from \"@plyaz/types/errors\";\nimport * as fs from \"fs\";\nimport * as path from \"path\";\n\n/** Constants for statement description extraction */\nconst DESCRIPTION_MAX_LENGTH = 60;\nconst FALLBACK_DESCRIPTION_LENGTH = 50;\n\n/** Constants for progress logging */\nconst PROGRESS_LOG_INTERVAL = 10;\n\n/** Constants for error message truncation */\nconst ERROR_MESSAGE_MAX_LENGTH = 300;\n\n/**\n * MigrationManager - Handles database schema migrations\n *\n * Discovers migration files, tracks migration history, and applies\n * migrations in order with support for rollback.\n */\nexport class MigrationManager {\n private adapter: DatabaseAdapterType;\n private migrationsPath: string;\n private tableName: string;\n private schema: string;\n\n constructor(config: MigrationManagerConfig) {\n this.adapter = config.adapter;\n this.migrationsPath = path.resolve(config.migrationsPath ?? \"./migrations\");\n this.schema = config.schema ?? \"public\";\n // Prefix table name with schema if not 'public'\n this.tableName =\n this.schema !== \"public\"\n ? `${this.schema}.${config.tableName ?? \"schema_migrations\"}`\n : (config.tableName ?? \"schema_migrations\");\n }\n\n /**\n * Initialize migrations table if it doesn't exist\n */\n async initialize(): Promise<DatabaseResult<void>> {\n try {\n // Create migrations tracking table with file_path for traceability\n const createTableSQL = `\n CREATE TABLE IF NOT EXISTS ${this.tableName} (\n version VARCHAR(255) PRIMARY KEY,\n name VARCHAR(255) NOT NULL,\n file_path VARCHAR(500),\n applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n execution_time INTEGER NOT NULL\n )\n `;\n\n // Execute using adapter's raw query if available\n if (typeof this.adapter.query === \"function\") {\n await this.adapter.query(createTableSQL);\n\n // Add file_path column if it doesn't exist (for existing tables)\n await this.adapter\n .query(\n `\n DO $$\n BEGIN\n IF NOT EXISTS (\n SELECT 1 FROM information_schema.columns\n WHERE table_name = '${this.tableName.split(\".\").pop()}'\n AND column_name = 'file_path'\n ) THEN\n ALTER TABLE ${this.tableName} ADD COLUMN file_path VARCHAR(500);\n END IF;\n END $$;\n `,\n )\n .catch(() => {\n // Ignore if column already exists or syntax not supported\n });\n }\n\n return success();\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to initialize migrations table: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.INIT_FAILED,\n { cause: error as Error },\n ),\n );\n }\n }\n\n /**\n * Discover migration files from migrations directory (including subdirectories)\n */\n private async discoverMigrations(): Promise<MigrationFile[]> {\n if (!fs.existsSync(this.migrationsPath)) {\n return [];\n }\n\n const migrations: MigrationFile[] = [];\n\n const scanDirectory = (dir: string): void => {\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n\n if (entry.isDirectory()) {\n // Recursively scan subdirectories\n scanDirectory(fullPath);\n } else if (entry.isFile()) {\n // Match migration file pattern: {version}_{name}.{ts|js|sql}\n // Examples: 001_initial_schema.sql, 20231124_add_users_table.ts\n const match = entry.name.match(/^(\\d+)_(.+)\\.(ts|js|sql)$/);\n if (match) {\n const [, version, name] = match;\n migrations.push({\n filePath: fullPath,\n version,\n name: name.replace(/_/g, \" \"),\n });\n }\n }\n }\n };\n\n scanDirectory(this.migrationsPath);\n\n // Sort by version\n return migrations.sort((a, b) => a.version.localeCompare(b.version));\n }\n\n /**\n * Parse SQL content to extract UP and DOWN sections\n */\n private parseSqlSections(sql: string): {\n upSQL: string;\n downSQL: string | null;\n } {\n const hasUpMarker = sql.includes(\"-- UP\");\n const hasDownMarker = sql.includes(\"-- DOWN\");\n\n if (hasUpMarker && hasDownMarker) {\n const parts = sql.split(\"-- DOWN\");\n return {\n upSQL: parts[0].replace(\"-- UP\", \"\").trim(),\n downSQL: parts[1].trim(),\n };\n }\n\n if (hasDownMarker) {\n const parts = sql.split(\"-- DOWN\");\n return {\n upSQL: parts[0].trim(),\n downSQL: parts[1].trim(),\n };\n }\n\n return { upSQL: sql.trim(), downSQL: null };\n }\n\n /**\n * Process dollar-quoted string delimiters ($$ or $tag$)\n * Returns updated state for tracking if we're inside a dollar block\n */\n private processDollarDelimiters(\n line: string,\n inDollarBlock: boolean,\n dollarTag: string,\n ): { inDollarBlock: boolean; dollarTag: string } {\n const dollarMatch = line.match(/\\$([a-zA-Z_]*)\\$/g);\n if (!dollarMatch) return { inDollarBlock, dollarTag };\n\n let currentInBlock = inDollarBlock;\n let currentTag = dollarTag;\n\n for (const match of dollarMatch) {\n if (!currentInBlock) {\n currentInBlock = true;\n currentTag = match;\n } else if (match === currentTag) {\n currentInBlock = false;\n currentTag = \"\";\n }\n }\n\n return { inDollarBlock: currentInBlock, dollarTag: currentTag };\n }\n\n /**\n * Filter out comment-only statements\n */\n private isNonCommentStatement(statement: string): boolean {\n const withoutComments = statement.replace(/--.*$/gm, \"\").trim();\n return withoutComments.length > 0;\n }\n\n /**\n * Split SQL into individual statements for better error reporting\n * Handles $$ delimited blocks (functions, triggers) correctly\n */\n private splitSqlStatements(sql: string): string[] {\n const statements: string[] = [];\n let current = \"\";\n let inDollarBlock = false;\n let dollarTag = \"\";\n\n for (const line of sql.split(\"\\n\")) {\n const trimmedLine = line.trim();\n const isEmptyOrComment =\n trimmedLine === \"\" || trimmedLine.startsWith(\"--\");\n\n // Always append line to current statement\n current += line + \"\\n\";\n\n // Skip processing for empty lines and comments\n if (isEmptyOrComment) continue;\n\n // Update dollar block tracking\n const dollarState = this.processDollarDelimiters(\n line,\n inDollarBlock,\n dollarTag,\n );\n inDollarBlock = dollarState.inDollarBlock;\n dollarTag = dollarState.dollarTag;\n\n // Check for end of statement\n const isEndOfStatement = !inDollarBlock && trimmedLine.endsWith(\";\");\n if (isEndOfStatement && current.trim()) {\n statements.push(current.trim());\n current = \"\";\n }\n }\n\n // Add any remaining content\n if (current.trim()) {\n statements.push(current.trim());\n }\n\n return statements.filter((s) => this.isNonCommentStatement(s));\n }\n\n /**\n * Extract a short description from a SQL statement for logging\n */\n private getStatementDescription(statement: string): string {\n const firstLine =\n statement\n .split(\"\\n\")\n .find((l) => l.trim() && !l.trim().startsWith(\"--\"))\n ?.trim() ?? \"\";\n\n // Extract the type and name of the object being created/modified\n const patterns = [\n /^(CREATE\\s+(?:OR\\s+REPLACE\\s+)?(?:TABLE|INDEX|UNIQUE\\s+INDEX|TYPE|FUNCTION|TRIGGER|EXTENSION|SCHEMA|VIEW|POLICY))\\s+(?:IF\\s+NOT\\s+EXISTS\\s+)?([^\\s(]+)/i,\n /^(ALTER\\s+TABLE)\\s+([^\\s]+)/i,\n /^(DROP\\s+(?:TABLE|INDEX|TYPE|FUNCTION|TRIGGER|EXTENSION|SCHEMA|VIEW|POLICY))\\s+(?:IF\\s+EXISTS\\s+)?([^\\s(;]+)/i,\n /^(INSERT\\s+INTO)\\s+([^\\s(]+)/i,\n /^(COMMENT\\s+ON\\s+(?:TABLE|COLUMN|INDEX|FUNCTION|TYPE))\\s+([^\\s]+)/i,\n /^(GRANT|REVOKE)\\s+.+\\s+ON\\s+([^\\s]+)/i,\n ];\n\n for (const pattern of patterns) {\n const match = firstLine.match(pattern);\n if (match) {\n return `${match[1]} ${match[2]}`.slice(0, DESCRIPTION_MAX_LENGTH);\n }\n }\n\n const truncated = firstLine.slice(0, FALLBACK_DESCRIPTION_LENGTH);\n const suffix = firstLine.length > FALLBACK_DESCRIPTION_LENGTH ? \"...\" : \"\";\n return truncated + suffix;\n }\n\n /**\n * Execute SQL statements individually with better error reporting\n */\n private async executeSqlStatements(\n adapter: DatabaseAdapterType,\n sql: string,\n migrationVersion: string,\n ): Promise<void> {\n const statements = this.splitSqlStatements(sql);\n const total = statements.length;\n\n console.log(` → ${total} statements to execute`);\n\n for (let i = 0; i < statements.length; i++) {\n const statement = statements[i];\n const description = this.getStatementDescription(statement);\n\n try {\n await adapter.query!(statement);\n // Show progress at intervals or for significant operations\n const isInterval = (i + 1) % PROGRESS_LOG_INTERVAL === 0;\n const isLast = i === total - 1;\n const isSignificant = Boolean(\n description.match(/^(CREATE TABLE|CREATE FUNCTION|CREATE TRIGGER)/i),\n );\n if (isInterval || isLast || isSignificant) {\n console.log(` āœ“ [${i + 1}/${total}] ${description}`);\n }\n } catch (error) {\n console.log(` āœ— [${i + 1}/${total}] ${description}`);\n\n // Extract clean error message\n const rawMessage = (error as Error).message;\n const errorMessage = rawMessage\n .replace(/^SQL Error:\\s*/i, \"\")\n .replace(/^Failed to execute query:.*?-\\s*/i, \"\")\n .slice(0, ERROR_MESSAGE_MAX_LENGTH);\n\n throw new DatabaseError(\n `Migration ${migrationVersion} failed at statement ${i + 1}/${total}:\\n` +\n ` Statement: ${description}\\n` +\n ` Error: ${errorMessage}`,\n DATABASE_ERROR_CODES.QUERY_FAILED,\n { cause: error as Error },\n );\n }\n }\n }\n\n /**\n * Load SQL migration from file\n */\n private loadSqlMigration(migrationFile: MigrationFile): Migration {\n const sql = fs.readFileSync(migrationFile.filePath, \"utf-8\");\n const { upSQL, downSQL } = this.parseSqlSections(sql);\n\n return {\n version: migrationFile.version,\n name: migrationFile.name,\n up: async (adapter: DatabaseAdapterType) => {\n if (typeof adapter.query === \"function\") {\n await this.executeSqlStatements(\n adapter,\n upSQL,\n migrationFile.version,\n );\n }\n },\n down: async (adapter: DatabaseAdapterType) => {\n if (downSQL && typeof adapter.query === \"function\") {\n await this.executeSqlStatements(\n adapter,\n downSQL,\n migrationFile.version,\n );\n } else {\n console.warn(\n `[Migrations] No DOWN migration for ${migrationFile.version}`,\n );\n }\n },\n };\n }\n\n /**\n * Load TypeScript/JavaScript migration from file\n */\n private async loadJsMigration(\n migrationFile: MigrationFile,\n ): Promise<Migration> {\n const importPath = migrationFile.filePath.startsWith(\"/\")\n ? migrationFile.filePath\n : new URL(`file:///${migrationFile.filePath.replace(/\\\\/g, \"/\")}`).href;\n\n const migrationModule = await import(importPath);\n return {\n version: migrationFile.version,\n name: migrationFile.name,\n up: migrationModule.up ?? migrationModule.default?.up,\n down: migrationModule.down ?? migrationModule.default?.down,\n };\n }\n\n /**\n * Load migration from file\n */\n private async loadMigration(\n migrationFile: MigrationFile,\n ): Promise<Migration> {\n const ext = path.extname(migrationFile.filePath);\n\n switch (ext) {\n case \".sql\":\n return this.loadSqlMigration(migrationFile);\n case \".ts\":\n case \".js\":\n return this.loadJsMigration(migrationFile);\n default:\n throw new DatabaseError(\n `Unsupported migration file extension: ${ext}`,\n DATABASE_ERROR_CODES.INVALID_PARAMETERS,\n { cause: new Error(`Unsupported extension: ${ext}`) },\n );\n }\n }\n\n /**\n * Get applied migrations from database\n */\n private async getAppliedMigrations(): Promise<MigrationRecord[]> {\n try {\n if (typeof this.adapter.query === \"function\") {\n const result = await this.adapter.query<MigrationRecord>(\n `SELECT * FROM ${this.tableName} ORDER BY version ASC`,\n );\n // Handle both array results and postgres-style { rows: [] } results\n return Array.isArray(result)\n ? result\n : (result as unknown as { rows: MigrationRecord[] }).rows || [];\n }\n return [];\n } catch {\n // Table might not exist yet\n return [];\n }\n }\n\n /**\n * Record migration as applied\n */\n private async recordMigration(\n version: string,\n name: string,\n executionTime: number,\n filePath?: string,\n ): Promise<void> {\n if (typeof this.adapter.query === \"function\") {\n // Store relative path from migrations directory for portability\n const relativePath = filePath\n ? path.relative(this.migrationsPath, filePath)\n : null;\n\n await this.adapter.query(\n `INSERT INTO ${this.tableName} (version, name, file_path, execution_time) VALUES ($1, $2, $3, $4)`,\n [version, name, relativePath, executionTime],\n );\n }\n }\n\n /**\n * Remove migration record (for rollback)\n */\n private async unrecordMigration(version: string): Promise<void> {\n if (typeof this.adapter.query === \"function\") {\n await this.adapter.query(\n `DELETE FROM ${this.tableName} WHERE version = $1`,\n [version],\n );\n }\n }\n\n /**\n * Get migration status (applied and pending)\n */\n async status(): Promise<DatabaseResult<MigrationStatus>> {\n try {\n await this.initialize();\n\n const allMigrations = await this.discoverMigrations();\n const appliedMigrations = await this.getAppliedMigrations();\n const appliedVersions = new Set(appliedMigrations.map((m) => m.version));\n\n const pending = allMigrations\n .filter((m) => !appliedVersions.has(m.version))\n .map((m) => `${m.version}_${m.name}`);\n\n return success({\n applied: appliedMigrations,\n pending,\n });\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to get migration status: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.QUERY_FAILED,\n { cause: error as Error },\n ),\n );\n }\n }\n\n /**\n * Run all pending migrations\n */\n /* eslint-disable max-depth, complexity */\n async up(targetVersion?: string): Promise<DatabaseResult<number>> {\n try {\n await this.initialize();\n\n const allMigrations = await this.discoverMigrations();\n const appliedMigrations = await this.getAppliedMigrations();\n const appliedVersions = new Set(appliedMigrations.map((m) => m.version));\n\n let applied = 0;\n\n for (const migrationFile of allMigrations) {\n // Skip if already applied\n if (appliedVersions.has(migrationFile.version)) {\n continue;\n }\n\n // Stop if we've reached target version\n if (targetVersion && migrationFile.version > targetVersion) {\n break;\n }\n\n console.log(\n `[Migrations] Applying ${migrationFile.version}_${migrationFile.name}...`,\n );\n\n const migration = await this.loadMigration(migrationFile);\n const startTime = Date.now();\n\n // Run migration in transaction if possible\n if (typeof this.adapter.transaction === \"function\") {\n const txResult = await this.adapter.transaction(async () => {\n await migration.up(this.adapter);\n });\n // Check transaction result - transaction() returns failure() instead of throwing\n if (!txResult.success) {\n throw (\n txResult.error ??\n new DatabaseError(\n `Migration ${migration.version} failed`,\n DATABASE_ERROR_CODES.QUERY_FAILED,\n )\n );\n }\n } else {\n await migration.up(this.adapter);\n }\n\n const executionTime = Date.now() - startTime;\n\n // Record migration with file path for traceability\n await this.recordMigration(\n migration.version,\n migration.name,\n executionTime,\n migrationFile.filePath,\n );\n\n console.log(\n `[Migrations] Applied ${migration.version} in ${executionTime}ms`,\n );\n applied++;\n }\n\n return success(applied);\n } catch (error) {\n return failure(\n new DatabaseError(\n `Migration failed: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.QUERY_FAILED,\n { cause: error as Error },\n ),\n );\n }\n }\n\n /**\n * Rollback last migration or rollback to specific version\n */\n async down(steps: number = 1): Promise<DatabaseResult<number>> {\n try {\n const appliedMigrations = await this.getAppliedMigrations();\n\n if (appliedMigrations.length === 0) {\n return success(0);\n }\n\n // Get migrations to rollback (in reverse order)\n const toRollback = appliedMigrations.slice(-steps).reverse();\n let rolledBack = 0;\n\n for (const appliedMigration of toRollback) {\n console.log(\n `[Migrations] Rolling back ${appliedMigration.version}_${appliedMigration.name}...`,\n );\n\n // Find migration file\n const allMigrations = await this.discoverMigrations();\n const migrationFile = allMigrations.find(\n (m) => m.version === appliedMigration.version,\n );\n\n if (!migrationFile) {\n console.warn(\n `[Migrations] Migration file not found for version ${appliedMigration.version}`,\n );\n continue;\n }\n\n const migration = await this.loadMigration(migrationFile);\n const startTime = Date.now();\n\n // Run rollback in transaction if possible\n if (typeof this.adapter.transaction === \"function\") {\n const txResult = await this.adapter.transaction(async () => {\n await migration.down(this.adapter);\n });\n // Check transaction result - transaction() returns failure() instead of throwing\n if (!txResult.success) {\n throw (\n txResult.error ??\n new DatabaseError(\n `Rollback ${appliedMigration.version} failed`,\n DATABASE_ERROR_CODES.QUERY_FAILED,\n )\n );\n }\n } else {\n await migration.down(this.adapter);\n }\n\n const executionTime = Date.now() - startTime;\n\n // Remove migration record\n await this.unrecordMigration(appliedMigration.version);\n\n console.log(\n `[Migrations] Rolled back ${appliedMigration.version} in ${executionTime}ms`,\n );\n rolledBack++;\n }\n\n return success(rolledBack);\n } catch (error) {\n return failure(\n new DatabaseError(\n `Rollback failed: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.QUERY_FAILED,\n { cause: error as Error },\n ),\n );\n }\n }\n\n /**\n * Reset database (rollback all migrations)\n */\n async reset(): Promise<DatabaseResult<number>> {\n const appliedMigrations = await this.getAppliedMigrations();\n return this.down(appliedMigrations.length);\n }\n\n /**\n * Clear migration history (delete all records from tracking table)\n *\n * Use this to force fresh migrations in test/development environments\n * without rolling back actual database changes.\n *\n * @example\n * ```typescript\n * // Clear history and re-run all migrations\n * await migrationManager.clearHistory();\n * await migrationManager.up();\n * ```\n */\n async clearHistory(): Promise<DatabaseResult<void>> {\n try {\n if (typeof this.adapter.query === \"function\") {\n await this.adapter.query(`DELETE FROM ${this.tableName}`);\n }\n return success();\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to clear migration history: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.QUERY_FAILED,\n { cause: error as Error },\n ),\n );\n }\n }\n}\n","/**\n * SeedManager - Database seeding for development and testing\n *\n * Manages database seeding with support for ordered execution,\n * seed history tracking, and idempotent seed operations.\n * Automatically discovers seed files from a specified directory.\n *\n * @example\n * ```typescript\n * const seedManager = new SeedManager({\n * adapter: sqlAdapter,\n * seedsPath: './seeds', // default\n * tableName: 'seed_history' // default\n * });\n *\n * // Run all seeds\n * await seedManager.run();\n *\n * // Run specific seed\n * await seedManager.run('users');\n *\n * // Clear all data (for testing)\n * await seedManager.reset();\n * ```\n */\n\nimport type {\n DatabaseAdapterType,\n DatabaseResult,\n Seed,\n SeedFile,\n SeedRecord,\n SeedManagerConfig,\n} from \"@plyaz/types/db\";\nimport { success, failure } from \"../utils/databaseResultHelpers\";\nimport { DatabaseError } from \"@plyaz/errors\";\nimport { DATABASE_ERROR_CODES } from \"@plyaz/types/errors\";\nimport * as fs from \"fs\";\nimport * as path from \"path\";\n\n/** Constants for statement description extraction */\nconst DESCRIPTION_MAX_LENGTH = 60;\nconst FALLBACK_DESCRIPTION_LENGTH = 50;\n\n/** Constants for progress logging */\nconst PROGRESS_LOG_INTERVAL = 10;\n\n/** Constants for error message truncation */\nconst ERROR_MESSAGE_MAX_LENGTH = 300;\n\n/**\n * SeedManager - Handles database seeding operations\n *\n * Discovers seed files, tracks seed history, and executes\n * seeds in order with support for cleanup and reset.\n */\nexport class SeedManager {\n private adapter: DatabaseAdapterType;\n private seedsPath: string;\n private tableName: string;\n private schema: string;\n private skipExisting: boolean;\n\n constructor(config: SeedManagerConfig) {\n this.adapter = config.adapter;\n this.seedsPath = path.resolve(config.seedsPath ?? \"./seeds\");\n this.schema = config.schema ?? \"public\";\n // Prefix table name with schema if not 'public'\n this.tableName =\n this.schema !== \"public\"\n ? `${this.schema}.${config.tableName ?? \"seed_history\"}`\n : (config.tableName ?? \"seed_history\");\n this.skipExisting = config.skipExisting ?? false;\n }\n\n /**\n * Initialize seeds tracking table if it doesn't exist\n */\n async initialize(): Promise<DatabaseResult<void>> {\n try {\n // Create seeds tracking table with file_path for traceability\n const createTableSQL = `\n CREATE TABLE IF NOT EXISTS ${this.tableName} (\n name VARCHAR(255) PRIMARY KEY,\n file_path VARCHAR(500),\n run_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n execution_time INTEGER NOT NULL\n )\n `;\n\n // Execute using adapter's raw query if available\n if (typeof this.adapter.query === \"function\") {\n await this.adapter.query(createTableSQL);\n\n // Add file_path column if it doesn't exist (for existing tables)\n await this.adapter\n .query(\n `\n DO $$\n BEGIN\n IF NOT EXISTS (\n SELECT 1 FROM information_schema.columns\n WHERE table_name = '${this.tableName.split(\".\").pop()}'\n AND column_name = 'file_path'\n ) THEN\n ALTER TABLE ${this.tableName} ADD COLUMN file_path VARCHAR(500);\n END IF;\n END $$;\n `,\n )\n .catch(() => {\n // Ignore if column already exists or syntax not supported\n });\n }\n\n return success();\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to initialize seeds table: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.INIT_FAILED,\n { cause: error as Error },\n ),\n );\n }\n }\n\n /**\n * Discover seed files from seeds directory\n */\n private async discoverSeeds(): Promise<SeedFile[]> {\n if (!fs.existsSync(this.seedsPath)) {\n return [];\n }\n\n const files = fs.readdirSync(this.seedsPath);\n const seeds: SeedFile[] = [];\n\n for (const file of files) {\n // Match seed file pattern: {order}_{name}.{ts|js|sql}\n // Examples: 001_users.ts, 002_campaigns.js, 003_data.sql\n const match = file.match(/^(\\d+)_(.+)\\.(ts|js|sql)$/);\n if (match) {\n const [, order, name] = match;\n seeds.push({\n filePath: path.join(this.seedsPath, file),\n order: Number.parseInt(order, 10),\n name,\n });\n }\n }\n\n // Sort by order\n return seeds.sort((a, b) => a.order - b.order);\n }\n\n /**\n * Process dollar-quoted string delimiters ($$ or $tag$)\n */\n private processDollarDelimiters(\n line: string,\n inDollarBlock: boolean,\n dollarTag: string,\n ): { inDollarBlock: boolean; dollarTag: string } {\n const dollarMatch = line.match(/\\$([a-zA-Z_]*)\\$/g);\n if (!dollarMatch) return { inDollarBlock, dollarTag };\n\n let currentInBlock = inDollarBlock;\n let currentTag = dollarTag;\n\n for (const match of dollarMatch) {\n if (!currentInBlock) {\n currentInBlock = true;\n currentTag = match;\n } else if (match === currentTag) {\n currentInBlock = false;\n currentTag = \"\";\n }\n }\n\n return { inDollarBlock: currentInBlock, dollarTag: currentTag };\n }\n\n /**\n * Filter out comment-only statements\n */\n private isNonCommentStatement(statement: string): boolean {\n const withoutComments = statement.replace(/--.*$/gm, \"\").trim();\n return withoutComments.length > 0;\n }\n\n /**\n * Split SQL into individual statements for better error reporting\n */\n private splitSqlStatements(sql: string): string[] {\n const statements: string[] = [];\n let current = \"\";\n let inDollarBlock = false;\n let dollarTag = \"\";\n\n for (const line of sql.split(\"\\n\")) {\n const trimmedLine = line.trim();\n const isEmptyOrComment =\n trimmedLine === \"\" || trimmedLine.startsWith(\"--\");\n\n current += line + \"\\n\";\n if (isEmptyOrComment) continue;\n\n const dollarState = this.processDollarDelimiters(\n line,\n inDollarBlock,\n dollarTag,\n );\n inDollarBlock = dollarState.inDollarBlock;\n dollarTag = dollarState.dollarTag;\n\n if (!inDollarBlock && trimmedLine.endsWith(\";\") && current.trim()) {\n statements.push(current.trim());\n current = \"\";\n }\n }\n\n if (current.trim()) {\n statements.push(current.trim());\n }\n\n return statements.filter((s) => this.isNonCommentStatement(s));\n }\n\n /**\n * Extract a short description from a SQL statement for logging\n */\n private getStatementDescription(statement: string): string {\n const firstLine =\n statement\n .split(\"\\n\")\n .find((l) => l.trim() && !l.trim().startsWith(\"--\"))\n ?.trim() ?? \"\";\n\n const patterns = [\n /^(CREATE\\s+(?:OR\\s+REPLACE\\s+)?(?:TABLE|INDEX|UNIQUE\\s+INDEX|TYPE|FUNCTION|TRIGGER|EXTENSION|SCHEMA|VIEW|POLICY))\\s+(?:IF\\s+NOT\\s+EXISTS\\s+)?([^\\s(]+)/i,\n /^(ALTER\\s+TABLE)\\s+([^\\s]+)/i,\n /^(DROP\\s+(?:TABLE|INDEX|TYPE|FUNCTION|TRIGGER|EXTENSION|SCHEMA|VIEW|POLICY))\\s+(?:IF\\s+EXISTS\\s+)?([^\\s(;]+)/i,\n /^(INSERT\\s+INTO)\\s+([^\\s(]+)/i,\n /^(COMMENT\\s+ON\\s+(?:TABLE|COLUMN|INDEX|FUNCTION|TYPE))\\s+([^\\s]+)/i,\n /^(GRANT|REVOKE)\\s+.+\\s+ON\\s+([^\\s]+)/i,\n ];\n\n for (const pattern of patterns) {\n const match = firstLine.match(pattern);\n if (match) {\n return `${match[1]} ${match[2]}`.slice(0, DESCRIPTION_MAX_LENGTH);\n }\n }\n\n const truncated = firstLine.slice(0, FALLBACK_DESCRIPTION_LENGTH);\n const suffix = firstLine.length > FALLBACK_DESCRIPTION_LENGTH ? \"...\" : \"\";\n return truncated + suffix;\n }\n\n /**\n * Execute SQL statements individually with better error reporting\n */\n private async executeSqlStatements(\n sql: string,\n seedName: string,\n ): Promise<void> {\n const statements = this.splitSqlStatements(sql);\n const total = statements.length;\n\n console.log(` → ${total} statements to execute`);\n\n for (let i = 0; i < statements.length; i++) {\n const statement = statements[i];\n const description = this.getStatementDescription(statement);\n\n try {\n await this.adapter.query!(statement);\n const isInterval = (i + 1) % PROGRESS_LOG_INTERVAL === 0;\n const isLast = i === total - 1;\n const isSignificant = Boolean(description.match(/^(INSERT INTO)/i));\n if (isInterval || isLast || isSignificant) {\n console.log(` āœ“ [${i + 1}/${total}] ${description}`);\n }\n } catch (error) {\n console.log(` āœ— [${i + 1}/${total}] ${description}`);\n\n const rawMessage = (error as Error).message;\n const errorMessage = rawMessage\n .replace(/^SQL Error:\\s*/i, \"\")\n .replace(/^Failed to execute query:.*?-\\s*/i, \"\")\n .slice(0, ERROR_MESSAGE_MAX_LENGTH);\n\n throw new DatabaseError(\n `Seed \"${seedName}\" failed at statement ${i + 1}/${total}:\\n` +\n ` Statement: ${description}\\n` +\n ` Error: ${errorMessage}`,\n DATABASE_ERROR_CODES.QUERY_FAILED,\n { cause: error as Error },\n );\n }\n }\n }\n\n /**\n * Load SQL seed from file\n */\n private loadSqlSeed(seedFile: SeedFile): Seed {\n const sql = fs.readFileSync(seedFile.filePath, \"utf-8\");\n\n return {\n name: seedFile.name,\n run: async () => {\n if (typeof this.adapter.query === \"function\") {\n await this.executeSqlStatements(sql, seedFile.name);\n }\n },\n // SQL seeds don't have cleanup by default\n cleanup: undefined,\n };\n }\n\n /**\n * Load seed from file (supports .ts, .js, and .sql)\n */\n // eslint-disable-next-line complexity\n private async loadSeed(seedFile: SeedFile): Promise<Seed> {\n const ext = path.extname(seedFile.filePath);\n\n // Handle SQL seeds\n if (ext === \".sql\") {\n return this.loadSqlSeed(seedFile);\n }\n\n // Handle JS/TS seeds\n // Convert Windows paths to file:// URLs for ESM imports\n const importPath = seedFile.filePath.startsWith(\"/\")\n ? seedFile.filePath\n : new URL(`file:///${seedFile.filePath.replace(/\\\\/g, \"/\")}`).href;\n\n const seedModule = await import(importPath);\n return {\n name: seedFile.name,\n run:\n seedModule.run ??\n seedModule.default?.run ??\n seedModule.seed ??\n seedModule.default,\n cleanup: seedModule.cleanup ?? seedModule.default?.cleanup,\n };\n }\n\n /**\n * Get executed seeds from database\n */\n private async getExecutedSeeds(): Promise<SeedRecord[]> {\n try {\n if (typeof this.adapter.query === \"function\") {\n const result = await this.adapter.query<SeedRecord>(\n `SELECT * FROM ${this.tableName} ORDER BY run_at ASC`,\n );\n // Handle both array results and postgres-style { rows: [] } results\n return Array.isArray(result)\n ? result\n : (result as unknown as { rows: SeedRecord[] }).rows || [];\n }\n return [];\n } catch {\n // Table might not exist yet\n return [];\n }\n }\n\n /**\n * Record seed as executed\n */\n private async recordSeed(\n name: string,\n executionTime: number,\n filePath?: string,\n ): Promise<void> {\n if (typeof this.adapter.query === \"function\") {\n // Store relative path from seeds directory for portability\n const relativePath = filePath\n ? path.relative(this.seedsPath, filePath)\n : null;\n\n await this.adapter.query(\n `INSERT INTO ${this.tableName} (name, file_path, execution_time) VALUES ($1, $2, $3)\n ON CONFLICT (name) DO UPDATE SET run_at = CURRENT_TIMESTAMP, file_path = $2, execution_time = $3`,\n [name, relativePath, executionTime],\n );\n }\n }\n\n /**\n * Remove seed record (for reset)\n */\n private async unrecordSeed(name: string): Promise<void> {\n if (typeof this.adapter.query === \"function\") {\n await this.adapter.query(\n `DELETE FROM ${this.tableName} WHERE name = $1`,\n [name],\n );\n }\n }\n\n /**\n * Execute a seed function with optional transaction support\n */\n private async executeSeed(seed: Seed): Promise<void> {\n if (typeof this.adapter.transaction === \"function\") {\n const txResult = await this.adapter.transaction(async () => {\n await seed.run(this.adapter);\n });\n // Check transaction result - transaction() returns failure() instead of throwing\n if (!txResult.success) {\n throw (\n txResult.error ??\n new DatabaseError(\n `Seed ${seed.name} failed`,\n DATABASE_ERROR_CODES.QUERY_FAILED,\n )\n );\n }\n } else {\n await seed.run(this.adapter);\n }\n }\n\n /**\n * Check if a seed should be skipped and log if applicable\n */\n private shouldSkipSeed(\n seedFile: SeedFile,\n seedName: string | undefined,\n executedNames: Set<string>,\n ): boolean {\n if (seedName && seedFile.name !== seedName) return true;\n\n if (this.skipExisting && executedNames.has(seedFile.name)) {\n console.log(`[Seeds] Skipping ${seedFile.name} (already executed)`);\n return true;\n }\n\n return false;\n }\n\n /**\n * Run all seeds or a specific seed\n */\n async run(seedName?: string): Promise<DatabaseResult<number>> {\n try {\n await this.initialize();\n\n const allSeeds = await this.discoverSeeds();\n const executedSeeds = await this.getExecutedSeeds();\n const executedNames = new Set(executedSeeds.map((s) => s.name));\n\n let executed = 0;\n\n for (const seedFile of allSeeds) {\n if (this.shouldSkipSeed(seedFile, seedName, executedNames)) {\n continue;\n }\n\n console.log(`[Seeds] Running ${seedFile.name}...`);\n\n const seed = await this.loadSeed(seedFile);\n const startTime = Date.now();\n\n await this.executeSeed(seed);\n\n const executionTime = Date.now() - startTime;\n await this.recordSeed(seed.name, executionTime, seedFile.filePath);\n\n console.log(`[Seeds] Executed ${seed.name} in ${executionTime}ms`);\n executed++;\n\n if (seedName) break;\n }\n\n return success(executed);\n } catch (error) {\n return failure(\n new DatabaseError(\n `Seed execution failed: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.QUERY_FAILED,\n { cause: error as Error },\n ),\n );\n }\n }\n\n /**\n * Execute cleanup function with optional transaction support\n */\n private async executeCleanup(seed: Seed): Promise<void> {\n if (!seed.cleanup) return;\n\n if (typeof this.adapter.transaction === \"function\") {\n const txResult = await this.adapter.transaction(async () => {\n await seed.cleanup!(this.adapter);\n });\n // Check transaction result - transaction() returns failure() instead of throwing\n if (!txResult.success) {\n throw (\n txResult.error ??\n new DatabaseError(\n `Seed cleanup for ${seed.name} failed`,\n DATABASE_ERROR_CODES.QUERY_FAILED,\n )\n );\n }\n } else {\n await seed.cleanup(this.adapter);\n }\n }\n\n /**\n * Reset all seeds (run cleanup functions)\n */\n async reset(): Promise<DatabaseResult<number>> {\n try {\n const allSeeds = await this.discoverSeeds();\n let cleaned = 0;\n\n // Run cleanup in reverse order\n for (const seedFile of allSeeds.reverse()) {\n console.log(`[Seeds] Cleaning up ${seedFile.name}...`);\n\n const seed = await this.loadSeed(seedFile);\n\n if (!seed.cleanup) {\n console.warn(`[Seeds] No cleanup function for ${seed.name}`);\n continue;\n }\n\n const startTime = Date.now();\n await this.executeCleanup(seed);\n const executionTime = Date.now() - startTime;\n\n await this.unrecordSeed(seed.name);\n\n console.log(`[Seeds] Cleaned ${seed.name} in ${executionTime}ms`);\n cleaned++;\n }\n\n return success(cleaned);\n } catch (error) {\n return failure(\n new DatabaseError(\n `Seed cleanup failed: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.QUERY_FAILED,\n { cause: error as Error },\n ),\n );\n }\n }\n\n /**\n * Get seed execution status\n */\n async status(): Promise<\n DatabaseResult<{ executed: SeedRecord[]; pending: string[] }>\n > {\n try {\n await this.initialize();\n\n const allSeeds = await this.discoverSeeds();\n const executedSeeds = await this.getExecutedSeeds();\n const executedNames = new Set(executedSeeds.map((s) => s.name));\n\n const pending = allSeeds\n .filter((s) => !executedNames.has(s.name))\n .map((s) => s.name);\n\n return success({\n executed: executedSeeds,\n pending,\n });\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to get seed status: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.QUERY_FAILED,\n { cause: error as Error },\n ),\n );\n }\n }\n\n /**\n * Clear seed history (doesn't clean data, just removes tracking records)\n */\n async clearHistory(): Promise<DatabaseResult<void>> {\n try {\n if (typeof this.adapter.query === \"function\") {\n await this.adapter.query(`DELETE FROM ${this.tableName}`);\n }\n return success();\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to clear seed history: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.QUERY_FAILED,\n { cause: error as Error },\n ),\n );\n }\n }\n}\n","/**\n * @fileoverview Type Guard Utilities for @plyaz/db package\n *\n * This module provides type guard functions for runtime type checking throughout\n * the @plyaz/db package. These utilities replace direct typeof checks with\n * consistent, reusable type validation functions.\n *\n */\n\n/**\n * Type guard to check if a value is a string\n *\n * @param {unknown} value - The value to check\n * @returns {value is string} True if value is a string, false otherwise\n *\n * @example\n * ```typescript\n * import { isString } from '@plyaz/db/utils';\n *\n * if (isString(userInput)) {\n * // userInput is now typed as string\n * console.log(userInput.toLowerCase());\n * }\n * ```\n */\nexport function isString(value: unknown): value is string {\n return typeof value === \"string\";\n}\n\n/**\n * Type guard to check if a value is a non-empty string\n *\n * @param {unknown} value - The value to check\n * @returns {value is string} True if value is a non-empty string, false otherwise\n *\n * @example\n * ```typescript\n * import { isNonEmptyString } from '@plyaz/db/utils';\n *\n * if (isNonEmptyString(tableName)) {\n * // tableName is guaranteed to be a non-empty string\n * const query = `SELECT * FROM ${tableName}`;\n * }\n * ```\n */\nexport function isNonEmptyString(value: unknown): value is string {\n return isString(value) && value.length > 0;\n}\n\n/**\n * Type guard to check if a value is a number\n *\n * @param {unknown} value - The value to check\n * @returns {value is number} True if value is a number, false otherwise\n */\nexport function isNumber(value: unknown): value is number {\n return typeof value === \"number\";\n}\n\n/**\n * Type guard to check if a value is an object (not null, not array)\n *\n * @param {unknown} value - The value to check\n * @returns {value is object} True if value is an object, false otherwise\n */\nexport function isObject(value: unknown): value is object {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n","/**\n * @fileoverview DatabaseEventEmitter - Event management for database operations\n *\n * Provides a comprehensive event system for monitoring and reacting to database\n * operations. The DatabaseEventEmitter implements the Observer pattern to enable\n * decoupled monitoring of database activities, allowing multiple components to\n * subscribe to and react to various database events.\n *\n * **Application Flow Context:**\n * ```\n * Database Operations → DatabaseEventEmitter → Event Handlers\n * ↓ ↓ ↓\n * Query Execution → Event Emission → Logging\n * Transaction → Handler Dispatch → Monitoring\n * Health Changes → Error Handling → Alerting\n * ```\n *\n * **Supported Events:**\n * - **BeforeQuery**: Emitted before database queries\n * - **AfterQuery**: Emitted after successful queries\n * - **QueryError**: Emitted when queries fail\n * - **BeforeTransaction**: Emitted before transactions start\n * - **AfterTransaction**: Emitted after transactions complete\n * - **TransactionRollback**: Emitted when transactions rollback\n * - **HealthChange**: Emitted when database health status changes\n *\n * @example\n * ```typescript\n * // Event emitter setup\n * const eventEmitter = new DatabaseEventEmitter('drizzle');\n *\n * // Subscribe to query events\n * eventEmitter.on('BeforeQuery', (event) => {\n * console.log(`Executing ${event.operation} on ${event.table}`);\n * });\n *\n * eventEmitter.on('QueryError', (event) => {\n * console.error(`Query failed: ${event.error.message}`);\n * });\n *\n * // Emit events during database operations\n * eventEmitter.emitBeforeQuery('users', 'SELECT', { id: '123' });\n * ```\n *\n */\n\nimport type {\n AfterQueryEvent,\n AfterTransactionEvent,\n BeforeQueryEvent,\n BeforeTransactionEvent,\n DatabaseEvent,\n DatabaseOperationType,\n DBEventHandler,\n HealthChangeEvent,\n QueryErrorEvent,\n TransactionRollbackEvent,\n} from \"@plyaz/types\";\nimport type {\n EmitQueryErrorOptions,\n DatabaseExecutionContext,\n} from \"@plyaz/types/db\";\nimport { DATABASE_EVENT_TYPE } from \"@plyaz/types\";\nimport type { ADAPTERS } from \"@plyaz/types\";\nimport { logger } from \"@plyaz/logger\";\nimport { isString, isObject } from \"@utils/typeGuards\";\nimport { DatabaseError } from \"@plyaz/errors\";\nimport { DATABASE_ERROR_CODES } from \"@plyaz/types/errors\";\n\n/**\n * Event emitter for database events that implements the observer pattern.\n * This class manages event subscriptions and emissions for various database operations,\n * allowing decoupled monitoring of database activities.\n *\n * @class\n * @implements {DatabaseEventEmitter}\n */\nexport class DatabaseEventEmitter implements DatabaseEventEmitter {\n private readonly eventHandlers: Map<string, DBEventHandler<DatabaseEvent>[]> =\n new Map();\n\n constructor(private readonly adapter: ADAPTERS) {\n if (!adapter) {\n throw new DatabaseError(\n \"Database adapter is required for event emitter\",\n DATABASE_ERROR_CODES.CONFIG_REQUIRED,\n {\n context: { source: \"DatabaseEventEmitter.constructor\" },\n cause: new Error(\"Database adapter is required for event emitter\"),\n },\n );\n }\n }\n\n /**\n * Register an event handler for a specific event type\n */\n on<T extends DatabaseEvent>(\n eventType: T[\"type\"],\n handler: DBEventHandler<T>,\n ): void {\n try {\n if (!isString(eventType)) {\n throw new DatabaseError(\n \"Invalid event type\",\n DATABASE_ERROR_CODES.INVALID_PARAMETERS,\n {\n context: { source: \"on\" },\n cause: new Error(\"Invalid event type\"),\n },\n );\n }\n\n if (!handler || typeof handler !== \"function\") {\n throw new DatabaseError(\n \"Invalid event handler\",\n DATABASE_ERROR_CODES.INVALID_PARAMETERS,\n {\n context: { source: \"on\" },\n cause: new Error(\"Invalid event handler\"),\n },\n );\n }\n\n if (!this.eventHandlers.has(eventType)) {\n this.eventHandlers.set(eventType, []);\n }\n\n const handlers = this.eventHandlers.get(eventType);\n if (handlers) {\n handlers.push(handler as DBEventHandler<DatabaseEvent>);\n }\n } catch (error) {\n logger.error(\n `Failed to register event handler: ${(error as Error).message}`,\n );\n }\n }\n\n /**\n * Remove an event handler for a specific event type\n */\n off<T extends DatabaseEvent>(\n eventType: T[\"type\"],\n handler: DBEventHandler<T>,\n ): void {\n const handlers = this.eventHandlers.get(eventType);\n if (handlers) {\n const index = handlers.indexOf(handler as DBEventHandler<DatabaseEvent>);\n if (index !== -1) handlers.splice(index, 1);\n }\n }\n\n /**\n * Emit an event to all registered handlers\n */\n emit(event: DatabaseEvent): void {\n try {\n if (!isObject(event) || !event.type) {\n logger.error(\"Invalid event object\");\n return;\n }\n\n const handlers = this.eventHandlers.get(event.type as string);\n if (!handlers || handlers.length === 0) return;\n\n handlers.forEach((handler) => {\n try {\n const result = handler(event);\n if (result instanceof Promise) {\n result.catch((error) => {\n logger.error(\n `Async event handler error: ${(error as Error).message}`,\n );\n });\n }\n } catch (error) {\n logger.error(`Event handler error: ${(error as Error).message}`);\n }\n });\n } catch (error) {\n logger.error(`Failed to emit event: ${(error as Error).message}`);\n }\n }\n\n /**\n * Emit a before query event\n */\n emitBeforeQuery(\n table: string,\n operation: DatabaseOperationType,\n params?: Record<string, object>,\n context?: DatabaseExecutionContext,\n ): void {\n const event: BeforeQueryEvent = {\n type: DATABASE_EVENT_TYPE.BeforeQuery,\n timestamp: new Date(),\n adapter: this.adapter.toString(),\n table,\n operation,\n params,\n context,\n };\n this.emit(event);\n }\n\n /**\n * Emit an after query event\n */\n emitAfterQuery(\n table: string,\n operation: DatabaseOperationType,\n duration: number,\n affectedRows?: number,\n ): void {\n const event: AfterQueryEvent = {\n type: DATABASE_EVENT_TYPE.AfterQuery,\n timestamp: new Date(),\n adapter: this.adapter.toString(),\n table,\n operation,\n duration,\n affectedRows,\n };\n this.emit(event);\n }\n\n emitQueryError(options: EmitQueryErrorOptions): void {\n try {\n if (!isObject(options)) {\n logger.error(\"Invalid options for emitQueryError\");\n return;\n }\n\n const { table, operation, error, params, context } = options;\n\n if (!table || !operation || !error) {\n logger.error(\"Missing required fields for query error event\");\n return;\n }\n\n const event: QueryErrorEvent = {\n type: DATABASE_EVENT_TYPE.QueryError,\n timestamp: new Date(),\n adapter: this.adapter.toString(),\n table,\n operation,\n error,\n params,\n context,\n };\n\n this.emit(event);\n } catch (emitError) {\n logger.error(\n `Failed to emit query error event: ${(emitError as Error).message}`,\n );\n }\n }\n\n /**\n * Emit a before transaction event\n */\n emitBeforeTransaction(\n transactionId: string,\n context?: DatabaseExecutionContext,\n ): void {\n const event: BeforeTransactionEvent = {\n type: DATABASE_EVENT_TYPE.BeforeTransaction,\n timestamp: new Date(),\n adapter: this.adapter.toString(),\n transactionId,\n context,\n };\n this.emit(event);\n }\n\n /**\n * Emit an after transaction event\n */\n emitAfterTransaction(transactionId: string, duration: number): void {\n const event: AfterTransactionEvent = {\n type: DATABASE_EVENT_TYPE.AfterTransaction,\n timestamp: new Date(),\n adapter: this.adapter.toString(),\n transactionId,\n duration,\n };\n this.emit(event);\n }\n\n /**\n * Emit a transaction rollback event\n */\n emitTransactionRollback(transactionId: string, error?: Error): void {\n const event: TransactionRollbackEvent = {\n type: DATABASE_EVENT_TYPE.TransactionRollback,\n timestamp: new Date(),\n adapter: this.adapter.toString(),\n transactionId,\n error,\n };\n this.emit(event);\n }\n\n /**\n * Emit a health change event\n */\n emitHealthChange(\n previousStatus: boolean,\n currentStatus: boolean,\n details?: Record<string, string | number | boolean>,\n ): void {\n const event: HealthChangeEvent = {\n type: DATABASE_EVENT_TYPE.HealthChange,\n timestamp: new Date(),\n adapter: this.adapter.toString(),\n previousStatus,\n currentStatus,\n details,\n };\n this.emit(event as DatabaseEvent);\n }\n}\n","/**\n * @fileoverview Detail Normalization Utilities for @plyaz/db package\n *\n * This module provides utilities for normalizing various data types into consistent\n * string-based record formats. Used throughout the @plyaz/db package for standardizing\n * error details, health status information, and event metadata.\n *\n * Part of the @plyaz/db package - a TypeScript database abstraction layer with\n * support for multiple adapters (Drizzle, Supabase, SQL), extensions (audit, encryption,\n * soft delete), and advanced features (caching, read replicas, multi-tenancy).\n *\n */\n\nimport { isObject } from \"./typeGuards\";\n\n/**\n * Normalizes any input into a standardized Record<string, string> format\n *\n * Converts various data types into a consistent string-based record format\n * for use in error details, health status information, and event metadata.\n * Provides safe handling of different input types with fallback strategies.\n *\n * **Normalization Rules:**\n * - Objects: Converts all property values to strings while preserving keys\n * - Primitives: Wraps in { info: stringValue } format\n * - null/undefined: Returns undefined (no details)\n * - Arrays: Converts to { info: stringified array }\n * - Errors: Safely handles conversion failures\n *\n * **Used by:**\n * - HealthManager for health status details\n * - DatabaseEventEmitter for event metadata\n * - Error handling throughout adapter chain\n * - Audit logging for consistent detail formatting\n *\n * @param {unknown} details - Input details of any type to normalize\n * @returns {Record<string, string> | undefined} Normalized details as string record or undefined\n *\n * @example\n * ```typescript\n * import { normalizeDetails } from '@plyaz/db/utils';\n *\n * // Object normalization\n * const objDetails = normalizeDetails({\n * count: 42,\n * active: true,\n * name: 'test'\n * });\n * console.log(objDetails);\n * // { count: \"42\", active: \"true\", name: \"test\" }\n *\n * // Primitive normalization\n * const stringDetails = normalizeDetails(\"Connection timeout\");\n * console.log(stringDetails);\n * // { info: \"Connection timeout\" }\n *\n * // Number normalization\n * const numberDetails = normalizeDetails(404);\n * console.log(numberDetails);\n * // { info: \"404\" }\n *\n * // Null/undefined handling\n * const nullDetails = normalizeDetails(null);\n * console.log(nullDetails);\n * // undefined\n *\n * // Array normalization\n * const arrayDetails = normalizeDetails(['error1', 'error2']);\n * console.log(arrayDetails);\n * // { info: \"error1,error2\" }\n *\n * // Error object normalization\n * const errorDetails = normalizeDetails(new Error('Database error'));\n * console.log(errorDetails);\n * // { info: \"Error: Database error\" }\n * ```\n *\n * @example\n * ### Usage in Health Status\n * ```typescript\n * // In HealthManager.checkHealth()\n * const healthStatus = {\n * isHealthy: true,\n * responseTime: 150,\n * details: normalizeDetails({\n * adapter: 'drizzle',\n * connections: 5,\n * lastQuery: new Date()\n * })\n * };\n * // details: { adapter: \"drizzle\", connections: \"5\", lastQuery: \"2024-01-01T10:00:00.000Z\" }\n * ```\n *\n * @example\n * ### Usage in Error Handling\n * ```typescript\n * // In adapter error handling\n * catch (error) {\n * return failure(new DatabaseError(\n * 'QUERY_FAILED',\n * HTTP_STATUS.INTERNAL_SERVER_ERROR,\n * 'Query execution failed',\n * normalizeDetails({\n * query: sql,\n * params: queryParams,\n * originalError: error.message\n * })\n * ));\n * }\n * ```\n *\n */\nexport function normalizeDetails(\n details: unknown,\n): Record<string, string> | undefined {\n try {\n // Handle null, undefined, or falsy values\n // Return undefined to indicate no details available\n if (!details) return undefined;\n\n // Handle object types (but not arrays)\n // Convert all object property values to strings while preserving keys\n if (isObject(details)) {\n const mapped: Record<string, string> = {};\n\n // Iterate through object entries and convert values to strings\n for (const [key, value] of Object.entries(details)) {\n // Use String() for safe conversion of any value type\n mapped[key] = String(value);\n }\n return mapped;\n }\n\n // Handle primitives, arrays, and other non-object types\n // Wrap in standardized { info: value } format\n return { info: String(details) };\n } catch (error) {\n // Fallback error handling for extreme cases\n // Return error information if normalization fails\n return {\n error: \"Failed to normalize details\",\n reason: (error as Error).message,\n };\n }\n}\n","/**\n * @fileoverview Health Manager for @plyaz/db package\n *\n * This module provides the HealthManager class responsible for monitoring database\n * connection health, performing periodic health checks, and managing the lifecycle\n * of database connections. It provides a centralized way to track database status.\n *\n * Part of the @plyaz/db package - a TypeScript database abstraction layer with\n * support for multiple adapters (Drizzle, Supabase, SQL), extensions (audit, encryption,\n * soft delete), and advanced features (caching, read replicas, multi-tenancy).\n *\n */\n\nimport type {\n DatabaseAdapterType,\n DatabaseHealthStatus,\n DatabaseResult,\n HealthManagerConfig,\n} from \"@plyaz/types/db\";\nimport { success, failure } from \"@utils/databaseResultHelpers\";\nimport { normalizeDetails } from \"@utils/normalizeDetails\";\nimport { DatabaseError } from \"@plyaz/errors\";\nimport { DATABASE_ERROR_CODES } from \"@plyaz/types/errors\";\n\n/** Default number of consecutive failures before triggering failover */\nconst DEFAULT_FAILOVER_THRESHOLD = 3;\n\n/**\n * šŸŒ”ļø HEALTH MANAGER - Database Health Monitoring\n *\n * Manages database health checks and monitoring functionality for all database adapters.\n * This class is responsible for performing health checks on the database connection,\n * storing the last known health status, and providing methods to quickly check\n * the current health state of the database.\n *\n * **Application Flow Position:**\n * DatabaseService → **HealthManager** → Adapter.healthCheck() → Database\n *\n * **What this class does:**\n * 1. Initializes database connections on startup\n * 2. Performs periodic health checks via adapter.healthCheck()\n * 3. Caches last known health status for quick access\n * 4. Normalizes health details across different adapters\n * 5. Manages connection lifecycle (connect/disconnect)\n *\n * **Called by:** DatabaseService.healthCheck(), application health endpoints\n * **Calls:** DatabaseAdapter.healthCheck(), DatabaseAdapter.connect/disconnect\n * **Used for:** Application health monitoring, load balancer health checks\n *\n * @example\n * ```typescript\n * // Create health manager with adapter\n * const healthManager = new HealthManager(drizzleAdapter);\n *\n * // Initialize connection and perform initial health check\n * await healthManager.init();\n *\n * // Perform health check\n * const healthResult = await healthManager.checkHealth();\n * if (healthResult.success) {\n * console.log('Database is healthy:', healthResult.value);\n * }\n *\n * // Quick health status check (uses cached result)\n * const isHealthy = healthManager.isHealthy();\n *\n * // Get last known status without new check\n * const lastStatus = healthManager.getLastHealthStatus();\n *\n * // Cleanup on shutdown\n * await healthManager.shutdown();\n * ```\n *\n */\nexport class HealthManager {\n private lastHealthStatus: DatabaseHealthStatus | null = null;\n private initialized = false;\n private currentAdapter: DatabaseAdapterType;\n private primaryAdapter: DatabaseAdapterType;\n private backupAdapters: DatabaseAdapterType[];\n private consecutiveFailures = 0;\n private healthCheckInterval?: number;\n private failoverThreshold: number;\n private autoFailover: boolean;\n private healthCheckTimer?: globalThis.NodeJS.Timeout;\n\n constructor(config: DatabaseAdapterType | HealthManagerConfig) {\n // Support both old (single adapter) and new (config) constructors\n if (\"primary\" in config) {\n this.primaryAdapter = config.primary;\n this.currentAdapter = config.primary;\n this.backupAdapters = config.backups ?? [];\n this.healthCheckInterval = config.healthCheckInterval;\n this.failoverThreshold =\n config.failoverThreshold ?? DEFAULT_FAILOVER_THRESHOLD;\n this.autoFailover = config.autoFailover ?? false;\n } else {\n this.primaryAdapter = config;\n this.currentAdapter = config;\n this.backupAdapters = [];\n this.failoverThreshold = DEFAULT_FAILOVER_THRESHOLD;\n this.autoFailover = false;\n }\n }\n\n /**\n * Initializes the health manager by establishing database connection and performing initial health check\n *\n * Sets up the database connection and performs an initial health check to establish\n * baseline health status. This method should be called during application startup\n * to ensure the database is ready for operations.\n *\n * **Initialization Process:**\n * 1. Checks if already initialized (prevents double initialization)\n * 2. Calls adapter.connect() if available (establishes connection)\n * 3. Performs initial health check via checkHealth()\n * 4. Sets initialized flag to prevent re-initialization\n *\n * @returns {Promise<void>} Promise that resolves when initialization is complete\n *\n * @example\n * ```typescript\n * const healthManager = new HealthManager(adapter);\n *\n * // Initialize during application startup\n * await healthManager.init();\n * console.log('Health manager initialized');\n *\n * // Subsequent calls are no-ops\n * await healthManager.init(); // Does nothing, already initialized\n * ```\n *\n */\n async init(): Promise<void> {\n // Prevent double initialization\n if (this.initialized) return;\n\n // Establish database connection if adapter supports it\n if (typeof this.currentAdapter.initialize === \"function\") {\n await this.currentAdapter.initialize();\n }\n\n // Perform initial health check to establish baseline status\n await this.checkHealth();\n this.initialized = true;\n\n // Start periodic health checks if configured\n if (this.healthCheckInterval && this.healthCheckInterval > 0) {\n this.startPeriodicHealthChecks();\n }\n }\n\n /**\n * Performs a comprehensive health check on the database connection\n *\n * Executes a health check via the database adapter and normalizes the results\n * into a standardized health status format. Measures response time and handles\n * both successful and failed health checks gracefully.\n *\n * **Health Check Process:**\n * 1. Records start time for response time measurement\n * 2. Calls adapter.healthCheck() to test database connectivity\n * 3. Normalizes adapter-specific response into standard format\n * 4. Caches result as lastHealthStatus for quick access\n * 5. Returns standardized DatabaseResult with health information\n *\n * **Health Status Fields:**\n * - isHealthy: Boolean indicating if database is operational\n * - responseTime: Time in milliseconds for health check to complete\n * - details: Normalized adapter-specific details (connection info, errors, etc.)\n *\n * @returns {Promise<DatabaseResult<DatabaseHealthStatus>>} Promise resolving to health status result\n *\n * @example\n * ```typescript\n * // Perform health check\n * const healthResult = await healthManager.checkHealth();\n *\n * if (healthResult.success) {\n * const status = healthResult.value;\n * console.log(`Database healthy: ${status.isHealthy}`);\n * console.log(`Response time: ${status.responseTime}ms`);\n * console.log('Details:', status.details);\n * } else {\n * console.error('Health check failed:', healthResult.error.message);\n * }\n *\n * // Example healthy response:\n * // {\n * // success: true,\n * // value: {\n * // isHealthy: true,\n * // responseTime: 45,\n * // details: { adapter: \"drizzle\", connections: \"5\" }\n * // }\n * // }\n *\n * // Example unhealthy response:\n * // {\n * // success: true,\n * // value: {\n * // isHealthy: false,\n * // responseTime: 5000,\n * // details: { error: \"Connection timeout\" }\n * // }\n * // }\n * ```\n *\n */\n /**\n * Handle health check result and update internal state\n */\n private async handleHealthResult(isSuccess: boolean): Promise<void> {\n if (isSuccess) {\n this.consecutiveFailures = 0;\n return;\n }\n\n this.consecutiveFailures++;\n if (\n this.autoFailover &&\n this.consecutiveFailures >= this.failoverThreshold\n ) {\n await this.performFailover();\n }\n }\n\n /**\n * Create health status from check result\n */\n private createHealthStatus(\n result: DatabaseResult<DatabaseHealthStatus>,\n responseTime: number,\n ): DatabaseHealthStatus {\n return {\n isHealthy: result.success,\n responseTime,\n details: result.success\n ? normalizeDetails(result.value)\n : { error: result.error?.message ?? \"Unknown error\" },\n };\n }\n\n async checkHealth(): Promise<DatabaseResult<DatabaseHealthStatus>> {\n const startTime = Date.now();\n\n try {\n const result = await this.currentAdapter.healthCheck();\n const responseTime = Date.now() - startTime;\n\n const status = this.createHealthStatus(result, responseTime);\n this.lastHealthStatus = status;\n\n await this.handleHealthResult(result.success);\n\n return success(status);\n } catch (error) {\n const status: DatabaseHealthStatus = {\n isHealthy: false,\n responseTime: Date.now() - startTime,\n details: { error: (error as Error).message },\n };\n\n this.lastHealthStatus = status;\n await this.handleHealthResult(false);\n\n return failure(\n new DatabaseError(\n `Health check failed: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.FETCH_FAILED,\n {\n context: { source: \"checkHealth\" },\n cause: error as Error,\n },\n ),\n );\n }\n }\n /**\n * Get the last known health status\n */\n getLastHealthStatus(): DatabaseHealthStatus | null {\n return this.lastHealthStatus;\n }\n\n /**\n * Check if the database is currently healthy\n */\n isHealthy(): boolean {\n return this.lastHealthStatus?.isHealthy ?? false;\n }\n\n /**\n * Get the current active adapter\n */\n getCurrentAdapter(): DatabaseAdapterType {\n return this.currentAdapter;\n }\n\n /**\n * Try to initialize and verify health of a backup adapter\n */\n private async tryBackupAdapter(\n backup: DatabaseAdapterType,\n ): Promise<boolean> {\n if (typeof backup.initialize === \"function\") {\n const initResult = await backup.initialize();\n if (!initResult.success) return false;\n }\n\n const healthResult = await backup.healthCheck();\n return healthResult.success && (healthResult.value?.isHealthy ?? false);\n }\n\n /**\n * Switch to a healthy backup adapter\n */\n private async switchToBackup(backup: DatabaseAdapterType): Promise<void> {\n await this.currentAdapter.close();\n this.currentAdapter = backup;\n this.consecutiveFailures = 0;\n console.log(\"[HealthManager] Failover successful to backup adapter\");\n }\n\n /**\n * Perform failover to next available backup adapter\n */\n private async performFailover(): Promise<void> {\n if (this.backupAdapters.length === 0) {\n console.warn(\"[HealthManager] No backup adapters available for failover\");\n return;\n }\n\n for (const backup of this.backupAdapters) {\n try {\n const isHealthy = await this.tryBackupAdapter(backup);\n if (isHealthy) {\n await this.switchToBackup(backup);\n return;\n }\n } catch (error) {\n console.error(\n \"[HealthManager] Backup adapter health check failed:\",\n error,\n );\n }\n }\n\n console.error(\n \"[HealthManager] All backup adapters failed, staying with current adapter\",\n );\n }\n\n /**\n * Start periodic health checks\n */\n private startPeriodicHealthChecks(): void {\n if (this.healthCheckTimer) return;\n\n this.healthCheckTimer = setInterval(async () => {\n await this.checkHealth();\n }, this.healthCheckInterval);\n }\n\n /**\n * Stop periodic health checks\n */\n private stopPeriodicHealthChecks(): void {\n if (this.healthCheckTimer) {\n clearInterval(this.healthCheckTimer);\n this.healthCheckTimer = undefined;\n }\n }\n\n /**\n * Gracefully shut down the health manager\n */\n async shutdown(): Promise<void> {\n this.stopPeriodicHealthChecks();\n\n await this.currentAdapter.close();\n\n this.initialized = false;\n this.lastHealthStatus = null;\n }\n}\n","/**\n * @fileoverview Configuration Merger for @plyaz/db package\n *\n * This module provides the ConfigMerger utility class responsible for deep merging\n * database configurations. It handles merging global database service configuration\n * with per-operation overrides to create resolved configurations for the adapter chain.\n *\n * Part of the @plyaz/db package - a TypeScript database abstraction layer with\n * support for multiple adapters (Drizzle, Supabase, SQL), extensions (audit, encryption,\n * soft delete), and advanced features (caching, read replicas, multi-tenancy).\n */\n\nimport { NUMERIX } from \"@plyaz/config\";\nimport type {\n DatabaseServiceConfig,\n DBCacheConfig,\n DBEncryptionConfig,\n OperationConfig,\n ResolvedOperationConfig,\n SoftDeleteConfig,\n TimestampsConfig,\n} from \"@plyaz/types/db\";\n\n/**\n * CONFIG MERGER - Configuration Resolution Engine\n *\n * Utility class for deep merging database configurations.\n * Handles merging global database service configuration with per-operation overrides\n *\n * Application Flow Position:**\n * DatabaseService → **ConfigMerger** → Resolved Config → Adapter Chain\n *\n * **What this class does:**\n * 1. Receives global config (from createDatabaseService) and operation config (from method calls)\n * 2. Deep merges nested objects (encryption, softDelete, cache, etc.)\n * 3. Operation config takes precedence over global config\n * 4. Returns resolved configuration for adapter chain\n *\n * **Called by:** DatabaseService methods (get, create, update, delete, etc.)\n * **Calls:** Internal merge methods for each config section\n * **Returns to:** DatabaseService for delegation to adapter chain\n *\n * **Merge Strategy:**\n * - Operation config overrides global config\n * - Nested objects are deep merged (not replaced)\n * - Arrays use replace strategy for fields, concat for others\n * - Undefined values in operation config fall back to global defaults\n *\n * @example\n * ### Configuration Merging Flow\n * ```typescript\n * // Global config (from createDatabaseService)\n * const globalConfig = {\n * softDelete: { enabled: true, field: 'deletedAt' },\n * cache: { enabled: true, ttl: 300 }\n * };\n *\n * // Operation config (from method call)\n * const operationConfig = {\n * cache: { enabled: false },\n * includeSoftDeleted: true\n * };\n *\n * // ConfigMerger.mergeConfigs() produces:\n * const resolved = {\n * softDelete: { enabled: true, field: 'deletedAt' }, // From global\n * cache: { enabled: false, ttl: 300 }, // Merged\n * includeSoftDeleted: true, // From operation\n * skipAudit: false // Default\n * };\n * ```\n */\nexport class ConfigMerger {\n /**\n * Merges global database configuration with operation-specific overrides\n *\n * This is the main entry point for configuration resolution in the DatabaseService.\n * It performs deep merging of nested configuration objects while preserving type safety\n * and applying proper precedence rules.\n *\n * **Merge Precedence (highest to lowest):**\n * 1. Operation-specific config (method-level overrides)\n * 2. Global service config (from createDatabaseService)\n * 3. Default values (built-in fallbacks)\n *\n * **Configuration Sections Merged:**\n * - softDelete: Logical deletion settings\n * - encryption: Field-level encryption settings\n * - cache: Caching behavior and TTL\n * - timestamps: Automatic timestamp management\n * - Operation flags: skipAudit, includeSoftDeleted, etc.\n *\n * @param {DatabaseServiceConfig} global - Global database service configuration from createDatabaseService()\n * @param {OperationConfig} [operation] - Optional operation-specific configuration overrides\n * @returns {ResolvedOperationConfig} Fully resolved configuration with all defaults applied\n *\n * @example\n * ```typescript\n * // In DatabaseService.get() method\n * const resolvedConfig = ConfigMerger.mergeConfigs(\n * this.globalConfig, // From createDatabaseService\n * operationConfig // From method parameter\n * );\n *\n * // Example global config\n * const globalConfig = {\n * softDelete: { enabled: true, field: 'deletedAt' },\n * encryption: { enabled: true, fields: { users: ['ssn'] } },\n * cache: { enabled: true, ttl: 300 }\n * };\n *\n * // Example operation config (disable cache for this operation)\n * const operationConfig = {\n * cache: { enabled: false },\n * skipAudit: true\n * };\n *\n * // Resulting merged config\n * const result = {\n * softDelete: { enabled: true, field: 'deletedAt' }, // From global\n * encryption: { enabled: true, fields: { users: ['ssn'] } }, // From global\n * cache: { enabled: false, ttl: 300 }, // Merged (enabled overridden)\n * timestamps: undefined, // Not specified\n * skipAudit: true, // From operation\n * includeSoftDeleted: false, // Default\n * forceAdapter: undefined, // Not specified\n * timeout: 30000 // Default\n * };\n * ```\n *\n */\n static mergeConfigs(\n global: DatabaseServiceConfig,\n operation?: OperationConfig,\n ): ResolvedOperationConfig {\n if (!operation) {\n return this.convertGlobalToResolved(global);\n }\n\n return {\n softDelete: this.mergeSoftDeleteConfig(\n global.softDelete,\n operation.softDelete,\n ),\n encryption: this.mergeEncryptionConfig(\n global.encryption,\n operation.encryption,\n ),\n cache: this.mergeCacheConfig(global.cache, operation.cache),\n timestamps: this.mergeTimestampsConfig(\n global.timestamps,\n operation.timestamps,\n ),\n skipAudit: operation.skipAudit ?? false,\n includeSoftDeleted: operation.includeSoftDeleted ?? false,\n forceAdapter: operation.forceAdapter,\n timeout: operation.timeout ?? NUMERIX.THIRTY_THOUSAND,\n };\n }\n\n /**\n * Merges soft delete configuration with operation-specific overrides\n *\n * Handles deep merging of soft delete settings, allowing operation-level\n * overrides while preserving base configuration values.\n *\n * @private\n * @param {SoftDeleteConfig} [base] - Base soft delete configuration from global config\n * @param {Partial<SoftDeleteConfig>} [override] - Operation-specific soft delete overrides\n * @returns {SoftDeleteConfig | undefined} Merged soft delete configuration or undefined if neither provided\n *\n * @example\n * ```typescript\n * // Base config: { enabled: true, field: 'deletedAt', excludeTables: ['logs'] }\n * // Override: { enabled: false }\n * // Result: { enabled: false, field: 'deletedAt', excludeTables: ['logs'] }\n * ```\n *\n */\n private static mergeSoftDeleteConfig(\n base?: SoftDeleteConfig,\n override?: Partial<SoftDeleteConfig>,\n ): SoftDeleteConfig | undefined {\n // Return undefined if neither base nor override provided\n if (!base && !override) return undefined;\n // Return base config if no override provided\n if (!override) return base;\n // Return override as complete config if no base provided\n if (!base) return override as SoftDeleteConfig;\n\n // Deep merge: override takes precedence, base provides fallbacks\n return {\n enabled: override.enabled ?? base.enabled,\n field: override.field ?? base.field,\n excludeTables: override.excludeTables ?? base.excludeTables,\n };\n }\n\n /**\n * Merges encryption configuration with operation-specific overrides\n *\n * Handles deep merging of field-level encryption settings, allowing operation-level\n * overrides for encryption behavior while preserving base configuration.\n *\n * @private\n * @param {DBEncryptionConfig} [base] - Base encryption configuration from global config\n * @param {Partial<DBEncryptionConfig>} [override] - Operation-specific encryption overrides\n * @returns {DBEncryptionConfig | undefined} Merged encryption configuration or undefined if neither provided\n *\n * @example\n * ```typescript\n * // Base config: { enabled: true, key: 'base64key', fields: { users: ['ssn'] } }\n * // Override: { enabled: false }\n * // Result: { enabled: false, key: 'base64key', fields: { users: ['ssn'] } }\n * ```\n *\n */\n // eslint-disable-next-line complexity\n private static mergeEncryptionConfig(\n base?: DBEncryptionConfig,\n override?: Partial<DBEncryptionConfig>,\n ): DBEncryptionConfig | undefined {\n // Return undefined if neither base nor override provided\n if (!base && !override) return undefined;\n // Return base config if no override provided\n if (!override) return base;\n // Return override as complete config if no base provided\n if (!base) return override as DBEncryptionConfig;\n\n // Deep merge: override takes precedence, base provides fallbacks\n return {\n enabled: override.enabled ?? base.enabled,\n key: override.key ?? base.key,\n fields: override.fields ?? base.fields,\n algorithm: override.algorithm ?? base.algorithm,\n useDatabaseNative: override.useDatabaseNative ?? base.useDatabaseNative,\n };\n }\n\n /**\n * Merges cache configuration with operation-specific overrides\n * \n * Handles deep merging of caching settings, allowing operation-level\n * overrides for cache behavior (enable/disable, TTL changes, etc.).\n * \n * @private\n * @param {DBCacheConfig} [base] - Base cache configuration from global config\n * @param {Partial<DBCacheConfig>} [override] - Operation-specific cache overrides\n * @returns {DBCacheConfig | undefined} Merged cache configuration or undefined if neither provided\n * \n * @example\n * ```typescript\n * // Base config: { enabled: true, ttl: 300, provider: 'redis' }\n * // Override: { enabled: false }\n * // Result: { enabled: false, ttl: 300, provider: 'redis' }\n * ```\n * \n\n */\n // eslint-disable-next-line complexity\n private static mergeCacheConfig(\n base?: DBCacheConfig,\n override?: Partial<DBCacheConfig>,\n ): DBCacheConfig | undefined {\n // Return undefined if neither base nor override provided\n if (!base && !override) return undefined;\n // Return base config if no override provided\n if (!override) return base;\n // Return override as complete config if no base provided\n if (!base) return override as DBCacheConfig;\n\n // Deep merge: override takes precedence, base provides fallbacks\n return {\n enabled: override.enabled ?? base.enabled,\n ttl: override.ttl ?? base.ttl,\n provider: override.provider ?? base.provider,\n invalidation: override.invalidation ?? base.invalidation,\n };\n }\n\n /**\n * Merges timestamps configuration with operation-specific overrides\n *\n * Handles deep merging of automatic timestamp settings, allowing operation-level\n * overrides for timestamp field names and auto-update behavior.\n *\n * @private\n * @param {TimestampsConfig} [base] - Base timestamps configuration from global config\n * @param {Partial<TimestampsConfig>} [override] - Operation-specific timestamp overrides\n * @returns {TimestampsConfig | undefined} Merged timestamps configuration or undefined if neither provided\n *\n * @example\n * ```typescript\n * // Base config: { enabled: true, createdAtField: 'createdAt', updatedAtField: 'updatedAt' }\n * // Override: { autoUpdate: false }\n * // Result: { enabled: true, createdAtField: 'createdAt', updatedAtField: 'updatedAt', autoUpdate: false }\n * ```\n */\n // eslint-disable-next-line complexity\n private static mergeTimestampsConfig(\n base?: TimestampsConfig,\n override?: Partial<TimestampsConfig>,\n ): TimestampsConfig | undefined {\n // Return undefined if neither base nor override provided\n if (!base && !override) return undefined;\n // Return base config if no override provided\n if (!override) return base;\n // Return override as complete config if no base provided\n if (!base) return override as TimestampsConfig;\n\n // Deep merge: override takes precedence, base provides fallbacks\n return {\n enabled: override.enabled ?? base.enabled,\n createdAtField: override.createdAtField ?? base.createdAtField,\n updatedAtField: override.updatedAtField ?? base.updatedAtField,\n autoUpdate: override.autoUpdate ?? base.autoUpdate,\n };\n }\n\n /**\n * Converts global database service configuration to resolved operation configuration\n *\n * Used when no operation-specific overrides are provided. Applies default values\n * for operation-specific flags while preserving global configuration settings.\n *\n * @private\n * @param {DatabaseServiceConfig} global - Global database service configuration\n * @returns {ResolvedOperationConfig} Resolved configuration with defaults applied\n *\n * @example\n * ```typescript\n * // Global config: { softDelete: { enabled: true }, cache: { enabled: true, ttl: 300 } }\n * // Result: {\n * // softDelete: { enabled: true },\n * // cache: { enabled: true, ttl: 300 },\n * // skipAudit: false, // Default\n * // includeSoftDeleted: false, // Default\n * // timeout: 30000 // Default\n * // }\n * ```\n *\n */\n private static convertGlobalToResolved(\n global: DatabaseServiceConfig,\n ): ResolvedOperationConfig {\n return {\n // Preserve global configuration sections as-is\n softDelete: global?.softDelete,\n encryption: global?.encryption,\n cache: global?.cache,\n timestamps: global?.timestamps,\n // Apply default values for operation-specific flags\n skipAudit: false, // Default: enable audit logging\n includeSoftDeleted: false, // Default: exclude soft-deleted records\n timeout: NUMERIX.THIRTY_THOUSAND, // Default: 30 second timeout\n };\n }\n}\n","/**\n * @fileoverview Internal Database Service Implementation for @plyaz/db package\n *\n * This module provides the internal DatabaseService class that orchestrates all database\n * operations. It is NOT exported and is created internally by the createDatabaseService() factory.\n *\n * Part of the @plyaz/db package - a TypeScript database abstraction layer with\n * support for multiple adapters (Drizzle, Supabase, SQL), extensions (audit, encryption,\n * soft delete), and advanced features (caching, read replicas, multi-tenancy).\n *\n */\n\nimport { DatabaseEventEmitter } from \"./EventEmitter\";\nimport { HealthManager } from \"./HealthManager\";\nimport { ConfigMerger } from \"@utils/ConfigMerger\";\nimport { DatabaseError } from \"@plyaz/errors\";\nimport { DATABASE_ERROR_CODES } from \"@plyaz/types/errors\";\nimport type {\n AuditContext,\n BatchUpdate,\n CreateInput,\n DatabaseAdapterType,\n DatabaseEvent,\n DatabaseEvents,\n DatabaseHealthStatus,\n DatabaseResult,\n DatabaseServiceConfig,\n DatabaseServiceInterface,\n Filter,\n OperationConfig,\n PaginatedResult,\n QueryOptions,\n ServiceStatus,\n TableName,\n TransactionFn,\n UpdateInput,\n} from \"@plyaz/types/db\";\nimport { ADAPTERS } from \"@plyaz/types/db\";\nimport { failure, success } from \"@utils/databaseResultHelpers\";\n\n/**\n * šŸ› ļø DATABASE SERVICE - Internal Service Layer\n *\n * Core service implementation that orchestrates all database operations.\n * NOT EXPORTED - created internally by createDatabaseService() factory.\n *\n * **Application Flow Position:**\n * createDatabaseService() → **DatabaseService** → Adapter Chain → Database\n *\n * **What this class does:**\n * 1. Stores global configuration from createDatabaseService()\n * 2. Receives calls from repositories via IDatabaseService interface\n * 3. Merges per-operation config with global config using ConfigMerger\n * 4. Fires before/after events (onBeforeWrite, onAfterWrite, etc.)\n * 5. Delegates to adapter chain with resolved configuration\n * 6. Returns results back to repositories\n *\n * **Called by:** Repository layer (BaseRepository, UserRepository, etc.)\n * **Calls:** ConfigMerger.mergeConfigs(), adapter chain methods, event handlers\n * **Delegates to:** Final wrapped adapter (ReadReplicaAdapter → AuditAdapter → ... → BaseAdapter)\n *\n * **Key Responsibilities:**\n * - Configuration merging and resolution\n * - Event system orchestration\n * - Audit context management\n * - Error handling and propagation\n * - Service status tracking\n *\n * @internal This class is not part of the public API\n */\nexport class DatabaseService implements DatabaseServiceInterface {\n private readonly globalConfig: DatabaseServiceConfig;\n public readonly adapter: DatabaseAdapterType;\n private readonly eventHandlers: DatabaseEvents | undefined;\n private readonly eventEmitter: DatabaseEventEmitter;\n private readonly healthManager: HealthManager;\n private readonly startTime: Date;\n private auditContext: AuditContext = {};\n\n constructor(config: {\n adapter: DatabaseAdapterType;\n globalConfig: DatabaseServiceConfig;\n eventHandlers?: DatabaseEvents;\n }) {\n this.globalConfig = config.globalConfig;\n this.adapter = config.adapter;\n this.eventHandlers = config.eventHandlers;\n this.startTime = new Date();\n\n const adapterType =\n (config.adapter?.constructor?.name?.toLowerCase() as ADAPTERS) ??\n ADAPTERS.SQL;\n this.eventEmitter = new DatabaseEventEmitter(adapterType);\n this.healthManager = new HealthManager(config.adapter);\n\n console.log(`DatabaseService initialized with ${adapterType} adapter`);\n }\n\n /**\n * šŸ”§ Prepare table name and configuration for operation\n *\n * Handles per-operation overrides for:\n * 1. Schema - prepends schema to table name (e.g., \"audit.logs\")\n * 2. ID Column - temporarily registers table with custom ID column\n *\n * Priority order:\n * - Operation config (highest) - per-query override\n * - TABLE_REGISTRY - global registration\n * - Default (lowest) - 'id' column, 'public' schema\n *\n * @param table Base table name\n * @param operationConfig Optional operation configuration with idColumn/schema\n * @returns Final table name to use (with schema prefix if applicable)\n *\n * @example\n * ```typescript\n * // With schema override\n * const tableName = this.prepareTable('logs', { schema: 'audit' });\n * // Returns: 'audit.logs'\n *\n * // With ID column override\n * const tableName = this.prepareTable('feature_flags', { idColumn: 'key' });\n * // Registers table with 'key' as ID column, returns: 'feature_flags'\n *\n * // With both\n * const tableName = this.prepareTable('users', { schema: 'backoffice', idColumn: 'user_id' });\n * // Returns: 'backoffice.users' with 'user_id' as ID column\n * ```\n */\n private prepareTable(\n table: TableName,\n operationConfig?: OperationConfig,\n ): string {\n let finalTableName = table;\n\n // Handle schema override\n if (operationConfig?.schema) {\n // If table already has schema prefix, replace it\n const tableWithoutSchema = table.includes(\".\")\n ? table.split(\".\")[1]\n : table;\n finalTableName = `${operationConfig.schema}.${tableWithoutSchema}`;\n }\n\n // Handle custom ID column override\n if (operationConfig?.idColumn) {\n // Temporarily register the table with the custom ID column\n // This allows the adapter to use the correct ID column for this operation\n this.adapter.registerTable(\n finalTableName,\n finalTableName,\n operationConfig.idColumn,\n );\n }\n\n return finalTableName;\n }\n\n /**\n * šŸ” Get a single record by ID\n *\n * **Flow:** Repository.findById() → **DatabaseService.get()** → ConfigMerger → Adapter Chain → Database\n *\n * **What happens:**\n * 1. Merges operation config with global config using ConfigMerger\n * 2. Fires onBeforeRead event (if configured)\n * 3. Delegates to adapter chain: ReadReplica → Audit → Cache → SoftDelete → Encryption → Base\n * 4. Fires onAfterRead event on success\n * 5. Returns result to repository\n *\n * **Called by:** BaseRepository.findById(), custom repository methods\n * **Calls:** ConfigMerger.mergeConfigs(), this.adapter.findById(), event handlers\n *\n * @param table Table name (from Tables enum)\n * @param id Record ID to retrieve\n * @param operationConfig Optional per-operation configuration overrides\n * @returns Promise resolving to the record or null if not found\n *\n * @example\n * ```typescript\n * // Called by UserRepository.findById()\n * const user = await this.db.get(Tables.USERS, 'user-123');\n *\n * // With operation config override\n * const user = await this.db.get(Tables.USERS, 'user-123', {\n * forceAdapter: 'primary', // Force primary DB\n * cache: { enabled: false } // Skip cache\n * });\n *\n * // With custom ID column (per-query override)\n * const flag = await this.db.get('feature_flags', 'my-flag-key', {\n * idColumn: 'key' // Use 'key' instead of 'id' as primary key\n * });\n *\n * // With custom schema\n * const auditLog = await this.db.get('logs', '123', {\n * schema: 'audit' // Query from audit.logs table\n * });\n *\n * // Combining multiple overrides\n * const backofficeUser = await this.db.get('users', 'admin-456', {\n * schema: 'backoffice',\n * idColumn: 'user_id',\n * forceAdapter: 'primary'\n * });\n * ```\n */\n async get<T extends Record<string, unknown>>(\n table: TableName,\n id: string,\n operationConfig?: OperationConfig,\n ): Promise<DatabaseResult<T | null>> {\n // Merge configs - operation config takes precedence\n ConfigMerger.mergeConfigs(this.globalConfig, operationConfig);\n\n // Prepare table with schema and ID column overrides\n const finalTable = this.prepareTable(table, operationConfig);\n\n try {\n // Fire before-read event if configured\n if (this.eventHandlers?.onBeforeRead) {\n await this.eventHandlers.onBeforeRead({\n type: \"beforeRead\",\n operation: \"READ\",\n table,\n timestamp: new Date(),\n });\n }\n\n // Delegate to adapter with resolved config\n const result = await this.adapter.findById<T>(finalTable, id);\n\n // Fire after-read event if configured and successful\n if (result.success && this.eventHandlers?.onAfterRead) {\n await this.eventHandlers.onAfterRead({\n type: \"afterRead\",\n operation: \"READ\",\n table,\n result: (result.value ?? {}) as Record<\n string,\n string | number | boolean | Date\n >,\n duration: 0, // TODO: Track duration\n timestamp: new Date(),\n });\n }\n\n return result;\n } catch (error) {\n return failure(\n new DatabaseError(\n `Get operation failed: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.QUERY_FAILED,\n {\n context: { source: \"get\" },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * List records with optional filtering, sorting, and pagination\n * Merges operation config with global config before delegating\n */\n async list<T extends Record<string, unknown>>(\n table: TableName,\n options?: QueryOptions<T>,\n operationConfig?: OperationConfig,\n ): Promise<DatabaseResult<PaginatedResult<T>>> {\n ConfigMerger.mergeConfigs(this.globalConfig, operationConfig);\n\n if (this.eventHandlers?.onBeforeRead) {\n await this.eventHandlers.onBeforeRead({\n type: \"beforeRead\",\n operation: \"READ\",\n table,\n timestamp: new Date(),\n });\n }\n\n const result = await this.adapter.findMany<T>(table, options);\n\n if (result.success && this.eventHandlers?.onAfterRead) {\n await this.eventHandlers.onAfterRead({\n type: \"afterRead\",\n operation: \"READ\",\n table,\n result: (result.value ?? {}) as Record<\n string,\n string | number | boolean | Date\n >,\n duration: 0,\n timestamp: new Date(),\n });\n }\n\n return result;\n }\n\n /**\n * Create a new record\n * Merges operation config with global config before delegating\n */\n async create<T extends Record<string, unknown>>(\n table: TableName,\n input: CreateInput<T>,\n operationConfig?: OperationConfig,\n ): Promise<DatabaseResult<T>> {\n ConfigMerger.mergeConfigs(this.globalConfig, operationConfig);\n\n // Prepare table with schema and ID column overrides\n const finalTable = this.prepareTable(table, operationConfig);\n\n if (this.eventHandlers?.onBeforeWrite) {\n await this.eventHandlers.onBeforeWrite({\n type: \"beforeWrite\",\n operation: \"CREATE\",\n table,\n data: input as Record<string, string | number | boolean | Date>,\n timestamp: new Date(),\n });\n }\n\n const result = await this.adapter.create<T>(finalTable, input as T);\n\n if (result.success && this.eventHandlers?.onAfterWrite) {\n await this.eventHandlers.onAfterWrite({\n type: \"afterWrite\",\n operation: \"CREATE\",\n table,\n result: result.value as Record<\n string,\n string | number | boolean | Date\n >,\n duration: 0,\n timestamp: new Date(),\n });\n }\n\n return result;\n }\n\n /**\n * Update an existing record\n * Merges operation config with global config before delegating\n */\n async update<T extends Record<string, unknown>>(\n table: TableName,\n id: string,\n input: UpdateInput<T>,\n operationConfig?: OperationConfig,\n ): Promise<DatabaseResult<T>> {\n ConfigMerger.mergeConfigs(this.globalConfig, operationConfig);\n\n // Prepare table with schema and ID column overrides\n const finalTable = this.prepareTable(table, operationConfig);\n\n if (this.eventHandlers?.onBeforeWrite) {\n await this.eventHandlers.onBeforeWrite({\n type: \"beforeWrite\",\n operation: \"UPDATE\",\n table,\n data: input as Record<string, string | number | boolean | Date>,\n timestamp: new Date(),\n });\n }\n\n const result = await this.adapter.update<T>(\n finalTable,\n id,\n input as Partial<T>,\n );\n\n if (result.success && this.eventHandlers?.onAfterWrite) {\n await this.eventHandlers.onAfterWrite({\n type: \"afterWrite\",\n operation: \"UPDATE\",\n table,\n result: result.value as Record<\n string,\n string | number | boolean | Date\n >,\n duration: 0,\n timestamp: new Date(),\n });\n }\n\n return result;\n }\n\n /**\n * Delete a record\n * Merges operation config with global config before delegating\n */\n async delete(\n table: TableName,\n id: string,\n operationConfig?: OperationConfig,\n ): Promise<DatabaseResult<void>> {\n ConfigMerger.mergeConfigs(this.globalConfig, operationConfig);\n\n // Prepare table with schema and ID column overrides\n const finalTable = this.prepareTable(table, operationConfig);\n\n if (this.eventHandlers?.onBeforeWrite) {\n await this.eventHandlers.onBeforeWrite({\n type: \"beforeWrite\",\n operation: \"DELETE\",\n table,\n data: { id },\n timestamp: new Date(),\n });\n }\n\n const result = await this.adapter.delete(finalTable, id);\n\n if (result.success && this.eventHandlers?.onAfterWrite) {\n await this.eventHandlers.onAfterWrite({\n type: \"afterWrite\",\n operation: \"DELETE\",\n table,\n result: {},\n duration: 0,\n timestamp: new Date(),\n });\n }\n\n return result;\n }\n\n // Batch Operations\n async batchCreate<T extends Record<string, unknown>>(\n table: TableName,\n inputs: CreateInput<T>[],\n operationConfig?: OperationConfig,\n ): Promise<DatabaseResult<T[]>> {\n // TODO: Implement batch operations\n const results: T[] = [];\n for (const input of inputs) {\n const result = await this.create<T>(table, input, operationConfig);\n if (result.success && result.value) {\n results.push(result.value);\n } else {\n return failure(\n result.error ??\n new DatabaseError(\n \"Batch create failed\",\n DATABASE_ERROR_CODES.CREATE_FAILED,\n {\n context: { source: \"batchCreate\" },\n cause: new Error(\"Batch create failed\"),\n },\n ),\n );\n }\n }\n return success(results);\n }\n\n async batchUpdate<T extends Record<string, unknown>>(\n table: TableName,\n updates: BatchUpdate<T>[],\n operationConfig?: OperationConfig,\n ): Promise<DatabaseResult<T[]>> {\n const results: T[] = [];\n for (const update of updates) {\n const result = await this.update<T>(\n table,\n update.id,\n update.data,\n operationConfig,\n );\n if (result.success && result.value) {\n results.push(result.value);\n } else {\n return failure(\n result.error ??\n new DatabaseError(\n \"Batch update failed\",\n DATABASE_ERROR_CODES.UPDATE_FAILED,\n {\n context: { source: \"batchUpdate\" },\n cause: new Error(\"Batch update failed\"),\n },\n ),\n );\n }\n }\n return success(results);\n }\n\n async batchDelete(\n table: TableName,\n ids: string[],\n operationConfig?: OperationConfig,\n ): Promise<DatabaseResult<void>> {\n for (const id of ids) {\n const result = await this.delete(table, id, operationConfig);\n if (!result.success) {\n return failure(\n result.error ??\n new DatabaseError(\n \"Batch delete failed\",\n DATABASE_ERROR_CODES.DELETE_FAILED,\n {\n context: { source: \"batchDelete\" },\n cause: new Error(\"Batch delete failed\"),\n },\n ),\n );\n }\n }\n return success();\n }\n\n // Query Operations\n async query<T extends Record<string, unknown>>(\n table: TableName,\n query: QueryOptions<T>,\n operationConfig?: OperationConfig,\n ): Promise<DatabaseResult<PaginatedResult<T>>> {\n return this.list<T>(table, query, operationConfig);\n }\n\n async count<T extends Record<string, unknown> = Record<string, unknown>>(\n table: TableName,\n filter?: Filter<T>,\n operationConfig?: OperationConfig,\n ): Promise<DatabaseResult<number>> {\n ConfigMerger.mergeConfigs(this.globalConfig, operationConfig);\n return this.adapter.count(table, filter);\n }\n\n // Transactions\n async transaction<T>(fn: TransactionFn<T>): Promise<DatabaseResult<T>> {\n return this.adapter.transaction(fn);\n }\n\n // Audit Context\n async setAuditContext(context: AuditContext): Promise<DatabaseResult<void>> {\n this.auditContext = { ...this.auditContext, ...context };\n return success();\n }\n\n // Event System\n on<T extends DatabaseEvent[\"type\"]>(\n event: T,\n handler: (\n event: Extract<DatabaseEvent, { type: T }>,\n ) => void | Promise<void>,\n ): void {\n this.eventEmitter.on(event, handler);\n }\n\n off<T extends DatabaseEvent[\"type\"]>(\n event: T,\n handler: (\n event: Extract<DatabaseEvent, { type: T }>,\n ) => void | Promise<void>,\n ): void {\n this.eventEmitter.off(event, handler);\n }\n\n // Health & Status\n async healthCheck(): Promise<DatabaseResult<DatabaseHealthStatus>> {\n return this.healthManager.checkHealth();\n }\n\n getStatus(): ServiceStatus {\n const uptime = Date.now() - this.startTime.getTime();\n return {\n isHealthy: true, // TODO: Get actual health status\n adapter: this.adapter.constructor.name,\n uptime,\n lastHealthCheck: new Date(),\n };\n }\n\n // Legacy methods for backward compatibility\n async findById<T extends Record<string, unknown>>(\n table: string,\n id: string,\n ): Promise<DatabaseResult<T | null>> {\n return this.get<T>(table, id);\n }\n\n async findMany<T extends Record<string, unknown>>(\n table: string,\n options?: QueryOptions<T>,\n ): Promise<DatabaseResult<PaginatedResult<T>>> {\n return this.list<T>(table, options);\n }\n\n async initialize(): Promise<DatabaseResult<void>> {\n return success();\n }\n\n /**\n * Registers a table with the underlying adapter.\n *\n * @param name - Logical table name (e.g., 'users')\n * @param table - Physical table name or Drizzle table object\n * @param idColumn - ID column name (defaults to 'id')\n *\n * @example SQL Adapter\n * ```typescript\n * db.registerTable('users', 'users', 'id');\n * db.registerTable('feature_flags', 'feature_flags', 'key');\n * ```\n *\n * @example Drizzle Adapter (requires PgTable objects)\n * ```typescript\n * db.registerTable('users', usersTable, usersTable.id);\n * ```\n */\n registerTable<TTable = string, TIdColumn = string>(\n name: string,\n table?: TTable,\n idColumn?: TIdColumn,\n ): void {\n // Delegate to the adapter's registerTable method\n if (this.adapter && typeof this.adapter.registerTable === \"function\") {\n // For SQL adapter: if table is not provided, use name as table name\n const tableValue = table ?? name;\n this.adapter.registerTable(name, tableValue, idColumn);\n }\n }\n\n async exists(table: string, id: string): Promise<DatabaseResult<boolean>> {\n const result = await this.get(table, id);\n return success(result.success && result.value !== null);\n }\n\n private async fireBeforeReadEvent(table: TableName): Promise<void> {\n if (this.eventHandlers?.onBeforeRead) {\n await this.eventHandlers.onBeforeRead({\n type: \"beforeRead\",\n operation: \"READ\",\n table,\n timestamp: new Date(),\n });\n }\n }\n\n private async fireAfterReadEvent<T>(\n table: TableName,\n record: T | null,\n ): Promise<void> {\n if (this.eventHandlers?.onAfterRead) {\n await this.eventHandlers.onAfterRead({\n type: \"afterRead\",\n operation: \"READ\",\n table,\n result:\n (record as Record<string, string | number | boolean | Date>) ?? {},\n duration: 0,\n timestamp: new Date(),\n });\n }\n }\n\n async findOne<T extends Record<string, unknown>>(\n table: TableName,\n filter: Filter<T>,\n operationConfig?: OperationConfig,\n ): Promise<DatabaseResult<T | null>> {\n ConfigMerger.mergeConfigs(this.globalConfig, operationConfig);\n\n try {\n await this.fireBeforeReadEvent(table);\n\n const result = await this.adapter.findMany<T>(table, {\n filter,\n pagination: { limit: 1, offset: 0 },\n });\n\n if (!result.success) {\n return { success: false, error: result.error };\n }\n\n const firstRecord = result.value?.data[0] ?? null;\n await this.fireAfterReadEvent(table, firstRecord);\n\n return { success: true, value: firstRecord };\n } catch (error) {\n return failure(\n new DatabaseError(\n `Find one operation failed: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.QUERY_FAILED,\n {\n context: { source: \"findOne\" },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n async softDelete(\n table: TableName,\n id: string,\n operationConfig?: OperationConfig,\n ): Promise<DatabaseResult<void>> {\n ConfigMerger.mergeConfigs(this.globalConfig, {\n ...operationConfig,\n softDelete: { enabled: true },\n });\n\n try {\n if (this.eventHandlers?.onBeforeWrite) {\n await this.eventHandlers.onBeforeWrite({\n type: \"beforeWrite\",\n operation: \"DELETE\",\n table,\n data: { id, softDelete: true },\n timestamp: new Date(),\n });\n }\n\n const result = await this.adapter.delete(table, id);\n\n if (result.success && this.eventHandlers?.onAfterWrite) {\n await this.eventHandlers.onAfterWrite({\n type: \"afterWrite\",\n operation: \"DELETE\",\n table,\n result: { softDeleted: true },\n duration: 0,\n timestamp: new Date(),\n });\n }\n\n return result;\n } catch (error) {\n return failure(\n new DatabaseError(\n `Soft delete operation failed: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.DELETE_FAILED,\n {\n context: { source: \"softDelete\" },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n get events(): DatabaseEventEmitter {\n return this.eventEmitter;\n }\n\n /**\n * šŸ”Œ Close the database connection\n *\n * Gracefully shuts down the database connection and releases all resources.\n * Should be called when the service is no longer needed.\n *\n * @returns Promise resolving to DatabaseResult indicating success or failure\n */\n async close(): Promise<DatabaseResult<void>> {\n try {\n if (this.adapter.close) {\n return await this.adapter.close();\n }\n return success();\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to close database connection: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.DISCONNECT_FAILED,\n {\n context: { source: \"close\" },\n cause: error as Error,\n },\n ),\n );\n }\n }\n}\n","/**\n * @fileoverview Pagination Utilities for @plyaz/db package\n *\n * This module provides pagination calculation utilities used across all database adapters\n * to generate consistent pagination metadata for query results. Supports offset-based\n * pagination with page calculation and validation.\n *\n * Part of the @plyaz/db package - a TypeScript database abstraction layer with\n * support for multiple adapters (Drizzle, Supabase, SQL), extensions (audit, encryption,\n * soft delete), and advanced features (caching, read replicas, multi-tenancy).\n *\n * @module pagination\n */\n\nimport type { PaginationInfo, PaginationOptions } from \"@plyaz/types\";\nimport { isNumber } from \"./typeGuards\";\nimport { DatabaseError } from \"@plyaz/errors\";\nimport { DATABASE_ERROR_CODES } from \"@plyaz/types/errors\";\n\n/**\n * Validates pagination input parameters for safety and consistency\n *\n * Performs comprehensive validation of pagination parameters to prevent invalid\n * calculations and ensure consistent behavior across all database adapters.\n *\n * **Validation Rules:**\n * - Total must be a non-negative number (>= 0)\n * - Limit must be a positive number (> 0) if provided\n * - Offset must be a non-negative number (>= 0)\n *\n * @private\n * @param {number} total - Total number of items in the dataset\n * @param {number} [limit] - Optional maximum number of items per page\n * @param {number} [offset] - Optional number of items to skip (default: 0)\n * @throws {Error} If any parameter fails validation\n *\n * @example\n * ```typescript\n * // Valid inputs\n * validatePaginationInputs(100, 20, 0); // āœ“ Valid\n * validatePaginationInputs(0, 10, 0); // āœ“ Valid (empty dataset)\n * validatePaginationInputs(50); // āœ“ Valid (no pagination)\n *\n * // Invalid inputs\n * validatePaginationInputs(-1, 10, 0); // āœ— Throws: negative total\n * validatePaginationInputs(100, 0, 0); // āœ— Throws: zero limit\n * validatePaginationInputs(100, 10, -5); // āœ— Throws: negative offset\n * ```\n *\n */\nfunction validatePaginationInputs(\n total: number,\n limit?: number,\n offset?: number,\n): void {\n // Total count validation\n // Must be non-negative to represent valid dataset size\n if (!isNumber(total) || total < 0) {\n throw new DatabaseError(\n \"Total must be a non-negative number\",\n DATABASE_ERROR_CODES.INVALID_PARAMETERS,\n {\n context: { source: \"validatePaginationInputs\" },\n cause: new Error(\"Total must be a non-negative number\"),\n },\n );\n }\n\n // Limit validation (if provided)\n // Must be positive to create meaningful pages\n if (limit !== undefined && (!isNumber(limit) || limit <= 0)) {\n throw new DatabaseError(\n \"Limit must be a positive number\",\n DATABASE_ERROR_CODES.INVALID_PARAMETERS,\n {\n context: { source: \"validatePaginationInputs\" },\n cause: new Error(\"Limit must be a positive number\"),\n },\n );\n }\n\n // Offset validation\n // Must be non-negative to represent valid starting position\n if (!isNumber(offset) || offset < 0) {\n throw new DatabaseError(\n \"Offset must be a non-negative number\",\n DATABASE_ERROR_CODES.INVALID_PARAMETERS,\n {\n context: { source: \"validatePaginationInputs\" },\n cause: new Error(\"Offset must be a non-negative number\"),\n },\n );\n }\n}\n\n/**\n * Calculates comprehensive pagination metadata for database query results\n *\n * Generates pagination information used by all database adapters to provide\n * consistent pagination metadata in query results. Supports both paginated\n * and non-paginated queries with automatic page calculation.\n *\n * **Used by:**\n * - DrizzleAdapter.findMany() for ORM-based pagination\n * - SupabaseAdapter.findMany() for Supabase pagination\n * - SQLAdapter.findMany() for raw SQL pagination\n * - All repository methods that return paginated results\n *\n * **Calculation Logic:**\n * - Page numbers are 1-based (first page = 1)\n * - Current page = floor(offset / limit) + 1\n * - Total pages = ceil(total / limit)\n * - Handles edge cases (no limit, empty results, etc.)\n *\n * @param {number} total - Total number of items matching the query\n * @param {PaginationOptions} [options] - Optional pagination configuration\n * @param {number} [options.limit] - Maximum items per page\n * @param {number} [options.offset] - Number of items to skip (default: 0)\n * @returns {PaginationInfo} Complete pagination metadata object\n *\n * @example\n * ```typescript\n * import { calculatePagination } from '@plyaz/db/utils';\n *\n * // Standard pagination (page 2 of 20 items per page)\n * const pagination1 = calculatePagination(100, { limit: 20, offset: 20 });\n * console.log(pagination1);\n * // {\n * // page: 2,\n * // limit: 20,\n * // offset: 20,\n * // totalPages: 5\n * // }\n *\n * // First page\n * const pagination2 = calculatePagination(100, { limit: 20, offset: 0 });\n * console.log(pagination2);\n * // {\n * // page: 1,\n * // limit: 20,\n * // offset: 0,\n * // totalPages: 5\n * // }\n *\n * // No pagination (return all results)\n * const pagination3 = calculatePagination(100);\n * console.log(pagination3);\n * // {\n * // page: undefined,\n * // limit: undefined,\n * // offset: 0,\n * // totalPages: undefined\n * // }\n * ```\n *\n */\nexport function calculatePagination(\n total: number,\n options?: PaginationOptions,\n): PaginationInfo {\n const limit = options?.limit;\n const offset = options?.offset ?? 0;\n\n // Validate all inputs before calculation\n validatePaginationInputs(total, limit, offset);\n\n // Calculate current page (1-based indexing)\n // Only calculate if limit is provided and positive\n // Formula: floor(offset / limit) + 1\n // Example: offset=20, limit=10 → floor(20/10) + 1 = 3 (page 3)\n const page = limit && limit > 0 ? Math.floor(offset / limit) + 1 : undefined;\n\n // Calculate total number of pages\n // Only calculate if limit is provided and positive\n // Formula: ceil(total / limit)\n // Example: total=95, limit=10 → ceil(95/10) = 10 pages\n const totalPages = limit && limit > 0 ? Math.ceil(total / limit) : undefined;\n\n return {\n page,\n limit,\n offset,\n totalPages,\n };\n}\n","/**\n * @fileoverview Centralized Regex Patterns for @plyaz/db package\n *\n * This module contains all regex patterns used throughout the database package.\n * Centralizing regex patterns improves maintainability, reusability, and consistency.\n *\n * Part of the @plyaz/db package - a TypeScript database abstraction layer with\n * support for multiple adapters (Drizzle, Supabase, SQL), extensions (audit, encryption,\n * soft delete), and advanced features (caching, read replicas, multi-tenancy).\n *\n */\n\n/**\n * Database field and table name validation patterns\n * Used for SQL injection prevention and database identifier validation\n */\nexport const DATABASE_PATTERNS = {\n /**\n * Validates database field names (columns)\n * - Must start with letter (a-z, A-Z) or underscore (_)\n * - Can contain letters, numbers, and underscores\n * - Prevents SQL injection through field names\n *\n * Used in: validation.ts, sql.ts, DrizzleAdapter.ts, SQLAdapter.ts\n */\n FIELD_NAME: /^[a-zA-Z_][a-zA-Z0-9_]*$/,\n\n /**\n * Validates database table names\n * - Same rules as field names for consistency\n * - Follows SQL identifier naming conventions\n *\n * Used in: validation.ts, CacheEvict.decorator.ts\n */\n TABLE_NAME: /^[a-zA-Z_][a-zA-Z0-9_]*$/,\n} as const;\n\n/**\n * Cache key validation patterns\n * Used for validating cache keys and patterns in caching system\n */\nexport const CACHE_PATTERNS = {\n /**\n * Validates cache keys\n * - Allows letters, numbers, colons, underscores, and hyphens\n * - Used for Redis cache key validation\n *\n * Used in: CacheEvict.decorator.ts\n */\n CACHE_KEY: /^[a-zA-Z0-9:_-]+$/,\n\n /**\n * Validates cache patterns (with wildcards)\n * - Same as cache key but allows asterisk (*) for wildcards\n * - Used for cache pattern matching and eviction\n *\n * Used in: CacheEvict.decorator.ts\n */\n CACHE_PATTERN: /^[a-zA-Z0-9:_*-]+$/,\n} as const;\n\n/**\n * SQL query sanitization patterns\n * Used for cleaning and normalizing SQL queries for metrics and logging\n */\nexport const SQL_PATTERNS = {\n /**\n * Matches PostgreSQL parameter placeholders ($1, $2, etc.)\n * - Used to normalize parameterized queries for metrics\n *\n * Used in: MetricsCollector.ts\n */\n POSTGRES_PARAMS: /\\$\\d+/g,\n\n /**\n * Matches numeric values in SQL queries\n * - Used to replace numbers with placeholders for query normalization\n *\n * Used in: MetricsCollector.ts\n */\n NUMERIC_VALUES: /\\d+/g,\n\n /**\n * Matches string literals in SQL queries (single quotes)\n * - Used to replace string values with placeholders\n *\n * Used in: MetricsCollector.ts\n */\n STRING_LITERALS: /'[^']*'/g,\n} as const;\n\n/**\n * Input sanitization patterns\n * Used for cleaning user input and preventing injection attacks\n */\nexport const SANITIZATION_PATTERNS = {\n /**\n * Matches dangerous characters for SQL injection prevention\n * - Null byte, backspace, tab, newline, carriage return\n * - Single and double quotes, backslashes, percent signs\n *\n * Used in: validation.ts (sanitizeInput function)\n */\n DANGEROUS_CHARS: /[\\0\\b\\t\\n\\r\"'\\\\%]/g,\n\n /**\n * Matches shell metacharacters for command injection prevention\n * - Semicolon, ampersand, pipe, backtick, dollar, parentheses, etc.\n *\n * Used in: BackupService.ts (sanitizeCommand function)\n */\n SHELL_METACHARACTERS: /[;&|`$(){}[\\]<>\"'\\\\]/g,\n\n /**\n * Matches multiple whitespace characters\n * - Used to normalize whitespace in sanitized input\n *\n * Used in: BackupService.ts\n */\n MULTIPLE_WHITESPACE: /\\s+/g,\n\n /**\n * Matches line breaks and tabs\n * - Used to replace line breaks with spaces\n *\n * Used in: BackupService.ts\n */\n LINE_BREAKS_TABS: /[\\r\\n\\t]/g,\n\n /**\n * Matches Unicode control characters\n * - Uses Unicode property escape to match all control characters\n *\n * Used in: BackupService.ts\n */\n CONTROL_CHARACTERS: /[\\p{Cc}]/gu,\n} as const;\n\n/**\n * File and path patterns\n * Used for file operations and path validation\n */\nexport const FILE_PATTERNS = {\n /**\n * Matches colon and dot characters in timestamps\n * - Used to create filesystem-safe timestamps\n *\n * Used in: BackupService.ts (timestamp generation)\n */\n TIMESTAMP_CHARS: /[:.]/g,\n} as const;\n\n/**\n * Utility functions for common regex operations\n */\nexport const DB_REGEX = {\n /**\n * Tests if a string matches the database field name pattern\n * @param fieldName - The field name to validate\n * @returns True if valid database field name\n */\n isValidFieldName: (fieldName: string): boolean => {\n return DATABASE_PATTERNS.FIELD_NAME.test(fieldName);\n },\n\n /**\n * Tests if a string matches the database table name pattern\n * @param tableName - The table name to validate\n * @returns True if valid database table name\n */\n isValidTableName: (tableName: string): boolean => {\n return DATABASE_PATTERNS.TABLE_NAME.test(tableName);\n },\n\n /**\n * Tests if a string matches the cache key pattern\n * @param cacheKey - The cache key to validate\n * @returns True if valid cache key\n */\n isValidCacheKey: (cacheKey: string): boolean => {\n return CACHE_PATTERNS.CACHE_KEY.test(cacheKey);\n },\n\n /**\n * Tests if a string matches the cache pattern (with wildcards)\n * @param cachePattern - The cache pattern to validate\n * @returns True if valid cache pattern\n */\n isValidCachePattern: (cachePattern: string): boolean => {\n return CACHE_PATTERNS.CACHE_PATTERN.test(cachePattern);\n },\n\n /**\n * Normalizes SQL query by replacing parameters and values with placeholders\n * @param query - The SQL query to normalize\n * @returns Normalized query string\n */\n normalizeSqlQuery: (query: string): string => {\n return query\n .replace(SQL_PATTERNS.POSTGRES_PARAMS, \"?\")\n .replace(SQL_PATTERNS.NUMERIC_VALUES, \"?\")\n .replace(SQL_PATTERNS.STRING_LITERALS, \"?\");\n },\n\n /**\n * Sanitizes input by escaping dangerous characters\n * @param input - The input string to sanitize\n * @param escapeMap - Map of characters to their escaped equivalents\n * @returns Sanitized string\n */\n sanitizeDangerousChars: (\n input: string,\n escapeMap: Record<string, string>,\n ): string => {\n return input.replace(\n SANITIZATION_PATTERNS.DANGEROUS_CHARS,\n (char) => escapeMap[char] || char,\n );\n },\n\n /**\n * Creates filesystem-safe timestamp string\n * @param timestamp - ISO timestamp string\n * @returns Filesystem-safe timestamp\n */\n createSafeTimestamp: (timestamp: string): string => {\n return timestamp.replace(FILE_PATTERNS.TIMESTAMP_CHARS, \"-\");\n },\n\n /**\n * Sanitizes command string by removing shell metacharacters\n * @param command - Command string to sanitize\n * @returns Sanitized command string\n */\n sanitizeCommand: (command: string): string => {\n return command\n .replace(SANITIZATION_PATTERNS.SHELL_METACHARACTERS, \"\")\n .replace(SANITIZATION_PATTERNS.MULTIPLE_WHITESPACE, \" \")\n .trim();\n },\n\n /**\n * Sanitizes log message by normalizing whitespace and removing control characters\n * @param message - Log message to sanitize\n * @returns Sanitized log message\n */\n sanitizeLogMessage: (message: string): string => {\n return message\n .replace(SANITIZATION_PATTERNS.LINE_BREAKS_TABS, \" \")\n .replace(SANITIZATION_PATTERNS.CONTROL_CHARACTERS, \"\")\n .trim();\n },\n} as const;\n","import { drizzle } from \"drizzle-orm/node-postgres\";\nimport type { PoolClient } from \"pg\";\nimport { Pool } from \"pg\";\nimport type {\n Column,\n ColumnBaseConfig,\n ColumnDataType,\n SQL,\n SQLWrapper,\n} from \"drizzle-orm\";\nimport {\n eq,\n not,\n gte,\n gt,\n lte,\n lt,\n inArray,\n like,\n between,\n isNull,\n isNotNull,\n asc,\n desc,\n sql,\n} from \"drizzle-orm\";\nimport type { PgTable, PgSelectBase } from \"drizzle-orm/pg-core\";\nimport { PgColumn } from \"drizzle-orm/pg-core\";\nimport { calculatePagination } from \"@utils/pagination\";\nimport type {\n DrizzleAdapterConfig,\n DatabaseAdapterType,\n DatabaseResult,\n PaginatedResult,\n QueryOptions,\n DatabaseHealthStatus,\n Filter,\n Transaction,\n SortOptions,\n} from \"@plyaz/types/db\";\nimport { failure, success } from \"@utils/databaseResultHelpers\";\nimport { DatabaseError } from \"@plyaz/errors\";\nimport { isNonEmptyString, isObject } from \"@utils/typeGuards\";\nimport { DATABASE_ERROR_CODES, type ErrorCodeValue } from \"@plyaz/types/errors\";\nimport { DB_REGEX } from \"@utils/regex\";\nimport type { BuildWhereClauseOptions } from \"@plyaz/types/db\";\n\n/** Minimum elements required for BETWEEN clause */\nconst BETWEEN_MIN_ELEMENTS = 2;\n\n/**\n * @class DrizzleAdapter\n * @implements {DatabaseAdapterType}\n * @classdesc\n * A PostgreSQL database adapter built on top of Drizzle ORM.\n * Provides generic CRUD operations, pagination, filtering, sorting,\n * and transactional support with a consistent result structure.\n */\nexport class DrizzleAdapter implements DatabaseAdapterType {\n private db: ReturnType<typeof drizzle>;\n private pool: Pool;\n private config: DrizzleAdapterConfig;\n private tableMap: Map<string, PgTable> = new Map();\n private idColumnMap: Map<string, PgColumn> = new Map();\n // String-based table registry for auto-registration (fallback when no PgTable schema)\n private stringTableMap: Map<string, string> = new Map();\n private stringIdColumnMap: Map<string, string> = new Map();\n private configIdColumns: Record<string, string>;\n\n /**\n * Creates a new DrizzleAdapter instance.\n * @param {DrizzleAdapterConfig} config - Configuration object for Drizzle and PostgreSQL connection.\n * @description\n * Initializes the adapter with the provided configuration, setting up the connection pool\n * and creating a Drizzle ORM instance. The configuration should include a connection string\n * and optional pool settings such as min/max connections and idle timeout.\n */\n constructor(config: DrizzleAdapterConfig) {\n this.config = config;\n this.pool = new Pool({\n connectionString: config.connectionString,\n ...config.pool,\n });\n this.db = drizzle(this.pool);\n // Store custom ID column mappings from config\n this.configIdColumns = config.tableIdColumns ?? {};\n }\n\n /**\n * Initializes the adapter by verifying database connectivity.\n * @returns {Promise<DatabaseResult<void>>} Success or failure result.\n * @description\n * Attempts to establish a connection to the database to verify that the adapter\n * can communicate with the database. This is typically called during application startup\n * to ensure the database is accessible before performing any operations.\n * Returns a success result if the connection is established, or a failure result with an error\n * if the connection cannot be established.\n */\n async initialize(): Promise<DatabaseResult<void>> {\n let client;\n try {\n client = await this.pool.connect();\n return success();\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to initialize Drizzle adapter: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.INIT_FAILED,\n {\n context: {\n source: \"DrizzleAdapter.initialize\",\n },\n cause: error as Error,\n },\n ),\n );\n } finally {\n if (client) {\n client.release();\n }\n }\n }\n\n /**\n * Opens a new connection to the database.\n * @returns {Promise<void>}\n * @description\n * Establishes a connection to the PostgreSQL database using the connection pool.\n * This method is called to ensure that a connection is available before performing database operations.\n * The connection pool manages the connections efficiently, reusing them when possible.\n */\n async connect(): Promise<void> {\n try {\n const client = await this.pool.connect();\n client.release();\n } catch (error) {\n throw new DatabaseError(\n `Failed to connect to database: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.CONNECT_FAILED,\n {\n context: {\n source: \"DrizzleAdapter.connect\",\n },\n cause: error as Error,\n },\n );\n }\n }\n\n /**\n * Closes all open connections and shuts down the connection pool.\n * @returns {Promise<void>}\n * @description\n * Gracefully shuts down the connection pool, closing all active connections.\n * This method should be called when the adapter is no longer needed, typically during\n * application shutdown, to free up database resources and prevent connection leaks.\n */\n async disconnect(): Promise<void> {\n try {\n await this.pool.end();\n } catch (error) {\n throw new DatabaseError(\n `Failed to disconnect from database: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.DISCONNECT_FAILED,\n {\n context: {\n source: \"DrizzleAdapter.disconnect\",\n },\n cause: error as Error,\n },\n );\n }\n }\n\n /**\n * Closes the database connection and cleanup resources.\n * @returns Promise resolving to DatabaseResult indicating success or failure.\n */\n async close(): Promise<DatabaseResult<void>> {\n try {\n await this.disconnect();\n return success();\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to close connection: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.DISCONNECT_FAILED,\n ),\n );\n }\n }\n\n /**\n * Gets the underlying Drizzle client instance.\n * @returns {TClient} The internal Drizzle client.\n * @description\n * This method exposes the internal Drizzle client instance. Direct access is discouraged\n * to maintain abstraction and ensure all database operations go through the adapter’s\n * interface for error handling, logging, and event emission.\n */\n getClient<TClient extends object = object>(): TClient {\n return this.db as TClient;\n }\n\n /**\n * Executes a raw SQL query.\n * @template T - The expected type of the query result rows.\n * @param {string} sql - Raw SQL query string.\n * @param {T[]} [params] - Optional query parameters.\n * @returns {Promise<T[]>} Array of query result rows.\n * @throws {DatabaseError} When query execution fails.\n * @description\n * Executes a raw SQL query against the database, with optional parameterization.\n * This method is useful for complex queries that cannot be easily expressed using the ORM\n * or for database-specific operations. The method uses parameterized queries to prevent\n * SQL injection attacks. If the query execution fails, a DatabaseError is thrown.\n */\n async query<T>(sql: string, params?: T[]): Promise<T[]> {\n try {\n // Validate SQL to prevent injection\n if (!isNonEmptyString(sql)) {\n throw new DatabaseError(\n \"Invalid SQL query\",\n DATABASE_ERROR_CODES.INVALID_SQL,\n );\n }\n\n const result = await this.pool.query(sql, params);\n return result.rows as T[];\n } catch (error) {\n throw new DatabaseError(\n `Failed to execute query: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.QUERY_FAILED,\n {\n context: {\n source: \"DrizzleAdapter.query\",\n },\n cause: error as Error,\n },\n );\n }\n }\n\n /**\n * Registers a table and optional ID column for ORM operations.\n * @template TTable - Type representing the table structure (PgTable or string).\n * @template TIdColumn - Type representing the ID column (PgColumn or string).\n * @param {string} name - Logical name of the table.\n * @param {TTable} table - Drizzle table object (PgTable) or string table name.\n * @param {TIdColumn} [idColumn] - Optional primary key column (PgColumn or string).\n * @description\n * Registers a table with the adapter, allowing it to be referenced by a logical name\n * in subsequent operations. This is necessary for the adapter to perform ORM operations\n * on the table. The ID column can also be specified if it differs from the default 'id'.\n *\n * **Supports two modes:**\n * 1. **PgTable mode**: Pass Drizzle schema objects for type-safe ORM operations\n * 2. **String mode**: Pass string table names for raw SQL fallback (auto-registration)\n *\n * This registration enables the adapter to map logical table names to actual table objects\n * and ID columns, providing a layer of abstraction between the application and the database schema.\n */\n registerTable<TTable, TIdColumn>(\n name: string,\n table: TTable,\n idColumn?: TIdColumn,\n ): void {\n try {\n if (!isNonEmptyString(name)) {\n throw new DatabaseError(\n \"Invalid table name\",\n DATABASE_ERROR_CODES.INVALID_TABLE_NAME,\n );\n }\n\n // Check if table is a PgTable (Drizzle schema) or a string (raw SQL mode)\n if (typeof table === \"string\") {\n // String mode: register for raw SQL operations\n this.stringTableMap.set(name, table);\n if (idColumn && typeof idColumn === \"string\") {\n this.stringIdColumnMap.set(name, idColumn);\n }\n } else {\n // PgTable mode: register for Drizzle ORM operations\n this.tableMap.set(name, table as PgTable);\n if (idColumn) {\n this.idColumnMap.set(name, idColumn as TIdColumn as PgColumn);\n }\n }\n } catch (error) {\n throw new DatabaseError(\n `Failed to register table: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.TABLE_REGISTRATION_FAILED,\n {\n context: {\n source: \"DrizzleAdapter.registerTable\",\n },\n cause: error as Error,\n },\n );\n }\n }\n\n /**\n * Execute raw SQL findById query\n */\n private async rawSqlFindById<T>(\n table: string,\n id: string,\n ): Promise<T | null> {\n const tableName = this.getStringTableName(table);\n const idColumn = this.getStringIdColumn(table);\n const sqlQuery = `SELECT * FROM \"${tableName}\" WHERE \"${idColumn}\" = $1 LIMIT 1`;\n const result = await this.pool.query(sqlQuery, [id]);\n return (result.rows[0] as T) || null;\n }\n\n /**\n * Finds a record by its primary ID.\n * @template T - The expected type of the record.\n * @param {string} table - Table name.\n * @param {string} id - Record ID.\n * @returns {Promise<DatabaseResult<T | null>>} Found record or null.\n * @description\n * Retrieves a single record from the specified table using its primary ID.\n * The method uses the registered table and ID column to construct the query.\n * If the record is found, it is returned in a success result. If no record is found,\n * null is returned in a success result. If an error occurs during the operation,\n * a failure result with an error message is returned.\n *\n * **Auto-registers tables**: If table is not registered with PgTable schema,\n * falls back to raw SQL mode (same behavior as SQLAdapter).\n */\n async findById<T>(\n table: string,\n id: string,\n ): Promise<DatabaseResult<T | null>> {\n try {\n // Check if we should use raw SQL mode\n if (this.isStringMode(table)) {\n return success(await this.rawSqlFindById<T>(table, id));\n }\n\n // Use Drizzle ORM mode\n const tableObj = this.getTable(table);\n const idColumn = this.getIdColumn(table);\n const result = await this.db\n .select()\n .from(tableObj)\n .where(eq(idColumn, id))\n .limit(1);\n return success((result[0] as T) || null);\n } catch (error) {\n // If error is USE_STRING_MODE, retry with raw SQL\n if (\n error instanceof DatabaseError &&\n error.message === \"USE_STRING_MODE\"\n ) {\n return this.handleStringModeFallback<T | null>(\n () => this.rawSqlFindById<T>(table, id),\n table,\n \"DrizzleAdapter.findById\",\n DATABASE_ERROR_CODES.FIND_BY_ID_FAILED,\n );\n }\n return failure(\n new DatabaseError(\n `Failed to find by id in table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.FIND_BY_ID_FAILED,\n {\n context: { source: \"DrizzleAdapter.findById\" },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Handle USE_STRING_MODE fallback with error wrapping\n */\n private async handleStringModeFallback<T>(\n operation: () => Promise<T>,\n table: string,\n source: string,\n errorCode: ErrorCodeValue,\n ): Promise<DatabaseResult<T>> {\n try {\n return success(await operation());\n } catch (sqlError) {\n return failure(\n new DatabaseError(\n `Failed operation on table ${table}: ${(sqlError as Error).message}`,\n errorCode,\n {\n context: { source },\n cause: sqlError as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Retrieves multiple records with optional filtering, sorting, and pagination.\n * @template T - The expected type of the records.\n * @param {string} table - Table name.\n * @param {QueryOptions} [options] - Optional filter, sort, and pagination options.\n * @returns {Promise<DatabaseResult<PaginatedResult<T>>>} Paginated result set.\n * @description\n * Retrieves multiple records from the specified table with support for filtering,\n * sorting, and pagination. The method first applies any filters to narrow down the result set,\n * then applies sorting to order the results, and finally applies pagination to limit the number\n * of records returned. The result includes the data array, total count of matching records,\n * and pagination metadata such as current page, total pages, and next/previous cursors.\n * If an error occurs during the operation, a failure result with an error message is returned.\n *\n * **Auto-registers tables**: If table is not registered with PgTable schema,\n * falls back to raw SQL mode (same behavior as SQLAdapter).\n */\n\n // eslint-disable-next-line complexity\n async findMany<T extends Record<string, unknown>>(\n table: string,\n options?: QueryOptions<T>,\n ): Promise<DatabaseResult<PaginatedResult<T>>> {\n try {\n // Check if we should use raw SQL mode\n if (this.isStringMode(table)) {\n return this.findManyRawSql<T>(table, options);\n }\n\n const tableObj = this.getTable(table);\n\n let query: PgSelectBase<\n string,\n Record<string, PgColumn>,\n \"single\",\n Record<string, \"not-null\">,\n false\n > = this.db.select().from(tableObj);\n\n // Apply sorting\n if (options?.sort) {\n query = this.applySorting(query as never, options.sort, tableObj);\n }\n // Apply filters\n if (options?.filter) {\n const whereClause = this.buildWhereClause(options.filter, tableObj);\n if (whereClause) {\n query = query.where(whereClause) as typeof query;\n }\n }\n\n // Get total count\n let countQuery = this.db\n .select({ count: sql<number>`count(*)::int`.as(\"count\") })\n .from(tableObj);\n if (options?.filter) {\n const whereClause = this.buildWhereClause(options.filter, tableObj);\n if (whereClause)\n countQuery = countQuery.where(whereClause) as typeof countQuery;\n }\n\n const countResult = await countQuery;\n const total = Number(countResult[0].count);\n\n // Apply pagination\n if (options?.pagination) {\n if (options.pagination.offset !== undefined) {\n query = query.offset(options.pagination.offset) as typeof query;\n }\n if (options.pagination.limit !== undefined) {\n query = query.limit(options.pagination.limit) as typeof query;\n }\n }\n\n const data = await query;\n return success({\n data: data as T[],\n total,\n pagination: calculatePagination(total, options?.pagination),\n });\n } catch (error) {\n // If error is USE_STRING_MODE, retry with raw SQL\n if (\n error instanceof DatabaseError &&\n error.message === \"USE_STRING_MODE\"\n ) {\n return this.findManyRawSql<T>(table, options);\n }\n return failure(\n new DatabaseError(\n `Failed to find many in table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.FIND_MANY_FAILED,\n {\n context: {\n source: \"DrizzleAdapter.findMany\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Raw SQL fallback for findMany when no PgTable schema is registered.\n * @private\n */\n // eslint-disable-next-line complexity\n private async findManyRawSql<T extends Record<string, unknown>>(\n table: string,\n options?: QueryOptions<T>,\n ): Promise<DatabaseResult<PaginatedResult<T>>> {\n try {\n const tableName = this.getStringTableName(table);\n const params: unknown[] = [];\n let whereClause = \"\";\n let paramIndex = 1;\n\n // Build WHERE clause\n if (options?.filter) {\n const { field, operator, value } = options.filter;\n whereClause = this.buildSqlWhereClause({\n field,\n operator,\n value,\n params,\n startIndex: paramIndex,\n });\n paramIndex = params.length + 1;\n }\n\n // Count total\n const countSql = `SELECT COUNT(*) as total FROM \"${tableName}\"${whereClause}`;\n const countResult = await this.pool.query(countSql, params);\n const total = Number.parseInt(countResult.rows[0].total);\n\n // ORDER BY clause\n let orderClause = \"\";\n if (options?.sort?.length) {\n orderClause =\n \" ORDER BY \" +\n options.sort\n .map((s) => `\"${s.field}\" ${s.direction.toUpperCase()}`)\n .join(\", \");\n }\n\n // Build main query params (need to copy for separate query)\n const queryParams = [...params];\n\n // LIMIT & OFFSET\n let limitClause = \"\";\n if (options?.pagination?.limit) {\n limitClause += ` LIMIT $${paramIndex++}`;\n queryParams.push(options.pagination.limit);\n }\n if (options?.pagination?.offset) {\n limitClause += ` OFFSET $${paramIndex++}`;\n queryParams.push(options.pagination.offset);\n }\n\n // Final query\n const sqlQuery = `SELECT * FROM \"${tableName}\"${whereClause}${orderClause}${limitClause}`;\n const result = await this.pool.query(sqlQuery, queryParams);\n\n return success({\n data: result.rows as T[],\n total,\n pagination: calculatePagination(total, options?.pagination),\n });\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to find many in table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.FIND_MANY_FAILED,\n {\n context: {\n source: \"DrizzleAdapter.findManyRawSql\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Builds a SQL WHERE clause string for raw SQL queries.\n * @private\n */\n // eslint-disable-next-line complexity\n private buildSqlWhereClause(options: BuildWhereClauseOptions): string {\n const { field, operator, value, params, startIndex } = options;\n let clause = \"\";\n\n switch (operator) {\n case \"eq\":\n clause = ` WHERE \"${field}\" = $${startIndex}`;\n params.push(value);\n break;\n case \"ne\":\n clause = ` WHERE \"${field}\" != $${startIndex}`;\n params.push(value);\n break;\n case \"gt\":\n clause = ` WHERE \"${field}\" > $${startIndex}`;\n params.push(value);\n break;\n case \"gte\":\n clause = ` WHERE \"${field}\" >= $${startIndex}`;\n params.push(value);\n break;\n case \"lt\":\n clause = ` WHERE \"${field}\" < $${startIndex}`;\n params.push(value);\n break;\n case \"lte\":\n clause = ` WHERE \"${field}\" <= $${startIndex}`;\n params.push(value);\n break;\n case \"in\":\n if (Array.isArray(value)) {\n const placeholders = value\n .map((_, i) => `$${startIndex + i}`)\n .join(\", \");\n clause = ` WHERE \"${field}\" IN (${placeholders})`;\n params.push(...value);\n }\n break;\n case \"like\":\n clause = ` WHERE \"${field}\" LIKE $${startIndex}`;\n params.push(value);\n break;\n case \"between\":\n if (Array.isArray(value) && value.length >= BETWEEN_MIN_ELEMENTS) {\n clause = ` WHERE \"${field}\" BETWEEN $${startIndex} AND $${startIndex + 1}`;\n params.push(value[0], value[1]);\n }\n break;\n case \"isNull\":\n clause = ` WHERE \"${field}\" IS NULL`;\n break;\n case \"isNotNull\":\n clause = ` WHERE \"${field}\" IS NOT NULL`;\n break;\n default:\n break;\n }\n\n return clause;\n }\n\n /**\n * Inserts a new record into the specified table.\n * @template T - The expected type of the record.\n * @param {string} table - Table name.\n * @param {T} data - Record to insert.\n * @returns {Promise<DatabaseResult<T>>} Inserted record.\n * @description\n * Inserts a new record into the specified table using the provided data.\n * The method uses the registered table to construct the insert query.\n * After insertion, it returns the inserted record with any auto-generated fields\n * (like IDs) populated. If an error occurs during the operation,\n * a failure result with an error message is returned.\n *\n * **Auto-registers tables**: If table is not registered with PgTable schema,\n * falls back to raw SQL mode (same behavior as SQLAdapter).\n */\n async create<T>(table: string, data: T): Promise<DatabaseResult<T>> {\n try {\n // Check if we should use raw SQL mode\n if (this.isStringMode(table)) {\n return this.createRawSql<T>(table, data);\n }\n\n const tableObj = this.getTable(table);\n const result = await this.db\n .insert(tableObj)\n .values(data as Record<string, T>)\n .returning();\n return success(result[0] as T);\n } catch (error) {\n // If error is USE_STRING_MODE, retry with raw SQL\n if (\n error instanceof DatabaseError &&\n error.message === \"USE_STRING_MODE\"\n ) {\n return this.createRawSql<T>(table, data);\n }\n return failure(\n new DatabaseError(\n `Failed to create in table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.CREATE_FAILED,\n {\n context: {\n source: \"DrizzleAdapter.create\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Raw SQL fallback for create when no PgTable schema is registered.\n * @private\n */\n private async createRawSql<T>(\n table: string,\n data: T,\n ): Promise<DatabaseResult<T>> {\n try {\n const tableName = this.getStringTableName(table);\n const keys = Object.keys(data as Record<string, unknown>);\n const values = Object.values(data as Record<string, unknown>);\n const placeholders = values.map((_, i) => `$${i + 1}`).join(\", \");\n const escapedKeys = keys.map((k) => `\"${k}\"`).join(\", \");\n\n const sqlQuery = `INSERT INTO \"${tableName}\" (${escapedKeys}) VALUES (${placeholders}) RETURNING *`;\n const result = await this.pool.query(sqlQuery, values);\n\n return success(result.rows[0] as T);\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to create in table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.CREATE_FAILED,\n {\n context: {\n source: \"DrizzleAdapter.createRawSql\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Updates an existing record by ID.\n * @template T - The expected type of the record.\n * @param {string} table - Table name.\n * @param {string} id - Record ID.\n * @param {Partial<T>} data - Partial object containing fields to update.\n * @returns {Promise<DatabaseResult<T>>} Updated record.\n * @description\n * Updates an existing record in the specified table using its primary ID.\n * Only the fields provided in the data object are updated, allowing for partial updates.\n * The method uses the registered table and ID column to construct the update query.\n * After updating, it returns the updated record. If an error occurs during the operation,\n * a failure result with an error message is returned.\n *\n * **Auto-registers tables**: If table is not registered with PgTable schema,\n * falls back to raw SQL mode (same behavior as SQLAdapter).\n */\n async update<T>(\n table: string,\n id: string,\n data: Partial<T>,\n ): Promise<DatabaseResult<T>> {\n try {\n // Check if we should use raw SQL mode\n if (this.isStringMode(table)) {\n return this.updateRawSql<T>(table, id, data);\n }\n\n const tableObj = this.getTable(table);\n const idColumn = this.getIdColumn(table);\n const result = await this.db\n .update(tableObj)\n .set(data as Record<string, T>)\n .where(eq(idColumn, id))\n .returning();\n return success(result[0] as T);\n } catch (error) {\n // If error is USE_STRING_MODE, retry with raw SQL\n if (\n error instanceof DatabaseError &&\n error.message === \"USE_STRING_MODE\"\n ) {\n return this.updateRawSql<T>(table, id, data);\n }\n return failure(\n new DatabaseError(\n `Failed to update in table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.UPDATE_FAILED,\n {\n context: {\n source: \"DrizzleAdapter.update\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Raw SQL fallback for update when no PgTable schema is registered.\n * @private\n */\n private async updateRawSql<T>(\n table: string,\n id: string,\n data: Partial<T>,\n ): Promise<DatabaseResult<T>> {\n try {\n const tableName = this.getStringTableName(table);\n const idColumn = this.getStringIdColumn(table);\n const keys = Object.keys(data as Record<string, unknown>);\n const values = Object.values(data as Record<string, unknown>);\n const setClause = keys.map((key, i) => `\"${key}\" = $${i + 1}`).join(\", \");\n\n const sqlQuery = `UPDATE \"${tableName}\" SET ${setClause} WHERE \"${idColumn}\" = $${keys.length + 1} RETURNING *`;\n const result = await this.pool.query(sqlQuery, [...values, id]);\n\n return success(result.rows[0] as T);\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to update in table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.UPDATE_FAILED,\n {\n context: {\n source: \"DrizzleAdapter.updateRawSql\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Deletes a record by ID.\n * @param {string} table - Table name.\n * @param {string} id - Record ID.\n * @returns {Promise<DatabaseResult<void>>}\n * @description\n * Deletes a record from the specified table using its primary ID.\n * The method uses the registered table and ID column to construct the delete query.\n * If the operation is successful, it returns a success result with no value.\n * If an error occurs during the operation, a failure result with an error message is returned.\n *\n * **Auto-registers tables**: If table is not registered with PgTable schema,\n * falls back to raw SQL mode (same behavior as SQLAdapter).\n */\n async delete(table: string, id: string): Promise<DatabaseResult<void>> {\n try {\n // Check if we should use raw SQL mode\n if (this.isStringMode(table)) {\n return this.deleteRawSql(table, id);\n }\n\n const tableObj = this.getTable(table);\n const idColumn = this.getIdColumn(table);\n await this.db.delete(tableObj).where(eq(idColumn, id));\n return success();\n } catch (error) {\n // If error is USE_STRING_MODE, retry with raw SQL\n if (\n error instanceof DatabaseError &&\n error.message === \"USE_STRING_MODE\"\n ) {\n return this.deleteRawSql(table, id);\n }\n return failure(\n new DatabaseError(\n `Failed to delete from table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.DELETE_FAILED,\n {\n context: {\n source: \"DrizzleAdapter.delete\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Raw SQL fallback for delete when no PgTable schema is registered.\n * @private\n */\n private async deleteRawSql(\n table: string,\n id: string,\n ): Promise<DatabaseResult<void>> {\n try {\n const tableName = this.getStringTableName(table);\n const idColumn = this.getStringIdColumn(table);\n const sqlQuery = `DELETE FROM \"${tableName}\" WHERE \"${idColumn}\" = $1`;\n await this.pool.query(sqlQuery, [id]);\n return success();\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to delete from table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.DELETE_FAILED,\n {\n context: {\n source: \"DrizzleAdapter.deleteRawSql\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Executes a transactional operation with rollback on failure.\n * @template T - The expected type of the transaction result.\n * @param {(trx: Transaction) => Promise<T>} callback - Function executed within a transaction.\n * @returns {Promise<DatabaseResult<T>>} Transaction result.\n * @description\n * Executes a callback function within a database transaction, providing atomicity.\n * If the callback function executes successfully, the transaction is committed.\n * If an error occurs during the execution of the callback function, the transaction\n * is rolled back, ensuring that no partial changes are applied to the database.\n * The method returns the result of the callback function if successful,\n * or a failure result with an error message if an error occurs.\n *\n * **Auto-registers tables**: Transaction operations use raw SQL mode for unregistered tables.\n */\n async transaction<T>(\n callback: (trx: Transaction) => Promise<T>,\n ): Promise<DatabaseResult<T>> {\n const client: PoolClient = await this.pool.connect();\n try {\n await client.query(\"BEGIN\");\n const trxDb = drizzle(client);\n\n // Transaction operations that support both PgTable and raw SQL modes\n const trx: Transaction = {\n findById: async <T>(table: string, id: string) => {\n // Use raw SQL for unregistered tables\n if (this.isStringMode(table)) {\n const tableName = this.getStringTableName(table);\n const idColumn = this.getStringIdColumn(table);\n const sqlQuery = `SELECT * FROM \"${tableName}\" WHERE \"${idColumn}\" = $1 LIMIT 1`;\n const result = await client.query(sqlQuery, [id]);\n return success((result.rows[0] as T) || null);\n }\n const tableObj = this.getTable(table);\n const idColumn = this.getIdColumn(table);\n const result = await trxDb\n .select()\n .from(tableObj)\n .where(eq(idColumn, id))\n .limit(1);\n return success((result[0] as T) || null);\n },\n create: async <T>(table: string, data: T) => {\n // Use raw SQL for unregistered tables\n if (this.isStringMode(table)) {\n const tableName = this.getStringTableName(table);\n const keys = Object.keys(data as Record<string, unknown>);\n const values = Object.values(data as Record<string, unknown>);\n const placeholders = values.map((_, i) => `$${i + 1}`).join(\", \");\n const escapedKeys = keys.map((k) => `\"${k}\"`).join(\", \");\n const sqlQuery = `INSERT INTO \"${tableName}\" (${escapedKeys}) VALUES (${placeholders}) RETURNING *`;\n const result = await client.query(sqlQuery, values);\n return success(result.rows[0] as T);\n }\n const tableObj = this.getTable(table);\n const result = await trxDb\n .insert(tableObj)\n .values(data as Record<string, T>)\n .returning();\n return success(result[0] as T);\n },\n update: async <T>(table: string, id: string, data: Partial<T>) => {\n // Use raw SQL for unregistered tables\n if (this.isStringMode(table)) {\n const tableName = this.getStringTableName(table);\n const idColumn = this.getStringIdColumn(table);\n const keys = Object.keys(data as Record<string, unknown>);\n const values = Object.values(data as Record<string, unknown>);\n const setClause = keys\n .map((key, i) => `\"${key}\" = $${i + 1}`)\n .join(\", \");\n const sqlQuery = `UPDATE \"${tableName}\" SET ${setClause} WHERE \"${idColumn}\" = $${keys.length + 1} RETURNING *`;\n const result = await client.query(sqlQuery, [...values, id]);\n return success(result.rows[0] as T);\n }\n const tableObj = this.getTable(table);\n const idColumn = this.getIdColumn(table);\n const result = await trxDb\n .update(tableObj)\n .set(data as Record<string, T>)\n .where(eq(idColumn, id))\n .returning();\n return success(result[0] as T);\n },\n delete: async (table: string, id: string) => {\n // Use raw SQL for unregistered tables\n if (this.isStringMode(table)) {\n const tableName = this.getStringTableName(table);\n const idColumn = this.getStringIdColumn(table);\n const sqlQuery = `DELETE FROM \"${tableName}\" WHERE \"${idColumn}\" = $1`;\n await client.query(sqlQuery, [id]);\n return success();\n }\n const tableObj = this.getTable(table);\n const idColumn = this.getIdColumn(table);\n await trxDb.delete(tableObj).where(eq(idColumn, id));\n return success();\n },\n commit: async () => {\n await client.query(\"COMMIT\");\n },\n rollback: async () => {\n await client.query(\"ROLLBACK\");\n },\n };\n\n const result = await callback(trx);\n await trx.commit();\n return success(result);\n } catch (error) {\n await client.query(\"ROLLBACK\");\n return failure(\n new DatabaseError(\n `Transaction failed: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.TRANSACTION_FAILED,\n {\n context: {\n source: \"DrizzleAdapter.transaction\",\n },\n cause: error as Error,\n },\n ),\n );\n } finally {\n client.release();\n }\n }\n\n /**\n * Checks if a record exists by ID.\n * @param {string} table - Table name.\n * @param {string} id - Record ID.\n * @returns {Promise<DatabaseResult<boolean>>} True if exists, otherwise false.\n * @description\n * Checks if a record with the specified ID exists in the table.\n * The method uses the registered table and ID column to construct the query.\n * It returns a success result with a boolean value indicating whether the record exists.\n * If an error occurs during the operation, a failure result with an error message is returned.\n *\n * **Auto-registers tables**: If table is not registered with PgTable schema,\n * falls back to raw SQL mode (same behavior as SQLAdapter).\n */\n async exists(table: string, id: string): Promise<DatabaseResult<boolean>> {\n try {\n // Check if we should use raw SQL mode\n if (this.isStringMode(table)) {\n const tableName = this.getStringTableName(table);\n const idColumn = this.getStringIdColumn(table);\n const sqlQuery = `SELECT 1 FROM \"${tableName}\" WHERE \"${idColumn}\" = $1 LIMIT 1`;\n const result = await this.pool.query(sqlQuery, [id]);\n return success(result.rows.length > 0);\n }\n\n const tableObj = this.getTable(table);\n const idColumn = this.getIdColumn(table);\n const result = await this.db\n .select({ exists: sql`1` })\n .from(tableObj)\n .where(eq(idColumn, id))\n .limit(1);\n return success(!!result.length);\n } catch (error) {\n // If error is USE_STRING_MODE, retry with raw SQL\n if (\n error instanceof DatabaseError &&\n error.message === \"USE_STRING_MODE\"\n ) {\n const tableName = this.getStringTableName(table);\n const idColumn = this.getStringIdColumn(table);\n const sqlQuery = `SELECT 1 FROM \"${tableName}\" WHERE \"${idColumn}\" = $1 LIMIT 1`;\n const result = await this.pool.query(sqlQuery, [id]);\n return success(result.rows.length > 0);\n }\n return failure(\n new DatabaseError(\n `Failed to check existence in table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.EXISTS_FAILED,\n {\n context: {\n source: \"DrizzleAdapter.exists\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Counts records matching an optional filter.\n * @param {string} table - Table name.\n * @param {Filter} [filter] - Optional filter object.\n * @returns {Promise<DatabaseResult<number>>} Total count of matching records.\n * @description\n * Counts the number of records in the specified table that match the optional filter.\n * The method uses the registered table to construct the count query.\n * If a filter is provided, it is applied to narrow down the count to matching records.\n * It returns a success result with the count of matching records.\n * If an error occurs during the operation, a failure result with an error message is returned.\n *\n * **Auto-registers tables**: If table is not registered with PgTable schema,\n * falls back to raw SQL mode (same behavior as SQLAdapter).\n */\n async count<T extends Record<string, unknown> = Record<string, unknown>>(\n table: string,\n filter?: Filter<T>,\n ): Promise<DatabaseResult<number>> {\n try {\n // Check if we should use raw SQL mode\n if (this.isStringMode(table)) {\n return this.countRawSql(table, filter);\n }\n\n const tableObj = this.getTable(table);\n\n const baseQuery = this.db\n .select({ count: sql<number>`count(*)::int` })\n .from(tableObj);\n\n const query =\n filter && this.buildWhereClause(filter, tableObj)\n ? baseQuery.where(this.buildWhereClause(filter, tableObj) as SQL)\n : baseQuery;\n\n const result = await query;\n const countValue = result.length > 0 ? result[0].count : 0;\n\n return success(Number(countValue));\n } catch (error) {\n // If error is USE_STRING_MODE, retry with raw SQL\n if (\n error instanceof DatabaseError &&\n error.message === \"USE_STRING_MODE\"\n ) {\n return this.countRawSql(table, filter);\n }\n return failure(\n new DatabaseError(\n `Failed to count in table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.COUNT_FAILED,\n {\n context: {\n source: \"DrizzleAdapter.count\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Raw SQL fallback for count when no PgTable schema is registered.\n * @private\n */\n private async countRawSql<T extends Record<string, unknown>>(\n table: string,\n filter?: Filter<T>,\n ): Promise<DatabaseResult<number>> {\n try {\n const tableName = this.getStringTableName(table);\n const params: unknown[] = [];\n let whereClause = \"\";\n\n if (filter) {\n const { field, operator, value } = filter;\n whereClause = this.buildSqlWhereClause({\n field,\n operator,\n value,\n params,\n startIndex: 1,\n });\n }\n\n const sqlQuery = `SELECT COUNT(*) as count FROM \"${tableName}\"${whereClause}`;\n const result = await this.pool.query(sqlQuery, params);\n const rowCount = Number.parseInt(result.rows[0].count);\n return success(Number(rowCount));\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to count in table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.COUNT_FAILED,\n {\n context: {\n source: \"DrizzleAdapter.countRawSql\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Performs a health check on the database connection.\n * @returns {Promise<DatabaseResult<DatabaseHealthStatus>>} Health status with response time.\n * @description\n * Checks the health of the database connection by executing a simple query.\n * The method measures the response time of the query to determine the health status.\n * It returns a success result with a HealthStatus object indicating whether the database is healthy,\n * the response time of the health check, and any additional details.\n * If an error occurs during the operation, a failure result with an error message is returned.\n */\n async healthCheck(): Promise<DatabaseResult<DatabaseHealthStatus>> {\n const startTime = Date.now();\n try {\n await this.pool.query(\"SELECT 1\");\n const responseTime = Date.now() - startTime;\n return success({\n isHealthy: true,\n responseTime,\n details: { adapter: \"drizzle\" } as DatabaseHealthStatus[\"details\"],\n });\n } catch (error) {\n const responseTime = Date.now() - startTime;\n return success({\n isHealthy: false,\n responseTime,\n details: {\n adapter: \"drizzle\",\n error: (error as Error).message,\n } as DatabaseHealthStatus[\"details\"],\n });\n }\n }\n\n // --- Private Helpers ---\n\n /**\n * Checks if a table is registered in string mode (raw SQL fallback).\n * @private\n * @param {string} name - Table name.\n * @returns {boolean} True if table is registered in string mode.\n */\n private isStringMode(name: string): boolean {\n return this.stringTableMap.has(name) || !this.tableMap.has(name);\n }\n\n /**\n * Retrieves a registered table by name.\n * @private\n * @param {string} name - Table name.\n * @returns {PgTable} Table object.\n * @throws {DatabaseError} If table is not registered and cannot be auto-registered.\n * @description\n * Retrieves a table object that has been previously registered with the adapter.\n * If the table is not found in PgTable mode, it auto-registers in string mode\n * for raw SQL operations (same behavior as SQLAdapter).\n */\n private getTable(name: string): PgTable {\n try {\n if (!isNonEmptyString(name)) {\n throw new DatabaseError(\n \"Invalid table name\",\n DATABASE_ERROR_CODES.INVALID_TABLE_NAME,\n );\n }\n\n const table = this.tableMap.get(name);\n if (!table) {\n // Auto-register in string mode for raw SQL fallback\n if (!this.stringTableMap.has(name)) {\n this.stringTableMap.set(name, name);\n }\n // Return a placeholder - actual operations will use raw SQL\n throw new DatabaseError(\n \"USE_STRING_MODE\",\n DATABASE_ERROR_CODES.TABLE_NOT_REGISTERED,\n );\n }\n return table;\n } catch (error) {\n throw error instanceof DatabaseError\n ? error\n : new DatabaseError(\n \"Failed to get table\",\n DATABASE_ERROR_CODES.GET_TABLE_FAILED,\n );\n }\n }\n\n /**\n * Gets the string table name for raw SQL operations.\n * @private\n * @param {string} name - Logical table name.\n * @returns {string} Physical table name.\n */\n private getStringTableName(name: string): string {\n let tableName = this.stringTableMap.get(name);\n if (!tableName) {\n // Auto-register table with same name and check for custom ID column from config\n const customIdColumn = this.configIdColumns[name];\n if (customIdColumn) {\n this.stringIdColumnMap.set(name, customIdColumn);\n }\n this.stringTableMap.set(name, name);\n tableName = name;\n }\n return tableName;\n }\n\n /**\n * Gets the string ID column for raw SQL operations.\n * @private\n * @param {string} name - Logical table name.\n * @returns {string} ID column name (defaults to 'id').\n * @description\n * Retrieves the ID column for a table. Checks in this order:\n * 1. Runtime registered ID column (from registerTable calls)\n * 2. Config-provided ID column (from tableIdColumns in config)\n * 3. Default 'id' column\n */\n private getStringIdColumn(name: string): string {\n // Check runtime registered first\n const runtimeIdColumn = this.stringIdColumnMap.get(name);\n if (runtimeIdColumn) {\n return runtimeIdColumn;\n }\n\n // Check config-provided ID columns\n const configIdColumn = this.configIdColumns[name];\n if (configIdColumn) {\n return configIdColumn;\n }\n\n // Default to 'id'\n return \"id\";\n }\n\n /**\n * Retrieves the registered ID column for a table.\n * @private\n * @param {string} name - Table name.\n * @returns {PgColumn} ID column.\n * @throws {DatabaseError} If ID column is not registered.\n * @description\n * Retrieves the ID column that has been previously registered for a table.\n * This method is used internally by other methods to ensure that operations that require\n * the ID column can access it. If the ID column is not found, it throws a DatabaseError.\n */\n private getIdColumn(name: string): PgColumn {\n try {\n if (!isNonEmptyString(name)) {\n throw new DatabaseError(\n \"Invalid table name\",\n DATABASE_ERROR_CODES.INVALID_TABLE_NAME,\n );\n }\n\n const idColumn = this.idColumnMap.get(name);\n if (!idColumn) {\n throw new DatabaseError(\n \"ID column is not registered with the adapter\",\n DATABASE_ERROR_CODES.ID_COLUMN_NOT_REGISTERED,\n );\n }\n return idColumn;\n } catch (error) {\n throw error instanceof DatabaseError\n ? error\n : new DatabaseError(\n \"Failed to get ID column\",\n DATABASE_ERROR_CODES.GET_ID_COLUMN_FAILED,\n );\n }\n }\n\n /**\n * Builds a SQL `WHERE` clause based on filter operators.\n * @private\n * @param {Filter} filter - Filter definition.\n * @param {PgTable} table - Table to apply filter on.\n * @returns {SQL | undefined} SQL condition object.\n * @throws {DatabaseError} If column or operator is invalid.\n * @description\n * Builds a SQL WHERE clause based on the provided filter definition.\n * It supports various operators like equality, comparison, and null checks.\n * If the column specified in the filter does not exist in the table, or if the operator\n * is not supported, it throws a DatabaseError. The method returns an SQL object that\n * can be used in queries, or undefined if no valid clause can be constructed.\n */\n // eslint-disable-next-line complexity\n private buildWhereClause<T extends Record<string, unknown>>(\n filter: Filter<T>,\n table: PgTable,\n ): SQL | undefined {\n try {\n if (!isObject(filter)) {\n return undefined;\n }\n\n const { field, operator, value } = filter;\n\n // Validate field name\n if (!isNonEmptyString(field) || !DB_REGEX.isValidFieldName(field)) {\n throw new DatabaseError(\n \"Invalid field name\",\n DATABASE_ERROR_CODES.INVALID_FIELD_NAME,\n );\n }\n\n // Access column from table - field is validated at runtime\n const column = table[field as keyof typeof table] as Column<\n ColumnBaseConfig<ColumnDataType, string>\n >;\n if (!column) {\n throw new DatabaseError(\n \"Column does not exist in table\",\n DATABASE_ERROR_CODES.COLUMN_NOT_EXISTS,\n );\n }\n\n // Drizzle operators work with the column types directly\n switch (operator) {\n case \"eq\":\n return eq(column, value);\n case \"ne\":\n return not(eq(column, value));\n case \"gt\":\n return gt(column, value);\n case \"gte\":\n return gte(column, value);\n case \"lt\":\n return lt(column, value);\n case \"lte\":\n return lte(column, value);\n case \"in\":\n return inArray(column, value as unknown[]);\n case \"notIn\":\n return not(inArray(column, value as unknown[]));\n case \"like\":\n return like(column, value as string);\n case \"between\":\n return between(\n column,\n (value as [unknown, unknown])[0],\n (value as [unknown, unknown])[1],\n );\n case \"isNull\":\n return isNull(column);\n case \"isNotNull\":\n return isNotNull(column);\n default:\n throw new DatabaseError(\n \"Unsupported operator\",\n DATABASE_ERROR_CODES.UNSUPPORTED_OPERATOR,\n );\n }\n } catch (error) {\n throw new DatabaseError(\n \"Failed to build WHERE clause\",\n DATABASE_ERROR_CODES.BUILD_WHERE_FAILED,\n {\n context: {\n source: \"DrizzleAdapter.buildWhereClause\",\n },\n cause: error as Error,\n },\n );\n }\n }\n\n /**\n * Applies sorting to a query using provided field and direction.\n * @private\n * @template TQuery - Type of the query builder.\n * @template TTable - Type of the table.\n * @param {TQuery} query - Drizzle query builder.\n * @param {SortOptions[]} sort - Array of sort conditions.\n * @param {TTable} table - Target table.\n * @returns {TQuery} Modified query with applied sorting.\n * @throws {DatabaseError} If field is invalid or missing.\n * @description\n * Applies sorting to a Drizzle query based on the provided sort options.\n * It supports sorting by multiple fields in ascending or descending order.\n * If a field specified in the sort options does not exist in the table, or is not a valid column,\n * it throws a DatabaseError. The method returns the modified query with the sorting applied.\n */\n private applySorting<\n T extends Record<string, unknown>,\n TQuery extends {\n orderBy: (...columns: (SQL | SQLWrapper | PgColumn)[]) => TQuery;\n },\n TTable extends PgTable,\n >(query: TQuery, sort: SortOptions<T>[], table: TTable): TQuery {\n return sort.reduce((q, { field, direction }) => {\n if (!Object.prototype.hasOwnProperty.call(table, field)) {\n throw new DatabaseError(\n `Column ${field} does not exist in table`,\n DATABASE_ERROR_CODES.COLUMN_NOT_EXISTS,\n );\n }\n\n const key = field as keyof TTable;\n const column = table[key];\n\n if (!(column instanceof PgColumn)) {\n throw new DatabaseError(\n `Field ${field} is not a valid column`,\n DATABASE_ERROR_CODES.INVALID_COLUMN,\n );\n }\n\n return direction === \"asc\"\n ? q.orderBy(asc(column))\n : q.orderBy(desc(column));\n }, query);\n }\n}\n","import type {\n DatabaseAdapterType,\n DatabaseResult,\n PaginatedResult,\n QueryOptions,\n Filter,\n DatabaseHealthStatus,\n Transaction,\n SupabaseAdapterConfig,\n} from \"@plyaz/types/db\";\nimport type { SupabaseClient } from \"@supabase/supabase-js\";\nimport { createClient } from \"@supabase/supabase-js\";\nimport { failure, success } from \"@utils/databaseResultHelpers\";\nimport { DatabaseError } from \"@plyaz/errors\";\nimport { DATABASE_ERROR_CODES } from \"@plyaz/types/errors\";\n\nimport { calculatePagination } from \"@utils/pagination\";\nimport { NUMERIX } from \"@plyaz/config\";\n\n/**\n * @class SupabaseAdapter\n * @implements {DatabaseAdapterType}\n * @classdesc\n * Supabase adapter implementation for database operations.\n *\n * This adapter provides an interface to interact with Supabase databases,\n * supporting CRUD operations, transactions, and health checks. It leverages\n * the Supabase JavaScript client to communicate with PostgreSQL databases through\n * Supabase's API. The adapter provides a consistent interface while abstracting\n * away the specifics of Supabase's API calls.\n */\nexport class SupabaseAdapter implements DatabaseAdapterType {\n private client: SupabaseClient;\n private config: SupabaseAdapterConfig;\n private tableMap: Map<string, string> = new Map();\n private idColumnMap: Map<string, string> = new Map();\n private configIdColumns: Record<string, string>;\n\n /**\n * Creates a new SupabaseAdapter instance.\n * @param {SupabaseAdapterConfig} config - Configuration for the Supabase adapter.\n * @description\n * Initializes the adapter with the provided configuration, setting up the Supabase client.\n * The configuration must include a Supabase URL and either a service key or an anonymous key.\n * The adapter maintains internal maps for table names and ID columns to provide a level of\n * abstraction over the database schema. If required configuration values are missing,\n * the constructor throws a DatabaseError.\n * @throws {DatabaseError} If Supabase URL or key is not provided in the configuration.\n */\n constructor(config: SupabaseAdapterConfig) {\n this.config = config;\n // Store custom ID column mappings from config\n this.configIdColumns = config.tableIdColumns ?? {};\n\n if (!config.supabaseUrl) {\n throw new DatabaseError(\n \"Supabase URL is required for Supabase adapter\",\n DATABASE_ERROR_CODES.CONFIG_REQUIRED,\n );\n }\n\n const key = config.supabaseServiceKey ?? config.supabaseAnonKey;\n\n if (!key) {\n throw new DatabaseError(\n \"Supabase key is required for Supabase adapter\",\n DATABASE_ERROR_CODES.CONFIG_REQUIRED,\n );\n }\n\n this.client = createClient(config.supabaseUrl, key, {\n auth: {\n persistSession: false,\n autoRefreshToken: false,\n },\n db: {\n schema: (config.schema ?? \"public\") as \"public\",\n },\n });\n }\n\n /**\n * Initializes the Supabase database adapter.\n * @returns {Promise<DatabaseResult<void>>} A promise resolving to a DatabaseResult indicating\n * whether the initialization was successful or failed.\n * @description\n * Validates the Supabase database connection by invoking a simple predefined RPC function (`version`).\n * This method is typically executed during application startup to ensure the adapter can\n * successfully communicate with the database before performing any operations.\n *\n * The method calls the `version` RPC to confirm connectivity. If the RPC function is not defined,\n * it is treated as a non-critical error and the connection is still considered valid. Any other\n * errors are reported as initialization failures.\n */\n async initialize(): Promise<DatabaseResult<void>> {\n try {\n // Verify the database connection by invoking the predefined `version` RPC function.\n const { error } = await this.client.rpc(\"version\");\n\n // If the `version` RPC function does not exist, consider it non-critical — connection is verified.\n if (\n error &&\n !error.message.includes('function \"version\" does not exist')\n ) {\n return failure(\n new DatabaseError(\n `Failed to initialize Supabase adapter: ${error.message}`,\n DATABASE_ERROR_CODES.INIT_FAILED,\n {\n context: {\n source: \"SupabaseAdapter.initialize\",\n },\n cause: error,\n },\n ),\n );\n }\n\n return success();\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to initialize Supabase adapter: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.INIT_FAILED,\n {\n context: {\n source: \"SupabaseAdapter.initialize\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Connect to the database.\n * @returns {Promise<void>} Promise that resolves when connected.\n * @description\n * Supabase handles connections automatically, so this method is a no-op.\n * The Supabase client manages connections internally, establishing them as needed\n * and handling connection pooling. This method is included for interface compatibility\n * but does not perform any connection operations.\n */\n async connect(): Promise<void> {\n // Supabase handles connections automatically\n }\n\n /**\n * Disconnect from the database.\n * @returns {Promise<void>} Promise that resolves when disconnected.\n * @description\n * Supabase handles disconnections automatically, so this method is a no-op.\n * The Supabase client manages connections internally, closing them when appropriate.\n * This method is included for interface compatibility but does not perform any\n * disconnection operations.\n */\n async disconnect(): Promise<void> {\n // Supabase handles disconnections automatically\n }\n\n /**\n * Closes the database connection and cleanup resources.\n * Supabase handles connections automatically, so this just returns success.\n * @returns Promise resolving to DatabaseResult indicating success.\n */\n async close(): Promise<DatabaseResult<void>> {\n await this.disconnect();\n return success();\n }\n\n /**\n * Gets the underlying Supabase client instance.\n * @template TClient - The type of the Supabase client to return.\n * @returns {TClient} The Supabase client instance cast to the specified client type.\n * @description\n * This method provides access to the underlying Supabase client.\n * Although direct access is technically possible, it is discouraged to maintain\n * abstraction and ensure that all database operations go through the adapter’s\n * interface for consistent error handling, logging, and event management.\n */\n getClient<TClient extends object = object>(): TClient {\n return this.client as TClient;\n }\n\n /**\n * Execute a raw SQL query.\n * @template T - The expected type of the query result rows.\n * @param {string} sql - SQL query string.\n * @param {T[]} [params] - Query parameters.\n * @returns {Promise<T[]>} Promise resolving to query results.\n * @description\n * Executes a raw SQL query against the database using Supabase's RPC function.\n * This method is useful for complex queries that cannot be easily expressed using the adapter's\n * built-in methods or for database-specific operations. The method uses parameterized queries\n * to prevent SQL injection attacks. If the query execution fails, a DatabaseError is thrown.\n * Note that this requires a custom RPC function named 'exec_sql' to be set up in your Supabase project.\n */\n async query<T>(sql: string, params?: T[]): Promise<T[]> {\n try {\n const { data, error } = await this.client.rpc(\"exec_sql\", {\n sql,\n params,\n });\n if (error)\n throw new DatabaseError(\n `Failed to execute query: ${sql} - ${error.message}`,\n DATABASE_ERROR_CODES.QUERY_FAILED,\n {\n context: {\n source: \"SupabaseAdapter.query\",\n },\n cause: error,\n },\n );\n return data as T[];\n } catch (error) {\n throw new DatabaseError(\n `Failed to execute query: ${sql} - ${(error as Error).message}`,\n DATABASE_ERROR_CODES.QUERY_FAILED,\n {\n context: {\n source: \"SupabaseAdapter.query\",\n },\n cause: error as Error,\n },\n );\n }\n }\n\n /**\n * Register a table with the adapter.\n * @template TTable - Type representing the table structure.\n * @template TIdColumn - Type representing the ID column.\n * @param {string} name - Logical name for the table.\n * @param {TTable} [table] - Actual table name (defaults to logical name if not provided).\n * @param {TIdColumn} [idColumn] - Optional ID column name.\n * @description\n * Registers a table with the adapter, allowing it to be referenced by a logical name\n * in subsequent operations. This is necessary for the adapter to perform operations\n * on the table. The ID column can also be specified if it differs from the default 'id'.\n * This registration enables the adapter to map logical table names to actual table names\n * and ID columns, providing a layer of abstraction between the application and the database schema.\n * If no table name is provided, the logical name is used as the actual table name.\n */\n registerTable<TTable, TIdColumn>(\n name: string,\n table?: TTable,\n idColumn?: TIdColumn,\n ): void {\n this.tableMap.set(name, (table as string) || name);\n if (idColumn) {\n this.idColumnMap.set(name, idColumn as string);\n }\n }\n\n /**\n * Find a single record by ID.\n * @template T - The expected type of the record.\n * @param {string} table - Table name.\n * @param {string} id - Record ID.\n * @returns {Promise<DatabaseResult<T | null>>} Promise resolving to DatabaseResult containing the record or null.\n * @description\n * Retrieves a single record from the specified table using its primary ID.\n * The method uses Supabase's select method with a filter for the ID column and\n * the single() method to retrieve exactly one record. If the record is found,\n * it is returned in a success result. If no record is found (indicated by error code PGRST116),\n * null is returned in a success result. If an error occurs during the operation,\n * a failure result with an error message is returned.\n */\n async findById<T>(\n table: string,\n id: string,\n ): Promise<DatabaseResult<T | null>> {\n try {\n const tableName = this.getTableName(table);\n const idColumn = this.idColumnMap.get(table) ?? \"id\";\n const { data, error } = await this.client\n .from(tableName)\n .select(\"*\")\n .eq(idColumn, id)\n .single();\n\n if (error) {\n if (error.code === \"PGRST116\") {\n return success();\n }\n return failure(\n new DatabaseError(\n `Failed to find by id in table ${table}: ${error.message}`,\n DATABASE_ERROR_CODES.FIND_BY_ID_FAILED,\n {\n context: {\n source: \"SupabaseAdapter.findById\",\n },\n cause: error,\n },\n ),\n );\n }\n\n return success(data as T);\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to find by id in table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.FIND_BY_ID_FAILED,\n {\n context: {\n source: \"SupabaseAdapter.findById\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Find multiple records with filtering and pagination.\n * @template T - The expected type of the records.\n * @param {string} table - Table name.\n * @param {QueryOptions} [options] - Query options including filters, sorting, and pagination.\n * @returns {Promise<DatabaseResult<PaginatedResult<T>>>} Promise resolving to DatabaseResult containing paginated data.\n * @description\n * Retrieves multiple records from the specified table with support for filtering,\n * sorting, and pagination. The method first executes a count query to get the\n * total number of matching records, then executes the main query with the applied filters,\n * sorting, and pagination. The result includes the data array, total count of matching records,\n * and pagination metadata such as current page, total pages, and limit.\n * If an error occurs during the operation, a failure result with an error message is returned.\n */\n // eslint-disable-next-line complexity\n async findMany<T extends Record<string, unknown>>(\n table: string,\n options?: QueryOptions<T>,\n ): Promise<DatabaseResult<PaginatedResult<T>>> {\n try {\n const tableName = this.getTableName(table);\n let query = this.client.from(tableName).select(\"*\");\n\n // Apply filters if provided\n if (options?.filter) {\n query = this.applyFilter(query, options.filter);\n }\n\n // Get total count for pagination\n let countQuery = this.client\n .from(tableName)\n .select(\"*\", { count: \"exact\", head: true });\n if (options?.filter) {\n countQuery = this.applyFilter(countQuery, options.filter);\n }\n const { count, error: countError } = await countQuery;\n\n if (countError) {\n return failure(\n new DatabaseError(\n `Failed to count records in table ${table}: ${countError.message}`,\n DATABASE_ERROR_CODES.COUNT_FAILED,\n {\n context: {\n source: \"SupabaseAdapter.findMany\",\n },\n cause: countError,\n },\n ),\n );\n }\n\n // Apply sorting if provided\n if (options?.sort) {\n options.sort.forEach((sortOption) => {\n query = query.order(sortOption.field, {\n ascending: sortOption.direction === \"asc\",\n });\n });\n }\n\n // Apply pagination if provided\n if (options?.pagination) {\n if (options.pagination.offset !== undefined) {\n query = query.range(\n options.pagination.offset,\n options.pagination.offset +\n (options.pagination.limit ?? NUMERIX.TEN) -\n 1,\n );\n } else if (options.pagination.limit !== undefined) {\n query = query.limit(options.pagination.limit);\n }\n }\n\n const { data, error } = await query;\n\n if (error) {\n return failure(\n new DatabaseError(\n `Failed to find many in table ${table}: ${error.message}`,\n DATABASE_ERROR_CODES.FIND_MANY_FAILED,\n {\n context: {\n source: \"SupabaseAdapter.findMany\",\n },\n cause: error,\n },\n ),\n );\n }\n\n const total = count ?? 0;\n\n return success({\n data: data as T[],\n total,\n pagination: calculatePagination(total, options?.pagination),\n });\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to find many in table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.FIND_MANY_FAILED,\n {\n context: {\n source: \"SupabaseAdapter.findMany\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Create a new record.\n * @template T - The expected type of the record.\n * @param {string} table - Table name.\n * @param {T} data - Record data to create.\n * @returns {Promise<DatabaseResult<T>>} Promise resolving to DatabaseResult containing the created record.\n * @description\n * Inserts a new record into the specified table using the provided data.\n * The method uses Supabase's insert method with the data and then chains a select()\n * and single() call to retrieve the inserted record with any auto-generated fields\n * (like IDs) populated. If the operation is successful, it returns the created record.\n * If an error occurs during the operation, a failure result with an error message is returned.\n */\n async create<T>(table: string, data: T): Promise<DatabaseResult<T>> {\n try {\n const tableName = this.getTableName(table);\n const { data: result, error } = await this.client\n .from(tableName)\n .insert(data)\n .select()\n .single();\n\n if (error) {\n return failure(\n new DatabaseError(\n `Failed to create in table ${table}: ${error.message}`,\n DATABASE_ERROR_CODES.CREATE_FAILED,\n {\n context: {\n source: \"SupabaseAdapter.create\",\n },\n cause: error,\n },\n ),\n );\n }\n\n return success(result as T);\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to create in table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.CREATE_FAILED,\n {\n context: {\n source: \"SupabaseAdapter.create\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Update an existing record.\n * @template T - The expected type of the record.\n * @param {string} table - Table name.\n * @param {string} id - Record ID.\n * @param {Partial<T>} data - Partial record data to update.\n * @returns {Promise<DatabaseResult<T>>} Promise resolving to DatabaseResult containing the updated record.\n * @description\n * Updates an existing record in the specified table using its primary ID.\n * Only the fields provided in the data object are updated, allowing for partial updates.\n * The method uses Supabase's update method with the data and a filter for the ID column,\n * then chains a select() and single() call to retrieve the updated record. If the operation\n * is successful, it returns the updated record. If an error occurs during the operation,\n * a failure result with an error message is returned.\n */\n async update<T>(\n table: string,\n id: string,\n data: Partial<T>,\n ): Promise<DatabaseResult<T>> {\n try {\n const tableName = this.getTableName(table);\n const idColumn = this.idColumnMap.get(table) ?? \"id\";\n const { data: result, error } = await this.client\n .from(tableName)\n .update(data)\n .eq(idColumn, id)\n .select()\n .single();\n\n if (error) {\n return failure(\n new DatabaseError(\n `Failed to update in table ${table}: ${error.message}`,\n DATABASE_ERROR_CODES.UPDATE_FAILED,\n {\n context: {\n source: \"SupabaseAdapter.update\",\n },\n cause: error,\n },\n ),\n );\n }\n\n return success(result as T);\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to update in table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.UPDATE_FAILED,\n {\n context: {\n source: \"SupabaseAdapter.update\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Delete a record.\n * @param {string} table - Table name.\n * @param {string} id - Record ID.\n * @returns {Promise<DatabaseResult<void>>} Promise resolving to DatabaseResult indicating success or failure.\n * @description\n * Deletes a record from the specified table using its primary ID.\n * The method uses Supabase's delete method with a filter for the ID column.\n * If the operation is successful, it returns a success result with no value.\n * If an error occurs during the operation, a failure result with an error message is returned.\n */\n async delete(table: string, id: string): Promise<DatabaseResult<void>> {\n try {\n const tableName = this.getTableName(table);\n const idColumn = this.idColumnMap.get(table) ?? \"id\";\n const { error } = await this.client\n .from(tableName)\n .delete()\n .eq(idColumn, id);\n\n if (error) {\n return failure(\n new DatabaseError(\n `Failed to delete from table ${table}: ${error.message}`,\n DATABASE_ERROR_CODES.DELETE_FAILED,\n {\n context: {\n source: \"SupabaseAdapter.delete\",\n },\n cause: error,\n },\n ),\n );\n }\n\n return success();\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to delete from table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.DELETE_FAILED,\n {\n context: {\n source: \"SupabaseAdapter.delete\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Execute a transaction.\n * @template T - The expected type of the transaction result.\n * @param {(trx: Transaction) => Promise<T>} callback - Function containing transaction operations.\n * @returns {Promise<DatabaseResult<T>>} Promise resolving to DatabaseResult containing the transaction result.\n * @description\n * Executes a callback function within a database transaction, providing atomicity.\n * Note that Supabase doesn't support traditional multi-statement transactions in the same way\n * as direct database connections. This adapter simulates transactional behavior by executing\n * all operations through the same client, but does not provide true rollback capabilities.\n * If the callback function executes successfully, the transaction is considered committed.\n * If an error occurs during the execution of the callback function, a failure result with\n * an error message is returned, but any successful operations within the callback will not\n * be rolled back.\n */\n async transaction<T>(\n callback: (trx: Transaction) => Promise<T>,\n ): Promise<DatabaseResult<T>> {\n try {\n // Create a transaction object that uses the same client\n const trx: Transaction = {\n findById: async <T>(table: string, id: string) => {\n return this.findById<T>(table, id);\n },\n create: async <T>(table: string, data: T) => {\n return this.create<T>(table, data);\n },\n update: async <T>(table: string, id: string, data: Partial<T>) => {\n return this.update<T>(table, id, data);\n },\n delete: async (table: string, id: string) => {\n return this.delete(table, id);\n },\n commit: async () => {\n // No-op for Supabase\n },\n rollback: async () => {\n // No-op for Supabase\n },\n };\n\n const result = await callback(trx);\n return success(result);\n } catch (error) {\n return failure(\n new DatabaseError(\n `Transaction failed: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.TRANSACTION_FAILED,\n {\n context: {\n source: \"SupabaseAdapter.transaction\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Check if a record exists.\n * @param {string} table - Table name.\n * @param {string} id - Record ID.\n * @returns {Promise<DatabaseResult<boolean>>} Promise resolving to DatabaseResult containing boolean indicating existence.\n * @description\n * Checks if a record with the specified ID exists in the table.\n * The method constructs a SELECT query with a WHERE clause for the ID column\n * and a LIMIT of 1. It returns a success result with a boolean value indicating\n * whether the record exists. If an error occurs during the operation, a failure result\n * with an error message is returned.\n */\n async exists(table: string, id: string): Promise<DatabaseResult<boolean>> {\n try {\n const tableName = this.getTableName(table);\n const idColumn = this.idColumnMap.get(table) ?? \"id\";\n const { data, error } = await this.client\n .from(tableName)\n .select(idColumn)\n .eq(idColumn, id)\n .limit(1);\n\n if (error) {\n return failure(\n new DatabaseError(\n `Failed to check existence in table ${table}: ${error.message}`,\n DATABASE_ERROR_CODES.EXISTS_FAILED,\n {\n context: {\n source: \"SupabaseAdapter.exists\",\n },\n cause: error,\n },\n ),\n );\n }\n return success((data && data.length > 0) || false);\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to check existence in table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.EXISTS_FAILED,\n {\n context: {\n source: \"SupabaseAdapter.exists\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Count records matching a filter.\n * @param {string} table - Table name.\n * @param {Filter} [filter] - Filter conditions.\n * @returns {Promise<DatabaseResult<number>>} Promise resolving to DatabaseResult containing the count.\n * @description\n * Counts the number of records in the specified table that match the optional filter.\n * The method uses Supabase's select method with the count option set to 'exact'\n * and head set to true to return only the count. If a filter is provided,\n * it is applied to narrow down the count to matching records. It returns a success\n * result with the count of matching records. If an error occurs during the operation,\n * a failure result with an error message is returned.\n */\n async count<T extends Record<string, unknown> = Record<string, unknown>>(\n table: string,\n filter?: Filter<T>,\n ): Promise<DatabaseResult<number>> {\n try {\n const tableName = this.getTableName(table);\n let query = this.client\n .from(tableName)\n .select(\"*\", { count: \"exact\", head: true });\n\n if (filter) {\n query = this.applyFilter(query, filter);\n }\n\n const { count, error } = await query;\n\n if (error) {\n return failure(\n new DatabaseError(\n `Failed to count in table ${table}: ${error.message}`,\n DATABASE_ERROR_CODES.COUNT_FAILED,\n {\n context: {\n source: \"SupabaseAdapter.count\",\n },\n cause: error,\n },\n ),\n );\n }\n return success(count ?? 0);\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to count in table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.COUNT_FAILED,\n {\n context: {\n source: \"SupabaseAdapter.count\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Perform health check.\n * @returns {Promise<DatabaseResult<DatabaseHealthStatus>>} Promise resolving to DatabaseResult containing health status.\n * @description\n * Checks the health of the database connection by executing a simple RPC call.\n * The method measures the response time of the query to determine the health status.\n * It attempts to call a 'version' RPC function, ignoring errors related to the function\n * not existing but reporting other errors. It returns a success result with a DatabaseHealthStatus\n * object indicating whether the database is healthy, the response time of the health check,\n * and any additional details. If an error occurs during the operation, a failure result\n * with an error message is returned.\n */\n async healthCheck(): Promise<DatabaseResult<DatabaseHealthStatus>> {\n const startTime = Date.now();\n try {\n const { error } = await this.client.rpc(\"version\");\n const responseTime = Date.now() - startTime;\n\n if (\n error &&\n !error.message.includes('function \"version\" does not exist')\n ) {\n return success({\n isHealthy: false,\n responseTime,\n details: { adapter: \"supabase\", error: error.message },\n });\n }\n return success({\n isHealthy: true,\n responseTime,\n details: { adapter: \"supabase\" },\n });\n } catch (error) {\n const responseTime = Date.now() - startTime;\n return success({\n isHealthy: false,\n responseTime,\n details: { adapter: \"supabase\", error: (error as Error).message },\n });\n }\n }\n\n /**\n * Get the actual table name from the mapped table name.\n * @private\n * @param {string} name - Logical table name.\n * @returns {string} Actual table name.\n * @description\n * Retrieves the actual table name. If not registered, auto-registers it.\n * This enables seamless table operations without manual registration.\n */\n private getTableName(name: string): string {\n let tableName = this.tableMap.get(name);\n if (!tableName) {\n // Auto-register table with same name\n // Only set ID column from config if not already registered (runtime override takes precedence)\n const hasRuntimeIdColumn = this.idColumnMap.has(name);\n const customIdColumn = hasRuntimeIdColumn\n ? undefined\n : this.configIdColumns[name];\n this.registerTable(name, name, customIdColumn);\n tableName = name;\n }\n return tableName;\n }\n\n /**\n * Applies filter conditions to a Supabase query with comprehensive operator support\n *\n * Transforms generic Filter objects into Supabase-specific query methods while maintaining\n * type safety and preventing SQL injection through operator validation.\n *\n * **Supported Operators:**\n * - Equality: eq, ne (not equal)\n * - Comparison: gt, gte, lt, lte\n * - Pattern: like (with % wildcards)\n * - Membership: in, notIn (array values)\n * - Range: between (two-element array)\n * - Null checks: isNull, isNotNull\n *\n * **Security Features:**\n * - Validates field names against regex: /^[a-zA-Z_][a-zA-Z0-9_]*$/\n * - Validates operator against whitelist\n * - Type-checks array values for 'in', 'notIn', 'between' operators\n *\n * @private\n * @template Q - Type of the Supabase query builder\n * @param {Q} query - Supabase query builder instance to apply filters to\n * @param {Filter} filter - Filter conditions with field, operator, and value\n * @returns {Q} Modified query builder with filter conditions applied\n *\n * @throws {BaseError} SUPABASE_INVALID_FILTER - If 'in'/'notIn' value is not an array\n * @throws {BaseError} SUPABASE_INVALID_FILTER - If 'between' value is not a 2-element array\n * @throws {BaseError} SUPABASE_UNSUPPORTED_OPERATOR - If operator is not in whitelist\n *\n * @example\n * ```typescript\n * // Equality filter\n * const query1 = this.applyFilter(baseQuery, {\n * field: 'status',\n * operator: 'eq',\n * value: 'active'\n * });\n * // Generates: query.eq('status', 'active')\n *\n * // Range filter\n * const query2 = this.applyFilter(baseQuery, {\n * field: 'age',\n * operator: 'between',\n * value: [18, 65]\n * });\n * // Generates: query.gte('age', 18).lte('age', 65)\n *\n * // Array membership filter\n * const query3 = this.applyFilter(baseQuery, {\n * field: 'category',\n * operator: 'in',\n * value: ['tech', 'science', 'business']\n * });\n * // Generates: query.in('category', ['tech', 'science', 'business'])\n * ```\n *\n */\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private applyFilter<T extends object = object>(q: any, f: Filter<T>): any {\n const { field, operator, value } = f;\n\n const ops: Record<string, Function> = {\n eq: () => q.eq(field, value),\n ne: () => q.neq(field, value),\n gt: () => q.gt(field, value),\n gte: () => q.gte(field, value),\n lt: () => q.lt(field, value),\n lte: () => q.lte(field, value),\n like: () => q.like(field, value),\n isNull: () => q.is(field, null),\n isNotNull: () => q.isNot(field, null),\n in: () => {\n if (!Array.isArray(value))\n throw new DatabaseError(\n `'in' requires array`,\n DATABASE_ERROR_CODES.INVALID_FILTER,\n );\n return q.in(field, value);\n },\n notIn: () => {\n if (!Array.isArray(value))\n throw new DatabaseError(\n `'notIn' requires array`,\n DATABASE_ERROR_CODES.INVALID_FILTER,\n );\n return q.notIn(field, value);\n },\n between: () => {\n if (!Array.isArray(value) || value.length !== NUMERIX.TWO)\n throw new DatabaseError(\n `'between' requires [min,max]`,\n DATABASE_ERROR_CODES.INVALID_FILTER,\n );\n return q.gte(field, value[0]).lte(field, value[1]);\n },\n };\n\n if (!ops[operator])\n throw new DatabaseError(\n `Unsupported operator: ${operator}`,\n DATABASE_ERROR_CODES.UNSUPPORTED_OPERATOR,\n );\n return ops[operator]();\n }\n}\n","import type { PoolClient } from \"pg\";\nimport { Pool } from \"pg\";\nimport type {\n SQLAdapterConfig,\n Transaction,\n DatabaseResult,\n PaginatedResult,\n QueryOptions,\n DatabaseHealthStatus,\n Filter,\n DatabaseAdapterType,\n} from \"@plyaz/types/db\";\nimport { failure, success } from \"@utils/databaseResultHelpers\";\nimport { DatabaseError } from \"@plyaz/errors\";\nimport { DATABASE_ERROR_CODES } from \"@plyaz/types/errors\";\nimport { calculatePagination } from \"@utils/pagination\";\nimport { isNonEmptyString, isObject } from \"@utils/typeGuards\";\nimport { DB_REGEX } from \"@utils/regex\";\n\n/** Maximum characters of SQL to include in error messages */\nconst SQL_ERROR_TRUNCATE_LENGTH = 500;\n\n/**\n * @class SQLAdapter\n * @implements {DatabaseAdapterType}\n * @classdesc\n * Plain SQL adapter implementation for raw SQL queries.\n *\n * This adapter provides an interface to interact with SQL databases using raw SQL queries,\n * supporting CRUD operations, transactions, and health checks. It uses PostgreSQL's node-pg\n * driver for database connectivity and provides a simple, direct SQL interface without\n * ORM abstractions. This adapter is ideal for applications that require direct control\n * over SQL queries or need to leverage database-specific features.\n */\nexport class SQLAdapter implements DatabaseAdapterType {\n private pool: Pool;\n private config: SQLAdapterConfig;\n private tableMap: Map<string, string> = new Map();\n private idColumnMap: Map<string, string> = new Map();\n private configIdColumns: Record<string, string>;\n private defaultSchema: string;\n private showSqlInErrors: boolean;\n\n /**\n * Creates a new SQLAdapter instance.\n * @param {SQLAdapterConfig} config - Configuration for the SQL adapter.\n * @description\n * Initializes the adapter with the provided configuration, setting up the connection pool\n * for PostgreSQL database connections. The configuration should include a connection string\n * and optional pool settings such as min/max connections and idle timeout. The adapter\n * maintains internal maps for table names and ID columns to provide a level of abstraction\n * over the raw database schema.\n */\n constructor(config: SQLAdapterConfig) {\n this.config = config;\n this.defaultSchema = config.schema ?? \"public\";\n this.showSqlInErrors = config.showSqlInErrors ?? true;\n this.pool = new Pool({\n connectionString: config.connectionString,\n ...config.pool,\n });\n // Store custom ID column mappings from config\n this.configIdColumns = config.tableIdColumns ?? {};\n }\n\n /**\n * Get fully-qualified table name with schema\n */\n private getQualifiedTableName(table: string, schema?: string): string {\n const targetSchema = schema ?? this.defaultSchema;\n\n // If table already has schema prefix (e.g., \"tenant_acme.users\"), use as-is\n if (table.includes(\".\")) {\n return table;\n }\n\n // Apply schema prefix\n return `${targetSchema}.${table}`;\n }\n\n /**\n * Initialize the adapter.\n * @returns {Promise<DatabaseResult<void>>} Promise resolving to DatabaseResult indicating success or failure.\n * @description\n * Tests the database connection by attempting to establish a connection to the database.\n * This method is typically called during application startup to verify that the adapter\n * can communicate with the database before performing any operations. Returns a success\n * result if the connection is established, or a failure result with an error if the\n * connection cannot be established.\n */\n async initialize(): Promise<DatabaseResult<void>> {\n try {\n const client = await this.pool.connect();\n\n // Set search_path for the connection if schema is configured\n if (this.defaultSchema && this.defaultSchema !== \"public\") {\n await client.query(`SET search_path TO ${this.defaultSchema}, public`);\n }\n\n client.release();\n return success();\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to initialize PlainSQL adapter: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.INIT_FAILED,\n {\n context: {\n source: \"SQLAdapter.initialize\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Connect to the database.\n * @returns {Promise<void>} Promise that resolves when connected.\n * @description\n * Establishes a connection to the PostgreSQL database using the connection pool.\n * This method is called to ensure that a connection is available before performing database operations.\n * The connection pool manages the connections efficiently, reusing them when possible.\n */\n async connect(): Promise<void> {\n await this.pool.connect();\n }\n\n /**\n * Disconnect from the database.\n * @returns {Promise<void>} Promise that resolves when disconnected.\n * @description\n * Gracefully shuts down the connection pool, closing all active connections.\n * This method should be called when the adapter is no longer needed, typically during\n * application shutdown, to free up database resources and prevent connection leaks.\n */\n async disconnect(): Promise<void> {\n await this.pool.end();\n }\n\n /**\n * Closes the database connection and cleanup resources.\n * @returns Promise resolving to DatabaseResult indicating success or failure.\n */\n async close(): Promise<DatabaseResult<void>> {\n try {\n await this.disconnect();\n return success();\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to close connection: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.DISCONNECT_FAILED,\n ),\n );\n }\n }\n\n /**\n * Gets the underlying PostgreSQL client instance.\n * @template TClient - The type of the database client to return.\n * @returns {TClient} The PostgreSQL pool instance cast to the specified client type.\n * @description\n * This method provides access to the underlying PostgreSQL connection pool.\n * While direct access is technically possible, it is generally discouraged to\n * preserve abstraction and ensure all database operations go through the adapter’s\n * interface for consistent error handling, logging, and event management.\n */\n getClient<TClient extends object = object>(): TClient {\n return this.pool as TClient;\n }\n\n /**\n * Execute a raw SQL query.\n * @template T - The expected type of the query result rows.\n * @param {string} sql - SQL query string.\n * @param {T[]} [params] - Query parameters.\n * @returns {Promise<T[]>} Promise resolving to query results.\n * @description\n * Executes a raw SQL query against the database, with optional parameterization.\n * This method is useful for complex queries that cannot be easily expressed using the adapter's\n * built-in methods or for database-specific operations. The method uses parameterized queries\n * to prevent SQL injection attacks. If the query execution fails, a DatabaseError is thrown.\n */\n async query<T>(sql: string, params?: T[]): Promise<T[]> {\n try {\n const result = await this.pool.query(sql, params);\n return result.rows as T[];\n } catch (error) {\n // Optionally include SQL in error message for debugging (default: true)\n const truncatedSql = sql.slice(0, SQL_ERROR_TRUNCATE_LENGTH);\n const sqlSuffix = sql.length > SQL_ERROR_TRUNCATE_LENGTH ? \"...\" : \"\";\n const errorMessage = this.showSqlInErrors\n ? `SQL Error: ${(error as Error).message}\\n Query: ${truncatedSql}${sqlSuffix}`\n : `SQL Error: ${(error as Error).message}`;\n\n throw new DatabaseError(errorMessage, DATABASE_ERROR_CODES.QUERY_FAILED, {\n context: {\n source: \"SQLAdapter.query\",\n },\n cause: error as Error,\n });\n }\n }\n\n /**\n * Register a table with the adapter.\n * @template TTable - Type representing the table structure.\n * @template TIdColumn - Type representing the ID column.\n * @param {string} name - Logical name for the table.\n * @param {TTable} [table] - Table name or object.\n * @param {TIdColumn} [idColumn] - Optional ID column name.\n * @description\n * Registers a table with the adapter, allowing it to be referenced by a logical name\n * in subsequent operations. This is necessary for the adapter to perform operations\n * on the table. The ID column can also be specified if it differs from the default 'id'.\n * This registration enables the adapter to map logical table names to actual table names\n * and ID columns, providing a layer of abstraction between the application and the database schema.\n */\n registerTable<TTable, TIdColumn>(\n name: string,\n table?: TTable,\n idColumn?: TIdColumn,\n ): void {\n this.tableMap.set(name, table as string);\n\n if (idColumn) {\n this.idColumnMap.set(name, idColumn as string);\n }\n }\n\n /**\n * Find a single record by ID.\n * @template T - The expected type of the record.\n * @param {string} table - Table name.\n * @param {string} id - Record ID.\n * @returns {Promise<DatabaseResult<T | null>>} Promise resolving to DatabaseResult containing the record or null.\n * @description\n * Retrieves a single record from the specified table using its primary ID.\n * The method constructs a SELECT query with a WHERE clause for the ID column.\n * If the record is found, it is returned in a success result. If no record is found,\n * null is returned in a success result. If an error occurs during the operation,\n * a failure result with an error message is returned.\n */\n async findById<T>(\n table: string,\n id: string,\n ): Promise<DatabaseResult<T | null>> {\n try {\n const validationError = this.validateBasicParams(table, id);\n if (validationError) return failure(validationError);\n\n const tableName = this.getTableName(table);\n const qualifiedTable = this.getQualifiedTableName(tableName);\n const idColumn = this.getIdColumn(table);\n const sql = `SELECT * FROM ${qualifiedTable} WHERE \"${idColumn}\" = $1`;\n const result = await this.pool.query(sql, [id]);\n\n if (!result?.rows) {\n return failure(\n new DatabaseError(\n \"Invalid query result\",\n DATABASE_ERROR_CODES.INVALID_RESULT,\n ),\n );\n }\n\n return success((result.rows?.[0] as T) ?? null);\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to find record: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.FIND_BY_ID_FAILED,\n {\n context: {\n source: \"SQLAdapter.findById\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Find multiple records with filtering and pagination.\n * @template T - The expected type of the records.\n * @param {string} table - Table name.\n * @param {QueryOptions} [options] - Query options including filters, sorting, and pagination.\n * @returns {Promise<DatabaseResult<PaginatedResult<object>>>} Promise resolving to DatabaseResult containing paginated data.\n * @description\n * Retrieves multiple records from the specified table with support for filtering,\n * sorting, and pagination. The method constructs a SELECT query with optional WHERE,\n * ORDER BY, LIMIT, and OFFSET clauses. It first executes a COUNT query to get the\n * total number of matching records, then executes the main query with the applied filters,\n * sorting, and pagination. The result includes the data array, total count of matching records,\n * and pagination metadata such as current page, total pages, and offset.\n * If an error occurs during the operation, a failure result with an error message is returned.\n */\n /**\n * Finds multiple records from the specified table with optional filtering, sorting, and pagination.\n * @template TRecord - Type representing the shape of records returned.\n * @template TOptions - Query options type.\n * @template TParam - Type of query parameters (primitives).\n * @param {string} table - Name of the table to query.\n * @param {TOptions} [options] - Optional query options for filtering, sorting, and pagination.\n * @returns {Promise<DatabaseResult<PaginatedResult<TRecord>>>} - A promise resolving to a paginated result.\n * @throws {DatabaseError} - When query execution or initialization fails.\n */\n /**\n * Finds multiple records from the specified table with optional filtering, sorting, and pagination.\n * @template T - Type representing the shape of records returned.\n * @param {string} table - Name of the table to query.\n * @param {QueryOptions<object>} [options] - Optional query options for filtering, sorting, and pagination.\n * @returns {Promise<DatabaseResult<PaginatedResult<T>>>} - A promise resolving to a paginated result.\n * @throws {DatabaseError} - When query execution or initialization fails.\n */\n // eslint-disable-next-line complexity\n async findMany<T extends Record<string, unknown>>(\n table: string,\n options?: QueryOptions<T>,\n ): Promise<DatabaseResult<PaginatedResult<T>>> {\n try {\n const tableName = this.getTableName(table);\n const qualifiedTable = this.getQualifiedTableName(tableName);\n const params: Object[] = [];\n let whereClause = \"\";\n let paramIndex = 1;\n\n // Build WHERE clause\n if (options?.filter) {\n whereClause = this.buildWhereClause(options.filter, params, paramIndex);\n paramIndex += params.length;\n }\n\n // Count total\n const countSql = `SELECT COUNT(*) as total FROM ${qualifiedTable}${whereClause}`;\n const countResult = await this.pool.query(countSql, params);\n\n if (!countResult.rows || countResult.rows.length === 0) {\n throw new DatabaseError(\n \"Count query returned no results\",\n DATABASE_ERROR_CODES.COUNT_NO_RESULTS,\n );\n }\n\n const total = Number.parseInt(countResult.rows[0].total);\n if (isNaN(total) || total < 0) {\n throw new DatabaseError(\n \"Invalid count result\",\n DATABASE_ERROR_CODES.INVALID_COUNT,\n );\n }\n\n // ORDER BY clause\n let orderClause = \"\";\n if (options?.sort?.length) {\n orderClause =\n \" ORDER BY \" +\n options.sort\n .map((s) => `${s.field} ${s.direction.toUpperCase()}`)\n .join(\", \");\n }\n\n // LIMIT & OFFSET\n let limitClause = \"\";\n if (options?.pagination?.limit) {\n limitClause += ` LIMIT $${paramIndex++}`;\n params.push(options.pagination.limit);\n }\n if (options?.pagination?.offset) {\n limitClause += ` OFFSET $${paramIndex++}`;\n params.push(options.pagination.offset);\n }\n\n // Final query\n const sql = `SELECT * FROM ${qualifiedTable}${whereClause}${orderClause}${limitClause}`;\n const result = await this.pool.query(sql, params);\n\n return success({\n data: result.rows as T[],\n total,\n pagination: calculatePagination(total, options?.pagination),\n });\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to find many in table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.FIND_MANY_FAILED,\n {\n context: {\n source: \"SQLAdapter.findMany\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Create a new record.\n * @template T - The expected type of the record.\n * @param {string} table - Table name.\n * @param {T} data - Record data to create.\n * @returns {Promise<DatabaseResult<T>>} Promise resolving to DatabaseResult containing the created record.\n * @description\n * Inserts a new record into the specified table using the provided data.\n * The method constructs an INSERT query with column names and parameter placeholders\n * for the values. After insertion, it returns the inserted record with any auto-generated\n * fields (like IDs) populated using the RETURNING clause. If an error occurs during the operation,\n * a failure result with an error message is returned.\n */\n async create<T>(table: string, data: T): Promise<DatabaseResult<T>> {\n try {\n const validationError = this.validateCreateParams(table, data);\n if (validationError) return failure(validationError);\n\n const tableName = this.getTableName(table);\n const qualifiedTable = this.getQualifiedTableName(tableName);\n const keys = Object.keys(data as Record<string, T>);\n const values = Object.values(data as Record<string, T>);\n const placeholders = values.map((_, i) => `$${i + 1}`).join(\", \");\n const escapedKeys = keys.map((k) => `\"${k}\"`).join(\", \");\n\n const sql = `INSERT INTO ${qualifiedTable} (${escapedKeys}) VALUES (${placeholders}) RETURNING *`;\n const result = await this.pool.query(sql, values);\n\n if (!result?.rows?.length) {\n return failure(\n new DatabaseError(\n \"Insert operation failed\",\n DATABASE_ERROR_CODES.INSERT_FAILED,\n ),\n );\n }\n\n return success(result.rows[0] as T);\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to create record: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.CREATE_FAILED,\n {\n context: {\n source: \"SQLAdapter.create\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Update an existing record.\n * @template T - The expected type of the record.\n * @param {string} table - Table name.\n * @param {string} id - Record ID.\n * @param {Partial<T>} data - Partial record data to update.\n * @returns {Promise<DatabaseResult<T>>} Promise resolving to DatabaseResult containing the updated record.\n * @description\n * Updates an existing record in the specified table using its primary ID.\n * Only the fields provided in the data object are updated, allowing for partial updates.\n * The method constructs an UPDATE query with a SET clause for the fields to update\n * and a WHERE clause for the ID. After updating, it returns the updated record using\n * the RETURNING clause. If an error occurs during the operation, a failure result with\n * an error message is returned.\n */\n async update<T>(\n table: string,\n id: string,\n data: Partial<T>,\n ): Promise<DatabaseResult<T>> {\n try {\n const validationError = this.validateUpdateParams(table, id, data);\n if (validationError) return failure(validationError);\n\n const tableName = this.getTableName(table);\n const qualifiedTable = this.getQualifiedTableName(tableName);\n const keys = Object.keys(data as Record<string, T>);\n const values = Object.values(data as Record<string, T>);\n const setClause = keys.map((key, i) => `\"${key}\" = $${i + 1}`).join(\", \");\n const idColumn = this.getIdColumn(table);\n\n const sql = `UPDATE ${qualifiedTable} SET ${setClause} WHERE \"${idColumn}\" = $${keys.length + 1} RETURNING *`;\n const result = await this.pool.query(sql, [...values, id]);\n\n if (!result.rows?.length) {\n return failure(\n new DatabaseError(\n \"Record not found or no changes made\",\n DATABASE_ERROR_CODES.UPDATE_NO_CHANGES,\n ),\n );\n }\n\n return success(result.rows[0] as T);\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to update record: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.UPDATE_FAILED,\n {\n context: {\n source: \"SQLAdapter.update\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Delete a record.\n * @param {string} table - Table name.\n * @param {string} id - Record ID.\n * @returns {Promise<DatabaseResult<void>>} Promise resolving to DatabaseResult indicating success or failure.\n * @description\n * Deletes a record from the specified table using its primary ID.\n * The method constructs a DELETE query with a WHERE clause for the ID column.\n * If the operation is successful, it returns a success result with no value.\n * If an error occurs during the operation, a failure result with an error message is returned.\n */\n async delete(table: string, id: string): Promise<DatabaseResult<void>> {\n try {\n if (!table || !id) {\n return failure(\n new DatabaseError(\n \"Invalid parameters\",\n DATABASE_ERROR_CODES.INVALID_PARAMS,\n ),\n );\n }\n\n const tableName = this.getTableName(table);\n const qualifiedTable = this.getQualifiedTableName(tableName);\n const idColumn = this.getIdColumn(table);\n const sql = `DELETE FROM ${qualifiedTable} WHERE \"${idColumn}\" = $1`;\n const result = await this.pool.query(sql, [id]);\n\n if (!result) {\n return failure(\n new DatabaseError(\n \"Delete operation failed\",\n DATABASE_ERROR_CODES.DELETE_FAILED,\n ),\n );\n }\n\n return success();\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to delete record: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.DELETE_FAILED,\n {\n context: {\n source: \"SQLAdapter.delete\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Execute a transaction.\n * @template T - The expected type of the transaction result.\n * @param {(trx: Transaction) => Promise<T>} callback - Function containing transaction operations.\n * @returns {Promise<DatabaseResult<T>>} Promise resolving to DatabaseResult containing the transaction result.\n * @description\n * Executes a callback function within a database transaction, providing atomicity.\n * If the callback function executes successfully, the transaction is committed.\n * If an error occurs during the execution of the callback function, the transaction\n * is rolled back, ensuring that no partial changes are applied to the database.\n * The method returns the result of the callback function if successful,\n * or a failure result with an error message if an error occurs.\n * The transaction object passed to the callback provides methods for performing\n * database operations within the transaction.\n */\n async transaction<T>(\n callback: (trx: Transaction) => Promise<T>,\n ): Promise<DatabaseResult<T>> {\n const client: PoolClient = await this.pool.connect();\n try {\n await client.query(\"BEGIN\");\n\n const trx: Transaction = {\n findById: async <T>(table: string, id: string) => {\n const tableName = this.getTableName(table);\n const qualifiedTable = this.getQualifiedTableName(tableName);\n const idColumn = this.getIdColumn(table);\n const sql = `SELECT * FROM ${qualifiedTable} WHERE \"${idColumn}\" = $1`;\n const result = await client.query(sql, [id]);\n return success((result.rows[0] as T) ?? null);\n },\n create: async <T>(table: string, data: T) => {\n const tableName = this.getTableName(table);\n const qualifiedTable = this.getQualifiedTableName(tableName);\n const keys = Object.keys(data as Record<string, T>);\n const values = Object.values(data as Record<string, T>);\n const placeholders = values.map((_, i) => `$${i + 1}`).join(\", \");\n const escapedKeys = keys.map((k) => `\"${k}\"`).join(\", \");\n\n const sql = `INSERT INTO ${qualifiedTable} (${escapedKeys}) VALUES (${placeholders}) RETURNING *`;\n const result = await client.query(sql, values);\n return success(result.rows[0] as T);\n },\n update: async <T>(table: string, id: string, data: Partial<T>) => {\n const tableName = this.getTableName(table);\n const qualifiedTable = this.getQualifiedTableName(tableName);\n const keys = Object.keys(data as Record<string, T>);\n const values = Object.values(data as Record<string, T>);\n const setClause = keys\n .map((key, i) => `\"${key}\" = $${i + 1}`)\n .join(\", \");\n const idColumn = this.getIdColumn(table);\n\n const sql = `UPDATE ${qualifiedTable} SET ${setClause} WHERE \"${idColumn}\" = $${keys.length + 1} RETURNING *`;\n const result = await client.query(sql, [...values, id]);\n return success(result.rows[0] as T);\n },\n delete: async (table: string, id: string) => {\n const tableName = this.getTableName(table);\n const qualifiedTable = this.getQualifiedTableName(tableName);\n const idColumn = this.getIdColumn(table);\n const sql = `DELETE FROM ${qualifiedTable} WHERE \"${idColumn}\" = $1`;\n await client.query(sql, [id]);\n return success();\n },\n commit: async () => {\n await client.query(\"COMMIT\");\n },\n rollback: async () => {\n await client.query(\"ROLLBACK\");\n },\n };\n\n const result = await callback(trx);\n await trx.commit();\n return success(result);\n } catch (error) {\n await client.query(\"ROLLBACK\");\n return failure(\n new DatabaseError(\n `Transaction failed: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.TRANSACTION_FAILED,\n {\n context: {\n source: \"SQLAdapter.transaction\",\n },\n cause: error as Error,\n },\n ),\n );\n } finally {\n client.release();\n }\n }\n\n /**\n * Check if a record exists.\n * @param {string} table - Table name.\n * @param {string} id - Record ID.\n * @returns {Promise<DatabaseResult<boolean>>} Promise resolving to DatabaseResult containing boolean indicating existence.\n * @description\n * Checks if a record with the specified ID exists in the table.\n * The method constructs a SELECT query with a WHERE clause for the ID column\n * and a LIMIT of 1. It returns a success result with a boolean value indicating\n * whether the record exists. If an error occurs during the operation, a failure result\n * with an error message is returned.\n */\n async exists(table: string, id: string): Promise<DatabaseResult<boolean>> {\n try {\n const tableName = this.getTableName(table);\n const qualifiedTable = this.getQualifiedTableName(tableName);\n const idColumn = this.getIdColumn(table);\n const sql = `SELECT 1 FROM ${qualifiedTable} WHERE \"${idColumn}\" = $1 LIMIT 1`;\n const result = await this.pool.query(sql, [id]);\n return success(result.rows.length > 0);\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to check existence in table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.EXISTS_FAILED,\n {\n context: {\n source: \"SQLAdapter.exists\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Count records matching a filter.\n * @param {string} table - Table name.\n * @param {Filter} [filter] - Filter conditions.\n * @returns {Promise<DatabaseResult<number>>} Promise resolving to DatabaseResult containing the count.\n * @description\n * Counts the number of records in the specified table that match the optional filter.\n * The method constructs a COUNT query with an optional WHERE clause based on the filter.\n * It returns a success result with the count of matching records.\n * If an error occurs during the operation, a failure result with an error message is returned.\n */\n async count<T extends Record<string, unknown> = Record<string, unknown>>(\n table: string,\n filter?: Filter<T>,\n ): Promise<DatabaseResult<number>> {\n try {\n const tableName = this.getTableName(table);\n const qualifiedTable = this.getQualifiedTableName(tableName);\n let whereClause = \"\";\n let params: object[] = [];\n\n if (filter) {\n whereClause = this.buildWhereClause(filter, params, 1);\n }\n\n const sql = `SELECT COUNT(*) as count FROM ${qualifiedTable}${whereClause}`;\n const result = await this.pool.query(sql, params);\n const rowCount = Number.parseInt(result.rows[0].count);\n return success(Number(rowCount));\n } catch (error) {\n return failure(\n new DatabaseError(\n `Failed to count in table ${table}: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.COUNT_FAILED,\n {\n context: {\n source: \"SQLAdapter.count\",\n },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Perform health check.\n * @returns {Promise<DatabaseResult<DatabaseHealthStatus>>} Promise resolving to DatabaseResult containing health status.\n * @description\n * Checks the health of the database connection by executing a simple query.\n * The method measures the response time of the query to determine the health status.\n * It returns a success result with a HealthStatus object indicating whether the database is healthy,\n * the response time of the health check, and any additional details.\n * If an error occurs during the operation, a failure result with an error message is returned.\n */\n async healthCheck(): Promise<DatabaseResult<DatabaseHealthStatus>> {\n const startTime = Date.now();\n try {\n await this.pool.query(\"SELECT 1\");\n const responseTime = Date.now() - startTime;\n return success({\n isHealthy: true,\n responseTime,\n details: { adapter: \"sql\" },\n });\n } catch (error) {\n const responseTime = Date.now() - startTime;\n return success({\n isHealthy: false,\n responseTime,\n details: { adapter: \"sql\", error: (error as Error).message },\n });\n }\n }\n\n /**\n * Get the actual table name from the mapped table name.\n * @private\n * @param {string} name - Logical table name.\n * @returns {string} Actual table name.\n * @description\n * Retrieves the actual table name. If not registered, auto-registers it with\n * the same logical name as the physical table name. This enables seamless\n * table operations without manual registration (matching Supabase adapter behavior).\n */\n private getTableName(name: string): string {\n let tableName = this.tableMap.get(name);\n if (!tableName) {\n // Auto-register table with same name\n // Only set ID column from config if not already registered (runtime override takes precedence)\n const hasRuntimeIdColumn = this.idColumnMap.has(name);\n const customIdColumn = hasRuntimeIdColumn\n ? undefined\n : this.configIdColumns[name];\n this.registerTable(name, name, customIdColumn);\n tableName = name;\n }\n return tableName;\n }\n\n /**\n * Get the ID column for a table.\n * @private\n * @param {string} table - Logical table name.\n * @returns {string} ID column name (defaults to 'id').\n * @description\n * Retrieves the ID column for a table. Checks in this order:\n * 1. Runtime registered ID column (from registerTable calls)\n * 2. Config-provided ID column (from tableIdColumns in config)\n * 3. Default 'id' column\n */\n private getIdColumn(table: string): string {\n // Check runtime registered first\n const runtimeIdColumn = this.idColumnMap.get(table);\n if (runtimeIdColumn) {\n return runtimeIdColumn;\n }\n\n // Check config-provided ID columns\n const configIdColumn = this.configIdColumns[table];\n if (configIdColumn) {\n return configIdColumn;\n }\n\n // Default to 'id'\n return \"id\";\n }\n\n private validateBasicParams(table: string, id: string): DatabaseError | null {\n if (!table || !id) {\n return new DatabaseError(\n \"Invalid parameters\",\n DATABASE_ERROR_CODES.INVALID_PARAMS,\n );\n }\n return null;\n }\n\n private validateCreateParams<T>(\n table: string,\n data: T,\n ): DatabaseError | null {\n if (!isNonEmptyString(table) || !isObject(data)) {\n return new DatabaseError(\n \"Invalid parameters\",\n DATABASE_ERROR_CODES.INVALID_PARAMS,\n );\n }\n\n const keys = Object.keys(data as Record<string, T>);\n if (keys.length === 0) {\n return new DatabaseError(\n \"No data to insert\",\n DATABASE_ERROR_CODES.NO_DATA,\n );\n }\n\n for (const key of keys) {\n if (!DB_REGEX.isValidFieldName(key)) {\n return new DatabaseError(\n \"Invalid field name\",\n DATABASE_ERROR_CODES.INVALID_FIELD_NAME,\n );\n }\n }\n return null;\n }\n\n private validateUpdateParams<T>(\n table: string,\n id: string,\n data: Partial<T>,\n ): DatabaseError | null {\n if (!isNonEmptyString(table) || !isNonEmptyString(id) || !isObject(data)) {\n return new DatabaseError(\n \"Invalid parameters for update operation\",\n DATABASE_ERROR_CODES.INVALID_UPDATE_PARAMS,\n );\n }\n\n const keys = Object.keys(data as Record<string, T>);\n if (keys.length === 0) {\n return new DatabaseError(\n \"No fields to update\",\n DATABASE_ERROR_CODES.NO_UPDATE_FIELDS,\n );\n }\n\n for (const key of keys) {\n if (!DB_REGEX.isValidFieldName(key)) {\n return new DatabaseError(\n \"Invalid field name\",\n DATABASE_ERROR_CODES.INVALID_FIELD_NAME,\n );\n }\n }\n return null;\n }\n\n /**\n * Builds a SQL WHERE clause string from a provided filter definition.\n *\n * @private\n * @template TParams - Tuple type representing the parameter array.\n * @param {Filter} filter - The filter condition containing the field, operator, and value.\n * @param {TParams} params - Mutable array to collect SQL parameter values.\n * @param {number} startIndex - The starting index for SQL parameter placeholders (e.g., $1, $2, ...).\n * @returns {string} The constructed SQL WHERE clause string.\n * @throws {DatabaseError} If an unsupported operator is encountered or if the filter value type is invalid.\n *\n * @description\n * This method dynamically builds a SQL WHERE clause based on the provided `filter` object.\n * It supports operators such as:\n * - `eq`, `ne` (equality and inequality)\n * - `gt`, `gte`, `lt`, `lte` (comparison)\n * - `in` (membership in a list)\n * - `like` (pattern matching)\n * - `between` (range)\n * - `isNull`, `isNotNull` (null checks)\n *\n * The function safely constructs parameterized queries by adding each value\n * into the `params` array and referencing it via `$<index>` placeholders,\n * helping to prevent SQL injection attacks.\n */\n\n // eslint-disable-next-line complexity\n private buildWhereClause<\n T extends Record<string, unknown>,\n TParams extends object[],\n >(filter: Filter<T>, params: unknown[], startIndex: number): string {\n const { field, operator, value } = filter;\n let clause = \"\";\n\n switch (operator) {\n case \"eq\":\n clause = ` WHERE ${field} = $${startIndex}`;\n params.push(value);\n break;\n\n case \"ne\":\n clause = ` WHERE ${field} != $${startIndex}`;\n params.push(value);\n break;\n\n case \"gt\":\n clause = ` WHERE ${field} > $${startIndex}`;\n params.push(value);\n break;\n\n case \"gte\":\n clause = ` WHERE ${field} >= $${startIndex}`;\n params.push(value);\n break;\n\n case \"lt\":\n clause = ` WHERE ${field} < $${startIndex}`;\n params.push(value);\n break;\n\n case \"lte\":\n clause = ` WHERE ${field} <= $${startIndex}`;\n params.push(value);\n break;\n\n case \"in\": {\n if (Array.isArray(value)) {\n const arr = value as readonly TParams[];\n const placeholders = arr\n .map((_, i: number) => `$${startIndex + i}`)\n .join(\", \");\n clause = ` WHERE ${field} IN (${placeholders})`;\n params.push(...arr);\n } else {\n throw new DatabaseError(\n `Operator \"in\" requires an array value.`,\n DATABASE_ERROR_CODES.INVALID_IN_OPERATOR,\n );\n }\n break;\n }\n\n case \"like\":\n clause = ` WHERE ${field} LIKE $${startIndex}`;\n params.push(value as TParams);\n break;\n\n case \"between\": {\n if (Array.isArray(value)) {\n const [min, max] = value as [TParams[number], TParams[number]];\n clause = ` WHERE ${field} BETWEEN $${startIndex} AND $${startIndex + 1}`;\n params.push(min, max);\n } else {\n throw new DatabaseError(\n `Operator \"between\" requires a two-element array.`,\n DATABASE_ERROR_CODES.INVALID_BETWEEN_OPERATOR,\n );\n }\n break;\n }\n\n case \"isNull\":\n clause = ` WHERE ${field} IS NULL`;\n break;\n\n case \"isNotNull\":\n clause = ` WHERE ${field} IS NOT NULL`;\n break;\n\n default:\n throw new DatabaseError(\n `Unsupported operator: ${operator}`,\n DATABASE_ERROR_CODES.UNSUPPORTED_OPERATOR,\n );\n }\n\n return clause;\n }\n}\n","/**\n * MockAdapter - In-Memory Database Adapter for Testing\n *\n * Provides a lightweight, in-memory database adapter that mimics\n * the behavior of real database adapters without requiring an actual\n * database connection. Perfect for unit tests and integration tests.\n *\n * @example\n * ```typescript\n * const db = await createDatabaseService({\n * adapter: 'mock',\n * config: {\n * initialData: {\n * users: [{ id: '1', name: 'Test User', email: 'test@example.com' }],\n * campaigns: [{ id: '1', title: 'Test Campaign', creator_id: '1' }]\n * },\n * autoGenerateIds: true\n * }\n * });\n * ```\n */\n\nimport type {\n DatabaseAdapterType,\n DatabaseResult,\n PaginatedResult,\n QueryOptions,\n Transaction,\n DatabaseHealthStatus,\n Filter,\n DbMockAdapterConfig,\n} from \"@plyaz/types/db\";\n\nimport { success, failure } from \"../../utils/databaseResultHelpers\";\nimport { DatabaseError } from \"@plyaz/errors\";\nimport { DATABASE_ERROR_CODES } from \"@plyaz/types/errors\";\nimport { calculatePagination } from \"../../utils/pagination\";\n\n/** Default pagination limit */\nconst DEFAULT_PAGINATION_LIMIT = 50;\n/** Base for random string generation */\nconst RANDOM_STRING_BASE = 36;\n/** Start index for substring in ID generation */\nconst ID_SUBSTRING_START = 2;\n/** End index for substring in ID generation */\nconst ID_SUBSTRING_END = 9;\n/** Required length for between filter values */\nconst BETWEEN_VALUES_LENGTH = 2;\n\n/** Type for table data storage */\ntype TableDataMap = Map<string, Record<string, unknown>>;\n\n/** Filter operator handler type */\ntype FilterOperatorHandler = (\n fieldValue: unknown,\n filterValue: unknown,\n) => boolean;\n\n/** Lookup map for filter operators */\nconst FILTER_OPERATORS: Record<string, FilterOperatorHandler> = {\n eq: (fieldValue, value) => fieldValue === value,\n ne: (fieldValue, value) => fieldValue !== value,\n gt: (fieldValue, value) => (fieldValue as number) > (value as number),\n gte: (fieldValue, value) => (fieldValue as number) >= (value as number),\n lt: (fieldValue, value) => (fieldValue as number) < (value as number),\n lte: (fieldValue, value) => (fieldValue as number) <= (value as number),\n in: (fieldValue, value) =>\n Array.isArray(value) && (value as unknown[]).includes(fieldValue),\n like: (fieldValue, value) =>\n String(fieldValue).toLowerCase().includes(String(value).toLowerCase()),\n between: (fieldValue, value) => {\n const betweenValues = value as [number, number];\n return (\n Array.isArray(betweenValues) &&\n betweenValues.length === BETWEEN_VALUES_LENGTH &&\n (fieldValue as number) >= betweenValues[0] &&\n (fieldValue as number) <= betweenValues[1]\n );\n },\n isNull: (fieldValue) => fieldValue === null || fieldValue === undefined,\n isNotNull: (fieldValue) => fieldValue !== null && fieldValue !== undefined,\n};\n\n/**\n * MockAdapter - In-memory database adapter for testing\n */\nexport class MockAdapter implements DatabaseAdapterType {\n private data: Map<string, Map<string, Record<string, unknown>>> = new Map();\n private config: DbMockAdapterConfig;\n private tableIdColumns: Map<string, string> = new Map();\n private defaultSchema: string;\n private isInitialized = false;\n private transactionDepth = 0;\n private transactionData: Map<\n string,\n Map<string, Record<string, unknown>>\n > | null = null;\n\n constructor(config: Partial<DbMockAdapterConfig> = {}) {\n this.config = {\n autoGenerateIds: true,\n latency: 0,\n failRate: 0,\n ...config,\n } as DbMockAdapterConfig;\n this.defaultSchema = config.schema ?? \"public\";\n\n // Initialize with provided data\n if (config.initialData) {\n this.initializeTableData(config.initialData);\n }\n\n // Register custom ID columns\n if (config.tableIdColumns) {\n for (const [table, idColumn] of Object.entries(config.tableIdColumns)) {\n this.tableIdColumns.set(table, idColumn);\n }\n }\n }\n\n async initialize(): Promise<DatabaseResult<void>> {\n await this.simulateLatency();\n if (this.shouldFail()) {\n return failure(\n new DatabaseError(\n \"Mock initialization failed\",\n DATABASE_ERROR_CODES.INIT_FAILED,\n ),\n );\n }\n\n this.isInitialized = true;\n return success();\n }\n\n async close(): Promise<DatabaseResult<void>> {\n await this.simulateLatency();\n this.data.clear();\n this.isInitialized = false;\n return success();\n }\n\n registerTable<TTable = string, TIdColumn = string>(\n name: string,\n table?: TTable,\n idColumn?: TIdColumn,\n ): void {\n if (idColumn && typeof idColumn === \"string\") {\n this.tableIdColumns.set(name, idColumn);\n }\n\n // Ensure table exists\n if (!this.data.has(name)) {\n this.data.set(name, new Map());\n }\n }\n\n async findById<T>(\n table: string,\n id: string,\n ): Promise<DatabaseResult<T | null>> {\n await this.simulateLatency();\n if (this.shouldFail()) {\n return failure(\n new DatabaseError(\n \"Mock findById failed\",\n DATABASE_ERROR_CODES.FIND_BY_ID_FAILED,\n ),\n );\n }\n\n const tableData = this.getTableData(table);\n const record = tableData.get(id);\n\n return success(record ? ({ ...record } as T) : null);\n }\n\n /**\n * Apply query options (filter, sort) to records\n */\n private applyQueryOptions<T extends Record<string, unknown>>(\n records: Record<string, unknown>[],\n options?: QueryOptions<T>,\n ): Record<string, unknown>[] {\n let result = records;\n if (options?.filter) {\n result = this.applyFilter(result, options.filter);\n }\n if (options?.sort) {\n result = this.applySort(result, options.sort);\n }\n return result;\n }\n\n /**\n * Get pagination params with defaults\n */\n private getPaginationParams<T extends object>(\n options?: QueryOptions<T>,\n ): {\n offset: number;\n limit: number;\n } {\n return {\n offset: options?.pagination?.offset ?? 0,\n limit: options?.pagination?.limit ?? DEFAULT_PAGINATION_LIMIT,\n };\n }\n\n /**\n * Apply pagination to records\n */\n private applyPagination(\n records: Record<string, unknown>[],\n offset: number,\n limit: number,\n ): Record<string, unknown>[] {\n return records.slice(offset, offset + limit);\n }\n\n async findMany<T extends Record<string, unknown>>(\n table: string,\n options?: QueryOptions<T>,\n ): Promise<DatabaseResult<PaginatedResult<T>>> {\n await this.simulateLatency();\n if (this.shouldFail()) {\n return failure(\n new DatabaseError(\n \"Mock findMany failed\",\n DATABASE_ERROR_CODES.FIND_MANY_FAILED,\n ),\n );\n }\n\n const tableData = this.getTableData(table);\n const allRecords = Array.from(tableData.values());\n const filteredRecords = this.applyQueryOptions(allRecords, options);\n const total = filteredRecords.length;\n const { offset, limit } = this.getPaginationParams(options);\n const paginatedRecords = this.applyPagination(\n filteredRecords,\n offset,\n limit,\n );\n\n return success({\n data: paginatedRecords as T[],\n total,\n pagination: calculatePagination(total, options?.pagination),\n });\n }\n\n async create<T>(table: string, data: T): Promise<DatabaseResult<T>> {\n await this.simulateLatency();\n if (this.shouldFail()) {\n return failure(\n new DatabaseError(\n \"Mock create failed\",\n DATABASE_ERROR_CODES.CREATE_FAILED,\n ),\n );\n }\n\n const tableData = this.getTableData(table);\n const idColumn = this.getIdColumn(table);\n const record = { ...(data as Record<string, unknown>) };\n\n // Generate ID if needed\n if (!record[idColumn] && this.config.autoGenerateIds) {\n record[idColumn] = this.generateId();\n }\n\n const id = record[idColumn];\n if (!id) {\n return failure(\n new DatabaseError(\n \"Record must have an ID\",\n DATABASE_ERROR_CODES.CREATE_FAILED,\n ),\n );\n }\n\n // Add timestamps\n const now = new Date().toISOString();\n record.created_at ??= now;\n record.updated_at ??= now;\n\n tableData.set(String(id), record);\n\n return success(record as T);\n }\n\n async update<T>(\n table: string,\n id: string,\n data: Partial<T>,\n ): Promise<DatabaseResult<T>> {\n await this.simulateLatency();\n if (this.shouldFail()) {\n return failure(\n new DatabaseError(\n \"Mock update failed\",\n DATABASE_ERROR_CODES.UPDATE_FAILED,\n ),\n );\n }\n\n const tableData = this.getTableData(table);\n const existing = tableData.get(id);\n\n if (!existing) {\n return failure(\n new DatabaseError(\n \"Record not found\",\n DATABASE_ERROR_CODES.RECORD_NOT_FOUND,\n ),\n );\n }\n\n const updated = {\n ...existing,\n ...data,\n updated_at: new Date().toISOString(),\n };\n\n tableData.set(id, updated);\n\n return success(updated as T);\n }\n\n async delete(table: string, id: string): Promise<DatabaseResult<void>> {\n await this.simulateLatency();\n if (this.shouldFail()) {\n return failure(\n new DatabaseError(\n \"Mock delete failed\",\n DATABASE_ERROR_CODES.DELETE_FAILED,\n ),\n );\n }\n\n const tableData = this.getTableData(table);\n const existed = tableData.delete(id);\n\n if (!existed) {\n return failure(\n new DatabaseError(\n \"Record not found\",\n DATABASE_ERROR_CODES.RECORD_NOT_FOUND,\n ),\n );\n }\n\n return success();\n }\n\n async transaction<T>(\n callback: (trx: Transaction) => Promise<T>,\n ): Promise<DatabaseResult<T>> {\n await this.simulateLatency();\n\n // Create a snapshot of current data\n const snapshot = new Map<string, TableDataMap>();\n for (const [table, tableData] of this.data.entries()) {\n snapshot.set(table, new Map(tableData));\n }\n\n this.transactionDepth++;\n this.transactionData = snapshot;\n\n try {\n const trx: Transaction = {\n findById: async <T>(table: string, id: string) =>\n this.findById<T>(table, id),\n create: async <T>(table: string, data: T) =>\n this.create<T>(table, data),\n update: async <T>(table: string, id: string, data: Partial<T>) =>\n this.update<T>(table, id, data),\n delete: async (table: string, id: string) => this.delete(table, id),\n commit: async () => {\n /* no-op, auto-committed */\n },\n rollback: async () => {\n // Restore snapshot\n this.data = snapshot;\n },\n };\n\n const result = await callback(trx);\n\n // Transaction succeeded - commit is implicit\n this.transactionDepth--;\n this.transactionData = null;\n\n return success(result);\n } catch (error) {\n // Rollback on error\n this.data = snapshot;\n this.transactionDepth--;\n this.transactionData = null;\n\n return failure(\n new DatabaseError(\n `Transaction failed: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.TRANSACTION_FAILED,\n { cause: error as Error },\n ),\n );\n }\n }\n\n async exists(table: string, id: string): Promise<DatabaseResult<boolean>> {\n await this.simulateLatency();\n const tableData = this.getTableData(table);\n return success(tableData.has(id));\n }\n\n async count<T extends Record<string, unknown> = Record<string, unknown>>(\n table: string,\n filter?: Filter<T>,\n ): Promise<DatabaseResult<number>> {\n await this.simulateLatency();\n const tableData = this.getTableData(table);\n let records = Array.from(tableData.values());\n\n if (filter) {\n records = this.applyFilter(records, filter);\n }\n\n return success(records.length);\n }\n\n async healthCheck(): Promise<DatabaseResult<DatabaseHealthStatus>> {\n await this.simulateLatency();\n\n return success({\n isHealthy: this.isInitialized,\n responseTime: this.config.latency ?? 0,\n details: {\n adapter: \"mock\",\n tables: this.data.size,\n totalRecords: Array.from(this.data.values()).reduce(\n (sum, table) => sum + table.size,\n 0,\n ),\n } as DatabaseHealthStatus[\"details\"],\n });\n }\n\n // DatabaseAdapterType required methods\n\n async connect(): Promise<void> {\n await this.simulateLatency();\n // Mock adapter doesn't need actual connection\n }\n\n async disconnect(): Promise<void> {\n await this.close();\n }\n\n getClient(): object {\n return {\n type: \"mock\",\n data: this.data,\n config: this.config,\n };\n }\n\n async query<T>(): Promise<T[]> {\n await this.simulateLatency();\n // Mock adapter doesn't execute real SQL\n // This is a stub for compatibility\n return [] as T[];\n }\n\n // Utility methods\n\n /**\n * Get fully-qualified table name with schema\n */\n private getQualifiedTableName(table: string, schema?: string): string {\n const targetSchema = schema ?? this.defaultSchema;\n\n // If table already has schema prefix (e.g., \"tenant_acme.users\"), use as-is\n if (table.includes(\".\")) {\n return table;\n }\n\n // For 'public' schema or non-qualified tables, return table name as-is for simplicity\n // This maintains backwards compatibility with existing tests\n if (targetSchema === \"public\") {\n return table;\n }\n\n // Apply schema prefix for non-public schemas\n return `${targetSchema}.${table}`;\n }\n\n private initializeTableData(\n initialData: Record<string, Record<string, unknown>[]>,\n ): void {\n for (const [table, records] of Object.entries(initialData)) {\n const tableData = new Map<string, Record<string, unknown>>();\n const idColumn = this.getIdColumn(table);\n\n for (const record of records) {\n const id = record[idColumn];\n if (id) {\n tableData.set(String(id), { ...record });\n }\n }\n\n this.data.set(table, tableData);\n }\n }\n\n private getTableData(table: string): TableDataMap {\n // Handle schema-qualified table names\n const qualifiedTable = this.getQualifiedTableName(table);\n\n if (!this.data.has(qualifiedTable)) {\n this.data.set(qualifiedTable, new Map());\n }\n return this.data.get(qualifiedTable)!;\n }\n\n private getIdColumn(table: string): string {\n // Strip schema prefix if present to get base table name for ID column lookup\n const baseTable = table.includes(\".\") ? table.split(\".\")[1] : table;\n return this.tableIdColumns.get(baseTable) ?? \"id\";\n }\n\n private generateId(): string {\n return `mock-${Date.now()}-${Math.random().toString(RANDOM_STRING_BASE).substring(ID_SUBSTRING_START, ID_SUBSTRING_END)}`;\n }\n\n private async simulateLatency(): Promise<void> {\n if (this.config.latency && this.config.latency > 0) {\n await new Promise((resolve) => setTimeout(resolve, this.config.latency));\n }\n }\n\n private shouldFail(): boolean {\n if (!this.config.failRate || this.config.failRate <= 0) return false;\n return Math.random() < this.config.failRate;\n }\n\n private applyFilter<T extends Record<string, unknown>>(\n records: Record<string, unknown>[],\n filter: Filter<T>,\n ): Record<string, unknown>[] {\n const { field, operator, value } = filter;\n const handler = FILTER_OPERATORS[operator];\n\n return records.filter((record: Record<string, unknown>) => {\n const fieldValue = record[field];\n return handler ? handler(fieldValue, value) : true;\n });\n }\n\n private applySort(\n records: Record<string, unknown>[],\n sort: Array<{ field: string; direction: \"asc\" | \"desc\" }>,\n ): Record<string, unknown>[] {\n return records.sort((a, b) => {\n for (const { field, direction } of sort) {\n const aVal = a[field];\n const bVal = b[field];\n\n if (aVal === bVal) continue;\n\n const comparison =\n (aVal as string | number) < (bVal as string | number) ? -1 : 1;\n return direction === \"asc\" ? comparison : -comparison;\n }\n return 0;\n });\n }\n\n /**\n * Test utility: Clear all data\n */\n clearAll(): void {\n this.data.clear();\n }\n\n /**\n * Test utility: Get current data for inspection\n */\n getData(\n table?: string,\n ): Record<string, unknown>[] | Record<string, Record<string, unknown>[]> {\n if (table) {\n return Array.from(this.getTableData(table).values());\n }\n\n const result: Record<string, Record<string, unknown>[]> = {};\n for (const [tableName, tableData] of this.data.entries()) {\n result[tableName] = Array.from(tableData.values());\n }\n return result;\n }\n\n /**\n * Test utility: Set data directly\n */\n setData(table: string, records: Record<string, unknown>[]): void {\n const tableData = new Map<string, Record<string, unknown>>();\n const idColumn = this.getIdColumn(table);\n\n for (const record of records) {\n const id = record[idColumn];\n if (id) {\n tableData.set(String(id), { ...record });\n }\n }\n\n this.data.set(table, tableData);\n }\n}\n","/**\n * @fileoverview Adapter Factory for @plyaz/db package\n *\n * This module provides the AdapterFactory class responsible for creating database adapter instances\n * based on configuration. Supports multiple database adapters including Drizzle ORM, Supabase,\n * and raw SQL adapters.\n *\n * Part of the @plyaz/db package factory system that creates the complete adapter chain:\n * AdapterFactory → Base Adapter → Extension Wrappers → Final Adapter Chain\n *\n */\n\nimport { DrizzleAdapter } from \"@adapters/drizzle/DrizzleAdapter\";\nimport { SupabaseAdapter } from \"@adapters/supabase/SupabaseAdapter\";\nimport { SQLAdapter } from \"@adapters/sql/SQLAdapter\";\nimport { MockAdapter } from \"@adapters/mock/MockAdapter\";\nimport type {\n DatabaseAdapterType,\n DatabaseConfig,\n DrizzleAdapterConfig,\n SQLAdapterConfig,\n SupabaseAdapterConfig,\n DbMockAdapterConfig,\n} from \"@plyaz/types/db\";\nimport { ADAPTERS } from \"@plyaz/types/db\";\nimport { DatabaseError } from \"@plyaz/errors\";\nimport { DATABASE_ERROR_CODES } from \"@plyaz/types/errors\";\n\n/**\n * ADAPTER FACTORY - Database Adapter Creation\n *\n * Factory class responsible for creating database adapter instances based on configuration.\n * This is the first step in the adapter chain creation process.\n *\n * **Factory Pattern Implementation:**\n * - Takes adapter type and configuration as input\n * - Returns appropriate DatabaseAdapterType implementation\n * - Handles type safety and error cases\n * - Supports all available database adapters\n *\n * **Supported Adapters:**\n * - DrizzleAdapter: For Drizzle ORM integration\n * - SupabaseAdapter: For Supabase database integration\n * - SQLAdapter: For raw SQL database operations\n *\n * **Usage Flow:**\n * createDatabaseService() → **AdapterFactory.create()** → Base Adapter → Extension Wrappers\n *\n * @example\n * ```typescript\n * // Create Drizzle adapter\n * const drizzleAdapter = AdapterFactory.create(ADAPTERS.DRIZZLE, {\n * adapter: ADAPTERS.DRIZZLE,\n * connection: { host: 'localhost', port: 5432 },\n * database: 'myapp'\n * });\n *\n * // Create Supabase adapter\n * const supabaseAdapter = AdapterFactory.create(ADAPTERS.SUPABASE, {\n * adapter: ADAPTERS.SUPABASE,\n * url: 'https://project.supabase.co',\n * key: 'your-anon-key'\n * });\n * ```\n *\n */\nexport class AdapterFactory {\n /**\n * Creates a new database adapter instance based on the configuration\n *\n * This is the core factory method that instantiates the appropriate database adapter\n * based on the provided type and configuration. Uses TypeScript generics to ensure\n * type safety between adapter type and configuration.\n *\n * **Creation Process:**\n * 1. Validates input parameters (type and config)\n * 2. Uses switch statement to match adapter type\n * 3. Instantiates appropriate adapter class with type-safe config\n * 4. Returns DatabaseAdapterType interface implementation\n *\n * **Type Safety:**\n * - Generic T extends DatabaseConfig ensures config matches adapter type\n * - Type assertions (as DrizzleAdapterConfig) provide compile-time safety\n * - Runtime validation prevents invalid configurations\n *\n * @template T - Database configuration type that extends DatabaseConfig\n * @param {T[\"adapter\"]} type - Adapter type from ADAPTERS enum (drizzle, supabase, sql)\n * @param {T} config - Database configuration object matching the adapter type\n * @returns {DatabaseAdapterType} The appropriate adapter implementation\n *\n * @throws {Error} If adapter type is not provided\n * @throws {Error} If adapter configuration is not provided\n * @throws {Error} If unsupported adapter type is specified\n * @throws {Error} If adapter instantiation fails\n *\n * @example\n * ```typescript\n * // Create Drizzle adapter with PostgreSQL\n * const drizzleAdapter = AdapterFactory.create(ADAPTERS.DRIZZLE, {\n * adapter: ADAPTERS.DRIZZLE,\n * connection: {\n * host: 'localhost',\n * port: 5432,\n * database: 'myapp',\n * user: 'postgres',\n * password: 'password'\n * }\n * });\n *\n * // Create Supabase adapter\n * const supabaseAdapter = AdapterFactory.create(ADAPTERS.SUPABASE, {\n * adapter: ADAPTERS.SUPABASE,\n * url: 'https://xyzcompany.supabase.co',\n * key: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'\n * });\n *\n * // Create SQL adapter for custom database\n * const sqlAdapter = AdapterFactory.create(ADAPTERS.SQL, {\n * adapter: ADAPTERS.SQL,\n * connectionString: 'postgresql://user:pass@localhost:5432/db'\n * });\n * ```\n *\n */\n static create<T extends DatabaseConfig>(\n type: T[\"adapter\"],\n config: T,\n ): DatabaseAdapterType {\n try {\n // Input validation - ensure required parameters are provided\n // This prevents runtime errors from missing configuration\n if (!type) {\n throw new DatabaseError(\n \"Adapter type is required\",\n DATABASE_ERROR_CODES.CONFIG_REQUIRED,\n {\n context: { source: \"AdapterFactory.create\" },\n cause: new Error(\"Adapter type is required\"),\n },\n );\n }\n\n if (!config) {\n throw new DatabaseError(\n \"Adapter configuration is required\",\n DATABASE_ERROR_CODES.CONFIG_REQUIRED,\n {\n context: { source: \"AdapterFactory.create\" },\n cause: new Error(\"Adapter configuration is required\"),\n },\n );\n }\n\n // Adapter instantiation using switch statement for type safety\n // Each case handles a specific adapter type with appropriate configuration casting\n switch (type) {\n // Drizzle ORM adapter - for type-safe database operations\n case ADAPTERS.DRIZZLE:\n return new DrizzleAdapter(config as DrizzleAdapterConfig);\n\n // Supabase adapter - for Supabase backend-as-a-service integration\n case ADAPTERS.SUPABASE:\n return new SupabaseAdapter(config as SupabaseAdapterConfig);\n\n // SQL adapter - for raw SQL operations and custom database integrations\n case ADAPTERS.SQL:\n return new SQLAdapter(config as SQLAdapterConfig);\n\n // Mock adapter - for in-memory testing without real database\n case ADAPTERS.MOCK:\n return new MockAdapter(config as DbMockAdapterConfig);\n\n // Default case - handles unsupported or invalid adapter types\n default:\n throw new DatabaseError(\n `Unsupported adapter type: ${type}`,\n DATABASE_ERROR_CODES.INVALID_PARAMETERS,\n {\n context: { source: \"AdapterFactory.create\" },\n cause: new Error(`Unsupported adapter type: ${type}`),\n },\n );\n }\n } catch (error) {\n // Error handling with context preservation\n // Wraps any instantiation errors with factory-specific context\n throw new DatabaseError(\n `Failed to create adapter: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.INIT_FAILED,\n {\n context: { source: \"AdapterFactory.create\" },\n cause: error as Error,\n },\n );\n }\n }\n}\n","/**\n * @fileoverview Soft Delete Extension for @plyaz/db package\n *\n * This module provides the SoftDeleteAdapter extension that implements logical deletion\n * instead of physical record removal. It automatically intercepts delete operations\n * and converts them to timestamp updates, while filtering queries to exclude soft-deleted records.\n *\n * Part of the @plyaz/db package - a TypeScript database abstraction layer with\n * support for multiple adapters (Drizzle, Supabase, SQL), extensions (audit, encryption,\n * soft delete), and advanced features (caching, read replicas, multi-tenancy).\n *\n */\n\nimport { logger } from \"@plyaz/logger\";\nimport type {\n DatabaseAdapterType,\n DatabaseResult,\n PaginatedResult,\n QueryOptions,\n Filter,\n DatabaseHealthStatus,\n Transaction,\n} from \"@plyaz/types/db\";\nimport { failure, success } from \"@utils/databaseResultHelpers\";\nimport { DatabaseError } from \"@plyaz/errors\";\nimport { DATABASE_ERROR_CODES } from \"@plyaz/types/errors\";\n\n/**\n * SOFT DELETE ADAPTER - Logical Deletion Layer\n *\n * Soft delete extension that implements logical deletion instead of physical removal.\n * Third layer in the adapter chain.\n *\n * **Adapter Chain Position:**\n * ReadReplica -> Audit -> Cache -> **SoftDelete** -> Encryption -> Base Adapter\n *\n * **What this adapter does:**\n * 1. Intercepts delete() operations sets deletedAt timestamp instead of removing\n * 2. Intercepts query/list operations adds \"WHERE deletedAt IS NULL\" filter\n * 3. Provides restore() method to undelete records\n * 4. Honors includeSoftDeleted flag from operation config\n *\n * **Called by:** CachingAdapter (or AuditAdapter if no caching)\n * **Calls:** EncryptionAdapter (or base adapter if no encryption)\n * **Provides:** restore(), permanentDelete() methods\n *\n * **Soft Delete Flow:**\n * - **Delete:** Sets deletedAt = NOW() instead of removing record\n * - **Queries:** Automatically filters WHERE deletedAt IS NULL\n * - **Restore:** Sets deletedAt = NULL to undelete\n *\n * @example\n * ### Configuration\n * ```typescript\n * softDelete: {\n * enabled: true,\n * field: 'deletedAt', // Custom field name\n * excludeTables: ['audit_logs'] // Tables that use hard delete\n * }\n * ```\n *\n * @example\n * ### Usage Flow\n * ```typescript\n * // Normal delete - sets deletedAt timestamp\n * await db.delete(Tables.USERS, 'user-123');\n *\n * // Query automatically excludes soft-deleted records\n * const activeUsers = await db.query(Tables.USERS, {});\n *\n * // Include soft-deleted records with operation config\n * const allUsers = await db.query(Tables.USERS, {}, {\n * includeSoftDeleted: true\n * });\n *\n * // Restore soft-deleted record\n * await db.restore(Tables.USERS, 'user-123');\n * ```\n */\nexport class SoftDeleteAdapter implements DatabaseAdapterType {\n /**\n * Creates a new SoftDeleteAdapter instance.\n *\n * **RESPONSIBILITY:** Wraps base adapter with soft delete functionality\n * **CONFIGURATION:** Sets up deletion field name and excluded tables\n *\n * @param baseAdapter - The underlying database adapter to wrap\n * @param config - Soft delete configuration options\n *\n * @example\n * ```typescript\n * const softDeleteAdapter = new SoftDeleteAdapter(baseAdapter, {\n * enabled: true,\n * field: 'deletedAt',\n * excludeTables: ['audit_logs', 'system_events']\n * });\n * ```\n */\n constructor(\n public baseAdapter: DatabaseAdapterType,\n private config: {\n enabled: boolean;\n field?: string;\n excludeTables?: string[];\n },\n ) {}\n\n /**\n * Initializes the soft delete adapter and underlying adapter.\n *\n * **RESPONSIBILITY:** Passes initialization to base adapter\n * **BEHAVIOR:** No additional initialization needed for soft delete\n *\n * @returns Promise resolving to initialization result\n *\n * @example\n * ```typescript\n * const result = await softDeleteAdapter.initialize();\n * if (result.success) {\n * console.log('Soft delete adapter initialized');\n * }\n * ```\n */\n async initialize(): Promise<DatabaseResult<void>> {\n return this.baseAdapter.initialize();\n }\n\n /**\n * Establishes database connection through base adapter.\n *\n * **RESPONSIBILITY:** Delegates connection to underlying adapter\n * **BEHAVIOR:** No additional connection logic needed\n *\n * @example\n * ```typescript\n * await softDeleteAdapter.connect();\n * console.log('Connected with soft delete support');\n * ```\n */\n async connect(): Promise<void> {\n return this.baseAdapter.connect();\n }\n\n /**\n * Closes database connection through base adapter.\n *\n * **RESPONSIBILITY:** Delegates disconnection to underlying adapter\n * **BEHAVIOR:** No additional cleanup needed for soft delete\n *\n * @example\n * ```typescript\n * await softDeleteAdapter.disconnect();\n * console.log('Disconnected gracefully');\n * ```\n */\n async disconnect(): Promise<void> {\n return this.baseAdapter.disconnect();\n }\n\n async close(): Promise<DatabaseResult<void>> {\n return this.baseAdapter.close();\n }\n\n /**\n * Gets the underlying database client.\n *\n * **RESPONSIBILITY:** Provides access to raw database client\n * **USE CASE:** For operations that bypass soft delete logic\n *\n * @returns Database client object\n *\n * @example\n * ```typescript\n * const client = softDeleteAdapter.getClient();\n * // Use for direct database operations if needed\n * ```\n */\n getClient(): object {\n return this.baseAdapter.getClient();\n }\n\n /**\n * Executes raw SQL query through base adapter.\n *\n * **RESPONSIBILITY:** Passes raw SQL to base adapter without modification\n * **BEHAVIOR:** Does not apply soft delete filtering to raw SQL\n * **NOTE:** Use findMany() for automatic soft delete filtering\n *\n * @param sql - SQL query string\n * @param params - Query parameters\n * @returns Query results\n *\n * @example\n * ```typescript\n * // Raw SQL bypasses soft delete filtering\n * const allUsers = await adapter.query(\n * 'SELECT * FROM users', // Includes soft-deleted records\n * []\n * );\n *\n * // Use findMany for automatic filtering\n * const activeUsers = await adapter.findMany('users'); // Excludes soft-deleted\n * ```\n */\n async query<T>(sql: string, params?: T[]): Promise<T[]> {\n return this.baseAdapter.query(sql, params);\n }\n\n /**\n * Registers a table schema with the base adapter.\n *\n * **RESPONSIBILITY:** Passes table registration to base adapter\n * **BEHAVIOR:** No additional registration logic needed\n *\n * @param name - Table name\n * @param table - Table schema\n * @param idColumn - Primary key column\n *\n * @example\n * ```typescript\n * softDeleteAdapter.registerTable('users', userSchema, 'id');\n * // Table now supports soft delete operations\n * ```\n */\n registerTable<T, U>(name: string, table: T, idColumn?: U): void {\n this.baseAdapter.registerTable(name, table, idColumn);\n }\n\n /**\n * Finds a record by ID with automatic soft delete filtering.\n *\n * **RESPONSIBILITY:** Retrieves single record, excluding soft-deleted by default\n * **FILTERING:** Automatically excludes records where deletedAt IS NOT NULL\n * **OVERRIDE:** Can include soft-deleted records with operation config\n *\n * @param table - Table name\n * @param id - Record ID\n * @returns Found record or null\n *\n * @example\n * ```typescript\n * // Excludes soft-deleted records by default\n * const user = await adapter.findById('users', 'user-123');\n * if (!user.value) {\n * console.log('User not found or soft-deleted');\n * }\n *\n * // Include soft-deleted records with config\n * const userIncludingDeleted = await adapter.findById('users', 'user-123', {\n * includeSoftDeleted: true\n * });\n * ```\n */\n async findById<T>(\n table: string,\n id: string,\n ): Promise<DatabaseResult<T | null>> {\n return this.baseAdapter.findById<T>(table, id);\n }\n\n async findMany<T extends Record<string, unknown>>(\n table: string,\n options?: QueryOptions<T>,\n ): Promise<DatabaseResult<PaginatedResult<T>>> {\n if (!this.config.enabled || this.isExcluded(table)) {\n return this.baseAdapter.findMany<T>(table, options);\n }\n\n // Add soft delete filter unless includeSoftDeleted is true\n const modifiedOptions: QueryOptions<T> = { ...options };\n modifiedOptions.filter ??= {\n field: this.config.field ?? \"deletedAt\",\n operator: \"isNull\",\n value: null,\n } as Filter<T>;\n\n return this.baseAdapter.findMany<T>(table, modifiedOptions);\n }\n\n /**\n * Creates a new record through base adapter.\n *\n * **RESPONSIBILITY:** Passes creation to base adapter without modification\n * **BEHAVIOR:** New records have deletedAt = NULL by default\n *\n * @param table - Table name\n * @param data - Record data\n * @returns Created record\n *\n * @example\n * ```typescript\n * const result = await adapter.create('users', {\n * name: 'John Doe',\n * email: 'john@example.com'\n * // deletedAt will be NULL (not soft-deleted)\n * });\n *\n * if (result.success) {\n * console.log('User created:', result.value.id);\n * }\n * ```\n */\n async create<T extends Record<string, unknown>>(\n table: string,\n data: T,\n ): Promise<DatabaseResult<T>> {\n return this.baseAdapter.create<T>(table, data);\n }\n\n /**\n * Updates an existing record through base adapter.\n *\n * **RESPONSIBILITY:** Passes update to base adapter without modification\n * **BEHAVIOR:** Can update soft-deleted records (they remain soft-deleted)\n * **NOTE:** Use restore() to undelete records\n *\n * @param table - Table name\n * @param id - Record ID\n * @param data - Partial record data\n * @returns Updated record\n *\n * @example\n * ```typescript\n * // Update active record\n * const result = await adapter.update('users', 'user-123', {\n * name: 'Jane Doe'\n * });\n *\n * // Can also update soft-deleted records\n * const softDeletedUpdate = await adapter.update('users', 'deleted-user', {\n * email: 'newemail@example.com'\n * // Record remains soft-deleted after update\n * });\n * ```\n */\n async update<T>(\n table: string,\n id: string,\n data: Partial<T>,\n ): Promise<DatabaseResult<T>> {\n return this.baseAdapter.update<T>(table, id, data);\n }\n\n async delete(table: string, id: string): Promise<DatabaseResult<void>> {\n if (!this.config.enabled || this.isExcluded(table)) {\n return this.baseAdapter.delete(table, id);\n }\n\n // Soft delete: set deletedAt field\n const deleteField = this.config.field ?? \"deletedAt\";\n const updateData = { [deleteField]: new Date().toISOString() };\n\n try {\n logger.debug(`Soft deleting record ${id} from table ${table}`);\n await this.baseAdapter.update(table, id, updateData);\n return success();\n } catch (error) {\n logger.error(`Soft delete failed for ${table}:${id}`);\n return failure(\n new DatabaseError(\n `Soft delete failed: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.DELETE_FAILED,\n {\n context: { source: \"delete\" },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Executes operations within a transaction.\n *\n * **RESPONSIBILITY:** Passes transaction to base adapter\n * **BEHAVIOR:** Soft delete operations within transaction are atomic\n * **ROLLBACK:** Failed transactions rollback soft delete operations\n *\n * @param callback - Transaction callback function\n * @returns Transaction result\n *\n * @example\n * ```typescript\n * const result = await adapter.transaction(async (trx) => {\n * // Create user\n * const user = await trx.create('users', { name: 'John' });\n *\n * // Soft delete old user (sets deletedAt)\n * await trx.delete('users', 'old-user-id');\n *\n * return user;\n * });\n *\n * // If transaction fails, both operations are rolled back\n * ```\n */\n async transaction<T>(\n callback: (trx: Transaction) => Promise<T>,\n ): Promise<DatabaseResult<T>> {\n return this.baseAdapter.transaction(callback);\n }\n\n /**\n * Checks if a record exists, excluding soft-deleted records.\n *\n * **RESPONSIBILITY:** Verifies record existence with soft delete filtering\n * **BEHAVIOR:** Returns false for soft-deleted records by default\n * **FILTERING:** Automatically excludes records where deletedAt IS NOT NULL\n *\n * @param table - Table name\n * @param id - Record ID\n * @returns True if record exists and is not soft-deleted\n *\n * @example\n * ```typescript\n * // Check if active user exists\n * const userExists = await adapter.exists('users', 'user-123');\n * if (userExists.value) {\n * console.log('User exists and is active');\n * } else {\n * console.log('User not found or soft-deleted');\n * }\n *\n * // Soft-deleted records return false\n * await adapter.delete('users', 'user-123'); // Soft delete\n * const stillExists = await adapter.exists('users', 'user-123'); // false\n * ```\n */\n async exists(table: string, id: string): Promise<DatabaseResult<boolean>> {\n return this.baseAdapter.exists(table, id);\n }\n\n /**\n * Counts records in a table, excluding soft-deleted records.\n *\n * **RESPONSIBILITY:** Counts records with automatic soft delete filtering\n * **BEHAVIOR:** Excludes soft-deleted records from count by default\n * **FILTERING:** Automatically adds deletedAt IS NULL filter\n *\n * @param table - Table name\n * @param filter - Optional filter conditions\n * @returns Count of non-soft-deleted records\n *\n * @example\n * ```typescript\n * // Count active users only\n * const activeCount = await adapter.count('users');\n * console.log('Active users:', activeCount.value);\n *\n * // Count with additional filter\n * const premiumActiveUsers = await adapter.count('users', {\n * field: 'plan',\n * operator: 'eq',\n * value: 'premium'\n * });\n * // Returns count of premium users that are NOT soft-deleted\n * ```\n */\n async count<T extends Record<string, unknown> = Record<string, unknown>>(\n table: string,\n filter?: Filter<T>,\n ): Promise<DatabaseResult<number>> {\n return this.baseAdapter.count<T>(table, filter);\n }\n\n /**\n * Performs health check through base adapter.\n *\n * **RESPONSIBILITY:** Delegates health check to underlying adapter\n * **BEHAVIOR:** No additional health metrics for soft delete\n *\n * @returns Health status from base adapter\n *\n * @example\n * ```typescript\n * const health = await adapter.healthCheck();\n * if (health.success && health.value?.isHealthy) {\n * console.log('Database healthy with soft delete support');\n * }\n * ```\n */\n async healthCheck(): Promise<DatabaseResult<DatabaseHealthStatus>> {\n return this.baseAdapter.healthCheck();\n }\n\n /**\n * Restores a previously soft-deleted record by clearing the deletion timestamp\n *\n * Undeletes a record by setting the soft delete field (typically 'deletedAt') to null,\n * making it visible in queries again. This operation is only available when soft delete\n * is enabled in the configuration.\n *\n * **Restore Process:**\n * 1. Validates that soft delete is enabled\n * 2. Sets the deletion field to null via update operation\n * 3. Logs the restoration for audit purposes\n * 4. Returns success or failure result\n *\n * @param {string} table - Name of the table containing the record to restore\n * @param {string} id - Primary key ID of the record to restore\n * @returns {Promise<DatabaseResult<void>>} Promise resolving to success/failure result\n *\n * @example\n * ```typescript\n * // Restore a soft-deleted user\n * const restoreResult = await softDeleteAdapter.restore('users', 'user-123');\n * if (restoreResult.success) {\n * console.log('User restored successfully');\n * } else {\n * console.error('Restore failed:', restoreResult.error.message);\n * }\n *\n * // After restoration, the record will appear in queries again\n * const user = await adapter.findById('users', 'user-123');\n * // user will now be found (not null)\n * ```\n *\n * @throws {DatabaseError} SOFT_DELETE_NOT_ENABLED - If soft delete is not enabled in configuration\n * @throws {DatabaseError} SOFT_DELETE_RESTORE_FAILED - If the restore operation fails\n *\n */\n async restore(table: string, id: string): Promise<DatabaseResult<void>> {\n // Validate that soft delete is enabled before attempting restore\n if (!this.config.enabled) {\n return failure(\n new DatabaseError(\n \"Soft delete not enabled\",\n DATABASE_ERROR_CODES.CONFIG_REQUIRED,\n {\n context: { source: \"restore\" },\n cause: new Error(\"Soft delete not enabled\"),\n },\n ),\n );\n }\n\n // Get the configured deletion field name (default: 'deletedAt')\n const deleteField = this.config.field ?? \"deletedAt\";\n // Create update data to clear the deletion timestamp\n const updateData = { [deleteField]: null };\n\n try {\n // Update the record to clear the deletion timestamp\n await this.baseAdapter.update(table, id, updateData);\n logger.info(`Record restored successfully: ${table}:${id}`);\n return success();\n } catch (error) {\n logger.error(`Restore failed for ${table}:${id}`);\n return failure(\n new DatabaseError(\n `Restore failed: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.UPDATE_FAILED,\n {\n context: { source: \"restore\" },\n cause: error as Error,\n },\n ),\n );\n }\n }\n\n /**\n * Checks if a table is excluded from soft delete functionality.\n * \n * **RESPONSIBILITY:** Determines if table should use hard delete instead\n * **CONFIGURATION:** Based on excludeTables array in config\n * **USE CASE:** Some tables like audit logs need permanent deletion\n * \n * @private\n * @param table - Name of the table to check\n * @returns True if table is excluded from soft delete\n * \n * @example\n * ```typescript\n * // Configuration: { excludeTables: ['audit_logs', 'temp_data'] }\n * \n * this.isExcluded('users'); // false - uses soft delete\n * this.isExcluded('audit_logs'); // true - uses hard delete\n * this.isExcluded('t\n private isExcluded(table: string): boolean {\n return this.config.excludeTables?.includes(table) ?? false;\n }emp_data'); // true - uses hard delete\n * ```\n * \n */\n private isExcluded(table: string): boolean {\n // Check if table is in the excludeTables array, default to false if not configured\n return this.config.excludeTables?.includes(table) ?? false;\n }\n}\n","import { DatabaseError } from \"@plyaz/errors\";\nimport { DATABASE_ERROR_CODES } from \"@plyaz/types/errors\";\nimport { logger } from \"@plyaz/logger\";\nimport type {\n DatabaseAdapterType,\n DatabaseResult,\n Filter,\n DatabaseHealthStatus,\n PaginatedResult,\n QueryOptions,\n Transaction,\n AuditContext,\n AuditEvent,\n} from \"@plyaz/types/db\";\nimport { AUDIT_OPERATION, EXTENSION_SOURCE } from \"@plyaz/types/db\";\n\n/** Minimum width for padded date parts (month, day) */\nconst DATE_PART_MIN_WIDTH = 2;\n\n/** Error source patterns for context-based matching */\nconst CONTEXT_SOURCE_PATTERNS: Array<{\n patterns: string[];\n source: EXTENSION_SOURCE;\n}> = [\n { patterns: [\"encrypt\"], source: EXTENSION_SOURCE.Encryption },\n {\n patterns: [\"softdelete\", \"soft_delete\"],\n source: EXTENSION_SOURCE.SoftDelete,\n },\n { patterns: [\"cach\"], source: EXTENSION_SOURCE.Caching },\n { patterns: [\"audit\"], source: EXTENSION_SOURCE.Audit },\n {\n patterns: [\"replica\", \"read_replica\"],\n source: EXTENSION_SOURCE.ReadReplica,\n },\n {\n patterns: [\"multi_write\", \"multiwrite\"],\n source: EXTENSION_SOURCE.MultiWrite,\n },\n];\n\n/** Error source patterns for message-based matching */\nconst MESSAGE_SOURCE_PATTERNS: Array<{\n patterns: string[];\n source: EXTENSION_SOURCE;\n}> = [\n { patterns: [\"encrypt\"], source: EXTENSION_SOURCE.Encryption },\n {\n patterns: [\"soft delete\", \"softdelete\"],\n source: EXTENSION_SOURCE.SoftDelete,\n },\n { patterns: [\"cache\", \"caching\"], source: EXTENSION_SOURCE.Caching },\n {\n patterns: [\"replica\", \"read replica\"],\n source: EXTENSION_SOURCE.ReadReplica,\n },\n {\n patterns: [\"multi-write\", \"multiwrite\"],\n source: EXTENSION_SOURCE.MultiWrite,\n },\n];\n\n/**\n * AUDIT ADAPTER - Compliance Logging Layer\n *\n * Audit extension that automatically logs all database operations for compliance.\n * Fifth layer in the adapter chain (second from outermost).\n *\n * **Adapter Chain Position:**\n * ReadReplica ļæ½ **Audit** ļæ½ Cache ļæ½ SoftDelete ļæ½ Encryption ļæ½ Base Adapter\n *\n * **What this adapter does:**\n * 1. Captures before-state for update/delete operations\n * 2. Delegates to next adapter in chain\n * 3. Captures after-state and writes audit record to daily audit tables\n * 4. Calls onAuditAfterWrite event handler (if configured)\n * 5. Honors skipAudit flag from operation config\n *\n * **Called by:** ReadReplicaAdapter (or DatabaseService if no read replicas)\n * **Calls:** CachingAdapter (or next adapter in chain)\n * **Writes to:** Daily partitioned audit tables ({schema}.audit_log_yyyy_mm_dd)\n *\n * **Audit Flow:**\n * 1. **CREATE:** Records after-state only\n * 2. **UPDATE:** Records before-state, after-state, and changed fields\n * 3. **DELETE:** Records before-state only\n * 4. **SOFT_DELETE:** Records before/after state with deletedAt change\n *\n * **Audit Context:** Uses context from DatabaseService.setAuditContext()\n * - userId, requestId, ipAddress, userAgent\n *\n * @example\n * ### Configuration\n * ```typescript\n * audit: {\n * enabled: true,\n * retentionDays: 90,\n * excludeFields: ['password', 'token'],\n * excludeTables: ['temp_data'],\n * onAuditAfterWrite: async (event) => {\n * await complianceService.recordAudit(event);\n * }\n * }\n * ```\n *\n * @example\n * ### Audit Record Structure\n * ```typescript\n * // Written to audit_20241201 table\n * {\n * operation: 'UPDATE',\n * table: 'users',\n * recordId: 'user-123',\n * userId: 'admin-456',\n * requestId: 'req-789',\n * changes: {\n * before: { name: 'John Doe', email: 'john@old.com' },\n * after: { name: 'John Smith', email: 'john@new.com' },\n * fields: ['name', 'email']\n * },\n * timestamp: '2024-12-01T10:30:00Z',\n * ipAddress: '192.168.1.1',\n * userAgent: 'Mozilla/5.0...'\n * }\n * ```\n */\nexport class AuditAdapter implements DatabaseAdapterType {\n private auditContext: AuditContext = {};\n // Using shared logger instance from @plyaz/logger\n\n /** Cached schema-qualified table name */\n private auditSchema: string;\n /** Whether to use daily partitioned tables */\n private usePartitionedTables: boolean;\n\n /**\n * Creates a new AuditAdapter instance.\n *\n * **RESPONSIBILITY:** Wraps base adapter with audit logging functionality\n * **CONFIGURATION:** Sets up audit rules, retention, and event handlers\n *\n * @param baseAdapter - The underlying database adapter to wrap\n * @param config - Audit configuration options\n *\n * @example\n * ```typescript\n * const auditAdapter = new AuditAdapter(baseAdapter, {\n * enabled: true,\n * retentionDays: 180,\n * excludeFields: ['password', 'token'],\n * excludeTables: ['temp_data'],\n * schema: 'audit',\n * usePartitionedTables: true,\n * onAuditAfterWrite: async (event) => {\n * await complianceService.recordAudit(event);\n * }\n * });\n * ```\n */\n constructor(\n public baseAdapter: DatabaseAdapterType,\n private config: {\n enabled: boolean;\n retentionDays?: number;\n excludeFields?: string[];\n excludeTables?: string[];\n /** Database schema for audit tables (default: 'audit') */\n schema?: string;\n /** Use daily partitioned tables (audit_log_yyyy_mm_dd format) (default: true) */\n usePartitionedTables?: boolean;\n onAuditAfterWrite?: (event: AuditEvent) => void | Promise<void>;\n /** Encrypted fields config from encryption extension (for audit metadata) */\n encryptedFields?: Record<string, string[]>;\n },\n ) {\n this.auditSchema = config.schema ?? \"audit\";\n this.usePartitionedTables = config.usePartitionedTables ?? true;\n }\n\n /**\n * Initializes the audit adapter and underlying adapter.\n *\n * **RESPONSIBILITY:** Passes initialization to base adapter\n * **BEHAVIOR:** No additional initialization needed for audit\n *\n * @returns Promise resolving to initialization result\n *\n * @example\n * ```typescript\n * const result = await auditAdapter.initialize();\n * if (result.success) {\n * console.log('Audit adapter initialized');\n * }\n * ```\n */\n async initialize(): Promise<DatabaseResult<void>> {\n return this.baseAdapter.initialize();\n }\n\n /**\n * Establishes database connection through base adapter.\n *\n * **RESPONSIBILITY:** Delegates connection to underlying adapter\n * **BEHAVIOR:** No additional connection logic needed\n *\n * @example\n * ```typescript\n * await auditAdapter.connect();\n * console.log('Connected with audit support');\n * ```\n */\n async connect(): Promise<void> {\n return this.baseAdapter.connect();\n }\n\n /**\n * Closes database connection through base adapter.\n *\n * **RESPONSIBILITY:** Delegates disconnection to underlying adapter\n * **BEHAVIOR:** No additional cleanup needed for audit\n *\n * @example\n * ```typescript\n * await auditAdapter.disconnect();\n * console.log('Disconnected gracefully');\n * ```\n */\n async disconnect(): Promise<void> {\n return this.baseAdapter.disconnect();\n }\n\n async close(): Promise<DatabaseResult<void>> {\n return this.baseAdapter.close();\n }\n\n /**\n * Gets the underlying database client.\n *\n * **RESPONSIBILITY:** Provides access to raw database client\n * **USE CASE:** For operations that bypass audit logging\n *\n * @returns Database client object\n *\n * @example\n * ```typescript\n * const client = auditAdapter.getClient();\n * // Use for direct database operations if needed\n * ```\n */\n getClient(): object {\n return this.baseAdapter.getClient();\n }\n\n /**\n * Executes raw SQL query through base adapter.\n *\n * **RESPONSIBILITY:** Passes raw SQL to base adapter without audit logging\n * **BEHAVIOR:** Does not audit raw SQL operations\n * **NOTE:** Use CRUD methods for automatic audit logging\n *\n * @param sql - SQL query string\n * @param params - Query parameters\n * @returns Query results\n *\n * @example\n * ```typescript\n * // Raw SQL bypasses audit logging\n * const results = await adapter.query(\n * 'SELECT * FROM users WHERE status = $1',\n * ['active']\n * );\n *\n * // Use findMany for automatic audit logging\n * const users = await adapter.findMany('users', { filter: ... });\n * ```\n */\n async query<T>(sql: string, params?: T[]): Promise<T[]> {\n return this.baseAdapter.query(sql, params);\n }\n\n /**\n * Registers a table schema with the base adapter.\n *\n * **RESPONSIBILITY:** Passes table registration to base adapter\n * **BEHAVIOR:** No additional registration logic needed\n *\n * @param name - Table name\n * @param table - Table schema\n * @param idColumn - Primary key column\n *\n * @example\n * ```typescript\n * auditAdapter.registerTable('users', userSchema, 'id');\n * // Table now supports audited operations\n * ```\n */\n registerTable<T, U>(name: string, table: T, idColumn?: U): void {\n this.baseAdapter.registerTable(name, table, idColumn);\n }\n\n /**\n * Sets audit context for tracking user actions.\n *\n * **RESPONSIBILITY:** Stores context information for audit records\n * **CONTEXT:** userId, requestId, ipAddress, userAgent\n * **USAGE:** Called by DatabaseService.setAuditContext()\n *\n * @param context - Audit context information\n *\n * @example\n * ```typescript\n * // Usually called by middleware\n * auditAdapter.setAuditContext({\n * userId: 'user-123',\n * requestId: 'req-456',\n * ipAddress: '192.168.1.1',\n * userAgent: 'Mozilla/5.0...'\n * });\n *\n * // Subsequent operations will include this context in audit logs\n * await adapter.create('users', userData); // Audited with context\n * ```\n */\n setAuditContext(context: AuditContext): void {\n this.auditContext = { ...this.auditContext, ...context };\n }\n\n /**\n * Finds a record by ID without audit logging.\n *\n * **RESPONSIBILITY:** Retrieves single record without creating audit trail\n * **BEHAVIOR:** Read operations are not audited by default\n * **PERFORMANCE:** No audit overhead for read operations\n *\n * @param table - Table name\n * @param id - Record ID\n * @returns Found record or null\n *\n * @example\n * ```typescript\n * // Read operations don't create audit records\n * const user = await adapter.findById('users', 'user-123');\n * if (user.success && user.value) {\n * console.log('User found:', user.value.name);\n * }\n * ```\n */\n async findById<T>(\n table: string,\n id: string,\n ): Promise<DatabaseResult<T | null>> {\n return this.baseAdapter.findById<T>(table, id);\n }\n\n /**\n * Finds multiple records without audit logging.\n *\n * **RESPONSIBILITY:** Retrieves multiple records without creating audit trail\n * **BEHAVIOR:** Read operations are not audited by default\n * **PERFORMANCE:** No audit overhead for read operations\n *\n * @param table - Table name\n * @param options - Query options\n * @returns Paginated results\n *\n * @example\n * ```typescript\n * // Read operations don't create audit records\n * const users = await adapter.findMany('users', {\n * filter: { field: 'status', operator: 'eq', value: 'active' },\n * pagination: { page: 1, limit: 10 }\n * });\n *\n * console.log('Found users:', users.value?.data.length);\n * ```\n */\n async findMany<T extends Record<string, unknown>>(\n table: string,\n options?: QueryOptions<T>,\n ): Promise<DatabaseResult<PaginatedResult<T>>> {\n return this.baseAdapter.findMany<T>(table, options);\n }\n\n async create<T extends Record<string, unknown>>(\n table: string,\n data: T,\n ): Promise<DatabaseResult<T>> {\n this.validateCreateParams(table, data);\n\n try {\n const result = await this.baseAdapter.create<T>(table, data);\n\n if (result.success && this.shouldAudit(table)) {\n await this.logAudit({\n operation: AUDIT_OPERATION.Create,\n table,\n recordId: (result.value as Record<string, string>)?.id,\n changes: {\n after: result.value as Record<\n string,\n string | number | boolean | Date\n >,\n encryptedFields: this.getEncryptedFields(table),\n },\n userId: this.auditContext.userId,\n requestId: this.auditContext.requestId,\n timestamp: new Date(),\n ipAddress: this.auditContext.ipAddress,\n userAgent: this.auditContext.userAgent,\n });\n }\n\n return result;\n } catch (error) {\n // Log the failure to audit before re-throwing\n if (this.shouldAudit(table)) {\n await this.logOperationFailure({\n operation: AUDIT_OPERATION.Create,\n table,\n data,\n error: error as Error,\n });\n }\n throw error;\n }\n }\n\n private validateCreateParams<T>(table: string, data: T): void {\n if (!table || !data) {\n throw new DatabaseError(\n \"Invalid parameters for create operation\",\n DATABASE_ERROR_CODES.INVALID_PARAMETERS,\n {\n context: { source: \"validateCreateParams\" },\n cause: new Error(\"Invalid parameters for create operation\"),\n },\n );\n }\n }\n\n async update<T>(\n table: string,\n id: string,\n data: Partial<T>,\n ): Promise<DatabaseResult<T>> {\n // Get before state for audit (before any operation)\n const before = await this.baseAdapter.findById(table, id);\n\n try {\n const result = await this.baseAdapter.update<T>(table, id, data);\n\n if (result.success && this.shouldAudit(table)) {\n await this.logAudit({\n operation: AUDIT_OPERATION.Update,\n table,\n recordId: id,\n changes: {\n before: before.success\n ? (before.value as Record<\n string,\n string | number | boolean | Date\n >)\n : undefined,\n after: result.value as Record<\n string,\n string | number | boolean | Date\n >,\n fields: Object.keys(data),\n encryptedFields: this.getEncryptedFields(table),\n },\n userId: this.auditContext.userId,\n requestId: this.auditContext.requestId,\n timestamp: new Date(),\n ipAddress: this.auditContext.ipAddress,\n userAgent: this.auditContext.userAgent,\n });\n }\n\n return result;\n } catch (error) {\n // Log the failure to audit before re-throwing\n if (this.shouldAudit(table)) {\n await this.logOperationFailure({\n operation: AUDIT_OPERATION.Update,\n table,\n data,\n error: error as Error,\n recordId: id,\n beforeState: before.value,\n });\n }\n throw error;\n }\n }\n\n async delete(table: string, id: string): Promise<DatabaseResult<void>> {\n // Get before state for audit\n const before = await this.baseAdapter.findById(table, id);\n\n try {\n const result = await this.baseAdapter.delete(table, id);\n\n if (result.success && this.shouldAudit(table)) {\n await this.logAudit({\n operation: AUDIT_OPERATION.Delete,\n table,\n recordId: id,\n changes: {\n before: before.success\n ? (before.value as Record<\n string,\n string | number | boolean | Date\n >)\n : undefined,\n },\n userId: this.auditContext.userId,\n requestId: this.auditContext.requestId,\n timestamp: new Date(),\n ipAddress: this.auditContext.ipAddress,\n userAgent: this.auditContext.userAgent,\n });\n }\n\n return result;\n } catch (error) {\n // Log the failure to audit before re-throwing\n if (this.shouldAudit(table)) {\n await this.logOperationFailure({\n operation: AUDIT_OPERATION.Delete,\n table,\n data: null,\n error: error as Error,\n recordId: id,\n beforeState: before.value,\n });\n }\n throw error;\n }\n }\n\n /**\n * Logs operation failures to audit for compliance tracking.\n * Captures the before state, attempted changes, and error details.\n */\n private async logOperationFailure<T>(options: {\n operation: AUDIT_OPERATION;\n table: string;\n data: T | null;\n error: Error;\n recordId?: string;\n beforeState?: unknown;\n }): Promise<void> {\n const { operation, table, data, error, recordId, beforeState } = options;\n\n try {\n // Determine error source (which extension failed)\n const errorSource = this.getErrorSource(error);\n\n // Map operation to failed operation\n const failedOperation = this.getFailedOperation(operation);\n\n await this.logAudit({\n operation: failedOperation,\n table,\n recordId: recordId ?? (data as Record<string, string>)?.id,\n changes: {\n before: beforeState as\n | Record<string, string | number | boolean | Date>\n | undefined,\n attempted: data as\n | Record<string, string | number | boolean | Date>\n | undefined,\n failure: {\n source: errorSource,\n error_type: error.name,\n error_message: error.message,\n error_code: (error as DatabaseError).errorCode,\n },\n },\n userId: this.auditContext.userId,\n requestId: this.auditContext.requestId,\n timestamp: new Date(),\n ipAddress: this.auditContext.ipAddress,\n userAgent: this.auditContext.userAgent,\n });\n } catch (auditError) {\n // Log to console if audit write fails - don't suppress the original error\n logger.error(\n `Failed to log operation failure to audit: ${(auditError as Error).message}`,\n );\n }\n }\n\n /**\n * Maps a successful operation to its failed counterpart.\n */\n private getFailedOperation(operation: AUDIT_OPERATION): AUDIT_OPERATION {\n switch (operation) {\n case AUDIT_OPERATION.Create:\n return AUDIT_OPERATION.CreateFailed;\n case AUDIT_OPERATION.Update:\n return AUDIT_OPERATION.UpdateFailed;\n case AUDIT_OPERATION.Delete:\n return AUDIT_OPERATION.DeleteFailed;\n default:\n return operation;\n }\n }\n\n /**\n * Determines which extension/layer caused the error based on error details.\n */\n private getErrorSource(error: Error): EXTENSION_SOURCE {\n const errorMessage = error.message.toLowerCase();\n const dbError = error as DatabaseError;\n const errorContext = (\n dbError.context as { source?: string }\n )?.source?.toLowerCase();\n\n // Check error context first (most reliable)\n if (errorContext) {\n const contextSource = this.matchPatterns(\n errorContext,\n CONTEXT_SOURCE_PATTERNS,\n );\n if (contextSource) return contextSource;\n }\n\n // Fallback to error message analysis\n const messageSource = this.matchPatterns(\n errorMessage,\n MESSAGE_SOURCE_PATTERNS,\n );\n if (messageSource) return messageSource;\n\n return EXTENSION_SOURCE.DatabaseAdapter;\n }\n\n /**\n * Matches a text against a list of pattern groups.\n */\n private matchPatterns(\n text: string,\n patternGroups: Array<{ patterns: string[]; source: EXTENSION_SOURCE }>,\n ): EXTENSION_SOURCE | null {\n for (const { patterns, source } of patternGroups) {\n if (patterns.some((pattern) => text.includes(pattern))) {\n return source;\n }\n }\n return null;\n }\n\n /**\n * Gets the list of encrypted fields for a table.\n * Returns undefined if no fields are encrypted for this table.\n */\n private getEncryptedFields(table: string): string[] | undefined {\n return this.config.encryptedFields?.[table];\n }\n\n /**\n * Executes operations within a transaction with audit logging.\n *\n * **RESPONSIBILITY:** Passes transaction to base adapter\n * **BEHAVIOR:** Individual operations within transaction are audited\n * **ATOMICITY:** Audit records are part of the transaction\n *\n * @param callback - Transaction callback function\n * @returns Transaction result\n *\n * @example\n * ```typescript\n * const result = await adapter.transaction(async (trx) => {\n * // Each operation creates audit record within transaction\n * const user = await trx.create('users', { name: 'John' });\n * await trx.update('profiles', 'profile-1', { userId: user.id });\n * return user;\n * });\n *\n * // If transaction fails, audit records are also rolled back\n * ```\n */\n async transaction<T>(\n callback: (trx: Transaction) => Promise<T>,\n ): Promise<DatabaseResult<T>> {\n return this.baseAdapter.transaction(callback);\n }\n\n /**\n * Checks if a record exists without audit logging.\n *\n * **RESPONSIBILITY:** Verifies record existence without creating audit trail\n * **BEHAVIOR:** Read operations are not audited by default\n * **PERFORMANCE:** No audit overhead for existence checks\n *\n * @param table - Table name\n * @param id - Record ID\n * @returns True if record exists\n *\n * @example\n * ```typescript\n * // Existence checks don't create audit records\n * const userExists = await adapter.exists('users', 'user-123');\n * if (userExists.value) {\n * console.log('User exists');\n * }\n * ```\n */\n async exists(table: string, id: string): Promise<DatabaseResult<boolean>> {\n return this.baseAdapter.exists(table, id);\n }\n\n /**\n * Counts records without audit logging.\n *\n * **RESPONSIBILITY:** Counts records without creating audit trail\n * **BEHAVIOR:** Read operations are not audited by default\n * **PERFORMANCE:** No audit overhead for counting operations\n *\n * @param table - Table name\n * @param filter - Optional filter conditions\n * @returns Count of records\n *\n * @example\n * ```typescript\n * // Count operations don't create audit records\n * const activeUsers = await adapter.count('users', {\n * field: 'status',\n * operator: 'eq',\n * value: 'active'\n * });\n *\n * console.log('Active users:', activeUsers.value);\n * ```\n */\n async count<T extends Record<string, unknown> = Record<string, unknown>>(\n table: string,\n filter?: Filter<T>,\n ): Promise<DatabaseResult<number>> {\n return this.baseAdapter.count<T>(table, filter);\n }\n\n /**\n * Performs health check through base adapter.\n *\n * **RESPONSIBILITY:** Delegates health check to underlying adapter\n * **BEHAVIOR:** No additional health metrics for audit\n *\n * @returns Health status from base adapter\n *\n * @example\n * ```typescript\n * const health = await adapter.healthCheck();\n * if (health.success && health.value?.isHealthy) {\n * console.log('Database healthy with audit support');\n * }\n * ```\n */\n async healthCheck(): Promise<DatabaseResult<DatabaseHealthStatus>> {\n return this.baseAdapter.healthCheck();\n }\n\n /**\n * Determines if a table should be audited.\n *\n * **RESPONSIBILITY:** Checks if table is enabled for audit logging\n * **CONFIGURATION:** Based on enabled flag and excludeTables array\n *\n * @private\n * @param table - Table name to check\n * @returns True if table should be audited\n *\n * @example\n * ```typescript\n * // Configuration: { enabled: true, excludeTables: ['temp_data'] }\n *\n * this.shouldAudit('users'); // true - will be audited\n * this.shouldAudit('temp_data'); // false - excluded from audit\n * ```\n */\n private shouldAudit(table: string): boolean {\n if (!this.config.enabled) return false;\n return !(this.config.excludeTables?.includes(table) ?? false);\n }\n\n /**\n * Logs an audit event to the audit table and executes custom handlers.\n *\n * **RESPONSIBILITY:** Orchestrates audit record creation and event handling\n * **PROCESS:** Validates event → Writes to audit table → Executes custom handler\n *\n * @private\n * @param event - Audit event to log\n *\n * @example\n * ```typescript\n * // Internal usage after successful operation\n * await this.logAudit({\n * operation: 'CREATE',\n * table: 'users',\n * recordId: 'user-123',\n * changes: { after: userData },\n * userId: 'admin-456',\n * timestamp: new Date()\n * });\n * ```\n */\n private async logAudit(event: AuditEvent): Promise<void> {\n this.validateAuditEvent(event);\n\n await this.writeAuditRecord(event);\n await this.executeCustomHandler(event);\n }\n\n /**\n * Validates audit event has required fields.\n *\n * **RESPONSIBILITY:** Ensures audit event is properly formed\n * **VALIDATION:** Checks for required operation and table fields\n *\n * @private\n * @param event - Audit event to validate\n * @throws {DatabaseError} When event is invalid\n *\n * @example\n * ```typescript\n * // Internal validation before logging\n * this.validateAuditEvent({\n * operation: 'CREATE', // Required\n * table: 'users', // Required\n * recordId: 'user-123'\n * });\n * ```\n */\n private validateAuditEvent(event: AuditEvent): void {\n if (!event?.operation || !event?.table) {\n throw new DatabaseError(\n \"Invalid audit event\",\n DATABASE_ERROR_CODES.INVALID_PARAMETERS,\n {\n context: { source: \"validateAuditEvent\" },\n cause: new Error(\"Invalid audit event\"),\n },\n );\n }\n }\n\n /**\n * Generates the audit table name based on configuration.\n *\n * **RESPONSIBILITY:** Determines the correct table name for audit records\n * **TABLE NAMING:**\n * - Partitioned: `{schema}.audit_log_yyyy_mm_dd` (e.g., audit.audit_log_2024_12_01)\n * - Non-partitioned: `{schema}.audit_logs` (e.g., audit.audit_logs)\n *\n * @private\n * @param timestamp - Timestamp to use for partition date\n * @returns Schema-qualified table name\n */\n private getAuditTableName(timestamp: Date): string {\n if (this.usePartitionedTables) {\n const year = timestamp.getFullYear();\n const month = String(timestamp.getMonth() + 1).padStart(\n DATE_PART_MIN_WIDTH,\n \"0\",\n );\n const day = String(timestamp.getDate()).padStart(\n DATE_PART_MIN_WIDTH,\n \"0\",\n );\n return `${this.auditSchema}.audit_log_${year}_${month}_${day}`;\n }\n return `${this.auditSchema}.audit_logs`;\n }\n\n /**\n * Writes audit record to daily audit table.\n *\n * **RESPONSIBILITY:** Persists audit event to database\n * **TABLE NAMING:** Uses daily partitioned tables (audit.audit_log_yyyy_mm_dd) by default\n * **STRUCTURE:** Converts event to database record format\n *\n * @private\n * @param event - Audit event to write\n * @throws {DatabaseError} When write operation fails\n *\n * @example\n * ```typescript\n * // Internal usage - writes to audit.audit_log_2024_12_01 table\n * await this.writeAuditRecord({\n * operation: 'UPDATE',\n * table: 'users',\n * recordId: 'user-123',\n * changes: { before: {...}, after: {...} },\n * timestamp: new Date('2024-12-01')\n * });\n * ```\n */\n private async writeAuditRecord(event: AuditEvent): Promise<void> {\n const tableName = this.getAuditTableName(event.timestamp);\n try {\n const auditResult = await this.baseAdapter.create(tableName, {\n operation: event.operation,\n table_name: event.table,\n record_id: event.recordId,\n user_id: event.userId,\n request_id: event.requestId,\n changes: event.changes,\n ip_address: event.ipAddress,\n user_agent: event.userAgent,\n timestamp: event.timestamp,\n });\n\n if (!auditResult.success) {\n throw new DatabaseError(\n \"Failed to write audit record\",\n DATABASE_ERROR_CODES.CREATE_FAILED,\n {\n context: { source: \"writeAuditRecord\" },\n cause:\n auditResult.error ?? new Error(\"Failed to write audit record\"),\n },\n );\n }\n } catch (error) {\n logger.error(`Audit write failed: ${(error as Error).message}`);\n throw new DatabaseError(\n \"Failed to write audit record\",\n DATABASE_ERROR_CODES.CREATE_FAILED,\n {\n context: { source: \"writeAuditRecord\" },\n cause: error as Error,\n },\n );\n }\n }\n\n /**\n * Executes custom audit event handler if configured.\n *\n * **RESPONSIBILITY:** Calls user-defined audit event handler\n * **ERROR HANDLING:** Logs handler errors without failing the operation\n * **USE CASE:** Integration with compliance systems, notifications\n *\n * @private\n * @param event - Audit event to handle\n *\n * @example\n * ```typescript\n * // Configuration with custom handler\n * {\n * onAuditAfterWrite: async (event) => {\n * await complianceService.recordAudit(event);\n * await notificationService.sendAuditAlert(event);\n * }\n * }\n *\n * // Handler is called after successful audit record write\n * ```\n */\n private async executeCustomHandler(event: AuditEvent): Promise<void> {\n if (this.config.onAuditAfterWrite) {\n try {\n await this.config.onAuditAfterWrite(event);\n } catch (handlerError) {\n logger.error(\n `Custom audit handler failed: ${(handlerError as Error).message}`,\n );\n }\n }\n }\n}\n","import { createCipheriv, createDecipheriv, randomBytes } from \"crypto\";\nimport {\n type DatabaseAdapterType,\n type DatabaseResult,\n type QueryOptions,\n type PaginatedResult,\n type Transaction,\n type Filter,\n type DatabaseHealthStatus,\n ENCRYPTION_DEFAULTS,\n} from \"@plyaz/types/db\";\nimport { isString, isObject } from \"@utils/typeGuards\";\nimport { DatabaseError } from \"@plyaz/errors\";\nimport { DATABASE_ERROR_CODES } from \"@plyaz/types/errors\";\n\n/**\n * ENCRYPTION ADAPTER — Field-Level Encryption Layer\n *\n * Encryption extension that automatically encrypts/decrypts specified fields.\n * Second layer in the adapter chain (after the base adapter).\n *\n * **Adapter Chain Position:**\n * ReadReplica → Audit → Cache → SoftDelete → **Encryption** → Base Adapter\n *\n * **What this adapter does:**\n * 1. Receives operations from SoftDeleteAdapter (or the next layer)\n * 2. Encrypts sensitive fields before write operations (create, update)\n * 3. Delegates to the base adapter with encrypted data\n * 4. Decrypts fields in response data after read operations\n * 5. Passes results back up the chain\n *\n * **Called by:** SoftDeleteAdapter (or CachingAdapter if no soft delete)\n * **Calls:** Base adapter methods (DrizzleAdapter, SupabaseAdapter, etc.)\n * **Wraps:** Base database adapter with transparent encryption\n *\n * **Encryption Flow:**\n * - **Writes:** Plain data → Encrypt fields → Store encrypted → Return decrypted\n * - **Reads:** Retrieve encrypted → Decrypt fields → Return plain data\n *\n * @example\n * ### Configuration\n * ```typescript\n * encryption: {\n * enabled: true,\n * key: process.env.ENCRYPTION_KEY,\n * fields: {\n * [Tables.USERS]: ['ssn', 'taxId'],\n * [Tables.PAYMENTS]: ['cardNumber', 'cvv']\n * }\n * }\n * ```\n *\n * @example\n * ### Transparent Usage\n * ```typescript\n * // Application code — encryption is transparent\n * await db.create(Tables.USERS, {\n * name: 'John Doe',\n * ssn: '123-45-6789' // Automatically encrypted before storage\n * });\n *\n * // Retrieved data is automatically decrypted\n * const user = await db.get(Tables.USERS, userId);\n * console.log(user.value.ssn); // '123-45-6789' (decrypted)\n * ```\n */\n\nexport class EncryptionAdapter implements DatabaseAdapterType {\n // Using shared logger instance from @plyaz/logger\n\n constructor(\n public baseAdapter: DatabaseAdapterType,\n private config: {\n enabled: boolean;\n key: string;\n fields: Record<string, string[]>;\n algorithm?: string;\n },\n ) {}\n\n async initialize(): Promise<DatabaseResult<void>> {\n return this.baseAdapter.initialize();\n }\n\n async connect(): Promise<void> {\n return this.baseAdapter.connect();\n }\n\n async disconnect(): Promise<void> {\n return this.baseAdapter.disconnect();\n }\n\n async close(): Promise<DatabaseResult<void>> {\n return this.baseAdapter.close();\n }\n\n getClient(): object {\n return this.baseAdapter.getClient();\n }\n\n async query<T>(sql: string, params?: T[]): Promise<T[]> {\n return this.baseAdapter.query(sql, params);\n }\n\n registerTable<T, U>(name: string, table: T, idColumn?: U): void {\n this.baseAdapter.registerTable(name, table, idColumn);\n }\n\n async findById<T>(\n table: string,\n id: string,\n ): Promise<DatabaseResult<T | null>> {\n const result = await this.baseAdapter.findById<T>(table, id);\n if (result.success && result.value) {\n result.value = this.decryptFields(table, result.value);\n }\n return result;\n }\n\n async findMany<T extends Record<string, unknown>>(\n table: string,\n options?: QueryOptions<T>,\n ): Promise<DatabaseResult<PaginatedResult<T>>> {\n const result = await this.baseAdapter.findMany<T>(table, options);\n if (result.success && result.value) {\n result.value.data = result.value.data.map((item) =>\n this.decryptFields(table, item),\n );\n }\n return result;\n }\n\n async create<T extends Record<string, unknown>>(\n table: string,\n data: T,\n ): Promise<DatabaseResult<T>> {\n // Encryption is critical for compliance - fail if encryption fails\n // AuditAdapter (outer layer) will catch and log the failure\n const encryptedData = this.encryptFields(table, data);\n const result = await this.baseAdapter.create<T>(table, encryptedData);\n if (result.success && result.value) {\n result.value = this.decryptFields(table, result.value);\n }\n return result;\n }\n\n async update<T>(\n table: string,\n id: string,\n data: Partial<T>,\n ): Promise<DatabaseResult<T>> {\n // Encryption is critical for compliance - fail if encryption fails\n // AuditAdapter (outer layer) will catch and log the failure\n const encryptedData = this.encryptFields(table, data);\n const result = await this.baseAdapter.update<T>(table, id, encryptedData);\n if (result.success && result.value) {\n result.value = this.decryptFields(table, result.value);\n }\n return result;\n }\n\n async delete(table: string, id: string): Promise<DatabaseResult<void>> {\n return this.baseAdapter.delete(table, id);\n }\n\n async transaction<T>(\n callback: (trx: Transaction) => Promise<T>,\n ): Promise<DatabaseResult<T>> {\n return this.baseAdapter.transaction(callback);\n }\n\n async exists(table: string, id: string): Promise<DatabaseResult<boolean>> {\n return this.baseAdapter.exists(table, id);\n }\n\n async count<T extends Record<string, unknown> = Record<string, unknown>>(\n table: string,\n filter?: Filter<T>,\n ): Promise<DatabaseResult<number>> {\n return this.baseAdapter.count<T>(table, filter);\n }\n\n async healthCheck(): Promise<DatabaseResult<DatabaseHealthStatus>> {\n return this.baseAdapter.healthCheck();\n }\n\n private encryptFields<T extends Record<string, unknown>>(\n table: string,\n data: T,\n ): T {\n if (!this.shouldProcessFields(data, table)) return data;\n\n const fieldsToEncrypt = this.config.fields[table];\n const result = { ...data } as T;\n\n for (const field of fieldsToEncrypt) {\n this.encryptSingleField(result, field);\n }\n\n return result as T;\n }\n\n private shouldProcessFields<T>(data: T, table: string): boolean {\n return (\n this.config.enabled &&\n isObject(data) &&\n Boolean(this.config.fields[table])\n );\n }\n\n private encryptSingleField<T extends Record<string, unknown>>(\n result: T,\n field: string,\n ): void {\n if (result[field as keyof T]) {\n result[field as keyof T] = this.encrypt(\n String(result[field as keyof T]),\n ) as T[keyof T];\n }\n }\n\n private decryptFields<T extends Record<string, unknown>>(\n table: string,\n data: T,\n ): T {\n if (!this.shouldProcessFields(data, table)) return data;\n\n const fieldsToDecrypt = this.config.fields[table];\n const result = { ...data } as T;\n\n for (const field of fieldsToDecrypt) {\n this.decryptSingleField(result, field);\n }\n\n return result as T;\n }\n\n private decryptSingleField<T extends Record<string, unknown>>(\n result: T,\n field: string,\n ): void {\n if (result[field as keyof T]) {\n const fieldValue = String(result[field as keyof T]);\n // Check if the field value is encrypted (contains colons)\n // If not encrypted, return as-is (backwards compatibility with old data)\n if (this.isEncryptedValue(fieldValue)) {\n try {\n result[field as keyof T] = this.decrypt(fieldValue) as T[keyof T];\n } catch (error) {\n // Decryption failed - might be corrupted data or wrong key\n console.warn(\n `Failed to decrypt field ${field}, returning as-is:`,\n (error as Error).message,\n );\n }\n }\n }\n }\n\n private encrypt(text: string): string {\n this.validateEncryptionInput(text);\n\n const { iv, cipher } = this.createCipher();\n const encrypted = this.performEncryption(cipher, text);\n const authTag =\n (cipher as { getAuthTag?: () => Buffer }).getAuthTag?.() ??\n Buffer.alloc(0);\n\n return iv.toString(\"hex\") + \":\" + authTag.toString(\"hex\") + \":\" + encrypted;\n }\n\n private validateEncryptionInput(text: string): void {\n if (!isString(text)) {\n throw new DatabaseError(\n \"Invalid text for encryption\",\n DATABASE_ERROR_CODES.INVALID_PARAMETERS,\n {\n context: { source: \"validateEncryptionInput\" },\n cause: new Error(\"Invalid text for encryption\"),\n },\n );\n }\n if (!this.config.key) {\n throw new DatabaseError(\n \"Encryption key is required\",\n DATABASE_ERROR_CODES.CONFIG_REQUIRED,\n {\n context: { source: \"validateEncryptionInput\" },\n cause: new Error(\"Encryption key is required\"),\n },\n );\n }\n }\n\n private createCipher(): {\n iv: Buffer;\n cipher: ReturnType<typeof createCipheriv>;\n } {\n const algorithm = this.config.algorithm ?? ENCRYPTION_DEFAULTS.ALGORITHM;\n const key = this.getKeyBuffer();\n const iv = randomBytes(ENCRYPTION_DEFAULTS.IV_LENGTH);\n const cipher = createCipheriv(algorithm, key, iv);\n return { iv, cipher };\n }\n\n private performEncryption(\n cipher: ReturnType<typeof createCipheriv>,\n text: string,\n ): string {\n let encrypted = cipher.update(text, \"utf8\", \"hex\");\n encrypted += cipher.final(\"hex\");\n return encrypted;\n }\n\n private decrypt(encryptedText: string): string {\n this.validateDecryptionInput(encryptedText);\n\n const parts = this.parseEncryptedText(encryptedText);\n const { iv, authTag, encrypted } = this.extractDecryptionParts(parts);\n const decipher = this.createDecipher(iv, authTag);\n\n return this.performDecryption(decipher, encrypted);\n }\n\n private validateDecryptionInput(encryptedText: string): void {\n if (!isString(encryptedText)) {\n throw new DatabaseError(\n \"Invalid encrypted text for decryption\",\n DATABASE_ERROR_CODES.INVALID_PARAMETERS,\n {\n context: { source: \"validateDecryptionInput\" },\n cause: new Error(\"Invalid encrypted text for decryption\"),\n },\n );\n }\n if (!this.config.key) {\n throw new DatabaseError(\n \"Encryption key is required\",\n DATABASE_ERROR_CODES.CONFIG_REQUIRED,\n {\n context: { source: \"validateDecryptionInput\" },\n cause: new Error(\"Encryption key is required\"),\n },\n );\n }\n }\n\n private parseEncryptedText(encryptedText: string): string[] {\n const parts = encryptedText.split(\":\");\n if (parts.length !== ENCRYPTION_DEFAULTS.ENCRYPTED_PARTS_COUNT) {\n throw new DatabaseError(\n \"Invalid encrypted text format\",\n DATABASE_ERROR_CODES.INVALID_PARAMETERS,\n {\n context: { source: \"parseEncryptedText\" },\n cause: new Error(\"Invalid encrypted text format\"),\n },\n );\n }\n return parts;\n }\n\n private extractDecryptionParts(parts: string[]): {\n iv: Buffer;\n authTag: Buffer;\n encrypted: string;\n } {\n const iv = Buffer.from(parts[0], \"hex\");\n const authTag = Buffer.from(parts[1], \"hex\");\n const encrypted = parts[2];\n return { iv, authTag, encrypted };\n }\n\n private createDecipher(\n iv: Buffer,\n authTag: Buffer,\n ): ReturnType<typeof createDecipheriv> {\n const algorithm = this.config.algorithm ?? ENCRYPTION_DEFAULTS.ALGORITHM;\n const key = this.getKeyBuffer();\n const decipher = createDecipheriv(algorithm, key, iv);\n\n if (authTag.length > 0) {\n (decipher as { setAuthTag?: (tag: Buffer) => void }).setAuthTag?.(\n authTag,\n );\n }\n\n return decipher;\n }\n\n private performDecryption(\n decipher: ReturnType<typeof createDecipheriv>,\n encrypted: string,\n ): string {\n let decrypted = decipher.update(encrypted, \"hex\", \"utf8\");\n decrypted += decipher.final(\"utf8\");\n return decrypted;\n }\n\n private isEncryptedValue(value: string): boolean {\n // Encrypted values have format: iv:authTag:encrypted (3 parts separated by colons)\n const parts = value.split(\":\");\n return parts.length === ENCRYPTION_DEFAULTS.ENCRYPTED_PARTS_COUNT;\n }\n\n private getKeyBuffer(): Buffer {\n // AES-256-GCM requires 32-byte key\n const AES_256_KEY_LENGTH = 32;\n const keyBuffer = Buffer.from(this.config.key, \"utf8\");\n\n if (keyBuffer.length !== AES_256_KEY_LENGTH) {\n throw new DatabaseError(\n `Encryption key must be exactly ${AES_256_KEY_LENGTH} bytes for AES-256, got ${keyBuffer.length}`,\n DATABASE_ERROR_CODES.CONFIG_REQUIRED,\n {\n context: { source: \"getKeyBuffer\" },\n cause: new Error(\"Invalid key length\"),\n },\n );\n }\n\n return keyBuffer;\n }\n}\n","import { NUMERIX } from \"@plyaz/config\";\nimport { logger } from \"@plyaz/logger\";\nimport type {\n DatabaseAdapterType,\n DatabaseResult,\n DBCacheConfig,\n Filter,\n DatabaseHealthStatus,\n PaginatedResult,\n QueryOptions,\n Transaction,\n} from \"@plyaz/types/db\";\n/**\n * CACHING ADAPTER - Query Result Caching Layer\n *\n * Caching extension that stores query results in memory for improved performance.\n * Third layer in the adapter chain.\n *\n * **Adapter Chain Position:**\n * ReadReplica → Audit → **Cache** → SoftDelete → Encryption → Base Adapter\n *\n * **What this adapter does:**\n * 1. Intercepts findById() operations → checks cache first, stores results\n * 2. Intercepts write operations → invalidates related cache entries\n * 3. Manages TTL-based cache expiration\n * 4. Honors cache configuration (enabled, ttl, invalidation strategy)\n *\n * **Called by:** AuditAdapter (or ReadReplicaAdapter if no audit)\n * **Calls:** SoftDeleteAdapter (or next adapter in chain)\n * **Cache Strategy:** In-memory Map with TTL expiration\n *\n * **Cache Flow:**\n * - **READ:** Check cache → Return if hit → Query DB → Cache result\n * - **WRITE:** Execute operation → Invalidate related cache entries\n *\n * @example\n * ### Configuration\n * ```typescript\n * cache: {\n * enabled: true,\n * ttl: 300, // 5 minutes\n * invalidation: 'write', // Invalidate on writes\n * maxSize: 1000 // Max cache entries\n * }\n * ```\n *\n * @example\n * ### Cache Behavior\n * ```typescript\n * // First call - cache miss, queries database\n * const user1 = await db.findById('users', 'user-123'); // DB query\n *\n * // Second call - cache hit, returns from memory\n * const user2 = await db.findById('users', 'user-123'); // Cache hit\n *\n * // Write operation invalidates cache\n * await db.update('users', 'user-123', { name: 'New Name' });\n *\n * // Next read - cache miss again, queries database\n * const user3 = await db.findById('users', 'user-123'); // DB query\n * ```\n */\nexport class CachingAdapter implements DatabaseAdapterType {\n private cache = new Map<\n string,\n {\n value:\n | Record<string, string | number | boolean | Date>\n | Record<string, string | number | boolean | Date>[];\n expiry: number;\n }\n >();\n\n /**\n * Creates a new CachingAdapter instance.\n *\n * **RESPONSIBILITY:** Wraps base adapter with caching functionality\n * **CONFIGURATION:** Sets up cache TTL, invalidation strategy, and size limits\n *\n * @param baseAdapter - The underlying database adapter to wrap\n * @param config - Cache configuration options\n *\n * @example\n * ```typescript\n * const cachingAdapter = new CachingAdapter(baseAdapter, {\n * enabled: true,\n * ttl: 300, // 5 minutes\n * invalidation: 'write', // Invalidate on writes\n * maxSize: 1000 // Max entries\n * });\n * ```\n */\n constructor(\n public baseAdapter: DatabaseAdapterType,\n private config: DBCacheConfig,\n ) {}\n\n /**\n * Initializes the caching adapter and underlying adapter.\n *\n * **RESPONSIBILITY:** Passes initialization to base adapter\n * **BEHAVIOR:** No additional initialization needed for caching\n *\n * @returns Promise resolving to initialization result\n *\n * @example\n * ```typescript\n * const result = await cachingAdapter.initialize();\n * if (result.success) {\n * console.log('Caching adapter initialized');\n * }\n * ```\n */\n async initialize(): Promise<DatabaseResult<void>> {\n return this.baseAdapter.initialize();\n }\n\n /**\n * Establishes database connection through base adapter.\n *\n * **RESPONSIBILITY:** Delegates connection to underlying adapter\n * **BEHAVIOR:** No additional connection logic needed\n *\n * @example\n * ```typescript\n * await cachingAdapter.connect();\n * console.log('Connected with caching support');\n * ```\n */\n async connect(): Promise<void> {\n return this.baseAdapter.connect();\n }\n\n /**\n * Closes database connection through base adapter.\n *\n * **RESPONSIBILITY:** Delegates disconnection to underlying adapter\n * **BEHAVIOR:** Cache is cleared on disconnect\n *\n * @example\n * ```typescript\n * await cachingAdapter.disconnect();\n * console.log('Disconnected and cache cleared');\n * ```\n */\n async disconnect(): Promise<void> {\n return this.baseAdapter.disconnect();\n }\n\n async close(): Promise<DatabaseResult<void>> {\n return this.baseAdapter.close();\n }\n\n /**\n * Gets the underlying database client.\n *\n * **RESPONSIBILITY:** Provides access to raw database client\n * **USE CASE:** For operations that bypass caching\n *\n * @returns Database client object\n *\n * @example\n * ```typescript\n * const client = cachingAdapter.getClient();\n * // Use for direct database operations if needed\n * ```\n */\n getClient(): object {\n return this.baseAdapter.getClient();\n }\n\n /**\n * Executes raw SQL query through base adapter.\n *\n * **RESPONSIBILITY:** Passes raw SQL to base adapter without caching\n * **BEHAVIOR:** Does not cache raw SQL results\n * **NOTE:** Use findById/findMany for automatic caching\n *\n * @param sql - SQL query string\n * @param params - Query parameters\n * @returns Query results\n *\n * @example\n * ```typescript\n * // Raw SQL bypasses caching\n * const results = await adapter.query(\n * 'SELECT * FROM users WHERE status = $1',\n * ['active']\n * );\n *\n * // Use findMany for automatic caching\n * const users = await adapter.findMany('users', { filter: ... });\n * ```\n */\n async query<T>(sql: string, params?: T[]): Promise<T[]> {\n return this.baseAdapter.query(sql, params);\n }\n\n /**\n * Registers a table schema with the base adapter.\n *\n * **RESPONSIBILITY:** Passes table registration to base adapter\n * **BEHAVIOR:** No additional registration logic needed\n *\n * @param name - Table name\n * @param table - Table schema\n * @param idColumn - Primary key column\n *\n * @example\n * ```typescript\n * cachingAdapter.registerTable('users', userSchema, 'id');\n * // Table now supports cached operations\n * ```\n */\n registerTable<T, U>(name: string, table: T, idColumn?: U): void {\n this.baseAdapter.registerTable(name, table, idColumn);\n }\n\n async findById<T>(\n table: string,\n id: string,\n ): Promise<DatabaseResult<T | null>> {\n if (!this.config.enabled) {\n return this.baseAdapter.findById<T>(table, id);\n }\n\n const cacheKey = `${table}:${id}`;\n const cached = this.getFromCache<T>(cacheKey);\n\n if (cached !== null) {\n logger.debug(`Cache hit for ${table}:${id}`);\n return { success: true, value: cached };\n }\n\n const result = await this.baseAdapter.findById<T>(table, id);\n\n if (result.success && result.value) {\n this.setCache(cacheKey, result.value);\n logger.debug(`Cache set for ${table}:${id}`);\n }\n\n return result;\n }\n\n /**\n * Finds multiple records without caching.\n *\n * **RESPONSIBILITY:** Retrieves multiple records, bypassing cache\n * **BEHAVIOR:** Complex queries are not cached currently\n * **FUTURE:** Could implement query result caching with cache keys\n *\n * @param table - Table name\n * @param options - Query options\n * @returns Paginated results\n *\n * @example\n * ```typescript\n * // Complex queries bypass cache (for now)\n * const users = await adapter.findMany('users', {\n * filter: { field: 'status', operator: 'eq', value: 'active' },\n * pagination: { page: 1, limit: 10 },\n * sort: { field: 'name', direction: 'asc' }\n * });\n *\n * // Always queries database directly\n * ```\n */\n async findMany<T extends Record<string, unknown>>(\n table: string,\n options?: QueryOptions<T>,\n ): Promise<DatabaseResult<PaginatedResult<T>>> {\n // For now, skip caching for complex queries\n return this.baseAdapter.findMany<T>(table, options);\n }\n\n /**\n * Creates a new record with cache invalidation.\n *\n * **RESPONSIBILITY:** Creates record and invalidates related cache entries\n * **INVALIDATION:** Clears table cache on successful write\n * **STRATEGY:** Based on config.invalidation setting\n *\n * @param table - Table name\n * @param data - Record data\n * @returns Created record\n *\n * @example\n * ```typescript\n * // Create user - invalidates users table cache\n * const result = await adapter.create('users', {\n * name: 'John Doe',\n * email: 'john@example.com'\n * });\n *\n * if (result.success) {\n * console.log('User created:', result.value.id);\n * // All cached users:* entries are now invalid\n * }\n * ```\n */\n async create<T extends Record<string, unknown>>(\n table: string,\n data: T,\n ): Promise<DatabaseResult<T>> {\n const result = await this.baseAdapter.create<T>(table, data);\n\n if (result.success && this.config.invalidation === \"write\") {\n this.invalidateTable(table);\n }\n\n return result;\n }\n\n /**\n * Updates an existing record with cache invalidation.\n *\n * **RESPONSIBILITY:** Updates record and invalidates related cache entries\n * **INVALIDATION:** Clears specific record and table cache\n * **STRATEGY:** Invalidates both table:id and table:* patterns\n *\n * @param table - Table name\n * @param id - Record ID\n * @param data - Partial record data\n * @returns Updated record\n *\n * @example\n * ```typescript\n * // Update user - invalidates specific cache entry\n * const result = await adapter.update('users', 'user-123', {\n * name: 'Jane Doe'\n * });\n *\n * if (result.success) {\n * console.log('User updated:', result.value.name);\n * // Cache entries users:user-123 and users:* are invalidated\n * }\n * ```\n */\n async update<T>(\n table: string,\n id: string,\n data: Partial<T>,\n ): Promise<DatabaseResult<T>> {\n const result = await this.baseAdapter.update<T>(table, id, data);\n\n if (result.success && this.config.invalidation === \"write\") {\n this.invalidateTable(table);\n this.invalidateKey(`${table}:${id}`);\n }\n\n return result;\n }\n\n /**\n * Deletes a record with cache invalidation.\n *\n * **RESPONSIBILITY:** Deletes record and invalidates related cache entries\n * **INVALIDATION:** Clears specific record and table cache\n * **STRATEGY:** Removes both table:id and table:* patterns\n *\n * @param table - Table name\n * @param id - Record ID\n * @returns Deletion result\n *\n * @example\n * ```typescript\n * // Delete user - invalidates cache entries\n * const result = await adapter.delete('users', 'user-123');\n *\n * if (result.success) {\n * console.log('User deleted successfully');\n * // Cache entries users:user-123 and users:* are invalidated\n * }\n * ```\n */\n async delete(table: string, id: string): Promise<DatabaseResult<void>> {\n const result = await this.baseAdapter.delete(table, id);\n\n if (result.success && this.config.invalidation === \"write\") {\n this.invalidateTable(table);\n this.invalidateKey(`${table}:${id}`);\n }\n\n return result;\n }\n\n /**\n * Executes operations within a transaction.\n *\n * **RESPONSIBILITY:** Passes transaction to base adapter\n * **BEHAVIOR:** Cache invalidation happens per operation within transaction\n * **ATOMICITY:** Cache invalidation is not rolled back if transaction fails\n *\n * @param callback - Transaction callback function\n * @returns Transaction result\n *\n * @example\n * ```typescript\n * const result = await adapter.transaction(async (trx) => {\n * // Each operation invalidates cache independently\n * const user = await trx.create('users', { name: 'John' });\n * await trx.update('profiles', 'profile-1', { userId: user.id });\n * return user;\n * });\n *\n * // Cache invalidation happens even if transaction fails\n * ```\n */\n async transaction<T>(\n callback: (trx: Transaction) => Promise<T>,\n ): Promise<DatabaseResult<T>> {\n return this.baseAdapter.transaction(callback);\n }\n\n /**\n * Checks if a record exists without caching.\n *\n * **RESPONSIBILITY:** Verifies record existence, bypassing cache\n * **BEHAVIOR:** Existence checks are not cached currently\n * **PERFORMANCE:** Always queries database for existence\n *\n * @param table - Table name\n * @param id - Record ID\n * @returns True if record exists\n *\n * @example\n * ```typescript\n * // Existence checks bypass cache\n * const userExists = await adapter.exists('users', 'user-123');\n * if (userExists.value) {\n * console.log('User exists');\n * }\n *\n * // Always queries database directly\n * ```\n */\n async exists(table: string, id: string): Promise<DatabaseResult<boolean>> {\n return this.baseAdapter.exists(table, id);\n }\n\n /**\n * Counts records without caching.\n *\n * **RESPONSIBILITY:** Counts records, bypassing cache\n * **BEHAVIOR:** Count operations are not cached currently\n * **PERFORMANCE:** Always queries database for counts\n *\n * @param table - Table name\n * @param filter - Optional filter conditions\n * @returns Count of records\n *\n * @example\n * ```typescript\n * // Count operations bypass cache\n * const activeUsers = await adapter.count('users', {\n * field: 'status',\n * operator: 'eq',\n * value: 'active'\n * });\n *\n * console.log('Active users:', activeUsers.value);\n * // Always queries database directly\n * ```\n */\n async count<T extends Record<string, unknown> = Record<string, unknown>>(\n table: string,\n filter?: Filter<T>,\n ): Promise<DatabaseResult<number>> {\n return this.baseAdapter.count<T>(table, filter);\n }\n\n /**\n * Performs health check through base adapter.\n *\n * **RESPONSIBILITY:** Delegates health check to underlying adapter\n * **BEHAVIOR:** No additional health metrics for cache\n *\n * @returns Health status from base adapter\n *\n * @example\n * ```typescript\n * const health = await adapter.healthCheck();\n * if (health.success && health.value?.isHealthy) {\n * console.log('Database healthy with caching support');\n * }\n * ```\n */\n async healthCheck(): Promise<DatabaseResult<DatabaseHealthStatus>> {\n return this.baseAdapter.healthCheck();\n }\n\n /**\n * Retrieves value from cache with TTL validation.\n *\n * **RESPONSIBILITY:** Gets cached value and validates expiration\n * **TTL HANDLING:** Removes expired entries automatically\n * **RETURN:** Cached value or null if not found/expired\n *\n * @private\n * @param key - Cache key to retrieve\n * @returns Cached value or null\n *\n * @example\n * ```typescript\n * // Internal usage\n * const user = this.getFromCache<User>('users:user-123');\n * if (user) {\n * console.log('Cache hit:', user.name);\n * } else {\n * console.log('Cache miss or expired');\n * }\n * ```\n */\n private getFromCache<T>(key: string): T | null {\n const cached = this.cache.get(key);\n if (!cached) return null;\n\n if (Date.now() > cached.expiry) {\n this.cache.delete(key);\n return null;\n }\n\n return cached.value as T;\n }\n\n /**\n * Stores value in cache with TTL expiration.\n *\n * **RESPONSIBILITY:** Caches value with calculated expiration time\n * **TTL:** Uses config.ttl or default 5 minutes (300 seconds)\n * **EXPIRY:** Calculates absolute expiration timestamp\n *\n * @private\n * @param key - Cache key to store\n * @param value - Value to cache\n *\n * @example\n * ```typescript\n * // Internal usage after database query\n * this.setCache('users:user-123', userData);\n *\n * // Value will expire after TTL seconds\n * // Default: 5 minutes from now\n * ```\n */\n private setCache(\n key: string,\n value:\n | Record<string, string | number | boolean | Date>\n | Record<string, string | number | boolean | Date>[],\n ): void {\n const ttl = this.config.ttl ?? NUMERIX.THREE_HUNDERD; // Default 5 minutes\n const expiry = Date.now() + ttl * NUMERIX.THOUSAND;\n this.cache.set(key, { value, expiry });\n }\n\n /**\n * Removes specific key from cache.\n *\n * **RESPONSIBILITY:** Invalidates single cache entry\n * **USE CASE:** Called after record updates/deletes\n * **PATTERN:** Removes exact key match\n *\n * @private\n * @param key - Cache key to invalidate\n *\n * @example\n * ```typescript\n * // Internal usage after record update\n * this.invalidateKey('users:user-123');\n *\n * // Only users:user-123 is removed from cache\n * // Other users:* entries remain cached\n * ```\n */\n private invalidateKey(key: string): void {\n this.cache.delete(key);\n }\n\n /**\n * Removes all cache entries for a table.\n *\n * **RESPONSIBILITY:** Invalidates all entries matching table pattern\n * **USE CASE:** Called after any write operation to table\n * **PATTERN:** Removes all keys starting with 'table:'\n *\n * @private\n * @param table - Table name to invalidate\n *\n * @example\n * ```typescript\n * // Internal usage after any write to users table\n * this.invalidateTable('users');\n *\n * // Removes all cache entries:\n * // - users:user-123\n * // - users:user-456\n * // - users:admin-789\n * // But keeps: profiles:profile-1, posts:post-1, etc.\n * ```\n */\n private invalidateTable(table: string): void {\n for (const key of this.cache.keys()) {\n if (key.startsWith(`${table}:`)) {\n this.cache.delete(key);\n }\n }\n }\n}\n","import type {\n DatabaseAdapterType,\n DatabaseResult,\n QueryOptions,\n PaginatedResult,\n Transaction,\n Filter,\n DatabaseHealthStatus,\n ReadReplicaConfig,\n} from \"@plyaz/types/db\";\n\n/**\n * Read replica extension that routes read operations to replicas\n * This is the outermost wrapper in the adapter chain\n */\nexport class ReadReplicaAdapter implements DatabaseAdapterType {\n private currentReplicaIndex = 0;\n\n constructor(\n private primaryAdapter: DatabaseAdapterType,\n private config: ReadReplicaConfig,\n ) {}\n\n async initialize(): Promise<DatabaseResult<void>> {\n return this.primaryAdapter.initialize();\n }\n\n async connect(): Promise<void> {\n return this.primaryAdapter.connect();\n }\n\n async disconnect(): Promise<void> {\n return this.primaryAdapter.disconnect();\n }\n\n async close(): Promise<DatabaseResult<void>> {\n return this.primaryAdapter.close();\n }\n\n getClient(): object {\n return this.primaryAdapter.getClient();\n }\n\n async query<T>(sql: string, params?: T[]): Promise<T[]> {\n return this.primaryAdapter.query(sql, params);\n }\n\n registerTable<T, U>(name: string, table: T, idColumn?: U): void {\n this.primaryAdapter.registerTable(name, table, idColumn);\n }\n\n async findById<T>(\n table: string,\n id: string,\n ): Promise<DatabaseResult<T | null>> {\n // Route reads to replicas if available\n const adapter = this.getReadAdapter();\n return adapter.findById<T>(table, id);\n }\n\n async findMany<T extends Record<string, unknown>>(\n table: string,\n options?: QueryOptions<T>,\n ): Promise<DatabaseResult<PaginatedResult<T>>> {\n // Route reads to replicas if available\n const adapter = this.getReadAdapter();\n return adapter.findMany<T>(table, options);\n }\n\n async create<T extends Record<string, unknown>>(\n table: string,\n data: T,\n ): Promise<DatabaseResult<T>> {\n // Always route writes to primary\n return this.primaryAdapter.create<T>(table, data);\n }\n\n async update<T>(\n table: string,\n id: string,\n data: Partial<T>,\n ): Promise<DatabaseResult<T>> {\n // Always route writes to primary\n return this.primaryAdapter.update<T>(table, id, data);\n }\n\n async delete(table: string, id: string): Promise<DatabaseResult<void>> {\n // Always route writes to primary\n return this.primaryAdapter.delete(table, id);\n }\n\n async transaction<T>(\n callback: (trx: Transaction) => Promise<T>,\n ): Promise<DatabaseResult<T>> {\n // Always route transactions to primary\n return this.primaryAdapter.transaction(callback);\n }\n\n async exists(table: string, id: string): Promise<DatabaseResult<boolean>> {\n // Route reads to replicas if available\n const adapter = this.getReadAdapter();\n return adapter.exists(table, id);\n }\n\n async count<T extends Record<string, unknown> = Record<string, unknown>>(\n table: string,\n filter?: Filter<T>,\n ): Promise<DatabaseResult<number>> {\n // Route reads to replicas if available\n const adapter = this.getReadAdapter();\n return adapter.count<T>(table, filter);\n }\n\n async healthCheck(): Promise<DatabaseResult<DatabaseHealthStatus>> {\n return this.primaryAdapter.healthCheck();\n }\n\n /**\n * Get the appropriate adapter for read operations\n * Routes to replicas using the configured strategy\n */\n private getReadAdapter(): DatabaseAdapterType {\n if (!this.config.enabled || this.config.replicas.length === 0) {\n return this.primaryAdapter;\n }\n\n switch (this.config.strategy) {\n case \"round-robin\": {\n const replica = this.config.replicas[this.currentReplicaIndex];\n this.currentReplicaIndex =\n (this.currentReplicaIndex + 1) % this.config.replicas.length;\n return replica;\n }\n\n case \"random\": {\n const randomIndex = Math.floor(\n Math.random() * this.config.replicas.length,\n );\n return this.config.replicas[randomIndex];\n }\n\n default:\n // Default to first replica\n return this.config.replicas[0];\n }\n }\n}\n","/**\n * DATABASE SERVICE FACTORY - Main Entry Point\n *\n * This file is responsible for creating fully configured database services with extension chains.\n * It implements the decorator pattern to wrap base adapters with feature extensions.\n *\n * **RESPONSIBILITIES:**\n * 1. Config Validation - Ensures valid configuration before proceeding\n * 2. Base Adapter Creation - Creates core database adapters (Drizzle/Supabase/SQL)\n * 3. Adapter Chain Building - Wraps adapters with extensions in correct order\n * 4. Service Assembly - Creates final DatabaseService with all components\n * 5. Initialization - Establishes database connections and readiness\n *\n * **ADAPTER CHAIN ORDER:**\n * Base → Encryption → SoftDelete → Caching → Audit → ReadReplica\n * (innermost to outermost - each wraps the previous)\n */\n\n// Core service and interfaces - Main building blocks\nimport { DatabaseService } from \"@service/DatabaseService\"; // Main service implementation\n\n// Factory and adapters - Core creation logic\nimport { AdapterFactory } from \"./AdapterFactory\"; // Creates base adapters\n\n// Extension adapters - Feature layers (imported in chain order)\nimport { SoftDeleteAdapter } from \"../extensions/SoftDeleteExtension\"; // Logical deletion (layer 2)\nimport { AuditAdapter } from \"../extensions/AuditExtension\"; // Operation logging (layer 4)\nimport { EncryptionAdapter } from \"../extensions/EncryptionExtension\"; // Data encryption (layer 1)\nimport { CachingAdapter } from \"../extensions/CachingAdapter\"; // Query caching (layer 3)\nimport { ReadReplicaAdapter } from \"../extensions/ReadReplicaAdapter\"; // Read/write splitting (layer 5)\n\n// External dependencies - Error handling and constants\nimport { DatabaseError } from \"@plyaz/errors\"; // Error classes\nimport { DATABASE_ERROR_CODES } from \"@plyaz/types/errors\";\nimport { ADAPTER_TYPES, ADAPTERS } from \"@plyaz/types/db\";\nimport type {\n DatabaseServiceInterface,\n SqlConfig,\n SupabaseConfig,\n DatabaseAdapterType,\n DatabaseConfig,\n DatabaseServiceConfig,\n DrizzleConfig,\n} from \"@plyaz/types/db\";\n\n/**\n * ADAPTER CHAIN BUILDER - Decorator Pattern Implementation\n *\n * **RESPONSIBILITY:** Wraps base adapter with extension layers in correct order\n * **PATTERN:** Decorator - each adapter wraps the previous, adding functionality\n * **ORDER:** Base → Encryption → SoftDelete → Caching → Audit → ReadReplica\n *\n * **WHY THIS ORDER:**\n * 1. Encryption (innermost) - Encrypts data before storage, decrypts after retrieval\n * 2. SoftDelete - Handles logical deletion, works on encrypted data\n * 3. Caching - Caches processed data (after encryption/soft-delete logic)\n * 4. Audit - Logs final operations (after all data processing)\n * 5. ReadReplica (outermost) - Routes requests to appropriate database\n *\n * @param baseAdapter - The core database adapter (Drizzle/Supabase/SQL)\n * @param config - Configuration specifying which extensions to enable\n * @returns Fully wrapped adapter with all enabled extensions\n *\n * @example\n * ```typescript\n * // Creates: AuditAdapter(CachingAdapter(EncryptionAdapter(DrizzleAdapter)))\n * const wrappedAdapter = buildAdapterChain(baseAdapter, {\n * encryption: { enabled: true, key: 'secret', fields: { users: ['ssn'] } },\n * softDelete: { enabled: true, field: 'deletedAt' },\n * audit: { enabled: true, retentionDays: 90 }\n * });\n * ```\n */\n// eslint-disable-next-line complexity\nfunction buildAdapterChain(\n baseAdapter: DatabaseAdapterType,\n config: DatabaseServiceConfig,\n): DatabaseAdapterType {\n let adapter: DatabaseAdapterType = baseAdapter;\n\n // Layer 1: Encryption (innermost after base)\n // RESPONSIBILITY: Encrypts sensitive fields before storage, decrypts on retrieval\n // WHEN: Always applied first to ensure data is encrypted at rest\n if (config.encryption?.enabled) {\n adapter = new EncryptionAdapter(adapter, config.encryption);\n }\n\n // Layer 2: Soft Delete\n // RESPONSIBILITY: Converts DELETE operations to UPDATE (sets deletedAt), filters soft-deleted records\n // WHEN: Applied after encryption so deletion logic works on encrypted data\n if (config.softDelete?.enabled) {\n adapter = new SoftDeleteAdapter(adapter, config.softDelete);\n }\n\n // Layer 3: Caching\n // RESPONSIBILITY: Stores query results in memory/Redis, invalidates on writes\n // WHEN: Applied after data processing to cache final processed results\n if (config.cache?.enabled) {\n adapter = new CachingAdapter(adapter, config.cache);\n }\n\n // Layer 4: Audit\n // RESPONSIBILITY: Logs all database operations for compliance and tracking\n // WHEN: Applied late in chain to capture final operation details\n if (config.audit?.enabled) {\n adapter = new AuditAdapter(adapter, {\n ...config.audit,\n // Pass encrypted fields config so audit can log which fields are encrypted at rest\n encryptedFields: config.encryption?.enabled\n ? config.encryption.fields\n : undefined,\n });\n }\n\n // Layer 5: Read Replica (outermost wrapper)\n // RESPONSIBILITY: Routes reads to replicas, writes to primary database\n // WHEN: Applied last to handle request routing before any processing\n if (config.readReplica?.enabled) {\n adapter = new ReadReplicaAdapter(adapter, {\n enabled: true,\n replicas: [], // TODO: Create replica adapters from config\n strategy: config.readReplica.strategy,\n fallbackToPrimary: config.readReplica.fallbackToPrimary,\n });\n }\n\n return adapter;\n}\n\n/**\n * CONFIG TRANSFORMER - Converts External to Internal Format\n *\n * **RESPONSIBILITY:** Transforms user-friendly config into internal adapter factory format\n * **WHY NEEDED:** External config is user-friendly, internal config is adapter-specific\n *\n * **TRANSFORMATIONS:**\n * - Maps adapter names to internal constants\n * - Extracts connection details from nested config\n * - Normalizes different config formats (connectionString vs url)\n * - Sets up adapter-specific options (pool, SSL, etc.)\n *\n * @param config - User-provided database service configuration\n * @returns Normalized configuration for AdapterFactory.create()\n */\nfunction createAdapterConfig(config: DatabaseServiceConfig): DatabaseConfig {\n // Drizzle Adapter Config - PostgreSQL with Drizzle ORM\n if (config.adapter === ADAPTER_TYPES.DRIZZLE) {\n const drizzleConfig = config.config as DrizzleConfig;\n return {\n adapter: ADAPTERS.DRIZZLE,\n // orm: ADAPTERS.SUPABASE,\n connectionString: drizzleConfig.connectionString ?? drizzleConfig.url, // Support both formats\n pool: drizzleConfig.poolSize\n ? { max: drizzleConfig.poolSize }\n : undefined, // Optional connection pooling\n tableIdColumns: drizzleConfig.tableIdColumns, // Custom ID column mappings\n };\n }\n\n // Supabase Adapter Config - Supabase API integration\n if (config.adapter === ADAPTER_TYPES.SUPABASE) {\n const supabaseConfig = config.config as SupabaseConfig;\n return {\n adapter: ADAPTERS.SUPABASE,\n // orm: ADAPTERS.SUPABASE, // Optional ORM choice\n supabaseUrl: supabaseConfig.supabaseUrl, // Supabase project URL\n supabaseAnonKey: supabaseConfig.supabaseAnonKey, // Public API key\n supabaseServiceKey: supabaseConfig.supabaseServiceKey, // Service role key (admin)\n schema: supabaseConfig.schema, // Database schema\n tableIdColumns: supabaseConfig.tableIdColumns, // Custom ID column mappings\n };\n }\n\n // Mock Adapter Config - In-memory testing database\n if (config.adapter === ADAPTER_TYPES.MOCK) {\n return {\n adapter: ADAPTERS.MOCK,\n ...config.config, // Pass through all mock config options\n };\n }\n\n // šŸ”§ Raw SQL Adapter Config - Direct SQL database connection\n const sqlConfig = config.config as SqlConfig;\n return {\n adapter: ADAPTERS.SQL,\n connectionString: sqlConfig.connectionString ?? sqlConfig.url, // Support both formats\n schema: sqlConfig.schema, // Default schema for all tables\n tableIdColumns: sqlConfig.tableIdColumns, // Custom ID column mappings\n };\n}\n\n/**\n * CONFIG VALIDATOR - Ensures Configuration Integrity\n *\n * **RESPONSIBILITY:** Validates user configuration before processing\n * **PREVENTS:** Runtime errors from invalid/missing configuration\n * **THROWS:** Descriptive validation errors for debugging\n *\n * **VALIDATION CHECKS:**\n * 1. Config object exists\n * 2. Adapter type is specified\n * 3. Adapter configuration is provided\n *\n * @param config - User-provided configuration to validate\n * @throws {DatabaseError} When configuration is invalid or incomplete\n */\nfunction validateConfig(config: DatabaseServiceConfig): void {\n // Check: Configuration object exists\n if (!config) {\n throw new DatabaseError(\n \"Database configuration is required\",\n DATABASE_ERROR_CODES.CONFIG_REQUIRED,\n {\n context: { source: \"validateConfig\" },\n cause: new Error(\"Database configuration is required\"),\n },\n );\n }\n\n // Check: Adapter type specified (drizzle/supabase/sql)\n if (!config.adapter) {\n throw new DatabaseError(\n \"Database adapter type is required\",\n DATABASE_ERROR_CODES.CONFIG_REQUIRED,\n {\n context: { source: \"validateConfig\" },\n cause: new Error(\"Database adapter type is required\"),\n },\n );\n }\n\n // Check: Adapter-specific configuration provided\n if (!config.config) {\n throw new DatabaseError(\n \"Adapter configuration is required\",\n DATABASE_ERROR_CODES.CONFIG_REQUIRED,\n {\n context: { source: \"validateConfig\" },\n cause: new Error(\"Adapter configuration is required\"),\n },\n );\n }\n}\n\n/**\n * MAIN FACTORY - Application Entry Point\n *\n * Creates a fully configured database service with extension chain.\n * This is the ONLY way applications should create database services.\n *\n * **Application Flow:**\n * 1. App calls createDatabaseService() at startup\n * 2. Factory validates config and creates base adapter (Drizzle/Supabase/etc.)\n * 3. Factory builds 6-layer adapter chain: Base → Encryption → SoftDelete → Cache → Audit → ReadReplica\n * 4. Factory creates DatabaseService with final wrapped adapter\n * 5. App uses returned DatabaseServiceInterface in repositories/services\n *\n * **What this function does:**\n * - Validates configuration using validateConfig()\n * - Creates base adapter via AdapterFactory.create()\n * - Builds decorator chain via buildAdapterChain()\n * - Initializes database connection\n * - Returns configured DatabaseService instance\n *\n * **Called by:** Application startup code (app.ts, main.ts)\n * **Calls:** validateConfig(), AdapterFactory.create(), buildAdapterChain(), DatabaseService constructor\n * **Returns to:** Application layer for injection into repositories\n *\n * @param config Complete database service configuration including adapter and extensions\n * @returns Promise resolving to configured DatabaseServiceInterface instance\n *\n * @throws {BaseError} When configuration is invalid or initialization fails\n *\n * @example\n * ### Basic Setup (app.ts)\n * ```typescript\n * import { createDatabaseService, Tables } from '@plyaz/db';\n *\n * // Called once at application startup\n * const db = await createDatabaseService({\n * adapter: 'drizzle',\n * config: { connectionString: process.env.DATABASE_URL }\n * });\n *\n * // Inject into services\n * const userService = new UserService(db);\n * ```\n *\n * @example\n * ### Production Configuration\n * ```typescript\n * const db = await createDatabaseService({\n * adapter: 'drizzle',\n * config: {\n * connectionString: process.env.DATABASE_URL,\n * poolSize: 20\n * },\n *\n * // Extensions applied in order: Base → Encryption → SoftDelete → Cache → Audit → ReadReplica\n * encryption: {\n * enabled: true,\n * key: process.env.ENCRYPTION_KEY,\n * fields: {\n * [Tables.USERS]: ['ssn', 'taxId'],\n * [Tables.PAYMENTS]: ['cardNumber', 'cvv']\n * }\n * },\n *\n * softDelete: {\n * enabled: true,\n * field: 'deletedAt'\n * },\n *\n * audit: {\n * enabled: true,\n * retentionDays: 90,\n * onAuditAfterWrite: async (event) => {\n * await complianceService.recordAudit(event);\n * }\n * },\n *\n * cache: {\n * enabled: true,\n * ttl: 300,\n * invalidation: 'write'\n * },\n *\n * events: {\n * onAfterWrite: async (event) => {\n * await notificationService.send(event);\n * }\n * }\n * });\n * ```\n *\n * @example\n * ### Testing Setup\n * ```typescript\n * // Use mock adapter for tests\n * const db = await createDatabaseService({\n * adapter: 'mock',\n * config: { logging: true }\n * });\n * ```\n */\nexport async function createDatabaseService(\n config: DatabaseServiceConfig,\n): Promise<DatabaseServiceInterface> {\n try {\n // STEP 1: Validate Configuration\n // RESPONSIBILITY: Ensure config is complete and valid before proceeding\n validateConfig(config);\n\n // STEP 2: Create Base Adapter\n // RESPONSIBILITY: Transform config and create core database adapter (Drizzle/Supabase/SQL)\n const adapterConfig = createAdapterConfig(config); // Transform to internal format\n const baseAdapter = AdapterFactory.create(\n adapterConfig.adapter,\n adapterConfig,\n ); // Create adapter\n\n // STEP 3: Build Adapter Chain\n // RESPONSIBILITY: Wrap base adapter with enabled extensions in correct order\n const finalAdapter = buildAdapterChain(baseAdapter, config);\n\n // STEP 4: Create Database Service\n // RESPONSIBILITY: Assemble final service with wrapped adapter and configuration\n const service = new DatabaseService({\n adapter: finalAdapter, // Fully wrapped adapter chain\n globalConfig: config, // Original configuration for reference\n eventHandlers: config.events, // Event handlers for notifications\n });\n\n // STEP 5: Initialize Database Connection\n // RESPONSIBILITY: Establish database connection and verify readiness\n const initResult = await baseAdapter.initialize();\n if (!initResult.success) {\n throw new DatabaseError(\n `Failed to initialize adapter: ${initResult.error?.message ?? \"Unknown error\"}`,\n DATABASE_ERROR_CODES.INIT_FAILED,\n {\n context: { source: \"createDatabaseService\" },\n cause: initResult.error ?? new Error(\"Failed to initialize adapter\"),\n },\n );\n }\n\n return service; // Return fully configured and initialized service\n } catch (error) {\n throw new DatabaseError(\n `Failed to create database service: ${(error as Error).message}`,\n DATABASE_ERROR_CODES.INIT_FAILED,\n {\n context: { source: \"createDatabaseService\" },\n cause: error as Error,\n },\n );\n }\n}\n","/**\n * @plyaz/db CLI - Database management commands\n *\n * Commands:\n * - db:migrate [up|down|status|reset] - Run migrations\n * - db:seed [run|reset|status] - Run seeds\n * - db:clear - Clear all database data\n * - db:drop - Drop all tables\n * - db:health - Check database health\n *\n * @example\n * ```bash\n * # Run migrations\n * npx @plyaz/db migrate up\n *\n * # Rollback last migration\n * npx @plyaz/db migrate down\n *\n * # Run seeds\n * npx @plyaz/db seed run\n *\n * # Clear all data\n * npx @plyaz/db clear --confirm\n * ```\n */\n\n/* eslint-disable n/no-process-exit */\n// CLI tools use process.exit() for proper exit codes - this is expected behavior\n\nimport { Command } from \"commander\";\nimport { MigrationManager } from \"../migrations/MigrationManager\";\nimport { SeedManager } from \"../seeds/SeedManager\";\nimport { createDatabaseService } from \"../factory/createDatabaseService\";\nimport type { DatabaseAdapterType, DatabaseCLIConfig } from \"@plyaz/types/db\";\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport * as readline from \"readline\";\nimport { randomUUID } from \"crypto\";\nimport { pathToFileURL, fileURLToPath } from \"url\";\nimport { execSync } from \"child_process\";\n\n/** JSON indentation spaces for pretty printing */\nconst JSON_INDENT_SPACES = 2;\n\n/** Number of digits for version/order padding (e.g., 001, 002) */\nconst VERSION_PAD_LENGTH = 3;\n\n/** Radix for parsing integers */\nconst DECIMAL_RADIX = 10;\n\n/** Width of separator lines in interactive mode */\nconst SEPARATOR_WIDTH = 50;\n\n/** Valid migration file types */\nconst VALID_MIGRATION_TYPES = [\"sql\", \"ts\"] as const;\ntype MigrationType = (typeof VALID_MIGRATION_TYPES)[number];\n\n/** Valid seed file types */\nconst VALID_SEED_TYPES = [\"ts\", \"sql\", \"csv\"] as const;\ntype SeedType = (typeof VALID_SEED_TYPES)[number];\n\n/** Minimum steps for rollback */\nconst MIN_ROLLBACK_STEPS = 1;\n\n/**\n * Validate migration/seed name\n * Must contain at least one letter and only alphanumeric, underscore, hyphen\n */\nfunction validateName(name: string, type: \"migration\" | \"seed\"): void {\n if (!name || name.trim() === \"\") {\n console.error(`āŒ ${type} name cannot be empty`);\n process.exit(1);\n }\n\n if (!/[a-zA-Z]/.test(name)) {\n console.error(`āŒ ${type} name must contain at least one letter`);\n process.exit(1);\n }\n\n if (!/^[a-zA-Z0-9_-]+$/.test(name)) {\n console.error(\n `āŒ ${type} name can only contain letters, numbers, underscores, and hyphens`,\n );\n process.exit(1);\n }\n}\n\n/**\n * Validate migration type option\n */\nfunction validateMigrationType(type: string): MigrationType {\n if (!VALID_MIGRATION_TYPES.includes(type as MigrationType)) {\n console.warn(\n `⚠ Invalid type \"${type}\". Valid options: ${VALID_MIGRATION_TYPES.join(\", \")}. Using default: sql`,\n );\n return \"sql\";\n }\n return type as MigrationType;\n}\n\n/**\n * Validate seed type option\n */\nfunction validateSeedType(type: string): SeedType {\n if (!VALID_SEED_TYPES.includes(type as SeedType)) {\n console.warn(\n `⚠ Invalid type \"${type}\". Valid options: ${VALID_SEED_TYPES.join(\", \")}. Using default: ts`,\n );\n return \"ts\";\n }\n return type as SeedType;\n}\n\n/**\n * Validate rollback steps parameter\n */\nfunction validateSteps(stepsStr: string): number {\n const steps = Number.parseInt(stepsStr, DECIMAL_RADIX);\n\n if (Number.isNaN(steps)) {\n console.error(`āŒ Steps must be a number, got: \"${stepsStr}\"`);\n process.exit(1);\n }\n\n if (steps < MIN_ROLLBACK_STEPS) {\n console.error(\n `āŒ Steps must be at least ${MIN_ROLLBACK_STEPS}, got: ${steps}`,\n );\n process.exit(1);\n }\n\n return steps;\n}\n\n/**\n * Validate schema name (basic SQL injection prevention)\n */\nfunction validateSchemaName(schema: string): void {\n if (!schema || schema.trim() === \"\") {\n console.error(\"āŒ Schema name cannot be empty\");\n process.exit(1);\n }\n\n if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(schema)) {\n console.error(\n \"āŒ Invalid schema name. Must start with letter or underscore, contain only alphanumeric and underscores\",\n );\n process.exit(1);\n }\n}\n\n/**\n * Get all user schemas from database\n * Uses INFORMATION_SCHEMA (SQL standard) for portability across databases\n * Note: Some databases (MySQL) call schemas \"databases\"\n */\nasync function getUserSchemas(adapter: DatabaseAdapterType): Promise<string[]> {\n // Use INFORMATION_SCHEMA.SCHEMATA (SQL standard - works on PostgreSQL, MySQL, SQL Server)\n const result = await adapter.query?.(`\n SELECT schema_name FROM information_schema.schemata\n WHERE schema_name NOT IN ('pg_catalog', 'information_schema', 'pg_toast', 'mysql', 'sys', 'performance_schema')\n AND schema_name NOT LIKE 'pg_%'\n AND schema_name NOT LIKE 'pg_temp_%'\n AND schema_name NOT LIKE 'pg_toast_temp_%'\n `);\n\n const schemas = Array.isArray(result)\n ? result\n : (result as unknown as { rows: { schema_name: string }[] }).rows || [];\n\n return (schemas as { schema_name: string }[]).map((s) => s.schema_name);\n}\n\n/**\n * Get list of tables from specified schemas\n * Uses INFORMATION_SCHEMA.TABLES (SQL standard) for portability\n */\nasync function getTablesFromSchemas(\n adapter: DatabaseAdapterType,\n schemas: string[],\n): Promise<{ schema: string; table: string }[]> {\n const tables: { schema: string; table: string }[] = [];\n\n for (const schema of schemas) {\n // Use INFORMATION_SCHEMA.TABLES (SQL standard)\n const result = await adapter.query?.(\n `\n SELECT table_name FROM information_schema.tables\n WHERE table_schema = $1\n AND table_type = 'BASE TABLE'\n AND table_name NOT IN ('schema_migrations', 'seed_history')\n `,\n [schema],\n );\n\n const schemaResult = Array.isArray(result)\n ? result\n : (result as unknown as { rows: { table_name: string }[] }).rows || [];\n\n for (const row of schemaResult as { table_name: string }[]) {\n tables.push({ schema, table: row.table_name });\n }\n }\n\n return tables;\n}\n\n/**\n * Clear specified tables from database\n * Note: TRUNCATE CASCADE is PostgreSQL-specific. Other databases may need different syntax.\n */\nasync function clearTables(\n adapter: DatabaseAdapterType,\n tables: { schema: string; table: string }[],\n): Promise<void> {\n let currentSchema = \"\";\n for (const { schema, table } of tables) {\n if (schema !== currentSchema) {\n console.log(`\\nšŸ“ Schema: ${schema}`);\n currentSchema = schema;\n }\n // Standard SQL uses quoted identifiers; CASCADE is PostgreSQL-specific\n // For other databases, adapter may need to handle this differently\n await adapter.query?.(`TRUNCATE TABLE \"${schema}\".\"${table}\" CASCADE`);\n console.log(` āœ“ Cleared ${schema}.${table}`);\n }\n}\n\n/**\n * Parse a single env line into key-value pair\n */\nfunction parseEnvLine(line: string): { key: string; value: string } | null {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) return null;\n\n const eqIndex = trimmed.indexOf(\"=\");\n if (eqIndex <= 0) return null;\n\n const key = trimmed.slice(0, eqIndex).trim();\n let value = trimmed.slice(eqIndex + 1).trim();\n\n // Remove surrounding quotes\n const isQuoted =\n (value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"));\n if (isQuoted) {\n value = value.slice(1, -1);\n }\n\n return { key, value };\n}\n\n/**\n * Load environment variables from a .env file\n */\nfunction loadEnvFile(envFilePath: string): void {\n if (!fs.existsSync(envFilePath)) return;\n\n const envContent = fs.readFileSync(envFilePath, \"utf-8\");\n for (const line of envContent.split(\"\\n\")) {\n const parsed = parseEnvLine(line);\n if (parsed) {\n process.env[parsed.key] ??= parsed.value;\n }\n }\n}\n\nconst program = new Command();\n\n// Global options (can be set via flags)\nlet globalConfigPath: string | undefined;\nlet globalEnvPath: string | undefined;\n\n/**\n * Convert a file path to a URL that can be used with dynamic import\n * On Windows, absolute paths must be file:// URLs for ESM imports\n */\nfunction toImportPath(filePath: string): string {\n return pathToFileURL(filePath).href;\n}\n\n/** Config file search paths */\nconst CONFIG_PATHS = [\n \"db.config.mjs\",\n \"db.config.js\",\n \".db.config.mjs\",\n \".db.config.js\",\n];\n\n/** TypeScript config paths to check for warnings */\nconst TS_CONFIG_PATHS = [\"db.config.ts\", \".db.config.ts\"];\n\n/**\n * Load config from a specific file path\n */\nasync function loadConfigFromPath(\n filePath: string,\n): Promise<DatabaseCLIConfig> {\n const importPath = toImportPath(filePath);\n const config = await import(importPath);\n console.log(`šŸ“ Using config: ${filePath}`);\n return config.default ?? config;\n}\n\n/**\n * Find and load config from standard locations\n */\nasync function findAndLoadConfig(): Promise<DatabaseCLIConfig | null> {\n for (const configName of CONFIG_PATHS) {\n const configFilePath = path.join(process.cwd(), configName);\n if (fs.existsSync(configFilePath)) {\n return loadConfigFromPath(configFilePath);\n }\n }\n return null;\n}\n\n/**\n * Warn about TypeScript config files that can't be imported directly\n */\nfunction warnAboutTypeScriptConfigs(): void {\n for (const tsName of TS_CONFIG_PATHS) {\n const tsPath = path.join(process.cwd(), tsName);\n if (fs.existsSync(tsPath)) {\n console.warn(\n `āš ļø Found ${path.basename(tsPath)} but cannot import TypeScript files directly.`,\n );\n console.warn(` Options:`);\n console.warn(` 1. Rename to db.config.mjs (recommended)`);\n console.warn(\n ` 2. Run with tsx: npx tsx node_modules/.bin/plyaz-db migrate status`,\n );\n console.warn(` 3. Use environment variables instead\\n`);\n }\n }\n}\n\n/**\n * Get fallback config from environment variables\n */\nfunction getEnvFallbackConfig(): DatabaseCLIConfig {\n if (!process.env.DATABASE_URL) {\n console.warn(\"āš ļø No db.config.mjs found and DATABASE_URL not set\");\n console.warn(\n \" Create db.config.mjs or set DATABASE_URL environment variable\\n\",\n );\n }\n\n const adapterType = (process.env.DB_ADAPTER ??\n \"sql\") as DatabaseCLIConfig[\"adapter\"];\n\n return {\n adapter: adapterType,\n config: {\n connectionString: process.env.DATABASE_URL,\n },\n };\n}\n\n/**\n * Load database configuration from file or environment\n * @param configPath - Optional explicit path to config file\n */\nasync function loadConfig(configPath?: string): Promise<DatabaseCLIConfig> {\n // If explicit config path provided, use it\n const explicitPath = configPath ?? globalConfigPath;\n if (explicitPath) {\n const resolvedPath = path.resolve(process.cwd(), explicitPath);\n if (fs.existsSync(resolvedPath)) {\n return loadConfigFromPath(resolvedPath);\n }\n console.error(`āŒ Config file not found: ${resolvedPath}`);\n process.exit(1);\n }\n\n // Try standard config locations\n const config = await findAndLoadConfig();\n if (config) return config;\n\n // Warn about TypeScript configs and fall back to env\n warnAboutTypeScriptConfigs();\n return getEnvFallbackConfig();\n}\n\n/** Pool settings optimized for long-running migrations/seeds */\nconst MIGRATION_POOL_SETTINGS = {\n max: 3, // Fewer connections, more stable\n idleTimeoutMillis: 0, // Never timeout idle connections during migrations\n connectionTimeoutMillis: 30000, // 30s to establish connection\n keepAlive: true,\n keepAliveInitialDelayMillis: 5000, // Start keepalive after 5s\n allowExitOnIdle: false, // Don't exit while migrations running\n};\n\n/**\n * Initialize database service\n * @param configPath - Optional explicit path to config file\n * @param forMigration - Use migration-optimized pool settings\n */\nasync function initDatabase(\n configPath?: string,\n forMigration = false,\n): Promise<{\n db: Awaited<ReturnType<typeof createDatabaseService>>;\n adapter: DatabaseAdapterType;\n config: DatabaseCLIConfig;\n}> {\n const config = await loadConfig(configPath);\n\n // Override pool settings for migrations/seeds\n if (forMigration && config.config) {\n config.pool = {\n ...MIGRATION_POOL_SETTINGS,\n ...config.pool, // User config can still override\n };\n }\n\n const db = await createDatabaseService(config);\n\n // Get the base adapter (unwrap extensions if any)\n // CLI needs access to underlying adapter for raw SQL operations\n let adapter = db.adapter;\n while (adapter.baseAdapter) {\n adapter = adapter.baseAdapter;\n }\n\n return { db, adapter, config };\n}\n\nprogram\n .name(\"plyaz-db\")\n .description(\"Database management CLI for @plyaz/db\")\n .version(\"1.1.0\")\n .option(\"-c, --config <path>\", \"Path to db.config.mjs file\")\n .option(\n \"-e, --env <path>\",\n \"Path to .env file (default: .env in current directory)\",\n )\n .hook(\"preAction\", (thisCommand) => {\n const opts = thisCommand.opts();\n\n // Load env file first (before config, so config can use env vars)\n if (opts.env) {\n globalEnvPath = path.resolve(process.cwd(), opts.env);\n loadEnvFile(globalEnvPath);\n console.log(`šŸ“ Using env: ${globalEnvPath}`);\n } else {\n // Default: load .env from current directory\n loadEnvFile(path.join(process.cwd(), \".env\"));\n }\n\n if (opts.config) {\n globalConfigPath = opts.config;\n }\n });\n\n// ============================================================================\n// MIGRATION COMMANDS\n// ============================================================================\n\nconst migrateCommand = program\n .command(\"migrate\")\n .description(\"Database migration commands\");\n\nmigrateCommand\n .command(\"up\")\n .description(\"Run pending migrations\")\n .option(\"-t, --target <version>\", \"Target migration version\")\n .action(async (options) => {\n try {\n const { adapter, config } = await initDatabase(undefined, true);\n\n const migrationManager = new MigrationManager({\n adapter,\n migrationsPath: config.migrationsPath ?? \"./migrations\",\n tableName: config.migrationsTable ?? \"schema_migrations\",\n });\n\n console.log(\"šŸ”„ Running migrations...\");\n const result = await migrationManager.up(options.target);\n\n if (result.success) {\n console.log(`āœ… Applied ${result.value} migration(s)`);\n process.exit(0);\n } else {\n console.error(\"āŒ Migration failed:\", result.error?.message);\n process.exit(1);\n }\n } catch (error) {\n console.error(\"āŒ Error:\", (error as Error).message);\n process.exit(1);\n }\n });\n\nmigrateCommand\n .command(\"down\")\n .description(\"Rollback migrations\")\n .option(\"-s, --steps <number>\", \"Number of migrations to rollback\", \"1\")\n .action(async (options) => {\n try {\n // Validate steps parameter\n const steps = validateSteps(options.steps);\n\n const { adapter, config } = await initDatabase(undefined, true);\n\n const migrationManager = new MigrationManager({\n adapter,\n migrationsPath: config.migrationsPath ?? \"./migrations\",\n tableName: config.migrationsTable ?? \"schema_migrations\",\n });\n\n console.log(`šŸ”„ Rolling back ${steps} migration(s)...`);\n const result = await migrationManager.down(steps);\n\n if (result.success) {\n console.log(`āœ… Rolled back ${result.value} migration(s)`);\n process.exit(0);\n } else {\n console.error(\"āŒ Rollback failed:\", result.error?.message);\n process.exit(1);\n }\n } catch (error) {\n console.error(\"āŒ Error:\", (error as Error).message);\n process.exit(1);\n }\n });\n\nmigrateCommand\n .command(\"status\")\n .description(\"Show migration status\")\n .action(async () => {\n try {\n const { adapter, config } = await initDatabase();\n\n const migrationManager = new MigrationManager({\n adapter,\n migrationsPath: config.migrationsPath ?? \"./migrations\",\n tableName: config.migrationsTable ?? \"schema_migrations\",\n });\n\n const result = await migrationManager.status();\n\n if (result.success && result.value) {\n const { applied, pending } = result.value;\n\n console.log(\"\\nšŸ“Š Migration Status\\n\");\n console.log(`āœ… Applied: ${applied.length}`);\n applied.forEach(\n (m: { version: string; name: string; applied_at: string }) => {\n console.log(\n ` - ${m.version} ${m.name} (${new Date(m.applied_at).toLocaleDateString()})`,\n );\n },\n );\n\n console.log(`\\nā³ Pending: ${pending.length}`);\n pending.forEach((m: string) => {\n console.log(` - ${m}`);\n });\n\n process.exit(0);\n } else {\n console.error(\"āŒ Failed to get status:\", result.error?.message);\n process.exit(1);\n }\n } catch (error) {\n console.error(\"āŒ Error:\", (error as Error).message);\n process.exit(1);\n }\n });\n\nmigrateCommand\n .command(\"reset\")\n .description(\"Rollback all migrations\")\n .option(\"--confirm\", \"Confirm reset operation\")\n .action(async (options) => {\n if (!options.confirm) {\n console.error(\"āŒ Please use --confirm flag to confirm reset operation\");\n process.exit(1);\n }\n\n try {\n const { adapter, config } = await initDatabase(undefined, true);\n\n const migrationManager = new MigrationManager({\n adapter,\n migrationsPath: config.migrationsPath ?? \"./migrations\",\n tableName: config.migrationsTable ?? \"schema_migrations\",\n });\n\n console.log(\"šŸ”„ Resetting database (rolling back all migrations)...\");\n const result = await migrationManager.reset();\n\n if (result.success) {\n console.log(\n `āœ… Reset complete. Rolled back ${result.value} migration(s)`,\n );\n process.exit(0);\n } else {\n console.error(\"āŒ Reset failed:\", result.error?.message);\n process.exit(1);\n }\n } catch (error) {\n console.error(\"āŒ Error:\", (error as Error).message);\n process.exit(1);\n }\n });\n\nmigrateCommand\n .command(\"generate-down\")\n .description(\"Generate DOWN sections for SQL migrations\")\n .option(\"--write\", \"Write changes to files (default: dry run)\")\n .action(async (options) => {\n try {\n const config = await loadConfig();\n const migrationsPath = config.migrationsPath ?? \"./migrations\";\n\n // Dynamic import for the generate-down module\n const generateDownModule = await import(\n \"../migrations/generateDownMigration\"\n );\n const { processDirectory } = generateDownModule;\n\n if (!processDirectory) {\n console.error(\"āŒ generateDownMigration module not found\");\n process.exit(1);\n }\n\n console.log(\"šŸ” Analyzing migrations for DOWN section generation\\n\");\n processDirectory(migrationsPath, !options.write);\n\n process.exit(0);\n } catch (error) {\n console.error(\"āŒ Error:\", (error as Error).message);\n process.exit(1);\n }\n });\n\n// ============================================================================\n// SEED COMMANDS\n// ============================================================================\n\nconst seedCommand = program\n .command(\"seed\")\n .description(\"Database seeding commands\");\n\nseedCommand\n .command(\"run\")\n .description(\"Run seeds\")\n .option(\"-n, --name <name>\", \"Specific seed to run\")\n .option(\"--skip-existing\", \"Skip seeds that have already been run\")\n .action(async (options) => {\n try {\n const { adapter, config } = await initDatabase(undefined, true);\n\n const seedManager = new SeedManager({\n adapter,\n seedsPath: config.seedsPath ?? \"./seeds\",\n tableName: config.seedsTable ?? \"seed_history\",\n skipExisting: options.skipExisting ?? false,\n });\n\n console.log(\"🌱 Running seeds...\");\n const result = await seedManager.run(options.name);\n\n if (result.success) {\n console.log(`āœ… Executed ${result.value} seed(s)`);\n process.exit(0);\n } else {\n console.error(\"āŒ Seeding failed:\", result.error?.message);\n process.exit(1);\n }\n } catch (error) {\n console.error(\"āŒ Error:\", (error as Error).message);\n process.exit(1);\n }\n });\n\nseedCommand\n .command(\"status\")\n .description(\"Show seed status\")\n .action(async () => {\n try {\n const { adapter, config } = await initDatabase();\n\n const seedManager = new SeedManager({\n adapter,\n seedsPath: config.seedsPath ?? \"./seeds\",\n tableName: config.seedsTable ?? \"seed_history\",\n });\n\n const result = await seedManager.status();\n\n if (result.success && result.value) {\n const { executed, pending } = result.value;\n\n console.log(\"\\n🌱 Seed Status\\n\");\n console.log(`āœ… Executed: ${executed.length}`);\n executed.forEach((s: { name: string; run_at: string }) => {\n console.log(\n ` - ${s.name} (${new Date(s.run_at).toLocaleDateString()})`,\n );\n });\n\n console.log(`\\nā³ Pending: ${pending.length}`);\n pending.forEach((s: string) => {\n console.log(` - ${s}`);\n });\n\n process.exit(0);\n } else {\n console.error(\"āŒ Failed to get status:\", result.error?.message);\n process.exit(1);\n }\n } catch (error) {\n console.error(\"āŒ Error:\", (error as Error).message);\n process.exit(1);\n }\n });\n\nseedCommand\n .command(\"reset\")\n .description(\"Reset seeds (run cleanup functions)\")\n .option(\"--confirm\", \"Confirm reset operation\")\n .action(async (options) => {\n if (!options.confirm) {\n console.error(\"āŒ Please use --confirm flag to confirm reset operation\");\n process.exit(1);\n }\n\n try {\n const { adapter, config } = await initDatabase(undefined, true);\n\n const seedManager = new SeedManager({\n adapter,\n seedsPath: config.seedsPath ?? \"./seeds\",\n tableName: config.seedsTable ?? \"seed_history\",\n });\n\n console.log(\"šŸ”„ Resetting seeds...\");\n const result = await seedManager.reset();\n\n if (result.success) {\n console.log(`āœ… Reset ${result.value} seed(s)`);\n process.exit(0);\n } else {\n console.error(\"āŒ Reset failed:\", result.error?.message);\n process.exit(1);\n }\n } catch (error) {\n console.error(\"āŒ Error:\", (error as Error).message);\n process.exit(1);\n }\n });\n\n// ============================================================================\n// DATABASE COMMANDS\n// ============================================================================\n\nprogram\n .command(\"clear\")\n .description(\"Clear all data from database (keep schema)\")\n .option(\"--confirm\", \"Confirm clear operation\")\n .option(\n \"-t, --tables <tables>\",\n \"Comma-separated list of tables to clear (format: schema.table or just table for public)\",\n )\n .option(\n \"-s, --schemas <schemas>\",\n \"Comma-separated list of schemas to clear (default: all user schemas)\",\n )\n .action(async (options) => {\n if (!options.confirm) {\n console.error(\"āŒ Please use --confirm flag to confirm clear operation\");\n process.exit(1);\n }\n\n try {\n const { adapter } = await initDatabase();\n\n console.log(\"šŸ”„ Clearing database data...\");\n\n if (typeof adapter.query !== \"function\") {\n console.error(\"āŒ Clear operation not supported by this adapter\");\n process.exit(1);\n }\n\n let tablesToClear: { schema: string; table: string }[];\n\n if (options.tables) {\n // Parse table list (supports schema.table or just table for public)\n tablesToClear = options.tables.split(\",\").map((t: string) => {\n const trimmed = t.trim();\n if (trimmed.includes(\".\")) {\n const [schema, table] = trimmed.split(\".\");\n return { schema, table };\n }\n return { schema: \"public\", table: trimmed };\n });\n } else {\n // Get all tables from specified schemas or all user schemas\n const schemas = options.schemas\n ? options.schemas.split(\",\").map((s: string) => s.trim())\n : await getUserSchemas(adapter);\n tablesToClear = await getTablesFromSchemas(adapter, schemas);\n }\n\n await clearTables(adapter, tablesToClear);\n\n console.log(`\\nāœ… Cleared ${tablesToClear.length} tables`);\n process.exit(0);\n } catch (error) {\n console.error(\"āŒ Error:\", (error as Error).message);\n process.exit(1);\n }\n });\n\nprogram\n .command(\"drop\")\n .description(\"Drop all tables from database (all schemas)\")\n .option(\"--confirm\", \"Confirm drop operation\")\n .option(\n \"-s, --schemas <schemas>\",\n \"Comma-separated list of schemas to drop from (default: all user schemas)\",\n )\n .option(\n \"--all\",\n \"Drop everything: tables, types, functions, views (not just tables)\",\n )\n .option(\"--drop-schemas\", \"Also drop the schemas themselves (except public)\")\n /* eslint-disable max-lines-per-function, complexity, max-depth, @typescript-eslint/naming-convention */\n .action(async (options) => {\n if (!options.confirm) {\n console.error(\"āŒ Please use --confirm flag to confirm drop operation\");\n process.exit(1);\n }\n\n try {\n const { adapter } = await initDatabase();\n\n console.log(\"šŸ”„ Dropping all tables...\");\n\n if (typeof adapter.query !== \"function\") {\n console.error(\"āŒ Drop operation not supported by this adapter\");\n process.exit(1);\n }\n\n // Get schemas to process (uses INFORMATION_SCHEMA for portability)\n const schemas = options.schemas\n ? options.schemas.split(\",\").map((s: string) => s.trim())\n : await getUserSchemas(adapter);\n\n let totalDropped = 0;\n\n // Drop tables from each schema (uses INFORMATION_SCHEMA for portability)\n for (const schema of schemas) {\n const result = await adapter.query(\n `\n SELECT table_name FROM information_schema.tables\n WHERE table_schema = $1\n AND table_type = 'BASE TABLE'\n `,\n [schema],\n );\n\n const tables = Array.isArray(result)\n ? result\n : (result as unknown as { rows: { table_name: string }[] }).rows ||\n [];\n\n if (tables.length === 0) continue;\n\n console.log(`\\nšŸ“ Schema: ${schema}`);\n for (const { table_name } of tables as { table_name: string }[]) {\n // DROP TABLE CASCADE is PostgreSQL-specific; other databases may need different syntax\n await adapter.query(\n `DROP TABLE IF EXISTS \"${schema}\".\"${table_name}\" CASCADE`,\n );\n console.log(` āœ“ Dropped ${schema}.${table_name}`);\n totalDropped++;\n }\n }\n\n // Drop types, functions, views, triggers, sequences if --all flag is set\n if (options.all) {\n // Drop views (uses INFORMATION_SCHEMA - portable)\n console.log(\"\\nšŸ—‘ļø Dropping views...\");\n for (const schema of schemas) {\n const viewResult = await adapter.query(\n `\n SELECT table_name FROM information_schema.views\n WHERE table_schema = $1\n `,\n [schema],\n );\n const views = Array.isArray(viewResult)\n ? viewResult\n : (viewResult as unknown as { rows: { table_name: string }[] })\n .rows || [];\n for (const { table_name } of views as { table_name: string }[]) {\n try {\n await adapter.query(\n `DROP VIEW IF EXISTS \"${schema}\".\"${table_name}\" CASCADE`,\n );\n console.log(` āœ“ Dropped view ${schema}.${table_name}`);\n } catch {\n // View might already be dropped via CASCADE\n }\n }\n }\n\n // Drop triggers (PostgreSQL-specific, uses information_schema.triggers)\n console.log(\"\\nšŸ—‘ļø Dropping triggers...\");\n for (const schema of schemas) {\n try {\n const triggerResult = await adapter.query(\n `\n SELECT DISTINCT trigger_name, event_object_table\n FROM information_schema.triggers\n WHERE trigger_schema = $1\n `,\n [schema],\n );\n const triggers = Array.isArray(triggerResult)\n ? triggerResult\n : (\n triggerResult as unknown as {\n rows: {\n trigger_name: string;\n event_object_table: string;\n }[];\n }\n ).rows || [];\n for (const { trigger_name, event_object_table } of triggers as {\n trigger_name: string;\n event_object_table: string;\n }[]) {\n try {\n await adapter.query(\n `DROP TRIGGER IF EXISTS \"${trigger_name}\" ON \"${schema}\".\"${event_object_table}\" CASCADE`,\n );\n console.log(` āœ“ Dropped trigger ${schema}.${trigger_name}`);\n } catch {\n // Trigger might already be dropped with table\n }\n }\n } catch {\n // Triggers might already be dropped with tables\n }\n }\n\n // Drop functions (PostgreSQL-specific, uses pg_proc)\n console.log(\"\\nšŸ—‘ļø Dropping functions...\");\n for (const schema of schemas) {\n try {\n const funcResult = await adapter.query(\n `\n SELECT p.proname, pg_get_function_identity_arguments(p.oid) as args\n FROM pg_proc p\n JOIN pg_namespace n ON p.pronamespace = n.oid\n WHERE n.nspname = $1\n AND p.prokind = 'f'\n `,\n [schema],\n );\n const funcs = Array.isArray(funcResult)\n ? funcResult\n : (\n funcResult as unknown as {\n rows: { proname: string; args: string }[];\n }\n ).rows || [];\n for (const { proname, args } of funcs as {\n proname: string;\n args: string;\n }[]) {\n try {\n await adapter.query(\n `DROP FUNCTION IF EXISTS \"${schema}\".\"${proname}\"(${args}) CASCADE`,\n );\n console.log(` āœ“ Dropped function ${schema}.${proname}`);\n } catch {\n // Function might already be dropped\n }\n }\n } catch {\n // pg_proc not available (non-PostgreSQL database)\n console.log(\n ` ⚠ Function dropping not supported for this database`,\n );\n break;\n }\n }\n\n // Drop procedures (PostgreSQL 11+, uses pg_proc)\n console.log(\"\\nšŸ—‘ļø Dropping procedures...\");\n for (const schema of schemas) {\n try {\n const procResult = await adapter.query(\n `\n SELECT p.proname, pg_get_function_identity_arguments(p.oid) as args\n FROM pg_proc p\n JOIN pg_namespace n ON p.pronamespace = n.oid\n WHERE n.nspname = $1\n AND p.prokind = 'p'\n `,\n [schema],\n );\n const procs = Array.isArray(procResult)\n ? procResult\n : (\n procResult as unknown as {\n rows: { proname: string; args: string }[];\n }\n ).rows || [];\n for (const { proname, args } of procs as {\n proname: string;\n args: string;\n }[]) {\n try {\n await adapter.query(\n `DROP PROCEDURE IF EXISTS \"${schema}\".\"${proname}\"(${args}) CASCADE`,\n );\n console.log(` āœ“ Dropped procedure ${schema}.${proname}`);\n } catch {\n // Procedure might already be dropped\n }\n }\n } catch {\n // Procedures not supported or already dropped\n }\n }\n\n // Drop sequences (uses INFORMATION_SCHEMA - portable)\n console.log(\"\\nšŸ—‘ļø Dropping sequences...\");\n for (const schema of schemas) {\n try {\n const seqResult = await adapter.query(\n `\n SELECT sequence_name FROM information_schema.sequences\n WHERE sequence_schema = $1\n `,\n [schema],\n );\n const sequences = Array.isArray(seqResult)\n ? seqResult\n : (seqResult as unknown as { rows: { sequence_name: string }[] })\n .rows || [];\n for (const { sequence_name } of sequences as {\n sequence_name: string;\n }[]) {\n try {\n await adapter.query(\n `DROP SEQUENCE IF EXISTS \"${schema}\".\"${sequence_name}\" CASCADE`,\n );\n console.log(` āœ“ Dropped sequence ${schema}.${sequence_name}`);\n } catch {\n // Sequence might already be dropped with table\n }\n }\n } catch {\n // Sequences might not be supported\n }\n }\n\n // Drop types/enums (PostgreSQL-specific, uses pg_type)\n console.log(\"\\nšŸ—‘ļø Dropping types...\");\n for (const schema of schemas) {\n try {\n const typeResult = await adapter.query(\n `\n SELECT t.typname\n FROM pg_type t\n JOIN pg_namespace n ON t.typnamespace = n.oid\n WHERE n.nspname = $1\n AND t.typtype = 'e'\n `,\n [schema],\n );\n const types = Array.isArray(typeResult)\n ? typeResult\n : (typeResult as unknown as { rows: { typname: string }[] })\n .rows || [];\n for (const { typname } of types as { typname: string }[]) {\n try {\n await adapter.query(\n `DROP TYPE IF EXISTS \"${schema}\".\"${typname}\" CASCADE`,\n );\n console.log(` āœ“ Dropped type ${schema}.${typname}`);\n } catch {\n // Type might already be dropped\n }\n }\n } catch {\n // pg_type not available (non-PostgreSQL database)\n console.log(` ⚠ Type dropping not supported for this database`);\n break;\n }\n }\n\n // Drop domains (PostgreSQL-specific)\n console.log(\"\\nšŸ—‘ļø Dropping domains...\");\n for (const schema of schemas) {\n try {\n const domainResult = await adapter.query(\n `\n SELECT domain_name FROM information_schema.domains\n WHERE domain_schema = $1\n `,\n [schema],\n );\n const domains = Array.isArray(domainResult)\n ? domainResult\n : (domainResult as unknown as { rows: { domain_name: string }[] })\n .rows || [];\n for (const { domain_name } of domains as {\n domain_name: string;\n }[]) {\n try {\n await adapter.query(\n `DROP DOMAIN IF EXISTS \"${schema}\".\"${domain_name}\" CASCADE`,\n );\n console.log(` āœ“ Dropped domain ${schema}.${domain_name}`);\n } catch {\n // Domain might already be dropped\n }\n }\n } catch {\n // Domains might not be supported\n }\n }\n }\n\n // Optionally drop schemas (except public)\n if (options.dropSchemas) {\n console.log(\"\\nšŸ—‘ļø Dropping schemas...\");\n for (const schema of schemas) {\n if (schema === \"public\") continue;\n try {\n await adapter.query(`DROP SCHEMA IF EXISTS \"${schema}\" CASCADE`);\n console.log(` āœ“ Dropped schema ${schema}`);\n } catch {\n console.log(` ⚠ Could not drop schema ${schema}`);\n }\n }\n }\n\n console.log(\n `\\nāœ… Dropped ${totalDropped} tables${options.all ? \" + types, functions, views\" : \"\"}`,\n );\n process.exit(0);\n } catch (error) {\n console.error(\"āŒ Error:\", (error as Error).message);\n process.exit(1);\n }\n });\n/* eslint-enable max-lines-per-function, complexity, max-depth, @typescript-eslint/naming-convention */\n\nprogram\n .command(\"health\")\n .description(\"Check database health\")\n .action(async () => {\n try {\n const { db } = await initDatabase();\n\n const result = await db.healthCheck();\n\n if (result.success && result.value) {\n if (result.value.isHealthy) {\n console.log(\"āœ… Database is healthy\");\n console.log(` Response time: ${result.value.responseTime}ms`);\n console.log(\n \" Details:\",\n JSON.stringify(result.value.details, null, JSON_INDENT_SPACES),\n );\n process.exit(0);\n } else {\n console.error(\"āŒ Database is unhealthy\");\n console.log(\n \" Details:\",\n JSON.stringify(result.value.details, null, JSON_INDENT_SPACES),\n );\n process.exit(1);\n }\n } else {\n console.error(\"āŒ Health check failed\");\n process.exit(1);\n }\n } catch (error) {\n console.error(\"āŒ Error:\", (error as Error).message);\n process.exit(1);\n }\n });\n\n// ============================================================================\n// RESET COMMAND - Full database reset (drop all + optionally migrate)\n// ============================================================================\n\n/**\n * Drop all database objects from specified schemas\n */\n/* eslint-disable max-lines-per-function, complexity, max-depth, @typescript-eslint/naming-convention */\nasync function dropAllObjects(\n adapter: DatabaseAdapterType,\n schemas: string[],\n dropSchemas: boolean,\n): Promise<{ tables: number; objects: number }> {\n let totalTables = 0;\n let totalObjects = 0;\n\n // Drop tables first\n console.log(\"\\nšŸ—‘ļø Dropping tables...\");\n for (const schema of schemas) {\n const result = await adapter.query!(\n `\n SELECT table_name FROM information_schema.tables\n WHERE table_schema = $1\n AND table_type = 'BASE TABLE'\n `,\n [schema],\n );\n\n const tables = Array.isArray(result)\n ? result\n : (result as unknown as { rows: { table_name: string }[] }).rows || [];\n\n if (tables.length === 0) continue;\n\n console.log(`\\nšŸ“ Schema: ${schema}`);\n for (const { table_name } of tables as { table_name: string }[]) {\n await adapter.query!(\n `DROP TABLE IF EXISTS \"${schema}\".\"${table_name}\" CASCADE`,\n );\n console.log(` āœ“ Dropped table ${schema}.${table_name}`);\n totalTables++;\n }\n }\n\n // Drop views\n console.log(\"\\nšŸ—‘ļø Dropping views...\");\n for (const schema of schemas) {\n const viewResult = await adapter.query!(\n `SELECT table_name FROM information_schema.views WHERE table_schema = $1`,\n [schema],\n );\n const views = Array.isArray(viewResult)\n ? viewResult\n : (viewResult as unknown as { rows: { table_name: string }[] }).rows ||\n [];\n for (const { table_name } of views as { table_name: string }[]) {\n try {\n await adapter.query!(\n `DROP VIEW IF EXISTS \"${schema}\".\"${table_name}\" CASCADE`,\n );\n console.log(` āœ“ Dropped view ${schema}.${table_name}`);\n totalObjects++;\n } catch {\n // Already dropped\n }\n }\n }\n\n // Drop triggers\n console.log(\"\\nšŸ—‘ļø Dropping triggers...\");\n for (const schema of schemas) {\n try {\n const triggerResult = await adapter.query!(\n `SELECT DISTINCT trigger_name, event_object_table FROM information_schema.triggers WHERE trigger_schema = $1`,\n [schema],\n );\n const triggers = Array.isArray(triggerResult)\n ? triggerResult\n : (\n triggerResult as unknown as {\n rows: { trigger_name: string; event_object_table: string }[];\n }\n ).rows || [];\n for (const { trigger_name, event_object_table } of triggers as {\n trigger_name: string;\n event_object_table: string;\n }[]) {\n try {\n await adapter.query!(\n `DROP TRIGGER IF EXISTS \"${trigger_name}\" ON \"${schema}\".\"${event_object_table}\" CASCADE`,\n );\n console.log(` āœ“ Dropped trigger ${schema}.${trigger_name}`);\n totalObjects++;\n } catch {\n // Already dropped\n }\n }\n } catch {\n // Triggers already dropped with tables\n }\n }\n\n // Drop functions\n console.log(\"\\nšŸ—‘ļø Dropping functions...\");\n for (const schema of schemas) {\n try {\n const funcResult = await adapter.query!(\n `SELECT p.proname, pg_get_function_identity_arguments(p.oid) as args\n FROM pg_proc p JOIN pg_namespace n ON p.pronamespace = n.oid\n WHERE n.nspname = $1 AND p.prokind = 'f'`,\n [schema],\n );\n const funcs = Array.isArray(funcResult)\n ? funcResult\n : (\n funcResult as unknown as {\n rows: { proname: string; args: string }[];\n }\n ).rows || [];\n for (const { proname, args } of funcs as {\n proname: string;\n args: string;\n }[]) {\n try {\n await adapter.query!(\n `DROP FUNCTION IF EXISTS \"${schema}\".\"${proname}\"(${args}) CASCADE`,\n );\n console.log(` āœ“ Dropped function ${schema}.${proname}`);\n totalObjects++;\n } catch {\n // Already dropped\n }\n }\n } catch {\n // pg_proc not available\n }\n }\n\n // Drop procedures\n console.log(\"\\nšŸ—‘ļø Dropping procedures...\");\n for (const schema of schemas) {\n try {\n const procResult = await adapter.query!(\n `SELECT p.proname, pg_get_function_identity_arguments(p.oid) as args\n FROM pg_proc p JOIN pg_namespace n ON p.pronamespace = n.oid\n WHERE n.nspname = $1 AND p.prokind = 'p'`,\n [schema],\n );\n const procs = Array.isArray(procResult)\n ? procResult\n : (\n procResult as unknown as {\n rows: { proname: string; args: string }[];\n }\n ).rows || [];\n for (const { proname, args } of procs as {\n proname: string;\n args: string;\n }[]) {\n try {\n await adapter.query!(\n `DROP PROCEDURE IF EXISTS \"${schema}\".\"${proname}\"(${args}) CASCADE`,\n );\n console.log(` āœ“ Dropped procedure ${schema}.${proname}`);\n totalObjects++;\n } catch {\n // Already dropped\n }\n }\n } catch {\n // Procedures not supported\n }\n }\n\n // Drop sequences\n console.log(\"\\nšŸ—‘ļø Dropping sequences...\");\n for (const schema of schemas) {\n try {\n const seqResult = await adapter.query!(\n `SELECT sequence_name FROM information_schema.sequences WHERE sequence_schema = $1`,\n [schema],\n );\n const sequences = Array.isArray(seqResult)\n ? seqResult\n : (seqResult as unknown as { rows: { sequence_name: string }[] })\n .rows || [];\n for (const { sequence_name } of sequences as {\n sequence_name: string;\n }[]) {\n try {\n await adapter.query!(\n `DROP SEQUENCE IF EXISTS \"${schema}\".\"${sequence_name}\" CASCADE`,\n );\n console.log(` āœ“ Dropped sequence ${schema}.${sequence_name}`);\n totalObjects++;\n } catch {\n // Already dropped\n }\n }\n } catch {\n // Sequences not supported\n }\n }\n\n // Drop types/enums\n console.log(\"\\nšŸ—‘ļø Dropping types...\");\n for (const schema of schemas) {\n try {\n const typeResult = await adapter.query!(\n `SELECT t.typname FROM pg_type t\n JOIN pg_namespace n ON t.typnamespace = n.oid\n WHERE n.nspname = $1 AND t.typtype = 'e'`,\n [schema],\n );\n const types = Array.isArray(typeResult)\n ? typeResult\n : (typeResult as unknown as { rows: { typname: string }[] }).rows || [];\n for (const { typname } of types as { typname: string }[]) {\n try {\n await adapter.query!(\n `DROP TYPE IF EXISTS \"${schema}\".\"${typname}\" CASCADE`,\n );\n console.log(` āœ“ Dropped type ${schema}.${typname}`);\n totalObjects++;\n } catch {\n // Already dropped\n }\n }\n } catch {\n // pg_type not available\n }\n }\n\n // Drop domains\n console.log(\"\\nšŸ—‘ļø Dropping domains...\");\n for (const schema of schemas) {\n try {\n const domainResult = await adapter.query!(\n `SELECT domain_name FROM information_schema.domains WHERE domain_schema = $1`,\n [schema],\n );\n const domains = Array.isArray(domainResult)\n ? domainResult\n : (domainResult as unknown as { rows: { domain_name: string }[] })\n .rows || [];\n for (const { domain_name } of domains as { domain_name: string }[]) {\n try {\n await adapter.query!(\n `DROP DOMAIN IF EXISTS \"${schema}\".\"${domain_name}\" CASCADE`,\n );\n console.log(` āœ“ Dropped domain ${schema}.${domain_name}`);\n totalObjects++;\n } catch {\n // Already dropped\n }\n }\n } catch {\n // Domains not supported\n }\n }\n\n // Drop schemas if requested\n if (dropSchemas) {\n console.log(\"\\nšŸ—‘ļø Dropping schemas...\");\n for (const schema of schemas) {\n if (schema === \"public\") continue;\n try {\n await adapter.query!(`DROP SCHEMA IF EXISTS \"${schema}\" CASCADE`);\n console.log(` āœ“ Dropped schema ${schema}`);\n } catch {\n console.log(` ⚠ Could not drop schema ${schema}`);\n }\n }\n }\n\n return { tables: totalTables, objects: totalObjects };\n}\n/* eslint-enable max-lines-per-function, complexity, max-depth, @typescript-eslint/naming-convention */\n\nprogram\n .command(\"reset\")\n .description(\n \"Full database reset: drop all objects from all schemas, optionally run migrations\",\n )\n .option(\"--confirm\", \"Confirm reset operation\")\n .option(\n \"-s, --schemas <schemas>\",\n \"Comma-separated list of schemas (default: all user schemas)\",\n )\n .option(\"--drop-schemas\", \"Also drop schemas themselves (except public)\")\n .option(\"--migrate\", \"Run migrations after reset\")\n /* eslint-disable complexity */\n .action(async (options) => {\n if (!options.confirm) {\n console.error(\"āŒ Please use --confirm flag to confirm reset operation\");\n console.error(\n \" This will DROP ALL database objects (tables, types, functions, etc.)\",\n );\n process.exit(1);\n }\n\n try {\n const { adapter, config } = await initDatabase();\n\n if (typeof adapter.query !== \"function\") {\n console.error(\"āŒ Reset operation not supported by this adapter\");\n process.exit(1);\n }\n\n console.log(\"šŸ”„ Resetting database (dropping all objects)...\");\n\n // Get schemas\n const schemas = options.schemas\n ? options.schemas.split(\",\").map((s: string) => s.trim())\n : await getUserSchemas(adapter);\n\n // Drop all objects\n const { tables, objects } = await dropAllObjects(\n adapter,\n schemas,\n options.dropSchemas ?? false,\n );\n\n console.log(\n `\\nāœ… Reset complete: dropped ${tables} tables, ${objects} other objects`,\n );\n\n // Optionally run migrations\n if (options.migrate) {\n console.log(\"\\nšŸ”„ Running migrations...\");\n\n const migrationManager = new MigrationManager({\n adapter,\n migrationsPath: config.migrationsPath ?? \"./migrations\",\n tableName: config.migrationsTable ?? \"schema_migrations\",\n });\n\n const result = await migrationManager.up();\n\n if (result.success) {\n console.log(`āœ… Applied ${result.value} migration(s)`);\n } else {\n console.error(\"āŒ Migration failed:\", result.error?.message);\n process.exit(1);\n }\n }\n\n process.exit(0);\n } catch (error) {\n console.error(\"āŒ Error:\", (error as Error).message);\n process.exit(1);\n }\n });\n\n// ============================================================================\n// INTERACTIVE PROMPTS - For interactive mode\n// ============================================================================\n\n/**\n * Create readline interface for user prompts\n */\nfunction createReadlineInterface(): readline.Interface {\n return readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n}\n\n/**\n * Prompt user for text input\n */\nasync function promptInput(\n message: string,\n defaultValue?: string,\n): Promise<string> {\n const rl = createReadlineInterface();\n const prompt = defaultValue\n ? `${message} (${defaultValue}): `\n : `${message}: `;\n\n return new Promise((resolve) => {\n rl.question(prompt, (answer) => {\n rl.close();\n const trimmed = answer.trim();\n resolve(trimmed !== \"\" ? trimmed : (defaultValue ?? \"\"));\n });\n });\n}\n\n/**\n * Prompt user to select from options\n */\nasync function promptSelect(\n message: string,\n options: string[],\n): Promise<string> {\n const rl = createReadlineInterface();\n\n console.log(message);\n options.forEach((opt, i) => console.log(` ${i + 1}) ${opt}`));\n\n return new Promise((resolve) => {\n rl.question(\"Select (number): \", (answer) => {\n rl.close();\n const index = Number.parseInt(answer, DECIMAL_RADIX) - 1;\n resolve(options[index] ?? options[0]);\n });\n });\n}\n\n/**\n * Prompt user for yes/no confirmation\n */\nasync function promptConfirm(message: string): Promise<boolean> {\n const rl = createReadlineInterface();\n\n return new Promise((resolve) => {\n rl.question(`${message} (y/N): `, (answer) => {\n rl.close();\n resolve(answer.toLowerCase() === \"y\" || answer.toLowerCase() === \"yes\");\n });\n });\n}\n\n/**\n * Run interactive migration creation\n */\nasync function runInteractiveMigration(\n config: DatabaseCLIConfig,\n): Promise<void> {\n console.log();\n console.log(\"šŸ“¦ Create Migration - Interactive Mode\");\n console.log(\"─\".repeat(SEPARATOR_WIDTH));\n console.log();\n\n // Get migration name\n const name = await promptInput(\"Migration name (e.g., add_users_table)\");\n if (!name) {\n console.error(\"āŒ Migration name is required\");\n process.exit(1);\n }\n\n // Validate name\n validateName(name, \"migration\");\n\n // Get table name\n const snakeName = toSnakeCase(name);\n const tableName = await promptInput(\"Table name\", snakeName);\n\n // Get schema\n const schema = await promptInput(\"Database schema\", \"public\");\n validateSchemaName(schema);\n\n // Get type\n const typeChoice = await promptSelect(\"File type:\", [\n \"SQL (.sql)\",\n \"TypeScript (.ts)\",\n ]);\n const type: MigrationType = typeChoice.includes(\"TypeScript\") ? \"ts\" : \"sql\";\n\n // Get author\n const gitUser = getGitUsername();\n const includeAuthor = gitUser\n ? await promptConfirm(`Include author (${gitUser})?`)\n : false;\n const author = includeAuthor ? gitUser : \"\";\n\n // Show summary\n console.log();\n console.log(\"─\".repeat(SEPARATOR_WIDTH));\n console.log(`Migration: ${name}`);\n console.log(`Table: ${schema}.${tableName}`);\n console.log(`Type: ${type.toUpperCase()}`);\n if (author) console.log(`Author: ${author}`);\n console.log(\"─\".repeat(SEPARATOR_WIDTH));\n\n const confirm = await promptConfirm(\"Create migration?\");\n if (!confirm) {\n console.log(\"Cancelled.\");\n process.exit(0);\n }\n\n // Create the migration\n const migrationsPath = config.migrationsPath ?? \"./migrations\";\n if (!fs.existsSync(migrationsPath)) {\n fs.mkdirSync(migrationsPath, { recursive: true });\n console.log(`šŸ“ Created directory: ${migrationsPath}`);\n }\n\n const version = getNextMigrationVersion(migrationsPath);\n const filename = `${version}_${snakeName}.${type}`;\n const filepath = path.join(migrationsPath, filename);\n\n // Check if file exists\n if (fs.existsSync(filepath)) {\n const overwrite = await promptConfirm(\n `File exists. Overwrite ${filename}?`,\n );\n if (!overwrite) {\n console.log(\"Cancelled.\");\n process.exit(0);\n }\n }\n\n const content = getMigrationTemplate({\n name,\n version,\n tableName,\n schema,\n author,\n type,\n });\n\n fs.writeFileSync(filepath, content, \"utf-8\");\n\n console.log();\n console.log(`āœ… Created migration: ${filename}`);\n console.log(` Path: ${filepath}`);\n console.log(` Type: ${type.toUpperCase()}`);\n console.log(` Table: ${schema}.${tableName}`);\n if (author) {\n console.log(` Author: ${author}`);\n }\n console.log(\"\");\n console.log(\"šŸ“ Next steps:\");\n console.log(` 1. Edit the migration file to add your schema changes`);\n console.log(` 2. Run 'plyaz-db migrate up' to apply the migration`);\n console.log(\n ` 3. Test rollback with 'plyaz-db migrate down' before deploying`,\n );\n}\n\n/**\n * Run interactive seed creation\n */\nasync function runInteractiveSeed(config: DatabaseCLIConfig): Promise<void> {\n console.log();\n console.log(\"🌱 Create Seed - Interactive Mode\");\n console.log(\"─\".repeat(SEPARATOR_WIDTH));\n console.log();\n\n // Get seed name\n const name = await promptInput(\"Seed name (e.g., admin_users)\");\n if (!name) {\n console.error(\"āŒ Seed name is required\");\n process.exit(1);\n }\n\n // Validate name\n validateName(name, \"seed\");\n\n // Get table name\n const snakeName = toSnakeCase(name);\n const tableName = await promptInput(\"Table name\", snakeName);\n\n // Get schema\n const schema = await promptInput(\"Database schema\", \"public\");\n validateSchemaName(schema);\n\n // Get type\n const typeChoice = await promptSelect(\"File type:\", [\n \"TypeScript (.ts)\",\n \"SQL (.sql)\",\n \"CSV (.csv)\",\n ]);\n const typeMap: Record<string, SeedType> = {\n \"TypeScript (.ts)\": \"ts\",\n \"SQL (.sql)\": \"sql\",\n \"CSV (.csv)\": \"csv\",\n };\n const type: SeedType = typeMap[typeChoice] ?? \"ts\";\n\n // Get author (not for CSV)\n let author = \"\";\n if (type !== \"csv\") {\n const gitUser = getGitUsername();\n const includeAuthor = gitUser\n ? await promptConfirm(`Include author (${gitUser})?`)\n : false;\n author = includeAuthor ? gitUser : \"\";\n }\n\n // Show summary\n console.log();\n console.log(\"─\".repeat(SEPARATOR_WIDTH));\n console.log(`Seed: ${name}`);\n console.log(`Table: ${schema}.${tableName}`);\n console.log(`Type: ${type.toUpperCase()}`);\n if (author) console.log(`Author: ${author}`);\n console.log(\"─\".repeat(SEPARATOR_WIDTH));\n\n const confirm = await promptConfirm(\"Create seed?\");\n if (!confirm) {\n console.log(\"Cancelled.\");\n process.exit(0);\n }\n\n // Create the seed\n const seedsPath = config.seedsPath ?? \"./seeds\";\n if (!fs.existsSync(seedsPath)) {\n fs.mkdirSync(seedsPath, { recursive: true });\n console.log(`šŸ“ Created directory: ${seedsPath}`);\n }\n\n const order = getNextSeedOrder(seedsPath);\n const filename = `${order}_${snakeName}.${type}`;\n const filepath = path.join(seedsPath, filename);\n\n // Check if file exists\n if (fs.existsSync(filepath)) {\n const overwrite = await promptConfirm(\n `File exists. Overwrite ${filename}?`,\n );\n if (!overwrite) {\n console.log(\"Cancelled.\");\n process.exit(0);\n }\n }\n\n let content: string;\n if (type === \"csv\") {\n content = getCsvSeedTemplate({ name, tableName, schema });\n } else {\n content = getSeedTemplate({\n name,\n order,\n tableName,\n schema,\n author,\n type,\n });\n }\n\n fs.writeFileSync(filepath, content, \"utf-8\");\n\n console.log();\n console.log(`āœ… Created seed: ${filename}`);\n console.log(` Path: ${filepath}`);\n console.log(` Type: ${type.toUpperCase()}`);\n console.log(` Table: ${schema}.${tableName}`);\n if (author && type !== \"csv\") {\n console.log(` Author: ${author}`);\n }\n console.log(\"\");\n console.log(\"šŸ“ Next steps:\");\n console.log(` 1. Edit the seed file to add your data`);\n console.log(` 2. Run 'plyaz-db seed run' to execute seeds`);\n console.log(` 3. Use 'plyaz-db seed status' to check seed status`);\n}\n\n// ============================================================================\n// CREATE COMMANDS - Generate new migration or seed files\n// ============================================================================\n\n/**\n * Generate migration version number based on existing files\n */\nfunction getNextMigrationVersion(migrationsPath: string): string {\n if (!fs.existsSync(migrationsPath)) {\n return \"001\";\n }\n\n const files = fs.readdirSync(migrationsPath);\n const versions = files\n .map((f) => {\n const match = f.match(/^(\\d+)_/);\n return match ? Number.parseInt(match[1], DECIMAL_RADIX) : 0;\n })\n .filter((v) => v > 0);\n\n const maxVersion = versions.length > 0 ? Math.max(...versions) : 0;\n return String(maxVersion + 1).padStart(VERSION_PAD_LENGTH, \"0\");\n}\n\n/**\n * Generate seed order number based on existing files\n */\nfunction getNextSeedOrder(seedsPath: string): string {\n if (!fs.existsSync(seedsPath)) {\n return \"001\";\n }\n\n const files = fs.readdirSync(seedsPath);\n const orders = files\n .map((f) => {\n const match = f.match(/^(\\d+)_/);\n return match ? Number.parseInt(match[1], DECIMAL_RADIX) : 0;\n })\n .filter((v) => v > 0);\n\n const maxOrder = orders.length > 0 ? Math.max(...orders) : 0;\n return String(maxOrder + 1).padStart(VERSION_PAD_LENGTH, \"0\");\n}\n\n/**\n * Convert name to snake_case filename\n */\nfunction toSnakeCase(name: string): string {\n return name\n .replace(/([A-Z])/g, \"_$1\")\n .toLowerCase()\n .replace(/^_/, \"\")\n .replace(/[^a-z0-9_]/g, \"_\")\n .replace(/_+/g, \"_\");\n}\n\n/**\n * Convert name to PascalCase for descriptions\n */\nfunction toPascalCase(name: string): string {\n return name\n .split(/[_\\s-]+/)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(\" \");\n}\n\n/**\n * Template variables interface\n */\ninterface TemplateVars {\n VERSION?: string;\n ORDER?: string;\n DESCRIPTION: string;\n TABLE_NAME: string;\n SCHEMA: string;\n CREATED_DATE: string;\n AUTHOR: string;\n UUID_1?: string;\n UUID_2?: string;\n UUID_3?: string;\n}\n\n/**\n * Get the template directory path\n */\nfunction getTemplateDir(): string {\n // Templates are in the package's template directory\n // Use import.meta.url for ESM compatibility\n const currentFile = fileURLToPath(import.meta.url);\n const currentDir = path.dirname(currentFile);\n const packageRoot = path.resolve(currentDir, \"..\", \"..\");\n return path.join(packageRoot, \"template\");\n}\n\n/**\n * Read and process a template file\n */\nfunction loadTemplate(templatePath: string, vars: TemplateVars): string {\n const fullPath = path.join(getTemplateDir(), templatePath);\n\n if (!fs.existsSync(fullPath)) {\n throw new Error(`Template not found: ${fullPath}`);\n }\n\n let content = fs.readFileSync(fullPath, \"utf-8\");\n\n // Replace all template variables\n for (const [key, value] of Object.entries(vars)) {\n const regex = new RegExp(`\\\\{\\\\{${key}\\\\}\\\\}`, \"g\");\n content = content.replace(regex, value ?? \"\");\n }\n\n return content;\n}\n\n/**\n * Get git username for author field\n */\nfunction getGitUsername(): string {\n try {\n return execSync(\"git config user.name\", { encoding: \"utf-8\" }).trim();\n } catch {\n return \"\";\n }\n}\n\n/**\n * Options for generating migration template\n */\ninterface MigrationTemplateOptions {\n name: string;\n version: string;\n tableName: string;\n schema: string;\n author: string;\n type: \"sql\" | \"ts\";\n}\n\n/**\n * Options for generating seed template\n */\ninterface SeedTemplateOptions {\n name: string;\n order: string;\n tableName: string;\n schema: string;\n author: string;\n type: \"sql\" | \"ts\";\n}\n\n/**\n * Get migration template content from external template file\n */\nfunction getMigrationTemplate(options: MigrationTemplateOptions): string {\n const { name, version, tableName, schema, author, type } = options;\n const description = toPascalCase(name);\n const date = new Date().toISOString().split(\"T\")[0];\n\n const vars: TemplateVars = {\n VERSION: version,\n DESCRIPTION: description,\n TABLE_NAME: tableName,\n SCHEMA: schema,\n CREATED_DATE: date,\n AUTHOR: author,\n };\n\n const templateFile =\n type === \"ts\"\n ? \"migrations/migration.ts.template\"\n : \"migrations/migration.sql.template\";\n\n return loadTemplate(templateFile, vars);\n}\n\n/**\n * Get seed template content from external template file\n */\nfunction getSeedTemplate(options: SeedTemplateOptions): string {\n const { name, order, tableName, schema, author, type } = options;\n const description = toPascalCase(name);\n const date = new Date().toISOString().split(\"T\")[0];\n\n const vars: TemplateVars = {\n ORDER: order,\n DESCRIPTION: description,\n TABLE_NAME: tableName,\n SCHEMA: schema,\n CREATED_DATE: date,\n AUTHOR: author,\n UUID_1: randomUUID(),\n UUID_2: randomUUID(),\n UUID_3: randomUUID(),\n };\n\n const templateFile =\n type === \"ts\" ? \"seeds/seed.ts.template\" : \"seeds/seed.sql.template\";\n\n return loadTemplate(templateFile, vars);\n}\n\n/**\n * Options for generating CSV seed template\n */\ninterface CsvSeedTemplateOptions {\n name: string;\n tableName: string;\n schema: string;\n}\n\n/**\n * Get CSV seed template content from external template file\n */\nfunction getCsvSeedTemplate(options: CsvSeedTemplateOptions): string {\n const { name, tableName, schema } = options;\n const description = toPascalCase(name);\n const date = new Date().toISOString().split(\"T\")[0];\n\n const vars: TemplateVars = {\n DESCRIPTION: description,\n TABLE_NAME: tableName,\n SCHEMA: schema,\n CREATED_DATE: date,\n AUTHOR: \"\",\n UUID_1: randomUUID(),\n UUID_2: randomUUID(),\n UUID_3: randomUUID(),\n };\n\n try {\n return loadTemplate(\"seeds/seed.csv.template\", vars);\n } catch {\n // Fallback to basic CSV structure if template not found\n return `id,name,created_at\n${randomUUID()},Example 1,${new Date().toISOString()}\n${randomUUID()},Example 2,${new Date().toISOString()}\n`;\n }\n}\n\n// Create command group\nconst createCommand = program\n .command(\"create\")\n .description(\"Create new migration or seed files\");\n\ncreateCommand\n .command(\"migration\")\n .description(\"Create a new migration file (interactive if no name provided)\")\n .argument(\"[name]\", \"Migration name (e.g., add_users_table)\")\n .option(\"-t, --type <type>\", \"File type: {sql, ts} (default: sql)\", \"sql\")\n .option(\n \"-T, --table <table>\",\n \"Table name (default: derived from migration name)\",\n )\n .option(\n \"-s, --schema <schema>\",\n \"Database schema (default: public)\",\n \"public\",\n )\n .option(\"--no-author\", \"Skip adding git username as author\")\n .option(\"-i, --interactive\", \"Force interactive mode\")\n .option(\n \"-d, --dry-run\",\n \"Preview what would be created without writing files\",\n )\n .option(\"-f, --force\", \"Overwrite existing file if it exists\")\n .action(\n async (\n name: string | undefined,\n options: {\n type: string;\n table?: string;\n schema: string;\n author: boolean;\n interactive?: boolean;\n dryRun?: boolean;\n force?: boolean;\n },\n ) => {\n try {\n const config = await loadConfig();\n\n // Run interactive mode if no name provided or -i flag\n if (!name || options.interactive) {\n await runInteractiveMigration(config);\n process.exit(0);\n }\n\n // Validate inputs\n validateName(name, \"migration\");\n validateSchemaName(options.schema);\n const fileType = validateMigrationType(options.type);\n\n const migrationsPath = config.migrationsPath ?? \"./migrations\";\n\n // Ensure directory exists (unless dry-run)\n if (!options.dryRun && !fs.existsSync(migrationsPath)) {\n fs.mkdirSync(migrationsPath, { recursive: true });\n console.log(`šŸ“ Created directory: ${migrationsPath}`);\n }\n\n const version = getNextMigrationVersion(migrationsPath);\n const snakeName = toSnakeCase(name);\n const tableName = options.table ?? snakeName;\n const schema = options.schema;\n const author = options.author ? getGitUsername() : \"\";\n const filename = `${version}_${snakeName}.${fileType}`;\n const filepath = path.join(migrationsPath, filename);\n\n // Check if file already exists\n if (fs.existsSync(filepath) && !options.force) {\n console.error(`āŒ File already exists: ${filepath}`);\n console.error(\" Use --force to overwrite\");\n process.exit(1);\n }\n\n // Generate content from template\n const content = getMigrationTemplate({\n name,\n version,\n tableName,\n schema,\n author,\n type: fileType,\n });\n\n // Dry-run mode - show preview\n if (options.dryRun) {\n console.log(\"šŸ” Dry-run mode - no files will be created\\n\");\n console.log(`Would create: ${filename}`);\n console.log(` Path: ${filepath}`);\n console.log(` Type: ${fileType.toUpperCase()}`);\n console.log(` Table: ${schema}.${tableName}`);\n if (author) {\n console.log(` Author: ${author}`);\n }\n console.log(\"\\nšŸ“„ File content preview:\");\n console.log(\"─\".repeat(SEPARATOR_WIDTH));\n console.log(content);\n console.log(\"─\".repeat(SEPARATOR_WIDTH));\n process.exit(0);\n }\n\n // Write file\n fs.writeFileSync(filepath, content, \"utf-8\");\n\n console.log(`āœ… Created migration: ${filename}`);\n console.log(` Path: ${filepath}`);\n console.log(` Type: ${fileType.toUpperCase()}`);\n console.log(` Table: ${schema}.${tableName}`);\n if (author) {\n console.log(` Author: ${author}`);\n }\n console.log(\"\");\n console.log(\"šŸ“ Next steps:\");\n console.log(` 1. Edit the migration file to add your schema changes`);\n console.log(` 2. Run 'plyaz-db migrate up' to apply the migration`);\n console.log(\n ` 3. Test rollback with 'plyaz-db migrate down' before deploying`,\n );\n\n process.exit(0);\n } catch (error) {\n console.error(\"āŒ Error:\", (error as Error).message);\n process.exit(1);\n }\n },\n );\n\ncreateCommand\n .command(\"seed\")\n .description(\"Create a new seed file (interactive if no name provided)\")\n .argument(\"[name]\", \"Seed name (e.g., admin_users)\")\n .option(\"-t, --type <type>\", \"File type: {ts, sql, csv} (default: ts)\", \"ts\")\n .option(\"-T, --table <table>\", \"Table name (default: derived from seed name)\")\n .option(\n \"-s, --schema <schema>\",\n \"Database schema (default: public)\",\n \"public\",\n )\n .option(\"--no-author\", \"Skip adding git username as author\")\n .option(\"-i, --interactive\", \"Force interactive mode\")\n .option(\n \"-d, --dry-run\",\n \"Preview what would be created without writing files\",\n )\n .option(\"-f, --force\", \"Overwrite existing file if it exists\")\n .action(\n async (\n name: string | undefined,\n options: {\n type: string;\n table?: string;\n schema: string;\n author: boolean;\n interactive?: boolean;\n dryRun?: boolean;\n force?: boolean;\n },\n ) => {\n try {\n const config = await loadConfig();\n\n // Run interactive mode if no name provided or -i flag\n if (!name || options.interactive) {\n await runInteractiveSeed(config);\n process.exit(0);\n }\n\n // Validate inputs\n validateName(name, \"seed\");\n validateSchemaName(options.schema);\n const fileType = validateSeedType(options.type);\n\n const seedsPath = config.seedsPath ?? \"./seeds\";\n\n // Ensure directory exists (unless dry-run)\n if (!options.dryRun && !fs.existsSync(seedsPath)) {\n fs.mkdirSync(seedsPath, { recursive: true });\n console.log(`šŸ“ Created directory: ${seedsPath}`);\n }\n\n const order = getNextSeedOrder(seedsPath);\n const snakeName = toSnakeCase(name);\n const tableName = options.table ?? snakeName;\n const schema = options.schema;\n const author = options.author ? getGitUsername() : \"\";\n\n const filename = `${order}_${snakeName}.${fileType}`;\n const filepath = path.join(seedsPath, filename);\n\n // Check if file already exists\n if (fs.existsSync(filepath) && !options.force) {\n console.error(`āŒ File already exists: ${filepath}`);\n console.error(\" Use --force to overwrite\");\n process.exit(1);\n }\n\n // Generate content from template\n let content: string;\n if (fileType === \"csv\") {\n content = getCsvSeedTemplate({ name, tableName, schema });\n } else {\n content = getSeedTemplate({\n name,\n order,\n tableName,\n schema,\n author,\n type: fileType,\n });\n }\n\n // Dry-run mode - show preview\n if (options.dryRun) {\n console.log(\"šŸ” Dry-run mode - no files will be created\\n\");\n console.log(`Would create: ${filename}`);\n console.log(` Path: ${filepath}`);\n console.log(` Type: ${fileType.toUpperCase()}`);\n console.log(` Table: ${schema}.${tableName}`);\n if (author && fileType !== \"csv\") {\n console.log(` Author: ${author}`);\n }\n console.log(\"\\nšŸ“„ File content preview:\");\n console.log(\"─\".repeat(SEPARATOR_WIDTH));\n console.log(content);\n console.log(\"─\".repeat(SEPARATOR_WIDTH));\n process.exit(0);\n }\n\n // Write file\n fs.writeFileSync(filepath, content, \"utf-8\");\n\n console.log(`āœ… Created seed: ${filename}`);\n console.log(` Path: ${filepath}`);\n console.log(` Type: ${fileType.toUpperCase()}`);\n console.log(` Table: ${schema}.${tableName}`);\n if (author && fileType !== \"csv\") {\n console.log(` Author: ${author}`);\n }\n console.log(\"\");\n console.log(\"šŸ“ Next steps:\");\n console.log(` 1. Edit the seed file to add your data`);\n console.log(` 2. Run 'plyaz-db seed run' to execute seeds`);\n console.log(` 3. Use 'plyaz-db seed status' to check seed status`);\n\n process.exit(0);\n } catch (error) {\n console.error(\"āŒ Error:\", (error as Error).message);\n process.exit(1);\n }\n },\n );\n\n// ============================================================================\n// INIT COMMAND - Create db.config.mjs interactively\n// ============================================================================\n\nprogram\n .command(\"init\")\n .description(\"Create a db.config.mjs configuration file interactively\")\n .option(\"-f, --force\", \"Overwrite existing config file\")\n .option(\"-y, --yes\", \"Use default values without prompting\")\n .action(async (options) => {\n const configPath = path.join(process.cwd(), \"db.config.mjs\");\n\n // Check if config already exists\n if (fs.existsSync(configPath) && !options.force) {\n console.error(\"āŒ db.config.mjs already exists\");\n console.error(\" Use --force to overwrite\");\n process.exit(1);\n }\n\n let adapter = \"sql\";\n let connectionString = \"postgresql://user:password@localhost:5432/database\";\n let migrationsPath = \"./migrations\";\n let seedsPath = \"./seeds\";\n let migrationsTable = \"schema_migrations\";\n let seedsTable = \"seed_history\";\n\n if (!options.yes) {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n const question = (prompt: string): Promise<string> =>\n new Promise((resolve) => rl.question(prompt, resolve));\n\n console.log(\"\\nšŸ“¦ Initialize Database Configuration\");\n console.log(\"─\".repeat(SEPARATOR_WIDTH));\n console.log(\"\");\n\n // Adapter selection\n console.log(\"Database adapter:\");\n console.log(\" 1) sql (PostgreSQL - recommended)\");\n console.log(\" 2) drizzle (Drizzle ORM)\");\n console.log(\" 3) supabase (Supabase client)\");\n const adapterChoice = await question(\"Select (number) [1]: \");\n if (adapterChoice === \"2\") adapter = \"drizzle\";\n else if (adapterChoice === \"3\") adapter = \"supabase\";\n\n // Connection string\n const connInput = await question(\n `Connection string [${connectionString}]: `,\n );\n if (connInput.trim()) connectionString = connInput.trim();\n\n // Migrations path\n const migrInput = await question(`Migrations path [${migrationsPath}]: `);\n if (migrInput.trim()) migrationsPath = migrInput.trim();\n\n // Seeds path\n const seedInput = await question(`Seeds path [${seedsPath}]: `);\n if (seedInput.trim()) seedsPath = seedInput.trim();\n\n // Migrations table\n const migrTableInput = await question(\n `Migrations table [${migrationsTable}]: `,\n );\n if (migrTableInput.trim()) migrationsTable = migrTableInput.trim();\n\n // Seeds table\n const seedTableInput = await question(`Seeds table [${seedsTable}]: `);\n if (seedTableInput.trim()) seedsTable = seedTableInput.trim();\n\n rl.close();\n console.log(\"\");\n }\n\n // Load template\n const templateDir = getTemplateDir();\n const templatePath = path.join(\n templateDir,\n \"config\",\n \"db.config.mjs.template\",\n );\n\n if (!fs.existsSync(templatePath)) {\n console.error(`āŒ Template not found: ${templatePath}`);\n process.exit(1);\n }\n\n // Generate config content from template\n let configContent = fs.readFileSync(templatePath, \"utf-8\");\n configContent = configContent\n .replace(/\\{\\{ADAPTER\\}\\}/g, adapter)\n .replace(/\\{\\{CONNECTION_STRING\\}\\}/g, connectionString)\n .replace(/\\{\\{MIGRATIONS_PATH\\}\\}/g, migrationsPath)\n .replace(/\\{\\{SEEDS_PATH\\}\\}/g, seedsPath)\n .replace(/\\{\\{MIGRATIONS_TABLE\\}\\}/g, migrationsTable)\n .replace(/\\{\\{SEEDS_TABLE\\}\\}/g, seedsTable);\n\n fs.writeFileSync(configPath, configContent, \"utf-8\");\n\n console.log(\"āœ… Created db.config.mjs\");\n console.log(\"\");\n console.log(\"šŸ“ Next steps:\");\n console.log(\" 1. Update DATABASE_URL in your .env file\");\n console.log(\" 2. Run 'plyaz-db health' to test connection\");\n console.log(\n \" 3. Run 'plyaz-db create migration <name>' to create migrations\",\n );\n\n process.exit(0);\n });\n\n// ============================================================================\n// VERSION COMMAND - Show current migration version\n// ============================================================================\n\nprogram\n .command(\"version\")\n .description(\"Show current applied migration version\")\n .action(async () => {\n try {\n const { db, adapter, config } = await initDatabase();\n\n const migrationsTable = config.migrationsTable ?? \"schema_migrations\";\n\n // Check if migrations table exists\n const tableCheck = await adapter.query<{ exists: string }>(\n `SELECT EXISTS (\n SELECT FROM information_schema.tables\n WHERE table_name = '${migrationsTable}'\n )::text as exists`,\n );\n\n if (tableCheck[0]?.exists !== \"true\") {\n console.log(\"šŸ“Š Migration Status\");\n console.log(\"─\".repeat(SEPARATOR_WIDTH));\n console.log(\" No migrations have been applied yet\");\n console.log(` (Table '${migrationsTable}' does not exist)`);\n await db.close();\n process.exit(0);\n }\n\n // Get latest migration\n const result = await adapter.query<{\n name: string;\n applied_at: string;\n }>(\n `SELECT name, applied_at FROM ${migrationsTable} ORDER BY applied_at DESC LIMIT 1`,\n );\n\n // Get total count\n const countResult = await adapter.query<{ count: string }>(\n `SELECT COUNT(*) as count FROM ${migrationsTable}`,\n );\n\n console.log(\"šŸ“Š Migration Status\");\n console.log(\"─\".repeat(SEPARATOR_WIDTH));\n\n if (result.length === 0) {\n console.log(\" No migrations have been applied yet\");\n } else {\n const latest = result[0];\n const total = Number.parseInt(countResult[0].count, DECIMAL_RADIX);\n console.log(` Current version: ${latest.name}`);\n console.log(\n ` Applied at: ${new Date(latest.applied_at).toLocaleString()}`,\n );\n console.log(` Total applied: ${total} migration(s)`);\n }\n\n await db.close();\n process.exit(0);\n } catch (error) {\n console.error(\"āŒ Error:\", (error as Error).message);\n process.exit(1);\n }\n });\n\n// ============================================================================\n// MIGRATE VERIFY COMMAND - Verify UP/DOWN sections in SQL migrations\n// ============================================================================\n\nmigrateCommand\n .command(\"verify\")\n .description(\"Verify all SQL migrations have valid UP and DOWN sections\")\n .option(\"--fix\", \"Show suggestions for fixing issues\")\n .action(async (options: { fix?: boolean }) => {\n try {\n const config = await loadConfig(program.opts().config);\n\n const migrationsPath = config.migrationsPath ?? \"./migrations\";\n\n if (!fs.existsSync(migrationsPath)) {\n console.log(\"šŸ“ No migrations directory found\");\n process.exit(0);\n }\n\n const files = fs\n .readdirSync(migrationsPath)\n .filter((f) => f.endsWith(\".sql\"));\n\n if (files.length === 0) {\n console.log(\"šŸ“ No SQL migration files found\");\n process.exit(0);\n }\n\n console.log(\"šŸ” Verifying SQL migrations...\\n\");\n\n let hasErrors = false;\n const issues: {\n file: string;\n type: \"error\" | \"warning\";\n message: string;\n }[] = [];\n\n for (const file of files.sort()) {\n const filepath = path.join(migrationsPath, file);\n const content = fs.readFileSync(filepath, \"utf-8\");\n\n const hasDown = /^--\\s*DOWN\\s*$/im.test(content);\n const hasDownContent =\n hasDown && content.split(/^--\\s*DOWN\\s*$/im)[1]?.trim().length > 0;\n\n if (!hasDown) {\n issues.push({\n file,\n type: \"error\",\n message: \"Missing -- DOWN section\",\n });\n hasErrors = true;\n } else if (!hasDownContent) {\n issues.push({\n file,\n type: \"warning\",\n message: \"DOWN section is empty\",\n });\n }\n\n // Check for common issues\n if (content.includes(\"DROP TABLE\") && !content.includes(\"IF EXISTS\")) {\n issues.push({\n file,\n type: \"warning\",\n message: \"DROP TABLE without IF EXISTS (may fail on rollback)\",\n });\n }\n\n if (\n content.includes(\"CREATE TABLE\") &&\n !content.includes(\"IF NOT EXISTS\")\n ) {\n issues.push({\n file,\n type: \"warning\",\n message: \"CREATE TABLE without IF NOT EXISTS (not idempotent)\",\n });\n }\n }\n\n // Display results\n if (issues.length === 0) {\n console.log(\n `āœ… All ${files.length} SQL migration(s) verified successfully`,\n );\n } else {\n // Group by file\n const byFile = new Map<string, typeof issues>();\n for (const issue of issues) {\n if (!byFile.has(issue.file)) byFile.set(issue.file, []);\n byFile.get(issue.file)!.push(issue);\n }\n\n for (const [file, fileIssues] of byFile) {\n console.log(`šŸ“„ ${file}`);\n for (const issue of fileIssues) {\n const icon = issue.type === \"error\" ? \"āŒ\" : \"āš ļø\";\n console.log(` ${icon} ${issue.message}`);\n }\n console.log(\"\");\n }\n\n console.log(\"─\".repeat(SEPARATOR_WIDTH));\n console.log(\n `Summary: ${files.length} file(s), ${issues.filter((i) => i.type === \"error\").length} error(s), ${issues.filter((i) => i.type === \"warning\").length} warning(s)`,\n );\n\n if (options.fix) {\n console.log(\"\\nšŸ’” Suggestions:\");\n console.log(\" - Add '-- DOWN' marker followed by rollback SQL\");\n console.log(\" - Use 'IF EXISTS' with DROP statements\");\n console.log(\" - Use 'IF NOT EXISTS' with CREATE statements\");\n console.log(\n \" - Run 'plyaz-db migrate generate-down' to auto-generate DOWN sections\",\n );\n }\n }\n\n process.exit(hasErrors ? 1 : 0);\n } catch (error) {\n console.error(\"āŒ Error:\", (error as Error).message);\n process.exit(1);\n }\n });\n\n// Parse arguments\nprogram.parse();\n"]}