prettyjson.js

Package for formatting JSON data in a coloured YAML-style, perfect for CLI output

Export package

module.exports = exports;

Module dependencies

var colors = require('colors');
var Utils  = require('./utils');
var fs = require('fs');

Package version

exports.version = JSON.parse(fs.readFileSync(__dirname + '/../package.json', 'utf8')).version;

Render function

Parameters:

  • data: Data to render
  • options: Hash with different options to configure the parser
  • indentation: Base indentation of the parsed output

Example of options hash:

{
  emptyArrayMsg: '(empty)', // Rendered message on empty strings
  keysColor: 'blue',        // Color for keys in hashes
  dashColor: 'red',         // Color for the dashes in arrays
  stringColor: 'grey',      // Color for strings
  defaultIndentation: 2     // Indentation on nested objects
}
exports.render = function render(data, options, indentation) {
  "use strict";

Default value for the indentation param

  indentation = indentation || 0;

Default values for the options

  options = options || {};
  options.emptyArrayMsg = options.emptyArrayMsg || '(empty array)';
  options.keysColor = options.keysColor || "green";
  options.dashColor = options.dashColor || "green";
  options.defaultIndentation = options.defaultIndentation || 2;

  options.stringColor = options.stringColor || null;

Initialize the output (it's an array of lines)

  var output = [];

Helper function to detect if an object can be serializable directly

  var isSerializable = function(input) {
    if (typeof input === 'string' || typeof input === 'boolean' ||
        typeof input === 'number' || input === null) {
      return true;
    }
    return false;
  };

  var addColorToData = function(input) {
    if (typeof input === 'string') {

Print strings in regular terminal color

      return options.stringColor ? input[options.stringColor] : input;
    }

    if (input === true) {
      return (input+'').green;
    }
    if (input === false) {
      return (input+'').red;
    }
    if (input === null) {
      return (input+'').grey;
    }
    if (typeof input === 'number') {
      return (input+'').blue;
    }
    return (input+'');
  };

Render a string exactly equal

  if (isSerializable(data)) {
    output.push(Utils.indent(indentation) + addColorToData(data));
  }
  else if (Array.isArray(data)) {

If the array is empty, render the emptyArrayMsg

    if (data.length === 0) {
      output.push(Utils.indent(indentation) + options.emptyArrayMsg);
    } else {
      data.forEach(function(element) {

Prepend the dash at the begining of each array's element line

        var line = Utils.indent(indentation) + ('- ')[options.dashColor];

If the element of the array is a string, render it in the same line

        if (typeof element === 'string') {
          line += exports.render(element, options);
          output.push(line);

If the element of the array is an array or object, render it in next line

        } else {
          output.push(line);
          output.push(
            exports.render(element, options, indentation + options.defaultIndentation)
          );
        }
      });
    }
  }
  else if (typeof data === 'object') {

Get the size of the longest index to render all the values on the same column

    var maxIndexLength = Utils.getMaxIndexLength(data);
    var key;

    for(var i in data) {

Prepend the index at the beginning of the line

      key = Utils.indent(indentation) + (i + ': ')[options.keysColor];

If the value is serializable, render it in the same line

      if (isSerializable(data[i])) {
        key += exports.render(data[i], options, maxIndexLength - i.length);
        output.push(key);

If the index is an array or object, render it in next line

      } else {
        output.push(key);
        output.push(
          exports.render(data[i], options, indentation + options.defaultIndentation)
        );
      }
    }
  }

Return all the lines as a string

  return output.join('\n');
};

Render from string function

Parameters:

  • data: Data to render as a string
  • options: Hash with different options to configure the parser
  • indentation: Base indentation of the parsed output

Example of options hash:

{
  emptyArrayMsg: '(empty)', // Rendered message on empty strings
  keysColor: 'blue',        // Color for keys in hashes
  dashColor: 'red',         // Color for the dashes in arrays
  defaultIndentation: 2     // Indentation on nested objects
}
exports.renderString = function renderString(data, options, indentation) {
  "use strict";

  var output = '';
  var parsedData;

If the input is not a string or if it's empty, just return an empty string

  if (typeof data !== 'string' || data === '') {
    return '';
  }

Remove non-JSON characters from the beginning string

  if (data[0] !== '{' && data[0] !== '[') {
    var beginingOfJson;
    if (data.indexOf('{') === -1) {
      beginingOfJson = data.indexOf('[');
    } else if (data.indexOf('[') === -1) {
      beginingOfJson = data.indexOf('{');
    } else {
      beginingOfJson = data.indexOf('{') < data.indexOf('[') ? data.indexOf('{') : data.indexOf('[');
    }
    output += data.substr(0, beginingOfJson) + "\n";
    data = data.substr(beginingOfJson);
  }

  try {
    parsedData = JSON.parse(data);
  } catch (e) {

Return an error in case of an invalid JSON

    return 'Error:'.red + ' Not valid JSON!';
  }

Call the real render() method

  output += exports.render(parsedData, options);
  return output;
};