├── .gitignore ├── LICENSE.md ├── README.md ├── demo.js ├── index.js ├── log_table.js ├── package.json ├── screenshot.png └── test.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | npm-debug.log 4 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Further resources on the 3-clause BSD license 2 | Note: This license has also been called the "New BSD License" or "Modified BSD License". See also the 2-clause BSD License. 3 | 4 | Copyright 2017 Mohsen Azimi 5 | 6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 11 | 12 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Better Console 2 | 3 | ![Screenshot](https://raw.github.com/mohsen1/better-console/master/screenshot.png) 4 | 5 | ## Installation 6 | 7 | Use NPM 8 | 9 | ```shell 10 | $ npm install better-console 11 | ``` 12 | 13 | ## A better console for Node.js 14 | 15 | 16 | `better-console` is a drop-in replacement for node's default console which 17 | gives you colors and more methods in console. 18 | 19 | ## How to use it 20 | 21 | You can override `console` object itself or assign better console to another variable. It's completely safe to override the native console object because better console calls native console methods for methods that are already available in it. 22 | 23 | ``` 24 | var console = require('better-console'); 25 | 26 | console.log("This is a log information"); 27 | console.warn("Warning!"); 28 | console.info("Information"); 29 | console.table([ [1,2], [3,4] ]); 30 | console.time("Timer"); 31 | console.timeEnd("Timer"); 32 | console.dir(myObject); 33 | 34 | ``` 35 | 36 | ## Methods 37 | 38 | ### `console.log`, `console.warn`, `console.error`, `console.info`, `console.debug`, `console.dir`, `console.trace` 39 | These methods work exactly same as native console methods but with colors for `warn`, `info` or `error` 40 | 41 | ### `console.clear` 42 | 43 | Clears the screen 44 | 45 | ### `console.table` 46 | 47 | Draws a table of data if a 2d array or object passed to it 48 | 49 | ### `console.time` 50 | 51 | Creates a new timer under the given name. Call `console.timeEnd(name)` 52 | with the same name to stop the timer and print the time elapsed. 53 | 54 | ### `console.timeEnd` 55 | 56 | Stops a timer created by a call to console.time(name) and write the time 57 | 58 | ### `console.trace` 59 | 60 | Prints a stack trace of JavaScript execution at the point 61 | where it is called. The stack trace details the functions on the stack, 62 | as well as the values that were passed as arguments to each function. 63 | 64 | ### `console.count` 65 | 66 | Writes number of times each argument is called with blue color 67 | 68 | ## TODOs 69 | 70 | * Use Unicode icons to mimic browser console icons in OSX 71 | * Make `console.trace` more detailed with V8 flags 72 | -------------------------------------------------------------------------------- /demo.js: -------------------------------------------------------------------------------- 1 | var console = require('./index'); 2 | 3 | console.log('> console.info("This is information")'); 4 | console.info("This is information"); 5 | 6 | console.log(''); 7 | console.log('> console.error("Oops!")'); 8 | console.error("Oops!"); 9 | 10 | console.log(''); 11 | console.log("> var arr = ["); 12 | console.log(" ['a','b','c','d'],"); 13 | console.log(" ['e','f','h','j']"); 14 | console.log(" ];"); 15 | console.log("> console.table(arr);"); 16 | 17 | var arr = [ 18 | ['a','b','c','d'], 19 | ['e','f','h','j'] 20 | ]; 21 | console.table(arr); 22 | console.log('> '); 23 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var chalk = require('chalk'); 2 | var util = require('util'); 3 | var logTable = require('./log_table'); 4 | var countBuffer = {}; 5 | 6 | function logWithColor(color, args, isError){ 7 | var log = util.format.apply(this, args); 8 | if(isError) 9 | console.error(chalk[color](log)); 10 | else 11 | console.log(chalk[color](log)); 12 | } 13 | 14 | 15 | module.exports = { 16 | 17 | // Writes a message to the console. You may pass as many arguments as 18 | // you'd like, and they will be joined together in a space-delimited line. 19 | // The first argument to log may be a string containing 20 | // printf-like string substitution patterns. 21 | log: function(){ 22 | console.log.apply(this, arguments); 23 | }, 24 | 25 | // Writes a message to the console with blue color 26 | info: function(){ 27 | logWithColor('blue', arguments); 28 | }, 29 | 30 | // Writes a message to the console with yellow color 31 | warn: function(){ 32 | logWithColor('yellow', arguments, true); 33 | }, 34 | 35 | // Writes a message to the console with red color 36 | error: function(){ 37 | logWithColor('red', arguments, true); 38 | }, 39 | 40 | // Writes a message to the console with regular color 41 | debug: function(){ 42 | console.log.apply(this, arguments); 43 | }, 44 | 45 | // Prints an interactive listing of all properties of the object. 46 | dir: function(){ 47 | console.dir.apply(this, arguments); 48 | }, 49 | 50 | // Clears the terminal buffer 51 | clear: function(){ 52 | process.stdout.write('\u001B[2J\u001B[0;0f'); 53 | }, 54 | 55 | // Prints a stack trace of JavaScript execution at the point 56 | // where it is called. The stack trace details the functions on the stack, 57 | // as well as the values that were passed as arguments to each function. 58 | trace: function(){ 59 | console.trace.apply(this, arguments); 60 | }, 61 | 62 | // Does nothing if first argument is truly. If first argument is falsy 63 | // it Writes red warning and throws assertion error 64 | assert: function(assertion){ 65 | // todo: for now we are cheating, it's just console.erroring and then 66 | // leave console.asset to do it's job. actual todo: print what 67 | // console.assert prints just make first line red 68 | if (!assertion){ 69 | logWithColor('red', ['AssertionError: false == true']); 70 | console.assert(assertion); 71 | } 72 | }, 73 | 74 | // Writes number of times each argument is called with blue color 75 | count: function(toCount){ 76 | var toCountString = toCount.toString && toCount.toString(), 77 | log; 78 | 79 | if (countBuffer[toCountString] == null){ 80 | countBuffer[toCountString] = 0; 81 | }else{ 82 | countBuffer[toCountString] += 1; 83 | } 84 | 85 | log = toCountString + ': ' + countBuffer[toCountString]; 86 | logWithColor('blue', [log]); 87 | }, 88 | 89 | // Creates a new timer under the given name. Call console.timeEnd(name) 90 | // with the same name to stop the timer and print the time elapsed.. 91 | time: function(){ 92 | console.time.apply(this, arguments); 93 | }, 94 | 95 | // Stops a timer created by a call to console.time(name) and writes the time 96 | // elapsed. 97 | timeEnd: function(){ 98 | console.timeEnd.apply(this, arguments); 99 | }, 100 | 101 | // draws a table of elements inside of a 2d array or object 102 | table: function(){ 103 | logTable.apply(this, arguments); 104 | } 105 | }; 106 | 107 | 108 | -------------------------------------------------------------------------------- /log_table.js: -------------------------------------------------------------------------------- 1 | var Table = require('cli-table'); 2 | 3 | module.exports = exports = function logTable(data){ 4 | if(typeof data !== 'object' || data === null){ 5 | console.log(''); 6 | return; 7 | } 8 | 9 | if(typeof data[Object.keys(data)[0]] !== 'object' || data[Object.keys(data)[0]] === null){ 10 | console.log(''); 11 | return; 12 | } 13 | 14 | 15 | var firstKey = Object.keys(data)[0]; 16 | var firstObject = data[firstKey]; 17 | var thead = Object.keys(firstObject); 18 | thead.unshift('(index)'); 19 | var colWidths = thead.map(calculateColWidth); 20 | 21 | 22 | Object.keys(data).forEach(function(rowKey){ 23 | var row = data[rowKey]; 24 | 25 | if(typeof row == 'object'){ 26 | Object.keys(row).forEach(function(k,i){ 27 | var width = calculateColWidth (row[k]); 28 | if(colWidths[i+1] < width) 29 | colWidths[i+1] = width; 30 | }); 31 | } 32 | }); 33 | 34 | var table = new Table({ 35 | head: thead, 36 | colWidths: colWidths 37 | }); 38 | 39 | Object.keys(data).forEach(function(rowKey){ 40 | var row = data[rowKey]; 41 | var rowValues = []; 42 | 43 | if(typeof row == 'object'){ 44 | rowValues = Object.keys(row).map(function(k){ 45 | return row[k]; 46 | }); 47 | } 48 | table.push([rowKey].concat(rowValues)); 49 | }); 50 | 51 | console.log(table.toString()); 52 | 53 | function calculateColWidth (item) { 54 | var MAX_COL_WIDTH = 28; 55 | var MIN_COL_WIDTH = 3; 56 | var width = null; 57 | 58 | if(item.toString){ 59 | if(item.toString().length > MAX_COL_WIDTH) 60 | width = MAX_COL_WIDTH; 61 | if(item.toString().length < MIN_COL_WIDTH) 62 | width = MIN_COL_WIDTH; 63 | else if(!width) 64 | width = item.toString().length; 65 | }else{ 66 | width = MAX_COL_WIDTH; 67 | } 68 | 69 | return width + 2; 70 | } 71 | }; 72 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "better-console", 3 | "version": "1.0.1", 4 | "description": "A better console for Node.js", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "node test.js" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git://github.com/mohsen1/better-console" 12 | }, 13 | "keywords": [ 14 | "console" 15 | ], 16 | "author": "Mohsen Azimi", 17 | "license": "BSD", 18 | "dependencies": { 19 | "chalk": "^1.1.3", 20 | "cli-table": "~0.3.1" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohsen1/better-console/dbf97a71174555ec211c2a29b2fcfc142d2d71f8/screenshot.png -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | var console = require('./index'); 2 | 3 | console.log('Something'); 4 | console.clear(); 5 | console.info('Console should be clean now'); 6 | 7 | console.log('Log'); 8 | console.log('A string'); 9 | console.log('A manipulated string (%s) with number: %d', 'apple', 42); 10 | console.log(1); 11 | console.log(true); 12 | console.log({ me: 1 }); 13 | console.log([1, 2, 3]); 14 | console.log(''); 15 | 16 | 17 | console.info('Information'); 18 | console.info('A string'); 19 | console.info('A manipulated string (%s) with number: %d', 'apple', 42); 20 | console.info(1); 21 | console.info(true); 22 | console.info({ me: 1 }); 23 | console.info([1, 2, 3]); 24 | console.info(''); 25 | 26 | 27 | console.warn('Warning'); 28 | console.warn('A string'); 29 | console.warn('A manipulated string (%s) with number: %d', 'apple', 42); 30 | console.warn(1); 31 | console.warn(true); 32 | console.warn({ me: 1 }); 33 | console.warn([1, 2, 3]); 34 | console.warn(''); 35 | 36 | 37 | console.error('Error'); 38 | console.error('A string'); 39 | console.error('A manipulated string (%s) with number: %d', 'apple', 42); 40 | console.error(1); 41 | console.error(true); 42 | console.error({ me: 1 }); 43 | console.error([1, 2, 3]); 44 | console.error(''); 45 | 46 | 47 | 48 | console.count('me'); 49 | console.count('me'); 50 | 51 | var arr = [ 52 | ['a', 'b', 'c', 'd'], 53 | ['e', 'f', 'h', 'j'] 54 | ]; 55 | console.table(arr); 56 | 57 | var obj = { 58 | SF: { total_population: 1000 }, 59 | LA: { total_population: 2000 }, 60 | NY: { total_population: 3000 } 61 | }; 62 | console.table(obj); 63 | 64 | console.table([ 65 | { a: 1, b: 2, c: 3 }, 66 | { a: 1, b: 2, c: 3, d: 4 }, 67 | { k: 11, f: 22 }, 68 | { a: 1, b: 2, c: 3 } 69 | ]); 70 | 71 | var obj = { 72 | SF: { f: 300, m: 100 }, 73 | LA: { f: 200, m: 200 }, 74 | NY: { f: 400, m: 500 } 75 | }; 76 | console.table(obj); 77 | 78 | 79 | var arr = [ 80 | ['a', 'b', 'c', 'd'], 81 | ['e', 'f', 'hoooohoooohooooo', 'j'] 82 | ]; 83 | console.table(arr); 84 | console.table(null); 85 | console.table([null]); 86 | 87 | console.assert(true); 88 | console.assert(false); 89 | --------------------------------------------------------------------------------