import type { CreateCardForTemporaryUsePayload, DuffelCardFormStrings, } from '../../../index'; import type { ConditionalFormPayload } from '../forms/CreateCardForTemporaryUseForm'; import { thisMonth } from '../utils/thisMonth'; import { validateCVCFn } from './validateCVCFn'; export type ValidationResult = { valid: boolean; error: string | null }; /** * These fields won't be present in the payload, * they only aid with keeping data and validation */ export interface VirtualFields { expiry_date: Date | null; } export type KeyToValidate = | keyof Omit | keyof VirtualFields; export function validateFieldFn(customStrings: DuffelCardFormStrings) { const validateCVC = validateCVCFn(customStrings); return ( fieldName: KeyToValidate, data: ConditionalFormPayload & VirtualFields ): ValidationResult => { if (fieldName === 'number') { if (data[fieldName] === '') { return { valid: false, error: customStrings.cardNumberRequired }; } else if (data[fieldName].length < 15 || data[fieldName].length > 16) { return { valid: false, error: customStrings.cardNumberDigitsInvalidMessage, }; } else { return { valid: true, error: null }; } } if (fieldName === 'expiry_date') { if (data[fieldName] === null) { return { valid: false, error: customStrings.expiryDateRequiredMessage }; } else if (data[fieldName] < thisMonth()) { return { valid: false, error: customStrings.expiryDateInThePastMessage, }; } else { return { valid: true, error: null }; } } if (fieldName === 'name') { if (data[fieldName] === '') { return { valid: false, error: customStrings.cardholderNameRequired }; } else { return { valid: true, error: null }; } } if (fieldName === 'address_line_1') { if (data[fieldName] === '') { return { valid: false, error: customStrings.addressRequiredMessage }; } else { return { valid: true, error: null }; } } if (fieldName === 'address_city') { if (data[fieldName] === '') { return { valid: false, error: customStrings.cityRequiredMessage }; } else { return { valid: true, error: null }; } } if (fieldName === 'address_region') { if (data[fieldName] === '') { return { valid: false, error: customStrings.regionRequiredMessage }; } else { return { valid: true, error: null }; } } if (fieldName === 'address_postal_code') { if ( data.address_country_code === 'US' && !/^\d{5}$/.test(data[fieldName]) ) { return { valid: false, error: customStrings.zipInvalidMessage }; } else if ( data.address_country_code === 'CA' && // Allows h2t-1b8, h2z 1b8, H2Z1B8. Disallows: leading Z, W or to contain D, F, I, O, Q or U !/^[ABCEGHJ-NPRSTVXY]\d[ABCEGHJ-NPRSTV-Z][ -]?\d[ABCEGHJ-NPRSTV-Z]\d$/i.test( data[fieldName] ) ) { return { valid: false, error: customStrings.postalCodeInvalidMessage }; } else if ( data.address_country_code === 'GB' && !/^[A-Z]{1,2}[0-9R][0-9A-Z]? ?[0-9][A-Z]{2}$/.test(data[fieldName]) ) { return { valid: false, error: customStrings.postcodeInvalidMessage }; } else if (data[fieldName] === '') { return { valid: false, error: customStrings.postalCodeRequiredMessage }; } else { return { valid: true, error: null }; } } if (fieldName === 'address_country_code') { if (data[fieldName] === 'null' || data[fieldName] === null) { return { valid: false, error: customStrings.countryRequiredMessage }; } else { return { valid: true, error: null }; } } if (fieldName === 'cvc') { return validateCVC((data as CreateCardForTemporaryUsePayload)[fieldName]); } if (fieldName === 'address_line_2') { // we don't validate this, it's optional return { valid: true, error: null }; } throw new Error( `Attempted to 'validateField' an invalid field: '${fieldName}'` ); }; }