From 6ec228df537f21321aa006e28767aed84ab91fe1 Mon Sep 17 00:00:00 2001 From: DJj123dj <80536295+DJj123dj@users.noreply.github.com> Date: Sun, 13 Apr 2025 21:03:45 +0200 Subject: [PATCH] Added 'save()' feature to configs + improvements --- src/core/api/modules/config.ts | 73 ++++++++++++++++++++++++++++------ 1 file changed, 60 insertions(+), 13 deletions(-) diff --git a/src/core/api/modules/config.ts b/src/core/api/modules/config.ts index 4d34b2d..c59b11a 100644 --- a/src/core/api/modules/config.ts +++ b/src/core/api/modules/config.ts @@ -5,6 +5,7 @@ import { ODId, ODManager, ODManagerData, ODPromiseVoid, ODSystemError, ODValidId import nodepath from "path" import { ODDebugger } from "./console" import fs from "fs" +import * as fjs from "formatted-json-stringify" /**## ODConfigManager `class` * This is an Open Ticket config manager. @@ -14,8 +15,17 @@ import fs from "fs" * You can use this class to get/change/add a config file (`ODConfig`) in your plugin! */ export class ODConfigManager extends ODManager { + /**Alias to Open Ticket debugger. */ + #debug: ODDebugger + constructor(debug:ODDebugger){ super(debug,"config") + this.#debug = debug + } + add(data:ODConfig|ODConfig[],overwrite?:boolean): boolean { + if (Array.isArray(data)) data.forEach((d) => d.useDebug(this.#debug)) + else data.useDebug(this.#debug) + return super.add(data,overwrite) } /**Init all config files. */ async init(){ @@ -42,15 +52,45 @@ export class ODConfig extends ODManagerData { path: string = "" /**An object/array of the entire config file! Variables inside it can be edited while the bot is running! */ data: any + /**Is this config already initiated? */ + initiated: boolean = false + /**An array of listeners to run when the config gets reloaded. These are not executed on the initial loading. */ + protected reloadListeners: Function[] = [] + /**Alias to Open Ticket debugger. */ + protected debug: ODDebugger|null = null constructor(id:ODValidId, data:any){ super(id) this.data = data } + /**Use the Open Ticket debugger for logs. */ + useDebug(debug:ODDebugger|null){ + this.debug = debug + } /**Init the config. */ init(): ODPromiseVoid { - //nothing + this.initiated = true + if (this.debug) this.debug.debug("Initiated config '"+this.file+"' in ODConfigManager.",[{key:"id",value:this.id.value}]) + //please implement this feature in your own config extension & extend this function. + } + /**Reload the config. Be aware that this doesn't update the config data everywhere in the bot! */ + reload(): ODPromiseVoid { + if (this.debug) this.debug.debug("Reloaded config '"+this.file+"' in ODConfigManager.",[{key:"id",value:this.id.value}]) + //please implement this feature in your own config extension & extend this function. + } + /**Save the edited config to the filesystem. This is used by the Interactive Setup CLI. It's not recommended to use this while the bot is running. */ + save(): ODPromiseVoid { + if (this.debug) this.debug.debug("Saved config '"+this.file+"' in ODConfigManager.",[{key:"id",value:this.id.value}]) + //please implement this feature in your own config extension & extend this function. + } + /**Listen for a reload of this JSON file! */ + onReload(cb:Function){ + this.reloadListeners.push(cb) + } + /**Remove all reload listeners. Not recommended! */ + removeAllReloadListeners(){ + this.reloadListeners = [] } } @@ -65,13 +105,13 @@ export class ODConfig extends ODManagerData { * const config = new api.ODJsonConfig("plugin-config","test.json","./plugins/testplugin/") */ export class ODJsonConfig extends ODConfig { - /**An array of listeners to run when the config gets reloaded. These are not executed on the initial loading. */ - #reloadListeners: Function[] = [] + formatter: fjs.custom.BaseFormatter - constructor(id:ODValidId, file:string, customPath?:string){ + constructor(id:ODValidId, file:string, customPath?:string, formatter?:fjs.custom.BaseFormatter){ super(id,{}) this.file = (file.endsWith(".json")) ? file : file+".json" this.path = customPath ? nodepath.join("./",customPath,this.file) : nodepath.join("./config/",this.file) + this.formatter = formatter ?? new fjs.DefaultFormatter(null,true," ") } /**Init the config. */ @@ -79,17 +119,20 @@ export class ODJsonConfig extends ODConfig { if (!fs.existsSync(this.path)) throw new ODSystemError("Unable to parse config \""+nodepath.join("./",this.path)+"\", the file doesn't exist!") try{ this.data = JSON.parse(fs.readFileSync(this.path).toString()) + super.init() }catch(err){ process.emit("uncaughtException",err) throw new ODSystemError("Unable to parse config \""+nodepath.join("./",this.path)+"\"!") } } - /**Reload the JSON file. Be aware that this doesn't update classes that used individual parts of the config data! */ + /**Reload the config. Be aware that this doesn't update the config data everywhere in the bot! */ reload(){ + if (!this.initiated) throw new ODSystemError("Unable to reload config \""+nodepath.join("./",this.path)+"\", the file hasn't been initiated yet!") if (!fs.existsSync(this.path)) throw new ODSystemError("Unable to reload config \""+nodepath.join("./",this.path)+"\", the file doesn't exist!") try{ this.data = JSON.parse(fs.readFileSync(this.path).toString()) - this.#reloadListeners.forEach((cb) => { + super.reload() + this.reloadListeners.forEach((cb) => { try{ cb() }catch(err){ @@ -101,12 +144,16 @@ export class ODJsonConfig extends ODConfig { throw new ODSystemError("Unable to reload config \""+nodepath.join("./",this.path)+"\"!") } } - /**Listen for a reload of this JSON file! */ - onReload(cb:Function){ - this.#reloadListeners.push(cb) - } - /**Remove all reload listeners. Not recommended! */ - removeAllReloadListeners(){ - this.#reloadListeners = [] + /**Save the edited config to the filesystem. This is used by the Interactive Setup CLI. It's not recommended to use this while the bot is running. */ + save(): ODPromiseVoid { + if (!this.initiated) throw new ODSystemError("Unable to save config \""+nodepath.join("./",this.path)+"\", the file hasn't been initiated yet!") + try{ + const contents = this.formatter.stringify(this.data) + fs.writeFileSync(this.path,contents) + super.save() + }catch(err){ + process.emit("uncaughtException",err) + throw new ODSystemError("Unable to save config \""+nodepath.join("./",this.path)+"\"!") + } } } \ No newline at end of file