{"version":3,"file":"ValidationLogic.cjs","sources":["../../src/ValidationLogic.ts"],"sourcesContent":["import type { AnyFormApi, FormValidators } from './FormApi'\n\nexport interface ValidationLogicValidatorsFn {\n  // TODO: Type this properly\n  fn: FormValidators<\n    any,\n    any,\n    any,\n    any,\n    any,\n    any,\n    any,\n    any,\n    any,\n    any\n  >[keyof FormValidators<any, any, any, any, any, any, any, any, any, any>]\n  cause: 'change' | 'blur' | 'submit' | 'mount' | 'server' | 'dynamic'\n}\n\nexport interface ValidationLogicProps {\n  // TODO: Type this properly\n  form: AnyFormApi\n  // TODO: Type this properly\n  validators:\n    | FormValidators<any, any, any, any, any, any, any, any, any, any>\n    | undefined\n    | null\n  event: {\n    type: 'blur' | 'change' | 'submit' | 'mount' | 'server'\n    fieldName?: string\n    async: boolean\n  }\n  runValidation: (props: {\n    validators: Array<ValidationLogicValidatorsFn | undefined>\n    form: AnyFormApi\n  }) => void\n}\n\ninterface RevalidateLogicProps {\n  /**\n   * @default 'submit'\n   *\n   * This is the mode that will be used before the form has been submitted.\n   * It will run the validation logic on `submit` by default, but can be set to `change` or `blur`.\n   */\n  mode?: 'change' | 'blur' | 'submit'\n  /**\n   * @default 'change'\n   *\n   * This is the mode that will be used after the form has been submitted.\n   * It will run the validation logic on `change` by default, but can be set to `blur` or `submit`.\n   */\n  modeAfterSubmission?: 'change' | 'blur' | 'submit'\n}\n\nexport type ValidationLogicFn = (props: ValidationLogicProps) => void\n\n/**\n * This forces a form's validation logic to be ran as if it were a React Hook Form validation logic.\n *\n * This means that it will only run the `onDynamic` validator, and it will not run any other validators and changes the validation\n * type based on the state of the form itself.\n *\n * When the form is not yet submitted, it will not run the validation logic.\n * When the form is submitted, it will run the validation logic on `change`\n */\nexport const revalidateLogic =\n  ({\n    mode = 'submit',\n    modeAfterSubmission = 'change',\n  }: RevalidateLogicProps = {}): ValidationLogicFn =>\n  (props) => {\n    const validatorNames = Object.keys(props.validators ?? {})\n    if (validatorNames.length === 0) {\n      // No validators is a valid case, just return\n      return props.runValidation({\n        validators: [],\n        form: props.form,\n      })\n    }\n\n    const dynamicValidator = {\n      fn: props.event.async\n        ? props.validators!['onDynamicAsync']\n        : props.validators!['onDynamic'],\n      cause: 'dynamic',\n    } as const\n\n    const validatorsToAdd = [] as ValidationLogicValidatorsFn[]\n\n    const modeToWatch =\n      props.form.state.submissionAttempts === 0 ? mode : modeAfterSubmission\n\n    if ([modeToWatch, 'submit'].includes(props.event.type)) {\n      validatorsToAdd.push(dynamicValidator)\n    }\n\n    let defaultValidators = [] as ValidationLogicValidatorsFn[]\n\n    defaultValidationLogic({\n      ...props,\n      runValidation: (vProps) => {\n        defaultValidators = vProps.validators as ValidationLogicValidatorsFn[]\n      },\n    })\n\n    if (validatorsToAdd.length === 0) {\n      return props.runValidation({\n        validators: defaultValidators,\n        form: props.form,\n      })\n    }\n\n    return props.runValidation({\n      validators: [...defaultValidators, ...validatorsToAdd],\n      form: props.form,\n    })\n  }\n\nexport const defaultValidationLogic: ValidationLogicFn = (props) => {\n  // Handle case where no validators are provided\n  if (!props.validators) {\n    return props.runValidation({\n      validators: [],\n      form: props.form,\n    })\n  }\n\n  const isAsync = props.event.async\n\n  const onMountValidator = isAsync\n    ? undefined\n    : ({ fn: props.validators.onMount, cause: 'mount' } as const)\n\n  const onChangeValidator = {\n    fn: isAsync ? props.validators.onChangeAsync : props.validators.onChange,\n    cause: 'change',\n  } as const\n\n  const onBlurValidator = {\n    fn: isAsync ? props.validators.onBlurAsync : props.validators.onBlur,\n    cause: 'blur',\n  } as const\n\n  const onSubmitValidator = {\n    fn: isAsync ? props.validators.onSubmitAsync : props.validators.onSubmit,\n    cause: 'submit',\n  } as const\n\n  // Allows us to clear onServer errors\n  const onServerValidator = isAsync\n    ? undefined\n    : ({ fn: () => undefined, cause: 'server' } as const)\n\n  switch (props.event.type) {\n    case 'mount': {\n      // Run mount validation\n      return props.runValidation({\n        validators: [onMountValidator],\n        form: props.form,\n      })\n    }\n    case 'submit': {\n      // Run change, blur, submit, server validation\n      return props.runValidation({\n        validators: [\n          onChangeValidator,\n          onBlurValidator,\n          onSubmitValidator,\n          onServerValidator,\n        ],\n        form: props.form,\n      })\n    }\n    case 'server': {\n      // Run server validation\n      return props.runValidation({\n        validators: [],\n        form: props.form,\n      })\n    }\n    case 'blur': {\n      // Run blur, server validation\n      return props.runValidation({\n        validators: [onBlurValidator, onServerValidator],\n        form: props.form,\n      })\n    }\n    case 'change': {\n      // Run change, server validation\n      return props.runValidation({\n        validators: [onChangeValidator, onServerValidator],\n        form: props.form,\n      })\n    }\n    default: {\n      throw new Error(`Unknown validation event type: ${props.event.type}`)\n    }\n  }\n}\n"],"names":[],"mappings":"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"}