All files / react useValidator.ts

100% Statements 17/17
87.5% Branches 7/8
100% Functions 3/3
100% Lines 17/17

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        1x                                                                                                 5x 3x 3x 3x   2x 2x 2x     5x 4x   4x 2x   2x   5x 5x 5x           5x    
import { DependencyList, useMemo } from 'react'
import { AnyObject } from '../types'
import { yup as _yup } from '../validator'
 
const validateOptions: _yup.SchemaValidateOptions = {
  strict: true,
  abortEarly: true,
  stripUnknown: false,
  recursive: true,
}
 
export type UseValidatorSchema<T> = (
  yup: typeof _yup,
) => T extends string
  ? _yup.StringSchema<T>
  : T extends number
  ? _yup.NumberSchema<T>
  : T extends boolean
  ? _yup.BooleanSchema<T>
  : T extends Array<infer X>
  ? _yup.ArraySchema<X>
  : T extends AnyObject
  ? _yup.ObjectSchema<T> | _yup.GetObjectSchema<T>
  : _yup.MixedSchema<T>
 
export interface UseValidatorResult<T> {
  data: T
  valid: boolean
  error?: _yup.ValidationError | undefined
}
 
export function useValidator<T>(
  data: T,
  dataDeps: DependencyList,
  schema: UseValidatorSchema<T>,
  schemaDeps?: DependencyList,
): UseValidatorResult<T>
 
export function useValidator<T>(
  data: T,
  schema: UseValidatorSchema<T>,
  schemaDeps?: DependencyList,
): UseValidatorResult<T>
 
export function useValidator<T>(
  data: T,
  dataDeps: any,
  schema?: any,
  schemaDeps?: any,
): UseValidatorResult<T> {
  let _dataDeps: DependencyList
  let _schema: UseValidatorSchema<T>
  let _schemaDeps: DependencyList
  if (Array.isArray(dataDeps)) {
    _dataDeps = dataDeps
    _schema = schema
    _schemaDeps = schemaDeps || []
  } else {
    _dataDeps = []
    _schema = dataDeps
    _schemaDeps = schema || []
  }
 
  const yupSchema = useMemo((): _yup.MixedSchema => {
    const schemaOrObjectDefinitions = _schema(_yup)
    // @ts-ignore
    if (schemaOrObjectDefinitions.__isYupSchema__) {
      return schemaOrObjectDefinitions as any
    }
    return _yup.object(schemaOrObjectDefinitions as any)
  }, _schemaDeps)
  const result = useMemo((): UseValidatorResult<T> => {
    const r = yupSchema.validatePlusSync(data, validateOptions)
    return {
      data: r.data,
      valid: !r.error,
      error: r.error,
    }
  }, [..._dataDeps, yupSchema])
  return result
}