UNPKG

@kadconsulting/dry

Version:
114 lines 4.03 kB
// @ts-nocheck import { z } from 'zod'; import { useCallback, useMemo } from 'react'; import { PhoneNumberUtil } from 'google-libphonenumber'; const phoneUtil = PhoneNumberUtil.getInstance(); const NON_EMPTY_STRING_ERROR_MESSAGE = 'Please fill out this field'; const INVALID_EMAIL_ERROR_MESSAGE = 'Please enter a valid email address'; const INVALID_PHONE_NUMBER_ERROR_MESSAGE = 'Please enter a valid phone number'; export const useValidation = (form) => { const validateNonEmpty = useCallback(({ value }) => { const nonEmptySchema = z .string() .min(1, { message: NON_EMPTY_STRING_ERROR_MESSAGE }); try { nonEmptySchema.parse(value); } catch (error) { return error.issues[0].message; } return null; }, []); const validatePhoneNumber = useCallback(({ value, region }) => { const schema = z .string() .min(1, { message: NON_EMPTY_STRING_ERROR_MESSAGE }) .refine((value) => { try { return phoneUtil.isValidNumber(phoneUtil.parse(value, region)); } catch (error) { return false; } }, { message: INVALID_PHONE_NUMBER_ERROR_MESSAGE, }); try { schema.parse(value); } catch (error) { return error.issues[0].message; } return null; }, []); const validateEmailAddress = useCallback(({ value }) => { const schema = z .string() .min(1, { message: NON_EMPTY_STRING_ERROR_MESSAGE }) .email(INVALID_EMAIL_ERROR_MESSAGE); try { schema.parse(value); } catch (error) { return error.issues[0].message; } return null; }, []); const validateBoolean = useCallback(({ value, errorMessage, requiredValue }) => value === requiredValue ? null : errorMessage, []); const validatePostalCode5Digit = useCallback(({ value }) => { const schema = z .string() .min(1, { message: NON_EMPTY_STRING_ERROR_MESSAGE }) .refine((value) => { const postalCodeRegex = /^\d{5}$/; return postalCodeRegex.test(value); }, { message: 'Please enter a valid 5-digit postal code', }); try { schema.parse(value); } catch (error) { return error.issues[0].message; } return null; }, []); /** ... validate other stuff as needed */ /** Iterate through form validation rules provided by hook consumer, test the values according to the rules passed, and construct dictionary of error messages. */ const errors = useMemo(() => Object.keys(form.rules).reduce((acc, key) => { const rule = form.rules[key]; switch (true) { case rule.type === 'non-empty-string': acc[key] = validateNonEmpty(rule); break; case rule.type === 'phone-number': acc[key] = validatePhoneNumber(rule); break; case rule.type === 'email': acc[key] = validateEmailAddress(rule); break; case rule.type === 'boolean': acc[key] = validateBoolean(rule); break; case rule.type === 'postal-code-5-digit': acc[key] = validatePostalCode5Digit(rule); break; default: throw new Error(`Unknown field type ${rule.type}`); } return acc; }, {}), [ form, validateEmailAddress, validateNonEmpty, validatePhoneNumber, validateBoolean, validatePostalCode5Digit, ]); const errorsExist = useMemo(() => Object.values(errors).some((error) => error !== null), [errors]); return { errors, errorsExist, }; }; //# sourceMappingURL=useValidation.js.map