subunit-money 3.0.0 → 3.2.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/index.cjs +1314 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +416 -0
- package/dist/index.d.ts +405 -11
- package/dist/index.js +1273 -56
- package/dist/index.js.map +1 -0
- package/package.json +14 -7
- package/dist/currency.d.ts +0 -38
- package/dist/currency.js +0 -56
- package/dist/errors.d.ts +0 -52
- package/dist/errors.js +0 -80
- package/dist/exchange-rate-service.d.ts +0 -96
- package/dist/exchange-rate-service.js +0 -174
- package/dist/money-converter.d.ts +0 -82
- package/dist/money-converter.js +0 -172
- package/dist/money.d.ts +0 -146
- package/dist/money.js +0 -362
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,1314 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __typeError = (msg) => {
|
|
7
|
+
throw TypeError(msg);
|
|
8
|
+
};
|
|
9
|
+
var __export = (target, all) => {
|
|
10
|
+
for (var name in all)
|
|
11
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
12
|
+
};
|
|
13
|
+
var __copyProps = (to, from, except, desc) => {
|
|
14
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
15
|
+
for (let key of __getOwnPropNames(from))
|
|
16
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
17
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
18
|
+
}
|
|
19
|
+
return to;
|
|
20
|
+
};
|
|
21
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
22
|
+
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
23
|
+
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
24
|
+
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
25
|
+
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
26
|
+
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
|
|
27
|
+
|
|
28
|
+
// lib/index.ts
|
|
29
|
+
var index_exports = {};
|
|
30
|
+
__export(index_exports, {
|
|
31
|
+
AmountError: () => AmountError,
|
|
32
|
+
CurrencyMismatchError: () => CurrencyMismatchError,
|
|
33
|
+
CurrencyUnknownError: () => CurrencyUnknownError,
|
|
34
|
+
ExchangeRateError: () => ExchangeRateError,
|
|
35
|
+
ExchangeRateService: () => ExchangeRateService,
|
|
36
|
+
Money: () => Money,
|
|
37
|
+
MoneyConverter: () => MoneyConverter,
|
|
38
|
+
SubunitError: () => SubunitError,
|
|
39
|
+
clearCurrencies: () => clearCurrencies,
|
|
40
|
+
getAllCurrencies: () => getAllCurrencies,
|
|
41
|
+
getCurrency: () => getCurrency,
|
|
42
|
+
hasCurrency: () => hasCurrency,
|
|
43
|
+
loadCurrencyMap: () => loadCurrencyMap,
|
|
44
|
+
registerCurrency: () => registerCurrency
|
|
45
|
+
});
|
|
46
|
+
module.exports = __toCommonJS(index_exports);
|
|
47
|
+
|
|
48
|
+
// lib/errors.ts
|
|
49
|
+
var CurrencyMismatchError = class _CurrencyMismatchError extends TypeError {
|
|
50
|
+
constructor(fromCurrency, toCurrency) {
|
|
51
|
+
super(`Cannot operate on ${fromCurrency} and ${toCurrency} - currencies must match`);
|
|
52
|
+
this.name = "CurrencyMismatchError";
|
|
53
|
+
this.fromCurrency = fromCurrency;
|
|
54
|
+
this.toCurrency = toCurrency;
|
|
55
|
+
Error.captureStackTrace?.(this, _CurrencyMismatchError);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
var CurrencyUnknownError = class _CurrencyUnknownError extends TypeError {
|
|
59
|
+
constructor(currency) {
|
|
60
|
+
super(`Unknown currency '${currency}' - register it first with Money.registerCurrency()`);
|
|
61
|
+
this.name = "CurrencyUnknownError";
|
|
62
|
+
this.currency = currency;
|
|
63
|
+
Error.captureStackTrace?.(this, _CurrencyUnknownError);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
var SubunitError = class _SubunitError extends RangeError {
|
|
67
|
+
constructor(currency, maxDecimals) {
|
|
68
|
+
super(`${currency} only supports ${maxDecimals} decimal place(s)`);
|
|
69
|
+
this.name = "SubunitError";
|
|
70
|
+
this.currency = currency;
|
|
71
|
+
this.maxDecimals = maxDecimals;
|
|
72
|
+
Error.captureStackTrace?.(this, _SubunitError);
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
var AmountError = class _AmountError extends TypeError {
|
|
76
|
+
constructor(amount) {
|
|
77
|
+
super(`Invalid amount: ${JSON.stringify(amount)}`);
|
|
78
|
+
this.name = "AmountError";
|
|
79
|
+
this.amount = amount;
|
|
80
|
+
Error.captureStackTrace?.(this, _AmountError);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
var ExchangeRateError = class _ExchangeRateError extends Error {
|
|
84
|
+
constructor(fromCurrency, toCurrency) {
|
|
85
|
+
super(`No exchange rate available from ${fromCurrency} to ${toCurrency}`);
|
|
86
|
+
this.name = "ExchangeRateError";
|
|
87
|
+
this.fromCurrency = fromCurrency;
|
|
88
|
+
this.toCurrency = toCurrency;
|
|
89
|
+
Error.captureStackTrace?.(this, _ExchangeRateError);
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
// lib/currency.ts
|
|
94
|
+
var currencies = /* @__PURE__ */ new Map();
|
|
95
|
+
function registerCurrency(code, decimalDigits, displayDecimals) {
|
|
96
|
+
currencies.set(code, { code, decimalDigits, displayDecimals });
|
|
97
|
+
}
|
|
98
|
+
function getCurrency(code) {
|
|
99
|
+
return currencies.get(code);
|
|
100
|
+
}
|
|
101
|
+
function hasCurrency(code) {
|
|
102
|
+
return currencies.has(code);
|
|
103
|
+
}
|
|
104
|
+
function getAllCurrencies() {
|
|
105
|
+
return Array.from(currencies.values()).sort((a, b) => a.code.localeCompare(b.code));
|
|
106
|
+
}
|
|
107
|
+
function loadCurrencyMap(map) {
|
|
108
|
+
for (const [code, data] of Object.entries(map)) {
|
|
109
|
+
registerCurrency(code, data.decimal_digits);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
function clearCurrencies() {
|
|
113
|
+
currencies.clear();
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// lib/money.ts
|
|
117
|
+
var _subunits, _currencyDef, _Money_instances, parseAmount_fn, _Money_static, formatForDisplay_fn, assertSameCurrency_fn, getInternalValue_fn, parseFactor_fn, roundedDivide_fn, createFromSubunits_fn, formatSubunits_fn;
|
|
118
|
+
var _Money = class _Money {
|
|
119
|
+
/**
|
|
120
|
+
* Create a new Money instance.
|
|
121
|
+
*
|
|
122
|
+
* @param currency - ISO 4217 currency code (must be registered)
|
|
123
|
+
* @param amount - The amount as a number or string
|
|
124
|
+
* @throws {CurrencyUnknownError} If the currency is not registered
|
|
125
|
+
* @throws {AmountError} If the amount is not a valid number
|
|
126
|
+
* @throws {SubunitError} If the amount has more decimals than the currency allows
|
|
127
|
+
*/
|
|
128
|
+
constructor(currency, amount) {
|
|
129
|
+
__privateAdd(this, _Money_instances);
|
|
130
|
+
// Private BigInt storage - stores currency native subunits directly
|
|
131
|
+
__privateAdd(this, _subunits);
|
|
132
|
+
__privateAdd(this, _currencyDef);
|
|
133
|
+
var _a, _b;
|
|
134
|
+
const currencyDef = getCurrency(currency);
|
|
135
|
+
if (!currencyDef) {
|
|
136
|
+
throw new CurrencyUnknownError(currency);
|
|
137
|
+
}
|
|
138
|
+
this.currency = currency;
|
|
139
|
+
__privateSet(this, _currencyDef, currencyDef);
|
|
140
|
+
__privateSet(this, _subunits, __privateMethod(this, _Money_instances, parseAmount_fn).call(this, amount));
|
|
141
|
+
this.amount = __privateMethod(_a = _Money, _Money_static, formatSubunits_fn).call(_a, __privateGet(this, _subunits), currencyDef);
|
|
142
|
+
this.displayAmount = __privateMethod(_b = _Money, _Money_static, formatForDisplay_fn).call(_b, this.amount, currencyDef);
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Custom console inspection for Node.js.
|
|
146
|
+
* Shows the amount and currency instead of just the class name.
|
|
147
|
+
*/
|
|
148
|
+
[/* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom")]() {
|
|
149
|
+
return `Money { amount: '${this.displayAmount}', currency: '${this.currency}' }`;
|
|
150
|
+
}
|
|
151
|
+
// ============ Arithmetic Operations ============
|
|
152
|
+
/**
|
|
153
|
+
* Add another Money amount.
|
|
154
|
+
* @throws {CurrencyMismatchError} If currencies don't match
|
|
155
|
+
*/
|
|
156
|
+
add(other) {
|
|
157
|
+
var _a, _b;
|
|
158
|
+
__privateMethod(this, _Money_instances, assertSameCurrency_fn).call(this, other);
|
|
159
|
+
const result = __privateGet(this, _subunits) + __privateMethod(_a = other, _Money_instances, getInternalValue_fn).call(_a);
|
|
160
|
+
return __privateMethod(_b = _Money, _Money_static, createFromSubunits_fn).call(_b, result, this.currency, __privateGet(this, _currencyDef));
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Subtract another Money amount.
|
|
164
|
+
* @throws {CurrencyMismatchError} If currencies don't match
|
|
165
|
+
*/
|
|
166
|
+
subtract(other) {
|
|
167
|
+
var _a, _b;
|
|
168
|
+
__privateMethod(this, _Money_instances, assertSameCurrency_fn).call(this, other);
|
|
169
|
+
const result = __privateGet(this, _subunits) - __privateMethod(_a = other, _Money_instances, getInternalValue_fn).call(_a);
|
|
170
|
+
return __privateMethod(_b = _Money, _Money_static, createFromSubunits_fn).call(_b, result, this.currency, __privateGet(this, _currencyDef));
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Multiply by a factor.
|
|
174
|
+
*
|
|
175
|
+
* DESIGN: Rounds immediately after multiplication using banker's rounding
|
|
176
|
+
* (round half-to-even). This prevents the "split penny problem".
|
|
177
|
+
*/
|
|
178
|
+
multiply(factor) {
|
|
179
|
+
var _a, _b, _c;
|
|
180
|
+
if (typeof factor !== "number" || !Number.isFinite(factor)) {
|
|
181
|
+
throw new TypeError(`Factor must be a finite number, got: ${factor}`);
|
|
182
|
+
}
|
|
183
|
+
const { value: factorValue, scale } = __privateMethod(_a = _Money, _Money_static, parseFactor_fn).call(_a, factor);
|
|
184
|
+
const product = __privateGet(this, _subunits) * factorValue;
|
|
185
|
+
const divisor = 10n ** scale;
|
|
186
|
+
const result = __privateMethod(_b = _Money, _Money_static, roundedDivide_fn).call(_b, product, divisor);
|
|
187
|
+
return __privateMethod(_c = _Money, _Money_static, createFromSubunits_fn).call(_c, result, this.currency, __privateGet(this, _currencyDef));
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Allocate this amount proportionally.
|
|
191
|
+
* Handles remainder distribution to avoid losing pennies.
|
|
192
|
+
*
|
|
193
|
+
* @param proportions - Array of proportions (e.g., [1, 1, 1] for three-way split)
|
|
194
|
+
* @returns Array of Money objects that sum to the original amount
|
|
195
|
+
*/
|
|
196
|
+
allocate(proportions) {
|
|
197
|
+
if (!Array.isArray(proportions) || proportions.length === 0) {
|
|
198
|
+
throw new TypeError("Proportions must be a non-empty array");
|
|
199
|
+
}
|
|
200
|
+
for (const p of proportions) {
|
|
201
|
+
if (typeof p !== "number" || !Number.isFinite(p) || p < 0) {
|
|
202
|
+
throw new TypeError("All proportions must be non-negative finite numbers");
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
const total = proportions.reduce((sum, p) => sum + p, 0);
|
|
206
|
+
if (total <= 0) {
|
|
207
|
+
throw new TypeError("Sum of proportions must be positive");
|
|
208
|
+
}
|
|
209
|
+
const totalSubunits = __privateGet(this, _subunits);
|
|
210
|
+
const allocations = proportions.map((p) => {
|
|
211
|
+
return totalSubunits * BigInt(Math.round(p * 1e6)) / BigInt(Math.round(total * 1e6));
|
|
212
|
+
});
|
|
213
|
+
let remainder = totalSubunits - allocations.reduce((sum, a) => sum + a, 0n);
|
|
214
|
+
let i = 0;
|
|
215
|
+
while (remainder > 0n) {
|
|
216
|
+
allocations[i % allocations.length] += 1n;
|
|
217
|
+
remainder -= 1n;
|
|
218
|
+
i++;
|
|
219
|
+
}
|
|
220
|
+
while (remainder < 0n) {
|
|
221
|
+
allocations[i % allocations.length] -= 1n;
|
|
222
|
+
remainder += 1n;
|
|
223
|
+
i++;
|
|
224
|
+
}
|
|
225
|
+
return allocations.map((subunits) => {
|
|
226
|
+
var _a;
|
|
227
|
+
return __privateMethod(_a = _Money, _Money_static, createFromSubunits_fn).call(_a, subunits, this.currency, __privateGet(this, _currencyDef));
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
// ============ Comparison Operations ============
|
|
231
|
+
/**
|
|
232
|
+
* Check if this amount equals another.
|
|
233
|
+
* @throws {CurrencyMismatchError} If currencies don't match
|
|
234
|
+
*/
|
|
235
|
+
equalTo(other) {
|
|
236
|
+
var _a;
|
|
237
|
+
__privateMethod(this, _Money_instances, assertSameCurrency_fn).call(this, other);
|
|
238
|
+
return __privateGet(this, _subunits) === __privateMethod(_a = other, _Money_instances, getInternalValue_fn).call(_a);
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Check if this amount is greater than another.
|
|
242
|
+
* @throws {CurrencyMismatchError} If currencies don't match
|
|
243
|
+
*/
|
|
244
|
+
greaterThan(other) {
|
|
245
|
+
var _a;
|
|
246
|
+
__privateMethod(this, _Money_instances, assertSameCurrency_fn).call(this, other);
|
|
247
|
+
return __privateGet(this, _subunits) > __privateMethod(_a = other, _Money_instances, getInternalValue_fn).call(_a);
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Check if this amount is less than another.
|
|
251
|
+
* @throws {CurrencyMismatchError} If currencies don't match
|
|
252
|
+
*/
|
|
253
|
+
lessThan(other) {
|
|
254
|
+
var _a;
|
|
255
|
+
__privateMethod(this, _Money_instances, assertSameCurrency_fn).call(this, other);
|
|
256
|
+
return __privateGet(this, _subunits) < __privateMethod(_a = other, _Money_instances, getInternalValue_fn).call(_a);
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Check if this amount is greater than or equal to another.
|
|
260
|
+
* @throws {CurrencyMismatchError} If currencies don't match
|
|
261
|
+
*/
|
|
262
|
+
greaterThanOrEqual(other) {
|
|
263
|
+
var _a;
|
|
264
|
+
__privateMethod(this, _Money_instances, assertSameCurrency_fn).call(this, other);
|
|
265
|
+
return __privateGet(this, _subunits) >= __privateMethod(_a = other, _Money_instances, getInternalValue_fn).call(_a);
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Check if this amount is less than or equal to another.
|
|
269
|
+
* @throws {CurrencyMismatchError} If currencies don't match
|
|
270
|
+
*/
|
|
271
|
+
lessThanOrEqual(other) {
|
|
272
|
+
var _a;
|
|
273
|
+
__privateMethod(this, _Money_instances, assertSameCurrency_fn).call(this, other);
|
|
274
|
+
return __privateGet(this, _subunits) <= __privateMethod(_a = other, _Money_instances, getInternalValue_fn).call(_a);
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Check if this amount is zero.
|
|
278
|
+
*/
|
|
279
|
+
isZero() {
|
|
280
|
+
return __privateGet(this, _subunits) === 0n;
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Check if this amount is positive (greater than zero).
|
|
284
|
+
*/
|
|
285
|
+
isPositive() {
|
|
286
|
+
return __privateGet(this, _subunits) > 0n;
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Check if this amount is negative (less than zero).
|
|
290
|
+
*/
|
|
291
|
+
isNegative() {
|
|
292
|
+
return __privateGet(this, _subunits) < 0n;
|
|
293
|
+
}
|
|
294
|
+
// ============ Serialization ============
|
|
295
|
+
/**
|
|
296
|
+
* Convert to a plain object (safe for JSON).
|
|
297
|
+
*/
|
|
298
|
+
toJSON() {
|
|
299
|
+
return {
|
|
300
|
+
currency: this.currency,
|
|
301
|
+
amount: this.amount
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Convert to string representation.
|
|
306
|
+
*/
|
|
307
|
+
toString() {
|
|
308
|
+
return `${this.displayAmount} ${this.currency}`;
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Get the amount as a number (may lose precision for large values).
|
|
312
|
+
* Use with caution - prefer string-based operations.
|
|
313
|
+
*/
|
|
314
|
+
toNumber() {
|
|
315
|
+
return Number(this.amount);
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Get the amount in subunits (e.g., cents for USD).
|
|
319
|
+
* Useful for database storage (Stripe-style integer storage).
|
|
320
|
+
*/
|
|
321
|
+
toSubunits() {
|
|
322
|
+
return __privateGet(this, _subunits);
|
|
323
|
+
}
|
|
324
|
+
// ============ Static Factory Methods ============
|
|
325
|
+
/**
|
|
326
|
+
* Create a Money instance from a plain object.
|
|
327
|
+
*/
|
|
328
|
+
static fromObject(obj) {
|
|
329
|
+
return new _Money(obj.currency, obj.amount);
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Create a Money instance from subunits (e.g., cents).
|
|
333
|
+
* Useful for loading from database (Stripe-style integer storage).
|
|
334
|
+
*/
|
|
335
|
+
static fromSubunits(subunits, currency) {
|
|
336
|
+
var _a;
|
|
337
|
+
const currencyDef = getCurrency(currency);
|
|
338
|
+
if (!currencyDef) {
|
|
339
|
+
throw new CurrencyUnknownError(currency);
|
|
340
|
+
}
|
|
341
|
+
const bigintSubunits = typeof subunits === "number" ? BigInt(subunits) : subunits;
|
|
342
|
+
return __privateMethod(_a = _Money, _Money_static, createFromSubunits_fn).call(_a, bigintSubunits, currency, currencyDef);
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Compare two Money objects (for use with Array.sort).
|
|
346
|
+
* @throws {CurrencyMismatchError} If currencies don't match
|
|
347
|
+
*/
|
|
348
|
+
static compare(a, b) {
|
|
349
|
+
var _a, _b;
|
|
350
|
+
if (a.currency !== b.currency) {
|
|
351
|
+
throw new CurrencyMismatchError(a.currency, b.currency);
|
|
352
|
+
}
|
|
353
|
+
const aVal = __privateMethod(_a = a, _Money_instances, getInternalValue_fn).call(_a);
|
|
354
|
+
const bVal = __privateMethod(_b = b, _Money_instances, getInternalValue_fn).call(_b);
|
|
355
|
+
if (aVal < bVal) return -1;
|
|
356
|
+
if (aVal > bVal) return 1;
|
|
357
|
+
return 0;
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Create a zero amount in the specified currency.
|
|
361
|
+
*/
|
|
362
|
+
static zero(currency) {
|
|
363
|
+
return new _Money(currency, "0");
|
|
364
|
+
}
|
|
365
|
+
};
|
|
366
|
+
_subunits = new WeakMap();
|
|
367
|
+
_currencyDef = new WeakMap();
|
|
368
|
+
_Money_instances = new WeakSet();
|
|
369
|
+
/**
|
|
370
|
+
* Parse an amount into native subunits.
|
|
371
|
+
*/
|
|
372
|
+
parseAmount_fn = function(amount) {
|
|
373
|
+
const str = typeof amount === "number" ? String(amount) : amount;
|
|
374
|
+
const match = str.match(/^(-)?(\d+)(?:\.(\d+))?$/);
|
|
375
|
+
if (!match) {
|
|
376
|
+
throw new AmountError(amount);
|
|
377
|
+
}
|
|
378
|
+
const [, sign, whole, frac = ""] = match;
|
|
379
|
+
if (frac.length > __privateGet(this, _currencyDef).decimalDigits) {
|
|
380
|
+
throw new SubunitError(this.currency, __privateGet(this, _currencyDef).decimalDigits);
|
|
381
|
+
}
|
|
382
|
+
const paddedFrac = frac.padEnd(__privateGet(this, _currencyDef).decimalDigits, "0");
|
|
383
|
+
const combined = BigInt(whole + paddedFrac);
|
|
384
|
+
return sign === "-" ? -combined : combined;
|
|
385
|
+
};
|
|
386
|
+
_Money_static = new WeakSet();
|
|
387
|
+
formatForDisplay_fn = function(fullAmount, currencyDef) {
|
|
388
|
+
const preferredDecimals = currencyDef.displayDecimals ?? currencyDef.decimalDigits;
|
|
389
|
+
if (preferredDecimals === currencyDef.decimalDigits) {
|
|
390
|
+
return fullAmount;
|
|
391
|
+
}
|
|
392
|
+
const [whole, frac = ""] = fullAmount.split(".");
|
|
393
|
+
if (!frac) return whole;
|
|
394
|
+
let trimmedFrac = frac.replace(/0+$/, "");
|
|
395
|
+
if (trimmedFrac.length < preferredDecimals) {
|
|
396
|
+
trimmedFrac = trimmedFrac.padEnd(preferredDecimals, "0");
|
|
397
|
+
}
|
|
398
|
+
if (trimmedFrac === "" && preferredDecimals === 0) {
|
|
399
|
+
return whole;
|
|
400
|
+
}
|
|
401
|
+
return `${whole}.${trimmedFrac}`;
|
|
402
|
+
};
|
|
403
|
+
/**
|
|
404
|
+
* Ensure another Money has the same currency.
|
|
405
|
+
*/
|
|
406
|
+
assertSameCurrency_fn = function(other) {
|
|
407
|
+
if (this.currency !== other.currency) {
|
|
408
|
+
throw new CurrencyMismatchError(this.currency, other.currency);
|
|
409
|
+
}
|
|
410
|
+
};
|
|
411
|
+
/**
|
|
412
|
+
* Get the internal BigInt value (for operations).
|
|
413
|
+
*/
|
|
414
|
+
getInternalValue_fn = function() {
|
|
415
|
+
return __privateGet(this, _subunits);
|
|
416
|
+
};
|
|
417
|
+
parseFactor_fn = function(factor) {
|
|
418
|
+
const str = String(factor);
|
|
419
|
+
const [base, exponent] = str.split("e");
|
|
420
|
+
const baseMatch = base.match(/^(-)?(\d+)(?:\.(\d+))?$/);
|
|
421
|
+
if (!baseMatch) {
|
|
422
|
+
throw new TypeError(`Invalid factor format: ${str}`);
|
|
423
|
+
}
|
|
424
|
+
const [, sign, whole, frac = ""] = baseMatch;
|
|
425
|
+
const baseValue = BigInt((sign || "") + whole + frac);
|
|
426
|
+
const baseDecimals = frac.length;
|
|
427
|
+
const exp = exponent ? Number(exponent) : 0;
|
|
428
|
+
const netExp = exp - baseDecimals;
|
|
429
|
+
if (netExp >= 0) {
|
|
430
|
+
return { value: baseValue * 10n ** BigInt(netExp), scale: 0n };
|
|
431
|
+
} else {
|
|
432
|
+
return { value: baseValue, scale: BigInt(-netExp) };
|
|
433
|
+
}
|
|
434
|
+
};
|
|
435
|
+
roundedDivide_fn = function(numerator, denominator) {
|
|
436
|
+
if (denominator === 1n) return numerator;
|
|
437
|
+
const quotient = numerator / denominator;
|
|
438
|
+
const remainder = numerator % denominator;
|
|
439
|
+
if (remainder === 0n) return quotient;
|
|
440
|
+
const halfDenominator = denominator / 2n;
|
|
441
|
+
const absRemainder = remainder < 0n ? -remainder : remainder;
|
|
442
|
+
if (absRemainder > halfDenominator) {
|
|
443
|
+
return numerator < 0n ? quotient - 1n : quotient + 1n;
|
|
444
|
+
}
|
|
445
|
+
if (absRemainder === halfDenominator) {
|
|
446
|
+
const isQuotientEven = quotient % 2n === 0n;
|
|
447
|
+
if (isQuotientEven) {
|
|
448
|
+
return quotient;
|
|
449
|
+
}
|
|
450
|
+
return numerator < 0n ? quotient - 1n : quotient + 1n;
|
|
451
|
+
}
|
|
452
|
+
return quotient;
|
|
453
|
+
};
|
|
454
|
+
createFromSubunits_fn = function(subunits, currency, currencyDef) {
|
|
455
|
+
var _a;
|
|
456
|
+
return new _Money(currency, __privateMethod(_a = _Money, _Money_static, formatSubunits_fn).call(_a, subunits, currencyDef));
|
|
457
|
+
};
|
|
458
|
+
formatSubunits_fn = function(subunits, currencyDef) {
|
|
459
|
+
const decimals = currencyDef.decimalDigits;
|
|
460
|
+
const abs = subunits < 0n ? -subunits : subunits;
|
|
461
|
+
const isNegative = subunits < 0n;
|
|
462
|
+
if (decimals === 0) {
|
|
463
|
+
return `${isNegative ? "-" : ""}${abs}`;
|
|
464
|
+
}
|
|
465
|
+
const multiplier = 10n ** BigInt(decimals);
|
|
466
|
+
const wholePart = abs / multiplier;
|
|
467
|
+
const fracPart = abs % multiplier;
|
|
468
|
+
const sign = isNegative ? "-" : "";
|
|
469
|
+
return `${sign}${wholePart}.${fracPart.toString().padStart(decimals, "0")}`;
|
|
470
|
+
};
|
|
471
|
+
__privateAdd(_Money, _Money_static);
|
|
472
|
+
var Money = _Money;
|
|
473
|
+
|
|
474
|
+
// lib/exchange-rate-service.ts
|
|
475
|
+
var _rates, _ExchangeRateService_instances, key_fn;
|
|
476
|
+
var ExchangeRateService = class {
|
|
477
|
+
constructor() {
|
|
478
|
+
__privateAdd(this, _ExchangeRateService_instances);
|
|
479
|
+
__privateAdd(this, _rates, /* @__PURE__ */ new Map());
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* Set an exchange rate.
|
|
483
|
+
*
|
|
484
|
+
* @param from - Source currency code
|
|
485
|
+
* @param to - Target currency code
|
|
486
|
+
* @param rate - Exchange rate (1 unit of 'from' = rate units of 'to')
|
|
487
|
+
* @param source - Optional source identifier (e.g., 'ECB', 'Coinbase')
|
|
488
|
+
* @param autoInverse - If true, automatically create inverse rate (default: true)
|
|
489
|
+
*/
|
|
490
|
+
setRate(from, to, rate, source, autoInverse = true) {
|
|
491
|
+
const rateStr = typeof rate === "number" ? rate.toPrecision(15) : rate;
|
|
492
|
+
__privateGet(this, _rates).set(__privateMethod(this, _ExchangeRateService_instances, key_fn).call(this, from, to), {
|
|
493
|
+
from,
|
|
494
|
+
to,
|
|
495
|
+
rate: rateStr,
|
|
496
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
497
|
+
source
|
|
498
|
+
});
|
|
499
|
+
if (autoInverse) {
|
|
500
|
+
const inverseKey = __privateMethod(this, _ExchangeRateService_instances, key_fn).call(this, to, from);
|
|
501
|
+
if (!__privateGet(this, _rates).has(inverseKey)) {
|
|
502
|
+
const inverseRate = 1 / Number(rateStr);
|
|
503
|
+
__privateGet(this, _rates).set(inverseKey, {
|
|
504
|
+
from: to,
|
|
505
|
+
to: from,
|
|
506
|
+
rate: inverseRate.toPrecision(15),
|
|
507
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
508
|
+
source: source ? `${source} (inverse)` : "(inverse)"
|
|
509
|
+
});
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
/**
|
|
514
|
+
* Get an exchange rate.
|
|
515
|
+
*
|
|
516
|
+
* @param from - Source currency code
|
|
517
|
+
* @param to - Target currency code
|
|
518
|
+
* @returns The exchange rate, or undefined if not set
|
|
519
|
+
*/
|
|
520
|
+
getRate(from, to) {
|
|
521
|
+
if (from === to) {
|
|
522
|
+
return {
|
|
523
|
+
from,
|
|
524
|
+
to,
|
|
525
|
+
rate: "1",
|
|
526
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
527
|
+
source: "(identity)"
|
|
528
|
+
};
|
|
529
|
+
}
|
|
530
|
+
return __privateGet(this, _rates).get(__privateMethod(this, _ExchangeRateService_instances, key_fn).call(this, from, to));
|
|
531
|
+
}
|
|
532
|
+
/**
|
|
533
|
+
* Check if a rate exists.
|
|
534
|
+
*/
|
|
535
|
+
hasRate(from, to) {
|
|
536
|
+
return from === to || __privateGet(this, _rates).has(__privateMethod(this, _ExchangeRateService_instances, key_fn).call(this, from, to));
|
|
537
|
+
}
|
|
538
|
+
/**
|
|
539
|
+
* Remove a rate.
|
|
540
|
+
*/
|
|
541
|
+
removeRate(from, to) {
|
|
542
|
+
return __privateGet(this, _rates).delete(__privateMethod(this, _ExchangeRateService_instances, key_fn).call(this, from, to));
|
|
543
|
+
}
|
|
544
|
+
/**
|
|
545
|
+
* Get both forward and reverse rates, with discrepancy analysis.
|
|
546
|
+
* Useful for detecting rate inconsistencies.
|
|
547
|
+
*
|
|
548
|
+
* @param currencyA - First currency
|
|
549
|
+
* @param currencyB - Second currency
|
|
550
|
+
* @returns Rate pair with discrepancy, or undefined if either rate is missing
|
|
551
|
+
*/
|
|
552
|
+
getRatePair(currencyA, currencyB) {
|
|
553
|
+
const forward = this.getRate(currencyA, currencyB);
|
|
554
|
+
const reverse = this.getRate(currencyB, currencyA);
|
|
555
|
+
if (!forward || !reverse) {
|
|
556
|
+
return void 0;
|
|
557
|
+
}
|
|
558
|
+
const product = Number(forward.rate) * Number(reverse.rate);
|
|
559
|
+
const discrepancy = Math.abs(1 - product);
|
|
560
|
+
return { forward, reverse, discrepancy };
|
|
561
|
+
}
|
|
562
|
+
/**
|
|
563
|
+
* Get all rates for a specific base currency.
|
|
564
|
+
*
|
|
565
|
+
* @param base - The base currency code
|
|
566
|
+
* @returns Array of rates from this currency
|
|
567
|
+
*/
|
|
568
|
+
getRatesFrom(base) {
|
|
569
|
+
const rates = [];
|
|
570
|
+
for (const rate of __privateGet(this, _rates).values()) {
|
|
571
|
+
if (rate.from === base) {
|
|
572
|
+
rates.push(rate);
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
return rates.sort((a, b) => a.to.localeCompare(b.to));
|
|
576
|
+
}
|
|
577
|
+
/**
|
|
578
|
+
* Get all registered rates.
|
|
579
|
+
*/
|
|
580
|
+
getAllRates() {
|
|
581
|
+
return Array.from(__privateGet(this, _rates).values()).sort((a, b) => {
|
|
582
|
+
const fromCompare = a.from.localeCompare(b.from);
|
|
583
|
+
return fromCompare !== 0 ? fromCompare : a.to.localeCompare(b.to);
|
|
584
|
+
});
|
|
585
|
+
}
|
|
586
|
+
/**
|
|
587
|
+
* Clear all rates.
|
|
588
|
+
*/
|
|
589
|
+
clear() {
|
|
590
|
+
__privateGet(this, _rates).clear();
|
|
591
|
+
}
|
|
592
|
+
/**
|
|
593
|
+
* Load rates from a simple object.
|
|
594
|
+
*
|
|
595
|
+
* @param rates - Object where keys are "FROM:TO" and values are rates
|
|
596
|
+
* @param source - Optional source identifier
|
|
597
|
+
*
|
|
598
|
+
* @example
|
|
599
|
+
* service.loadRates({
|
|
600
|
+
* 'USD:EUR': 0.92,
|
|
601
|
+
* 'USD:GBP': 0.79,
|
|
602
|
+
* }, 'daily-update')
|
|
603
|
+
*/
|
|
604
|
+
loadRates(rates, source) {
|
|
605
|
+
for (const [key, rate] of Object.entries(rates)) {
|
|
606
|
+
const [from, to] = key.split(":");
|
|
607
|
+
if (from && to) {
|
|
608
|
+
this.setRate(from, to, rate, source, false);
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
};
|
|
613
|
+
_rates = new WeakMap();
|
|
614
|
+
_ExchangeRateService_instances = new WeakSet();
|
|
615
|
+
/**
|
|
616
|
+
* Create a rate key for storage.
|
|
617
|
+
*/
|
|
618
|
+
key_fn = function(from, to) {
|
|
619
|
+
return `${from}:${to}`;
|
|
620
|
+
};
|
|
621
|
+
|
|
622
|
+
// lib/money-converter.ts
|
|
623
|
+
var _rateService, _MoneyConverter_instances, bankersRound_fn;
|
|
624
|
+
var MoneyConverter = class {
|
|
625
|
+
constructor(rateService) {
|
|
626
|
+
__privateAdd(this, _MoneyConverter_instances);
|
|
627
|
+
__privateAdd(this, _rateService);
|
|
628
|
+
__privateSet(this, _rateService, rateService);
|
|
629
|
+
}
|
|
630
|
+
/**
|
|
631
|
+
* Convert a Money amount to another currency.
|
|
632
|
+
*
|
|
633
|
+
* @param money - The amount to convert
|
|
634
|
+
* @param targetCurrency - The target currency code
|
|
635
|
+
* @returns A new Money in the target currency
|
|
636
|
+
* @throws {ExchangeRateError} If no rate is available
|
|
637
|
+
*/
|
|
638
|
+
convert(money, targetCurrency) {
|
|
639
|
+
if (money.currency === targetCurrency) {
|
|
640
|
+
return money;
|
|
641
|
+
}
|
|
642
|
+
const currencyDef = getCurrency(targetCurrency);
|
|
643
|
+
if (!currencyDef) {
|
|
644
|
+
throw new CurrencyUnknownError(targetCurrency);
|
|
645
|
+
}
|
|
646
|
+
const rate = __privateGet(this, _rateService).getRate(money.currency, targetCurrency);
|
|
647
|
+
if (!rate) {
|
|
648
|
+
throw new ExchangeRateError(money.currency, targetCurrency);
|
|
649
|
+
}
|
|
650
|
+
const sourceCurrencyDef = getCurrency(money.currency);
|
|
651
|
+
const sourceSubunits = money.toSubunits();
|
|
652
|
+
const sourceMultiplier = 10n ** BigInt(sourceCurrencyDef.decimalDigits);
|
|
653
|
+
const targetMultiplier = 10n ** BigInt(currencyDef.decimalDigits);
|
|
654
|
+
const RATE_PRECISION = 15n;
|
|
655
|
+
const rateMultiplier = 10n ** RATE_PRECISION;
|
|
656
|
+
const rateValue = Number(rate.rate);
|
|
657
|
+
const rateBigInt = BigInt(Math.round(rateValue * Number(rateMultiplier)));
|
|
658
|
+
const product = sourceSubunits * rateBigInt * targetMultiplier;
|
|
659
|
+
const divisor = rateMultiplier * sourceMultiplier;
|
|
660
|
+
const targetSubunits = __privateMethod(this, _MoneyConverter_instances, bankersRound_fn).call(this, product, divisor);
|
|
661
|
+
return Money.fromSubunits(targetSubunits, targetCurrency);
|
|
662
|
+
}
|
|
663
|
+
/**
|
|
664
|
+
* Add two Money amounts, converting as needed.
|
|
665
|
+
*
|
|
666
|
+
* @param a - First amount
|
|
667
|
+
* @param b - Second amount
|
|
668
|
+
* @param resultCurrency - Currency for the result (must be one of the input currencies)
|
|
669
|
+
* @returns Sum in the result currency
|
|
670
|
+
*/
|
|
671
|
+
add(a, b, resultCurrency) {
|
|
672
|
+
const aConverted = this.convert(a, resultCurrency);
|
|
673
|
+
const bConverted = this.convert(b, resultCurrency);
|
|
674
|
+
return aConverted.add(bConverted);
|
|
675
|
+
}
|
|
676
|
+
/**
|
|
677
|
+
* Subtract two Money amounts, converting as needed.
|
|
678
|
+
*
|
|
679
|
+
* @param a - Amount to subtract from
|
|
680
|
+
* @param b - Amount to subtract
|
|
681
|
+
* @param resultCurrency - Currency for the result
|
|
682
|
+
* @returns Difference in the result currency
|
|
683
|
+
*/
|
|
684
|
+
subtract(a, b, resultCurrency) {
|
|
685
|
+
const aConverted = this.convert(a, resultCurrency);
|
|
686
|
+
const bConverted = this.convert(b, resultCurrency);
|
|
687
|
+
return aConverted.subtract(bConverted);
|
|
688
|
+
}
|
|
689
|
+
/**
|
|
690
|
+
* Calculate what percentage one amount is of another.
|
|
691
|
+
* Converts both to the same currency before comparison.
|
|
692
|
+
*
|
|
693
|
+
* @param part - The partial amount
|
|
694
|
+
* @param whole - The whole amount
|
|
695
|
+
* @returns Percentage as a number (e.g., 25 for 25%)
|
|
696
|
+
*/
|
|
697
|
+
percentageOf(part, whole) {
|
|
698
|
+
const partConverted = this.convert(part, whole.currency);
|
|
699
|
+
return partConverted.toNumber() / whole.toNumber() * 100;
|
|
700
|
+
}
|
|
701
|
+
/**
|
|
702
|
+
* Sum multiple Money amounts, converting all to a target currency.
|
|
703
|
+
*
|
|
704
|
+
* @param amounts - Array of Money objects (can be different currencies)
|
|
705
|
+
* @param targetCurrency - Currency for the result
|
|
706
|
+
* @returns Total in the target currency
|
|
707
|
+
*/
|
|
708
|
+
sum(amounts, targetCurrency) {
|
|
709
|
+
let total = Money.zero(targetCurrency);
|
|
710
|
+
for (const amount of amounts) {
|
|
711
|
+
const converted = this.convert(amount, targetCurrency);
|
|
712
|
+
total = total.add(converted);
|
|
713
|
+
}
|
|
714
|
+
return total;
|
|
715
|
+
}
|
|
716
|
+
/**
|
|
717
|
+
* Compare two Money amounts across currencies.
|
|
718
|
+
* Returns negative if a < b, zero if equal, positive if a > b.
|
|
719
|
+
*
|
|
720
|
+
* @param a - First amount
|
|
721
|
+
* @param b - Second amount
|
|
722
|
+
* @returns Comparison result
|
|
723
|
+
*/
|
|
724
|
+
compare(a, b) {
|
|
725
|
+
const bConverted = this.convert(b, a.currency);
|
|
726
|
+
return Money.compare(a, bConverted);
|
|
727
|
+
}
|
|
728
|
+
/**
|
|
729
|
+
* Get the exchange rate service (for direct rate access).
|
|
730
|
+
*/
|
|
731
|
+
get rateService() {
|
|
732
|
+
return __privateGet(this, _rateService);
|
|
733
|
+
}
|
|
734
|
+
};
|
|
735
|
+
_rateService = new WeakMap();
|
|
736
|
+
_MoneyConverter_instances = new WeakSet();
|
|
737
|
+
bankersRound_fn = function(numerator, denominator) {
|
|
738
|
+
if (denominator === 1n) return numerator;
|
|
739
|
+
const quotient = numerator / denominator;
|
|
740
|
+
const remainder = numerator % denominator;
|
|
741
|
+
if (remainder === 0n) return quotient;
|
|
742
|
+
const halfDenominator = denominator / 2n;
|
|
743
|
+
const absRemainder = remainder < 0n ? -remainder : remainder;
|
|
744
|
+
if (absRemainder > halfDenominator) {
|
|
745
|
+
return numerator < 0n ? quotient - 1n : quotient + 1n;
|
|
746
|
+
}
|
|
747
|
+
if (absRemainder === halfDenominator) {
|
|
748
|
+
const isQuotientEven = quotient % 2n === 0n;
|
|
749
|
+
if (isQuotientEven) {
|
|
750
|
+
return quotient;
|
|
751
|
+
}
|
|
752
|
+
return numerator < 0n ? quotient - 1n : quotient + 1n;
|
|
753
|
+
}
|
|
754
|
+
return quotient;
|
|
755
|
+
};
|
|
756
|
+
|
|
757
|
+
// currencymap.json
|
|
758
|
+
var currencymap_default = {
|
|
759
|
+
AED: {
|
|
760
|
+
decimal_digits: 2
|
|
761
|
+
},
|
|
762
|
+
AFN: {
|
|
763
|
+
decimal_digits: 2
|
|
764
|
+
},
|
|
765
|
+
ALL: {
|
|
766
|
+
decimal_digits: 2
|
|
767
|
+
},
|
|
768
|
+
AMD: {
|
|
769
|
+
decimal_digits: 2
|
|
770
|
+
},
|
|
771
|
+
AOA: {
|
|
772
|
+
decimal_digits: 2
|
|
773
|
+
},
|
|
774
|
+
ARS: {
|
|
775
|
+
decimal_digits: 2
|
|
776
|
+
},
|
|
777
|
+
AUD: {
|
|
778
|
+
decimal_digits: 2
|
|
779
|
+
},
|
|
780
|
+
AWG: {
|
|
781
|
+
decimal_digits: 2
|
|
782
|
+
},
|
|
783
|
+
AZN: {
|
|
784
|
+
decimal_digits: 2
|
|
785
|
+
},
|
|
786
|
+
BAM: {
|
|
787
|
+
decimal_digits: 2
|
|
788
|
+
},
|
|
789
|
+
BBD: {
|
|
790
|
+
decimal_digits: 2
|
|
791
|
+
},
|
|
792
|
+
BDT: {
|
|
793
|
+
decimal_digits: 2
|
|
794
|
+
},
|
|
795
|
+
BHD: {
|
|
796
|
+
decimal_digits: 3
|
|
797
|
+
},
|
|
798
|
+
BIF: {
|
|
799
|
+
decimal_digits: 0
|
|
800
|
+
},
|
|
801
|
+
BMD: {
|
|
802
|
+
decimal_digits: 2
|
|
803
|
+
},
|
|
804
|
+
BND: {
|
|
805
|
+
decimal_digits: 2
|
|
806
|
+
},
|
|
807
|
+
BOB: {
|
|
808
|
+
decimal_digits: 2
|
|
809
|
+
},
|
|
810
|
+
BOV: {
|
|
811
|
+
decimal_digits: 2
|
|
812
|
+
},
|
|
813
|
+
BRL: {
|
|
814
|
+
decimal_digits: 2
|
|
815
|
+
},
|
|
816
|
+
BSD: {
|
|
817
|
+
decimal_digits: 2
|
|
818
|
+
},
|
|
819
|
+
BTN: {
|
|
820
|
+
decimal_digits: 2
|
|
821
|
+
},
|
|
822
|
+
BWP: {
|
|
823
|
+
decimal_digits: 2
|
|
824
|
+
},
|
|
825
|
+
BYN: {
|
|
826
|
+
decimal_digits: 2
|
|
827
|
+
},
|
|
828
|
+
BZD: {
|
|
829
|
+
decimal_digits: 2
|
|
830
|
+
},
|
|
831
|
+
CAD: {
|
|
832
|
+
decimal_digits: 2
|
|
833
|
+
},
|
|
834
|
+
CDF: {
|
|
835
|
+
decimal_digits: 2
|
|
836
|
+
},
|
|
837
|
+
CHE: {
|
|
838
|
+
decimal_digits: 2
|
|
839
|
+
},
|
|
840
|
+
CHF: {
|
|
841
|
+
decimal_digits: 2
|
|
842
|
+
},
|
|
843
|
+
CHW: {
|
|
844
|
+
decimal_digits: 2
|
|
845
|
+
},
|
|
846
|
+
CLF: {
|
|
847
|
+
decimal_digits: 4
|
|
848
|
+
},
|
|
849
|
+
CLP: {
|
|
850
|
+
decimal_digits: 0
|
|
851
|
+
},
|
|
852
|
+
CNY: {
|
|
853
|
+
decimal_digits: 2
|
|
854
|
+
},
|
|
855
|
+
COP: {
|
|
856
|
+
decimal_digits: 2
|
|
857
|
+
},
|
|
858
|
+
COU: {
|
|
859
|
+
decimal_digits: 2
|
|
860
|
+
},
|
|
861
|
+
CRC: {
|
|
862
|
+
decimal_digits: 2
|
|
863
|
+
},
|
|
864
|
+
CUP: {
|
|
865
|
+
decimal_digits: 2
|
|
866
|
+
},
|
|
867
|
+
CVE: {
|
|
868
|
+
decimal_digits: 2
|
|
869
|
+
},
|
|
870
|
+
CZK: {
|
|
871
|
+
decimal_digits: 2
|
|
872
|
+
},
|
|
873
|
+
DJF: {
|
|
874
|
+
decimal_digits: 0
|
|
875
|
+
},
|
|
876
|
+
DKK: {
|
|
877
|
+
decimal_digits: 2
|
|
878
|
+
},
|
|
879
|
+
DOP: {
|
|
880
|
+
decimal_digits: 2
|
|
881
|
+
},
|
|
882
|
+
DZD: {
|
|
883
|
+
decimal_digits: 2
|
|
884
|
+
},
|
|
885
|
+
EGP: {
|
|
886
|
+
decimal_digits: 2
|
|
887
|
+
},
|
|
888
|
+
ERN: {
|
|
889
|
+
decimal_digits: 2
|
|
890
|
+
},
|
|
891
|
+
ETB: {
|
|
892
|
+
decimal_digits: 2
|
|
893
|
+
},
|
|
894
|
+
EUR: {
|
|
895
|
+
decimal_digits: 2
|
|
896
|
+
},
|
|
897
|
+
FJD: {
|
|
898
|
+
decimal_digits: 2
|
|
899
|
+
},
|
|
900
|
+
FKP: {
|
|
901
|
+
decimal_digits: 2
|
|
902
|
+
},
|
|
903
|
+
GBP: {
|
|
904
|
+
decimal_digits: 2
|
|
905
|
+
},
|
|
906
|
+
GEL: {
|
|
907
|
+
decimal_digits: 2
|
|
908
|
+
},
|
|
909
|
+
GHS: {
|
|
910
|
+
decimal_digits: 2
|
|
911
|
+
},
|
|
912
|
+
GIP: {
|
|
913
|
+
decimal_digits: 2
|
|
914
|
+
},
|
|
915
|
+
GMD: {
|
|
916
|
+
decimal_digits: 2
|
|
917
|
+
},
|
|
918
|
+
GNF: {
|
|
919
|
+
decimal_digits: 0
|
|
920
|
+
},
|
|
921
|
+
GTQ: {
|
|
922
|
+
decimal_digits: 2
|
|
923
|
+
},
|
|
924
|
+
GYD: {
|
|
925
|
+
decimal_digits: 2
|
|
926
|
+
},
|
|
927
|
+
HKD: {
|
|
928
|
+
decimal_digits: 2
|
|
929
|
+
},
|
|
930
|
+
HNL: {
|
|
931
|
+
decimal_digits: 2
|
|
932
|
+
},
|
|
933
|
+
HTG: {
|
|
934
|
+
decimal_digits: 2
|
|
935
|
+
},
|
|
936
|
+
HUF: {
|
|
937
|
+
decimal_digits: 2
|
|
938
|
+
},
|
|
939
|
+
IDR: {
|
|
940
|
+
decimal_digits: 2
|
|
941
|
+
},
|
|
942
|
+
ILS: {
|
|
943
|
+
decimal_digits: 2
|
|
944
|
+
},
|
|
945
|
+
INR: {
|
|
946
|
+
decimal_digits: 2
|
|
947
|
+
},
|
|
948
|
+
IQD: {
|
|
949
|
+
decimal_digits: 3
|
|
950
|
+
},
|
|
951
|
+
IRR: {
|
|
952
|
+
decimal_digits: 2
|
|
953
|
+
},
|
|
954
|
+
ISK: {
|
|
955
|
+
decimal_digits: 0
|
|
956
|
+
},
|
|
957
|
+
JMD: {
|
|
958
|
+
decimal_digits: 2
|
|
959
|
+
},
|
|
960
|
+
JOD: {
|
|
961
|
+
decimal_digits: 3
|
|
962
|
+
},
|
|
963
|
+
JPY: {
|
|
964
|
+
decimal_digits: 0
|
|
965
|
+
},
|
|
966
|
+
KES: {
|
|
967
|
+
decimal_digits: 2
|
|
968
|
+
},
|
|
969
|
+
KGS: {
|
|
970
|
+
decimal_digits: 2
|
|
971
|
+
},
|
|
972
|
+
KHR: {
|
|
973
|
+
decimal_digits: 2
|
|
974
|
+
},
|
|
975
|
+
KMF: {
|
|
976
|
+
decimal_digits: 0
|
|
977
|
+
},
|
|
978
|
+
KPW: {
|
|
979
|
+
decimal_digits: 2
|
|
980
|
+
},
|
|
981
|
+
KRW: {
|
|
982
|
+
decimal_digits: 0
|
|
983
|
+
},
|
|
984
|
+
KWD: {
|
|
985
|
+
decimal_digits: 3
|
|
986
|
+
},
|
|
987
|
+
KYD: {
|
|
988
|
+
decimal_digits: 2
|
|
989
|
+
},
|
|
990
|
+
KZT: {
|
|
991
|
+
decimal_digits: 2
|
|
992
|
+
},
|
|
993
|
+
LAK: {
|
|
994
|
+
decimal_digits: 2
|
|
995
|
+
},
|
|
996
|
+
LBP: {
|
|
997
|
+
decimal_digits: 2
|
|
998
|
+
},
|
|
999
|
+
LKR: {
|
|
1000
|
+
decimal_digits: 2
|
|
1001
|
+
},
|
|
1002
|
+
LRD: {
|
|
1003
|
+
decimal_digits: 2
|
|
1004
|
+
},
|
|
1005
|
+
LSL: {
|
|
1006
|
+
decimal_digits: 2
|
|
1007
|
+
},
|
|
1008
|
+
LYD: {
|
|
1009
|
+
decimal_digits: 3
|
|
1010
|
+
},
|
|
1011
|
+
MAD: {
|
|
1012
|
+
decimal_digits: 2
|
|
1013
|
+
},
|
|
1014
|
+
MDL: {
|
|
1015
|
+
decimal_digits: 2
|
|
1016
|
+
},
|
|
1017
|
+
MGA: {
|
|
1018
|
+
decimal_digits: 2
|
|
1019
|
+
},
|
|
1020
|
+
MKD: {
|
|
1021
|
+
decimal_digits: 2
|
|
1022
|
+
},
|
|
1023
|
+
MMK: {
|
|
1024
|
+
decimal_digits: 2
|
|
1025
|
+
},
|
|
1026
|
+
MNT: {
|
|
1027
|
+
decimal_digits: 2
|
|
1028
|
+
},
|
|
1029
|
+
MOP: {
|
|
1030
|
+
decimal_digits: 2
|
|
1031
|
+
},
|
|
1032
|
+
MRU: {
|
|
1033
|
+
decimal_digits: 2
|
|
1034
|
+
},
|
|
1035
|
+
MUR: {
|
|
1036
|
+
decimal_digits: 2
|
|
1037
|
+
},
|
|
1038
|
+
MVR: {
|
|
1039
|
+
decimal_digits: 2
|
|
1040
|
+
},
|
|
1041
|
+
MWK: {
|
|
1042
|
+
decimal_digits: 2
|
|
1043
|
+
},
|
|
1044
|
+
MXN: {
|
|
1045
|
+
decimal_digits: 2
|
|
1046
|
+
},
|
|
1047
|
+
MXV: {
|
|
1048
|
+
decimal_digits: 2
|
|
1049
|
+
},
|
|
1050
|
+
MYR: {
|
|
1051
|
+
decimal_digits: 2
|
|
1052
|
+
},
|
|
1053
|
+
MZN: {
|
|
1054
|
+
decimal_digits: 2
|
|
1055
|
+
},
|
|
1056
|
+
NAD: {
|
|
1057
|
+
decimal_digits: 2
|
|
1058
|
+
},
|
|
1059
|
+
NGN: {
|
|
1060
|
+
decimal_digits: 2
|
|
1061
|
+
},
|
|
1062
|
+
NIO: {
|
|
1063
|
+
decimal_digits: 2
|
|
1064
|
+
},
|
|
1065
|
+
NOK: {
|
|
1066
|
+
decimal_digits: 2
|
|
1067
|
+
},
|
|
1068
|
+
NPR: {
|
|
1069
|
+
decimal_digits: 2
|
|
1070
|
+
},
|
|
1071
|
+
NZD: {
|
|
1072
|
+
decimal_digits: 2
|
|
1073
|
+
},
|
|
1074
|
+
OMR: {
|
|
1075
|
+
decimal_digits: 3
|
|
1076
|
+
},
|
|
1077
|
+
PAB: {
|
|
1078
|
+
decimal_digits: 2
|
|
1079
|
+
},
|
|
1080
|
+
PEN: {
|
|
1081
|
+
decimal_digits: 2
|
|
1082
|
+
},
|
|
1083
|
+
PGK: {
|
|
1084
|
+
decimal_digits: 2
|
|
1085
|
+
},
|
|
1086
|
+
PHP: {
|
|
1087
|
+
decimal_digits: 2
|
|
1088
|
+
},
|
|
1089
|
+
PKR: {
|
|
1090
|
+
decimal_digits: 2
|
|
1091
|
+
},
|
|
1092
|
+
PLN: {
|
|
1093
|
+
decimal_digits: 2
|
|
1094
|
+
},
|
|
1095
|
+
PYG: {
|
|
1096
|
+
decimal_digits: 0
|
|
1097
|
+
},
|
|
1098
|
+
QAR: {
|
|
1099
|
+
decimal_digits: 2
|
|
1100
|
+
},
|
|
1101
|
+
RON: {
|
|
1102
|
+
decimal_digits: 2
|
|
1103
|
+
},
|
|
1104
|
+
RSD: {
|
|
1105
|
+
decimal_digits: 2
|
|
1106
|
+
},
|
|
1107
|
+
RUB: {
|
|
1108
|
+
decimal_digits: 2
|
|
1109
|
+
},
|
|
1110
|
+
RWF: {
|
|
1111
|
+
decimal_digits: 0
|
|
1112
|
+
},
|
|
1113
|
+
SAR: {
|
|
1114
|
+
decimal_digits: 2
|
|
1115
|
+
},
|
|
1116
|
+
SBD: {
|
|
1117
|
+
decimal_digits: 2
|
|
1118
|
+
},
|
|
1119
|
+
SCR: {
|
|
1120
|
+
decimal_digits: 2
|
|
1121
|
+
},
|
|
1122
|
+
SDG: {
|
|
1123
|
+
decimal_digits: 2
|
|
1124
|
+
},
|
|
1125
|
+
SEK: {
|
|
1126
|
+
decimal_digits: 2
|
|
1127
|
+
},
|
|
1128
|
+
SGD: {
|
|
1129
|
+
decimal_digits: 2
|
|
1130
|
+
},
|
|
1131
|
+
SHP: {
|
|
1132
|
+
decimal_digits: 2
|
|
1133
|
+
},
|
|
1134
|
+
SLE: {
|
|
1135
|
+
decimal_digits: 2
|
|
1136
|
+
},
|
|
1137
|
+
SOS: {
|
|
1138
|
+
decimal_digits: 2
|
|
1139
|
+
},
|
|
1140
|
+
SRD: {
|
|
1141
|
+
decimal_digits: 2
|
|
1142
|
+
},
|
|
1143
|
+
SSP: {
|
|
1144
|
+
decimal_digits: 2
|
|
1145
|
+
},
|
|
1146
|
+
STN: {
|
|
1147
|
+
decimal_digits: 2
|
|
1148
|
+
},
|
|
1149
|
+
SVC: {
|
|
1150
|
+
decimal_digits: 2
|
|
1151
|
+
},
|
|
1152
|
+
SYP: {
|
|
1153
|
+
decimal_digits: 2
|
|
1154
|
+
},
|
|
1155
|
+
SZL: {
|
|
1156
|
+
decimal_digits: 2
|
|
1157
|
+
},
|
|
1158
|
+
THB: {
|
|
1159
|
+
decimal_digits: 2
|
|
1160
|
+
},
|
|
1161
|
+
TJS: {
|
|
1162
|
+
decimal_digits: 2
|
|
1163
|
+
},
|
|
1164
|
+
TMT: {
|
|
1165
|
+
decimal_digits: 2
|
|
1166
|
+
},
|
|
1167
|
+
TND: {
|
|
1168
|
+
decimal_digits: 3
|
|
1169
|
+
},
|
|
1170
|
+
TOP: {
|
|
1171
|
+
decimal_digits: 2
|
|
1172
|
+
},
|
|
1173
|
+
TRY: {
|
|
1174
|
+
decimal_digits: 2
|
|
1175
|
+
},
|
|
1176
|
+
TTD: {
|
|
1177
|
+
decimal_digits: 2
|
|
1178
|
+
},
|
|
1179
|
+
TWD: {
|
|
1180
|
+
decimal_digits: 2
|
|
1181
|
+
},
|
|
1182
|
+
TZS: {
|
|
1183
|
+
decimal_digits: 2
|
|
1184
|
+
},
|
|
1185
|
+
UAH: {
|
|
1186
|
+
decimal_digits: 2
|
|
1187
|
+
},
|
|
1188
|
+
UGX: {
|
|
1189
|
+
decimal_digits: 0
|
|
1190
|
+
},
|
|
1191
|
+
USD: {
|
|
1192
|
+
decimal_digits: 2
|
|
1193
|
+
},
|
|
1194
|
+
USN: {
|
|
1195
|
+
decimal_digits: 2
|
|
1196
|
+
},
|
|
1197
|
+
UYI: {
|
|
1198
|
+
decimal_digits: 0
|
|
1199
|
+
},
|
|
1200
|
+
UYU: {
|
|
1201
|
+
decimal_digits: 2
|
|
1202
|
+
},
|
|
1203
|
+
UYW: {
|
|
1204
|
+
decimal_digits: 4
|
|
1205
|
+
},
|
|
1206
|
+
UZS: {
|
|
1207
|
+
decimal_digits: 2
|
|
1208
|
+
},
|
|
1209
|
+
VED: {
|
|
1210
|
+
decimal_digits: 2
|
|
1211
|
+
},
|
|
1212
|
+
VES: {
|
|
1213
|
+
decimal_digits: 2
|
|
1214
|
+
},
|
|
1215
|
+
VND: {
|
|
1216
|
+
decimal_digits: 0
|
|
1217
|
+
},
|
|
1218
|
+
VUV: {
|
|
1219
|
+
decimal_digits: 0
|
|
1220
|
+
},
|
|
1221
|
+
WST: {
|
|
1222
|
+
decimal_digits: 2
|
|
1223
|
+
},
|
|
1224
|
+
XAD: {
|
|
1225
|
+
decimal_digits: 2
|
|
1226
|
+
},
|
|
1227
|
+
XAF: {
|
|
1228
|
+
decimal_digits: 0
|
|
1229
|
+
},
|
|
1230
|
+
XAG: {
|
|
1231
|
+
decimal_digits: 0
|
|
1232
|
+
},
|
|
1233
|
+
XAU: {
|
|
1234
|
+
decimal_digits: 0
|
|
1235
|
+
},
|
|
1236
|
+
XBA: {
|
|
1237
|
+
decimal_digits: 0
|
|
1238
|
+
},
|
|
1239
|
+
XBB: {
|
|
1240
|
+
decimal_digits: 0
|
|
1241
|
+
},
|
|
1242
|
+
XBC: {
|
|
1243
|
+
decimal_digits: 0
|
|
1244
|
+
},
|
|
1245
|
+
XBD: {
|
|
1246
|
+
decimal_digits: 0
|
|
1247
|
+
},
|
|
1248
|
+
XCD: {
|
|
1249
|
+
decimal_digits: 2
|
|
1250
|
+
},
|
|
1251
|
+
XCG: {
|
|
1252
|
+
decimal_digits: 2
|
|
1253
|
+
},
|
|
1254
|
+
XDR: {
|
|
1255
|
+
decimal_digits: 0
|
|
1256
|
+
},
|
|
1257
|
+
XOF: {
|
|
1258
|
+
decimal_digits: 0
|
|
1259
|
+
},
|
|
1260
|
+
XPD: {
|
|
1261
|
+
decimal_digits: 0
|
|
1262
|
+
},
|
|
1263
|
+
XPF: {
|
|
1264
|
+
decimal_digits: 0
|
|
1265
|
+
},
|
|
1266
|
+
XPT: {
|
|
1267
|
+
decimal_digits: 0
|
|
1268
|
+
},
|
|
1269
|
+
XSU: {
|
|
1270
|
+
decimal_digits: 0
|
|
1271
|
+
},
|
|
1272
|
+
XTS: {
|
|
1273
|
+
decimal_digits: 0
|
|
1274
|
+
},
|
|
1275
|
+
XUA: {
|
|
1276
|
+
decimal_digits: 0
|
|
1277
|
+
},
|
|
1278
|
+
XXX: {
|
|
1279
|
+
decimal_digits: 0
|
|
1280
|
+
},
|
|
1281
|
+
YER: {
|
|
1282
|
+
decimal_digits: 2
|
|
1283
|
+
},
|
|
1284
|
+
ZAR: {
|
|
1285
|
+
decimal_digits: 2
|
|
1286
|
+
},
|
|
1287
|
+
ZMW: {
|
|
1288
|
+
decimal_digits: 2
|
|
1289
|
+
},
|
|
1290
|
+
ZWG: {
|
|
1291
|
+
decimal_digits: 2
|
|
1292
|
+
}
|
|
1293
|
+
};
|
|
1294
|
+
|
|
1295
|
+
// lib/index.ts
|
|
1296
|
+
loadCurrencyMap(currencymap_default);
|
|
1297
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
1298
|
+
0 && (module.exports = {
|
|
1299
|
+
AmountError,
|
|
1300
|
+
CurrencyMismatchError,
|
|
1301
|
+
CurrencyUnknownError,
|
|
1302
|
+
ExchangeRateError,
|
|
1303
|
+
ExchangeRateService,
|
|
1304
|
+
Money,
|
|
1305
|
+
MoneyConverter,
|
|
1306
|
+
SubunitError,
|
|
1307
|
+
clearCurrencies,
|
|
1308
|
+
getAllCurrencies,
|
|
1309
|
+
getCurrency,
|
|
1310
|
+
hasCurrency,
|
|
1311
|
+
loadCurrencyMap,
|
|
1312
|
+
registerCurrency
|
|
1313
|
+
});
|
|
1314
|
+
//# sourceMappingURL=index.cjs.map
|