All files / builtins/divide index.ts

100% Statements 29/29
100% Branches 6/6
100% Functions 7/7
100% Lines 28/28

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 923x 3x     3x   3x   3x 3x   3x 6x             6x 6x 4x   4x 4x           2x                   6x 6x 1x     5x           5x           6x         4x           3x 1x   2x     4x           6x       2x   6x          
import {z} from 'zod';
import {ERRORS} from '@grnsft/if-core/utils';
import {ExecutePlugin, PluginParams, ConfigParams} from '@grnsft/if-core/types';
 
import {validate} from '../../util/validations';
 
import {STRINGS} from '../../config';
 
const {GlobalConfigError, MissingInputDataError} = ERRORS;
const {MISSING_GLOBAL_CONFIG, MISSING_INPUT_DATA} = STRINGS;
 
export const Divide = (globalConfig: ConfigParams): ExecutePlugin => {
  const metadata = {
    kind: 'execute',
  };
 
  /**
   * Calculate the division of each input parameter.
   */
  const execute = (inputs: PluginParams[]) => {
    const safeGlobalConfig = validateGlobalConfig();
    const {numerator, denominator, output} = safeGlobalConfig;
 
    return inputs.map(input => {
      const safeInput = Object.assign(
        {},
        input,
        validateSingleInput(input, numerator, denominator)
      );
 
      return {
        ...input,
        [output]: calculateDivide(safeInput, numerator, denominator),
      };
    });
  };
 
  /**
   * Checks global config value are valid.
   */
  const validateGlobalConfig = () => {
    if (!globalConfig) {
      throw new GlobalConfigError(MISSING_GLOBAL_CONFIG);
    }
 
    const schema = z.object({
      numerator: z.string().min(1),
      denominator: z.string().or(z.number().gt(0)),
      output: z.string(),
    });
 
    return validate<z.infer<typeof schema>>(schema, globalConfig);
  };
 
  /**
   * Checks for required fields in input.
   */
  const validateSingleInput = (
    input: PluginParams,
    numerator: string,
    denominator: number | string
  ) => {
    const schema = z
      .object({
        [numerator]: z.number(),
        [denominator]: z.number().optional(),
      })
      .refine(() => {
        if (typeof denominator === 'string' && !input[denominator]) {
          throw new MissingInputDataError(MISSING_INPUT_DATA(denominator));
        }
        return true;
      });
 
    return validate<z.infer<typeof schema>>(schema, input);
  };
 
  /**
   * Calculates the division of the given parameter.
   */
  const calculateDivide = (
    input: PluginParams,
    numerator: string,
    denominator: number | string
  ) => input[numerator] / (input[denominator] || denominator);
 
  return {
    metadata,
    execute,
  };
};