fix linting

This commit is contained in:
2025-06-19 19:06:37 -06:00
parent 15ba31033f
commit 78d27eecfb
3 changed files with 304 additions and 148 deletions

View File

@@ -26,10 +26,19 @@ import "dexie-export-import";
import { PlatformServiceFactory } from "./PlatformServiceFactory";
import { db, accountsDBPromise } from "../db/index";
import { Contact, ContactMethod } from "../db/tables/contacts";
import { Settings, MASTER_SETTINGS_KEY, BoundingBox } from "../db/tables/settings";
import {
Settings,
MASTER_SETTINGS_KEY,
BoundingBox,
} from "../db/tables/settings";
import { Account } from "../db/tables/accounts";
import { logger } from "../utils/logger";
import { mapColumnsToValues, parseJsonField, generateUpdateStatement, generateInsertStatement } from "../db/databaseUtil";
import {
mapColumnsToValues,
parseJsonField,
generateUpdateStatement,
generateInsertStatement,
} from "../db/databaseUtil";
import { importFromMnemonic } from "../libs/util";
/**
@@ -186,12 +195,18 @@ export async function getSqliteContacts(): Promise<Contact[]> {
let contacts: Contact[] = [];
if (result?.values?.length) {
const preContacts = mapColumnsToValues(result.columns, result.values) as unknown as Contact[];
const preContacts = mapColumnsToValues(
result.columns,
result.values,
) as unknown as Contact[];
// This is redundant since absurd-sql auto-parses JSON strings to objects.
// But we started it, and it should be known everywhere, so we're keeping it.
contacts = preContacts.map((contact) => {
if (contact.contactMethods) {
contact.contactMethods = parseJsonField(contact.contactMethods, []) as ContactMethod[];
contact.contactMethods = parseJsonField(
contact.contactMethods,
[],
) as ContactMethod[];
}
return contact;
});
@@ -212,7 +227,7 @@ export async function getSqliteContacts(): Promise<Contact[]> {
*
* This function connects to the Dexie database and retrieves all settings
* records.
*
*
* Settings include both master settings (id=1) and account-specific settings
* that override the master settings for particular user accounts.
*
@@ -275,16 +290,21 @@ export async function getSqliteSettings(): Promise<Settings[]> {
let settings: Settings[] = [];
if (result?.values?.length) {
const presettings =
mapColumnsToValues(result.columns, result.values) as Settings[];
const presettings = mapColumnsToValues(
result.columns,
result.values,
) as Settings[];
// This is redundant since absurd-sql auto-parses JSON strings to objects.
// But we started it, and it should be known everywhere, so we're keeping it.
settings = presettings.map((setting) => {
if (setting.searchBoxes) {
setting.searchBoxes = parseJsonField(setting.searchBoxes, []) as Array<{ name: string, bbox: BoundingBox }>;
setting.searchBoxes = parseJsonField(
setting.searchBoxes,
[],
) as Array<{ name: string; bbox: BoundingBox }>;
}
return setting;
})
});
}
logger.info(
@@ -557,7 +577,9 @@ function compareSettings(
// Find settings that exist in Dexie but not in SQLite
for (const dexieSetting of dexieSettings) {
const sqliteSetting = sqliteSettings.find((s) => s.accountDid == dexieSetting.accountDid);
const sqliteSetting = sqliteSettings.find(
(s) => s.accountDid == dexieSetting.accountDid,
);
if (!sqliteSetting) {
added.push(dexieSetting);
} else if (!settingsEqual(dexieSetting, sqliteSetting)) {
@@ -569,7 +591,9 @@ function compareSettings(
// Find settings that exist in SQLite but not in Dexie
for (const sqliteSetting of sqliteSettings) {
const dexieSetting = dexieSettings.find((s) => s.accountDid == sqliteSetting.accountDid);
const dexieSetting = dexieSettings.find(
(s) => s.accountDid == sqliteSetting.accountDid,
);
if (!dexieSetting) {
missing.push(sqliteSetting);
}
@@ -654,22 +678,29 @@ function compareAccounts(dexieAccounts: Account[], sqliteDids: string[]) {
* ```
*/
function contactsEqual(contact1: Contact, contact2: Contact): boolean {
const ifEmpty = (arg: any, def: any) => !!arg ? arg : def;
const ifEmpty = (arg: any, def: any) => (arg ? arg : def);
const contact1Methods =
contact1.contactMethods && Array.isArray(contact1.contactMethods) && contact1.contactMethods.length > 0
? JSON.stringify(contact1.contactMethods)
: "[]";
contact1.contactMethods &&
Array.isArray(contact1.contactMethods) &&
contact1.contactMethods.length > 0
? JSON.stringify(contact1.contactMethods)
: "[]";
const contact2Methods =
contact2.contactMethods && Array.isArray(contact2.contactMethods) && contact2.contactMethods.length > 0
? JSON.stringify(contact2.contactMethods)
: "[]";
contact2.contactMethods &&
Array.isArray(contact2.contactMethods) &&
contact2.contactMethods.length > 0
? JSON.stringify(contact2.contactMethods)
: "[]";
return (
ifEmpty(contact1.did, "") == ifEmpty(contact2.did, "") &&
ifEmpty(contact1.name, "") == ifEmpty(contact2.name, "") &&
ifEmpty(contact1.notes, "") == ifEmpty(contact2.notes, "") &&
ifEmpty(contact1.profileImageUrl, "") == ifEmpty(contact2.profileImageUrl, "") &&
ifEmpty(contact1.publicKeyBase64, "") == ifEmpty(contact2.publicKeyBase64, "") &&
ifEmpty(contact1.nextPubKeyHashB64, "") == ifEmpty(contact2.nextPubKeyHashB64, "") &&
ifEmpty(contact1.profileImageUrl, "") ==
ifEmpty(contact2.profileImageUrl, "") &&
ifEmpty(contact1.publicKeyBase64, "") ==
ifEmpty(contact2.publicKeyBase64, "") &&
ifEmpty(contact1.nextPubKeyHashB64, "") ==
ifEmpty(contact2.nextPubKeyHashB64, "") &&
!!contact1.seesMe == !!contact2.seesMe &&
!!contact1.registered == !!contact2.registered &&
contact1Methods == contact2Methods
@@ -762,18 +793,21 @@ function settingsEqual(settings1: Settings, settings2: Settings): boolean {
* }
* ```
*/
function accountsEqual(account1: Account, account2: Account): boolean {
return (
account1.id === account2.id &&
account1.dateCreated === account2.dateCreated &&
account1.derivationPath === account2.derivationPath &&
account1.did === account2.did &&
account1.identity === account2.identity &&
account1.mnemonic === account2.mnemonic &&
account1.passkeyCredIdHex === account2.passkeyCredIdHex &&
account1.publicKeyHex === account2.publicKeyHex
);
}
//
// unused
//
// function accountsEqual(account1: Account, account2: Account): boolean {
// return (
// account1.id === account2.id &&
// account1.dateCreated === account2.dateCreated &&
// account1.derivationPath === account2.derivationPath &&
// account1.did === account2.did &&
// account1.identity === account2.identity &&
// account1.mnemonic === account2.mnemonic &&
// account1.passkeyCredIdHex === account2.passkeyCredIdHex &&
// account1.publicKeyHex === account2.publicKeyHex
// );
// }
/**
* Generates YAML-formatted comparison data
@@ -801,58 +835,64 @@ export function generateComparisonYaml(comparison: DataComparison): string {
const yaml = {
summary: {
dexieContacts: comparison.dexieContacts.length,
sqliteContacts: comparison.sqliteContacts.filter(c => c.did).length,
sqliteContacts: comparison.sqliteContacts.filter((c) => c.did).length,
dexieSettings: comparison.dexieSettings.length,
sqliteSettings: comparison.sqliteSettings.filter(s => s.accountDid || s.activeDid).length,
sqliteSettings: comparison.sqliteSettings.filter(
(s) => s.accountDid || s.activeDid,
).length,
dexieAccounts: comparison.dexieAccounts.length,
sqliteAccounts: comparison.sqliteAccounts.filter(a => a).length,
sqliteAccounts: comparison.sqliteAccounts.filter((a) => a).length,
},
differences: {
contacts: {
added: comparison.differences.contacts.added.length,
modified: comparison.differences.contacts.modified.length,
unmodified: comparison.differences.contacts.unmodified.length,
missing: comparison.differences.contacts.missing.filter(c => c.did).length,
missing: comparison.differences.contacts.missing.filter((c) => c.did)
.length,
},
settings: {
added: comparison.differences.settings.added.length,
modified: comparison.differences.settings.modified.length,
unmodified: comparison.differences.settings.unmodified.length,
missing: comparison.differences.settings.missing.filter(s => s.accountDid || s.activeDid).length,
missing: comparison.differences.settings.missing.filter(
(s) => s.accountDid || s.activeDid,
).length,
},
accounts: {
added: comparison.differences.accounts.added.length,
unmodified: comparison.differences.accounts.unmodified.length,
missing: comparison.differences.accounts.missing.filter(a => a).length,
missing: comparison.differences.accounts.missing.filter((a) => a)
.length,
},
},
details: {
contacts: {
dexie: comparison.dexieContacts.map((c) => ({
did: c.did,
name: c.name || '<empty>',
name: c.name || "<empty>",
contactMethods: (c.contactMethods || []).length,
})),
sqlite: comparison.sqliteContacts
.filter(c => c.did)
.filter((c) => c.did)
.map((c) => ({
did: c.did,
name: c.name || '<empty>',
name: c.name || "<empty>",
contactMethods: (c.contactMethods || []).length,
})),
},
settings: {
dexie: comparison.dexieSettings.map((s) => ({
id: s.id,
type: s.id === MASTER_SETTINGS_KEY ? 'master' : 'account',
type: s.id === MASTER_SETTINGS_KEY ? "master" : "account",
did: s.activeDid || s.accountDid,
isRegistered: s.isRegistered || false,
})),
sqlite: comparison.sqliteSettings
.filter(s => s.accountDid || s.activeDid)
.filter((s) => s.accountDid || s.activeDid)
.map((s) => ({
id: s.id,
type: s.id === MASTER_SETTINGS_KEY ? 'master' : 'account',
type: s.id === MASTER_SETTINGS_KEY ? "master" : "account",
did: s.activeDid || s.accountDid,
isRegistered: s.isRegistered || false,
})),
@@ -1039,20 +1079,22 @@ export async function migrateSettings(): Promise<MigrationResult> {
dexieSettings: dexieSettings.length,
});
const platformService = PlatformServiceFactory.getInstance();
// Create an array of promises for all settings migrations
const migrationPromises = dexieSettings.map(async (setting) => {
logger.info("[MigrationService] Starting to migrate settings", setting);
let sqliteSettingRaw: { columns: string[], values: unknown[][] } | undefined;
let sqliteSettingRaw:
| { columns: string[]; values: unknown[][] }
| undefined;
if (!setting.accountDid) {
sqliteSettingRaw = await platformService.dbQuery(
"SELECT * FROM settings WHERE accountDid is null"
"SELECT * FROM settings WHERE accountDid is null",
);
} else {
sqliteSettingRaw = await platformService.dbQuery(
"SELECT * FROM settings WHERE accountDid = ?",
[setting.accountDid]
)
[setting.accountDid],
);
}
logger.info("[MigrationService] Migrating one set of settings:", {
setting,
@@ -1060,9 +1102,11 @@ export async function migrateSettings(): Promise<MigrationResult> {
});
if (sqliteSettingRaw?.values?.length) {
// should cover the master settings, were accountDid is null
const sqliteSettings = mapColumnsToValues(sqliteSettingRaw.columns, sqliteSettingRaw.values) as unknown as Settings[];
const sqliteSettings = mapColumnsToValues(
sqliteSettingRaw.columns,
sqliteSettingRaw.values,
) as unknown as Settings[];
const sqliteSetting = sqliteSettings[0];
console.log('sqliteSetting', sqliteSetting)
let conditional: string;
let preparams: unknown[];
if (!setting.accountDid) {
@@ -1076,16 +1120,16 @@ export async function migrateSettings(): Promise<MigrationResult> {
sqliteSetting as unknown as Record<string, unknown>,
"settings",
conditional,
preparams
preparams,
);
await platformService.dbExec(sql, params)
await platformService.dbExec(sql, params);
result.settingsMigrated++;
} else {
// insert new setting
delete setting.activeDid; // ensure we don't set the activeDid (since master settings are an update and don't hit this case)
const { sql, params } = generateInsertStatement(
setting as unknown as Record<string, unknown>,
"settings"
"settings",
);
await platformService.dbExec(sql, params);
result.settingsMigrated++;
@@ -1094,12 +1138,19 @@ export async function migrateSettings(): Promise<MigrationResult> {
// Wait for all migrations to complete
const updatedSettings = await Promise.all(migrationPromises);
logger.info("[MigrationService] Finished migrating settings", updatedSettings, result);
logger.info(
"[MigrationService] Finished migrating settings",
updatedSettings,
result,
);
return result;
} catch (error) {
logger.error("[MigrationService] Complete settings migration failed:", error);
logger.error(
"[MigrationService] Complete settings migration failed:",
error,
);
const errorMessage = `Settings migration failed: ${error}`;
result.errors.push(errorMessage);
result.success = false;
@@ -1158,12 +1209,17 @@ export async function migrateAccounts(): Promise<MigrationResult> {
// Group accounts by DID and keep only the most recent one
const accountsByDid = new Map<string, Account>();
dexieAccounts.forEach(account => {
dexieAccounts.forEach((account) => {
const existingAccount = accountsByDid.get(account.did);
if (!existingAccount || new Date(account.dateCreated) > new Date(existingAccount.dateCreated)) {
if (
!existingAccount ||
new Date(account.dateCreated) > new Date(existingAccount.dateCreated)
) {
accountsByDid.set(account.did, account);
if (existingAccount) {
result.warnings.push(`Found duplicate account for DID ${account.did}, keeping most recent`);
result.warnings.push(
`Found duplicate account for DID ${account.did}, keeping most recent`,
);
}
}
});
@@ -1174,30 +1230,34 @@ export async function migrateAccounts(): Promise<MigrationResult> {
// Check if account already exists
const existingResult = await platformService.dbQuery(
"SELECT did FROM accounts WHERE did = ?",
[did]
[did],
);
if (existingResult?.values?.length) {
result.warnings.push(`Account with DID ${did} already exists, skipping`);
result.warnings.push(
`Account with DID ${did} already exists, skipping`,
);
continue;
}
if (account.mnemonic) {
await importFromMnemonic(account.mnemonic, account.derivationPath);
result.accountsMigrated++;
} else {
result.errors.push(`Account with DID ${did} has no mnemonic, skipping`);
result.errors.push(
`Account with DID ${did} has no mnemonic, skipping`,
);
}
logger.info("[MigrationService] Successfully migrated account", {
did,
dateCreated: account.dateCreated
dateCreated: account.dateCreated,
});
} catch (error) {
const errorMessage = `Failed to migrate account ${did}: ${error}`;
result.errors.push(errorMessage);
logger.error("[MigrationService] Account migration failed:", {
error,
did
did,
});
}
}
@@ -1211,7 +1271,10 @@ export async function migrateAccounts(): Promise<MigrationResult> {
const errorMessage = `Account migration failed: ${error}`;
result.errors.push(errorMessage);
result.success = false;
logger.error("[MigrationService] Complete account migration failed:", error);
logger.error(
"[MigrationService] Complete account migration failed:",
error,
);
return result;
}
}