Comparing version 0.2.0 to 0.3.0
24
cedar.js
// Wrap JSON.stringify with a circular-safe function. | ||
require('./common/json/stringify'); | ||
require('./common/json/stringify') | ||
/** | ||
* Create and return a logger with one or more transports. | ||
* Create and return a log with one or more transports. | ||
*/ | ||
var cedar = module.exports = function (arg, config) { | ||
var cedar = module.exports = process.cedar || function (arg, config) { | ||
// The default transport is `console`. | ||
var transport = arg || 'console'; | ||
var transport = arg || 'console' | ||
// If Cedar is called with an Array, it's a multi-transport config list. | ||
if (arg instanceof Array) { | ||
config = arg; | ||
transport = 'multi'; | ||
config = arg | ||
transport = 'multi' | ||
} | ||
// Make sure a config exists and a transport is specified. | ||
config = config || {}; | ||
config.transport = transport; | ||
config = config || {} | ||
config.transport = transport | ||
return require(__dirname + '/lib/transports/' + transport)(config); | ||
}; | ||
return require(__dirname + '/lib/transports/' + transport)(config) | ||
} | ||
@@ -30,4 +30,4 @@ /** | ||
get: function () { | ||
return require(__dirname + '/package.json').version; | ||
return require(__dirname + '/package.json').version | ||
} | ||
}); | ||
}) |
/** | ||
* Return a colorized stack trace with code snippets. | ||
* | ||
* @origin lighter-common/common/error/snippet-stack.js | ||
* @origin https://github.com/lighterio/lighter-common/common/error/snippet-stack.js | ||
* @version 0.0.1 | ||
* @import string/colors | ||
* @import fs/shorten-path | ||
* @import process/cache | ||
*/ | ||
var fs = require('fs'); | ||
var colors = require('../string/colors'); | ||
var shortenPath = require('../fs/shorten-path'); | ||
var fs = require('fs') | ||
var colors = require('../../common/string/colors') | ||
var shortenPath = require('../../common/fs/shorten-path') | ||
var processCache = require('../../common/process/cache') | ||
var snippetStack = module.exports = function (stack, options) { | ||
var arrow = (process.platform == 'win32' ? '\u2192' : '\u279C') + ' '; | ||
options = options || 0; | ||
var lead = options.lead || 5; | ||
var trail = options.trail || lead / 2; | ||
var decay = options.decay || 0.5; | ||
var indent = options.indent || ' '; | ||
var color = options.color || 'red'; | ||
var ignore = options.ignore || 0; | ||
var arrow = (process.platform === 'win32' ? '\u2192' : '\u279C') + ' ' | ||
options = options || 0 | ||
var lead = options.lead || 5 | ||
var trail = options.trail || lead / 2 | ||
var decay = options.decay || 0.5 | ||
var indent = options.indent || ' ' | ||
var color = options.color || 'red' | ||
var ignore = options.ignore || 0 | ||
stack = stack.replace( | ||
/\n +at ([^:\n]+ )?(\(|)(\/[^:]+\/)([^\/:]+):(\d+):(\d+)(\)?)/g, | ||
function (match, name, start, path, file, line, column, end) { | ||
if (ignore && ignore.test(path)) { | ||
return match; | ||
/\n +at ([^:\n]+ )?(\(|)(\/[^:]+\/|vm-run:)([^\/:]+):(\d+):(\d+)(\)?)/g, | ||
function (match, name, start, dir, file, line, column, end) { | ||
if (ignore && ignore.test(dir)) { | ||
return match | ||
} | ||
var shortPath = shortenPath(path); | ||
name = name ? colors.base + name + colors.gray : '' | ||
var shortPath = shortenPath(dir) | ||
var message = '\n' + indent + | ||
colors.gray + 'at ' + | ||
(name ? colors.base + name + colors.gray : '') + '(' + | ||
colors.gray + 'at ' + name + '(' + | ||
colors.cyan + shortPath + | ||
colors.yellow + file + colors.gray + ':' + | ||
colors.base + line + colors.gray + ':' + | ||
colors.green + column + colors.gray + ')'; | ||
colors.green + column + colors.gray + ')' | ||
if (lead >= 1) { | ||
var lineNumber = line * 1; // 1-indexed. | ||
var lines = ''; | ||
var lines = '' | ||
try { | ||
lines += fs.readFileSync(path + file); | ||
} | ||
catch (e) { | ||
var path = dir + file | ||
lines += processCache.get(path) || fs.readFileSync(path) | ||
} catch (e) { | ||
// If we can't find a file, we show a line without a snippet. | ||
} | ||
lines = lines.split('\n'); | ||
start = Math.max(1, Math.round(lineNumber - lead)); | ||
end = Math.min(lines.length, lineNumber + Math.round(trail)); | ||
var numberLength = ('' + end).length; | ||
lines = lines.split('\n') | ||
start = Math.max(1, Math.round(lineNumber - lead)) | ||
end = Math.min(lines.length, lineNumber + Math.round(trail)) | ||
var numberLength = ('' + end).length | ||
for (i = start; i <= end; i++) { | ||
line = lines[i - 1]; | ||
var blockIndent = indent + ' '; | ||
var pipe = '| '; | ||
if (i == lineNumber) { | ||
column--; | ||
line = line.substr(0, column) + line.substr(column).replace(/(;?$)/, '$1'.gray).green; | ||
blockIndent = indent + ' ' + arrow[color]; | ||
pipe = pipe.gray; | ||
line = lines[i - 1] | ||
var blockIndent = indent + ' ' | ||
var pipe = '| ' | ||
if (i === lineNumber) { | ||
column-- | ||
line = line.substr(0, column) + line.substr(column).replace(/(;?$)/, '$1'.gray).green | ||
blockIndent = indent + ' ' + arrow[color] | ||
pipe = pipe.gray | ||
} | ||
var n = '' + i; | ||
n = Array(numberLength - n.length + 1).join(' ') + n; | ||
message += '\n' + blockIndent + n + pipe + line.replace('\t', ' ') + colors.gray; | ||
var n = '' + i | ||
n = Array(numberLength - n.length + 1).join(' ') + n | ||
message += '\n' + blockIndent + n + pipe + line.replace('\t', ' ') + colors.gray | ||
} | ||
lead *= decay; | ||
trail *= decay; | ||
lead *= decay | ||
trail *= decay | ||
} | ||
return message; | ||
return message | ||
} | ||
); | ||
stack = stack.replace(/(\n +at )(\S+ )?/g, '\n' + indent + 'at '.gray + '$2' + colors.gray); | ||
return colors[color] + stack; | ||
}; | ||
) | ||
stack = stack.replace(/(\n +at )(\S+ )?/g, '\n' + indent + 'at '.gray + '$2' + colors.gray) | ||
return colors[color] + stack | ||
} |
@@ -14,3 +14,3 @@ /** | ||
* | ||
* @origin lighter-common/common/events/emitter.js | ||
* @origin https://github.com/lighterio/lighter-common/common/events/emitter.js | ||
* @version 0.0.5 | ||
@@ -20,5 +20,4 @@ * @import object/type | ||
var Type = require('../object/type'); | ||
var Type = require('../object/type') | ||
var Emitter = module.exports = Type.extend({ | ||
/** | ||
@@ -28,5 +27,5 @@ * Set the maximum number of listeners that can listen to any type of event. | ||
setMaxListeners: function (max) { | ||
var self = this; | ||
self._maxListeners = max ? max : Infinity; | ||
return self; | ||
var self = this | ||
self._maxListeners = max ? max : Infinity | ||
return self | ||
}, | ||
@@ -38,5 +37,5 @@ | ||
maxListenersExceeded: function (type) { | ||
var self = this; | ||
var max = self._maxListeners || Emitter.defaultMaxListeners; | ||
throw new Error('Max ' + max + ' listeners exceeded for "' + type + '".'); | ||
var self = this | ||
var max = self._maxListeners || Emitter.defaultMaxListeners | ||
throw new Error('Max ' + max + ' listeners exceeded for "' + type + '".') | ||
}, | ||
@@ -48,29 +47,27 @@ | ||
on: function (type, fn) { | ||
var self = this; | ||
var events = self._events = self._events || {}; | ||
var listeners = events[type]; | ||
var max = self._maxListeners || Emitter.defaultMaxListeners; | ||
var self = this | ||
var events = self._events = self._events || {} | ||
var listeners = events[type] | ||
var max = self._maxListeners || Emitter.defaultMaxListeners | ||
// If there's only one, don't waste an Array. | ||
if (!listeners) { | ||
events[type] = fn; | ||
} | ||
events[type] = fn | ||
// When there's more than one, start an Array unless the max is 1. | ||
else if (typeof listeners == 'function') { | ||
} else if (typeof listeners === 'function') { | ||
if (max > 1) { | ||
events[type] = [listeners, fn]; | ||
events[type] = [listeners, fn] | ||
} else { | ||
self.maxListenersExceeded(type) | ||
} | ||
else { | ||
self.maxListenersExceeded(type); | ||
} | ||
} | ||
// When it's already an Array, push unless we've exceeded the max. | ||
else { | ||
} else { | ||
if (listeners.length < max) { | ||
listeners.push(fn); | ||
listeners.push(fn) | ||
} else { | ||
self.maxListenersExceeded(type) | ||
} | ||
else { | ||
self.maxListenersExceeded(type); | ||
} | ||
} | ||
return self; | ||
return self | ||
}, | ||
@@ -82,9 +79,9 @@ | ||
once: function (type, fn) { | ||
var self = this; | ||
function one() { | ||
self.removeListener(type, one); | ||
fn.apply(self, arguments); | ||
var self = this | ||
function one () { | ||
self.removeListener(type, one) | ||
fn.apply(self, arguments) | ||
} | ||
self.on(type, one); | ||
return self; | ||
self.on(type, one) | ||
return self | ||
}, | ||
@@ -96,30 +93,28 @@ | ||
emit: function (type, data) { | ||
var self = this; | ||
var events = self._events; | ||
var self = this | ||
var events = self._events | ||
if (events) { | ||
var listeners = events[type]; | ||
var listeners = events[type] | ||
if (listeners) { | ||
// If there's more than one data argument, build an array. | ||
var args; | ||
var args | ||
if (arguments.length > 2) { | ||
args = Array.prototype.slice.call(arguments, 1); | ||
args = Array.prototype.slice.call(arguments, 1) | ||
} | ||
// If there's only one listener, run it. | ||
if (typeof listeners == 'function') { | ||
if (typeof listeners === 'function') { | ||
if (args) { | ||
listeners.apply(self, args); | ||
listeners.apply(self, args) | ||
} else { | ||
listeners.call(self, data) | ||
} | ||
else { | ||
listeners.call(self, data); | ||
} | ||
} | ||
// If there's more than one listener, run them all. | ||
else { | ||
} else { | ||
for (var i = 0, l = listeners.length; i < l; i++) { | ||
if (args) { | ||
listeners[i].apply(self, args); | ||
listeners[i].apply(self, args) | ||
} else { | ||
listeners[i].call(self, data) | ||
} | ||
else { | ||
listeners[i].call(self, data); | ||
} | ||
} | ||
@@ -129,3 +124,3 @@ } | ||
} | ||
return self; | ||
return self | ||
}, | ||
@@ -137,6 +132,6 @@ | ||
listeners: function (type) { | ||
var self = this; | ||
var events = self._events; | ||
var list = events ? events[type] : undefined; | ||
return !list ? [] : list instanceof Array ? list : [list]; | ||
var self = this | ||
var events = self._events | ||
var list = events ? events[type] : undefined | ||
return !list ? [] : list instanceof Array ? list : [list] | ||
}, | ||
@@ -148,15 +143,14 @@ | ||
removeListener: function (type, fn) { | ||
var self = this; | ||
var events = self._events; | ||
var self = this | ||
var events = self._events | ||
if (events) { | ||
var listeners = events[type]; | ||
if (listeners == fn) { | ||
delete events[type]; | ||
self.emit('removeListener', type, fn); | ||
} | ||
else if (typeof listeners == Array) { | ||
var listeners = events[type] | ||
if (listeners === fn) { | ||
delete events[type] | ||
self.emit('removeListener', type, fn) | ||
} else if (typeof listeners === Array) { | ||
for (var i = 0, l = listeners.length; i < l; i++) { | ||
if (listeners[i] == fn) { | ||
listeners.splice(i, 1); | ||
return self.emit('removeListener', type, fn); | ||
if (listeners[i] === fn) { | ||
listeners.splice(i, 1) | ||
return self.emit('removeListener', type, fn) | ||
} | ||
@@ -166,3 +160,3 @@ } | ||
} | ||
return self; | ||
return self | ||
}, | ||
@@ -174,14 +168,13 @@ | ||
removeAllListeners: function (type) { | ||
var self = this; | ||
var events = self._events; | ||
var self = this | ||
var events = self._events | ||
// We only need to do something if there are events. | ||
if (events) { | ||
if (type) { | ||
delete events[type]; | ||
delete events[type] | ||
} else { | ||
delete self._events | ||
} | ||
else { | ||
delete self._events; | ||
} | ||
} | ||
return self; | ||
return self | ||
}, | ||
@@ -193,11 +186,11 @@ | ||
one: function (type, fn) { | ||
var self = this; | ||
var events = self._events = self._events || {}; | ||
events[type] = fn; | ||
return self; | ||
var self = this | ||
var events = self._events = self._events || {} | ||
events[type] = fn | ||
return self | ||
} | ||
}); | ||
}) | ||
// Same default as native EventEmitter. | ||
Emitter.defaultMaxListeners = 10; | ||
Emitter.defaultMaxListeners = 10 |
/** | ||
* Asynchronous recursive mkdir, like `mkdir -p`. | ||
* | ||
* @origin lighter-common/common/fs/mkdirp.js | ||
* @origin https://github.com/lighterio/lighter-common/common/fs/mkdirp.js | ||
* @version 0.0.2 | ||
*/ | ||
var path = require('path'); | ||
var resolve = path.resolve; | ||
var dirname = path.dirname; | ||
var path = require('path') | ||
var resolve = path.resolve | ||
var dirname = path.dirname | ||
var mkdirp = module.exports = function (path, mode, fn) { | ||
path = resolve(path); | ||
if (typeof mode == 'function') { | ||
fn = mode; | ||
mode = 0777 & (~mkdirp.umask); | ||
path = resolve(path) | ||
if (typeof mode === 'function') { | ||
fn = mode | ||
mode = 0777 & (~mkdirp.umask) | ||
} | ||
mk(path, mode, fn || function () {}); | ||
}; | ||
mk(path, mode, fn || function () {}) | ||
} | ||
function mk(path, mode, fn, dir) { | ||
function mk (path, mode, fn, dir) { | ||
mkdirp.fs.mkdir(path, mode, function (error) { | ||
if (!error) { | ||
dir = dir || path; | ||
fn(null, dir); | ||
} | ||
else if (error.code == 'ENOENT') { | ||
dir = dir || path | ||
fn(null, dir) | ||
} else if (error.code === 'ENOENT') { | ||
mk(dirname(path), mode, function (error, dir) { | ||
if (error) { | ||
fn(error, dir); | ||
fn(error, dir) | ||
} else { | ||
mk(path, mode, fn, dir) | ||
} | ||
else { | ||
mk(path, mode, fn, dir); | ||
} | ||
}); | ||
} | ||
else { | ||
}) | ||
} else { | ||
mkdirp.fs.stat(path, function (statError, stat) { | ||
fn((statError || !stat.isDirectory()) ? error : null, dir); | ||
}); | ||
fn((statError || !stat.isDirectory()) ? error : null, dir) | ||
}) | ||
} | ||
}); | ||
}) | ||
} | ||
// Allow a user to specify a custom file system. | ||
mkdirp.fs = require('fs'); | ||
mkdirp.fs = require('fs') | ||
// Allow the umask to be changed externally. | ||
mkdirp.umask = process.umask(); | ||
mkdirp.umask = process.umask() |
@@ -5,3 +5,3 @@ /** | ||
* | ||
* @origin lighter-common/common/fs/shorten-path.js | ||
* @origin https://github.com/lighterio/lighter-common/common/fs/shorten-path.js | ||
* @version 0.0.1 | ||
@@ -11,11 +11,11 @@ */ | ||
var shortenPath = module.exports = function (path) { | ||
var dirs = shortenPath.dirs; | ||
var dirs = shortenPath.dirs | ||
for (var i = 0; i < 2; i++) { | ||
var dir = dirs[i]; | ||
var dir = dirs[i] | ||
if (dir[0] && (path.indexOf(dir[0]) === 0)) { | ||
return dir[1] + path.substr(dir[0].length); | ||
return dir[1] + path.substr(dir[0].length) | ||
} | ||
} | ||
return path; | ||
}; | ||
return path | ||
} | ||
@@ -25,5 +25,5 @@ /** | ||
*/ | ||
shortenPath.dirs = [ | ||
[process.cwd() + '/', './'], | ||
[process.env.HOME + '/', '~/'] | ||
]; | ||
var cwd = [process.cwd() + '/', './'] | ||
var home = [process.env.HOME + '/', '~/'] | ||
shortenPath.dirs = [cwd, home] | ||
/** | ||
* Stringify JSON with colors for console logging. | ||
* | ||
* @origin lighter-common/common/json/colorize.js | ||
* @origin https://github.com/lighterio/lighter-common/common/json/colorize.js | ||
* @version 0.0.1 | ||
@@ -9,127 +9,113 @@ * @import string/colors | ||
var colors = require('../string/colors'); | ||
var colors = require('../string/colors') | ||
JSON.colorize = module.exports = function (data, stack, space, indent, maxWidth, maxDepth) { | ||
maxWidth = maxWidth || 80; | ||
maxDepth = maxDepth || 5; | ||
var type = typeof data; | ||
var color; | ||
if (type == 'function') { | ||
data = data.toString(); | ||
maxWidth = maxWidth || 80 | ||
maxDepth = maxDepth || 5 | ||
var type = typeof data | ||
var color | ||
if (type === 'function') { | ||
data = data.toString() | ||
if (stack) { | ||
data = data.replace(/\s+/g, ' '); | ||
data = data.replace(/\s+/g, ' ') | ||
if (data.length > maxWidth) { | ||
data = data.replace(/^([^\{]+?)\{.*\}$/, '$1{...}'); | ||
data = data.replace(/^([^\{]+?)\{.*\}$/, '$1{...}') | ||
} | ||
color = 'cyan'; | ||
color = 'cyan' | ||
} | ||
} | ||
else if ((type == 'object') && data) { | ||
} else if ((type === 'object') && data) { | ||
if (data instanceof Date) { | ||
data = data.toUTCString(); | ||
data = data.toUTCString() | ||
if (stack) { | ||
data = '[Date: ' + data + ']'; | ||
color = 'cyan'; | ||
data = '[Date: ' + data + ']' | ||
color = 'cyan' | ||
} | ||
} | ||
else if (data instanceof Error) { | ||
var e = data; | ||
var message = (e.stack || '' + e).replace(/^\w*Error:? ?/, ''); | ||
} else if (data instanceof Error) { | ||
var e = data | ||
var message = (e.stack || '' + e).replace(/^\w*Error:? ?/, '') | ||
if (stack) { | ||
data = '[' + (e.name || 'Error') + ': ' + message + ']'; | ||
data = '[' + (e.name || 'Error') + ': ' + message + ']' | ||
} else { | ||
data = e.stack || '' + e | ||
} | ||
else { | ||
data = e.stack || '' + e; | ||
} | ||
color = 'cyan'; | ||
} | ||
else if (data instanceof RegExp) { | ||
data = '/' + data.source + '/' + | ||
(data.global ? 'g' : '') + | ||
(data.ignoreCase ? 'i' : '') + | ||
(data.multiline ? 'm' : ''); | ||
color = 'green'; | ||
} | ||
else { | ||
stack = stack || []; | ||
indent = indent || space; | ||
var colon = (space ? ': ' : ':').gray; | ||
color = 'cyan' | ||
} else if (data instanceof RegExp) { | ||
data = '/' + data.source + '/' | ||
+ (data.global ? 'g' : '') | ||
+ (data.ignoreCase ? 'i' : '') | ||
+ (data.multiline ? 'm' : '') | ||
color = 'green' | ||
} else { | ||
stack = stack || [] | ||
indent = indent || space | ||
var colon = (space ? ': ' : ':').gray | ||
for (var i = 0, l = stack.length; i < l; i++) { | ||
if (stack[i] == data) { | ||
return ('[Circular ^' + (l - i) + ']').gray; | ||
if (stack[i] === data) { | ||
return ('[Circular ^' + (l - i) + ']').gray | ||
} | ||
} | ||
stack.push(data); | ||
var parts = []; | ||
var length = 0; | ||
var text; | ||
var isArray = (data instanceof Array); | ||
stack.push(data) | ||
var parts = [] | ||
var length = 0 | ||
var text | ||
var isArray = (data instanceof Array) | ||
if (stack.length > maxDepth) { | ||
data = (isArray ? '[Array]' : '[Object]').cyan; | ||
} | ||
else { | ||
data = (isArray ? '[Array]' : '[Object]').cyan | ||
} else { | ||
if (isArray) { | ||
data.forEach(function (value) { | ||
text = JSON.colorize(value, stack, space, indent + space, maxWidth - 2, maxDepth); | ||
length += text.replace().length; | ||
parts.push(text); | ||
}); | ||
} | ||
else { | ||
text = JSON.colorize(value, stack, space, indent + space, maxWidth - 2, maxDepth) | ||
length += text.replace().length | ||
parts.push(text) | ||
}) | ||
} else { | ||
for (var key in data) { | ||
if (data.hasOwnProperty(key)) { | ||
var value = data[key]; | ||
var value = data[key] | ||
if (/[^$\w\d]/.test(key)) { | ||
key = '"' + key + '"'; | ||
key = '"' + key + '"' | ||
} | ||
if (key[0] == '_') { | ||
key = key.gray; | ||
if (key[0] === '_') { | ||
key = key.gray | ||
} | ||
text = key + colon + JSON.colorize(value, stack, space, indent + space, maxWidth - 2); | ||
length += text.plain.length; | ||
parts.push(text); | ||
text = key + colon + JSON.colorize(value, stack, space, indent + space, maxWidth - 2) | ||
length += text.plain.length | ||
parts.push(text) | ||
} | ||
} | ||
} | ||
stack.pop(); | ||
if (space) { | ||
if (parts.length) { | ||
length += (parts.length - 1) * 2; | ||
length += (parts.length - 1) * 2 | ||
} | ||
if (length + indent.length > maxWidth) { | ||
data = '\n' + indent + parts.join(',\n'.gray + indent) + '\n' + indent.substr(2); | ||
data = '\n' + indent + parts.join(',\n'.gray + indent) + '\n' + indent.substr(2) | ||
} else { | ||
data = parts.join(', '.gray) | ||
} | ||
else { | ||
data = parts.join(', '.gray); | ||
} | ||
} else { | ||
data = parts.join(','.gray) | ||
} | ||
else { | ||
data = parts.join(','.gray); | ||
} | ||
if (isArray) { | ||
data = '['.gray + data + ']'.gray; | ||
data = '['.gray + data + ']'.gray | ||
} else { | ||
data = '{'.gray + data + '}'.gray | ||
} | ||
else { | ||
data = '{'.gray + data + '}'.gray; | ||
} | ||
} | ||
stack.pop() | ||
} | ||
} | ||
else if (stack && !color) { | ||
if (type == 'string') { | ||
data = JSON.stringify(data); | ||
color = 'green'; | ||
} else if (stack && !color) { | ||
if (type === 'string') { | ||
data = JSON.stringify(data) | ||
color = 'green' | ||
} else if (type === 'number') { | ||
color = 'magenta' | ||
} else if (type === 'boolean') { | ||
color = 'yellow' | ||
} else { | ||
color = 'red' | ||
} | ||
else if (type == 'number') { | ||
color = 'magenta'; | ||
} | ||
else if (type == 'boolean') { | ||
color = 'yellow'; | ||
} | ||
else { | ||
color = 'red'; | ||
} | ||
} | ||
data = '' + data; | ||
return color ? data[color] : data; | ||
}; | ||
data = '' + data | ||
return color ? data[color] : data | ||
} |
@@ -5,62 +5,68 @@ /** | ||
* | ||
* @origin lighter-common/common/json/scriptify.js | ||
* @version 0.0.1 | ||
* The JSON.scriptify method also has options, attached as properties: | ||
* - scriptify.ownPropertiesOnly: false | ||
* - scriptify.maxDepth: 5 | ||
* | ||
* @origin https://github.com/lighterio/lighter-common/common/json/scriptify.js | ||
* @version 0.0.3 | ||
*/ | ||
var scriptify = module.exports = JSON.scriptify = function (value, stack) { | ||
var type = typeof value; | ||
if (type == 'function') { | ||
return value.toString(); | ||
var type = typeof value | ||
if (type === 'function') { | ||
return value.toString() | ||
} | ||
if (type == 'string') { | ||
return JSON.stringify(value); | ||
if (type === 'string') { | ||
return JSON.stringify(value) | ||
} | ||
if (type == 'object' && value) { | ||
if (type === 'object' && value) { | ||
if (value instanceof Date) { | ||
return 'new Date(' + value.getTime() + ')'; | ||
return 'new Date(' + value.getTime() + ')' | ||
} | ||
if (value instanceof Error) { | ||
return '(function(){var e=new Error(' + scriptify(value.message) + ');' + | ||
'e.stack=' + scriptify(value.stack) + ';return e})()'; | ||
'e.stack=' + scriptify(value.stack) + ';return e})()' | ||
} | ||
if (value instanceof RegExp) { | ||
return '/' + value.source + '/' + | ||
(value.global ? 'g' : '') + | ||
(value.ignoreCase ? 'i' : '') + | ||
(value.multiline ? 'm' : ''); | ||
return '/' + value.source + '/' + (value.global ? 'g' : '') + (value.ignoreCase ? 'i' : '') + (value.multiline ? 'm' : '') | ||
} | ||
var i, length; | ||
var i, length | ||
if (stack) { | ||
length = stack.length; | ||
length = stack.length | ||
for (i = 0; i < length; i++) { | ||
if (stack[i] == value) { | ||
return '{"^":' + (length - i) + '}'; | ||
if (stack[i] === value) { | ||
return '{"^":' + (length - i) + '}' | ||
} | ||
} | ||
} | ||
(stack = stack || []).push(value); | ||
var string; | ||
if (value instanceof Array) { | ||
string = '['; | ||
length = value.length; | ||
stack = stack || [] | ||
stack.push(value) | ||
var string | ||
if (stack.length > scriptify.maxDepth) { | ||
value = (value instanceof Array) ? '"[Array]"' : '"[Object]"' | ||
} else if (value instanceof Array) { | ||
string = '[' | ||
length = value.length | ||
for (i = 0; i < length; i++) { | ||
string += (i ? ',' : '') + scriptify(value[i], stack); | ||
string += (i ? ',' : '') + scriptify(value[i], stack) | ||
} | ||
stack.pop(); | ||
return string + ']'; | ||
} | ||
else { | ||
var i = 0; | ||
string = '{'; | ||
stack.pop() | ||
return string + ']' | ||
} else { | ||
i = 0 | ||
string = '{' | ||
for (var key in value) { | ||
string += (i ? ',' : '') + | ||
(/^[$_a-z][\w$]*$/i.test(key) ? key : '"' + key + '"') + | ||
':' + scriptify(value[key], stack); | ||
i++; | ||
if (scriptify.ownPropertiesOnly || value.hasOwnProperty(key)) { | ||
string += (i ? ',' : '') + (/^[$_a-z][\w$]*$/i.test(key) ? key : '"' + key + '"') + ':' + scriptify(value[key], stack) | ||
i++ | ||
} | ||
} | ||
stack.pop(); | ||
return string + '}'; | ||
stack.pop() | ||
return string + '}' | ||
} | ||
} | ||
return '' + value; | ||
}; | ||
return '' + value | ||
} | ||
scriptify.maxDepth = 5 | ||
scriptify.ownPropertiesOnly = false |
/** | ||
* Wrap the native JSON.stringify with a circular-safe method. | ||
* | ||
* @origin lighter-common/common/json/stringify.js | ||
* @origin https://github.com/lighterio/lighter-common/common/json/stringify.js | ||
* @version 0.0.2 | ||
@@ -10,40 +10,37 @@ */ | ||
if (!JSON.nativeStringify) { | ||
// Reference the native stringify function. | ||
var nativeStringify = JSON.nativeStringify = JSON.stringify; | ||
var nativeStringify = JSON.nativeStringify = JSON.stringify | ||
// Stringify using a stack of parent values to detect circularity. | ||
var stringify = function (value, stack, space) { | ||
var string; | ||
if (value === null) { | ||
return 'null'; | ||
return 'null' | ||
} | ||
if (typeof value != 'object') { | ||
return nativeStringify(value); | ||
if (typeof value !== 'object') { | ||
return nativeStringify(value) | ||
} | ||
var length = stack.length; | ||
var length = stack.length | ||
for (var i = 0; i < length; i++) { | ||
if (stack[i] == value) { | ||
return '"[Circular ' + (length - i) + ']"'; | ||
if (stack[i] === value) { | ||
return '"[Circular ' + (length - i) + ']"' | ||
} | ||
} | ||
stack.push(value); | ||
var isArray = (value instanceof Array); | ||
var list = []; | ||
var json; | ||
stack.push(value) | ||
var isArray = (value instanceof Array) | ||
var list = [] | ||
var json | ||
if (isArray) { | ||
length = value.length; | ||
length = value.length | ||
for (i = 0; i < length; i++) { | ||
json = stringify(value[i], stack, space); | ||
if (json != undefined) { | ||
list.push(json); | ||
json = stringify(value[i], stack, space) | ||
if (json !== undefined) { | ||
list.push(json) | ||
} | ||
} | ||
} | ||
else { | ||
} else { | ||
for (var key in value) { | ||
json = stringify(value[key], stack, space); | ||
if (json != undefined) { | ||
key = nativeStringify(key) + ':' + (space ? ' ' : ''); | ||
list.push(key + json); | ||
json = stringify(value[key], stack, space) | ||
if (json !== undefined) { | ||
key = nativeStringify(key) + ':' + (space ? ' ' : '') | ||
list.push(key + json) | ||
} | ||
@@ -53,13 +50,12 @@ } | ||
if (space && list.length) { | ||
var indent = '\n' + (new Array(stack.length)).join(space); | ||
var indentSpace = indent + space; | ||
list = indentSpace + list.join(',' + indentSpace) + indent; | ||
var indent = '\n' + (new Array(stack.length)).join(space) | ||
var indentSpace = indent + space | ||
list = indentSpace + list.join(',' + indentSpace) + indent | ||
} else { | ||
list = list.join(',') | ||
} | ||
else { | ||
list = list.join(','); | ||
} | ||
value = isArray ? '[' + list + ']' : '{' + list + '}'; | ||
stack.pop(); | ||
return value; | ||
}; | ||
value = isArray ? '[' + list + ']' : '{' + list + '}' | ||
stack.pop() | ||
return value | ||
} | ||
@@ -70,4 +66,4 @@ // Stringify, optionally using an replacer function. | ||
nativeStringify(value, replacer, space) : | ||
stringify(value, [], space); | ||
}; | ||
stringify(value, [], space) | ||
} | ||
@@ -77,2 +73,2 @@ } | ||
// Export, in case someone is using the function directly. | ||
module.exports = JSON.stringify; | ||
module.exports = JSON.stringify |
@@ -5,3 +5,3 @@ /** | ||
* | ||
* @origin lighter-common/common/object/type.js | ||
* @origin https://github.com/lighterio/lighter-common/common/object/type.js | ||
* @version 0.0.1 | ||
@@ -11,3 +11,3 @@ */ | ||
// The default constructor does nothing. | ||
var Type = module.exports = function () {}; | ||
var Type = module.exports = function () {} | ||
@@ -18,20 +18,19 @@ /** | ||
Type.extend = function (properties) { | ||
// Create the constructor, using a new or inherited `init` method. | ||
var type = properties.init || function () { | ||
if (this.init) { | ||
this.init.apply(this, arguments); | ||
if (this.init) { | ||
this.init.apply(this, arguments) | ||
} | ||
} | ||
}; | ||
// Copy the parent and its prototype. | ||
var parent = type.parent = this; | ||
Type.decorate(type, parent); | ||
Type.decorate(type.prototype, parent.prototype); | ||
var parent = type.parent = this | ||
Type.decorate(type, parent) | ||
Type.decorate(type.prototype, parent.prototype) | ||
// Copy the properties that extend the parent. | ||
Type.decorate(type.prototype, properties); | ||
Type.decorate(type.prototype, properties) | ||
return type; | ||
}; | ||
return type | ||
} | ||
@@ -42,7 +41,7 @@ /** | ||
Type.decorate = function (object, properties) { | ||
properties = properties || this.prototype; | ||
properties = properties || this.prototype | ||
for (var key in properties) { | ||
object[key] = properties[key]; | ||
object[key] = properties[key] | ||
} | ||
return object; | ||
}; | ||
return object | ||
} |
/** | ||
* Extend the String prototype with terminal color methods. | ||
* | ||
* @origin lighter-common/common/string/colors.js | ||
* @origin https://github.com/lighterio/lighter-common/common/string/colors.js | ||
* @version 0.0.3 | ||
@@ -37,11 +37,11 @@ */ | ||
bgWhite: '\u001b[47m' | ||
}; | ||
} | ||
// When re-required, don't redefine. | ||
if (String.prototype.red) { | ||
return; | ||
return | ||
} | ||
// Enable colors by default. | ||
var enableColors = true; | ||
var enableColors = true | ||
@@ -52,53 +52,52 @@ // Allow colors to be disabled by setting `String.colors = false`. | ||
get: function () { | ||
return enableColors; | ||
return enableColors | ||
}, | ||
set: function (value) { | ||
enableColors = value; | ||
enableColors = value | ||
for (var key in colors) { | ||
if (value) { | ||
colors[key] = colors['_' + key] || colors[key]; | ||
colors[key] = colors['_' + key] || colors[key] | ||
} else { | ||
colors['_' + key] = colors[key] | ||
colors[key] = '' | ||
} | ||
else { | ||
colors['_' + key] = colors[key]; | ||
colors[key] = ''; | ||
} | ||
} | ||
return enableColors; | ||
return enableColors | ||
} | ||
}); | ||
}) | ||
// Define non-enumerable properties on the String prototype. | ||
function define(name, fn) { | ||
function define (name, fn) { | ||
Object.defineProperty(String.prototype, name, { | ||
enumerable: false, | ||
get: fn | ||
}); | ||
}; | ||
}) | ||
} | ||
define('plain', function () { return this.replace(/\u001b\[\d+m/g, ''); }); | ||
define('reset', function () { return enableColors ? '\u001b[0m' + this : this; }); | ||
define('base', function () { return enableColors ? '\u001b[39m' + this : this; }); | ||
define('bold', function () { return enableColors ? '\u001b[1m' + this + '\u001b[22m' : this; }); | ||
define('normal', function () { return enableColors ? '\u001b[2m' + this + '\u001b[22m' : this; }); | ||
define('italic', function () { return enableColors ? '\u001b[3m' + this + '\u001b[23m' : this; }); | ||
define('underline', function () { return enableColors ? '\u001b[4m' + this + '\u001b[24m' : this; }); | ||
define('inverse', function () { return enableColors ? '\u001b[7m' + this + '\u001b[27m' : this; }); | ||
define('hidden', function () { return enableColors ? '\u001b[8m' + this + '\u001b[28m' : this; }); | ||
define('strike', function () { return enableColors ? '\u001b[9m' + this + '\u001b[29m' : this; }); | ||
define('black', function () { return enableColors ? '\u001b[30m' + this + '\u001b[39m' : this; }); | ||
define('red', function () { return enableColors ? '\u001b[31m' + this + '\u001b[39m' : this; }); | ||
define('green', function () { return enableColors ? '\u001b[32m' + this + '\u001b[39m' : this; }); | ||
define('yellow', function () { return enableColors ? '\u001b[33m' + this + '\u001b[39m' : this; }); | ||
define('blue', function () { return enableColors ? '\u001b[34m' + this + '\u001b[39m' : this; }); | ||
define('magenta', function () { return enableColors ? '\u001b[35m' + this + '\u001b[39m' : this; }); | ||
define('cyan', function () { return enableColors ? '\u001b[36m' + this + '\u001b[39m' : this; }); | ||
define('white', function () { return enableColors ? '\u001b[37m' + this + '\u001b[39m' : this; }); | ||
define('gray', function () { return enableColors ? '\u001b[90m' + this + '\u001b[39m' : this; }); | ||
define('bgBlack', function () { return enableColors ? '\u001b[40m' + this + '\u001b[49m' : this; }); | ||
define('bgRed', function () { return enableColors ? '\u001b[41m' + this + '\u001b[49m' : this; }); | ||
define('bgGreen', function () { return enableColors ? '\u001b[42m' + this + '\u001b[49m' : this; }); | ||
define('bgYellow', function () { return enableColors ? '\u001b[43m' + this + '\u001b[49m' : this; }); | ||
define('bgBlue', function () { return enableColors ? '\u001b[44m' + this + '\u001b[49m' : this; }); | ||
define('bgMagenta', function () { return enableColors ? '\u001b[45m' + this + '\u001b[49m' : this; }); | ||
define('bgCyan', function () { return enableColors ? '\u001b[46m' + this + '\u001b[49m' : this; }); | ||
define('bgWhite', function () { return enableColors ? '\u001b[47m' + this + '\u001b[49m' : this; }); | ||
define('plain', function () { return this.replace(/\u001b\[\d+m/g, ''); }) | ||
define('reset', function () { return enableColors ? '\u001b[0m' + this : this; }) | ||
define('base', function () { return enableColors ? '\u001b[39m' + this : this; }) | ||
define('bold', function () { return enableColors ? '\u001b[1m' + this + '\u001b[22m' : this; }) | ||
define('normal', function () { return enableColors ? '\u001b[2m' + this + '\u001b[22m' : this; }) | ||
define('italic', function () { return enableColors ? '\u001b[3m' + this + '\u001b[23m' : this; }) | ||
define('underline', function () { return enableColors ? '\u001b[4m' + this + '\u001b[24m' : this; }) | ||
define('inverse', function () { return enableColors ? '\u001b[7m' + this + '\u001b[27m' : this; }) | ||
define('hidden', function () { return enableColors ? '\u001b[8m' + this + '\u001b[28m' : this; }) | ||
define('strike', function () { return enableColors ? '\u001b[9m' + this + '\u001b[29m' : this; }) | ||
define('black', function () { return enableColors ? '\u001b[30m' + this + '\u001b[39m' : this; }) | ||
define('red', function () { return enableColors ? '\u001b[31m' + this + '\u001b[39m' : this; }) | ||
define('green', function () { return enableColors ? '\u001b[32m' + this + '\u001b[39m' : this; }) | ||
define('yellow', function () { return enableColors ? '\u001b[33m' + this + '\u001b[39m' : this; }) | ||
define('blue', function () { return enableColors ? '\u001b[34m' + this + '\u001b[39m' : this; }) | ||
define('magenta', function () { return enableColors ? '\u001b[35m' + this + '\u001b[39m' : this; }) | ||
define('cyan', function () { return enableColors ? '\u001b[36m' + this + '\u001b[39m' : this; }) | ||
define('white', function () { return enableColors ? '\u001b[37m' + this + '\u001b[39m' : this; }) | ||
define('gray', function () { return enableColors ? '\u001b[90m' + this + '\u001b[39m' : this; }) | ||
define('bgBlack', function () { return enableColors ? '\u001b[40m' + this + '\u001b[49m' : this; }) | ||
define('bgRed', function () { return enableColors ? '\u001b[41m' + this + '\u001b[49m' : this; }) | ||
define('bgGreen', function () { return enableColors ? '\u001b[42m' + this + '\u001b[49m' : this; }) | ||
define('bgYellow', function () { return enableColors ? '\u001b[43m' + this + '\u001b[49m' : this; }) | ||
define('bgBlue', function () { return enableColors ? '\u001b[44m' + this + '\u001b[49m' : this; }) | ||
define('bgMagenta', function () { return enableColors ? '\u001b[45m' + this + '\u001b[49m' : this; }) | ||
define('bgCyan', function () { return enableColors ? '\u001b[46m' + this + '\u001b[49m' : this; }) | ||
define('bgWhite', function () { return enableColors ? '\u001b[47m' + this + '\u001b[49m' : this; }) |
/** | ||
* A `QueueStream` queues `write` arguments temporarily. | ||
*/ | ||
var QueueStream = module.exports = function QueueStream() { | ||
this.queue = []; | ||
}; | ||
var QueueStream = module.exports = function QueueStream () { | ||
this.queue = [] | ||
} | ||
var doNothing = function () {}; | ||
var doNothing = function () {} | ||
@@ -16,3 +16,3 @@ QueueStream.prototype = { | ||
write: function () { | ||
this.queue.push(arguments); | ||
this.queue.push(arguments) | ||
}, | ||
@@ -29,8 +29,8 @@ | ||
pipe: function (stream) { | ||
if (stream != this) { | ||
var queue = this.queue; | ||
if (stream !== this) { | ||
var queue = this.queue | ||
for (var i = 0, l = queue.length; i < l; i++) { | ||
stream.write.apply(stream, queue[i]); | ||
stream.write.apply(stream, queue[i]) | ||
} | ||
queue.length = 0; | ||
queue.length = 0 | ||
} | ||
@@ -44,2 +44,2 @@ }, | ||
}; | ||
} |
@@ -1,49 +0,49 @@ | ||
var doNothing = function () {}; | ||
var doNothing = function () {} | ||
/** | ||
* The `Base` logger defines methods that transports will share. | ||
* The `Base` log defines methods that transports will share. | ||
*/ | ||
var Base = module.exports = function (config, defaults) { | ||
var cedar = require('../../cedar'); | ||
var cedar = require('../../cedar') | ||
// A logger is a shorthand for `logger.log`, among other things. | ||
var logger = function () { | ||
logger.log.apply(logger, arguments); | ||
}; | ||
// A log is a shorthand for `log.log`, among other things. | ||
var log = function () { | ||
log.log.apply(log, arguments) | ||
} | ||
// Don't run `setMethods` until all config properties are set. | ||
var setMethods = doNothing; | ||
var setMethods = doNothing | ||
// Define properties that trigger `setMethods`. | ||
Base.resetters.forEach(function (property) { | ||
var value; | ||
Object.defineProperty(logger, property, { | ||
var value | ||
Object.defineProperty(log, property, { | ||
get: function () { | ||
return value; | ||
return value | ||
}, | ||
set: function (newValue) { | ||
value = newValue; | ||
setMethods.apply(logger); | ||
value = newValue | ||
setMethods.apply(log) | ||
} | ||
}); | ||
}); | ||
}) | ||
}) | ||
// Copy `config` properties to the `logger`. | ||
Base.decorate(logger, config, true); | ||
// Copy `config` properties to the `log`. | ||
Base.decorate(log, config, true) | ||
// Apply default properties. | ||
Base.decorate(logger, defaults || Base.defaults); | ||
Base.decorate(log, defaults || Base.defaults) | ||
// Set up logging methods. | ||
Base.setMethods.apply(logger); | ||
Base.setMethods.apply(log) | ||
// Re-run `setMethods` if `resetters` change. | ||
setMethods = Base.setMethods; | ||
setMethods = Base.setMethods | ||
// Return the fully-decorated log function. | ||
return logger; | ||
return log | ||
}; | ||
} | ||
@@ -54,3 +54,3 @@ | ||
*/ | ||
Base.resetters = ['level', 'prefixes', 'format', 'showTrace']; | ||
Base.resetters = ['level', 'prefixes', 'format', 'showTrace'] | ||
@@ -60,6 +60,6 @@ /** | ||
*/ | ||
Base.levels = ['trace', 'debug', 'log', 'info', 'warn', 'error', 'alert']; | ||
Base.levels = ['trace', 'debug', 'log', 'info', 'warn', 'error', 'fatal'] | ||
/** | ||
* Share defaults between logger objects. | ||
* Share defaults between log objects. | ||
*/ | ||
@@ -82,14 +82,13 @@ Base.defaults = { | ||
join: function (args) { | ||
var list = []; | ||
var list = [] | ||
for (var index = 0, length = args.length; index < length; index++) { | ||
var arg = args[index]; | ||
var arg = args[index] | ||
if (arg instanceof Error) { | ||
arg = '"' + (arg.stack || arg.toString()).replace(/\n/, '\\n') + '"'; | ||
arg = '"' + (arg.stack || arg.toString()).replace(/\n/, '\\n') + '"' | ||
} else { | ||
arg = JSON.stringify(arg, null, this.space) | ||
} | ||
else { | ||
arg = JSON.stringify(arg, null, this.space); | ||
} | ||
list.push(arg); | ||
list.push(arg) | ||
} | ||
return '[' + list.join(',') + ']'; | ||
return '[' + list.join(',') + ']' | ||
}, | ||
@@ -105,3 +104,3 @@ | ||
error: 'ERROR ', | ||
alert: 'ALERT ' | ||
fatal: 'FATAL ' | ||
}, | ||
@@ -111,6 +110,6 @@ | ||
format: function (message, type, prefix) { | ||
return prefix + message + '\n'; | ||
return prefix + message + '\n' | ||
} | ||
}; | ||
} | ||
@@ -122,10 +121,10 @@ | ||
Base.decorate = function (object, defaults, shouldOverwrite) { | ||
object = object || {}; | ||
object = object || {} | ||
for (var key in defaults) { | ||
if (shouldOverwrite || (typeof object[key] == 'undefined')) { | ||
object[key] = defaults[key]; | ||
if (shouldOverwrite || (typeof object[key] === 'undefined')) { | ||
object[key] = defaults[key] | ||
} | ||
} | ||
return object; | ||
}; | ||
return object | ||
} | ||
@@ -136,49 +135,47 @@ /** | ||
Base.setMethods = function () { | ||
var self = this; | ||
var found = false; | ||
if ((Base.levels.indexOf(self.level) < 0) && self.level != 'nothing') { | ||
self.error('Unknown log level: "' + self.level + '".'); | ||
} | ||
else { | ||
var self = this | ||
var found = false | ||
if ((Base.levels.indexOf(self.level) < 0) && self.level !== 'nothing') { | ||
self.error('Unknown log level: "' + self.level + '".') | ||
} else { | ||
Base.levels.forEach(function (methodName, index) { | ||
if (methodName == self.level) { | ||
found = true; | ||
if (methodName === self.level) { | ||
found = true | ||
} | ||
var prefix = self.prefixes[methodName] || ''; | ||
var format = self.format; | ||
// If this logger is an Emitter, we can catch and emit errors. | ||
var prefix = self.prefixes[methodName] || '' | ||
var format = self.format | ||
// If this log is an Emitter, we can catch and emit errors. | ||
if (self.emit) { | ||
self[methodName] = found ? function () { | ||
var message = self.join(arguments); | ||
message = format.call(self, message, methodName, prefix); | ||
var message = self.join(arguments) | ||
message = format.call(self, message, methodName, prefix) | ||
try { | ||
self.stream.write(message); | ||
self.stream.write(message) | ||
} catch (e) { | ||
self.emit('error', e) | ||
} | ||
catch (e) { | ||
self.emit('error', e); | ||
} | ||
} : doNothing; | ||
} | ||
} : doNothing | ||
// Otherwise, they'll just throw. | ||
else { | ||
} else { | ||
self[methodName] = found ? function () { | ||
var message = self.join(arguments); | ||
message = format.call(self, message, methodName, prefix); | ||
self.stream.write(message); | ||
} : doNothing; | ||
var message = self.join(arguments) | ||
message = format.call(self, message, methodName, prefix) | ||
self.stream.write(message) | ||
} : doNothing | ||
} | ||
}); | ||
}) | ||
// Wrap the trace method with a stack tracer. | ||
if (self.trace != doNothing) { | ||
var traceMethod = self.trace; | ||
if (self.trace !== doNothing) { | ||
var traceMethod = self.trace | ||
self.trace = function () { | ||
var e = new Error(''); | ||
Error.captureStackTrace(e, self.trace); | ||
var l = arguments.length; | ||
arguments[l] = e.stack.split('\n').splice(2).join('\n'); | ||
arguments.length = ++l; | ||
traceMethod.apply(self, arguments); | ||
}; | ||
var e = new Error('') | ||
Error.captureStackTrace(e, self.trace) | ||
var l = arguments.length | ||
arguments[l] = e.stack.split('\n').splice(2).join('\n') | ||
arguments.length = ++l | ||
traceMethod.apply(self, arguments) | ||
} | ||
} | ||
} | ||
}; | ||
} |
@@ -1,9 +0,9 @@ | ||
var Base = require('./base'); | ||
var Base = require('./base') | ||
/** | ||
* The `Blackhole` logger drops everything. | ||
* The `Blackhole` log drops everything. | ||
*/ | ||
module.exports = function (config) { | ||
config.stream = {write: function () {}}; | ||
return Base(config); | ||
}; | ||
config.stream = {write: function () {}} | ||
return Base(config) | ||
} |
@@ -1,23 +0,17 @@ | ||
var fs = require('fs'); | ||
var Base = require('./base'); | ||
var snippetStack = require('../../common/error/snippet-stack'); | ||
var colors = require('../../common/string/colors'); | ||
require('../../common/json/colorize'); | ||
var Base = require('./base') | ||
var snippetStack = require('../../common/error/snippet-stack') | ||
var colors = require('../../common/string/colors') | ||
require('../../common/json/colorize') | ||
var isWindows = (process.platform == 'win32'); | ||
var cwd = process.cwd(); | ||
var specialPattern = /(\.\?\*\+\(\)\[\]\{\}\\)/g; | ||
var dirs = cwd.replace(specialPattern, '\\$1') + '/'; | ||
var stackPattern = new RegExp('\n +at ([^\n]*)' + dirs + '([^:\n]*?)([^/:]+):([0-9]+):([0-9]+)([^\n]*)', 'g'); | ||
var reserved = /^(break|case|catch|continue|debugger|default|delete|do|else|finally|for|function|if|in|instanceof|new|return|switch|this|throw|try|typeof|var|void|while|with)$/; | ||
var isWindows = (process.platform === 'win32') | ||
/** | ||
* The `Console` logger writes pretty strings to stdout. | ||
* The `Console` log writes pretty strings to stdout. | ||
*/ | ||
var Console = module.exports = function (config) { | ||
return Base(config, Console.defaults); | ||
}; | ||
return Base(config, Console.defaults) | ||
} | ||
/** | ||
* Set up `Console` logger defaults. | ||
* Set up `Console` log defaults. | ||
*/ | ||
@@ -36,33 +30,36 @@ Console.defaults = Base.decorate({ | ||
// Silence noisy getters. | ||
var errWrite = process.stderr.write; | ||
var outWrite = process.stdout.write; | ||
process.stderr.write = process.stdout.write = function () {}; | ||
var errWrite = process.stderr.write | ||
var outWrite = process.stdout.write | ||
process.stderr.write = process.stdout.write = function () {} | ||
// Build an array of lines. | ||
var space = this.space; | ||
var lines = []; | ||
var space = this.space | ||
var lines = [] | ||
for (var i = 0, l = args.length; i < l; i++) { | ||
var line = args[i]; | ||
if (typeof line != 'string') { | ||
var line = args[i] | ||
if (typeof line !== 'string') { | ||
if (line instanceof Error) { | ||
line = (line.stack || line.toString()); | ||
} | ||
else { | ||
line = (line.stack || line.toString()) | ||
} else if (line && line.stack && /Error/.test(line.stack)) { | ||
var n = line.line | ||
var c = line.col || line.column | ||
var message = line.message + (n ? ' ' + n + (c ? ':' + c : '') : '') | ||
line = line.stack.replace(/^[\n]+/, message) | ||
} else { | ||
try { | ||
line = this.stringify(line, null, space); | ||
line = this.stringify(line, null, space, 0, 78, 3) | ||
} catch (e) { | ||
line = e.stack | ||
} | ||
catch (e) { | ||
line = e.stack; | ||
} | ||
} | ||
} | ||
lines.push(line); | ||
lines.push(line) | ||
} | ||
// Restore stderr and stdout. | ||
process.stderr.write = errWrite; | ||
process.stdout.write = outWrite; | ||
process.stderr.write = errWrite | ||
process.stdout.write = outWrite | ||
// Return lines with breaks. | ||
return lines.join('\n'); | ||
return lines.join('\n') | ||
}, | ||
@@ -78,3 +75,3 @@ | ||
error: colors.red + (isWindows ? '\u00D7 ' : '\u2716 '), | ||
alert: colors.red + (isWindows ? '* ' : '\u2739 ') | ||
fatal: colors.red + (isWindows ? '* ' : '\u2739 ') | ||
}, | ||
@@ -90,3 +87,3 @@ | ||
error: 'red', | ||
alert: 'red' | ||
fatal: 'red' | ||
}, | ||
@@ -102,8 +99,8 @@ | ||
format: function (string, type) { | ||
var self = this; | ||
var self = this | ||
string = string.replace(/^\[(\w+)\] ([^\n]+)/, function (match, name, text) { | ||
var length = text.plain.length; | ||
var pad = Array(Math.max(self.bracketStart - length, 2)).join(' '); | ||
return text + pad + name.gray; | ||
}); | ||
var length = text.plain.length | ||
var pad = Array(Math.max(self.bracketStart - length, 2)).join(' ') | ||
return text + pad + name.gray | ||
}) | ||
string = string.replace(/\n +at[\s\S]+/, function (stack) { | ||
@@ -114,9 +111,9 @@ return snippetStack(stack, { | ||
indent: ' ' | ||
}); | ||
}); | ||
string = string.replace(/\n/g, '\n' + self.space); | ||
return self.prefixes[type] + string + '\n'; | ||
}) | ||
}) | ||
string = string.replace(/\n/g, '\n' + self.space) | ||
return self.prefixes[type] + string + '\n' | ||
} | ||
}, Base.defaults); | ||
}, Base.defaults) | ||
@@ -128,3 +125,3 @@ | ||
Console.getColorlessLength = function (text) { | ||
return text.replace(/\u001b\[\d\dm/g, '').length; | ||
}; | ||
return text.replace(/\u001b\[\d\dm/g, '').length | ||
} |
@@ -1,39 +0,39 @@ | ||
var fs = require('fs'); | ||
var dirname = require('path').dirname; | ||
var os = require('os'); | ||
var spawn = require('child_process').spawn; | ||
var Base = require('./base'); | ||
var mkdirp = require('../../common/fs/mkdirp'); | ||
var QueueStream = require('../queue-stream'); | ||
var Emitter = require('../../common/event/emitter'); | ||
var fs = require('fs') | ||
var dirname = require('path').dirname | ||
var os = require('os') | ||
var spawn = require('child_process').spawn | ||
var Base = require('./base') | ||
var mkdirp = require('../../common/fs/mkdirp') | ||
var QueueStream = require('../queue-stream') | ||
var Emitter = require('../../common/event/emitter') | ||
/** | ||
* The `File` logger writes log messages to disk. | ||
* The `File` log writes log messages to disk. | ||
*/ | ||
var File = module.exports = function (config) { | ||
// Create a file logger. | ||
var logger = Base(config, File.defaults); | ||
// Create a file log. | ||
var log = Base(config, File.defaults) | ||
// Add emitter methods. | ||
Emitter.decorate(logger); | ||
Emitter.decorate(log) | ||
// Detect the duration from the path pattern. | ||
logger.path.replace(/\$\{(DD|HH|NN|SS)\}/g, function (match, token) { | ||
logger.duration = Math.min(File.durations[token], logger.duration); | ||
}); | ||
log.path.replace(/\$\{(DD|HH|NN|SS)\}/g, function (match, token) { | ||
log.duration = Math.min(File.durations[token], log.duration) | ||
}) | ||
// Until an actual stream is open, push `stream.write` arguments to a queue. | ||
logger.stream = logger.queue = new QueueStream(); | ||
log.stream = log.queue = new QueueStream() | ||
// Open a stream. | ||
var isRotating = (logger.duration < Infinity); | ||
logger[isRotating ? 'checkTime' : 'openStream'].apply(logger); | ||
var isRotating = (log.duration < Infinity) | ||
log[isRotating ? 'checkTime' : 'openStream'].apply(log) | ||
return logger; | ||
return log | ||
}; | ||
} | ||
/** | ||
* Set up `File` logger defaults. | ||
* Set up `File` log defaults. | ||
*/ | ||
@@ -53,3 +53,3 @@ File.defaults = Base.decorate({ | ||
format: function (message, type, prefix) { | ||
return prefix + timestamp() + ' ' + message.replace(/\n/g, '\\n') + '\n'; | ||
return prefix + timestamp() + ' ' + message.replace(/\n/g, '\\n') + '\n' | ||
}, | ||
@@ -65,10 +65,10 @@ | ||
close: function () { | ||
var self = this; | ||
clearTimeout(self.timer); | ||
self.isClosed = true; | ||
self._events = 0; | ||
var self = this | ||
clearTimeout(self.timer) | ||
self.isClosed = true | ||
self._events = 0 | ||
self.on('open', function () { | ||
self.close(); | ||
self._events = 0; | ||
}); | ||
self.close() | ||
self._events = 0 | ||
}) | ||
}, | ||
@@ -78,7 +78,7 @@ | ||
checkTime: function () { | ||
var self = this; | ||
var self = this | ||
var now = Date.now(); | ||
var elapsed = now % self.duration; | ||
var start = now - elapsed; | ||
var now = Date.now() | ||
var elapsed = now % self.duration | ||
var start = now - elapsed | ||
@@ -88,12 +88,12 @@ // If we're in a new time period, open a new stream. | ||
// Enter the new time period. | ||
self.currentStart = start; | ||
self.currentStart = start | ||
// Open a write stream. | ||
self.openStream(); | ||
self.openStream() | ||
} | ||
// Check again later. | ||
var remaining = self.duration - elapsed; | ||
var remaining = self.duration - elapsed | ||
self.timer = setTimeout(function () { | ||
self.checkTime(); | ||
}, remaining); | ||
self.checkTime() | ||
}, remaining) | ||
@@ -104,64 +104,62 @@ }, | ||
openStream: function () { | ||
var self = this; | ||
var path = File.getPath(self.path); | ||
var self = this | ||
var path = File.getPath(self.path) | ||
// Ensure the directory exists, and create the file stream. | ||
var dir = dirname(path); | ||
var dir = dirname(path) | ||
mkdirp(dir, function (error) { | ||
if (error) { | ||
throw error; | ||
throw error | ||
} | ||
if (self.isClosed) { | ||
return; | ||
return | ||
} | ||
// End the existing stream. | ||
self.stream.end(); | ||
self.stream.end() | ||
// Queue `write` arguments until the new stream is open. | ||
self.stream = self.queue; | ||
self.stream = self.queue | ||
// Open the new stream. | ||
try { | ||
var stream = fs.createWriteStream(path, self.streamOptions); | ||
var stream = fs.createWriteStream(path, self.streamOptions) | ||
} catch (e) { | ||
self.emit('error', e) | ||
} | ||
catch (e) { | ||
self.emit('error', e); | ||
} | ||
// Once open, pipe queued writes in, then emit an "open" event. | ||
stream.on('open', function () { | ||
self.stream = stream; | ||
self.queue.pipe(stream); | ||
self.currentFile = path; | ||
self.emit('open', path); | ||
}); | ||
self.stream = stream | ||
self.queue.pipe(stream) | ||
self.currentFile = path | ||
self.emit('open', path) | ||
}) | ||
// When closed, emit a "close" event. | ||
stream.on('close', function () { | ||
self.emit('close', path); | ||
if (typeof self.after == 'function') { | ||
self.after(path); | ||
} | ||
else if (typeof self.after == 'string') { | ||
var cmds = self.after.replace(/\$\{PATH\}/g, path).split(';'); | ||
self.emit('close', path) | ||
if (typeof self.after === 'function') { | ||
self.after(path) | ||
} else if (typeof self.after === 'string') { | ||
var cmds = self.after.replace(/\$\{PATH\}/g, path).split(';') | ||
var run = function (index) { | ||
var args = cmds[index].split(/\s+/); | ||
var cmd = args.shift(); | ||
cmd = spawn(cmd, args); | ||
var args = cmds[index].split(/\s+/) | ||
var cmd = args.shift() | ||
cmd = spawn(cmd, args) | ||
cmd.on('error', function (error) { | ||
self.error(error); | ||
}); | ||
self.error(error) | ||
}) | ||
cmd.on('exit', function (error) { | ||
if (++index < cmds.length) { | ||
run(index); | ||
run(index) | ||
} | ||
}); | ||
}; | ||
run(0); | ||
}) | ||
} | ||
run(0) | ||
} | ||
}); | ||
}); | ||
}) | ||
}) | ||
} | ||
}, Base.defaults); | ||
}, Base.defaults) | ||
@@ -176,3 +174,3 @@ /** | ||
SS: 1e3 | ||
}; | ||
} | ||
@@ -183,14 +181,14 @@ /** | ||
File.getPath = function (pathPattern) { | ||
var stamp = timestamp(); | ||
var tokens = /\$\{(YYYY|MM|DD|HH|NN|SS|HOST)\}/g; | ||
var stamp = timestamp() | ||
var tokens = /\$\{(YYYY|MM|DD|HH|NN|SS|HOST)\}/g | ||
return pathPattern.replace(tokens, function (match, token) { | ||
return token == 'YYYY' ? stamp.substr(0, 4) : | ||
token == 'MM' ? stamp.substr(5, 2) : | ||
token == 'DD' ? stamp.substr(8, 2) : | ||
token == 'HH' ? stamp.substr(11, 2) : | ||
token == 'NN' ? stamp.substr(14, 2) : | ||
token == 'SS' ? stamp.substr(17, 2) : | ||
token == 'HOST' ? os.hostname() : token; | ||
}); | ||
}; | ||
return token === 'YYYY' ? stamp.substr(0, 4) : | ||
token === 'MM' ? stamp.substr(5, 2) : | ||
token === 'DD' ? stamp.substr(8, 2) : | ||
token === 'HH' ? stamp.substr(11, 2) : | ||
token === 'NN' ? stamp.substr(14, 2) : | ||
token === 'SS' ? stamp.substr(17, 2) : | ||
token === 'HOST' ? os.hostname() : token | ||
}) | ||
} | ||
@@ -200,4 +198,4 @@ /** | ||
*/ | ||
function timestamp() { | ||
return (new Date()).toISOString(); | ||
function timestamp () { | ||
return (new Date()).toISOString() | ||
} |
@@ -1,19 +0,19 @@ | ||
var cluster = require('cluster'); | ||
var crypto = require('crypto'); | ||
var cedar = require('../../cedar'); | ||
var Base = require('./base'); | ||
require('../../common/json/scriptify'); | ||
require('../../common/json/eval'); | ||
var cluster = require('cluster') | ||
var crypto = require('crypto') | ||
var cedar = require('../../cedar') | ||
var Base = require('./base') | ||
var scriptify = require('../../common/json/scriptify') | ||
var evaluate = require('../../common/json/evaluate') | ||
/** | ||
* The `Multi` logger logs to an array of loggers. | ||
* The `Multi` log logs to an array of logs. | ||
*/ | ||
var Multi = module.exports = function (loggers) { | ||
var Multi = module.exports = function (logs) { | ||
// Give the logger an ID based on its configuration, and register it. | ||
var json = JSON.stringify(loggers); | ||
var hash = crypto.createHash('md5').update(json).digest('hex'); | ||
var id = 'CEDAR_' + hash.substr(0, 8); | ||
// Give the log an ID based on its configuration, and register it. | ||
var json = JSON.stringify(logs) | ||
var hash = crypto.createHash('md5').update(json).digest('hex') | ||
var id = 'CEDAR_' + hash.substr(0, 8) | ||
var logger; | ||
var log | ||
@@ -23,68 +23,63 @@ // In the master process, log to each transport. | ||
// The multi logger is a "log" function alias, like all other Cedar loggers. | ||
logger = function () { | ||
for (var i = 0, l = loggers.length; i < l; i++) { | ||
var item = logger[i]; | ||
item.apply(item, arguments); | ||
// The multi log is a "log" function alias, like all other Cedar logs. | ||
log = function () { | ||
for (var i = 0, l = logs.length; i < l; i++) { | ||
var item = log[i] | ||
item.apply(item, arguments) | ||
} | ||
}; | ||
} | ||
// Set the array of loggers as a property. | ||
logger.loggers = loggers; | ||
// Set the array of logs as a property. | ||
log.logs = logs | ||
// Instantiate a Cedar logger for each item in the array. | ||
loggers.forEach(function (item, i) { | ||
if (typeof item == 'string') { | ||
item = {transport: item}; | ||
// Instantiate a Cedar log for each item in the array. | ||
logs.forEach(function (item, i) { | ||
if (typeof item === 'string') { | ||
item = {transport: item} | ||
} else if (!item.transport) { | ||
item.transport = 'console' | ||
} | ||
else if (!item.transport) { | ||
item.transport = 'console'; | ||
} | ||
logger[i] = loggers[i] = cedar(item.transport, item); | ||
}); | ||
log[i] = logs[i] = cedar(item.transport, item) | ||
}) | ||
// Set up all logging methods. | ||
Base.levels.forEach(function (methodName) { | ||
logger[methodName] = function () { | ||
for (var i = 0, l = loggers.length; i < l; i++) { | ||
var item = logger[i]; | ||
item[methodName].apply(item, arguments); | ||
log[methodName] = function () { | ||
for (var i = 0, l = logs.length; i < l; i++) { | ||
var item = log[i] | ||
item[methodName].apply(item, arguments) | ||
} | ||
}; | ||
}); | ||
} | ||
}) | ||
// Register the logger in the `Multi` map so workers can reach it. | ||
Multi[id] = logger; | ||
} | ||
// Register the log in the `Multi` map so workers can reach it. | ||
Multi[id] = log | ||
// In worker processes, send log messages to the master. | ||
else { | ||
} else { | ||
// Send a log message. | ||
logger = function () { | ||
var args = Array.prototype.slice.call(arguments); | ||
process.send(logger.id + 'log' + logger.stringify(args)); | ||
}; | ||
log = function () { | ||
var args = Array.prototype.slice.call(arguments) | ||
process.send(log.id + 'log' + scriptify(args)) | ||
} | ||
// Make builtin object instances re-constructable. | ||
logger.stringify = JSON.scriptify; | ||
// Set up all logging methods. | ||
Base.levels.forEach(function (methodName) { | ||
var glue = '.' + methodName; | ||
logger[methodName] = function () { | ||
var args = Array.prototype.slice.call(arguments); | ||
process.send(logger.id + methodName + logger.stringify(args)); | ||
}; | ||
}); | ||
log[methodName] = function () { | ||
var args = Array.prototype.slice.call(arguments) | ||
process.send(log.id + methodName + scriptify(args)) | ||
} | ||
}) | ||
} | ||
// Self identify as a Multi logger. | ||
logger.transport = 'multi'; | ||
logger.id = id; | ||
// Self identify as a Multi log. | ||
log.transport = 'multi' | ||
log.id = id | ||
log.logs = logs | ||
return logger; | ||
return log | ||
}; | ||
} | ||
@@ -95,37 +90,31 @@ // Listen for messages from workers. | ||
var receive = function (message) { | ||
var id = message.substr(0, 14); | ||
var pos = message.indexOf('['); | ||
var type = message.substring(14, pos); | ||
var data = message.substring(pos); | ||
try { | ||
data = JSON.eval(data); | ||
data.push(address); | ||
} | ||
catch (e) { | ||
} | ||
var logger = Multi[id]; | ||
if (logger) { | ||
var loggers = logger.loggers; | ||
for (var i = 0, l = loggers.length; i < l; i++) { | ||
var item = logger[i]; | ||
if (!item.worker || (item.worker == worker.id)) { | ||
var id = message.substr(0, 14) | ||
var pos = message.indexOf('[') | ||
var type = message.substring(14, pos) | ||
var data = message.substring(pos) | ||
data = evaluate(data) | ||
var log = Multi[id] | ||
if (log) { | ||
var logs = log.logs | ||
for (var i = 0, l = logs.length; i < l; i++) { | ||
var item = log[i] | ||
if (!item.worker || (item.worker === worker.id)) { | ||
try { | ||
item[type].apply(item, data); | ||
item[type].apply(item, data) | ||
} catch (e) { | ||
} | ||
catch (e) { | ||
} | ||
} | ||
} | ||
} | ||
}; | ||
var alreadyListening = false; | ||
} | ||
var alreadyListening = false | ||
worker.listeners('message').forEach(function (listener) { | ||
if (listener.toString() == receive.toString()) { | ||
alreadyListening = true; | ||
if (listener.toString() === receive.toString()) { | ||
alreadyListening = true | ||
} | ||
}); | ||
}) | ||
if (!alreadyListening) { | ||
worker.on('message', receive); | ||
worker.on('message', receive) | ||
} | ||
}); | ||
}) | ||
} |
{ | ||
"name": "cedar", | ||
"version": "0.2.0", | ||
"version": "0.3.0", | ||
"description": "User-friendly logger", | ||
"dependencies": {}, | ||
"devDependencies": { | ||
"coveralls": "2.11.1", | ||
"exam": "^0.2.1", | ||
"istanbul": "0.3.0" | ||
"exam": "0.3.0" | ||
}, | ||
@@ -28,5 +26,5 @@ "keywords": [ | ||
"test": "./node_modules/exam/exam.js", | ||
"cover": "istanbul cover ./node_modules/exam/exam.js", | ||
"cover": "./node_modules/exam/exam-cover.js", | ||
"report": "open coverage/lcov-report/index.html", | ||
"coveralls": "istanbul cover ./node_modules/exam/exam.js --report lcovonly -- -R spec && cat ./coverage/lcov.info | coveralls && rm -rf ./coverage" | ||
"coveralls": "./node_modules/exam/exam-coveralls.js" | ||
}, | ||
@@ -33,0 +31,0 @@ "repository": "https://github.com/lighterio/cedar.git", |
@@ -10,3 +10,3 @@ # <a href="http://lighter.io/cedar" style="font-size:40px;text-decoration:none;color:#000"><img src="https://cdn.rawgit.com/lighterio/lighter.io/master/public/cedar.svg" style="width:90px;height:90px"> Cedar</a> | ||
Cedar is a Node.js logger, designed to be fast, extensible, and super useful. | ||
Cedar is a Node.js log, designed to be fast, extensible, and super useful. | ||
@@ -16,3 +16,3 @@ ### Powerful features | ||
* Modifiable logging prefixes, formatters, and stringify functions. | ||
* Loggers which are functions, allowing shorthand calls. | ||
* Logs which are functions, allowing shorthand calls. | ||
* A `console` transport with color unicode symbols and helpful code snippets | ||
@@ -32,3 +32,3 @@ inside stack traces. | ||
Create a logger, and use it. | ||
Create a log, and use it. | ||
```js | ||
@@ -59,3 +59,3 @@ var log = require('cedar')([ | ||
log.error('This gets formatted as an error message.', error); | ||
log.alert('This gets formatted as an alerting message.', error); | ||
log.fatal('This gets formatted as a fatal error message.', error); | ||
``` | ||
@@ -71,3 +71,3 @@ | ||
// Set the log `level` in a configuration object. | ||
var log = require('cedar')({level: 'warn'}); // "warn", "error" and "alert". | ||
var log = require('cedar')({level: 'warn'}); // "warn", "error" and "fatal". | ||
@@ -95,3 +95,3 @@ log('log'); // Ignore. | ||
of the levels after it: `debug`, `trace`, `log`, `info`, `warn`, `error` | ||
and `alert`. Setting the level to `nothing` will stop all logs. | ||
and `fatal`. Setting the level to `nothing` will stop all logs. | ||
@@ -112,3 +112,3 @@ #### log.prefixes `object` | ||
error: 'ERROR: '.red, | ||
alert: 'ALERT: '.red | ||
fatal: 'FATAL: '.red | ||
}; | ||
@@ -155,8 +155,8 @@ ``` | ||
The `console` logger writes to `process.stdout` with pretty colors. | ||
The `console` log writes to `process.stdout` with pretty colors. | ||
Console is the default transport, so the following are equivalent: | ||
```js | ||
logger = require('cedar')(); | ||
logger = require('cedar')('color'); | ||
log = require('cedar')(); | ||
log = require('cedar')('color'); | ||
``` | ||
@@ -166,3 +166,3 @@ | ||
The `file` logger writes JSON messages to a file. In addition, it acts as a | ||
The `file` log writes JSON messages to a file. In addition, it acts as a | ||
simple event emitter so you can receive notifications when file rotation | ||
@@ -190,3 +190,3 @@ events occur. | ||
The `multi` logger writes to multiple loggers at once. Its configuration object | ||
The `multi` log writes to multiple logs at once. Its configuration object | ||
is an array of configurations with transports specified by a `transport` | ||
@@ -209,3 +209,3 @@ property. | ||
Additionally, huge thanks go to [TUNE](http://www.tune.com) for employing | ||
Additionally, huge thanks go to [Goin’](https://goin.io) for employing | ||
and supporting [Cedar](http://lighter.io/cedar) project maintainers, | ||
@@ -212,0 +212,0 @@ and for being an epically awesome place to work (and play). |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
57230
1
22
1544
8
4