fliplog
Advanced tools
Comparing version 0.3.13 to 1.0.0
@@ -20,3 +20,2 @@ let index = 0 | ||
// pass in tags & instance here just for fn filter | ||
@@ -41,10 +40,14 @@ function shouldFilter({filters, tags, checkTags, instance}) { | ||
// whitelist vs blacklist | ||
shouldBeFiltered = filter(Object.assign(instance.entries(), { | ||
tags, | ||
checkTags, | ||
debugs, | ||
index, | ||
filters, | ||
})) | ||
if (shouldBeFiltered === false) shouldBeFiltered = true | ||
shouldBeFiltered = filter( | ||
Object.assign(instance.entries(), { | ||
tags, | ||
checkTags, | ||
debugs, | ||
index, | ||
filters, | ||
}) | ||
) | ||
if (shouldBeFiltered === true) shouldBeFiltered = false | ||
else if (shouldBeFiltered === false) shouldBeFiltered = true | ||
else if (shouldBeFiltered === null) shouldBeFiltered = true | ||
return shouldBeFiltered | ||
@@ -51,0 +54,0 @@ } |
@@ -1,2 +0,1 @@ | ||
/** | ||
@@ -18,3 +17,2 @@ * @tutorial https://github.com/lukeed/obj-str | ||
// https://github.com/npm/npmlog | ||
@@ -56,12 +54,12 @@ // http://tostring.it/2014/06/23/advanced-logging-with-nodejs/ | ||
} | ||
const psr3 = [ | ||
'emergency', | ||
'alert', | ||
'critical', | ||
'error', | ||
'warning', | ||
'notice', | ||
'warning', | ||
'debug', | ||
] | ||
// const psr3 = [ | ||
// 'emergency', | ||
// 'alert', | ||
// 'critical', | ||
// 'error', | ||
// 'warning', | ||
// 'notice', | ||
// 'warning', | ||
// 'debug', | ||
// ] | ||
@@ -73,10 +71,16 @@ const combinations = clrs.concat(bgColors).concat(em) | ||
const isFunctionWithNoKeys = obj => | ||
typeof obj === 'function' && Object.keys(obj).length === 0 | ||
const matcher = require('./matcher') | ||
module.exports = { | ||
matcher, | ||
isFunctionWithNoKeys, | ||
combinations, | ||
OFF, | ||
bgColors, | ||
psr3, | ||
// psr3, | ||
xtermByName, | ||
objToStr, | ||
} |
87
index.js
@@ -1,3 +0,3 @@ | ||
const ChainedMapExtendable = require('chain-able/ChainedMapExtendable') | ||
const {OFF, objToStr} = require('./deps') | ||
const ChainedMapExtendable = require('chain-able') | ||
const {OFF, objToStr, isFunctionWithNoKeys} = require('./deps') | ||
const pluginObjs = Object.assign(require('./plugins'), require('./middleware')) | ||
@@ -47,7 +47,7 @@ | ||
delete this.inspect | ||
this.version = '0.3.0' | ||
this.version = '0.3.14' | ||
// this extending is 0microseconds | ||
this.extend(['title', 'color']) | ||
this.extendTrue(['space', 'tosource', 'time', 'silent']) | ||
this.extendWith(['space', 'tosource', 'time', 'silent'], true) | ||
@@ -133,7 +133,7 @@ this.set('logger', console.log) | ||
if (!dep) { | ||
// const colored = this.colored(name) | ||
// @nOTE: IGNORING THIS | ||
// this.text('did not have package ' + colored) | ||
// .data(`npm i ${colored} --save-dev \n yarn add ${colored} --dev`) | ||
// .echo() | ||
const colored = this.colored(name) | ||
// @NOTE: IGNORING THIS | ||
this.text('did not have package ' + colored) | ||
.data(`npm i ${colored} --save-dev \n yarn add ${colored} --dev`) | ||
.echo() | ||
return false | ||
@@ -156,4 +156,4 @@ } | ||
use(obj) { | ||
if (typeof obj === 'function' && Object.keys(obj).length === 0) { | ||
obj = obj(this) | ||
if (isFunctionWithNoKeys(obj)) { | ||
obj = obj.call(this, this) | ||
} | ||
@@ -410,2 +410,3 @@ | ||
/** | ||
* @rename @since 0.4.0 echoConsole -> forceEcho | ||
* @since 0.3.0 | ||
@@ -416,7 +417,7 @@ * @see this.echo, this.finalize, this.logText, this.logData, this.reset | ||
*/ | ||
echoConsole() { | ||
forceEcho() { | ||
// so we can have them on 1 line | ||
this.finalize() | ||
const datas = this.logData() | ||
const text = this.logText() | ||
const datas = this.logData() | ||
const logger = this.get('logger') || console.log | ||
@@ -439,3 +440,14 @@ | ||
else if (datas !== OFF && text !== OFF) { | ||
logger(text + '', datas) | ||
if ((/\n|\r/gmi).test(text)) { | ||
if (logger === console.log) { | ||
logger(text + '') | ||
logger(datas) | ||
} | ||
else { | ||
logger(text + '', datas) | ||
} | ||
} | ||
else { | ||
logger(text + '', datas) | ||
} | ||
} | ||
@@ -454,3 +466,29 @@ | ||
/** | ||
* @TODO: needs thought whether to return or to echo... | ||
* since `+` is shorter to echo | ||
* | ||
* @alias log | ||
* @alias echo | ||
* @since 0.4.0 | ||
* @return {string} log output | ||
*/ | ||
// toString() { | ||
// return this.echo() | ||
// } | ||
/** | ||
* @desc echos, then returns | ||
* @example log.bold('eh').data({})+ | ||
* @alias echo | ||
* @alias log | ||
* @return {number} 0 if silent, 1 if success | ||
*/ | ||
toNumber() { | ||
this.echo() | ||
return shh.shushed === true || this.has('silent') === true ? 0 : 1 | ||
} | ||
/** | ||
* @alias toString | ||
* @alias log | ||
* @since 0.0.1 | ||
@@ -468,2 +506,4 @@ * @param {boolean} [data=OFF] `false` will make it not output | ||
// data !== 'force' && | ||
/* prettier-ignore */ | ||
if (this.has('tags') === true || this.has('filter') === true) { | ||
@@ -500,3 +540,3 @@ this._filter() | ||
return this.echoConsole() | ||
return this.forceEcho() | ||
} | ||
@@ -516,2 +556,19 @@ | ||
} | ||
// @TODO: don't forget about ansi... | ||
if (this.has('textFormatter') === true) { | ||
let txt = this.get('text') | ||
let text = txt | ||
let title = '' | ||
if (this.has('title')) { | ||
title = this.get('title') | ||
text = title + txt | ||
this.delete('title') | ||
} | ||
text = this.get('textFormatter').call(this, text, this) | ||
this.set('text', text) | ||
this.delete('textFormatter') | ||
} | ||
return this.set('data', arg) | ||
@@ -518,0 +575,0 @@ } |
@@ -95,2 +95,14 @@ const {inspector} = require('../modules/inspector-gadget') | ||
let stack = msg.stack | ||
let message = msg.message | ||
let text = this.get('text') | ||
if (text && text.includes('🚨')) text = '' | ||
if (!text) text = '' | ||
if (text.includes('error:')) text = '' | ||
if (text == '') { | ||
this.text(chalk.bgRed.black(' ' + message + ' ') + '\n') | ||
} | ||
let obj = Object.create(null) | ||
@@ -117,5 +129,6 @@ | ||
const c = { | ||
fn: chalk.blue(functionName), | ||
fn: chalk.yellow(functionName), | ||
col: columnNumber, // chalk.white(columnNumber), | ||
line: chalk.bold(lineNumber), | ||
// line: chalk.bold(lineNumber), | ||
line: lineNumber, | ||
file: chalk.underline(fileName), | ||
@@ -173,4 +186,8 @@ src: source, | ||
.map(moduleError => source.includes(moduleError)) | ||
// .concat(moduleErrors.map(moduleError => | ||
// functionName && functionName.includes(moduleError) | ||
// )) | ||
.includes(true) | ||
// console.log({isModuleError, source, hitNativeNode}) | ||
if (isModuleError) { | ||
@@ -192,3 +209,5 @@ hitNativeNode = true | ||
// ) | ||
c.col = c.col + ' ' + chalk.magenta('(entry)') | ||
// c.col = c.col + ' ' + chalk.magenta('(entry)') | ||
c.src = chalk.magenta('(entry)') + ` line ${c.line} col ${c.col} ` + c.src | ||
// c.src = c.src | ||
@@ -213,3 +232,3 @@ | ||
// in ${c.file} | ||
return `${c.fn} #${c.line}:${c.col} ${c.src}` | ||
return `${c.fn} ${c.src}` | ||
}) | ||
@@ -225,3 +244,8 @@ .filter(line => line) | ||
try { | ||
objStr = '\n' + this.prettyjson({extraErrorProperties: obj}) || '' | ||
objStr = '\n' + this.prettyjson({extraErrorProperties: obj}, { | ||
keysColor: 'red', | ||
dashColor: 'yellow', | ||
stringColor: 'italic', | ||
numberColor: 'green', | ||
}) || '' | ||
} | ||
@@ -233,2 +257,3 @@ catch (e) { | ||
stack += objStr || '' | ||
return stack | ||
@@ -240,4 +265,2 @@ // const logger = this.factory() | ||
// @TODO: | ||
// this.tap('text', text => (text || '') + '\n') | ||
// return inspected | ||
@@ -244,0 +267,0 @@ } |
@@ -40,3 +40,3 @@ const {combinations} = require('../deps') | ||
if (this.get('text')) return `${logWrapFn(msg)}` | ||
if (this.get('text')) return '' + logWrapFn(msg) | ||
let text = logWrapFn(this.get('text')) | ||
@@ -69,2 +69,6 @@ if (text) text += ':' | ||
if (this.has('colorer')) { | ||
return this.get('colorer').call(this, color, this) | ||
} | ||
// maybe we colored with something not in chalk, like xterm | ||
@@ -71,0 +75,0 @@ if (typeof color === 'function') { |
@@ -1,3 +0,3 @@ | ||
const ChainedMap = require('chain-able/ChainedMapExtendable') | ||
const traverse = require('./traverse') | ||
const ChainedMap = require('chain-able/TraverseChain') | ||
// const traverse = require('./traverse') | ||
// const log = require('fliplog') | ||
@@ -50,38 +50,2 @@ | ||
/** | ||
* @desc matches for value | ||
* @modifies this.vals | ||
* @param {Array<Regexp | Function>} tests | ||
* @return {Cleaner} @chainable | ||
*/ | ||
keys(tests) { | ||
return this.set('keys', tests) | ||
} | ||
/** | ||
* @desc matches for value | ||
* @modifies this.vals | ||
* @param {Array<Regexp | Function>} tests | ||
* @return {Cleaner} @chainable | ||
*/ | ||
vals(tests) { | ||
return this.set('vals', tests) | ||
} | ||
/** | ||
* @desc callback for each match | ||
* @modifies this.onMatch | ||
* @param {Function} [cb=null] defaults to .remove | ||
* @return {Matcher} @chainable | ||
*/ | ||
onMatch(cb = null) { | ||
if (cb === null) { | ||
return this.set('onMatch', (arg, traverser) => { | ||
traverser.remove() | ||
}) | ||
} | ||
return this.set('onMatch', cb) | ||
} | ||
/** | ||
* @desc runs traverser, checks the tests, calls the onMatch | ||
@@ -92,61 +56,3 @@ * @modifies this.cleaned | ||
clean() { | ||
if (this.has('onMatch') === false) this.onMatch() | ||
const debug = this.get('debug') | ||
const {obj, keys, vals, onMatch} = this.entries() | ||
// console.log('starting match...') | ||
// log.bold('key val matchers').fmtobj({keys, vals}).echo(debug) | ||
// debug this | ||
const matcher = (prop, val) => { | ||
if (keys) { | ||
for (var keyTest of keys) { | ||
// log | ||
// .dim('testing keys') | ||
// .data({test, prop, matched: test.test(prop)}) | ||
// .echo(debug) | ||
if (typeof keyTest === 'function' && !keyTest.test && keyTest(prop)) { | ||
return true | ||
} | ||
else if (keyTest.test(prop)) { | ||
// log.green('matched!').echo(debug) | ||
return true | ||
} | ||
} | ||
} | ||
if (vals) { | ||
for (var valTest of vals) { | ||
// log | ||
// .dim('testing vals') | ||
// .data({test, val, matched: test.test(val)}) | ||
// .echo(debug) | ||
if (typeof valTest === 'function' && !valTest.test && valTest(prop)) { | ||
return true | ||
} | ||
else if (valTest.test(val)) { | ||
// log.green('matched!').echo(debug) | ||
return true | ||
} | ||
} | ||
} | ||
// log.red('did not match').fmtobj({prop, val}).echo(debug) | ||
return false | ||
} | ||
// bound to the traverser | ||
traverse(obj).forEach(function(x) { | ||
// require('fliplog').data({ x }).bold(this.key).echo() | ||
// if (x && x.parser) this.remove() | ||
if (matcher(this.key, x)) { | ||
// require('fliplog').data({ x }).bold(this.key).echo() | ||
onMatch(x, this) | ||
} | ||
else { | ||
// require('fliplog').data({ x }).red(this.key).echo() | ||
} | ||
}) | ||
this.set('cleaned', obj) | ||
return this | ||
return this.set('cleaned', this.traverse(true)) | ||
} | ||
@@ -153,0 +59,0 @@ |
@@ -8,3 +8,3 @@ { | ||
"name": "fliplog", | ||
"version": "0.3.13", | ||
"version": "1.0.0", | ||
"main": "index.js", | ||
@@ -33,4 +33,2 @@ "description": "fluent logging with verbose insight, colors, tables, emoji, filtering, spinners, progress bars, timestamps, capturing, stack traces, clearing, & presets", | ||
"index.js", | ||
"config.js", | ||
"tagged.js", | ||
"deps/", | ||
@@ -52,3 +50,3 @@ "middleware/", | ||
"test": "node ./test/examples && node ./test/test", | ||
"test-all": "node ./test/examples && node ./test/test && node test/boxen && node test/filter && node test/progress && node test/slow && node test/formatter && node test/from && node test/pretty && node test/diff && node test/dept && node test/write && node test/quick", | ||
"test-all": "node ./test/examples && node ./test/test && node test/boxen && node test/filter && node test/progress && node test/slow && node test/formatter && node test/from && node test/pretty && node test/diff && node test/dept && node test/write && node test/fun && node test/quick", | ||
"_prepublish": "echo {} > ./deps/cache.json", | ||
@@ -69,3 +67,3 @@ "_magicpublish": "node ./dynamicTags.js", | ||
"dependencies": { | ||
"chain-able": "^1.0.1" | ||
"chain-able": "3.0.0" | ||
}, | ||
@@ -72,0 +70,0 @@ "license": "MIT", |
let toarr | ||
let shouldFilter | ||
let matcher | ||
module.exports = { | ||
reset() { | ||
this.delete('tags') | ||
}, | ||
const isNumber = obj => | ||
Object.prototype.toString.call(obj) === '[object Number]' || | ||
(/^0x[0-9a-f]+$/i).test(obj) || | ||
(/^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/).test(obj) | ||
/** | ||
* @TODO | ||
* - [ ] wildcard, best using [] instead | ||
* - [ ] use debugFor.js | ||
* - [ ] enableTags, disableTags | ||
* - [ ] handle keys here... | ||
* | ||
* @since 0.1.0 | ||
* @tutorial https://github.com/fliphub/fliplog/blob/master/README.md#-filtering | ||
* @param {string | Array<string> | Function} filters filter white or black flags | ||
* @return {FlipLog} @chainable | ||
*/ | ||
filter(filters) { | ||
toarr = toarr ? toarr : require('chain-able/deps/to-arr') | ||
const filter = toarr(filters).concat(this.get('filters') || []) | ||
return this.set('filter', filter) | ||
}, | ||
const stripSpaces = str => str.replace(/([\s\t\n\r ])*/gim, '') | ||
const stripSymbols = str => str.replace(/[><=]/gim, '') | ||
const levelFilterRegExp = /[><=]\d+/ | ||
const isLogLevel = str => str && levelFilterRegExp.test(str) | ||
/** | ||
* @since 0.1.0 | ||
* @desc tag the log for filtering when needed | ||
* @param {string | Array<string>} names tags to use | ||
* @return {FlipLog} @chainable | ||
*/ | ||
tags(names) { | ||
toarr = toarr ? toarr : require('chain-able/deps/to-arr') | ||
const tags = this.get('tags') || [] | ||
const updated = tags.concat(toarr(names)) | ||
return this.set('tags', updated) | ||
}, | ||
const levelFactory = filter => { | ||
const num = stripSymbols(filter) | ||
if (filter.includes('<=')) return lv => lv <= num | ||
else if (filter.includes('>=')) return lv => lv >= num | ||
else if (filter.includes('>')) return lv => lv > num | ||
else if (filter.includes('<')) return lv => lv < num | ||
else if (filter.includes('=')) return lv => lv == num | ||
else | ||
return lv => { | ||
throw new Error('invalid filter') | ||
} | ||
} | ||
/** | ||
* @protected | ||
* @since 0.1.0 | ||
* @desc check if the filters allow the tags | ||
* @return {FlipLog} @chainable | ||
*/ | ||
_filter() { | ||
shouldFilter = shouldFilter ? shouldFilter : require('../deps/filter') | ||
const filterLevelFactory = filter => { | ||
const levelMatcher = levelFactory(filter) | ||
const tags = this.get('tags') || [] | ||
const filters = this.get('filter') || [] | ||
const should = shouldFilter({filters, tags, instance: this}) | ||
if (should) return this.silent(true) | ||
return this | ||
// console.log(tags, filters) | ||
}, | ||
// @TODO: add a way to enforce level tagging | ||
// @TODO: if ONLY checking level, could be more optimized | ||
// @TODO: unsure if level needs to be diff from tags... | ||
return entries => { | ||
// spread, add safety | ||
let {level, tags, namespace} = entries | ||
let nums = tags || [] | ||
// merge level, filter numbers | ||
if (level !== undefined) nums.push(level) | ||
nums = nums.filter(isNumber) | ||
// console.log({level, tags, nums}) | ||
if (nums.length) { | ||
const passing = nums.filter(levelMatcher) | ||
// console.log({passing}) | ||
if (!passing.length) return false | ||
} | ||
return true | ||
} | ||
} | ||
const filterMatcherFactory = filter => { | ||
if (!matcher) matcher = require('../deps/matcher') | ||
const matchFn = matcher.map(filter) | ||
return entries => { | ||
let {level, tags, namespace} = entries | ||
let input = tags || [] | ||
if (level !== undefined) input.push(level) | ||
const matches = matcher(input, matchFn) | ||
// @TODO: reason for matching internalActivityLog here | ||
if (matches.length === 0) return false | ||
return true | ||
} | ||
} | ||
// could also be named abstractFilterFactory | ||
const filterFactory = filter => { | ||
if (typeof filter === 'string') { | ||
// console.log('is string') | ||
const stripped = stripSpaces(filter) | ||
// console.log({stripped}) | ||
if (isLogLevel(stripped)) { | ||
return filterLevelFactory(stripSpaces(filter)) | ||
} | ||
} | ||
// just using a single function, allow full access? | ||
if (typeof filter === 'function') { | ||
return filter | ||
} | ||
return filterMatcherFactory(filter) | ||
// return isMatchCurry(toarr(filter)) | ||
} | ||
// https://github.com/visionmedia/debug#wildcards | ||
// DEBUG='' | ||
module.exports = chain => { | ||
chain.lvl = _level => chain.level(_level) | ||
chain.tag = _tags => chain.tags(_tags) | ||
chain.ns = _namespace => chain.namespace(_namespace) | ||
chain.set('filterer', args => { | ||
if (!shouldFilter) shouldFilter = require('../deps/filter') | ||
return shouldFilter(args) | ||
}) | ||
const plugin = { | ||
reset() { | ||
this.delete('tags') | ||
}, | ||
/** | ||
* @TODO: filter with prop like | ||
* .filterWith('prop', prop => )... | ||
* | ||
* @TODO: this and weights | ||
* @see weights | ||
* @desc set levels for namespaces | ||
* @param {Object} namespaces | ||
* @type {FlipLog} @chainable | ||
*/ | ||
// namespaces(namespaces) {}, | ||
// namespace(namespace) { | ||
// return this.set('namespace', namespace) | ||
// }, | ||
/** | ||
* @alias lvl | ||
* @since 0.4.0 | ||
* @param {number} level | ||
* @return {[type]} | ||
*/ | ||
level(level) { | ||
return this.set('level', level).tags(level) | ||
}, | ||
/** | ||
* @TODO | ||
* - [ ] wildcard, best using [] instead | ||
* - [ ] use debugFor.js | ||
* - [ ] enableTags, disableTags | ||
* - [ ] handle keys here... | ||
* | ||
* {boolean} [verbose=true] if disabled & only a fn is passed as first param, only tags are returned | ||
* | ||
* @since 0.1.0 | ||
* @tutorial https://github.com/fliphub/fliplog/blob/master/README.md#-filtering | ||
* @param {string | Array<string> | Function} filters filter white or black flags | ||
* @return {FlipLog} @chainable | ||
*/ | ||
filter(filters) { | ||
toarr = toarr ? toarr : require('chain-able/deps/to-arr') | ||
let filter = toarr(filters) | ||
// @NOTE: keeps some maintainability with the old since desc is string, arr, of fn | ||
if (filter.length <= 1) { | ||
filter = filterFactory(filters) | ||
} | ||
const merged = toarr(filter).concat(this.get('filter') || []) | ||
// would need a double tap... | ||
// this.tap('filter', existing => existing || []) | ||
return this.set('filter', merged) | ||
}, | ||
/** | ||
* @alias tag | ||
* @since 0.1.0 | ||
* @desc tag the log for filtering when needed | ||
* @param {string | Array<string>} names tags to use | ||
* @return {FlipLog} @chainable | ||
*/ | ||
tags(names) { | ||
toarr = toarr ? toarr : require('chain-able/deps/to-arr') | ||
const tags = this.get('tags') || [] | ||
const updated = tags.concat(toarr(names)) | ||
return this.set('tags', updated) | ||
}, | ||
/** | ||
* @protected | ||
* @since 0.1.0 | ||
* @desc check if the filters allow the tags | ||
* @return {FlipLog} @chainable | ||
*/ | ||
_filter() { | ||
const filterer = this.get('filterer') | ||
const tags = this.get('tags') || [] | ||
const filters = this.get('filter') || [] | ||
const should = filterer.call(this, {filters, tags, instance: this}) | ||
if (should) return this.silent(true) | ||
return this | ||
// console.log(tags, filters) | ||
}, | ||
} | ||
return plugin | ||
} |
@@ -30,2 +30,3 @@ const ansi = require('./ansi') | ||
const table = require('./formatter') | ||
const templates = require('./text') | ||
const time = require('./time') | ||
@@ -66,2 +67,3 @@ const timer = require('./timer') | ||
table, | ||
templates, | ||
time, | ||
@@ -68,0 +70,0 @@ timer, |
@@ -1,8 +0,9 @@ | ||
const defaults = { | ||
keysColor: 'blue', | ||
dashColor: 'yellow', | ||
stringColor: 'italic', | ||
numberColor: 'green', | ||
const getDefaults = () => { | ||
return { | ||
keysColor: 'blue', | ||
dashColor: 'yellow', | ||
stringColor: 'italic', | ||
numberColor: 'green', | ||
} | ||
} | ||
module.exports = { | ||
@@ -14,3 +15,3 @@ // deps: { | ||
prettyjson(data = null, opts = {}) { | ||
const options = Object.assign({}, defaults, {}, opts) | ||
const options = Object.assign(getDefaults(), opts) | ||
const prettyjson = this.requirePkg('prettyjson') // eslint-disable-line | ||
@@ -34,3 +35,3 @@ if (data !== null) { | ||
opts = Object.assign({}, defaults, {}, opts) | ||
opts = Object.assign(getDefaults(), opts) | ||
@@ -37,0 +38,0 @@ // return this.data(this.prettyjson().render(data, opts)) |
@@ -10,2 +10,3 @@ module.exports = { | ||
* @todo alias as notification/notify | ||
* @TODO: put as formatter | ||
* | ||
@@ -12,0 +13,0 @@ * @param {string | boolean | any} options |
// presets | ||
function presetError(chain) { | ||
return chain.text('🚨 error:').color('bgRed.black').verbose(10) | ||
return chain.text(chain.chalk().bgRed.black('🚨 error: ') + '\n\n').verbose(10) | ||
} | ||
function presetWarning(chain) { | ||
return chain.text('⚠ warning:').color('bgYellow.black').verbose(10) | ||
return chain.text('⚠ warning: ').color('bgYellow.black').verbose(10) | ||
} | ||
@@ -18,2 +18,15 @@ function presetInfo(chain) { | ||
const ignored = [ | ||
'__defineGetter__', | ||
'__defineSetter__', | ||
'hasOwnProperty', | ||
'__lookupGetter__', | ||
'__lookupSetter__', | ||
'propertyIsEnumerable', | ||
'toString', | ||
'toLocaleString', | ||
'valueOf', | ||
'isPrototypeOf', | ||
] | ||
function presetHidden(chain) { | ||
@@ -31,2 +44,3 @@ /* prettier-ignore */ | ||
.concat(allKeys(data)) | ||
.filter(key => !ignored.includes(key)) | ||
.map(key => ({[key]: Object.getOwnPropertyDescriptor(data, key)})) | ||
@@ -33,0 +47,0 @@ |
@@ -0,10 +1,69 @@ | ||
const Chain = require('chain-able') | ||
const {OFF} = require('../deps') | ||
// const isNumber = require('chain-able/deps/is/number') | ||
// const replaceLength = /\[length\]\: (\d+|(.*?)(?=,|\'|\]|\s+)?)\s+?/i | ||
class Indent extends Chain { | ||
// increment | ||
indent(level) { | ||
if (level === 0) return this.set('indent', 0) | ||
return this.tap('indent', indent => indent + level) | ||
} | ||
// string repeat indent | ||
toString() { | ||
return ' '.repeat(this.get('indent')) | ||
} | ||
toNumber() { | ||
return this.get('indent') | ||
} | ||
} | ||
module.exports = { | ||
prettyformat(obj) { | ||
const format = this.requirePkg('pretty-format') | ||
return this.formatter(format).data(obj) | ||
return this.formatter(arg => this.requirePkg('pretty-format')(arg)).data( | ||
obj | ||
) | ||
}, | ||
fmtobj(obj) { | ||
const format = this.requirePkg('fmt-obj') | ||
return this.formatter(format).data(obj) | ||
return this.formatter(arg => this.requirePkg('fmt-obj')(arg)).data(obj) | ||
}, | ||
indentStr(str) { | ||
if (!this.has('indent')) this.indent(0) | ||
const indent = this.get('indent') | ||
return indent.toString() + str | ||
}, | ||
indent(level) { | ||
// if (!isNumber(level)) {} | ||
if (!this.has('indent')) { | ||
this.set('indent', new Indent(this)) | ||
} | ||
this.get('indent').indent(level) | ||
return this | ||
}, | ||
prettyobj(obj) { | ||
return this.formatter(arg => { | ||
const inspector = this.inspector() | ||
const strip = this.requirePkg('strip-ansi') || (x => x) | ||
return ( | ||
this.inspectorGadget() | ||
.inspect(arg, 5, {showHidden: false}) | ||
.split('\n') | ||
.map(data => this.indentStr(data)) | ||
.filter(data => data) | ||
// .map(data => data.replace(replaceLength, '')) | ||
.map(data => (data.endsWith(',') ? data.slice(0, -1) : data)) | ||
.map(data => data.replace(/[{}]/gim, '')) | ||
// .map(data => { | ||
// console.log({data}) | ||
// return data | ||
// }) | ||
.join('\n') | ||
) | ||
}) | ||
// .set('textFormatter', text => { | ||
// if (!text.endsWith('\n')) text += '\n' | ||
// return text | ||
// }) | ||
.data(obj) | ||
}, | ||
prettysize(bytes) { | ||
@@ -17,6 +76,49 @@ const pretty = this.module('prettysize')(bytes) | ||
}, | ||
tree(obj) { | ||
const format = this.requirePkg('treeify') | ||
return this.formatter(data => format.asTree(data, true)).data(obj) | ||
/** | ||
* @since 0.4.0 | ||
* @param {Object} [obj=null] data | ||
* @param {Object | null} [opts=null] options to pass into treeify | ||
* @return {FlipLog} @chainable | ||
*/ | ||
tree(obj = null, opts = null) { | ||
if (obj) this.data(obj) | ||
return this.formatter(data => { | ||
let arg = typeof opts === 'function' ? | ||
{lineCallback: opts, asLines: true} : | ||
opts | ||
const options = Object.assign( | ||
{ | ||
asTree: true, | ||
asLines: false, | ||
showValues: true, | ||
hideFunctions: false, | ||
lineCallback: false, | ||
color: true, | ||
}, | ||
arg | ||
) | ||
const {asLines, showValues, hideFunctions, lineCallback, color} = options | ||
const treeify = this.requirePkg('treeify') | ||
let result = asLines ? | ||
treeify.asLines(data, showValues, hideFunctions, lineCallback) : | ||
treeify.asTree(data, showValues, hideFunctions) | ||
// if (!this.get('text')) this.text('\n') | ||
// else this.text(this.get('text') + '\n\n') | ||
if (color && result && this.has('color')) { | ||
result = result | ||
.replace(/[├─│─┐└─]/gim, string => { | ||
const colored = this.getLogWrapFn()(string) // .replace(/undefined/, string) | ||
return colored | ||
// this.getColored(string) | ||
}) | ||
.trim() | ||
} | ||
return result ? '\n' + result : OFF | ||
}) | ||
}, | ||
} |
@@ -8,2 +8,22 @@ // https://www.youtube.com/watch?v=SwSle66O5sU | ||
/** | ||
* @alias logText | ||
* @since 0.4.0 | ||
* @return {string} text log | ||
*/ | ||
getText() { | ||
const text = this.logText() | ||
return text === OFF ? '' : text | ||
}, | ||
/** | ||
* @alias logData | ||
* @since 0.4.0 | ||
* @return {any} | ||
*/ | ||
getData() { | ||
const data = this.logData() | ||
return data === OFF ? undefined : data | ||
}, | ||
/** | ||
* @since 0.2.0 | ||
* @tutorial https://github.com/fliphub/fliplog#return | ||
@@ -10,0 +30,0 @@ * @return {ReturnVals} |
188
README.md
@@ -21,31 +21,18 @@ # ⛓🔈 fliplog | ||
[deepdiff]: https://www.npmjs.com/package/deep-diff | ||
[fmtobj]: https://github.com/queckezz/fmt-obj | ||
[sprintf]: https://github.com/alexei/sprintf.js | ||
[prettyformat]: https://github.com/facebook/jest/tree/master/packages/pretty-format | ||
[ava-prettyformat]: https://github.com/avajs/pretty-format | ||
[jest-diff]: https://github.com/facebook/jest | ||
[diff-match-patch]: https://code.google.com/archive/p/google-diff-match-patch/ | ||
[code-prettify]: https://github.com/google/code-prettify | ||
[chain-able]: https://github.com/fluents/chain-able | ||
[ansi]: https://github.com/TooTallNate/ansi.js | ||
[prettysize]: https://github.com/davglass/prettysize | ||
[listr]: https://github.com/samverschueren/listr | ||
[treeify]: https://github.com/notatestuser/treeify | ||
[js-traverse]: https://github.com/substack/js-traverse | ||
------- new ------ | ||
- [ ] ansii | ||
- [ ] prettyformat | ||
- [ ] fmtobj | ||
- [ ] cleaner | ||
- [ ] chalk | ||
- [ ] .colored | ||
- [ ] prettysize | ||
- [ ] catchAndThrow | ||
- [ ] listr | ||
```js | ||
var obj = {property: {}} | ||
obj.circularReference = obj | ||
obj[Symbol('foo')] = 'foo' | ||
obj.map = new Map() | ||
obj.map.set('prop', 'value') | ||
obj.array = [1, NaN, Infinity] | ||
log.prettyformat(obj).echo() | ||
const cleaner = log | ||
.cleaner(true) | ||
.keys([/array|circularReference|map|property/]) | ||
.data(obj) | ||
.clean() | ||
.echo() | ||
``` | ||
## usage | ||
@@ -63,3 +50,3 @@ ```bash | ||
fluent logging with verbose insight, colors, tables, emoji, filtering, spinners, progress bars, timestamps, capturing, stack traces, clearing, boxen, stringifying, code highlighting, notifications, beeping, sparkles, slow-mode, formatting, bar charts, & presets | ||
fluent logging with verbose insight, colors, tables, emoji, deep cleaning, filtering, spinners, progress bars, timestamps, capturing, stack traces, clearing, boxen, stringifying, code highlighting, notifications, beeping, sparkles, slow-mode, formatting, bar charts, & presets | ||
@@ -82,2 +69,4 @@ ## 🗝️ legend: | ||
- [☕ filtering](#-filtering) | ||
- [🔢 level](#-level) | ||
- [🎯 matcher](#-matcher) | ||
- [🚩 flags](#filter-tags) | ||
@@ -88,5 +77,4 @@ - [filter](#filter--tags) | ||
- [⬛ table](#-tables) | ||
- [🛁 cleaner](#-cleaner) | ||
- [⚖️ diff](https://github.com/fliphub/fliplog/blob/master/README.md#️-diff) | ||
- [row](https://github.com/fliphub/fliplog/blob/master/README.md#️-diff) | ||
- [diffs](https://github.com/fliphub/fliplog/blob/master/README.md#️-diff) | ||
- [🌀 spinner](#-spinner) | ||
@@ -114,2 +102,3 @@ - [multi](#-spinner) | ||
- [🎢 fun](#-fun) | ||
- [🌲 tree](#-tree) | ||
- [📊 bar chart](#-bar) | ||
@@ -124,3 +113,3 @@ - [📦 box](#-box) | ||
- [⏲ timer](#-timer) | ||
- [⚡ performance](#-performance) | ||
- [⚡ performance](#-performance) (_lightweight configurable dependencies_) | ||
- [resources](#-resources) | ||
@@ -138,5 +127,17 @@ | ||
🆕 [lightweight configurable dependencies](#-performance) | ||
# 🆕 NEW! | ||
> 📝📚 all of these new ones need more docs | ||
[📖 read the wip docs for new stuff on the wiki](https://github.com/fliphub/fliplog/wiki/new) | ||
### `+` == `.echo` | ||
```js | ||
log.italic('so short!')+ | ||
// ^ same as `log.italic('so short!').echo()` | ||
``` | ||
## 🎀 stringifying | ||
@@ -262,2 +263,35 @@ ### json | ||
### 🔢 level | ||
filter by log level as a number with simple [comparison operators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators) | ||
```js | ||
log.filter('>= 1') | ||
log.level(1).bold('above 1... success').echo() | ||
log.level(0).bold('not above 1...').echo() | ||
``` | ||
### 🎯 matcher | ||
filter using an `Array` made up of `Function`s, `String`s, and `RegExp`s! | ||
```js | ||
log.filter(['canada*']) | ||
log.tag('canada-eh').white('canadian, pass.').echo() | ||
``` | ||
more advanced | ||
```js | ||
log.filter(['eh*', '!warm', tag => (/ez/).test(tag)]) | ||
log.tag('eh').underline('eh').echo() | ||
log.tag('warm').red('warm').echo() | ||
log.tag('ez').yellow('ez').echo() | ||
``` | ||
❗ important to note, if only a function is passed in, it will have the entire log instance passed to the argument, rather than the array of tags (for compatibility & simplicity.) | ||
### filter & tags | ||
- `verbose` enables everything | ||
@@ -267,3 +301,2 @@ - `silent` silences everything | ||
### filter & tags | ||
```js | ||
@@ -324,20 +357,58 @@ log | ||
## ⚖️ diff | ||
using [deep-diff](https://www.npmjs.com/package/deep-diff), you can compare before and after data differences as tables. Data will be cloned so it can be mutated and then compared. | ||
![https://github.com/avajs/ava/raw/master/media/magic-assert-combined.png] | ||
(_uses a fork of [ava-format][ava-format] which is a fork of [jest-diff][jest-diff] which is a fork of [google's diff-match-patch][diff-match-patch]_) | ||
Compare two pieces of data. Data will be cloned so it can be mutated if needed, and then compared. | ||
```js | ||
const royalty = { | ||
posh: true, | ||
} | ||
const lowlyPeasant = { | ||
pauper: true, | ||
} | ||
let oneOneTwoTwo = 'one-one was a race horse 🐎 ' | ||
log.diff(oneOneTwoTwo) | ||
log.diff(oneOneTwoTwo + '... two-two was one, two.') | ||
log.echo() | ||
``` | ||
(_previously [deep-diff][deep-diff] & cli-table was used._) | ||
```js | ||
const royalty = {posh: true} | ||
const lowlyPeasant = {pauper: true} | ||
log.diff(royalty) | ||
const abomination = deepmerge(royalty, lowlyPeasant) | ||
const abomination = Object.assign(royalty, lowlyPeasant) | ||
log.diff(abomination) | ||
log.echo() | ||
``` | ||
log.diffs().echo() | ||
## 🛁 cleaner | ||
extremely powerful tool built with [chain-able][chain-able] using a fork of [js-traverse][js-traverse] | ||
can take next-to-unusable output such as this ![garbage](https://user-images.githubusercontent.com/4022631/27126483-7bd3e21a-50ac-11e7-840a-ea49d3de5176.gif) | ||
and clean it usable | ||
![cleaned](https://user-images.githubusercontent.com/4022631/27126552-b2a512a0-50ac-11e7-966d-9b92803503f8.png) | ||
...or you could clean out certain phrases from every log | ||
```js | ||
var obj = {property: {}} | ||
obj.circularReference = obj | ||
obj[Symbol('foo')] = 'foo' | ||
obj.map = new Map() | ||
obj.map.set('prop', 'value') | ||
obj.array = [1, NaN, Infinity] | ||
log.prettyformat(obj).echo() | ||
const cleaner = log | ||
.cleaner(true) | ||
.keys([/array|circularReference|map|property/]) | ||
.data(obj) | ||
.clean() | ||
.echo() | ||
``` | ||
## 🌀 spinner | ||
@@ -526,3 +597,2 @@ | ||
## ®️ register | ||
@@ -689,2 +759,25 @@ | ||
## 🌲 tree | ||
<img width="563" alt="screen shot 2017-06-13 at 11 24 29 pm" src="https://user-images.githubusercontent.com/4022631/27118316-8e138d80-508f-11e7-8ce5-d383678ca2a0.png"> | ||
```js | ||
log | ||
.color('green') | ||
.text('🌲 treeify') | ||
.tree({ | ||
oranges: { | ||
mandarin: { | ||
clementine: null, | ||
tangerine: 'so cheap and juicy!', | ||
}, | ||
}, | ||
apples: { | ||
'gala': null, | ||
'pink lady': null, | ||
}, | ||
}) | ||
.echo() | ||
``` | ||
### 🎇 sparkly | ||
@@ -833,2 +926,5 @@ | ||
> ✍ interesting to note, this is how most plugins do their formatting | ||
```js | ||
@@ -866,3 +962,3 @@ function cb(data) { | ||
the dependencies that are installed can be configured by a package json config, or by using magic npm tags which contain the configs. | ||
<!-- the dependencies that are installed can be configured by a package json config, or by using magic npm tags which contain the configs. | ||
@@ -889,7 +985,7 @@ the available options are: | ||
[see the full preset list](https://github.com/fliphub/fliplog/wiki/dynamic-dependencies) | ||
[see the full preset list](https://github.com/fliphub/fliplog/wiki/dynamic-dependencies) --> | ||
#### requiring | ||
all non-core dependencies are required when functions are called. this way, only the used-functionality is loaded. | ||
all non-core dependencies are required when functions are called **& the filtering passes**. this way, only the used-functionality is loaded. | ||
@@ -896,0 +992,0 @@ additionally, almost all of the functions are not formatted until `.echo()`, so they will not have dependencies loaded when echoing is false which means code does not have to be changed for production. |
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
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 4 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
3048045
227
26784
0
1001
20
4
+ Addedchain-able@3.0.0(transitive)
- Removedchain-able@1.0.1(transitive)
Updatedchain-able@3.0.0