export function json2HTML()

in packages/sdk/shared/src/utils/json2HTML.ts [33:93]


export function json2HTML(obj: { [key: string]: any }, isDiff = false): string {
  if (!obj) {
    return null;
  }
  let json = JSON.stringify(obj, null, 2);
  // Hide ampersands we don't want replaced
  json = json.replace(/&(amp|apos|copy|gt|lt|nbsp|quot|#x?\d+|[\w\d]+);/g, '\x01');
  // Escape remaining ampersands and other HTML special characters
  json = json
    .replace(/&/g, '&')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;');
  // Restore hidden ampersands
  // eslint-disable-next-line no-control-regex
  json = json.replace(/\x01/g, '&');
  // Match all the JSON parts and add theming markup
  let parentClassName = '';
  json = json.replace(
    // eslint-disable-next-line no-useless-escape
    /"(\\u[a-fA-F0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
    match => {
      // Default to "number"
      let className = isDiff ? 'default' : 'number';
      // Detect the type of the JSON part
      // string value or field name
      if (match.startsWith('"')) {
        if (match.endsWith(':')) {
          className = isDiff ? 'default' : 'key';
          if (isDiff) {
            if (match.substr(1, 1) === '+') {
              parentClassName = className = 'added';
            }
            if (match.substr(1, 1) === '-') {
              parentClassName = className = 'removed';
            }
          }
        } else {
          className = isDiff ? 'default' : 'string';
        }
      } else if (!isDiff && /true|false/.test(match)) {
        className = 'boolean';
      } else if (!isDiff && /null/.test(match)) {
        className = 'null';
      }
      const isKey = className === 'key';
      if (parentClassName && parentClassName !== className) {
        className = parentClassName;
        parentClassName = '';
      }
      if (isKey) {
        // Don't color the : character after the key
        const exec = /"(.*)":\s*/.exec(match);
        return `<span class="json-${className}">"${exec[1]}"</span>:`;
      } else {
        return `<span class="json-${className}">${match}</span>`;
      }
    }
  );

  return json;
}