NeuraLegion/sectester-js

View on GitHub
packages/reporter/src/formatters/PlainTextFormatter.ts

Summary

Maintainability
A
0 mins
Test Coverage
A
100%
import { Formatter } from '../lib';
import { Comment, Issue } from '@sectester/scan';
import { format } from 'util';

export class PlainTextFormatter implements Formatter {
  private readonly BULLET_POINT = '●';
  private readonly NEW_LINE = '\n';
  private readonly TABULATION = '\t';

  public format(issue: Issue): string {
    const {
      link,
      name,
      severity,
      remedy,
      details,
      comments = [],
      resources = []
    } = issue;
    const template = this.generateTemplate({
      extraInfo: comments.length > 0,
      references: resources.length > 0
    });

    const message = format(
      template,
      link,
      name,
      severity,
      remedy,
      details,
      this.formatList(comments, comment => this.formatExtraInfo(comment)),
      this.formatList(resources)
    );

    return message.trim();
  }

  private generateTemplate(options: {
    extraInfo: boolean;
    references: boolean;
  }): string {
    return `
Issue in Bright UI:   %s
Name:                 %s
Severity:             %s
Remediation:
%s
Details:
%s${options.extraInfo ? `\nExtra Details:\n%s` : ''}${
      options.references ? `\nReferences:\n%s` : ''
    }`.trim();
  }

  private formatExtraInfo({ headline, text = '', links = [] }: Comment) {
    const footer = links.length
      ? this.combineList(['Links:', this.formatList(links)])
      : '';
    const blocks = [text, footer].map(x => this.indent(x));
    const document = this.combineList(blocks);

    return this.combineList([headline, document]);
  }

  private indent(x: string, length: number = 1) {
    const lines = x.split(this.NEW_LINE);

    return this.combineList(
      lines.map(line => `${this.TABULATION.repeat(length)}${line}`)
    );
  }

  private formatList<T>(list: T[], map?: (x: T) => string): string {
    const items = list.map(
      x => `${this.BULLET_POINT} ${typeof map == 'function' ? map(x) : x}`
    );

    return this.combineList(items);
  }

  private combineList(list: string[], sep?: string): string {
    return list.join(sep ?? this.NEW_LINE);
  }
}