From 200808be304af16361d1368a405a93cd8927baa8 Mon Sep 17 00:00:00 2001 From: Dany Sluijk Date: Wed, 13 Nov 2024 15:37:06 +0100 Subject: [PATCH] feat(option): allow full JSON object notation in the configuration --- lib/option.ts | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/lib/option.ts b/lib/option.ts index c26165767..da5243993 100644 --- a/lib/option.ts +++ b/lib/option.ts @@ -31,8 +31,41 @@ export class Opt extends Variable { return super.getValue(); }; init(cacheFile: string): void { - const cacheV = JSON.parse(Utils.readFile(cacheFile) || '{}')[this.id]; - if (cacheV !== undefined) this.value = cacheV; + // Find the configuration key based on either dot notation, or JavaScript objects. + const findKey = (obj: unknown, path: string[]): T | undefined => { + const top = path.shift(); + if (!top) { + // The path is empty, so this is our value. + return obj as T; + } + + if(!(obj instanceof Object || obj instanceof Array)) { + // Not an array, not an object, but we need to go deeper. + // This is invalid, so return. + return undefined; + } + + const mergedPath = [top, ...path].join("."); + if (mergedPath in obj) { + // The key exists on this level with dot-notation, so we return that. + // Typescript does not know what to do with an untyped object, hence the any. + return (obj as any)[mergedPath] as T; + } + + if (top in obj) { + // The value exists but we are not there yet, so we recurse. + // Typescript does not know what to do with an untyped object, hence the any. + return findKey((obj as any)[top] as object, path); + } + + // Key does not exist :( + return undefined; + } + + const cacheV = findKey(JSON.parse(Utils.readFile(cacheFile) || '{}'), this.id.split(".")); + if (cacheV !== undefined) { + this.value = cacheV; + } this.connect('changed', () => { const cache = JSON.parse(Utils.readFile(cacheFile) || '{}');