All files / src/libs/vee backendErrors.ts

92% Statements 23/25
44.44% Branches 4/9
100% Functions 1/1
92% Lines 23/25

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                              1x 2x 2x 2x 2x 2x 2x   1x 2x   1x   1x 1x 1x   1x 1x 1x 1x   1x 1x 1x 1x 1x   1x      
export type MsgFromCode = (code?: string, params?: any) => string
export type ResolveField = (backendPath: string) => { name: string }
 
export type ApplyBackendErrorsOptions<Name extends string = string> = {
  setErrors: (errs: Record<string, string>) => void
  setTouched?: (name: Name, isTouched: boolean) => void
  resolveField: (backendPath: string) => { name: Name }
  msgFromCode: (code?: string, params?: any) => string
  fieldLabelKeyOf?: (name: Name) => string
}
 
/**
 * 422(Validation Error)の details を vee-validate の setErrors 形式へ変換し、適用する。
 * 成功時 true(= 422 を処理した)、それ以外 false を返す。
 */
export function setErrorsFrom422<Name extends string = string>(
  err: unknown,
  opts: ApplyBackendErrorsOptions<Name>,
): boolean {
  const { setErrors, setTouched, resolveField, msgFromCode, fieldLabelKeyOf } = opts
  const resp = (err as any)?.response
  if (!resp || resp.status !== 422) return false
 
  const details = resp?.data?.error?.details as Record<string, any>
  if (!details || typeof details !== 'object') return false
 
  const out: Record<string, string> = {}
 
  for (const [backendPath, issuesRaw] of Object.entries(details)) {
    const issue = Array.isArray(issuesRaw) ? issuesRaw[0] : issuesRaw
    const { name } = resolveField(backendPath) // name: Name
 
    const fieldKey = fieldLabelKeyOf ? fieldLabelKeyOf(name) : undefined
    const msg =
      issue?.message ||
      msgFromCode(issue?.code, { ...(issue?.params || {}), fieldKey })
 
    if (name && msg) {
      out[name as string] = String(msg)
      if (setTouched) setTouched(name, true)
    }
  }
 
  if (Object.keys(out).length) { setErrors(out); return true }
  return false
}