monetra 2.0.0 → 2.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/README.md +177 -160
- package/dist/currency/Currency.d.ts +27 -0
- package/dist/currency/index.d.ts +4 -0
- package/dist/currency/iso4217.d.ts +245 -0
- package/dist/currency/precision.d.ts +2 -0
- package/dist/currency/registry.d.ts +22 -0
- package/dist/errors/BaseError.d.ts +22 -0
- package/dist/errors/CurrencyMismatchError.d.ts +12 -0
- package/dist/errors/InsufficientFundsError.d.ts +4 -0
- package/dist/errors/InvalidArgumentError.d.ts +4 -0
- package/dist/errors/InvalidPrecisionError.d.ts +4 -0
- package/dist/errors/OverflowError.d.ts +4 -0
- package/dist/errors/RoundingRequiredError.d.ts +4 -0
- package/dist/errors/index.d.ts +7 -0
- package/dist/financial/compound.d.ts +20 -0
- package/dist/financial/depreciation.d.ts +30 -0
- package/dist/financial/index.d.ts +7 -0
- package/dist/financial/index.js +1323 -0
- package/dist/financial/index.js.map +1 -0
- package/dist/financial/index.mjs +1275 -0
- package/dist/financial/index.mjs.map +1 -0
- package/dist/financial/investment.d.ts +31 -0
- package/dist/financial/leverage.d.ts +66 -0
- package/dist/financial/loan.d.ts +67 -0
- package/dist/financial/rate.d.ts +169 -0
- package/dist/financial/simple.d.ts +60 -0
- package/dist/format/formatter.d.ts +42 -0
- package/dist/format/parser.d.ts +53 -0
- package/dist/index.d.ts +11 -1202
- package/dist/index.js +263 -41
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +248 -41
- package/dist/index.mjs.map +1 -1
- package/dist/ledger/Ledger.d.ts +65 -0
- package/dist/ledger/index.d.ts +3 -0
- package/dist/ledger/index.js +1054 -0
- package/dist/ledger/index.js.map +1 -0
- package/dist/ledger/index.mjs +1029 -0
- package/dist/ledger/index.mjs.map +1 -0
- package/dist/ledger/types.d.ts +30 -0
- package/dist/ledger/verification.d.ts +36 -0
- package/dist/money/Converter.d.ts +26 -0
- package/dist/money/Money.d.ts +299 -0
- package/dist/money/MoneyBag.d.ts +46 -0
- package/dist/money/allocation.d.ts +13 -0
- package/dist/money/arithmetic.d.ts +32 -0
- package/dist/money/guards.d.ts +3 -0
- package/dist/money/index.d.ts +4 -0
- package/dist/rounding/index.d.ts +3 -0
- package/dist/rounding/strategies.d.ts +36 -0
- package/dist/tokens/defineToken.d.ts +30 -0
- package/dist/tokens/index.d.ts +2 -0
- package/dist/tokens/index.js +100 -0
- package/dist/tokens/index.js.map +1 -0
- package/dist/tokens/index.mjs +69 -0
- package/dist/tokens/index.mjs.map +1 -0
- package/dist/tokens/types.d.ts +13 -0
- package/package.json +34 -14
- package/dist/index.d.mts +0 -1211
package/dist/index.js
CHANGED
|
@@ -49,6 +49,7 @@ __export(index_exports, {
|
|
|
49
49
|
INR: () => INR,
|
|
50
50
|
ISK: () => ISK,
|
|
51
51
|
InsufficientFundsError: () => InsufficientFundsError,
|
|
52
|
+
InvalidArgumentError: () => InvalidArgumentError,
|
|
52
53
|
InvalidPrecisionError: () => InvalidPrecisionError,
|
|
53
54
|
JOD: () => JOD,
|
|
54
55
|
JPY: () => JPY,
|
|
@@ -95,16 +96,24 @@ __export(index_exports, {
|
|
|
95
96
|
assertNonNegative: () => assertNonNegative,
|
|
96
97
|
assertSameCurrency: () => assertSameCurrency,
|
|
97
98
|
compound: () => compound,
|
|
99
|
+
currentYield: () => currentYield,
|
|
100
|
+
debtToAssets: () => debtToAssets,
|
|
101
|
+
debtToEquity: () => debtToEquity,
|
|
98
102
|
discount: () => discount,
|
|
99
103
|
divideWithRounding: () => divideWithRounding,
|
|
104
|
+
equityMultiplier: () => equityMultiplier,
|
|
100
105
|
format: () => format,
|
|
101
106
|
futureValue: () => futureValue,
|
|
102
107
|
generateHash: () => generateHash,
|
|
103
108
|
generateHashSync: () => generateHashSync,
|
|
109
|
+
getAllCurrencies: () => getAllCurrencies,
|
|
104
110
|
getCurrency: () => getCurrency,
|
|
105
111
|
getMinorUnitExponent: () => getMinorUnitExponent,
|
|
112
|
+
interestCoverage: () => interestCoverage,
|
|
113
|
+
interestOnlyPayment: () => interestOnlyPayment,
|
|
106
114
|
irr: () => irr,
|
|
107
115
|
isCurrencyRegistered: () => isCurrencyRegistered,
|
|
116
|
+
leverageRatios: () => leverageRatios,
|
|
108
117
|
loan: () => loan,
|
|
109
118
|
money: () => money,
|
|
110
119
|
npv: () => npv,
|
|
@@ -114,7 +123,13 @@ __export(index_exports, {
|
|
|
114
123
|
pmt: () => pmt,
|
|
115
124
|
presentValue: () => presentValue,
|
|
116
125
|
registerCurrency: () => registerCurrency,
|
|
126
|
+
roi: () => roi,
|
|
117
127
|
setHashFunction: () => setHashFunction,
|
|
128
|
+
simpleInterest: () => simpleInterest,
|
|
129
|
+
simpleInterestTotal: () => simpleInterestTotal,
|
|
130
|
+
straightLineDepreciation: () => straightLineDepreciation,
|
|
131
|
+
totalInterest: () => totalInterest,
|
|
132
|
+
totalInterestFromSchedule: () => totalInterestFromSchedule,
|
|
118
133
|
verifyChain: () => verifyChain,
|
|
119
134
|
verifyChainSync: () => verifyChainSync
|
|
120
135
|
});
|
|
@@ -135,6 +150,9 @@ function getCurrency(code) {
|
|
|
135
150
|
function isCurrencyRegistered(code) {
|
|
136
151
|
return registry.has(code);
|
|
137
152
|
}
|
|
153
|
+
function getAllCurrencies() {
|
|
154
|
+
return Object.fromEntries(registry);
|
|
155
|
+
}
|
|
138
156
|
|
|
139
157
|
// src/rounding/strategies.ts
|
|
140
158
|
var RoundingMode = /* @__PURE__ */ ((RoundingMode3) => {
|
|
@@ -151,6 +169,7 @@ var RoundingMode = /* @__PURE__ */ ((RoundingMode3) => {
|
|
|
151
169
|
var MonetraErrorCode = /* @__PURE__ */ ((MonetraErrorCode2) => {
|
|
152
170
|
MonetraErrorCode2["CURRENCY_MISMATCH"] = "MONETRA_CURRENCY_MISMATCH";
|
|
153
171
|
MonetraErrorCode2["INSUFFICIENT_FUNDS"] = "MONETRA_INSUFFICIENT_FUNDS";
|
|
172
|
+
MonetraErrorCode2["INVALID_ARGUMENT"] = "MONETRA_INVALID_ARGUMENT";
|
|
154
173
|
MonetraErrorCode2["INVALID_PRECISION"] = "MONETRA_INVALID_PRECISION";
|
|
155
174
|
MonetraErrorCode2["OVERFLOW"] = "MONETRA_OVERFLOW";
|
|
156
175
|
MonetraErrorCode2["ROUNDING_REQUIRED"] = "MONETRA_ROUNDING_REQUIRED";
|
|
@@ -211,6 +230,13 @@ var InsufficientFundsError = class extends MonetraError {
|
|
|
211
230
|
}
|
|
212
231
|
};
|
|
213
232
|
|
|
233
|
+
// src/errors/InvalidArgumentError.ts
|
|
234
|
+
var InvalidArgumentError = class extends MonetraError {
|
|
235
|
+
constructor(message) {
|
|
236
|
+
super(message, "MONETRA_INVALID_ARGUMENT" /* INVALID_ARGUMENT */);
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
|
|
214
240
|
// src/errors/OverflowError.ts
|
|
215
241
|
var OverflowError = class extends MonetraError {
|
|
216
242
|
constructor(message = "Arithmetic overflow") {
|
|
@@ -240,33 +266,34 @@ function divideWithRounding(numerator, denominator, mode) {
|
|
|
240
266
|
if (remainder === 0n) {
|
|
241
267
|
return quotient;
|
|
242
268
|
}
|
|
243
|
-
const
|
|
269
|
+
const isNegativeResult = numerator < 0n !== denominator < 0n;
|
|
270
|
+
const isPositiveResult = !isNegativeResult;
|
|
244
271
|
const absRemainder = remainder < 0n ? -remainder : remainder;
|
|
245
272
|
const absDenominator = denominator < 0n ? -denominator : denominator;
|
|
246
273
|
const isHalf = absRemainder * 2n === absDenominator;
|
|
247
274
|
const isMoreThanHalf = absRemainder * 2n > absDenominator;
|
|
248
275
|
switch (mode) {
|
|
249
276
|
case "FLOOR" /* FLOOR */:
|
|
250
|
-
return
|
|
277
|
+
return isPositiveResult ? quotient : quotient - 1n;
|
|
251
278
|
case "CEIL" /* CEIL */:
|
|
252
|
-
return
|
|
279
|
+
return isPositiveResult ? quotient + 1n : quotient;
|
|
253
280
|
case "HALF_UP" /* HALF_UP */:
|
|
254
281
|
if (isMoreThanHalf || isHalf) {
|
|
255
|
-
return
|
|
282
|
+
return isPositiveResult ? quotient + 1n : quotient - 1n;
|
|
256
283
|
}
|
|
257
284
|
return quotient;
|
|
258
285
|
case "HALF_DOWN" /* HALF_DOWN */:
|
|
259
286
|
if (isMoreThanHalf) {
|
|
260
|
-
return
|
|
287
|
+
return isPositiveResult ? quotient + 1n : quotient - 1n;
|
|
261
288
|
}
|
|
262
289
|
return quotient;
|
|
263
290
|
case "HALF_EVEN" /* HALF_EVEN */:
|
|
264
291
|
if (isMoreThanHalf) {
|
|
265
|
-
return
|
|
292
|
+
return isPositiveResult ? quotient + 1n : quotient - 1n;
|
|
266
293
|
}
|
|
267
294
|
if (isHalf) {
|
|
268
295
|
if (quotient % 2n !== 0n) {
|
|
269
|
-
return
|
|
296
|
+
return isPositiveResult ? quotient + 1n : quotient - 1n;
|
|
270
297
|
}
|
|
271
298
|
}
|
|
272
299
|
return quotient;
|
|
@@ -305,7 +332,10 @@ function divide(amount, divisor, rounding) {
|
|
|
305
332
|
return product / numerator;
|
|
306
333
|
}
|
|
307
334
|
if (!rounding) {
|
|
308
|
-
throw new RoundingRequiredError(
|
|
335
|
+
throw new RoundingRequiredError(
|
|
336
|
+
"divide",
|
|
337
|
+
Number(product) / Number(numerator)
|
|
338
|
+
);
|
|
309
339
|
}
|
|
310
340
|
return divideWithRounding(product, numerator, rounding);
|
|
311
341
|
}
|
|
@@ -393,11 +423,8 @@ function parseLocaleString(amount, options) {
|
|
|
393
423
|
let normalized = amount.replace(/[^\d.,\-\s]/g, "").trim();
|
|
394
424
|
const isNegative = normalized.startsWith("-") || amount.includes("(");
|
|
395
425
|
normalized = normalized.replace(/[-()]/g, "");
|
|
396
|
-
|
|
397
|
-
normalized = normalized.
|
|
398
|
-
if (decimalSeparator !== ".") {
|
|
399
|
-
normalized = normalized.replace(decimalSeparator, ".");
|
|
400
|
-
}
|
|
426
|
+
normalized = normalized.split(groupSeparator).join("");
|
|
427
|
+
normalized = normalized.split(decimalSeparator).join(".");
|
|
401
428
|
return isNegative ? `-${normalized}` : normalized;
|
|
402
429
|
}
|
|
403
430
|
function parseLocaleToMinor(amount, currency, options) {
|
|
@@ -411,6 +438,9 @@ function parseToMinor(amount, currency) {
|
|
|
411
438
|
if (/[^0-9.-]/.test(amount)) {
|
|
412
439
|
throw new Error("Invalid characters in amount");
|
|
413
440
|
}
|
|
441
|
+
if (!/[0-9]/.test(amount)) {
|
|
442
|
+
throw new Error("Invalid format");
|
|
443
|
+
}
|
|
414
444
|
const parts = amount.split(".");
|
|
415
445
|
if (parts.length > 2) {
|
|
416
446
|
throw new Error("Invalid format: multiple decimal points");
|
|
@@ -424,9 +454,6 @@ function parseToMinor(amount, currency) {
|
|
|
424
454
|
}
|
|
425
455
|
const paddedFractional = fractionalPart.padEnd(currency.decimals, "0");
|
|
426
456
|
const combined = integerPart + paddedFractional;
|
|
427
|
-
if (combined === "-" || combined === "") {
|
|
428
|
-
throw new Error("Invalid format");
|
|
429
|
-
}
|
|
430
457
|
return BigInt(combined);
|
|
431
458
|
}
|
|
432
459
|
|
|
@@ -466,7 +493,7 @@ function format(money2, options) {
|
|
|
466
493
|
style: "currency",
|
|
467
494
|
currency: money2.currency.code,
|
|
468
495
|
currencyDisplay: display
|
|
469
|
-
}).formatToParts(isNegative ? -
|
|
496
|
+
}).formatToParts(isNegative ? -1234.5 : 1234.5);
|
|
470
497
|
} catch (e) {
|
|
471
498
|
const symbol = display === "symbol" ? money2.currency.symbol : money2.currency.code;
|
|
472
499
|
if (isNegative) {
|
|
@@ -476,28 +503,39 @@ function format(money2, options) {
|
|
|
476
503
|
}
|
|
477
504
|
let result = "";
|
|
478
505
|
let numberInserted = false;
|
|
479
|
-
let hasMinusSign = false;
|
|
480
506
|
for (const part of templateParts) {
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
507
|
+
switch (part.type) {
|
|
508
|
+
case "minusSign": {
|
|
509
|
+
if (!useAccounting) {
|
|
510
|
+
result += part.value;
|
|
511
|
+
}
|
|
512
|
+
break;
|
|
485
513
|
}
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
514
|
+
case "integer": {
|
|
515
|
+
if (!numberInserted) {
|
|
516
|
+
result += absString;
|
|
517
|
+
numberInserted = true;
|
|
518
|
+
}
|
|
519
|
+
break;
|
|
520
|
+
}
|
|
521
|
+
// Skip the remaining numeric parts, since we already inserted the full number string.
|
|
522
|
+
case "group":
|
|
523
|
+
case "decimal":
|
|
524
|
+
case "fraction": {
|
|
525
|
+
break;
|
|
492
526
|
}
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
527
|
+
case "currency": {
|
|
528
|
+
if (display === "symbol" && money2.currency.symbol) {
|
|
529
|
+
result += money2.currency.symbol;
|
|
530
|
+
} else {
|
|
531
|
+
result += part.value;
|
|
532
|
+
}
|
|
533
|
+
break;
|
|
534
|
+
}
|
|
535
|
+
default: {
|
|
497
536
|
result += part.value;
|
|
537
|
+
break;
|
|
498
538
|
}
|
|
499
|
-
} else {
|
|
500
|
-
result += part.value;
|
|
501
539
|
}
|
|
502
540
|
}
|
|
503
541
|
if (useAccounting && isNegative) {
|
|
@@ -696,10 +734,7 @@ var Money = class _Money {
|
|
|
696
734
|
* @returns A new Money instance with the absolute value.
|
|
697
735
|
*/
|
|
698
736
|
abs() {
|
|
699
|
-
return new _Money(
|
|
700
|
-
this.minor < 0n ? -this.minor : this.minor,
|
|
701
|
-
this.currency
|
|
702
|
-
);
|
|
737
|
+
return new _Money(this.minor < 0n ? -this.minor : this.minor, this.currency);
|
|
703
738
|
}
|
|
704
739
|
/**
|
|
705
740
|
* Returns the negated value of this Money.
|
|
@@ -1588,6 +1623,43 @@ function pmt(options) {
|
|
|
1588
1623
|
const schedule = loan(options);
|
|
1589
1624
|
return schedule[0].payment;
|
|
1590
1625
|
}
|
|
1626
|
+
function totalInterest(options) {
|
|
1627
|
+
const {
|
|
1628
|
+
principal,
|
|
1629
|
+
annualRate,
|
|
1630
|
+
periods,
|
|
1631
|
+
rounding = "HALF_EVEN" /* HALF_EVEN */
|
|
1632
|
+
} = options;
|
|
1633
|
+
if (annualRate === 0) {
|
|
1634
|
+
return Money.zero(principal.currency);
|
|
1635
|
+
}
|
|
1636
|
+
const payment = pmt(options);
|
|
1637
|
+
const totalPaid = payment.multiply(periods, { rounding });
|
|
1638
|
+
return totalPaid.subtract(principal);
|
|
1639
|
+
}
|
|
1640
|
+
function totalInterestFromSchedule(schedule) {
|
|
1641
|
+
if (schedule.length === 0) {
|
|
1642
|
+
throw new Error("Schedule must have at least one entry");
|
|
1643
|
+
}
|
|
1644
|
+
const currency = schedule[0].interest.currency;
|
|
1645
|
+
return schedule.reduce(
|
|
1646
|
+
(sum, entry) => sum.add(entry.interest),
|
|
1647
|
+
Money.zero(currency)
|
|
1648
|
+
);
|
|
1649
|
+
}
|
|
1650
|
+
function interestOnlyPayment(options) {
|
|
1651
|
+
const {
|
|
1652
|
+
principal,
|
|
1653
|
+
annualRate,
|
|
1654
|
+
periodsPerYear = 12,
|
|
1655
|
+
rounding = "HALF_EVEN" /* HALF_EVEN */
|
|
1656
|
+
} = options;
|
|
1657
|
+
if (annualRate === 0) {
|
|
1658
|
+
return Money.zero(principal.currency);
|
|
1659
|
+
}
|
|
1660
|
+
const periodicRate = annualRate / periodsPerYear;
|
|
1661
|
+
return principal.multiply(periodicRate, { rounding });
|
|
1662
|
+
}
|
|
1591
1663
|
|
|
1592
1664
|
// src/financial/compound.ts
|
|
1593
1665
|
function futureValue(presentValue2, options) {
|
|
@@ -1618,6 +1690,16 @@ var compound = futureValue;
|
|
|
1618
1690
|
var discount = presentValue;
|
|
1619
1691
|
|
|
1620
1692
|
// src/financial/investment.ts
|
|
1693
|
+
function roi(initialValue, finalValue) {
|
|
1694
|
+
if (initialValue.currency.code !== finalValue.currency.code) {
|
|
1695
|
+
throw new CurrencyMismatchError(
|
|
1696
|
+
initialValue.currency.code,
|
|
1697
|
+
finalValue.currency.code
|
|
1698
|
+
);
|
|
1699
|
+
}
|
|
1700
|
+
const gain = finalValue.subtract(initialValue);
|
|
1701
|
+
return Number(gain.minor) / Number(initialValue.minor);
|
|
1702
|
+
}
|
|
1621
1703
|
function npv(discountRate, cashFlows) {
|
|
1622
1704
|
if (cashFlows.length === 0) {
|
|
1623
1705
|
throw new Error("At least one cash flow required");
|
|
@@ -1656,6 +1738,18 @@ function irr(cashFlows, guess = 0.1) {
|
|
|
1656
1738
|
}
|
|
1657
1739
|
throw new Error("IRR calculation did not converge");
|
|
1658
1740
|
}
|
|
1741
|
+
function currentYield(annualCoupon, currentPrice) {
|
|
1742
|
+
if (annualCoupon.currency.code !== currentPrice.currency.code) {
|
|
1743
|
+
throw new CurrencyMismatchError(
|
|
1744
|
+
annualCoupon.currency.code,
|
|
1745
|
+
currentPrice.currency.code
|
|
1746
|
+
);
|
|
1747
|
+
}
|
|
1748
|
+
if (currentPrice.minor <= 0n) {
|
|
1749
|
+
throw new InvalidArgumentError("Current price must be positive");
|
|
1750
|
+
}
|
|
1751
|
+
return Number(annualCoupon.minor) / Number(currentPrice.minor);
|
|
1752
|
+
}
|
|
1659
1753
|
|
|
1660
1754
|
// src/financial/rate.ts
|
|
1661
1755
|
var _Rate = class _Rate {
|
|
@@ -1861,11 +1955,124 @@ var _Rate = class _Rate {
|
|
|
1861
1955
|
_Rate.SCALE = 10n ** 18n;
|
|
1862
1956
|
var Rate = _Rate;
|
|
1863
1957
|
|
|
1958
|
+
// src/financial/simple.ts
|
|
1959
|
+
function simpleInterest(principal, options) {
|
|
1960
|
+
const { rate, years, rounding = "HALF_EVEN" /* HALF_EVEN */ } = options;
|
|
1961
|
+
if (rate.isZero() || years === 0) {
|
|
1962
|
+
return Money.zero(principal.currency);
|
|
1963
|
+
}
|
|
1964
|
+
const interestMultiplier = rate.toDecimal() * years;
|
|
1965
|
+
return principal.multiply(interestMultiplier, { rounding });
|
|
1966
|
+
}
|
|
1967
|
+
function simpleInterestTotal(principal, options) {
|
|
1968
|
+
const { rate, years, rounding = "HALF_EVEN" /* HALF_EVEN */ } = options;
|
|
1969
|
+
if (rate.isZero() || years === 0) {
|
|
1970
|
+
return principal;
|
|
1971
|
+
}
|
|
1972
|
+
const totalMultiplier = 1 + rate.toDecimal() * years;
|
|
1973
|
+
return principal.multiply(totalMultiplier, { rounding });
|
|
1974
|
+
}
|
|
1975
|
+
|
|
1976
|
+
// src/financial/leverage.ts
|
|
1977
|
+
function debtToEquity(totalDebt, totalEquity) {
|
|
1978
|
+
assertSameCurrency(totalDebt, totalEquity);
|
|
1979
|
+
if (totalEquity.isZero()) {
|
|
1980
|
+
throw new Error("Total equity cannot be zero");
|
|
1981
|
+
}
|
|
1982
|
+
return Number(totalDebt.minor) / Number(totalEquity.minor);
|
|
1983
|
+
}
|
|
1984
|
+
function debtToAssets(totalDebt, totalAssets) {
|
|
1985
|
+
assertSameCurrency(totalDebt, totalAssets);
|
|
1986
|
+
if (totalAssets.isZero()) {
|
|
1987
|
+
throw new Error("Total assets cannot be zero");
|
|
1988
|
+
}
|
|
1989
|
+
return Number(totalDebt.minor) / Number(totalAssets.minor);
|
|
1990
|
+
}
|
|
1991
|
+
function interestCoverage(ebit, interestExpense) {
|
|
1992
|
+
assertSameCurrency(ebit, interestExpense);
|
|
1993
|
+
if (interestExpense.isZero()) {
|
|
1994
|
+
return Infinity;
|
|
1995
|
+
}
|
|
1996
|
+
return Number(ebit.minor) / Number(interestExpense.minor);
|
|
1997
|
+
}
|
|
1998
|
+
function equityMultiplier(totalAssets, totalEquity) {
|
|
1999
|
+
assertSameCurrency(totalAssets, totalEquity);
|
|
2000
|
+
if (totalEquity.isZero()) {
|
|
2001
|
+
throw new Error("Total equity cannot be zero");
|
|
2002
|
+
}
|
|
2003
|
+
return Number(totalAssets.minor) / Number(totalEquity.minor);
|
|
2004
|
+
}
|
|
2005
|
+
function leverageRatios(inputs) {
|
|
2006
|
+
return {
|
|
2007
|
+
debtToEquity: debtToEquity(inputs.totalDebt, inputs.totalEquity),
|
|
2008
|
+
debtToAssets: debtToAssets(inputs.totalDebt, inputs.totalAssets),
|
|
2009
|
+
interestCoverage: interestCoverage(inputs.ebit, inputs.interestExpense),
|
|
2010
|
+
equityMultiplier: equityMultiplier(inputs.totalAssets, inputs.totalEquity)
|
|
2011
|
+
};
|
|
2012
|
+
}
|
|
2013
|
+
|
|
2014
|
+
// src/financial/depreciation.ts
|
|
2015
|
+
function straightLineDepreciation(options) {
|
|
2016
|
+
const {
|
|
2017
|
+
cost,
|
|
2018
|
+
salvageValue,
|
|
2019
|
+
usefulLife,
|
|
2020
|
+
rounding = "HALF_EVEN" /* HALF_EVEN */
|
|
2021
|
+
} = options;
|
|
2022
|
+
if (cost.currency.code !== salvageValue.currency.code) {
|
|
2023
|
+
throw new CurrencyMismatchError(
|
|
2024
|
+
cost.currency.code,
|
|
2025
|
+
salvageValue.currency.code
|
|
2026
|
+
);
|
|
2027
|
+
}
|
|
2028
|
+
if (usefulLife <= 0) {
|
|
2029
|
+
throw new InvalidArgumentError("Useful life must be positive");
|
|
2030
|
+
}
|
|
2031
|
+
if (salvageValue.greaterThan(cost)) {
|
|
2032
|
+
throw new InvalidArgumentError("Salvage value cannot be greater than cost");
|
|
2033
|
+
}
|
|
2034
|
+
const depreciableAmount = cost.subtract(salvageValue);
|
|
2035
|
+
const annualDepreciation = depreciableAmount.divide(usefulLife, { rounding });
|
|
2036
|
+
const result = {
|
|
2037
|
+
annualDepreciation,
|
|
2038
|
+
bookValueAtYear(year) {
|
|
2039
|
+
if (year < 0) {
|
|
2040
|
+
throw new InvalidArgumentError("Year must be non-negative");
|
|
2041
|
+
}
|
|
2042
|
+
if (year === 0) return cost;
|
|
2043
|
+
const totalDepreciation = annualDepreciation.multiply(year);
|
|
2044
|
+
const bookValue = cost.subtract(totalDepreciation);
|
|
2045
|
+
if (bookValue.lessThan(salvageValue)) {
|
|
2046
|
+
return salvageValue;
|
|
2047
|
+
}
|
|
2048
|
+
return bookValue;
|
|
2049
|
+
},
|
|
2050
|
+
schedule() {
|
|
2051
|
+
const schedule = [];
|
|
2052
|
+
let previousBookValue = cost;
|
|
2053
|
+
const maxYears = Math.ceil(usefulLife);
|
|
2054
|
+
for (let year = 1; year <= maxYears; year++) {
|
|
2055
|
+
const currentBookValue = result.bookValueAtYear(year);
|
|
2056
|
+
const depreciation = previousBookValue.subtract(currentBookValue);
|
|
2057
|
+
schedule.push({
|
|
2058
|
+
year,
|
|
2059
|
+
depreciation,
|
|
2060
|
+
bookValue: currentBookValue
|
|
2061
|
+
});
|
|
2062
|
+
previousBookValue = currentBookValue;
|
|
2063
|
+
}
|
|
2064
|
+
return schedule;
|
|
2065
|
+
}
|
|
2066
|
+
};
|
|
2067
|
+
return result;
|
|
2068
|
+
}
|
|
2069
|
+
|
|
1864
2070
|
// src/ledger/verification.ts
|
|
1865
2071
|
var hashFunction = null;
|
|
1866
2072
|
function getHashFunction() {
|
|
1867
2073
|
if (hashFunction) return hashFunction;
|
|
1868
|
-
|
|
2074
|
+
const disableNodeCrypto = globalThis.__MONETRA_DISABLE_NODE_CRYPTO__ === true;
|
|
2075
|
+
if (!disableNodeCrypto && typeof globalThis !== "undefined") {
|
|
1869
2076
|
try {
|
|
1870
2077
|
const nodeCrypto = require("crypto");
|
|
1871
2078
|
if (nodeCrypto && nodeCrypto.createHash) {
|
|
@@ -2014,7 +2221,7 @@ var Ledger = class _Ledger {
|
|
|
2014
2221
|
const hash = await generateHash(content);
|
|
2015
2222
|
const entry = {
|
|
2016
2223
|
...content,
|
|
2017
|
-
hash
|
|
2224
|
+
hash
|
|
2018
2225
|
};
|
|
2019
2226
|
this.entries.push(Object.freeze(entry));
|
|
2020
2227
|
return entry;
|
|
@@ -2098,7 +2305,7 @@ var Ledger = class _Ledger {
|
|
|
2098
2305
|
balance: this.getBalance(),
|
|
2099
2306
|
currency: this.currency,
|
|
2100
2307
|
createdAt: /* @__PURE__ */ new Date(),
|
|
2101
|
-
checksum
|
|
2308
|
+
checksum
|
|
2102
2309
|
};
|
|
2103
2310
|
}
|
|
2104
2311
|
/**
|
|
@@ -2164,6 +2371,7 @@ function money(amount, currency) {
|
|
|
2164
2371
|
INR,
|
|
2165
2372
|
ISK,
|
|
2166
2373
|
InsufficientFundsError,
|
|
2374
|
+
InvalidArgumentError,
|
|
2167
2375
|
InvalidPrecisionError,
|
|
2168
2376
|
JOD,
|
|
2169
2377
|
JPY,
|
|
@@ -2210,16 +2418,24 @@ function money(amount, currency) {
|
|
|
2210
2418
|
assertNonNegative,
|
|
2211
2419
|
assertSameCurrency,
|
|
2212
2420
|
compound,
|
|
2421
|
+
currentYield,
|
|
2422
|
+
debtToAssets,
|
|
2423
|
+
debtToEquity,
|
|
2213
2424
|
discount,
|
|
2214
2425
|
divideWithRounding,
|
|
2426
|
+
equityMultiplier,
|
|
2215
2427
|
format,
|
|
2216
2428
|
futureValue,
|
|
2217
2429
|
generateHash,
|
|
2218
2430
|
generateHashSync,
|
|
2431
|
+
getAllCurrencies,
|
|
2219
2432
|
getCurrency,
|
|
2220
2433
|
getMinorUnitExponent,
|
|
2434
|
+
interestCoverage,
|
|
2435
|
+
interestOnlyPayment,
|
|
2221
2436
|
irr,
|
|
2222
2437
|
isCurrencyRegistered,
|
|
2438
|
+
leverageRatios,
|
|
2223
2439
|
loan,
|
|
2224
2440
|
money,
|
|
2225
2441
|
npv,
|
|
@@ -2229,7 +2445,13 @@ function money(amount, currency) {
|
|
|
2229
2445
|
pmt,
|
|
2230
2446
|
presentValue,
|
|
2231
2447
|
registerCurrency,
|
|
2448
|
+
roi,
|
|
2232
2449
|
setHashFunction,
|
|
2450
|
+
simpleInterest,
|
|
2451
|
+
simpleInterestTotal,
|
|
2452
|
+
straightLineDepreciation,
|
|
2453
|
+
totalInterest,
|
|
2454
|
+
totalInterestFromSchedule,
|
|
2233
2455
|
verifyChain,
|
|
2234
2456
|
verifyChainSync
|
|
2235
2457
|
});
|