Files
WRNexusJS/packages/i18n/src/format.ts
T
2026-07-12 15:55:18 +05:30

53 lines
1.7 KiB
TypeScript

/**
* Locale-aware formatting helpers (Intl-based) + pluralization. Pair with the
* request language (`ctx.lang`) so numbers, dates, and currencies render right
* for each user.
*/
/** Format a number for a locale (e.g. 1234.5 → "1,234.5"). */
export function formatNumber(
value: number,
lang: string,
options?: Intl.NumberFormatOptions,
): string {
return new Intl.NumberFormat(lang || undefined, options).format(value);
}
/** Format a currency amount (e.g. 9.99, "USD" → "$9.99"). */
export function formatCurrency(value: number, currency: string, lang: string): string {
return new Intl.NumberFormat(lang || undefined, { style: "currency", currency }).format(value);
}
/** Format a date/timestamp for a locale. */
export function formatDate(
value: Date | number | string,
lang: string,
options: Intl.DateTimeFormatOptions = { dateStyle: "medium" },
): string {
const date = value instanceof Date ? value : new Date(value);
return new Intl.DateTimeFormat(lang || undefined, options).format(date);
}
/** Relative time, e.g. -3 days → "3 days ago" (localized). */
export function formatRelativeTime(
value: number,
unit: Intl.RelativeTimeFormatUnit,
lang: string,
): string {
return new Intl.RelativeTimeFormat(lang || undefined, { numeric: "auto" }).format(value, unit);
}
/**
* Pick a plural form for `count` in `lang` using CLDR rules, e.g.
* `plural(n, { one: "1 item", other: "# items" }, lang)` — "#" is replaced by n.
*/
export function plural(
count: number,
forms: Partial<Record<Intl.LDMLPluralRule, string>>,
lang: string,
): string {
const rule = new Intl.PluralRules(lang || undefined).select(count);
const template = forms[rule] ?? forms.other ?? "";
return template.replace(/#/g, String(count));
}