fix(runtime/npm/debug): support full DEBUG namespace syntax + extend delimiter#554
fix(runtime/npm/debug): support full DEBUG namespace syntax + extend delimiter#554tsushanth wants to merge 1 commit into
Conversation
…delimiter Closes unjs#546. The `debug` polyfill at `src/runtime/npm/debug.ts` enabled a debugger only when DEBUG was exactly `*` or `env.startsWith(namespace)`. That silently dropped two well-documented features of the upstream `debug` package: - Comma- or whitespace-separated namespace lists: `DEBUG=worker1,worker2` enabled NEITHER worker1 nor worker2 — only `worker1,worker2` as a literal prefix. - Wildcard patterns: `DEBUG=worker:*` did not match `worker:db` / `worker:queue` because the env didn't startsWith the child namespace. And because `startsWith` is unanchored, `DEBUG=work` would also have falsely enabled the `worker` namespace. Implement the upstream parsing algorithm: split DEBUG on `,` / whitespace, treat a leading `-` as a negation, glob-escape regex metacharacters, promote `*` to `.*`, anchor with `^…$`. A namespace is enabled when it matches at least one include pattern and no exclude pattern. Compiled patterns are cached in a single slot keyed on the env string so the common case (DEBUG unchanged between log calls) does not reparse. Also fix `extend(ns, delimiter)` which previously discarded the delimiter argument and concatenated raw: `createDebug("app").extend("worker")` now yields `app:worker` (matching upstream) instead of `appworker`. The delimiter parameter is honoured when supplied. Tests (`test/runtime-npm-debug.test.ts`) cover `*`, exact match, env unset, comma-separated, whitespace-separated, wildcard, anchor guard (`worker:*` does not match `worker`), negation, prefix-not-substring (DEBUG=work does not enable `worker`), env-change-detection, and both `extend` shapes. Verified 7/12 fail on master, 12/12 pass on the fix.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThis PR fixes the debug polyfill to properly parse the DEBUG environment variable with support for wildcard patterns, multiple comma/whitespace-separated namespaces, negation syntax, and cached regex matching. It also updates the namespace extension method to respect configurable delimiters. ChangesDebug Polyfill Enhancement
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Warning Tools execution failed with the following error: Failed to run tools: 13 INTERNAL: Received RST_STREAM with code 2 (Internal server error) Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary
Closes #546.
The
debugpolyfill atsrc/runtime/npm/debug.tsenabled a debugger only when DEBUG was exactly*orenv.startsWith(namespace). That silently dropped two well-documented features of the upstreamdebugpackage:DEBUG=worker1,worker2enabled NEITHERworker1norworker2(only the literal stringworker1,worker2as a prefix).DEBUG=worker:*did not matchworker:db/worker:queuebecause the env didn'tstartsWiththe child namespace.And because
startsWithis unanchored,DEBUG=workwould also have falsely enabled theworkernamespace (no boundary).Fix
Implement the upstream parsing algorithm. Split DEBUG on
,/ whitespace, treat a leading-as a negation, glob-escape regex metacharacters, promote*to.*, anchor with^…$. A namespace is enabled when it matches at least one include pattern and no exclude pattern.Compiled patterns are cached in a single slot keyed on the env string so the common case (DEBUG unchanged between log calls) does not reparse. Cache invalidation is
===on the string — DEBUG flips rarely at runtime and that's sufficient.Also fixed
extend(ns, delimiter)which previously discarded the delimiter argument and concatenated raw:So
createDebug("app").extend("worker")now yieldsapp:worker(matching upstream) instead ofappworker. The delimiter parameter is honoured when supplied.Tests
New file
test/runtime-npm-debug.test.ts. 12 tests covering:*, exact match, env unset (baseline)worker:*)worker:*does NOT match the bareworker)-worker:internal)DEBUG=workdoes NOT enableworker)extenddefault delimiter (:)extendcustom delimiterVerified the new tests fail on
main(7/12 fail) and pass on this branch (12/12).Test plan
npx vitest run test/runtime-npm-debug.test.ts— 12/12 passnpm run lintclean for the touched files (the 5 prettier warnings surfaced are pre-existing in files this PR does not touch)Out of scope
The full upstream
debugAPI also handleshumanize, color picking, and theenable()/disable()runtime control. This PR keeps the existing pass-through stubs for those — they're separately tracked and out of scope for the namespace-matching regression.Summary by CodeRabbit
Improvements
Tests