UNPKG

supa-seed

Version:

A constraint-aware, framework-agnostic database seeding framework with deep PostgreSQL business logic discovery and MakerKit integration support

185 lines β€’ 6.97 kB
"use strict"; /** * Query Translation Layer * FEAT-003: Memory Management & Schema Mapping Fixes - Phase 2 * * Provides seamless query translation between framework-expected table names * and actual schema table names. Wraps Supabase client operations. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.QueryTranslator = void 0; exports.createQueryTranslator = createQueryTranslator; exports.translateTableName = translateTableName; const logger_1 = require("../core/utils/logger"); const table_mapping_resolver_1 = require("./table-mapping-resolver"); /** * Query translator that automatically maps table names in Supabase queries */ class QueryTranslator { constructor(client, config) { this.tableNameCache = new Map(); this.client = client; this.config = config; this.resolver = (0, table_mapping_resolver_1.createTableMappingResolver)(client, { framework: config.framework, customMappings: config.customMappings, validateWithDatabase: config.enableValidation !== false }); logger_1.Logger.debug('πŸ”„ QueryTranslator initialized:', { framework: config.framework, enableValidation: config.enableValidation, enableCaching: config.enableCaching }); } /** * Translate a framework-expected table name to actual table name */ async translateTableName(expectedTableName) { // Check cache first if caching is enabled if (this.config.enableCaching && this.tableNameCache.has(expectedTableName)) { return this.tableNameCache.get(expectedTableName); } let actualTableName; try { // Determine table type based on expected name const tableType = this.inferTableType(expectedTableName); if (tableType) { const result = await this.resolver.resolveTableName(expectedTableName, tableType); actualTableName = result.actualTableName; if (result.warnings.length > 0) { logger_1.Logger.warn(`⚠️ Table translation warnings for '${expectedTableName}':`, result.warnings); } } else { // Fallback: use expected name as-is actualTableName = expectedTableName; logger_1.Logger.debug(`πŸ”„ No table type mapping for '${expectedTableName}', using as-is`); } } catch (error) { logger_1.Logger.warn(`⚠️ Table translation failed for '${expectedTableName}', using as-is:`, error); actualTableName = expectedTableName; } // Cache the result if caching is enabled if (this.config.enableCaching) { this.tableNameCache.set(expectedTableName, actualTableName); } if (expectedTableName !== actualTableName) { logger_1.Logger.debug(`πŸ—ΊοΈ Table translated: ${expectedTableName} -> ${actualTableName}`); } return actualTableName; } /** * Create a translated Supabase query builder */ async from(tableName) { const actualTableName = await this.translateTableName(tableName); return this.client.from(actualTableName); } /** * Infer table type from expected table name for mapping resolution */ inferTableType(expectedTableName) { // Map common table name patterns to table types const patterns = { // User tables 'users': 'userTable', 'accounts': 'userTable', 'profiles': 'userTable', // Setup tables 'setups': 'setupTable', 'posts': 'setupTable', // Base template tables 'base_templates': 'baseTemplateTable', 'setup_types': 'baseTemplateTable', 'templates': 'baseTemplateTable', // Media tables 'media_attachments': 'mediaAttachmentsTable', 'attachments': 'mediaAttachmentsTable', 'media': 'mediaAttachmentsTable' }; // Direct match if (patterns[expectedTableName]) { return patterns[expectedTableName]; } // Pattern matching for partial matches if (expectedTableName.includes('user') || expectedTableName.includes('account') || expectedTableName.includes('profile')) { return 'userTable'; } if (expectedTableName.includes('setup') || expectedTableName.includes('post')) { return 'setupTable'; } if (expectedTableName.includes('template') || expectedTableName.includes('type')) { return 'baseTemplateTable'; } if (expectedTableName.includes('media') || expectedTableName.includes('attachment')) { return 'mediaAttachmentsTable'; } return null; } /** * Clear translation cache */ clearCache() { this.tableNameCache.clear(); this.resolver.clearCache(); logger_1.Logger.debug('πŸ—‘οΈ QueryTranslator cache cleared'); } /** * Get translation statistics */ getStats() { return { cachedTranslations: this.tableNameCache.size, framework: this.config.framework, enableValidation: this.config.enableValidation !== false, enableCaching: this.config.enableCaching !== false }; } /** * Get all current table mappings */ async getAllMappings() { const mappings = {}; // Common table names to check const commonTables = [ 'users', 'accounts', 'profiles', 'setups', 'posts', 'base_templates', 'setup_types', 'templates', 'media_attachments', 'attachments', 'media' ]; for (const tableName of commonTables) { try { const actualName = await this.translateTableName(tableName); if (actualName !== tableName) { mappings[tableName] = actualName; } } catch (error) { logger_1.Logger.debug(`Could not resolve mapping for table: ${tableName}`); } } return mappings; } } exports.QueryTranslator = QueryTranslator; /** * Factory function to create a query translator */ function createQueryTranslator(client, config) { return new QueryTranslator(client, config); } /** * Utility function for one-off table name translation */ async function translateTableName(client, framework, expectedTableName, customMappings) { const translator = createQueryTranslator(client, { framework, customMappings, enableValidation: true, enableCaching: false }); return translator.translateTableName(expectedTableName); } exports.default = QueryTranslator; //# sourceMappingURL=query-translator.js.map