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 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 | 2x 2x 2x 2x 2x 2x 2x 1x 7x 6x 6x 6x 2x 4x 4x 4x 1x 7x 1x 6x 1x 7x 7x 7x 4x 4x 12x 10x 4x 10x 12x 12x 12x 12x 4x 12x 12x 3x 9x 1x 8x 12x 4x 8x 4x 4x 1x | import {writeFile} from 'fs/promises';
import {stringify} from 'csv-stringify/sync';
import {ERRORS} from '@grnsft/if-core/utils';
import {PluginParams} from '@grnsft/if-core/types';
import {STRINGS} from '../config';
import {Context} from '../types/manifest';
const {ExhaustOutputArgError} = ERRORS;
const {CSV_EXPORT, OUTPUT_REQUIRED, EXPORTING_TO_CSV_FILE} = STRINGS;
/**
* Extension to IF that outputs the tree in a CSV format.
*/
export const ExportCSV = () => {
const parseOutputAndField = (outputPath: string) => {
const validatedPath = validateOutputPath(outputPath);
const paths = validatedPath.split('#');
const criteria = paths[paths.length - 1];
if (paths.length <= 1 || !criteria) {
throw new ExhaustOutputArgError(CSV_EXPORT);
}
const output = paths.slice(0, paths.length - 1).join('');
console.debug(EXPORTING_TO_CSV_FILE(output));
return {
output,
criteria,
};
};
/**
* Validates output path.
*/
const validateOutputPath = (outputPath: string) => {
if (!outputPath) {
throw new ExhaustOutputArgError(OUTPUT_REQUIRED);
}
return outputPath;
};
/**
* Grabs output and criteria from cli args, then call tree walker to collect csv data.
*/
const execute = async (tree: any, context: Context, outputPath: string) => {
const columns = ['Path'];
const matrix = [columns];
const {output, criteria} = parseOutputAndField(outputPath);
const aggregationIsEnabled = !!context.aggregation;
/**
* Walks through all tree branches and leaves, collecting the data
*/
const treeWalker = (node: any, criteria: string, path = 'tree') => {
/** Hmm aggregated, then checks if it's the first one. If so adds column, pushes the value. */
if (node.aggregated) {
if (path === 'tree') {
columns.push('Aggregated');
}
matrix.push([`${path}.${criteria}`, node.aggregated[criteria]]);
}
/** So it has outputs, whats then? checks if timestamp is not there, adds one. Then appends values to it. */
if (node.outputs) {
node.outputs.forEach((output: PluginParams) => {
const {timestamp} = output;
if (!columns.includes(timestamp)) {
columns.push(output.timestamp);
}
const lastRow = matrix[matrix.length - 1];
if (aggregationIsEnabled) {
lastRow.push(output[criteria]);
} else {
/** Handle without aggregation export strategy. */
if (matrix.length === 1 || lastRow.length === columns.length) {
matrix.push([`${path}.${criteria}`, output[criteria]]);
} else {
lastRow.push(output[criteria]);
}
}
});
}
/** Ohh children? then call every one and execute. */
if (node.children) {
for (const child in node.children) {
treeWalker(
node.children[child],
criteria,
`${path}.children.${child}`
);
}
}
};
treeWalker(tree, criteria);
await writeFile(`${output}.csv`, stringify(matrix, {columns}));
};
return {
execute,
metadata: {
kind: 'exhaust',
},
};
};
|