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 | 1x 11x 11x 11x 11x 11x 11x 11x 11x 11x 11x 11x 11x 11x 11x 11x 11x 11x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x | // 共通の t 型
export type TFunc = (key: string, params?: Record<string, any>) => string;
/** 各フィールドの表示名辞書 L を受け取り、メッセージを返す小さなビルダ */
export function makeMsg(t: TFunc, L: Record<string, string>) {
return {
req: (name: string) => t('validation.rules.required', { field: L[name] }),
typeNum: (name: string) => t('validation.rules.type.number', { field: L[name] }),
typeStr: (name: string) => t('validation.rules.type.string', { field: L[name] }),
len: (name: string, len: number) => t('validation.rules.len.string', { field: L[name], len }),
min: (name: string, n: number) => t('validation.rules.min.string', { field: L[name], min: n }),
max: (name: string, n: number) => t('validation.rules.max.string', { field: L[name], max: n }),
positive: (name: string) => t('validation.rules.positive.number',{ field: L[name] }),
range: (name: string, min: number, max: number) => t('validation.rules.range.number', { field: L[name], min, max }),
regex: (name: string) => t('validation.rules.regex', { field: L[name] }),
date: (name: string) => t('validation.rules.date', { field: L[name] }),
// カスタム
jpPostal: (name: string) => t('validation.custom.jpPostal', { field: L[name] }),
coordPair: () => t('validation.custom.coordPair'),
email: (name: string) => t('validation.rules.email', { field: L[name] }),
requiredAny: (names: string[]) => t('validation.custom.requiredAny', { fields: names.map(n => L[n]).join(', ') }),
};
}
/** backend の code→i18nキー解決(422マッピングでも再利用可) */
export function msgFromCode(t: TFunc, code?: string, params: any = {}): string {
if (!code) return t('validation.invalid');
let key = String(code);
// rules.* は .string/.number を補完
if (key.startsWith('validation.rules.') && !/\.string$|\.number$/.test(key)) {
// NOTE: 簡易に .string を足す。必要に応じて number に寄せ替え可
key += '.string';
}
const p = params || {};
const fieldLabel =
typeof p.fieldKey === 'string' ? t(p.fieldKey) :
typeof p.field === 'string' ? t(p.field) : undefined;
const len = p.len ?? p.param;
const max = p.max ?? p.param;
const min = p.min ?? p.param;
const msg = t(key, { field: fieldLabel, len, max, min });
if (msg && msg !== key) return msg;
// 旧式フォールバック(任意)
if (p?.tag === 'max' && (p?.param || p?.max))
return t('validation.rules.max.string', { field: fieldLabel ?? '', max: p.param || p.max });
if (p?.tag === 'len' && (p?.param || p?.len))
return t('validation.rules.len.string', { field: fieldLabel ?? '', len: p.param || p.len });
// ✅ range のフォールバックも追加
if (p?.tag === 'range' && (p?.min != null && p?.max != null))
return t('validation.rules.range.number', { field: fieldLabel ?? '', min: p.min, max: p.max });
return t('validation.invalid');
}
|