@bhagat-surya-dev/dashchat-database-manager
Version:
AI-powered database schema analysis and management library
138 lines • 5.99 kB
JavaScript
;
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