refactor: enforce frontend view model boundaries
Frontend verify / commits (pull_request) Successful in 28s
Frontend verify / security (pull_request) Successful in 10s
Frontend verify / verify (pull_request) Successful in 8m19s

This commit is contained in:
2026-09-28 18:48:23 +03:00
parent 5b69003516
commit ca0ad4f824
287 changed files with 8558 additions and 4538 deletions
+32 -6
View File
@@ -4,6 +4,7 @@ const CENTS_PRECISION = 2;
type FormatMoneyOptions = {
withZeroCents?: boolean;
};
type Money = { currency: string; value: string };
function formatDate(value: string): string {
@@ -21,23 +22,40 @@ function formatDecimal(value: string): string {
const digits = sign ? integer.slice(1) : integer;
const groupSize = 3;
const groups: string[] = [];
for (let end = digits.length; end > 0; end -= groupSize) {
groups.push(digits.slice(Math.max(0, end - groupSize), end));
}
const grouped = groups.toReversed().join(" ");
const suffix = fraction ? `,${fraction}` : "";
return `${sign}${grouped}${suffix}`;
}
function formatMoney(
money: Money | null | undefined,
money: Money
| null
| undefined,
{ withZeroCents = false }: FormatMoneyOptions = {},
): string {
if (!money) return "—";
const [integerPart, fractionPart = ""] = money.value.split(".", DECIMAL_PART_COUNT);
const normalizedFraction = withZeroCents ? fractionPart.padEnd(CENTS_PRECISION, "0") : fractionPart;
const decimal = normalizedFraction ? `${integerPart}.${normalizedFraction}` : integerPart;
const [integerPart, fractionPart = ""] = money.value.split(
".",
DECIMAL_PART_COUNT,
);
const normalizedFraction = withZeroCents
? fractionPart.padEnd(CENTS_PRECISION, "0")
: fractionPart;
const decimal = normalizedFraction
? `${integerPart}.${normalizedFraction}`
: integerPart;
const currency = money.currency === "RUB" ? "₽" : money.currency;
return `${formatDecimal(decimal)} ${currency}`;
}
@@ -51,14 +69,22 @@ function formatSnapshotTime(value: string): string {
const logoSize = 160;
function instrumentLogoUrl(logoName: null | string | undefined): null | string {
function formatChartValue(value: number) {
return new Intl.NumberFormat("ru-RU", { maximumFractionDigits: 4 }).format(
value,
);
}
function instrumentLogoUrl(logoName?: null | string): null | string {
const stem = logoName?.trim().replace(/\.png$/i, "");
return stem
? `https://invest-brands.cdn-tinkoff.ru/${stem}x${logoSize}.png`
: /* eslint-disable-line unicorn/no-null -- The existing formatter contract uses null for unavailable data. */ null;
: null; // eslint-disable-line unicorn/no-null -- The existing formatter contract uses null for unavailable data.
}
export {
formatChartValue,
formatDate,
formatDecimal,
formatMoney,