import { z } from 'zod'; import { CURRENCY_DATA_SCALE } from '@repo/utils'; export const PRICE_DECIMAL_SCALE = CURRENCY_DATA_SCALE; export const QUANTITY_DECIMAL_SCALE = 4; function coerceDecimalInput(value: unknown) { if (value === '' || value === null || value === undefined) { return undefined; } if (typeof value === 'number') { return Number.isFinite(value) ? String(value) : value; } return value; } export function toDecimalStringValue(value: unknown): string | undefined { const next = coerceDecimalInput(value); return typeof next === 'string' ? next : undefined; } function decimalPattern(maxDecimals: number) { return new RegExp(`^\\d+(\\.\\d{1,${maxDecimals}})?$`); } export function decimalStringSchema( t: (key: string) => string, fieldKey = 'common:fields.price', maxDecimals = QUANTITY_DECIMAL_SCALE, ) { return z.preprocess( coerceDecimalInput, z.string().regex(decimalPattern(maxDecimals), { message: JSON.stringify({ key: 'validation:invalid_format', values: { field: t(fieldKey) } }), }), ); } export function optionalDecimalStringSchema( t: (key: string) => string, fieldKey = 'common:fields.price', maxDecimals = PRICE_DECIMAL_SCALE, ) { return z.preprocess( coerceDecimalInput, z .string() .regex(decimalPattern(maxDecimals), { message: JSON.stringify({ key: 'validation:invalid_format', values: { field: t(fieldKey) } }), }) .optional(), ); }