All files / builtins/regex index.ts

100% Statements 35/35
100% Branches 9/9
100% Functions 6/6
100% Lines 34/34

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 974x 4x     4x   4x   4x 4x   4x 4x             4x 5x 1x     4x           4x           4x 4x 1x     3x           4x 5x 4x   4x 4x           3x                   4x         3x 3x     3x 2x     3x 3x   3x 1x     2x     4x          
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 {MissingInputDataError, GlobalConfigError, RegexMismatchError} = ERRORS;
const {MISSING_GLOBAL_CONFIG, MISSING_INPUT_DATA, REGEX_MISMATCH} = STRINGS;
 
export const Regex = (globalConfig: ConfigParams): ExecutePlugin => {
  const metadata = {
    kind: 'execute',
  };
 
  /**
   * Checks global config value are valid.
   */
  const validateGlobalConfig = () => {
    if (!globalConfig) {
      throw new GlobalConfigError(MISSING_GLOBAL_CONFIG);
    }
 
    const schema = z.object({
      parameter: z.string().min(1),
      match: z.string().min(1),
      output: z.string(),
    });
 
    return validate<z.infer<typeof schema>>(schema, globalConfig);
  };
 
  /**
   * Checks for required fields in input.
   */
  const validateSingleInput = (input: PluginParams, parameter: string) => {
    if (!input[parameter]) {
      throw new MissingInputDataError(MISSING_INPUT_DATA(parameter));
    }
 
    return input;
  };
 
  /**
   * Executes the regex of the given parameter.
   */
  const execute = (inputs: PluginParams[]) => {
    const safeGlobalConfig = validateGlobalConfig();
    const {parameter: parameter, match, output} = safeGlobalConfig;
 
    return inputs.map(input => {
      const safeInput = Object.assign(
        {},
        input,
        validateSingleInput(input, parameter)
      );
 
      return {
        ...input,
        [output]: extractMatching(safeInput, parameter, match),
      };
    });
  };
 
  /**
   * Extracts a substring from the given input parameter that matches the provided regular expression pattern.
   */
  const extractMatching = (
    input: PluginParams,
    parameter: string,
    match: string
  ) => {
    if (!match.startsWith('/')) {
      match = '/' + match;
    }
 
    if (!match.endsWith('/g') && !match.endsWith('/')) {
      match += '/';
    }
 
    const regex = eval(match);
    const matchedItem = input[parameter].match(regex);
 
    if (!matchedItem || !matchedItem[0]) {
      throw new RegexMismatchError(REGEX_MISMATCH(input[parameter], match));
    }
 
    return matchedItem[0];
  };
 
  return {
    metadata,
    execute,
  };
};