@stll/money 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +27 -11
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -171,18 +171,34 @@ const toMajorUnits = ({ amountCents, currency }) => amountCents / 10 ** currency
|
|
|
171
171
|
* RangeError would take the whole board down with it.
|
|
172
172
|
*/
|
|
173
173
|
const formatMoneyCents = ({ amountCents, currency, locale, fractionDigits }) => {
|
|
174
|
-
const
|
|
175
|
-
|
|
176
|
-
|
|
174
|
+
const minorDigits = currencyMinorUnitDigits(currency);
|
|
175
|
+
const digits = fractionDigits ?? minorDigits;
|
|
176
|
+
if (!Number.isInteger(digits) || digits < 0 || digits > 100) return panic("Money fraction digits must be an integer from 0 to 100");
|
|
177
|
+
const magnitude = BigInt(Math.abs(cents(amountCents)));
|
|
178
|
+
const negative = amountCents < 0 || Object.is(amountCents, -0);
|
|
179
|
+
const displayUnits = digits >= minorDigits ? magnitude * 10n ** BigInt(digits - minorDigits) : (magnitude + 10n ** BigInt(minorDigits - digits) / 2n) / 10n ** BigInt(minorDigits - digits);
|
|
180
|
+
const scale = 10n ** BigInt(digits);
|
|
181
|
+
const whole = displayUnits / scale;
|
|
182
|
+
const fraction = (displayUnits % scale).toString().padStart(digits, "0");
|
|
183
|
+
const formatted = Result.try(() => {
|
|
184
|
+
const formatter = new Intl.NumberFormat(locale, {
|
|
185
|
+
style: "currency",
|
|
186
|
+
currency,
|
|
187
|
+
minimumFractionDigits: digits,
|
|
188
|
+
maximumFractionDigits: digits
|
|
189
|
+
});
|
|
190
|
+
const digitFormatter = new Intl.NumberFormat(locale, { useGrouping: false });
|
|
191
|
+
const localizedFraction = fraction.split("").map((digit) => digitFormatter.format(Number(digit))).join("");
|
|
192
|
+
const negativeSubunit = negative && whole === 0n;
|
|
193
|
+
let template = whole;
|
|
194
|
+
if (negative) template = negativeSubunit ? -1n : -whole;
|
|
195
|
+
return formatter.formatToParts(template).map((part) => {
|
|
196
|
+
if (part.type === "fraction") return localizedFraction;
|
|
197
|
+
if (negativeSubunit && part.type === "integer") return digitFormatter.format(0);
|
|
198
|
+
return part.value;
|
|
199
|
+
}).join("");
|
|
177
200
|
});
|
|
178
|
-
|
|
179
|
-
const formatted = Result.try(() => new Intl.NumberFormat(locale, {
|
|
180
|
-
style: "currency",
|
|
181
|
-
currency,
|
|
182
|
-
minimumFractionDigits: digits,
|
|
183
|
-
maximumFractionDigits: digits
|
|
184
|
-
}).format(major));
|
|
185
|
-
return formatted.isErr() ? `${major.toFixed(digits)} ${currency}` : formatted.value;
|
|
201
|
+
return formatted.isErr() ? `${negative ? "-" : ""}${whole}${digits === 0 ? "" : `.${fraction}`} ${currency}` : formatted.value;
|
|
186
202
|
};
|
|
187
203
|
//#endregion
|
|
188
204
|
//#region src/index.ts
|