From f9b6603134f3cb7760e03616b2167839037649d6 Mon Sep 17 00:00:00 2001 From: Yunare Maia Date: Thu, 3 Sep 2026 20:16:22 +0000 Subject: [PATCH] fix: preserve existing namespaces on enable() call Previously, calling `enable()` would reset the `names` and `skips` arrays, clearing any namespaces that were previously enabled. This caused behavior where `debug.enable('bar')` after `DEBUG=foo` would silently disable the 'foo' namespace, surprising users who expected both to be active. The fix makes `enable()` merge namespaces instead of replacing them. Empty/null/undefined still resets (for `disable()` compatibility). Fixes debug-js/debug#425 --- src/common.js | 20 ++++++++++++++++---- test.js | 12 ++++++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/common.js b/src/common.js index 141cb578..f5f72a22 100644 --- a/src/common.js +++ b/src/common.js @@ -160,12 +160,22 @@ function setup(env) { * @api public */ function enable(namespaces) { + // Normalize: empty/null/undefined means "disable all" (full replace with empty). + // Non-empty string means "merge" with existing namespaces. + // See: https://github.com/debug-js/debug/issues/425 + const isReset = !namespaces || (typeof namespaces === 'string' && namespaces.trim() === ''); + createDebug.save(namespaces); createDebug.namespaces = namespaces; - createDebug.names = []; - createDebug.skips = []; + if (isReset) { + createDebug.names = []; + createDebug.skips = []; + return; + } + // Merge: preserve previously enabled namespaces when enable() is called + // again (e.g., `debug.enable('bar')` after `DEBUG=foo` won't clear 'foo'). const split = (typeof namespaces === 'string' ? namespaces : '') .trim() .replace(/\s+/g, ',') @@ -174,8 +184,10 @@ function setup(env) { for (const ns of split) { if (ns[0] === '-') { - createDebug.skips.push(ns.slice(1)); - } else { + if (!createDebug.skips.includes(ns.slice(1))) { + createDebug.skips.push(ns.slice(1)); + } + } else if (!createDebug.names.includes(ns)) { createDebug.names.push(ns); } } diff --git a/test.js b/test.js index a1d6f633..89129a1c 100644 --- a/test.js +++ b/test.js @@ -27,6 +27,12 @@ describe('debug', () => { debug.enable('test:12345'); assert.deepStrictEqual(debug('test:12345').enabled, true); assert.deepStrictEqual(debug('test:67890').enabled, false); + + // Enable() should merge, not replace (issue #425) + debug.enable('test:67890'); + assert.deepStrictEqual(debug('test:12345').enabled, true); + assert.deepStrictEqual(debug('test:67890').enabled, true); + debug.disable(); }); it('uses custom log function', () => { @@ -82,12 +88,14 @@ describe('debug', () => { describe('rebuild namespaces string (disable)', () => { it('handle names, skips, and wildcards', () => { + debug.disable(); debug.enable('test,abc*,-abc'); const namespaces = debug.disable(); assert.deepStrictEqual(namespaces, 'test,abc*,-abc'); }); it('handles empty', () => { + debug.disable(); debug.enable(''); const namespaces = debug.disable(); assert.deepStrictEqual(namespaces, ''); @@ -96,18 +104,21 @@ describe('debug', () => { }); it('handles all', () => { + debug.disable(); debug.enable('*'); const namespaces = debug.disable(); assert.deepStrictEqual(namespaces, '*'); }); it('handles skip all', () => { + debug.disable(); debug.enable('-*'); const namespaces = debug.disable(); assert.deepStrictEqual(namespaces, '-*'); }); it('names+skips same with new string', () => { + debug.disable(); debug.enable('test,abc*,-abc'); const oldNames = [...debug.names]; const oldSkips = [...debug.skips]; @@ -119,6 +130,7 @@ describe('debug', () => { }); it('handles re-enabling existing instances', () => { + debug.disable(); debug.disable('*'); const inst = debug('foo'); const messages = [];