All files / if-run/lib regroup.ts

100% Statements 36/36
100% Branches 8/8
100% Functions 6/6
100% Lines 35/35

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 892x 2x     2x   2x   2x 2x         2x           39x 18x 18x 18x     21x 21x 21x   21x           2x 11x 11x         11x   9x           2x 25x 2x     23x           2x         11x   9x         16x 20x 25x   18x       9x 9x 7x   7x    
import {z} from 'zod';
import {ERRORS} from '@grnsft/if-core/utils';
import {PluginParams} from '@grnsft/if-core/types';
 
import {validate} from '../../common/util/validations';
 
import {STRINGS} from '../config';
 
const {InvalidGroupingError} = ERRORS;
const {INVALID_GROUP_KEY, REGROUP_ERROR} = STRINGS;
 
/**
 * Creates structure to insert inputs by groups.
 */
const appendGroup = (
  value: PluginParams,
  object: any,
  target: string,
  groups: string[]
): any => {
  if (groups.length === 0) {
    object[target] = object[target] || [];
    object[target].push(value);
    return object;
  }
 
  const group = groups.shift()!;
  object.children = object.children || {};
  object.children[group] = object.children[group] || {};
 
  return appendGroup(value, object.children[group], target, groups);
};
 
/**
 * Validates the groups array.
 */
const validateGroups = (groups: string[]): string[] => {
  const inputData = {regroup: groups};
  const validationSchema = z.record(
    z.string(),
    z.array(z.string(), {message: REGROUP_ERROR}).min(1)
  );
 
  validate(validationSchema, inputData);
 
  return groups;
};
 
/**
 * Looks up a group key value in the input.
 */
const lookupGroupKey = (input: PluginParams, groupKey: string): string => {
  if (!input[groupKey]) {
    throw new InvalidGroupingError(INVALID_GROUP_KEY(groupKey));
  }
 
  return input[groupKey];
};
 
/**
 * Regroups inputs and outputs based on the given group keys.
 */
export const Regroup = (
  inputs: PluginParams[],
  outputs: PluginParams[],
  groups: string[]
): any => {
  const validatedGroups = validateGroups(groups);
 
  const appendToAccumulator = (
    items: PluginParams[],
    acc: any,
    target: string
  ) => {
    for (const item of items) {
      const groupsWithData = validatedGroups.map(groupKey =>
        lookupGroupKey(item, groupKey)
      );
      appendGroup(item, acc, target, groupsWithData);
    }
  };
 
  const acc = {} as any;
  appendToAccumulator(inputs, acc, 'inputs');
  appendToAccumulator(outputs, acc, 'outputs');
 
  return acc.children;
};