diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
deleted file mode 100644
index 58858535..00000000
--- a/.github/ISSUE_TEMPLATE.md
+++ /dev/null
@@ -1,28 +0,0 @@
-
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
deleted file mode 100644
index af3da470..00000000
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ /dev/null
@@ -1,17 +0,0 @@
-
diff --git a/README.md b/README.md
index 5ea4cd27..9ebdfbf1 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
# debug
-[![Build Status](https://travis-ci.org/debug-js/debug.svg?branch=master)](https://travis-ci.org/debug-js/debug) [![Coverage Status](https://coveralls.io/repos/github/debug-js/debug/badge.svg?branch=master)](https://coveralls.io/github/debug-js/debug?branch=master) [![Slack](https://visionmedia-community-slackin.now.sh/badge.svg)](https://visionmedia-community-slackin.now.sh/) [![OpenCollective](https://opencollective.com/debug/backers/badge.svg)](#backers)
+[![OpenCollective](https://opencollective.com/debug/backers/badge.svg)](#backers)
[![OpenCollective](https://opencollective.com/debug/sponsors/badge.svg)](#sponsors)
@@ -241,6 +241,9 @@ setInterval(function(){
}, 1200);
```
+In Chromium-based web browsers (e.g. Brave, Chrome, and Electron), the JavaScript console will—by default—only show messages logged by `debug` if the "Verbose" log level is _enabled_.
+
+
## Output streams
diff --git a/package.json b/package.json
index cb7efa8e..60dfcf57 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "debug",
- "version": "4.3.3",
+ "version": "4.4.0",
"repository": {
"type": "git",
"url": "git://github.com/debug-js/debug.git"
@@ -16,7 +16,7 @@
"LICENSE",
"README.md"
],
- "author": "Josh Junon ",
+ "author": "Josh Junon (https://github.com/qix-)",
"contributors": [
"TJ Holowaychuk ",
"Nathan Rajlich (http://n8.io)",
@@ -26,12 +26,12 @@
"scripts": {
"lint": "xo",
"test": "npm run test:node && npm run test:browser && npm run lint",
- "test:node": "istanbul cover _mocha -- test.js",
+ "test:node": "istanbul cover _mocha -- test.js test.node.js",
"test:browser": "karma start --single-run",
"test:coverage": "cat ./coverage/lcov.info | coveralls"
},
"dependencies": {
- "ms": "2.1.2"
+ "ms": "^2.1.3"
},
"devDependencies": {
"brfs": "^2.0.1",
@@ -44,6 +44,7 @@
"karma-mocha": "^1.3.0",
"mocha": "^5.2.0",
"mocha-lcov-reporter": "^1.2.0",
+ "sinon": "^14.0.0",
"xo": "^0.23.0"
},
"peerDependenciesMeta": {
@@ -55,5 +56,10 @@
"browser": "./src/browser.js",
"engines": {
"node": ">=6.0"
+ },
+ "xo": {
+ "rules": {
+ "import/extensions": "off"
+ }
}
}
diff --git a/src/browser.js b/src/browser.js
index cd0fc35d..df8e179e 100644
--- a/src/browser.js
+++ b/src/browser.js
@@ -125,14 +125,17 @@ function useColors() {
return false;
}
+ let m;
+
// Is webkit? http://stackoverflow.com/a/16459606/376773
// document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
+ // eslint-disable-next-line no-return-assign
return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
// Is firebug? http://stackoverflow.com/a/398120/376773
(typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
// Is firefox >= v31?
// https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
- (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) ||
+ (typeof navigator !== 'undefined' && navigator.userAgent && (m = navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)) && parseInt(m[1], 10) >= 31) ||
// Double check webkit in userAgent just in case we are in a worker
(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/));
}
diff --git a/src/common.js b/src/common.js
index 6d571d28..528c7ecf 100644
--- a/src/common.js
+++ b/src/common.js
@@ -166,24 +166,62 @@ function setup(env) {
createDebug.names = [];
createDebug.skips = [];
- let i;
- const split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/);
- const len = split.length;
-
- for (i = 0; i < len; i++) {
- if (!split[i]) {
- // ignore empty strings
- continue;
+ const split = (typeof namespaces === 'string' ? namespaces : '')
+ .trim()
+ .replace(' ', ',')
+ .split(',')
+ .filter(Boolean);
+
+ for (const ns of split) {
+ if (ns[0] === '-') {
+ createDebug.skips.push(ns.slice(1));
+ } else {
+ createDebug.names.push(ns);
}
+ }
+ }
- namespaces = split[i].replace(/\*/g, '.*?');
-
- if (namespaces[0] === '-') {
- createDebug.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));
+ /**
+ * Checks if the given string matches a namespace template, honoring
+ * asterisks as wildcards.
+ *
+ * @param {String} search
+ * @param {String} template
+ * @return {Boolean}
+ */
+ function matchesTemplate(search, template) {
+ let searchIndex = 0;
+ let templateIndex = 0;
+ let starIndex = -1;
+ let matchIndex = 0;
+
+ while (searchIndex < search.length) {
+ if (templateIndex < template.length && (template[templateIndex] === search[searchIndex] || template[templateIndex] === '*')) {
+ // Match character or proceed with wildcard
+ if (template[templateIndex] === '*') {
+ starIndex = templateIndex;
+ matchIndex = searchIndex;
+ templateIndex++; // Skip the '*'
+ } else {
+ searchIndex++;
+ templateIndex++;
+ }
+ } else if (starIndex !== -1) { // eslint-disable-line no-negated-condition
+ // Backtrack to the last '*' and try to match more characters
+ templateIndex = starIndex + 1;
+ matchIndex++;
+ searchIndex = matchIndex;
} else {
- createDebug.names.push(new RegExp('^' + namespaces + '$'));
+ return false; // No match
}
}
+
+ // Handle trailing '*' in template
+ while (templateIndex < template.length && template[templateIndex] === '*') {
+ templateIndex++;
+ }
+
+ return templateIndex === template.length;
}
/**
@@ -194,8 +232,8 @@ function setup(env) {
*/
function disable() {
const namespaces = [
- ...createDebug.names.map(toNamespace),
- ...createDebug.skips.map(toNamespace).map(namespace => '-' + namespace)
+ ...createDebug.names,
+ ...createDebug.skips.map(namespace => '-' + namespace)
].join(',');
createDebug.enable('');
return namespaces;
@@ -209,21 +247,14 @@ function setup(env) {
* @api public
*/
function enabled(name) {
- if (name[name.length - 1] === '*') {
- return true;
- }
-
- let i;
- let len;
-
- for (i = 0, len = createDebug.skips.length; i < len; i++) {
- if (createDebug.skips[i].test(name)) {
+ for (const skip of createDebug.skips) {
+ if (matchesTemplate(name, skip)) {
return false;
}
}
- for (i = 0, len = createDebug.names.length; i < len; i++) {
- if (createDebug.names[i].test(name)) {
+ for (const ns of createDebug.names) {
+ if (matchesTemplate(name, ns)) {
return true;
}
}
@@ -231,19 +262,6 @@ function setup(env) {
return false;
}
- /**
- * Convert regexp to namespace
- *
- * @param {RegExp} regxep
- * @return {String} namespace
- * @api private
- */
- function toNamespace(regexp) {
- return regexp.toString()
- .substring(2, regexp.toString().length - 2)
- .replace(/\.\*\?$/, '*');
- }
-
/**
* Coerce `val`.
*
diff --git a/src/node.js b/src/node.js
index 79bc085c..715560a4 100644
--- a/src/node.js
+++ b/src/node.js
@@ -187,11 +187,11 @@ function getDate() {
}
/**
- * Invokes `util.format()` with the specified arguments and writes to stderr.
+ * Invokes `util.formatWithOptions()` with the specified arguments and writes to stderr.
*/
function log(...args) {
- return process.stderr.write(util.format(...args) + '\n');
+ return process.stderr.write(util.formatWithOptions(exports.inspectOpts, ...args) + '\n');
}
/**
diff --git a/test.node.js b/test.node.js
new file mode 100644
index 00000000..4cc3c051
--- /dev/null
+++ b/test.node.js
@@ -0,0 +1,40 @@
+/* eslint-env mocha */
+
+const assert = require('assert');
+const util = require('util');
+const sinon = require('sinon');
+const debug = require('./src/node');
+
+const formatWithOptionsSpy = sinon.spy(util, 'formatWithOptions');
+beforeEach(() => {
+ formatWithOptionsSpy.resetHistory();
+});
+
+describe('debug node', () => {
+ describe('formatting options', () => {
+ it('calls util.formatWithOptions', () => {
+ debug.enable('*');
+ const stdErrWriteStub = sinon.stub(process.stderr, 'write');
+ const log = debug('formatting options');
+ log('hello world');
+ assert(util.formatWithOptions.callCount === 1);
+ stdErrWriteStub.restore();
+ });
+
+ it('calls util.formatWithOptions with inspectOpts', () => {
+ debug.enable('*');
+ const options = {
+ hideDate: true,
+ colors: true,
+ depth: 10,
+ showHidden: true
+ };
+ Object.assign(debug.inspectOpts, options);
+ const stdErrWriteStub = sinon.stub(process.stderr, 'write');
+ const log = debug('format with inspectOpts');
+ log('hello world2');
+ assert.deepStrictEqual(util.formatWithOptions.getCall(0).args[0], options);
+ stdErrWriteStub.restore();
+ });
+ });
+});