UNPKG

kist

Version:

Lightweight Package Pipeline Processor with Plugin Architecture

86 lines 3.09 kB
import { AbstractProcess } from "../abstract/AbstractProcess.js"; import { defaultConfig } from "./defaultConfig.js"; export class ConfigStore extends AbstractProcess { constructor() { super(); this.config = defaultConfig; this.logDebug("ConfigStore initialized with default configuration."); } static getInstance() { if (!ConfigStore.instance) { ConfigStore.instance = new ConfigStore(); } return ConfigStore.instance; } get(key) { const keys = key.split("."); let current = this.config; for (const k of keys) { if (current[k] === undefined) { return undefined; } current = current[k]; } this.logDebug(`Configuration key "${key}" retrieved.`); return current; } set(key, value) { const keys = key.split("."); let current = this.config; for (let i = 0; i < keys.length - 1; i++) { const k = keys[i]; if (["__proto__", "constructor", "prototype"].includes(k)) { this.logWarn(`Attempted prototype pollution detected: "${k}"`); return; } if (!Object.prototype.hasOwnProperty.call(current, k) || typeof current[k] !== "object") { current[k] = Object.create(null); } current = current[k]; } const finalKey = keys[keys.length - 1]; if (["__proto__", "constructor", "prototype"].includes(finalKey)) { this.logWarn(`Attempted prototype pollution detected: "${finalKey}"`); return; } current[finalKey] = value; this.logDebug(`Set configuration key "${key}" to: ${JSON.stringify(value)}`); } merge(newConfig) { this.config = this.deepMerge(this.config, newConfig); this.logDebug("Configuration successfully merged."); } getConfig() { return this.config; } print() { console.log("Current Configuration:", JSON.stringify(this.config, null, 2)); } deepMerge(target, source) { if (typeof target !== "object" || target === null) { return source; } for (const key of Object.keys(source)) { if (["__proto__", "constructor", "prototype"].includes(key)) { this.logWarn(`Skipping unsafe key during merge: "${key}"`); continue; } if (source[key] && typeof source[key] === "object" && !Array.isArray(source[key])) { if (!Object.prototype.hasOwnProperty.call(target, key) || typeof target[key] !== "object") { target[key] = Object.create(null); } target[key] = this.deepMerge(target[key], source[key]); } else { target[key] = source[key]; } } return target; } } ConfigStore.instance = null; //# sourceMappingURL=ConfigStore.js.map