Simon Priet e69a613a37 feat: Created a mini nodeJS server with NewMan for testing without PostMan GUI.
This will mimic a run in a CD/CI environment or docker container.
2021-09-08 14:01:19 +02:00

308 lines
7.4 KiB
JavaScript

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
const path = require('path');
const util = require('util');
const chalk = require('chalk');
const dbug = require('dbug');
const stack = require('stack-trace');
const utc = require('utcstring');
const intel = require('./');
const ALIASES = [
'trace',
'debug',
'info',
'warn',
'error'
];
function copyProperties(source, target, props) {
props.forEach(function(prop) {
target[prop] = source[prop];
});
}
var ORIGINAL_METHODS = {};
const METHOD_NAMES = [
'trace',
'debug',
'dir',
'error',
'info',
'log',
'warn'
];
var ORIGINAL_STDERR;
function endsWith(str, suffix) {
return str.indexOf(suffix, str.length - suffix.length) !== -1;
}
var root;
var ignore;
var parentLogger;
var basename;
function getLoggerName(debugName) {
var trace = stack.get();
// walk up the stack until we find a function that isn't from this
// module. that's the calling module.
// ALSO: 'console.js' could be on the stack if console.trace() or
// something similar was called, cause we don't modify those, since
// they internally call console.log(), which is us!
var filename;
var debug = [];
if (debugName) {
debug = [
// debug@0.x
path.join('node_modules', 'debug', 'lib', 'debug.js'),
// debug@1.x
path.join('node_modules', 'debug', 'node.js'),
path.join('node_modules', 'debug', 'debug.js'),
// dbug@0.x
path.join('node_modules', 'dbug', 'lib', 'dbug.js'),
path.join('node_modules', 'dbug', 'index.js')
];
}
function skip(name) {
if (name === __filename || name === 'console.js') {
return true;
}
return debug.some(function(d) {
return endsWith(name, d);
});
}
for (var i = 0, len = trace.length; i < len; i++) {
filename = path.normalize(trace[i].getFileName());
if (!skip(filename)) {
break;
}
}
var topName = basename || path.basename(root);
topName = topName.replace(path.extname(topName), '');
var moduleName = path.join(topName, path.relative(root, filename));
moduleName = moduleName.replace(path.extname(moduleName), '');
moduleName = moduleName.replace(/[\\\/]/g, '.');
// lib is the defacto place to store js files, but removing lib looks
// better: connect.lib.session -> connect.session
moduleName = moduleName.replace(/\.lib\./g, '.');
// index.js filename shouldn't be used, since it's really the folder
// up. better: gryphon.index -> gryphon
moduleName = moduleName.replace(/\.index/g, '');
if (debugName) {
// clean up duplicated parts of the name
// ex: node_modules.intel.logger.intel.logger =>
// node_modules.intel.logger
if (!endsWith(moduleName, debugName)) {
moduleName += '.' + debugName;
}
}
if (parentLogger) {
moduleName = parentLogger + '.' + moduleName;
}
return moduleName;
}
function setRoot(r) {
root = r;
}
function setIgnore(i) {
if (typeof i === 'string') {
i = [i];
}
ignore = i;
}
const DEBUG_COLORED_RE = new RegExp([
'^',
' ', // starts with 2 spaces. yea really
'\\u001b\\[\\d{1,2};1m', // colored debug has colors
'(.+)', // logger name
'\\u001b\\[\\d?0m', // color end
'(.+)', // message
'\n?', // debug 2.0 addes a newline
'$'
].join(''));
const DBUG_LEVELS = ['debug', 'info', 'warn', 'error'];
function getLoggerLevel(name) {
var i = DBUG_LEVELS.length;
while (i--) {
var level = DBUG_LEVELS[i];
if (endsWith(name, '.' + level)) {
return level;
}
}
return 'debug';
}
function dbugName(name) {
if (!name) {
return;
}
if (name.indexOf('.') === -1) {
return name;
}
var level = getLoggerLevel(name.toLowerCase());
level = new RegExp('\\.' + level + '$', 'i');
return name.replace(level, '');
}
function parseDebug(args) {
// O_O
// Dear reader: I'm so sorry.
var str = String(args[0]);
// is it colored debug() ?
var match = str.match(DEBUG_COLORED_RE);
if (match) {
var logger = chalk.stripColor(match[1]).trim();
var msg = chalk.stripColor(match[2]).trim();
args[0] = msg; // overwrite the message portion
return logger.replace(/:/g, '.');
} else if (utc.has(str)) {
str = str.replace(utc.get(str), '').trim();
var logger = str.split(' ').shift();
var msg = str.replace(logger, '').trim();
args[0] = msg;
return logger.replace(/:/g, '.');
}
}
// cached loggers that hook into dbug.__log
// this way, we don't format a level message, and then parse it with
// regex, just to format a new message in intel
// ALSO: we only get a stacktrace once, and then save the name, so
// PERFORMANCE WIN!
var dbugLoggers = {};
function dbugHook(name, level, args) {
var logger = dbugLoggers[name];
if (!logger) {
logger = dbugLoggers[name] =
intel.getLogger(getLoggerName(name.replace(/:/g, '.')));
}
logger[level].apply(logger, args);
}
var isDebugging = false;
var __log = dbug.__log;
function setDebug(debug) {
if (debug === true) {
process.env.DEBUG = dbug.env = '*';
} else if (debug === false) {
process.env.DEBUG = dbug.env = '';
} else if (debug) {
if (process.env.DEBUG) {
process.env.DEBUG += ',' + debug;
dbug.env = process.env.DEBUG;
} else {
process.env.DEBUG = dbug.env = '' + debug;
}
}
isDebugging = !!debug;
dbug.__log = dbugHook;
}
function setLoggerBaseName(bn){
basename = bn;
}
function deliver(method, args) {
var debugged = isDebugging && parseDebug(args);
var name = getLoggerName(dbugName(debugged));
var i = ignore.length;
var logger = intel.getLogger(name);
name = logger._name;
while (i--) {
if (name.indexOf(ignore[i]) === 0) {
if (method === 'stderr') {
ORIGINAL_STDERR.call(process.stderr, args[0]);
} else {
ORIGINAL_METHODS[method].apply(console, args);
}
return;
}
}
if (debugged) {
method = getLoggerLevel(debugged);
}
var level = ALIASES.indexOf(method) !== -1 ? method : 'debug';
logger[level].apply(logger, args);
}
function overrideConsole(options) {
options = options || {};
setRoot(options.root || path.join(
stack.get(options.__trace || overrideConsole)[0].getFileName(),
'..'
));
setIgnore(options.ignore || []);
parentLogger = options.logger;
setDebug(options.debug);
setLoggerBaseName(options.basename);
if (!ORIGINAL_METHODS.log) {
copyProperties(console, ORIGINAL_METHODS, METHOD_NAMES);
}
if (!ORIGINAL_STDERR) {
ORIGINAL_STDERR = process.stderr.write;
}
ALIASES.forEach(function(method) {
console[method] = function alias(){
deliver(method, arguments);
};
});
console.log = function log() {
deliver('log', arguments);
};
console.dir = function dir(obj) {
deliver('dir', [util.inspect(obj)]);
};
process.stderr.write = function write(str) {
deliver('stderr', [str]);
return true;
};
}
function restoreConsole() {
for (var name in ORIGINAL_METHODS) {
if (ORIGINAL_METHODS.hasOwnProperty(name) && ORIGINAL_METHODS[name]) {
console[name] = ORIGINAL_METHODS[name];
}
}
copyProperties({}, ORIGINAL_METHODS, METHOD_NAMES);
dbug.__log = __log;
if (ORIGINAL_STDERR) {
process.stderr.write = ORIGINAL_STDERR;
ORIGINAL_STDERR = undefined;
}
}
module.exports = exports = overrideConsole;
exports.restore = restoreConsole;