diff --git a/src/node/utils/Settings.ts b/src/node/utils/Settings.ts index 7b7bca5d6..ebc564944 100644 --- a/src/node/utils/Settings.ts +++ b/src/node/utils/Settings.ts @@ -28,6 +28,7 @@ */ import {MapArrayType} from "../types/MapType"; +import {SettingsNode, SettingsTree} from "./SettingsTree"; const absolutePaths = require('./AbsolutePaths'); const deepEqual = require('fast-deep-equal/es6'); @@ -601,7 +602,7 @@ const coerceValue = (stringValue:string) => { * see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#The_replacer_parameter */ const lookupEnvironmentVariables = (obj: MapArrayType) => { - function replaceEnvs(obj: MapArrayType) { + const replaceEnvs = (obj: MapArrayType)=> { for (let [key, value] of Object.entries(obj)) { /* * the first invocation of replacer() is with an empty key. Just go on, or @@ -620,13 +621,13 @@ const lookupEnvironmentVariables = (obj: MapArrayType) => { * The environment variable expansion syntax "${ENV_VAR}" is just a string * of specific form, after all. */ - if (typeof value !== 'string' && typeof value !== 'object') { + if ((typeof value !== 'string' && typeof value !== 'object') || value === null) { obj[key] = value; continue } - if (typeof value === "object") { - replaceEnvs(value); + if (typeof obj[key] === "object") { + replaceEnvs(obj[key]); continue } @@ -685,20 +686,47 @@ const lookupEnvironmentVariables = (obj: MapArrayType) => { obj[key] = coerceValue(envVarValue!); } + return obj } replaceEnvs(obj); + const envVars:MapArrayType = {} + // Add plugin ENV variables - for (const key of Object.keys(process.env)) { - if (key.startsWith('EP_')) { - // Add to object - obj[key] = process.env[key]; + + /** + * If the key contains a double underscore, it's a plugin variable + * E.g. + */ + let treeEntries = new Map + const root = new SettingsNode("EP") + + for (let [env,envVal] of Object.entries(process.env)) { + if(!env.startsWith("EP")) continue + treeEntries.set(env, envVal) + } + + treeEntries.forEach((value, key) => { + let pathToKey = key.split("__") + let currentNode = root + let depth = 0 + depth++ + currentNode.addChild(pathToKey, value!) + }) + + console.log("Root is", JSON.stringify(root, (k,v)=>{ + if(v instanceof Map) { + return { + dataType: 'Map', + value: Array.from(v.entries()), // or with spread: value: [...value] + }; + } else { + return v; } - } - - console.log(obj) + })) + obj = Object.assign(obj, envVars) return obj; }; @@ -892,4 +920,3 @@ exports.exportedForTestingOnly = { // initially load settings exports.reloadSettings(); - diff --git a/src/node/utils/SettingsTree.ts b/src/node/utils/SettingsTree.ts new file mode 100644 index 000000000..b5b533e5d --- /dev/null +++ b/src/node/utils/SettingsTree.ts @@ -0,0 +1,69 @@ +export class SettingsTree { + private children: Map; + constructor() { + this.children = new Map(); + } + + public addChild(key: string, value: string) { + this.children.set(key, new SettingsNode(key, value)); + } + + public removeChild(key: string) { + this.children.delete(key); + } + + public getChild(key: string) { + return this.children.get(key); + } + + public hasChild(key: string) { + return this.children.has(key); + } +} + + +export class SettingsNode { + private readonly key: string; + private value: string|undefined; + private children: Map; + + constructor(key: string, value?: string) { + this.key = key; + this.value = value; + this.children = new Map(); + } + + public addChild(key: string[], value?: string) { + let depth = 0 + + while (depth < key.length) { + const k = key[depth]; + const slicedKey = key.slice(depth + 1) + depth++; + if(this.key === k) { + console.log("same key") + continue + } + if (this.children.has(k)) { + console.log("has child", k) + this.children.get(k)!.addChild(slicedKey, value); + } else { + const newNode = new SettingsNode(k); + this.children.set(k, newNode); + if(slicedKey.length > 0) + newNode.addChild(slicedKey, value); + else + newNode.value = value; + this.children.get(k)!.addChild(slicedKey, undefined); + } + } + } + + public getChild(key: string) { + return this.children.get(key); + } + + public hasChild(key: string) { + return this.children.has(key); + } +}