UNPKG

@bhagat-surya-dev/dashchat-database-manager

Version:

AI-powered database schema analysis and management library

138 lines 5.99 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.robustJsonParse = robustJsonParse; exports.safeJsonParse = safeJsonParse; const jsonrepair_1 = require("jsonrepair"); /** * Enhanced production-ready JSON parser that handles malformed JSON from LLMs * Uses jsonrepair library for robust parsing with size validation and multiple fallback strategies */ function robustJsonParse(content, fallback = {}) { if (!content?.trim()) { return fallback; } // Size validation - prevent memory issues const MAX_SIZE = 100000; // 100KB limit if (content.length > MAX_SIZE) { console.warn(`robustJsonParse: Content too large (${content.length} chars), truncating to ${MAX_SIZE}`); content = content.substring(0, MAX_SIZE); // Try to find a reasonable truncation point const lastBraceIndex = content.lastIndexOf('}'); if (lastBraceIndex > MAX_SIZE * 0.8) { content = content.substring(0, lastBraceIndex + 1); } } // Step 1: Basic cleanup let cleaned = content.trim(); try { // First attempt: Parse as-is return JSON.parse(content); } catch (error) { console.log('robustJsonParse: Initial parse failed, attempting cleanup...'); try { // Remove markdown code blocks if present if (cleaned.startsWith('```json')) { cleaned = cleaned.replace(/^```json\s*/i, '').replace(/\s*```$/i, ''); } else if (cleaned.startsWith('```')) { cleaned = cleaned.replace(/^```\s*/i, '').replace(/\s*```$/i, ''); } // Step 2: Extract JSON object bounds const jsonStart = cleaned.indexOf('{'); const jsonEnd = cleaned.lastIndexOf('}'); if (jsonStart !== -1 && jsonEnd !== -1 && jsonEnd > jsonStart) { cleaned = cleaned.substring(jsonStart, jsonEnd + 1); } // Step 3: Try parsing cleaned content return JSON.parse(cleaned); } catch (cleanError) { console.log('robustJsonParse: Cleaned parse failed, trying jsonrepair...'); try { // Step 4: Use jsonrepair to fix malformed JSON const repaired = (0, jsonrepair_1.jsonrepair)(cleaned); return JSON.parse(repaired); } catch (repairError) { console.log('robustJsonParse: jsonrepair failed, attempting partial extraction...'); try { // Step 5: Try to extract just the tables array if full object parsing fails return extractTablesArray(content); } catch (extractError) { console.error('robustJsonParse: All parsing strategies failed:', { originalError: error instanceof Error ? error.message : 'Unknown error', repairError: repairError instanceof Error ? repairError.message : 'Unknown error', extractError: extractError instanceof Error ? extractError.message : 'Unknown error', contentLength: content.length, contentPreview: content.substring(0, 300) + '...', contentSuffix: content.length > 300 ? '...' + content.substring(content.length - 100) : '' }); return fallback; } } } } } /** * Fallback strategy: Extract just the tables array from malformed JSON */ function extractTablesArray(content) { console.log('robustJsonParse: Attempting to extract tables array...'); // Pattern 1: Look for "tables": [...] const tablesArrayMatch = content.match(/"tables"\s*:\s*\[(.*?)\]\s*[,}]/s); if (tablesArrayMatch) { try { const tablesJson = `{"tables": [${tablesArrayMatch[1]}]}`; const repaired = (0, jsonrepair_1.jsonrepair)(tablesJson); const parsed = JSON.parse(repaired); console.log('robustJsonParse: Successfully extracted tables array'); return parsed; } catch (error) { console.log('robustJsonParse: Tables array extraction failed, trying simpler approach...'); } } // Pattern 2: Look for array of table objects const tableObjectsMatch = content.match(/\[(\s*{[\s\S]*?}\s*(?:,\s*{[\s\S]*?}\s*)*)\]/); if (tableObjectsMatch) { try { const tablesJson = `{"tables": [${tableObjectsMatch[1]}]}`; const repaired = (0, jsonrepair_1.jsonrepair)(tablesJson); const parsed = JSON.parse(repaired); console.log('robustJsonParse: Successfully extracted table objects'); return parsed; } catch (error) { console.log('robustJsonParse: Table objects extraction failed'); } } // Pattern 3: Try to find individual table objects and construct array const individualTables = []; const tablePattern = /{[^{}]*"table_name"[^{}]*}/g; let match; while ((match = tablePattern.exec(content)) !== null && individualTables.length < 20) { try { const tableJson = (0, jsonrepair_1.jsonrepair)(match[0]); const parsed = JSON.parse(tableJson); individualTables.push(parsed); } catch (error) { // Skip malformed individual tables } } if (individualTables.length > 0) { console.log(`robustJsonParse: Extracted ${individualTables.length} individual tables`); return { tables: individualTables }; } throw new Error('No valid JSON structure could be extracted'); } /** * Legacy function for backward compatibility * @deprecated Use robustJsonParse instead */ function safeJsonParse(content, fallback = {}) { return robustJsonParse(content, fallback); } //# sourceMappingURL=robust_json_parser.js.map