react-app/src/components/RHF/utils/additionalRules.ts
import { RegisterOptions } from "react-hook-form";import { AdditionalRule, RuleGenerator, SortFuncs } from "shared-types/forms"; export const sortFunctions: { [x in SortFuncs]: (a: string, b: string) => number;} = { noSort: () => 0, reverseSort: (a, b) => b.localeCompare(a),}; // New function to sort options from lowest to highestexport function sortOptionsLowestToHighest<T extends { value: string | number }>( options: T[],): T[] { return [...options].sort((a, b) => { const aValue = typeof a.value === "string" ? parseFloat(a.value) : a.value; const bValue = typeof b.value === "string" ? parseFloat(b.value) : b.value; return aValue - bValue; });} export function stringCompare(a: { label: string }, b: { label: string }): number { const aIsNumber = !isNaN(parseFloat(a.label)); const bIsNumber = !isNaN(parseFloat(b.label)); if (aIsNumber && bIsNumber) { return parseFloat(a.label) - parseFloat(b.label); } return a.label.localeCompare(b.label);} export const ruleGenerator: RuleGenerator = (rules, addtnlRules) => { if (!rules && !addtnlRules) return undefined; const simpleRules = rules ?? {}; const customRules = addtnlRules ? { validate: addtnlRules.reduce(valReducer, {}) } : {}; return { ...simpleRules, ...customRules };}; Function `valReducer` has a Cognitive Complexity of 44 (exceeds 5 allowed). Consider refactoring.export const valReducer = ( valSet: RegisterOptions["validate"], rule: AdditionalRule, index: number,): RegisterOptions["validate"] => { const valName = `${rule.type}_${index}`; switch (rule.type) { case "lessThanField": return { ...valSet, [valName]: (value, fields) => { if (!rule.strictGreater && parseFloat(value) <= parseFloat(fields[rule.fieldName])) return true; if (parseFloat(value) < parseFloat(fields[rule.fieldName])) return true; return rule.message; }, }; case "greaterThanField": return { ...valSet, [valName]: (value, fields) => { if (!rule.strictGreater && parseFloat(value) >= parseFloat(fields[rule.fieldName])) return true; if (parseFloat(value) > parseFloat(fields[rule.fieldName])) return true; return rule.message; }, }; case "cannotCoexist": return { ...valSet, [valName]: (value, fields) => { if (value !== undefined && fields[rule.fieldName] === undefined) return true; if (value === undefined && fields[rule.fieldName] !== undefined) return true; return rule.message; }, }; case "noGapsOrOverlaps": return { ...valSet, [valName]: (_, fields) => { const fieldArray = fields[rule.fieldName]; if (!fieldArray || !Array.isArray(fieldArray) || fieldArray.length <= 1) { return true; // No validation needed for 0 or 1 entry } const fromField = rule.fromField; const toField = rule.toField; const range = fieldArray.map((item: any) => ({ from: parseInt(item[fromField], 10), to: parseInt(item[toField], 10), })); // Sort ranges by from value range.sort((a, b) => a.from - b.from); // Check for overlaps and gaps for (let i = 1; i < range.length; i++) { if (range[i].from < range[i - 1].to) { return "No age overlaps allowed"; } if (range[i].from > range[i - 1].to) { return "No gaps between ages allowed"; } } return true; // No issues found }, }; case "toGreaterThanFrom": return { ...valSet, [valName]: (value, formValues) => { const fromValue = parseInt(value, 10); const fieldArray = formValues[rule.fieldName]; if (!fieldArray || !Array.isArray(fieldArray)) { return true; // Skip validation if field array is not valid } const currentIndex = fieldArray.findIndex((item) => item[rule.fromField] === value); if (currentIndex === -1) { return true; // Skip validation if current item is not found } const toValue = parseInt(fieldArray[currentIndex][rule.toField], 10); if (isNaN(fromValue) || isNaN(toValue)) { return true; // Skip validation if values are not valid numbers } return toValue > fromValue || rule.message || "To age must be greater than From age"; }, }; default: return { ...valSet }; }};