// prettyBytes taken from https://github.com/sindresorhus/pretty-bytes /* eslint-disable no-param-reassign */ const BYTE_UNITS = ["B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]; const BIBYTE_UNITS = ["B", "kiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"]; const BIT_UNITS = ["b", "kbit", "Mbit", "Gbit", "Tbit", "Pbit", "Ebit", "Zbit", "Ybit"]; const BIBIT_UNITS = ["b", "kibit", "Mibit", "Gibit", "Tibit", "Pibit", "Eibit", "Zibit", "Yibit"]; /* Formats the given number using `Number#toLocaleString`. - If locale is a string, the value is expected to be a locale-key (for example: `de`). - If locale is true, the system default locale is used for translation. - If no value for locale is specified, the number is returned unmodified. */ const toLocaleString = (number, locale, options) => { let result = number; if (typeof locale === "string" || Array.isArray(locale)) { result = number.toLocaleString(locale, options); } else if (locale === true || options !== undefined) { result = number.toLocaleString(undefined, options); } return result; }; function prettyBytes(number, options) { if (!Number.isFinite(number)) { throw new TypeError(`Expected a finite number, got ${typeof number}: ${number}`); } options = { bits: false, binary: false, ...options, }; // eslint-disable-next-line no-nested-ternary const UNITS = options.bits ? (options.binary ? BIBIT_UNITS : BIT_UNITS) : options.binary ? BIBYTE_UNITS : BYTE_UNITS; if (options.signed && number === 0) { return ` 0 ${UNITS[0]}`; } const isNegative = number < 0; // eslint-disable-next-line no-nested-ternary const prefix = isNegative ? "-" : options.signed ? "+" : ""; if (isNegative) { number = -number; } let localeOptions; if (options.minimumFractionDigits !== undefined) { localeOptions = { minimumFractionDigits: options.minimumFractionDigits }; } if (options.maximumFractionDigits !== undefined) { localeOptions = { maximumFractionDigits: options.maximumFractionDigits, ...localeOptions }; } if (number < 1) { const numberString = toLocaleString(number, options.locale, localeOptions); return `${prefix + numberString} ${UNITS[0]}`; } const exponent = Math.min( Math.floor(options.binary ? Math.log(number) / Math.log(1024) : Math.log10(number) / 3), UNITS.length - 1 ); number /= (options.binary ? 1024 : 1000) ** exponent; if (!localeOptions) { number = number.toPrecision(3); } const numberString = toLocaleString(Number(number), options.locale, localeOptions); const unit = UNITS[exponent]; return `${prefix + numberString} ${unit}`; } module.exports = { i18n: { defaultLocale: "en", locales: ["en"], }, serializeConfig: false, use: [ { init: (i18next) => { i18next.services.formatter.add("bytes", (value, lng, options) => prettyBytes(parseFloat(value), { locale: lng, ...options }) ); i18next.services.formatter.add("rate", (value, lng, options) => { const k = options.binary ? 1024 : 1000; const sizes = options.bits ? (options.binary ? BIBIT_UNITS : BIT_UNITS) : (options.binary ? BIBYTE_UNITS : BYTE_UNITS); if (value === 0) return `0 ${sizes[0]}/s`; const dm = options.decimals ? options.decimals : 0; const i = options.binary ? 2 : Math.floor(Math.log(value) / Math.log(k)); const formatted = new Intl.NumberFormat(lng, { maximumFractionDigits: dm, minimumFractionDigits: dm }).format( parseFloat(value / k ** i) ); return `${formatted} ${sizes[i]}/s`; }); i18next.services.formatter.add("percent", (value, lng, options) => new Intl.NumberFormat(lng, { style: "percent", ...options }).format(parseFloat(value) / 100.0) ); }, type: "3rdParty", }, ], };