subunit-money 2.1.0 → 3.0.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/README.md +6 -0
- package/dist/money.d.ts +1 -11
- package/dist/money.js +55 -73
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -228,6 +228,12 @@ const loaded = new Money('USD', row.price) // Works perfectly
|
|
|
228
228
|
|
|
229
229
|
Use `toNumber()` only when you explicitly need numeric calculations.
|
|
230
230
|
|
|
231
|
+
## Choosing the Right Money Library
|
|
232
|
+
|
|
233
|
+
**subunit-money** sits between currency.js (pragmatic but imprecise) and dinero.js (precise but ceremony-heavy). If you want BigInt precision with method-chaining ergonomics, and you're onboard with banker's rounding as the sensible default, this is your library.
|
|
234
|
+
|
|
235
|
+
See **[CHOOSING-A-MONEY-LIBRARY.md](./CHOOSING-A-MONEY-LIBRARY.md)** for a detailed comparison of JavaScript money/precision libraries.
|
|
236
|
+
|
|
231
237
|
## Requirements
|
|
232
238
|
|
|
233
239
|
- Node.js 18+
|
package/dist/money.d.ts
CHANGED
|
@@ -59,13 +59,7 @@ export declare class Money<C extends string = string> {
|
|
|
59
59
|
* Multiply by a factor.
|
|
60
60
|
*
|
|
61
61
|
* DESIGN: Rounds immediately after multiplication using banker's rounding
|
|
62
|
-
* (round half-to-even). This prevents the "split penny problem"
|
|
63
|
-
* line-item rounding differs from deferred rounding:
|
|
64
|
-
* Per-item: $1.65 tax × 10 items = $16.50 ✓ (matches receipt)
|
|
65
|
-
* Deferred: 10 × $1.649175 = $16.49 ✗ (missing penny)
|
|
66
|
-
*
|
|
67
|
-
* For chained calculations without intermediate rounding, perform arithmetic
|
|
68
|
-
* in Number space first, then create a Money object with the final result.
|
|
62
|
+
* (round half-to-even). This prevents the "split penny problem".
|
|
69
63
|
*/
|
|
70
64
|
multiply(factor: number): Money<C>;
|
|
71
65
|
/**
|
|
@@ -74,10 +68,6 @@ export declare class Money<C extends string = string> {
|
|
|
74
68
|
*
|
|
75
69
|
* @param proportions - Array of proportions (e.g., [1, 1, 1] for three-way split)
|
|
76
70
|
* @returns Array of Money objects that sum to the original amount
|
|
77
|
-
*
|
|
78
|
-
* @example
|
|
79
|
-
* new Money('USD', '100').allocate([1, 1, 1])
|
|
80
|
-
* // Returns: [Money('33.34'), Money('33.33'), Money('33.33')]
|
|
81
71
|
*/
|
|
82
72
|
allocate(proportions: number[]): Money<C>[];
|
|
83
73
|
/**
|
package/dist/money.js
CHANGED
|
@@ -19,14 +19,11 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
19
19
|
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
20
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
21
21
|
};
|
|
22
|
-
var _Money_instances, _a,
|
|
22
|
+
var _Money_instances, _a, _Money_subunits, _Money_currencyDef, _Money_parseAmount, _Money_assertSameCurrency, _Money_getInternalValue, _Money_parseFactor, _Money_roundedDivide, _Money_createFromSubunits, _Money_formatSubunits;
|
|
23
23
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
24
|
exports.Money = void 0;
|
|
25
25
|
const errors_js_1 = require("./errors.js");
|
|
26
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);
|
|
30
27
|
/**
|
|
31
28
|
* Money class - represents a monetary amount in a specific currency.
|
|
32
29
|
*
|
|
@@ -50,8 +47,8 @@ class Money {
|
|
|
50
47
|
*/
|
|
51
48
|
constructor(currency, amount) {
|
|
52
49
|
_Money_instances.add(this);
|
|
53
|
-
// Private BigInt storage -
|
|
54
|
-
|
|
50
|
+
// Private BigInt storage - stores currency native subunits directly
|
|
51
|
+
_Money_subunits.set(this, void 0);
|
|
55
52
|
_Money_currencyDef.set(this, void 0);
|
|
56
53
|
const currencyDef = (0, currency_js_1.getCurrency)(currency);
|
|
57
54
|
if (!currencyDef) {
|
|
@@ -59,7 +56,7 @@ class Money {
|
|
|
59
56
|
}
|
|
60
57
|
this.currency = currency;
|
|
61
58
|
__classPrivateFieldSet(this, _Money_currencyDef, currencyDef, "f");
|
|
62
|
-
__classPrivateFieldSet(this,
|
|
59
|
+
__classPrivateFieldSet(this, _Money_subunits, __classPrivateFieldGet(this, _Money_instances, "m", _Money_parseAmount).call(this, amount), "f");
|
|
63
60
|
}
|
|
64
61
|
/**
|
|
65
62
|
* The amount as a formatted string with correct decimal places.
|
|
@@ -69,10 +66,8 @@ class Money {
|
|
|
69
66
|
*/
|
|
70
67
|
get amount() {
|
|
71
68
|
const decimals = __classPrivateFieldGet(this, _Money_currencyDef, "f").decimalDigits;
|
|
72
|
-
const
|
|
73
|
-
const
|
|
74
|
-
const isNegative = adjusted < 0n;
|
|
75
|
-
const abs = isNegative ? -adjusted : adjusted;
|
|
69
|
+
const abs = __classPrivateFieldGet(this, _Money_subunits, "f") < 0n ? -__classPrivateFieldGet(this, _Money_subunits, "f") : __classPrivateFieldGet(this, _Money_subunits, "f");
|
|
70
|
+
const isNegative = __classPrivateFieldGet(this, _Money_subunits, "f") < 0n;
|
|
76
71
|
if (decimals === 0) {
|
|
77
72
|
return `${isNegative ? '-' : ''}${abs}`;
|
|
78
73
|
}
|
|
@@ -89,8 +84,8 @@ class Money {
|
|
|
89
84
|
*/
|
|
90
85
|
add(other) {
|
|
91
86
|
__classPrivateFieldGet(this, _Money_instances, "m", _Money_assertSameCurrency).call(this, other);
|
|
92
|
-
const result = __classPrivateFieldGet(this,
|
|
93
|
-
return __classPrivateFieldGet(_a, _a, "m",
|
|
87
|
+
const result = __classPrivateFieldGet(this, _Money_subunits, "f") + __classPrivateFieldGet(other, _Money_instances, "m", _Money_getInternalValue).call(other);
|
|
88
|
+
return __classPrivateFieldGet(_a, _a, "m", _Money_createFromSubunits).call(_a, result, this.currency, __classPrivateFieldGet(this, _Money_currencyDef, "f"));
|
|
94
89
|
}
|
|
95
90
|
/**
|
|
96
91
|
* Subtract another Money amount.
|
|
@@ -98,30 +93,24 @@ class Money {
|
|
|
98
93
|
*/
|
|
99
94
|
subtract(other) {
|
|
100
95
|
__classPrivateFieldGet(this, _Money_instances, "m", _Money_assertSameCurrency).call(this, other);
|
|
101
|
-
const result = __classPrivateFieldGet(this,
|
|
102
|
-
return __classPrivateFieldGet(_a, _a, "m",
|
|
96
|
+
const result = __classPrivateFieldGet(this, _Money_subunits, "f") - __classPrivateFieldGet(other, _Money_instances, "m", _Money_getInternalValue).call(other);
|
|
97
|
+
return __classPrivateFieldGet(_a, _a, "m", _Money_createFromSubunits).call(_a, result, this.currency, __classPrivateFieldGet(this, _Money_currencyDef, "f"));
|
|
103
98
|
}
|
|
104
99
|
/**
|
|
105
100
|
* Multiply by a factor.
|
|
106
101
|
*
|
|
107
102
|
* 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.
|
|
103
|
+
* (round half-to-even). This prevents the "split penny problem".
|
|
115
104
|
*/
|
|
116
105
|
multiply(factor) {
|
|
117
106
|
if (typeof factor !== 'number' || !Number.isFinite(factor)) {
|
|
118
107
|
throw new TypeError(`Factor must be a finite number, got: ${factor}`);
|
|
119
108
|
}
|
|
120
|
-
const
|
|
121
|
-
const
|
|
122
|
-
const
|
|
123
|
-
const result = __classPrivateFieldGet(_a, _a, "m", _Money_roundedDivide).call(_a, product,
|
|
124
|
-
return __classPrivateFieldGet(_a, _a, "m",
|
|
109
|
+
const { value: factorValue, scale } = __classPrivateFieldGet(_a, _a, "m", _Money_parseFactor).call(_a, factor);
|
|
110
|
+
const product = __classPrivateFieldGet(this, _Money_subunits, "f") * factorValue;
|
|
111
|
+
const divisor = 10n ** scale;
|
|
112
|
+
const result = __classPrivateFieldGet(_a, _a, "m", _Money_roundedDivide).call(_a, product, divisor);
|
|
113
|
+
return __classPrivateFieldGet(_a, _a, "m", _Money_createFromSubunits).call(_a, result, this.currency, __classPrivateFieldGet(this, _Money_currencyDef, "f"));
|
|
125
114
|
}
|
|
126
115
|
/**
|
|
127
116
|
* Allocate this amount proportionally.
|
|
@@ -129,10 +118,6 @@ class Money {
|
|
|
129
118
|
*
|
|
130
119
|
* @param proportions - Array of proportions (e.g., [1, 1, 1] for three-way split)
|
|
131
120
|
* @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
121
|
*/
|
|
137
122
|
allocate(proportions) {
|
|
138
123
|
if (!Array.isArray(proportions) || proportions.length === 0) {
|
|
@@ -147,10 +132,7 @@ class Money {
|
|
|
147
132
|
if (total <= 0) {
|
|
148
133
|
throw new TypeError('Sum of proportions must be positive');
|
|
149
134
|
}
|
|
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;
|
|
135
|
+
const totalSubunits = __classPrivateFieldGet(this, _Money_subunits, "f");
|
|
154
136
|
// Calculate base allocations
|
|
155
137
|
const allocations = proportions.map((p) => {
|
|
156
138
|
return (totalSubunits * BigInt(Math.round(p * 1000000))) / BigInt(Math.round(total * 1000000));
|
|
@@ -170,8 +152,7 @@ class Money {
|
|
|
170
152
|
}
|
|
171
153
|
// Convert back to Money objects
|
|
172
154
|
return allocations.map((subunits) => {
|
|
173
|
-
|
|
174
|
-
return __classPrivateFieldGet(_a, _a, "m", _Money_createFromInternal).call(_a, internalValue, this.currency, __classPrivateFieldGet(this, _Money_currencyDef, "f"));
|
|
155
|
+
return __classPrivateFieldGet(_a, _a, "m", _Money_createFromSubunits).call(_a, subunits, this.currency, __classPrivateFieldGet(this, _Money_currencyDef, "f"));
|
|
175
156
|
});
|
|
176
157
|
}
|
|
177
158
|
// ============ Comparison Operations ============
|
|
@@ -181,7 +162,7 @@ class Money {
|
|
|
181
162
|
*/
|
|
182
163
|
equalTo(other) {
|
|
183
164
|
__classPrivateFieldGet(this, _Money_instances, "m", _Money_assertSameCurrency).call(this, other);
|
|
184
|
-
return __classPrivateFieldGet(this,
|
|
165
|
+
return __classPrivateFieldGet(this, _Money_subunits, "f") === __classPrivateFieldGet(other, _Money_instances, "m", _Money_getInternalValue).call(other);
|
|
185
166
|
}
|
|
186
167
|
/**
|
|
187
168
|
* Check if this amount is greater than another.
|
|
@@ -189,7 +170,7 @@ class Money {
|
|
|
189
170
|
*/
|
|
190
171
|
greaterThan(other) {
|
|
191
172
|
__classPrivateFieldGet(this, _Money_instances, "m", _Money_assertSameCurrency).call(this, other);
|
|
192
|
-
return __classPrivateFieldGet(this,
|
|
173
|
+
return __classPrivateFieldGet(this, _Money_subunits, "f") > __classPrivateFieldGet(other, _Money_instances, "m", _Money_getInternalValue).call(other);
|
|
193
174
|
}
|
|
194
175
|
/**
|
|
195
176
|
* Check if this amount is less than another.
|
|
@@ -197,7 +178,7 @@ class Money {
|
|
|
197
178
|
*/
|
|
198
179
|
lessThan(other) {
|
|
199
180
|
__classPrivateFieldGet(this, _Money_instances, "m", _Money_assertSameCurrency).call(this, other);
|
|
200
|
-
return __classPrivateFieldGet(this,
|
|
181
|
+
return __classPrivateFieldGet(this, _Money_subunits, "f") < __classPrivateFieldGet(other, _Money_instances, "m", _Money_getInternalValue).call(other);
|
|
201
182
|
}
|
|
202
183
|
/**
|
|
203
184
|
* Check if this amount is greater than or equal to another.
|
|
@@ -205,7 +186,7 @@ class Money {
|
|
|
205
186
|
*/
|
|
206
187
|
greaterThanOrEqual(other) {
|
|
207
188
|
__classPrivateFieldGet(this, _Money_instances, "m", _Money_assertSameCurrency).call(this, other);
|
|
208
|
-
return __classPrivateFieldGet(this,
|
|
189
|
+
return __classPrivateFieldGet(this, _Money_subunits, "f") >= __classPrivateFieldGet(other, _Money_instances, "m", _Money_getInternalValue).call(other);
|
|
209
190
|
}
|
|
210
191
|
/**
|
|
211
192
|
* Check if this amount is less than or equal to another.
|
|
@@ -213,25 +194,25 @@ class Money {
|
|
|
213
194
|
*/
|
|
214
195
|
lessThanOrEqual(other) {
|
|
215
196
|
__classPrivateFieldGet(this, _Money_instances, "m", _Money_assertSameCurrency).call(this, other);
|
|
216
|
-
return __classPrivateFieldGet(this,
|
|
197
|
+
return __classPrivateFieldGet(this, _Money_subunits, "f") <= __classPrivateFieldGet(other, _Money_instances, "m", _Money_getInternalValue).call(other);
|
|
217
198
|
}
|
|
218
199
|
/**
|
|
219
200
|
* Check if this amount is zero.
|
|
220
201
|
*/
|
|
221
202
|
isZero() {
|
|
222
|
-
return __classPrivateFieldGet(this,
|
|
203
|
+
return __classPrivateFieldGet(this, _Money_subunits, "f") === 0n;
|
|
223
204
|
}
|
|
224
205
|
/**
|
|
225
206
|
* Check if this amount is positive (greater than zero).
|
|
226
207
|
*/
|
|
227
208
|
isPositive() {
|
|
228
|
-
return __classPrivateFieldGet(this,
|
|
209
|
+
return __classPrivateFieldGet(this, _Money_subunits, "f") > 0n;
|
|
229
210
|
}
|
|
230
211
|
/**
|
|
231
212
|
* Check if this amount is negative (less than zero).
|
|
232
213
|
*/
|
|
233
214
|
isNegative() {
|
|
234
|
-
return __classPrivateFieldGet(this,
|
|
215
|
+
return __classPrivateFieldGet(this, _Money_subunits, "f") < 0n;
|
|
235
216
|
}
|
|
236
217
|
// ============ Serialization ============
|
|
237
218
|
/**
|
|
@@ -261,9 +242,7 @@ class Money {
|
|
|
261
242
|
* Useful for database storage (Stripe-style integer storage).
|
|
262
243
|
*/
|
|
263
244
|
toSubunits() {
|
|
264
|
-
|
|
265
|
-
const divisor = 10n ** BigInt(INTERNAL_PRECISION - decimals);
|
|
266
|
-
return __classPrivateFieldGet(this, _Money_value, "f") / divisor;
|
|
245
|
+
return __classPrivateFieldGet(this, _Money_subunits, "f");
|
|
267
246
|
}
|
|
268
247
|
// ============ Static Factory Methods ============
|
|
269
248
|
/**
|
|
@@ -282,9 +261,7 @@ class Money {
|
|
|
282
261
|
throw new errors_js_1.CurrencyUnknownError(currency);
|
|
283
262
|
}
|
|
284
263
|
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);
|
|
264
|
+
return __classPrivateFieldGet(_a, _a, "m", _Money_createFromSubunits).call(_a, bigintSubunits, currency, currencyDef);
|
|
288
265
|
}
|
|
289
266
|
/**
|
|
290
267
|
* Compare two Money objects (for use with Array.sort).
|
|
@@ -310,21 +287,17 @@ class Money {
|
|
|
310
287
|
}
|
|
311
288
|
}
|
|
312
289
|
exports.Money = Money;
|
|
313
|
-
_a = Money,
|
|
314
|
-
// Convert to string for consistent parsing
|
|
290
|
+
_a = Money, _Money_subunits = new WeakMap(), _Money_currencyDef = new WeakMap(), _Money_instances = new WeakSet(), _Money_parseAmount = function _Money_parseAmount(amount) {
|
|
315
291
|
const str = typeof amount === 'number' ? String(amount) : amount;
|
|
316
|
-
// Validate format: optional minus, digits, optional decimal part
|
|
317
292
|
const match = str.match(/^(-)?(\d+)(?:\.(\d+))?$/);
|
|
318
293
|
if (!match) {
|
|
319
294
|
throw new errors_js_1.AmountError(amount);
|
|
320
295
|
}
|
|
321
296
|
const [, sign, whole, frac = ''] = match;
|
|
322
|
-
// Check decimal places don't exceed currency limit
|
|
323
297
|
if (frac.length > __classPrivateFieldGet(this, _Money_currencyDef, "f").decimalDigits) {
|
|
324
298
|
throw new errors_js_1.SubunitError(this.currency, __classPrivateFieldGet(this, _Money_currencyDef, "f").decimalDigits);
|
|
325
299
|
}
|
|
326
|
-
|
|
327
|
-
const paddedFrac = frac.padEnd(INTERNAL_PRECISION, '0');
|
|
300
|
+
const paddedFrac = frac.padEnd(__classPrivateFieldGet(this, _Money_currencyDef, "f").decimalDigits, '0');
|
|
328
301
|
const combined = BigInt(whole + paddedFrac);
|
|
329
302
|
return sign === '-' ? -combined : combined;
|
|
330
303
|
}, _Money_assertSameCurrency = function _Money_assertSameCurrency(other) {
|
|
@@ -332,7 +305,26 @@ _a = Money, _Money_value = new WeakMap(), _Money_currencyDef = new WeakMap(), _M
|
|
|
332
305
|
throw new errors_js_1.CurrencyMismatchError(this.currency, other.currency);
|
|
333
306
|
}
|
|
334
307
|
}, _Money_getInternalValue = function _Money_getInternalValue() {
|
|
335
|
-
return __classPrivateFieldGet(this,
|
|
308
|
+
return __classPrivateFieldGet(this, _Money_subunits, "f");
|
|
309
|
+
}, _Money_parseFactor = function _Money_parseFactor(factor) {
|
|
310
|
+
const str = String(factor);
|
|
311
|
+
const [base, exponent] = str.split('e');
|
|
312
|
+
const baseMatch = base.match(/^(-)?(\d+)(?:\.(\d+))?$/);
|
|
313
|
+
if (!baseMatch) {
|
|
314
|
+
// Fallback for unlikely cases, though String(number) should strictly produce valid formats
|
|
315
|
+
throw new TypeError(`Invalid factor format: ${str}`);
|
|
316
|
+
}
|
|
317
|
+
const [, sign, whole, frac = ''] = baseMatch;
|
|
318
|
+
const baseValue = BigInt((sign || '') + whole + frac);
|
|
319
|
+
const baseDecimals = frac.length;
|
|
320
|
+
const exp = exponent ? Number(exponent) : 0;
|
|
321
|
+
const netExp = exp - baseDecimals;
|
|
322
|
+
if (netExp >= 0) {
|
|
323
|
+
return { value: baseValue * 10n ** BigInt(netExp), scale: 0n };
|
|
324
|
+
}
|
|
325
|
+
else {
|
|
326
|
+
return { value: baseValue, scale: BigInt(-netExp) };
|
|
327
|
+
}
|
|
336
328
|
}, _Money_roundedDivide = function _Money_roundedDivide(numerator, denominator) {
|
|
337
329
|
if (denominator === 1n)
|
|
338
330
|
return numerator;
|
|
@@ -353,22 +345,12 @@ _a = Money, _Money_value = new WeakMap(), _Money_currencyDef = new WeakMap(), _M
|
|
|
353
345
|
return numerator < 0n ? quotient - 1n : quotient + 1n;
|
|
354
346
|
}
|
|
355
347
|
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) {
|
|
348
|
+
}, _Money_createFromSubunits = function _Money_createFromSubunits(subunits, currency, currencyDef) {
|
|
349
|
+
return new _a(currency, __classPrivateFieldGet(_a, _a, "m", _Money_formatSubunits).call(_a, subunits, currencyDef));
|
|
350
|
+
}, _Money_formatSubunits = function _Money_formatSubunits(subunits, currencyDef) {
|
|
367
351
|
const decimals = currencyDef.decimalDigits;
|
|
368
|
-
const
|
|
369
|
-
const
|
|
370
|
-
const isNegative = adjusted < 0n;
|
|
371
|
-
const abs = isNegative ? -adjusted : adjusted;
|
|
352
|
+
const abs = subunits < 0n ? -subunits : subunits;
|
|
353
|
+
const isNegative = subunits < 0n;
|
|
372
354
|
if (decimals === 0) {
|
|
373
355
|
return `${isNegative ? '-' : ''}${abs}`;
|
|
374
356
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "subunit-money",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.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",
|
|
@@ -23,6 +23,7 @@
|
|
|
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",
|
|
@@ -51,6 +52,7 @@
|
|
|
51
52
|
},
|
|
52
53
|
"devDependencies": {
|
|
53
54
|
"@types/node": "^20.0.0",
|
|
55
|
+
"fast-check": "^4.5.3",
|
|
54
56
|
"tsx": "^4.0.0",
|
|
55
57
|
"typescript": "^5.0.0"
|
|
56
58
|
}
|