all files / src/ dumper.js

82.76% Statements 48/58
70.83% Branches 17/24
100% Functions 4/4
82.76% Lines 48/58
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150                         17×                     18×   18× 18×   18×           15×         16×       16× 16× 16×   16×                                   31× 31×   31× 31×               11× 11×     11×     12× 12× 12×                       31×                         16×               16× 11×            
const kindOf = require('kind-of');
const {red, cyan, blue, black, green, magenta} = require('kleur');
 
/**
 * Generate structured information about one or more objects that
 * includes each item type and value.
 *
 * @author Zeeshan Ahmad <ziishaned@gmail.com>
 */
class Dumper {
  /**
   * @param {int} indentCount Number of spaces to indent the object with
   */
  constructor(indentCount = 4) {
    this.spaces = ' '.repeat(indentCount);
  }
 
  /**
   * Iterates over each property of the provided object and make the output.
   *
   * @param {*} toDump
   * @param {string|null} indent
   * @return {string}
   */
  generateDump(toDump, indent = '') {
    let dump = '';
 
    let startWith = '';
    let endWith = '';
 
    switch (kindOf(toDump)) {
      case 'array':
        startWith = `${black.bold('array')} (size=${toDump.length}) [\n`;
        endWith = `${indent}]`;
        break;
      case 'object':
        startWith = `${black.bold('object')} (size=${
          Object.keys(toDump).length
        }) {\n`;
        endWith = `${indent}}`;
        break;
      default:
        return this.prepareValueDump(indent, toDump);
    }
 
    // For each key of the object, keep
    // preparing the inspection output
    for (let itemKey in toDump) {
      Iif (!toDump.hasOwnProperty(itemKey)) {
        continue;
      }
 
      const originalValue = toDump[itemKey];
      const originalParamType = kindOf(originalValue);
      const valueDump = this.prepareValueDump(indent, originalValue);
 
      dump += this.makeArrowString(
        originalParamType,
        indent,
        itemKey,
        valueDump
      );
    }
 
    return startWith + dump + endWith;
  }
 
  /**
   * Prepare the dump output for the given value
   *
   * @param indent
   * @param originalValue
   * @return {*|string}
   */
  prepareValueDump(indent, originalValue) {
    let displayType = '';
    let displayValue = '';
 
    const paramType = kindOf(originalValue);
    switch (paramType) {
      case 'array':
      case 'object':
        displayType = '';
        displayValue = this.generateDump(
          originalValue,
          `${indent}${this.spaces}`
        );
        break;
      case 'boolean':
        displayType = 'boolean';
        displayValue = originalValue ? magenta('true') : magenta('false');
        break;
      case 'string':
        displayType = 'string';
        displayValue = `${red(`"${originalValue}"`)} (length=${
          originalValue.length
        })`;
        break;
      case 'null':
        displayValue = `${blue('null')}`;
        break;
      case 'number':
        displayType = Number.isInteger(originalValue) ? 'int' : 'float';
        displayValue = green(originalValue);
        break;
      case 'function':
        displayType = '';
        displayValue = 'function () {}';
        break;
      case 'regexp':
        displayType = '';
        displayValue = `${blue(originalValue)}`;
        break;
      default:
        displayType = '';
        displayValue = originalValue;
        break;
    }
 
    return `${cyan(displayType)} ${displayValue}`;
  }
 
  /**
   * Make the arrow string.
   *
   * @param {string} paramType
   * @param {string} indent
   * @param {string|number} key
   * @param {*} valueDump
   * @return {string}
   */
  makeArrowString(paramType, indent, key, valueDump) {
    Iif (paramType === 'array') {
      if (typeof key === 'string') {
        return `${indent}${this.spaces}'${key}' => ${valueDump},\n`;
      }
 
      return `${indent}${this.spaces}[${key}] => ${valueDump},\n`;
    }
 
    if (Number.isInteger(parseInt(key))) {
      return `${indent}${this.spaces}[${key}] => ${valueDump},\n`;
    }
 
    return `${indent}${this.spaces}'${key}' => ${valueDump},\n`;
  }
}
 
module.exports = Dumper;