All files / app/formFields getCustomFormFieldsValidationSchema.ts

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  32x 32x   32x                                                 32x 407x 407x   407x     3716x 727x       727x             727x 237x       121x   237x 237x 490x     490x     727x 6x         727x 6x         727x 32x   32x         727x              
import { FormField } from '@bigcommerce/checkout-sdk';
import { memoize } from '@bigcommerce/memoize';
import { array, date, number, object, string, ArraySchema, NumberSchema, ObjectSchema, Schema } from 'yup';
 
import { DynamicFormFieldType } from '../ui/form';
 
export type TranslateValidationErrorFunction = ((
    validationType: 'max' | 'min' | 'required' | 'invalid',
    field: {
        name: string;
        label: string;
        min?: number;
        max?: number;
    }
) => string | undefined);
 
export interface FormFieldsValidationSchemaOptions {
    formFields: FormField[];
    translate?: TranslateValidationErrorFunction;
}
 
export interface CustomFormFieldValues {
    customFields: CustomFormFields;
}
 
export interface CustomFormFields {
    [id: string]: string | string[] | number;
}
 
export default memoize(function getCustomFormFieldsValidationSchema({
    formFields,
    translate = () => undefined,
}: FormFieldsValidationSchemaOptions): ObjectSchema<CustomFormFieldValues> {
    return object({
        customFields: object(
            formFields
                .filter(({ custom }) => !!custom)
                .reduce((schema, { name, label, required, fieldType, type, min, max }) => {
                    let maxValue: number | undefined;
                    let minValue: number | undefined;
 
                    Iif (type === 'date') {
                        schema[name] = date()
                            // Transform NaN values to undefined to avoid empty string (empty input) to fail date
                            // validation when it's optional
                            .strict(true)
                            .nullable(true)
                            .transform((value, originalValue) => originalValue === '' ? null : value);
                    } else if (type === 'integer') {
                        schema[name] = number()
                            // Transform NaN values to undefined to avoid empty string (empty input) to fail number
                            // validation when it's optional
                            .strict(true)
                            .transform(value => isNaN(value) ? undefined : value);
 
                        maxValue = typeof max === 'number' ? max : undefined;
                        minValue = typeof min === 'number' ? min : undefined;
                    } else Iif (fieldType === DynamicFormFieldType.checkbox) {
                        schema[name] = array();
                    } else {
                        schema[name] = string();
                    }
 
                    if (maxValue !== undefined) {
                        schema[name] = (schema[name] as NumberSchema).max(maxValue,
                            translate('max', { label, name, max: maxValue + 1 })
                        );
                    }
 
                    if (minValue !== undefined) {
                        schema[name] = (schema[name] as NumberSchema).min(minValue,
                            translate('min', { label, name, min: minValue - 1 })
                        );
                    }
 
                    if (required) {
                        const requiredErrorMessage = translate('required', { name, label });
 
                        schema[name] = fieldType === DynamicFormFieldType.checkbox ?
                            (schema[name] as ArraySchema<string>).min(1, requiredErrorMessage) :
                            (schema[name] as ArraySchema<string>).required(requiredErrorMessage);
                    }
 
                    return schema;
                },
                {} as { [key: string]: Schema<any> }
            )
        ).nullable(true),
    }) as ObjectSchema<CustomFormFieldValues>;
});