You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
197 lines
6.3 KiB
197 lines
6.3 KiB
import { PlatformServiceFactory } from "@/services/PlatformServiceFactory";
|
|
import { MASTER_SETTINGS_KEY, Settings } from "./tables/settings";
|
|
import { logger } from "@/utils/logger";
|
|
import { DEFAULT_ENDORSER_API_SERVER } from "@/constants/app";
|
|
|
|
export async function updateDefaultSettings(
|
|
settingsChanges: Settings,
|
|
): Promise<boolean> {
|
|
delete settingsChanges.accountDid; // just in case
|
|
// ensure there is no "id" that would override the key
|
|
delete settingsChanges.id;
|
|
try {
|
|
const platformService = PlatformServiceFactory.getInstance();
|
|
const { sql, params } = generateUpdateStatement(settingsChanges, "settings", "id = ?", [MASTER_SETTINGS_KEY]);
|
|
const result = await platformService.dbExec(sql, params);
|
|
return result.changes === 1;
|
|
} catch (error) {
|
|
logger.error("Error updating default settings:", error);
|
|
if (error instanceof Error) {
|
|
throw error; // Re-throw if it's already an Error with a message
|
|
} else {
|
|
throw new Error(
|
|
`Failed to update settings. We recommend you try again or restart the app.`,
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
export async function updateAccountSettings(
|
|
accountDid: string,
|
|
settingsChanges: Settings,
|
|
): Promise<boolean> {
|
|
settingsChanges.accountDid = accountDid;
|
|
delete settingsChanges.id; // key off account, not ID
|
|
|
|
const platform = PlatformServiceFactory.getInstance();
|
|
|
|
// First try to update existing record
|
|
const { sql: updateSql, params: updateParams } = generateUpdateStatement(
|
|
settingsChanges,
|
|
"settings",
|
|
"accountDid = ?",
|
|
[accountDid]
|
|
);
|
|
|
|
const updateResult = await platform.dbExec(updateSql, updateParams);
|
|
|
|
// If no record was updated, insert a new one
|
|
if (updateResult.changes === 1) {
|
|
return true;
|
|
} else {
|
|
const columns = Object.keys(settingsChanges);
|
|
const values = Object.values(settingsChanges);
|
|
const placeholders = values.map(() => '?').join(', ');
|
|
|
|
const insertSql = `INSERT INTO settings (${columns.join(', ')}) VALUES (${placeholders})`;
|
|
const result = await platform.dbExec(insertSql, values);
|
|
|
|
return result.changes === 1;
|
|
}
|
|
}
|
|
|
|
const DEFAULT_SETTINGS: Settings = {
|
|
id: MASTER_SETTINGS_KEY,
|
|
activeDid: undefined,
|
|
apiServer: DEFAULT_ENDORSER_API_SERVER,
|
|
};
|
|
|
|
// retrieves default settings
|
|
export async function retrieveSettingsForDefaultAccount(): Promise<Settings> {
|
|
const platform = PlatformServiceFactory.getInstance();
|
|
const result = await platform.dbQuery("SELECT * FROM settings WHERE id = ?", [MASTER_SETTINGS_KEY])
|
|
if (!result) {
|
|
return DEFAULT_SETTINGS;
|
|
} else {
|
|
return mapColumnsToValues(result.columns, result.values)[0] as Settings;
|
|
}
|
|
}
|
|
|
|
export async function retrieveSettingsForActiveAccount(): Promise<Settings> {
|
|
const defaultSettings = await retrieveSettingsForDefaultAccount();
|
|
if (!defaultSettings.activeDid) {
|
|
return defaultSettings;
|
|
} else {
|
|
const platform = PlatformServiceFactory.getInstance();
|
|
const result = await platform.dbQuery(
|
|
"SELECT * FROM settings WHERE accountDid = ?",
|
|
[defaultSettings.activeDid]
|
|
);
|
|
const overrideSettings = result ? mapColumnsToValues(result.columns, result.values)[0] as Settings : {};
|
|
const overrideSettingsFiltered = Object.fromEntries(Object.entries(overrideSettings).filter(([_, v]) => v !== null));
|
|
return { ...defaultSettings, ...overrideSettingsFiltered };
|
|
}
|
|
}
|
|
|
|
export async function logToDb(message: string): Promise<void> {
|
|
const platform = PlatformServiceFactory.getInstance();
|
|
const todayKey = new Date().toDateString();
|
|
|
|
// Check if we have any logs for today
|
|
const result = await platform.dbQuery(
|
|
"SELECT message FROM logs WHERE date = ?",
|
|
[todayKey]
|
|
);
|
|
|
|
if (!result || result.values.length === 0) {
|
|
// If no logs for today, clear all previous logs
|
|
await platform.dbExec("DELETE FROM logs");
|
|
|
|
// Insert new log
|
|
const fullMessage = `${new Date().toISOString()} ${message}`;
|
|
await platform.dbExec(
|
|
"INSERT INTO logs (date, message) VALUES (?, ?)",
|
|
[todayKey, fullMessage]
|
|
);
|
|
} else {
|
|
// Append to existing log
|
|
const prevMessages = result.values[0][0] as string;
|
|
const fullMessage = `${prevMessages}\n${new Date().toISOString()} ${message}`;
|
|
|
|
await platform.dbExec(
|
|
"UPDATE logs SET message = ? WHERE date = ?",
|
|
[fullMessage, todayKey]
|
|
);
|
|
}
|
|
}
|
|
|
|
// similar method is in the sw_scripts/additional-scripts.js file
|
|
export async function logConsoleAndDb(
|
|
message: string,
|
|
isError = false,
|
|
): Promise<void> {
|
|
if (isError) {
|
|
logger.error(`${new Date().toISOString()} ${message}`);
|
|
} else {
|
|
logger.log(`${new Date().toISOString()} ${message}`);
|
|
}
|
|
await logToDb(message);
|
|
}
|
|
|
|
/**
|
|
* Generates an SQL UPDATE statement and parameters from a model object.
|
|
* @param model The model object containing fields to update
|
|
* @param tableName The name of the table to update
|
|
* @param whereClause The WHERE clause for the update (e.g. "id = ?")
|
|
* @param whereParams Parameters for the WHERE clause
|
|
* @returns Object containing the SQL statement and parameters array
|
|
*/
|
|
function generateUpdateStatement(
|
|
model: Record<string, any>,
|
|
tableName: string,
|
|
whereClause: string,
|
|
whereParams: any[] = []
|
|
): { sql: string; params: any[] } {
|
|
// Filter out undefined/null values and create SET clause
|
|
const setClauses: string[] = [];
|
|
const params: any[] = [];
|
|
|
|
Object.entries(model).forEach(([key, value]) => {
|
|
if (value !== undefined) {
|
|
setClauses.push(`${key} = ?`);
|
|
params.push(value);
|
|
}
|
|
});
|
|
|
|
if (setClauses.length === 0) {
|
|
throw new Error('No valid fields to update');
|
|
}
|
|
|
|
const sql = `UPDATE ${tableName} SET ${setClauses.join(', ')} WHERE ${whereClause}`;
|
|
|
|
return {
|
|
sql,
|
|
params: [...params, ...whereParams]
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Maps an array of column names to an array of value arrays, creating objects where each column name
|
|
* is mapped to its corresponding value.
|
|
* @param columns Array of column names to use as object keys
|
|
* @param values Array of value arrays, where each inner array corresponds to one row of data
|
|
* @returns Array of objects where each object maps column names to their corresponding values
|
|
*/
|
|
export function mapColumnsToValues(
|
|
columns: string[],
|
|
values: any[][]
|
|
): Record<string, any>[] {
|
|
return values.map(row => {
|
|
const obj: Record<string, any> = {};
|
|
columns.forEach((column, index) => {
|
|
obj[column] = row[index];
|
|
});
|
|
return obj;
|
|
});
|
|
}
|
|
|
|
|