All files / if-csv/util helpers.ts

100% Statements 44/44
100% Branches 16/16
100% Functions 5/5
100% Lines 42/42

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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 881x 1x   1x   1x     1x   1x 1x         1x 2x 2x   2x 1x     1x           1x 5x 5x 5x 5x   5x 15x 11x 5x   11x     15x 15x 15x   15x 5x     15x   15x 3x   12x 2x   10x           15x 5x 10x                 5x   5x   5x 1x     4x    
import * as fs from 'fs/promises';
import {stringify} from 'csv-stringify/sync';
import {PluginParams} from '@grnsft/if-core/types';
import {ERRORS} from '@grnsft/if-core/utils';
 
import {load} from '../../common/lib/load';
 
import {CsvOptions} from '../types/csv';
import {STRINGS} from '../config';
 
const {FAILURE_MESSAGE_OUTPUTS} = STRINGS;
const {ManifestValidationError} = ERRORS;
 
/**
 * Gets the manifest data if `outputs` is present in it.
 */
export const getManifestData = async (manifest: string) => {
  const {rawManifest} = await load(manifest);
  const {children} = rawManifest.tree;
 
  if (children?.child?.outputs || children?.['child-0']?.outputs) {
    return rawManifest;
  }
 
  throw new ManifestValidationError(FAILURE_MESSAGE_OUTPUTS);
};
 
/**
 * Generates a CSV file based on the provided tree structure, context, output path, and params.
 */
export const generateCsv = async (options: CsvOptions) => {
  const {tree, context, outputPath, params} = options;
  const columns = ['Path'];
  const matrix = [columns];
  const aggregationIsEnabled = !!context.aggregation;
 
  const traverseTree = (node: any, params: string, path = 'tree') => {
    if (node.aggregated) {
      if (path === 'tree') {
        columns.push('Aggregated');
      }
      matrix.push([`${path}.${params}`, node.aggregated[params]]);
    }
 
    if (node.outputs) {
      node.outputs.forEach((output: PluginParams) => {
        const {timestamp} = output;
 
        if (!columns.includes(timestamp)) {
          columns.push(timestamp);
        }
 
        const lastRow = matrix[matrix.length - 1];
 
        if (aggregationIsEnabled) {
          lastRow.push(output[params]);
        } else {
          if (matrix.length === 1 || lastRow.length === columns.length) {
            matrix.push([`${path}.${params}`, output[params]]);
          } else {
            lastRow.push(output[params]);
          }
        }
      });
    }
 
    if (node.children) {
      Object.keys(node.children).forEach(childKey => {
        traverseTree(
          node.children![childKey],
          params,
          `${path}.children.${childKey}`
        );
      });
    }
  };
 
  traverseTree(tree, params);
 
  const csvString = stringify(matrix, {columns});
 
  if (!outputPath) {
    return csvString;
  }
 
  return await fs.writeFile(`${outputPath}.csv`, csvString);
};