monetra 0.0.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/LICENSE +21 -0
- package/README.md +140 -0
- package/dist/index 2.js +424 -0
- package/dist/index 2.mjs +381 -0
- package/dist/index.d 2.mts +76 -0
- package/dist/index.d 2.ts +76 -0
- package/dist/index.d.mts +250 -0
- package/dist/index.d.ts +250 -0
- package/dist/index.js +516 -0
- package/dist/index.js 2.map +1 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +473 -0
- package/dist/index.mjs 2.map +1 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +46 -0
package/dist/index 2.mjs
ADDED
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
// src/errors/BaseError.ts
|
|
2
|
+
var MonetraError = class extends Error {
|
|
3
|
+
constructor(message) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.name = this.constructor.name;
|
|
6
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
7
|
+
}
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
// src/errors/CurrencyMismatchError.ts
|
|
11
|
+
var CurrencyMismatchError = class extends MonetraError {
|
|
12
|
+
constructor(expected, actual) {
|
|
13
|
+
super(`Currency mismatch: expected ${expected}, got ${actual}`);
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
// src/errors/InvalidPrecisionError.ts
|
|
18
|
+
var InvalidPrecisionError = class extends MonetraError {
|
|
19
|
+
constructor(message) {
|
|
20
|
+
super(message);
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
// src/errors/RoundingRequiredError.ts
|
|
25
|
+
var RoundingRequiredError = class extends MonetraError {
|
|
26
|
+
constructor() {
|
|
27
|
+
super("Rounding is required for this operation but was not provided.");
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
// src/errors/InsufficientFundsError.ts
|
|
32
|
+
var InsufficientFundsError = class extends MonetraError {
|
|
33
|
+
constructor() {
|
|
34
|
+
super("Insufficient funds for this operation.");
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// src/errors/OverflowError.ts
|
|
39
|
+
var OverflowError = class extends MonetraError {
|
|
40
|
+
constructor(message = "Arithmetic overflow") {
|
|
41
|
+
super(message);
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
// src/money/guards.ts
|
|
46
|
+
function assertSameCurrency(a, b) {
|
|
47
|
+
if (a.currency.code !== b.currency.code) {
|
|
48
|
+
throw new CurrencyMismatchError(a.currency.code, b.currency.code);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// src/rounding/strategies.ts
|
|
53
|
+
var RoundingMode = /* @__PURE__ */ ((RoundingMode3) => {
|
|
54
|
+
RoundingMode3["HALF_UP"] = "HALF_UP";
|
|
55
|
+
RoundingMode3["HALF_DOWN"] = "HALF_DOWN";
|
|
56
|
+
RoundingMode3["HALF_EVEN"] = "HALF_EVEN";
|
|
57
|
+
RoundingMode3["FLOOR"] = "FLOOR";
|
|
58
|
+
RoundingMode3["CEIL"] = "CEIL";
|
|
59
|
+
return RoundingMode3;
|
|
60
|
+
})(RoundingMode || {});
|
|
61
|
+
|
|
62
|
+
// src/rounding/index.ts
|
|
63
|
+
function divideWithRounding(numerator, denominator, mode) {
|
|
64
|
+
if (denominator === 0n) {
|
|
65
|
+
throw new Error("Division by zero");
|
|
66
|
+
}
|
|
67
|
+
const quotient = numerator / denominator;
|
|
68
|
+
const remainder = numerator % denominator;
|
|
69
|
+
if (remainder === 0n) {
|
|
70
|
+
return quotient;
|
|
71
|
+
}
|
|
72
|
+
const sign = (numerator >= 0n ? 1n : -1n) * (denominator >= 0n ? 1n : -1n);
|
|
73
|
+
const absRemainder = remainder < 0n ? -remainder : remainder;
|
|
74
|
+
const absDenominator = denominator < 0n ? -denominator : denominator;
|
|
75
|
+
const isHalf = absRemainder * 2n === absDenominator;
|
|
76
|
+
const isMoreThanHalf = absRemainder * 2n > absDenominator;
|
|
77
|
+
switch (mode) {
|
|
78
|
+
case "FLOOR" /* FLOOR */:
|
|
79
|
+
return sign > 0n ? quotient : quotient - 1n;
|
|
80
|
+
case "CEIL" /* CEIL */:
|
|
81
|
+
return sign > 0n ? quotient + 1n : quotient;
|
|
82
|
+
case "HALF_UP" /* HALF_UP */:
|
|
83
|
+
if (isMoreThanHalf || isHalf) {
|
|
84
|
+
return sign > 0n ? quotient + 1n : quotient - 1n;
|
|
85
|
+
}
|
|
86
|
+
return quotient;
|
|
87
|
+
case "HALF_DOWN" /* HALF_DOWN */:
|
|
88
|
+
if (isMoreThanHalf) {
|
|
89
|
+
return sign > 0n ? quotient + 1n : quotient - 1n;
|
|
90
|
+
}
|
|
91
|
+
return quotient;
|
|
92
|
+
case "HALF_EVEN" /* HALF_EVEN */:
|
|
93
|
+
if (isMoreThanHalf) {
|
|
94
|
+
return sign > 0n ? quotient + 1n : quotient - 1n;
|
|
95
|
+
}
|
|
96
|
+
if (isHalf) {
|
|
97
|
+
if (quotient % 2n !== 0n) {
|
|
98
|
+
return sign > 0n ? quotient + 1n : quotient - 1n;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return quotient;
|
|
102
|
+
default:
|
|
103
|
+
throw new Error(`Unsupported rounding mode: ${mode}`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// src/money/arithmetic.ts
|
|
108
|
+
function add(a, b) {
|
|
109
|
+
return a + b;
|
|
110
|
+
}
|
|
111
|
+
function subtract(a, b) {
|
|
112
|
+
return a - b;
|
|
113
|
+
}
|
|
114
|
+
function multiply(amount, multiplier, rounding) {
|
|
115
|
+
const { numerator, denominator } = parseMultiplier(multiplier);
|
|
116
|
+
const product = amount * numerator;
|
|
117
|
+
if (product % denominator === 0n) {
|
|
118
|
+
return product / denominator;
|
|
119
|
+
}
|
|
120
|
+
if (!rounding) {
|
|
121
|
+
throw new RoundingRequiredError();
|
|
122
|
+
}
|
|
123
|
+
return divideWithRounding(product, denominator, rounding);
|
|
124
|
+
}
|
|
125
|
+
function parseMultiplier(multiplier) {
|
|
126
|
+
const s = multiplier.toString();
|
|
127
|
+
if (/[eE]/.test(s)) {
|
|
128
|
+
throw new Error("Scientific notation not supported");
|
|
129
|
+
}
|
|
130
|
+
const parts = s.split(".");
|
|
131
|
+
if (parts.length > 2) {
|
|
132
|
+
throw new Error("Invalid number format");
|
|
133
|
+
}
|
|
134
|
+
const integerPart = parts[0];
|
|
135
|
+
const fractionalPart = parts[1] || "";
|
|
136
|
+
const denominator = 10n ** BigInt(fractionalPart.length);
|
|
137
|
+
const numerator = BigInt(integerPart + fractionalPart);
|
|
138
|
+
return { numerator, denominator };
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// src/money/allocation.ts
|
|
142
|
+
function allocate(amount, ratios) {
|
|
143
|
+
if (ratios.length === 0) {
|
|
144
|
+
throw new Error("Cannot allocate to empty ratios");
|
|
145
|
+
}
|
|
146
|
+
const scaledRatios = ratios.map((r) => {
|
|
147
|
+
const s = r.toString();
|
|
148
|
+
if (/[eE]/.test(s)) throw new Error("Scientific notation not supported");
|
|
149
|
+
const parts = s.split(".");
|
|
150
|
+
const decimals = parts[1] ? parts[1].length : 0;
|
|
151
|
+
const value = BigInt(parts[0] + (parts[1] || ""));
|
|
152
|
+
return { value, decimals };
|
|
153
|
+
});
|
|
154
|
+
const maxDecimals = Math.max(...scaledRatios.map((r) => r.decimals));
|
|
155
|
+
const normalizedRatios = scaledRatios.map((r) => {
|
|
156
|
+
const factor = 10n ** BigInt(maxDecimals - r.decimals);
|
|
157
|
+
return r.value * factor;
|
|
158
|
+
});
|
|
159
|
+
const total = normalizedRatios.reduce((sum, r) => sum + r, 0n);
|
|
160
|
+
if (total === 0n) {
|
|
161
|
+
throw new Error("Total ratio must be greater than zero");
|
|
162
|
+
}
|
|
163
|
+
const results = [];
|
|
164
|
+
let allocatedTotal = 0n;
|
|
165
|
+
for (let i = 0; i < normalizedRatios.length; i++) {
|
|
166
|
+
const ratio = normalizedRatios[i];
|
|
167
|
+
const share = amount * ratio / total;
|
|
168
|
+
const remainder = amount * ratio % total;
|
|
169
|
+
results.push({ share, remainder, index: i });
|
|
170
|
+
allocatedTotal += share;
|
|
171
|
+
}
|
|
172
|
+
let leftOver = amount - allocatedTotal;
|
|
173
|
+
results.sort((a, b) => {
|
|
174
|
+
if (b.remainder > a.remainder) return 1;
|
|
175
|
+
if (b.remainder < a.remainder) return -1;
|
|
176
|
+
return 0;
|
|
177
|
+
});
|
|
178
|
+
for (let i = 0; i < Number(leftOver); i++) {
|
|
179
|
+
results[i].share += 1n;
|
|
180
|
+
}
|
|
181
|
+
results.sort((a, b) => a.index - b.index);
|
|
182
|
+
return results.map((r) => r.share);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// src/format/parser.ts
|
|
186
|
+
function parseToMinor(amount, currency) {
|
|
187
|
+
if (/[eE]/.test(amount)) {
|
|
188
|
+
throw new Error("Scientific notation not supported");
|
|
189
|
+
}
|
|
190
|
+
if (/[^0-9.-]/.test(amount)) {
|
|
191
|
+
throw new Error("Invalid characters in amount");
|
|
192
|
+
}
|
|
193
|
+
const parts = amount.split(".");
|
|
194
|
+
if (parts.length > 2) {
|
|
195
|
+
throw new Error("Invalid format: multiple decimal points");
|
|
196
|
+
}
|
|
197
|
+
const integerPart = parts[0];
|
|
198
|
+
const fractionalPart = parts[1] || "";
|
|
199
|
+
if (fractionalPart.length > currency.decimals) {
|
|
200
|
+
throw new InvalidPrecisionError(
|
|
201
|
+
`Precision ${fractionalPart.length} exceeds currency decimals ${currency.decimals}`
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
const paddedFractional = fractionalPart.padEnd(currency.decimals, "0");
|
|
205
|
+
const combined = integerPart + paddedFractional;
|
|
206
|
+
if (combined === "-" || combined === "") {
|
|
207
|
+
throw new Error("Invalid format");
|
|
208
|
+
}
|
|
209
|
+
return BigInt(combined);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// src/format/formatter.ts
|
|
213
|
+
function format(money, options) {
|
|
214
|
+
const locale = options?.locale || money.currency.locale || "en-US";
|
|
215
|
+
const showSymbol = options?.symbol ?? true;
|
|
216
|
+
const decimals = money.currency.decimals;
|
|
217
|
+
const minor = money.minor;
|
|
218
|
+
const absMinor = minor < 0n ? -minor : minor;
|
|
219
|
+
const divisor = 10n ** BigInt(decimals);
|
|
220
|
+
const integerPart = absMinor / divisor;
|
|
221
|
+
const fractionalPart = absMinor % divisor;
|
|
222
|
+
const fractionalStr = fractionalPart.toString().padStart(decimals, "0");
|
|
223
|
+
const parts = new Intl.NumberFormat(locale, {
|
|
224
|
+
style: "decimal",
|
|
225
|
+
minimumFractionDigits: 1
|
|
226
|
+
}).formatToParts(1.1);
|
|
227
|
+
const decimalSeparator = parts.find((p) => p.type === "decimal")?.value || ".";
|
|
228
|
+
const integerFormatted = new Intl.NumberFormat(locale, {
|
|
229
|
+
style: "decimal",
|
|
230
|
+
useGrouping: true
|
|
231
|
+
}).format(integerPart);
|
|
232
|
+
const absString = decimals > 0 ? `${integerFormatted}${decimalSeparator}${fractionalStr}` : integerFormatted;
|
|
233
|
+
if (!showSymbol) {
|
|
234
|
+
return minor < 0n ? `-${absString}` : absString;
|
|
235
|
+
}
|
|
236
|
+
const templateParts = new Intl.NumberFormat(locale, {
|
|
237
|
+
style: "currency",
|
|
238
|
+
currency: money.currency.code
|
|
239
|
+
}).formatToParts(minor < 0n ? -1 : 1);
|
|
240
|
+
let result = "";
|
|
241
|
+
let numberInserted = false;
|
|
242
|
+
for (const part of templateParts) {
|
|
243
|
+
if (["integer", "group", "decimal", "fraction"].includes(part.type)) {
|
|
244
|
+
if (!numberInserted) {
|
|
245
|
+
result += absString;
|
|
246
|
+
numberInserted = true;
|
|
247
|
+
}
|
|
248
|
+
} else if (part.type === "currency") {
|
|
249
|
+
result += part.value;
|
|
250
|
+
} else {
|
|
251
|
+
result += part.value;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
return result;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// src/money/Money.ts
|
|
258
|
+
var Money = class _Money {
|
|
259
|
+
constructor(minor, currency) {
|
|
260
|
+
this.minor = minor;
|
|
261
|
+
this.currency = currency;
|
|
262
|
+
}
|
|
263
|
+
static fromMinor(minor, currency) {
|
|
264
|
+
return new _Money(BigInt(minor), currency);
|
|
265
|
+
}
|
|
266
|
+
static fromMajor(amount, currency) {
|
|
267
|
+
const minor = parseToMinor(amount, currency);
|
|
268
|
+
return new _Money(minor, currency);
|
|
269
|
+
}
|
|
270
|
+
static zero(currency) {
|
|
271
|
+
return new _Money(0n, currency);
|
|
272
|
+
}
|
|
273
|
+
add(other) {
|
|
274
|
+
assertSameCurrency(this, other);
|
|
275
|
+
return new _Money(add(this.minor, other.minor), this.currency);
|
|
276
|
+
}
|
|
277
|
+
subtract(other) {
|
|
278
|
+
assertSameCurrency(this, other);
|
|
279
|
+
return new _Money(subtract(this.minor, other.minor), this.currency);
|
|
280
|
+
}
|
|
281
|
+
multiply(multiplier, options) {
|
|
282
|
+
const result = multiply(this.minor, multiplier, options?.rounding);
|
|
283
|
+
return new _Money(result, this.currency);
|
|
284
|
+
}
|
|
285
|
+
allocate(ratios) {
|
|
286
|
+
const shares = allocate(this.minor, ratios);
|
|
287
|
+
return shares.map((share) => new _Money(share, this.currency));
|
|
288
|
+
}
|
|
289
|
+
format(options) {
|
|
290
|
+
return format(this, options);
|
|
291
|
+
}
|
|
292
|
+
equals(other) {
|
|
293
|
+
return this.currency.code === other.currency.code && this.minor === other.minor;
|
|
294
|
+
}
|
|
295
|
+
greaterThan(other) {
|
|
296
|
+
assertSameCurrency(this, other);
|
|
297
|
+
return this.minor > other.minor;
|
|
298
|
+
}
|
|
299
|
+
lessThan(other) {
|
|
300
|
+
assertSameCurrency(this, other);
|
|
301
|
+
return this.minor < other.minor;
|
|
302
|
+
}
|
|
303
|
+
isZero() {
|
|
304
|
+
return this.minor === 0n;
|
|
305
|
+
}
|
|
306
|
+
isNegative() {
|
|
307
|
+
return this.minor < 0n;
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
// src/currency/iso4217.ts
|
|
312
|
+
var USD = {
|
|
313
|
+
code: "USD",
|
|
314
|
+
decimals: 2,
|
|
315
|
+
symbol: "$",
|
|
316
|
+
locale: "en-US"
|
|
317
|
+
};
|
|
318
|
+
var EUR = {
|
|
319
|
+
code: "EUR",
|
|
320
|
+
decimals: 2,
|
|
321
|
+
symbol: "\u20AC",
|
|
322
|
+
locale: "de-DE"
|
|
323
|
+
// Default locale, can be overridden
|
|
324
|
+
};
|
|
325
|
+
var GBP = {
|
|
326
|
+
code: "GBP",
|
|
327
|
+
decimals: 2,
|
|
328
|
+
symbol: "\xA3",
|
|
329
|
+
locale: "en-GB"
|
|
330
|
+
};
|
|
331
|
+
var JPY = {
|
|
332
|
+
code: "JPY",
|
|
333
|
+
decimals: 0,
|
|
334
|
+
symbol: "\xA5",
|
|
335
|
+
locale: "ja-JP"
|
|
336
|
+
};
|
|
337
|
+
var ZAR = {
|
|
338
|
+
code: "ZAR",
|
|
339
|
+
decimals: 2,
|
|
340
|
+
symbol: "R",
|
|
341
|
+
locale: "en-ZA"
|
|
342
|
+
};
|
|
343
|
+
var CURRENCIES = {
|
|
344
|
+
USD,
|
|
345
|
+
EUR,
|
|
346
|
+
GBP,
|
|
347
|
+
JPY,
|
|
348
|
+
ZAR
|
|
349
|
+
};
|
|
350
|
+
function getCurrency(code) {
|
|
351
|
+
const currency = CURRENCIES[code.toUpperCase()];
|
|
352
|
+
if (!currency) {
|
|
353
|
+
throw new Error(`Unknown currency code: ${code}`);
|
|
354
|
+
}
|
|
355
|
+
return currency;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// src/currency/precision.ts
|
|
359
|
+
function getMinorUnitExponent(currency) {
|
|
360
|
+
return 10n ** BigInt(currency.decimals);
|
|
361
|
+
}
|
|
362
|
+
export {
|
|
363
|
+
CURRENCIES,
|
|
364
|
+
CurrencyMismatchError,
|
|
365
|
+
EUR,
|
|
366
|
+
GBP,
|
|
367
|
+
InsufficientFundsError,
|
|
368
|
+
InvalidPrecisionError,
|
|
369
|
+
JPY,
|
|
370
|
+
MonetraError,
|
|
371
|
+
Money,
|
|
372
|
+
OverflowError,
|
|
373
|
+
RoundingMode,
|
|
374
|
+
RoundingRequiredError,
|
|
375
|
+
USD,
|
|
376
|
+
ZAR,
|
|
377
|
+
divideWithRounding,
|
|
378
|
+
getCurrency,
|
|
379
|
+
getMinorUnitExponent
|
|
380
|
+
};
|
|
381
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
interface Currency {
|
|
2
|
+
code: string;
|
|
3
|
+
decimals: number;
|
|
4
|
+
symbol: string;
|
|
5
|
+
locale?: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
declare enum RoundingMode {
|
|
9
|
+
HALF_UP = "HALF_UP",
|
|
10
|
+
HALF_DOWN = "HALF_DOWN",
|
|
11
|
+
HALF_EVEN = "HALF_EVEN",
|
|
12
|
+
FLOOR = "FLOOR",
|
|
13
|
+
CEIL = "CEIL"
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
declare class Money {
|
|
17
|
+
readonly minor: bigint;
|
|
18
|
+
readonly currency: Currency;
|
|
19
|
+
private constructor();
|
|
20
|
+
static fromMinor(minor: bigint | number, currency: Currency): Money;
|
|
21
|
+
static fromMajor(amount: string, currency: Currency): Money;
|
|
22
|
+
static zero(currency: Currency): Money;
|
|
23
|
+
add(other: Money): Money;
|
|
24
|
+
subtract(other: Money): Money;
|
|
25
|
+
multiply(multiplier: string | number, options?: {
|
|
26
|
+
rounding?: RoundingMode;
|
|
27
|
+
}): Money;
|
|
28
|
+
allocate(ratios: number[]): Money[];
|
|
29
|
+
format(options?: {
|
|
30
|
+
locale?: string;
|
|
31
|
+
symbol?: boolean;
|
|
32
|
+
}): string;
|
|
33
|
+
equals(other: Money): boolean;
|
|
34
|
+
greaterThan(other: Money): boolean;
|
|
35
|
+
lessThan(other: Money): boolean;
|
|
36
|
+
isZero(): boolean;
|
|
37
|
+
isNegative(): boolean;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
declare const USD: Currency;
|
|
41
|
+
declare const EUR: Currency;
|
|
42
|
+
declare const GBP: Currency;
|
|
43
|
+
declare const JPY: Currency;
|
|
44
|
+
declare const ZAR: Currency;
|
|
45
|
+
declare const CURRENCIES: Record<string, Currency>;
|
|
46
|
+
declare function getCurrency(code: string): Currency;
|
|
47
|
+
|
|
48
|
+
declare function getMinorUnitExponent(currency: Currency): bigint;
|
|
49
|
+
|
|
50
|
+
declare function divideWithRounding(numerator: bigint, denominator: bigint, mode: RoundingMode): bigint;
|
|
51
|
+
|
|
52
|
+
declare class MonetraError extends Error {
|
|
53
|
+
constructor(message: string);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
declare class CurrencyMismatchError extends MonetraError {
|
|
57
|
+
constructor(expected: string, actual: string);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
declare class InvalidPrecisionError extends MonetraError {
|
|
61
|
+
constructor(message: string);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
declare class RoundingRequiredError extends MonetraError {
|
|
65
|
+
constructor();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
declare class InsufficientFundsError extends MonetraError {
|
|
69
|
+
constructor();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
declare class OverflowError extends MonetraError {
|
|
73
|
+
constructor(message?: string);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export { CURRENCIES, type Currency, CurrencyMismatchError, EUR, GBP, InsufficientFundsError, InvalidPrecisionError, JPY, MonetraError, Money, OverflowError, RoundingMode, RoundingRequiredError, USD, ZAR, divideWithRounding, getCurrency, getMinorUnitExponent };
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
interface Currency {
|
|
2
|
+
code: string;
|
|
3
|
+
decimals: number;
|
|
4
|
+
symbol: string;
|
|
5
|
+
locale?: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
declare enum RoundingMode {
|
|
9
|
+
HALF_UP = "HALF_UP",
|
|
10
|
+
HALF_DOWN = "HALF_DOWN",
|
|
11
|
+
HALF_EVEN = "HALF_EVEN",
|
|
12
|
+
FLOOR = "FLOOR",
|
|
13
|
+
CEIL = "CEIL"
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
declare class Money {
|
|
17
|
+
readonly minor: bigint;
|
|
18
|
+
readonly currency: Currency;
|
|
19
|
+
private constructor();
|
|
20
|
+
static fromMinor(minor: bigint | number, currency: Currency): Money;
|
|
21
|
+
static fromMajor(amount: string, currency: Currency): Money;
|
|
22
|
+
static zero(currency: Currency): Money;
|
|
23
|
+
add(other: Money): Money;
|
|
24
|
+
subtract(other: Money): Money;
|
|
25
|
+
multiply(multiplier: string | number, options?: {
|
|
26
|
+
rounding?: RoundingMode;
|
|
27
|
+
}): Money;
|
|
28
|
+
allocate(ratios: number[]): Money[];
|
|
29
|
+
format(options?: {
|
|
30
|
+
locale?: string;
|
|
31
|
+
symbol?: boolean;
|
|
32
|
+
}): string;
|
|
33
|
+
equals(other: Money): boolean;
|
|
34
|
+
greaterThan(other: Money): boolean;
|
|
35
|
+
lessThan(other: Money): boolean;
|
|
36
|
+
isZero(): boolean;
|
|
37
|
+
isNegative(): boolean;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
declare const USD: Currency;
|
|
41
|
+
declare const EUR: Currency;
|
|
42
|
+
declare const GBP: Currency;
|
|
43
|
+
declare const JPY: Currency;
|
|
44
|
+
declare const ZAR: Currency;
|
|
45
|
+
declare const CURRENCIES: Record<string, Currency>;
|
|
46
|
+
declare function getCurrency(code: string): Currency;
|
|
47
|
+
|
|
48
|
+
declare function getMinorUnitExponent(currency: Currency): bigint;
|
|
49
|
+
|
|
50
|
+
declare function divideWithRounding(numerator: bigint, denominator: bigint, mode: RoundingMode): bigint;
|
|
51
|
+
|
|
52
|
+
declare class MonetraError extends Error {
|
|
53
|
+
constructor(message: string);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
declare class CurrencyMismatchError extends MonetraError {
|
|
57
|
+
constructor(expected: string, actual: string);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
declare class InvalidPrecisionError extends MonetraError {
|
|
61
|
+
constructor(message: string);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
declare class RoundingRequiredError extends MonetraError {
|
|
65
|
+
constructor();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
declare class InsufficientFundsError extends MonetraError {
|
|
69
|
+
constructor();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
declare class OverflowError extends MonetraError {
|
|
73
|
+
constructor(message?: string);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export { CURRENCIES, type Currency, CurrencyMismatchError, EUR, GBP, InsufficientFundsError, InvalidPrecisionError, JPY, MonetraError, Money, OverflowError, RoundingMode, RoundingRequiredError, USD, ZAR, divideWithRounding, getCurrency, getMinorUnitExponent };
|