From 0e0ea3c37838336880500a380576883c4716d3ab Mon Sep 17 00:00:00 2001 From: Eddy G Date: Tue, 24 Jun 2025 22:53:25 -0400 Subject: [PATCH] Add debug flag management system - Default debug flags settable by query param or env variable - Allows comma-separated list of debug flags - Runtime modification (enable/disable/set) via console - Support "all" flag for enabling/disabling everything --- server/scripts/modules/utils/debug.mjs | 148 +++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 server/scripts/modules/utils/debug.mjs diff --git a/server/scripts/modules/utils/debug.mjs b/server/scripts/modules/utils/debug.mjs new file mode 100644 index 0000000..0578933 --- /dev/null +++ b/server/scripts/modules/utils/debug.mjs @@ -0,0 +1,148 @@ +// Debug flag management system +// Supports comma-separated debug flags or "all" for everything +// URL parameter takes priority over OVERRIDES.DEBUG + +let debugFlags = null; // memoized parsed flags +let runtimeFlags = null; // runtime modifications via debugEnable/debugDisable/debugSet + +/** + * Parse debug flags from URL parameter or environment variable + * @returns {Set} Set of enabled debug flags + */ +const parseDebugFlags = () => { + if (debugFlags !== null) return debugFlags; + + let debugString = ''; + + // Check URL parameter first + const urlParams = new URLSearchParams(window.location.search); + const urlDebug = urlParams.get('debug'); + + if (urlDebug) { + debugString = urlDebug; + } else { + // Fall back to OVERRIDES.DEBUG + debugString = (typeof OVERRIDES !== 'undefined' ? OVERRIDES?.DEBUG : '') || ''; + } + + // Parse comma-separated values into a Set + if (debugString.trim()) { + debugFlags = new Set( + debugString + .split(',') + .map((flag) => flag.trim().toLowerCase()) + .filter((flag) => flag.length > 0), + ); + } else { + debugFlags = new Set(); + } + + return debugFlags; +}; + +/** + * Get the current active debug flags (including runtime modifications) + * @returns {Set} Set of currently active debug flags + */ +const getActiveFlags = () => { + if (runtimeFlags !== null) { + return runtimeFlags; + } + return parseDebugFlags(); +}; + +/** + * Check if a debug flag is enabled + * @param {string} flag - The debug flag to check + * @returns {boolean} True if the flag is enabled + */ +const debugFlag = (flag) => { + const activeFlags = getActiveFlags(); + + // "all" enables everything + if (activeFlags.has('all')) { + return true; + } + + // Check for specific flag + return activeFlags.has(flag.toLowerCase()); +}; + +/** + * Enable one or more debug flags at runtime + * @param {...string} flags - Debug flags to enable + * @returns {string[]} Array of currently active debug flags after enabling + */ +const debugEnable = (...flags) => { + // Initialize runtime flags from current state if not already done + if (runtimeFlags === null) { + runtimeFlags = new Set(getActiveFlags()); + } + + // Add new flags + flags.forEach((flag) => { + runtimeFlags.add(flag.toLowerCase()); + }); + + return debugList(); +}; + +/** + * Disable one or more debug flags at runtime + * @param {...string} flags - Debug flags to disable + * @returns {string[]} Array of currently active debug flags after disabling + */ +const debugDisable = (...flags) => { + // Initialize runtime flags from current state if not already done + if (runtimeFlags === null) { + runtimeFlags = new Set(getActiveFlags()); + } + + flags.forEach((flag) => { + const lowerFlag = flag.toLowerCase(); + if (lowerFlag === 'all') { + // Special case: disable all flags + runtimeFlags.clear(); + } else { + runtimeFlags.delete(lowerFlag); + } + }); + + return debugList(); +}; + +/** + * Set debug flags at runtime (overwrites existing flags) + * @param {...string} flags - Debug flags to set (replaces all current flags) + * @returns {string[]} Array of currently active debug flags after setting + */ +const debugSet = (...flags) => { + runtimeFlags = new Set( + flags.map((flag) => flag.toLowerCase()), + ); + + return debugList(); +}; + +/** + * Get current debug flags for inspection + * @returns {string[]} Array of currently active debug flags + */ +const debugList = () => Array.from(getActiveFlags()).sort(); + +// Make debug functions globally accessible in development for console use +if (typeof window !== 'undefined') { + window.debugFlag = debugFlag; + window.debugEnable = debugEnable; + window.debugDisable = debugDisable; + window.debugSet = debugSet; + window.debugList = debugList; +} + +export { + debugFlag, + debugEnable, + debugDisable, + debugSet, + debugList, +};