subunit-money 2.1.1 → 3.1.0
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/cjs/currency.d.ts +38 -0
- package/dist/cjs/currency.js +56 -0
- package/dist/cjs/errors.d.ts +52 -0
- package/dist/cjs/errors.js +80 -0
- package/dist/cjs/exchange-rate-service.d.ts +96 -0
- package/dist/cjs/exchange-rate-service.js +174 -0
- package/dist/cjs/index.d.ts +22 -0
- package/dist/cjs/index.js +58 -0
- package/dist/cjs/money-converter.d.ts +82 -0
- package/dist/cjs/money-converter.js +172 -0
- package/dist/cjs/money.d.ts +146 -0
- package/dist/cjs/money.js +362 -0
- package/dist/currency.js +6 -14
- package/dist/errors.js +5 -13
- package/dist/exchange-rate-service.js +1 -5
- package/dist/index.js +8 -28
- package/dist/money-converter.js +11 -15
- package/dist/money.d.ts +1 -11
- package/dist/money.js +66 -88
- package/package.json +3 -2
package/dist/money.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Money - An immutable value object for monetary amounts.
|
|
4
3
|
*
|
|
@@ -19,14 +18,9 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
19
18
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
20
19
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
21
20
|
};
|
|
22
|
-
var _Money_instances, _a,
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const errors_js_1 = require("./errors.js");
|
|
26
|
-
const currency_js_1 = require("./currency.js");
|
|
27
|
-
// Internal precision: 8 decimal places (supports Bitcoin and most cryptocurrencies)
|
|
28
|
-
const INTERNAL_PRECISION = 8;
|
|
29
|
-
const PRECISION_MULTIPLIER = 10n ** BigInt(INTERNAL_PRECISION);
|
|
21
|
+
var _Money_instances, _a, _Money_subunits, _Money_currencyDef, _Money_parseAmount, _Money_assertSameCurrency, _Money_getInternalValue, _Money_parseFactor, _Money_roundedDivide, _Money_createFromSubunits, _Money_formatSubunits;
|
|
22
|
+
import { CurrencyMismatchError, CurrencyUnknownError, SubunitError, AmountError, } from './errors.js';
|
|
23
|
+
import { getCurrency } from './currency.js';
|
|
30
24
|
/**
|
|
31
25
|
* Money class - represents a monetary amount in a specific currency.
|
|
32
26
|
*
|
|
@@ -38,7 +32,7 @@ const PRECISION_MULTIPLIER = 10n ** BigInt(INTERNAL_PRECISION);
|
|
|
38
32
|
* const total = price.add(tax)
|
|
39
33
|
* console.log(total.amount) // "21.59"
|
|
40
34
|
*/
|
|
41
|
-
class Money {
|
|
35
|
+
export class Money {
|
|
42
36
|
/**
|
|
43
37
|
* Create a new Money instance.
|
|
44
38
|
*
|
|
@@ -50,16 +44,16 @@ class Money {
|
|
|
50
44
|
*/
|
|
51
45
|
constructor(currency, amount) {
|
|
52
46
|
_Money_instances.add(this);
|
|
53
|
-
// Private BigInt storage -
|
|
54
|
-
|
|
47
|
+
// Private BigInt storage - stores currency native subunits directly
|
|
48
|
+
_Money_subunits.set(this, void 0);
|
|
55
49
|
_Money_currencyDef.set(this, void 0);
|
|
56
|
-
const currencyDef =
|
|
50
|
+
const currencyDef = getCurrency(currency);
|
|
57
51
|
if (!currencyDef) {
|
|
58
|
-
throw new
|
|
52
|
+
throw new CurrencyUnknownError(currency);
|
|
59
53
|
}
|
|
60
54
|
this.currency = currency;
|
|
61
55
|
__classPrivateFieldSet(this, _Money_currencyDef, currencyDef, "f");
|
|
62
|
-
__classPrivateFieldSet(this,
|
|
56
|
+
__classPrivateFieldSet(this, _Money_subunits, __classPrivateFieldGet(this, _Money_instances, "m", _Money_parseAmount).call(this, amount), "f");
|
|
63
57
|
}
|
|
64
58
|
/**
|
|
65
59
|
* The amount as a formatted string with correct decimal places.
|
|
@@ -69,10 +63,8 @@ class Money {
|
|
|
69
63
|
*/
|
|
70
64
|
get amount() {
|
|
71
65
|
const decimals = __classPrivateFieldGet(this, _Money_currencyDef, "f").decimalDigits;
|
|
72
|
-
const
|
|
73
|
-
const
|
|
74
|
-
const isNegative = adjusted < 0n;
|
|
75
|
-
const abs = isNegative ? -adjusted : adjusted;
|
|
66
|
+
const abs = __classPrivateFieldGet(this, _Money_subunits, "f") < 0n ? -__classPrivateFieldGet(this, _Money_subunits, "f") : __classPrivateFieldGet(this, _Money_subunits, "f");
|
|
67
|
+
const isNegative = __classPrivateFieldGet(this, _Money_subunits, "f") < 0n;
|
|
76
68
|
if (decimals === 0) {
|
|
77
69
|
return `${isNegative ? '-' : ''}${abs}`;
|
|
78
70
|
}
|
|
@@ -89,8 +81,8 @@ class Money {
|
|
|
89
81
|
*/
|
|
90
82
|
add(other) {
|
|
91
83
|
__classPrivateFieldGet(this, _Money_instances, "m", _Money_assertSameCurrency).call(this, other);
|
|
92
|
-
const result = __classPrivateFieldGet(this,
|
|
93
|
-
return __classPrivateFieldGet(_a, _a, "m",
|
|
84
|
+
const result = __classPrivateFieldGet(this, _Money_subunits, "f") + __classPrivateFieldGet(other, _Money_instances, "m", _Money_getInternalValue).call(other);
|
|
85
|
+
return __classPrivateFieldGet(_a, _a, "m", _Money_createFromSubunits).call(_a, result, this.currency, __classPrivateFieldGet(this, _Money_currencyDef, "f"));
|
|
94
86
|
}
|
|
95
87
|
/**
|
|
96
88
|
* Subtract another Money amount.
|
|
@@ -98,30 +90,24 @@ class Money {
|
|
|
98
90
|
*/
|
|
99
91
|
subtract(other) {
|
|
100
92
|
__classPrivateFieldGet(this, _Money_instances, "m", _Money_assertSameCurrency).call(this, other);
|
|
101
|
-
const result = __classPrivateFieldGet(this,
|
|
102
|
-
return __classPrivateFieldGet(_a, _a, "m",
|
|
93
|
+
const result = __classPrivateFieldGet(this, _Money_subunits, "f") - __classPrivateFieldGet(other, _Money_instances, "m", _Money_getInternalValue).call(other);
|
|
94
|
+
return __classPrivateFieldGet(_a, _a, "m", _Money_createFromSubunits).call(_a, result, this.currency, __classPrivateFieldGet(this, _Money_currencyDef, "f"));
|
|
103
95
|
}
|
|
104
96
|
/**
|
|
105
97
|
* Multiply by a factor.
|
|
106
98
|
*
|
|
107
99
|
* DESIGN: Rounds immediately after multiplication using banker's rounding
|
|
108
|
-
* (round half-to-even). This prevents the "split penny problem"
|
|
109
|
-
* line-item rounding differs from deferred rounding:
|
|
110
|
-
* Per-item: $1.65 tax × 10 items = $16.50 ✓ (matches receipt)
|
|
111
|
-
* Deferred: 10 × $1.649175 = $16.49 ✗ (missing penny)
|
|
112
|
-
*
|
|
113
|
-
* For chained calculations without intermediate rounding, perform arithmetic
|
|
114
|
-
* in Number space first, then create a Money object with the final result.
|
|
100
|
+
* (round half-to-even). This prevents the "split penny problem".
|
|
115
101
|
*/
|
|
116
102
|
multiply(factor) {
|
|
117
103
|
if (typeof factor !== 'number' || !Number.isFinite(factor)) {
|
|
118
104
|
throw new TypeError(`Factor must be a finite number, got: ${factor}`);
|
|
119
105
|
}
|
|
120
|
-
const
|
|
121
|
-
const
|
|
122
|
-
const
|
|
123
|
-
const result = __classPrivateFieldGet(_a, _a, "m", _Money_roundedDivide).call(_a, product,
|
|
124
|
-
return __classPrivateFieldGet(_a, _a, "m",
|
|
106
|
+
const { value: factorValue, scale } = __classPrivateFieldGet(_a, _a, "m", _Money_parseFactor).call(_a, factor);
|
|
107
|
+
const product = __classPrivateFieldGet(this, _Money_subunits, "f") * factorValue;
|
|
108
|
+
const divisor = 10n ** scale;
|
|
109
|
+
const result = __classPrivateFieldGet(_a, _a, "m", _Money_roundedDivide).call(_a, product, divisor);
|
|
110
|
+
return __classPrivateFieldGet(_a, _a, "m", _Money_createFromSubunits).call(_a, result, this.currency, __classPrivateFieldGet(this, _Money_currencyDef, "f"));
|
|
125
111
|
}
|
|
126
112
|
/**
|
|
127
113
|
* Allocate this amount proportionally.
|
|
@@ -129,10 +115,6 @@ class Money {
|
|
|
129
115
|
*
|
|
130
116
|
* @param proportions - Array of proportions (e.g., [1, 1, 1] for three-way split)
|
|
131
117
|
* @returns Array of Money objects that sum to the original amount
|
|
132
|
-
*
|
|
133
|
-
* @example
|
|
134
|
-
* new Money('USD', '100').allocate([1, 1, 1])
|
|
135
|
-
* // Returns: [Money('33.34'), Money('33.33'), Money('33.33')]
|
|
136
118
|
*/
|
|
137
119
|
allocate(proportions) {
|
|
138
120
|
if (!Array.isArray(proportions) || proportions.length === 0) {
|
|
@@ -147,10 +129,7 @@ class Money {
|
|
|
147
129
|
if (total <= 0) {
|
|
148
130
|
throw new TypeError('Sum of proportions must be positive');
|
|
149
131
|
}
|
|
150
|
-
|
|
151
|
-
const decimals = __classPrivateFieldGet(this, _Money_currencyDef, "f").decimalDigits;
|
|
152
|
-
const subunitMultiplier = 10n ** BigInt(INTERNAL_PRECISION - decimals);
|
|
153
|
-
const totalSubunits = __classPrivateFieldGet(this, _Money_value, "f") / subunitMultiplier;
|
|
132
|
+
const totalSubunits = __classPrivateFieldGet(this, _Money_subunits, "f");
|
|
154
133
|
// Calculate base allocations
|
|
155
134
|
const allocations = proportions.map((p) => {
|
|
156
135
|
return (totalSubunits * BigInt(Math.round(p * 1000000))) / BigInt(Math.round(total * 1000000));
|
|
@@ -170,8 +149,7 @@ class Money {
|
|
|
170
149
|
}
|
|
171
150
|
// Convert back to Money objects
|
|
172
151
|
return allocations.map((subunits) => {
|
|
173
|
-
|
|
174
|
-
return __classPrivateFieldGet(_a, _a, "m", _Money_createFromInternal).call(_a, internalValue, this.currency, __classPrivateFieldGet(this, _Money_currencyDef, "f"));
|
|
152
|
+
return __classPrivateFieldGet(_a, _a, "m", _Money_createFromSubunits).call(_a, subunits, this.currency, __classPrivateFieldGet(this, _Money_currencyDef, "f"));
|
|
175
153
|
});
|
|
176
154
|
}
|
|
177
155
|
// ============ Comparison Operations ============
|
|
@@ -181,7 +159,7 @@ class Money {
|
|
|
181
159
|
*/
|
|
182
160
|
equalTo(other) {
|
|
183
161
|
__classPrivateFieldGet(this, _Money_instances, "m", _Money_assertSameCurrency).call(this, other);
|
|
184
|
-
return __classPrivateFieldGet(this,
|
|
162
|
+
return __classPrivateFieldGet(this, _Money_subunits, "f") === __classPrivateFieldGet(other, _Money_instances, "m", _Money_getInternalValue).call(other);
|
|
185
163
|
}
|
|
186
164
|
/**
|
|
187
165
|
* Check if this amount is greater than another.
|
|
@@ -189,7 +167,7 @@ class Money {
|
|
|
189
167
|
*/
|
|
190
168
|
greaterThan(other) {
|
|
191
169
|
__classPrivateFieldGet(this, _Money_instances, "m", _Money_assertSameCurrency).call(this, other);
|
|
192
|
-
return __classPrivateFieldGet(this,
|
|
170
|
+
return __classPrivateFieldGet(this, _Money_subunits, "f") > __classPrivateFieldGet(other, _Money_instances, "m", _Money_getInternalValue).call(other);
|
|
193
171
|
}
|
|
194
172
|
/**
|
|
195
173
|
* Check if this amount is less than another.
|
|
@@ -197,7 +175,7 @@ class Money {
|
|
|
197
175
|
*/
|
|
198
176
|
lessThan(other) {
|
|
199
177
|
__classPrivateFieldGet(this, _Money_instances, "m", _Money_assertSameCurrency).call(this, other);
|
|
200
|
-
return __classPrivateFieldGet(this,
|
|
178
|
+
return __classPrivateFieldGet(this, _Money_subunits, "f") < __classPrivateFieldGet(other, _Money_instances, "m", _Money_getInternalValue).call(other);
|
|
201
179
|
}
|
|
202
180
|
/**
|
|
203
181
|
* Check if this amount is greater than or equal to another.
|
|
@@ -205,7 +183,7 @@ class Money {
|
|
|
205
183
|
*/
|
|
206
184
|
greaterThanOrEqual(other) {
|
|
207
185
|
__classPrivateFieldGet(this, _Money_instances, "m", _Money_assertSameCurrency).call(this, other);
|
|
208
|
-
return __classPrivateFieldGet(this,
|
|
186
|
+
return __classPrivateFieldGet(this, _Money_subunits, "f") >= __classPrivateFieldGet(other, _Money_instances, "m", _Money_getInternalValue).call(other);
|
|
209
187
|
}
|
|
210
188
|
/**
|
|
211
189
|
* Check if this amount is less than or equal to another.
|
|
@@ -213,25 +191,25 @@ class Money {
|
|
|
213
191
|
*/
|
|
214
192
|
lessThanOrEqual(other) {
|
|
215
193
|
__classPrivateFieldGet(this, _Money_instances, "m", _Money_assertSameCurrency).call(this, other);
|
|
216
|
-
return __classPrivateFieldGet(this,
|
|
194
|
+
return __classPrivateFieldGet(this, _Money_subunits, "f") <= __classPrivateFieldGet(other, _Money_instances, "m", _Money_getInternalValue).call(other);
|
|
217
195
|
}
|
|
218
196
|
/**
|
|
219
197
|
* Check if this amount is zero.
|
|
220
198
|
*/
|
|
221
199
|
isZero() {
|
|
222
|
-
return __classPrivateFieldGet(this,
|
|
200
|
+
return __classPrivateFieldGet(this, _Money_subunits, "f") === 0n;
|
|
223
201
|
}
|
|
224
202
|
/**
|
|
225
203
|
* Check if this amount is positive (greater than zero).
|
|
226
204
|
*/
|
|
227
205
|
isPositive() {
|
|
228
|
-
return __classPrivateFieldGet(this,
|
|
206
|
+
return __classPrivateFieldGet(this, _Money_subunits, "f") > 0n;
|
|
229
207
|
}
|
|
230
208
|
/**
|
|
231
209
|
* Check if this amount is negative (less than zero).
|
|
232
210
|
*/
|
|
233
211
|
isNegative() {
|
|
234
|
-
return __classPrivateFieldGet(this,
|
|
212
|
+
return __classPrivateFieldGet(this, _Money_subunits, "f") < 0n;
|
|
235
213
|
}
|
|
236
214
|
// ============ Serialization ============
|
|
237
215
|
/**
|
|
@@ -261,9 +239,7 @@ class Money {
|
|
|
261
239
|
* Useful for database storage (Stripe-style integer storage).
|
|
262
240
|
*/
|
|
263
241
|
toSubunits() {
|
|
264
|
-
|
|
265
|
-
const divisor = 10n ** BigInt(INTERNAL_PRECISION - decimals);
|
|
266
|
-
return __classPrivateFieldGet(this, _Money_value, "f") / divisor;
|
|
242
|
+
return __classPrivateFieldGet(this, _Money_subunits, "f");
|
|
267
243
|
}
|
|
268
244
|
// ============ Static Factory Methods ============
|
|
269
245
|
/**
|
|
@@ -277,14 +253,12 @@ class Money {
|
|
|
277
253
|
* Useful for loading from database (Stripe-style integer storage).
|
|
278
254
|
*/
|
|
279
255
|
static fromSubunits(subunits, currency) {
|
|
280
|
-
const currencyDef =
|
|
256
|
+
const currencyDef = getCurrency(currency);
|
|
281
257
|
if (!currencyDef) {
|
|
282
|
-
throw new
|
|
258
|
+
throw new CurrencyUnknownError(currency);
|
|
283
259
|
}
|
|
284
260
|
const bigintSubunits = typeof subunits === 'number' ? BigInt(subunits) : subunits;
|
|
285
|
-
|
|
286
|
-
const internalValue = bigintSubunits * multiplier;
|
|
287
|
-
return __classPrivateFieldGet(_a, _a, "m", _Money_createFromInternal).call(_a, internalValue, currency, currencyDef);
|
|
261
|
+
return __classPrivateFieldGet(_a, _a, "m", _Money_createFromSubunits).call(_a, bigintSubunits, currency, currencyDef);
|
|
288
262
|
}
|
|
289
263
|
/**
|
|
290
264
|
* Compare two Money objects (for use with Array.sort).
|
|
@@ -292,7 +266,7 @@ class Money {
|
|
|
292
266
|
*/
|
|
293
267
|
static compare(a, b) {
|
|
294
268
|
if (a.currency !== b.currency) {
|
|
295
|
-
throw new
|
|
269
|
+
throw new CurrencyMismatchError(a.currency, b.currency);
|
|
296
270
|
}
|
|
297
271
|
const aVal = __classPrivateFieldGet(a, _Money_instances, "m", _Money_getInternalValue).call(a);
|
|
298
272
|
const bVal = __classPrivateFieldGet(b, _Money_instances, "m", _Money_getInternalValue).call(b);
|
|
@@ -309,30 +283,44 @@ class Money {
|
|
|
309
283
|
return new _a(currency, '0');
|
|
310
284
|
}
|
|
311
285
|
}
|
|
312
|
-
|
|
313
|
-
_a = Money, _Money_value = new WeakMap(), _Money_currencyDef = new WeakMap(), _Money_instances = new WeakSet(), _Money_parseAmount = function _Money_parseAmount(amount) {
|
|
314
|
-
// Convert to string for consistent parsing
|
|
286
|
+
_a = Money, _Money_subunits = new WeakMap(), _Money_currencyDef = new WeakMap(), _Money_instances = new WeakSet(), _Money_parseAmount = function _Money_parseAmount(amount) {
|
|
315
287
|
const str = typeof amount === 'number' ? String(amount) : amount;
|
|
316
|
-
// Validate format: optional minus, digits, optional decimal part
|
|
317
288
|
const match = str.match(/^(-)?(\d+)(?:\.(\d+))?$/);
|
|
318
289
|
if (!match) {
|
|
319
|
-
throw new
|
|
290
|
+
throw new AmountError(amount);
|
|
320
291
|
}
|
|
321
292
|
const [, sign, whole, frac = ''] = match;
|
|
322
|
-
// Check decimal places don't exceed currency limit
|
|
323
293
|
if (frac.length > __classPrivateFieldGet(this, _Money_currencyDef, "f").decimalDigits) {
|
|
324
|
-
throw new
|
|
294
|
+
throw new SubunitError(this.currency, __classPrivateFieldGet(this, _Money_currencyDef, "f").decimalDigits);
|
|
325
295
|
}
|
|
326
|
-
|
|
327
|
-
const paddedFrac = frac.padEnd(INTERNAL_PRECISION, '0');
|
|
296
|
+
const paddedFrac = frac.padEnd(__classPrivateFieldGet(this, _Money_currencyDef, "f").decimalDigits, '0');
|
|
328
297
|
const combined = BigInt(whole + paddedFrac);
|
|
329
298
|
return sign === '-' ? -combined : combined;
|
|
330
299
|
}, _Money_assertSameCurrency = function _Money_assertSameCurrency(other) {
|
|
331
300
|
if (this.currency !== other.currency) {
|
|
332
|
-
throw new
|
|
301
|
+
throw new CurrencyMismatchError(this.currency, other.currency);
|
|
333
302
|
}
|
|
334
303
|
}, _Money_getInternalValue = function _Money_getInternalValue() {
|
|
335
|
-
return __classPrivateFieldGet(this,
|
|
304
|
+
return __classPrivateFieldGet(this, _Money_subunits, "f");
|
|
305
|
+
}, _Money_parseFactor = function _Money_parseFactor(factor) {
|
|
306
|
+
const str = String(factor);
|
|
307
|
+
const [base, exponent] = str.split('e');
|
|
308
|
+
const baseMatch = base.match(/^(-)?(\d+)(?:\.(\d+))?$/);
|
|
309
|
+
if (!baseMatch) {
|
|
310
|
+
// Fallback for unlikely cases, though String(number) should strictly produce valid formats
|
|
311
|
+
throw new TypeError(`Invalid factor format: ${str}`);
|
|
312
|
+
}
|
|
313
|
+
const [, sign, whole, frac = ''] = baseMatch;
|
|
314
|
+
const baseValue = BigInt((sign || '') + whole + frac);
|
|
315
|
+
const baseDecimals = frac.length;
|
|
316
|
+
const exp = exponent ? Number(exponent) : 0;
|
|
317
|
+
const netExp = exp - baseDecimals;
|
|
318
|
+
if (netExp >= 0) {
|
|
319
|
+
return { value: baseValue * 10n ** BigInt(netExp), scale: 0n };
|
|
320
|
+
}
|
|
321
|
+
else {
|
|
322
|
+
return { value: baseValue, scale: BigInt(-netExp) };
|
|
323
|
+
}
|
|
336
324
|
}, _Money_roundedDivide = function _Money_roundedDivide(numerator, denominator) {
|
|
337
325
|
if (denominator === 1n)
|
|
338
326
|
return numerator;
|
|
@@ -353,22 +341,12 @@ _a = Money, _Money_value = new WeakMap(), _Money_currencyDef = new WeakMap(), _M
|
|
|
353
341
|
return numerator < 0n ? quotient - 1n : quotient + 1n;
|
|
354
342
|
}
|
|
355
343
|
return quotient;
|
|
356
|
-
},
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
Object.defineProperties(instance, {
|
|
360
|
-
currency: { value: currency, enumerable: true, writable: false },
|
|
361
|
-
});
|
|
362
|
-
// Access private fields via the class mechanism
|
|
363
|
-
// This is a workaround since we can't directly set #private fields on Object.create instances
|
|
364
|
-
// Instead, we'll use a different approach: call a private static method
|
|
365
|
-
return new _a(currency, __classPrivateFieldGet(_a, _a, "m", _Money_formatInternalValue).call(_a, value, currencyDef));
|
|
366
|
-
}, _Money_formatInternalValue = function _Money_formatInternalValue(value, currencyDef) {
|
|
344
|
+
}, _Money_createFromSubunits = function _Money_createFromSubunits(subunits, currency, currencyDef) {
|
|
345
|
+
return new _a(currency, __classPrivateFieldGet(_a, _a, "m", _Money_formatSubunits).call(_a, subunits, currencyDef));
|
|
346
|
+
}, _Money_formatSubunits = function _Money_formatSubunits(subunits, currencyDef) {
|
|
367
347
|
const decimals = currencyDef.decimalDigits;
|
|
368
|
-
const
|
|
369
|
-
const
|
|
370
|
-
const isNegative = adjusted < 0n;
|
|
371
|
-
const abs = isNegative ? -adjusted : adjusted;
|
|
348
|
+
const abs = subunits < 0n ? -subunits : subunits;
|
|
349
|
+
const isNegative = subunits < 0n;
|
|
372
350
|
if (decimals === 0) {
|
|
373
351
|
return `${isNegative ? '-' : ''}${abs}`;
|
|
374
352
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "subunit-money",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "A type-safe value object for monetary amounts with currency conversion support",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -18,11 +18,12 @@
|
|
|
18
18
|
"README.md"
|
|
19
19
|
],
|
|
20
20
|
"scripts": {
|
|
21
|
-
"build": "tsc",
|
|
21
|
+
"build": "tsc && tsc --module commonjs --outDir dist/cjs",
|
|
22
22
|
"test": "node --import tsx --test test/*.test.ts",
|
|
23
23
|
"lint": "tsc --noEmit",
|
|
24
24
|
"check-clean": "git diff --quiet && git diff --cached --quiet",
|
|
25
25
|
"preversion": "npm run check-clean && npm test",
|
|
26
|
+
"version": "npm run build && git add dist",
|
|
26
27
|
"postversion": "git push && git push --tags",
|
|
27
28
|
"prepublishOnly": "npm run check-clean && npm run build",
|
|
28
29
|
"release:patch": "npm version patch && npm publish",
|