feat(dashboard): implement bot settings page with partial updates and serialization fixes

This commit is contained in:
syntaxbullet
2026-01-08 22:35:46 +01:00
parent d46434de18
commit c6fd23b5fa
5 changed files with 740 additions and 13 deletions

View File

@@ -1,3 +1,4 @@
import { jsonReplacer } from './utils';
import { readFileSync, existsSync, writeFileSync } from 'node:fs';
import { join } from 'node:path';
import { z } from 'zod';
@@ -191,14 +192,7 @@ export function saveConfig(newConfig: unknown) {
// Validate and transform input
const validatedConfig = configSchema.parse(newConfig);
const replacer = (key: string, value: any) => {
if (typeof value === 'bigint') {
return value.toString();
}
return value;
};
const jsonString = JSON.stringify(validatedConfig, replacer, 4);
const jsonString = JSON.stringify(validatedConfig, jsonReplacer, 4);
writeFileSync(configPath, jsonString, 'utf-8');
reloadConfig();
}

View File

@@ -9,3 +9,42 @@ import type { Command } from "./types";
export function createCommand(command: Command): Command {
return command;
}
/**
* JSON Replacer function for serialization
* Handles safe serialization of BigInt values to strings
*/
export const jsonReplacer = (_key: string, value: unknown): unknown => {
if (typeof value === 'bigint') {
return value.toString();
}
return value;
};
/**
* Deep merge utility
*/
export function deepMerge(target: any, source: any): any {
if (typeof target !== 'object' || target === null) {
return source;
}
if (typeof source !== 'object' || source === null) {
return source;
}
const output = { ...target };
Object.keys(source).forEach(key => {
if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {
if (!(key in target)) {
Object.assign(output, { [key]: source[key] });
} else {
output[key] = deepMerge(target[key], source[key]);
}
} else {
Object.assign(output, { [key]: source[key] });
}
});
return output;
}