import type { FoxValidationErrors } from './fox-validators'; type MessageFactory = (detail: unknown) => string; function detailOf(detail: unknown): T { return detail as T; } const DEFAULT_MESSAGES: Record = { required: () => '필수 입력 항목입니다.', minlength: (detail) => `${detailOf<{ requiredLength: number }>(detail).requiredLength}자 이상 입력해 주세요.`, maxlength: (detail) => `${detailOf<{ requiredLength: number }>(detail).requiredLength}자 이내로 입력해 주세요.`, pattern: () => '형식이 올바르지 않습니다.', email: () => '이메일 형식이 올바르지 않습니다.', characterKinds: (detail) => `영문, 숫자, 특수문자 중 ${ detailOf<{ requiredKinds: number }>(detail).requiredKinds }종류 이상을 섞어 주세요.`, repeatedCharacters: (detail) => `같은 문자를 ${detailOf<{ max: number }>(detail).max}번까지만 연달아 쓸 수 있습니다.`, sequentialCharacters: (detail) => `연속된 문자나 숫자를 ${ detailOf<{ max: number }>(detail).max }자를 넘겨 쓸 수 없습니다.`, notContaining: (detail) => `${detailOf<{ forbidden: string }>(detail).forbidden}은(는) 포함할 수 없습니다.`, equalTo: () => '값이 일치하지 않습니다.', }; const MESSAGE_ORDER = [ 'required', 'minlength', 'maxlength', 'pattern', 'email', 'characterKinds', 'repeatedCharacters', 'sequentialCharacters', 'notContaining', 'equalTo', ]; export type FoxValidationMessages = Record< string, string | ((detail: unknown) => string) >; export function foxValidationMessage( errors: FoxValidationErrors | null, overrides: FoxValidationMessages = {} ): string | undefined { if (!errors) { return undefined; } const keys = Object.keys(errors); const ordered = [ ...MESSAGE_ORDER.filter((key) => keys.includes(key)), ...keys.filter((key) => !MESSAGE_ORDER.includes(key)), ]; for (const key of ordered) { const override = overrides[key]; if (typeof override === 'string') { return override; } if (typeof override === 'function') { return override(errors[key]); } const fallback = DEFAULT_MESSAGES[key]; if (fallback) { return fallback(errors[key]); } } return undefined; }