@ -135,6 +135,19 @@ export async function retrieveSettingsForActiveAccount(): Promise<Settings> {
result . columns ,
result . values ,
) [ 0 ] as Settings ;
// Debug: Check the actual data types from SQLite
logConsoleAndDb (
` [DEBUG] Raw SQLite data types for ${ defaultSettings . activeDid } : ` ,
false ,
) ;
Object . entries ( overrideSettings ) . forEach ( ( [ key , value ] ) = > {
logConsoleAndDb (
` [DEBUG] - ${ key } : ${ typeof value } = ${ JSON . stringify ( value ) } ` ,
false ,
) ;
} ) ;
const overrideSettingsFiltered = Object . fromEntries (
Object . entries ( overrideSettings ) . filter ( ( [ _ , v ] ) = > v !== null ) ,
) ;
@ -144,17 +157,7 @@ export async function retrieveSettingsForActiveAccount(): Promise<Settings> {
// Handle searchBoxes parsing
if ( settings . searchBoxes ) {
try {
// @ts-expect-error - the searchBoxes field is a string in the DB
settings . searchBoxes = JSON . parse ( settings . searchBoxes ) ;
} catch ( error ) {
logConsoleAndDb (
` [databaseUtil] Failed to parse searchBoxes for ${ defaultSettings . activeDid } : ${ error } ` ,
true ,
) ;
// Reset to empty array on parse failure
settings . searchBoxes = [ ] ;
}
settings . searchBoxes = parseJsonField ( settings . searchBoxes , [ ] ) ;
}
return settings ;
@ -326,3 +329,109 @@ export function mapColumnsToValues(
return obj ;
} ) ;
}
/ * *
* Debug function to inspect raw settings data in the database
* This helps diagnose issues with data corruption or malformed JSON
* @param did Optional DID to inspect specific account settings
* @author Matthew Raymer
* /
export async function debugSettingsData ( did? : string ) : Promise < void > {
try {
const platform = PlatformServiceFactory . getInstance ( ) ;
// Get all settings records
const allSettings = await platform . dbQuery ( "SELECT * FROM settings" ) ;
logConsoleAndDb ( ` [DEBUG] Total settings records: ${ allSettings ? . values ? . length || 0 } ` , false ) ;
if ( allSettings ? . values ? . length ) {
allSettings . values . forEach ( ( row , index ) = > {
const settings = mapColumnsToValues ( allSettings . columns , [ row ] ) [ 0 ] ;
logConsoleAndDb ( ` [DEBUG] Settings record ${ index + 1 } : ` , false ) ;
logConsoleAndDb ( ` [DEBUG] - ID: ${ settings . id } ` , false ) ;
logConsoleAndDb ( ` [DEBUG] - accountDid: ${ settings . accountDid } ` , false ) ;
logConsoleAndDb ( ` [DEBUG] - activeDid: ${ settings . activeDid } ` , false ) ;
if ( settings . searchBoxes ) {
logConsoleAndDb ( ` [DEBUG] - searchBoxes type: ${ typeof settings . searchBoxes } ` , false ) ;
logConsoleAndDb ( ` [DEBUG] - searchBoxes value: ${ String ( settings . searchBoxes ) } ` , false ) ;
// Try to parse it
try {
const parsed = JSON . parse ( String ( settings . searchBoxes ) ) ;
logConsoleAndDb ( ` [DEBUG] - searchBoxes parsed successfully: ${ JSON . stringify ( parsed ) } ` , false ) ;
} catch ( parseError ) {
logConsoleAndDb ( ` [DEBUG] - searchBoxes parse error: ${ parseError } ` , true ) ;
}
}
logConsoleAndDb ( ` [DEBUG] - Full record: ${ JSON . stringify ( settings , null , 2 ) } ` , false ) ;
} ) ;
}
// If specific DID provided, also check accounts table
if ( did ) {
const account = await platform . dbQuery ( "SELECT * FROM accounts WHERE did = ?" , [ did ] ) ;
logConsoleAndDb ( ` [DEBUG] Account for ${ did } : ${ JSON . stringify ( account , null , 2 ) } ` , false ) ;
}
} catch ( error ) {
logConsoleAndDb ( ` [DEBUG] Error inspecting settings data: ${ error } ` , true ) ;
}
}
/ * *
* Platform - agnostic JSON parsing utility
* Handles different SQLite implementations :
* - Web SQLite ( wa - sqlite / absurd - sql ) : Auto - parses JSON strings to objects
* - Capacitor SQLite : Returns raw strings that need manual parsing
*
* @param value The value to parse ( could be string or already parsed object )
* @param defaultValue Default value if parsing fails
* @returns Parsed object or default value
* @author Matthew Raymer
* /
export function parseJsonField < T > (
value : unknown ,
defaultValue : T
) : T {
try {
// If already an object (web SQLite auto-parsed), return as-is
if ( typeof value === 'object' && value !== null ) {
logConsoleAndDb (
` [DEBUG] JSON field is already an object (auto-parsed by web SQLite), skipping parse ` ,
false ,
) ;
return value as T ;
}
// If it's a string (Capacitor SQLite or fallback), parse it
if ( typeof value === 'string' ) {
logConsoleAndDb (
` [DEBUG] JSON field is a string, parsing JSON (Capacitor SQLite or web fallback) ` ,
false ,
) ;
return JSON . parse ( value ) as T ;
}
// If it's null/undefined, return default
if ( value === null || value === undefined ) {
return defaultValue ;
}
// Unexpected type, log and return default
logConsoleAndDb (
` [DEBUG] JSON field has unexpected type: ${ typeof value } , returning default ` ,
true ,
) ;
return defaultValue ;
} catch ( error ) {
logConsoleAndDb (
` [databaseUtil] Failed to parse JSON field: ${ error } ` ,
true ,
) ;
return defaultValue ;
}
}