@eriveltondasilva/currency 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +21 -0
- package/README.md +215 -0
- package/dist/chunk-5VVSCRNB.js +18 -0
- package/dist/index.d.ts +526 -0
- package/dist/index.js +17 -0
- package/dist/presets.d.ts +60 -0
- package/dist/presets.js +17 -0
- package/dist/types-BX9n6pbS.d.ts +662 -0
- package/package.json +96 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Erivelton da Silva
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
# Currency
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@eriveltondasilva/currency)
|
|
4
|
+
[](https://www.npmjs.com/package/@eriveltondasilva/currency)
|
|
5
|
+
[](https://github.com/eriveltondasilva/currency/actions/workflows/pull-request.yml)
|
|
6
|
+
[](https://biomejs.dev)
|
|
7
|
+
[](https://www.npmjs.com/package/@eriveltondasilva/currency)
|
|
8
|
+
[](https://opensource.org/licenses/MIT)
|
|
9
|
+
|
|
10
|
+
A lightweight TypeScript library for precise monetary operations. All values are stored internally as **minor-unit integers** to eliminate floating-point errors. Every operation returns a new instance — the API is fully immutable.
|
|
11
|
+
|
|
12
|
+
<p align="center">
|
|
13
|
+
<img src="https://raw.githubusercontent.com/eriveltondasilva/currency.js/main/src/assets/currency-banner.png" alt="Currency.js Banner" width="600">
|
|
14
|
+
</p>
|
|
15
|
+
|
|
16
|
+
## Features
|
|
17
|
+
|
|
18
|
+
- 💰 **Precise calculations** — integer-based math eliminates floating-point errors
|
|
19
|
+
- 🔒 **Immutable API** — every operation returns a new instance
|
|
20
|
+
- 🌍 **Internationalization** — formatting support for 14 countries and 100+ locales
|
|
21
|
+
- 🧮 **Business operations** — discounts, surcharges, allocations, and more
|
|
22
|
+
- 📦 **Zero dependencies** — lightweight and focused (< 5KB min+gzip)
|
|
23
|
+
- 🎯 **Type-safe** — full TypeScript support with comprehensive type definitions
|
|
24
|
+
|
|
25
|
+
## Quick Start
|
|
26
|
+
|
|
27
|
+
### Installation
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npm install @eriveltonsilva/currency.js
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
bun add @eriveltonsilva/currency.js
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Import
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
// Named imports (recommended — better tree-shaking)
|
|
41
|
+
import { from, parse, sum, total, isMoney, ... } from '@eriveltonsilva/currency.js'
|
|
42
|
+
|
|
43
|
+
// Default namespace
|
|
44
|
+
import Money from '@eriveltonsilva/currency.js'
|
|
45
|
+
|
|
46
|
+
// Country presets
|
|
47
|
+
import { br, us, ... } from '@eriveltonsilva/currency.js/presets'
|
|
48
|
+
|
|
49
|
+
// Types
|
|
50
|
+
import type { MoneyContract, MoneyInput, FormatOptions, RoundingMode, PricedItem } from '@eriveltonsilva/currency.js'
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Basic Usage
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
// Create instances
|
|
57
|
+
const price = from(19.99, 'BR')
|
|
58
|
+
price.format() // => 'R$ 19,99'
|
|
59
|
+
price.amount() // => 19.99
|
|
60
|
+
price.minorUnits() // => 1999
|
|
61
|
+
|
|
62
|
+
// Arithmetic (all return new instances)
|
|
63
|
+
price.plus(5).format() // => 'R$ 24,99'
|
|
64
|
+
price.minus(4.99).format() // => 'R$ 15,00'
|
|
65
|
+
price.times(2).format() // => 'R$ 39,98'
|
|
66
|
+
price.divide(2).format() // => 'R$ 10,00'
|
|
67
|
+
|
|
68
|
+
// Business operations
|
|
69
|
+
price.applyDiscount(10).format() // => 'R$ 17,99' (10% off)
|
|
70
|
+
price.applySurcharge(5).format() // => 'R$ 20,99' (5% added)
|
|
71
|
+
price.percentOf(15).format() // => 'R$ 3,00' (15% of price)
|
|
72
|
+
|
|
73
|
+
// Comparison
|
|
74
|
+
price.equals(19.99) // => true
|
|
75
|
+
price.greaterThan(10) // => true
|
|
76
|
+
price.isBetween(10, 50) // => true
|
|
77
|
+
|
|
78
|
+
// Allocation (largest-remainder method)
|
|
79
|
+
from(10, 'BR').allocate(3).map((m) => m.amount())
|
|
80
|
+
// => [3.34, 3.33, 3.33]
|
|
81
|
+
|
|
82
|
+
from(100, 'US').allocateByRatio([1, 3]).map((m) => m.amount())
|
|
83
|
+
// => [25, 75]
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Collection Functions
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
import { sum, average, max, min, clamp } from '@eriveltonsilva/currency.js'
|
|
90
|
+
|
|
91
|
+
sum([10, 20.50, 5], 'BR').format() // => 'R$ 35,50'
|
|
92
|
+
average([10, 20, 30], 'US').format() // => '$20.00'
|
|
93
|
+
max([5, 30, 10], 'US').format() // => '$30.00'
|
|
94
|
+
min([5, 30, 10], 'US').format() // => '$5.00'
|
|
95
|
+
clamp(150, 0, 100, 'US').format() // => '$100.00'
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Business Functions
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
import { total, percent } from '@eriveltonsilva/currency.js'
|
|
102
|
+
|
|
103
|
+
const items = [
|
|
104
|
+
{ price: 9.99, quantity: 3 },
|
|
105
|
+
{ price: 4.99 },
|
|
106
|
+
]
|
|
107
|
+
total(items, 'US').format() // => '$34.96'
|
|
108
|
+
|
|
109
|
+
percent(25, 200, 'US') // => 12.5 (25 is 12.5% of 200)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Country Presets
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
import { br, us, de, jp } from '@eriveltonsilva/currency.js/presets'
|
|
116
|
+
|
|
117
|
+
// Accepts number (major units) or locale-formatted string
|
|
118
|
+
br(19.99).format() // => 'R$ 19,99'
|
|
119
|
+
us(19.99).format() // => '$19.99'
|
|
120
|
+
|
|
121
|
+
br('R$ 1.999,99').amount() // => 1999.99
|
|
122
|
+
us('$1,999.99').amount() // => 1999.99
|
|
123
|
+
|
|
124
|
+
de(1500).format() // => '1.500,00 €'
|
|
125
|
+
jp(500).format() // => '¥500'
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Formatting
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
const price = from(1999.9, 'BR')
|
|
132
|
+
|
|
133
|
+
price.format() // => 'R$ 1.999,90'
|
|
134
|
+
price.format({ currencyDisplay: 'code' }) // => 'BRL 1.999,90'
|
|
135
|
+
price.format({ currencyDisplay: 'none' }) // => '1.999,90'
|
|
136
|
+
price.format({ notation: 'compact' }) // => 'R$ 2 mil'
|
|
137
|
+
price.format({ signDisplay: 'always' }) // => '+R$ 1.999,90'
|
|
138
|
+
price.format({ currencySign: 'accounting' }) // => 'R$ 1.999,90'
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Serialization
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
const price = from(19.99, 'BR')
|
|
145
|
+
|
|
146
|
+
// JSON round-trip
|
|
147
|
+
const json = price.toJSON()
|
|
148
|
+
// => { minorUnits: 1999, currencyCode: 'BRL' }
|
|
149
|
+
|
|
150
|
+
const restored = fromMinorUnits(json.minorUnits, 'BR')
|
|
151
|
+
restored.equals(price) // => true
|
|
152
|
+
|
|
153
|
+
// String output
|
|
154
|
+
price.toString() // => '19.99'
|
|
155
|
+
price.format() // => 'R$ 19,99'
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Error Handling
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
import { from, MoneyError, CurrencyMismatchError } from '@eriveltonsilva/currency.js'
|
|
162
|
+
|
|
163
|
+
try {
|
|
164
|
+
from(10, 'BR').plus(from(10, 'US'))
|
|
165
|
+
} catch (err) {
|
|
166
|
+
if (err instanceof MoneyError) {
|
|
167
|
+
console.error(err.code) // => 'CURRENCY_MISMATCH'
|
|
168
|
+
console.error(err.message) // => 'Cannot operate on mismatched currencies: BRL and USD.'
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
All errors extend `MoneyError` and expose a `code` property for programmatic handling:
|
|
174
|
+
|
|
175
|
+
| Error | Code |
|
|
176
|
+
| -------------------------- | ------------------------ |
|
|
177
|
+
| `InvalidInputError` | `'INVALID_INPUT'` |
|
|
178
|
+
| `InvalidPercentageError` | `'INVALID_PERCENTAGE'` |
|
|
179
|
+
| `DivisionByZeroError` | `'DIVISION_BY_ZERO'` |
|
|
180
|
+
| `InvalidAllocationError` | `'INVALID_ALLOCATION'` |
|
|
181
|
+
| `InvalidRangeError` | `'INVALID_RANGE'` |
|
|
182
|
+
| `CurrencyMismatchError` | `'CURRENCY_MISMATCH'` |
|
|
183
|
+
| `UnsupportedCurrencyError` | `'UNSUPPORTED_CURRENCY'` |
|
|
184
|
+
| `UnsafeIntegerError` | `'UNSAFE_INTEGER'` |
|
|
185
|
+
|
|
186
|
+
## Supported Countries
|
|
187
|
+
|
|
188
|
+
| Code | Country | Currency |
|
|
189
|
+
| ---- | -------------- | -------- |
|
|
190
|
+
| `AU` | Australia | AUD |
|
|
191
|
+
| `BR` | Brazil | BRL |
|
|
192
|
+
| `CA` | Canada | CAD |
|
|
193
|
+
| `CH` | Switzerland | CHF |
|
|
194
|
+
| `CN` | China | CNY |
|
|
195
|
+
| `DE` | Germany | EUR |
|
|
196
|
+
| `FR` | France | EUR |
|
|
197
|
+
| `GB` | United Kingdom | GBP |
|
|
198
|
+
| `IN` | India | INR |
|
|
199
|
+
| `JP` | Japan | JPY |
|
|
200
|
+
| `MX` | Mexico | MXN |
|
|
201
|
+
| `PT` | Portugal | EUR |
|
|
202
|
+
| `SG` | Singapore | SGD |
|
|
203
|
+
| `US` | United States | USD |
|
|
204
|
+
|
|
205
|
+
## Changelog
|
|
206
|
+
|
|
207
|
+
See [CHANGELOG.md](./CHANGELOG.md) for a detailed list of changes in each release.
|
|
208
|
+
|
|
209
|
+
## Contributing
|
|
210
|
+
|
|
211
|
+
Contributions are welcome! Please read our [Contributing Guide](./CONTRIBUTING.md) for details.
|
|
212
|
+
|
|
213
|
+
## License
|
|
214
|
+
|
|
215
|
+
MIT © [Erivelton Silva](https://github.com/eriveltondasilva)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @ERIVELTONDASILVA/CURRENCY v1.0.0
|
|
3
|
+
*
|
|
4
|
+
* A lightweight and reliable JavaScript library for precise currency operations, built to safely handle monetary values without floating point errors.
|
|
5
|
+
*
|
|
6
|
+
* @author Erivelton Silva <eriveltondasilva13@gmail.com>
|
|
7
|
+
* @license MIT
|
|
8
|
+
* @copyright 2026 Erivelton Silva
|
|
9
|
+
* @version 1.0.0
|
|
10
|
+
*
|
|
11
|
+
* @see https://github.com/eriveltondasilva/currency#readme - Documentation
|
|
12
|
+
*
|
|
13
|
+
* Inspired by:
|
|
14
|
+
* @see https://github.com/scurker/currency.js
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
var z=Object.defineProperty;var V=(r,n)=>{for(var e in n)z(r,e,{get:n[e],enumerable:true});};var f=class extends Error{code;input;constructor(n,e,t){super(n,t),this.code=e,this.input=t?.input;}},i=class extends f{name="InvalidInputError";constructor(n,e){super(n,"INVALID_INPUT",e);}},d=class extends f{name="InvalidPercentageError";constructor(n,e){super(n,"INVALID_PERCENTAGE",e);}},D=class extends f{name="DivisionByZeroError";constructor(n){super("Cannot divide by zero.","DIVISION_BY_ZERO",n);}},b=class extends f{name="InvalidAllocationError";constructor(n,e){super(n,"INVALID_ALLOCATION",e);}},x=class extends f{name="InvalidRangeError";constructor(n){super("The minimum value cannot be greater than the maximum value.","INVALID_RANGE",n);}},E=class extends f{name="CurrencyMismatchError";constructor(n,e,t){super(`Cannot operate on mismatched currencies: ${n} and ${e}.`,"CURRENCY_MISMATCH",t);}},O=class extends f{name="UnsupportedCurrencyError";constructor(n,e,t){super(`'${n}' is not a supported currency country. Supported codes: ${e}.`,"UNSUPPORTED_CURRENCY",t);}},U=class extends f{name="UnsafeIntegerError";constructor(n){super("The resulting amount exceeds the safe integer limit for precision.","UNSAFE_INTEGER",n);}};var S=Symbol("@eriveltondasilva/currency");function F(r){return typeof r=="object"&&r!=null&&!Array.isArray(r)}function g(r){return F(r)&&S in r}function v(r){return typeof r=="number"||g(r)}function Y(r){return r>=0?Math.ceil(r):Math.floor(r)}function k(r){return Math.sign(r)*Math.round(Math.abs(r))}function J(r){let n=Math.floor(r);return r-n!==.5?Math.round(r):n%2===0?n:n+1}function Z(r){return Math.ceil(r-.5)}function H(r){return r>=0?Math.ceil(r-.5):Math.floor(r+.5)}var I={ceil:Math.ceil,floor:Math.floor,trunc:Math.trunc,expand:Y,halfExpand:k,halfEven:J,halfCeil:Math.round,halfFloor:Z,halfTrunc:H},h="halfExpand",_=I[h];var $=r=>r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),P=new Map;function q(r,n){let e=`${r}\0${n}`;return P.has(e)||P.set(e,new RegExp(`[^\\d${$(r)}${$(n)}]`,"g")),P.get(e)}function w(r,n){if(!Number.isFinite(r))throw new i("Value must be a finite number.",{input:r});if(r===0)return 0;let e=_(+`${r}e${n}`);if(!Number.isFinite(e))throw new i("Value is too large to be represented as a monetary amount.",{input:r});if(!Number.isSafeInteger(e))throw new i("Value exceeds safe integer range after conversion to minor units.",{input:r});return e}function G(r,n){let{group:e,decimal:t,fractionDigits:o}=n,[,s="",a=""]=/^([+-]?)(.*)$/.exec(r.trim())??[],u=q(e,t),C=a.replace(u,"").replaceAll(e,"");if(C.indexOf(t)!==C.lastIndexOf(t))throw new i("Cannot parse value as a monetary amount: multiple decimal separators found.",{input:r});let l=s+C.replace(t,"."),A=Number.parseFloat(l);if(Number.isNaN(A))throw new i(`Cannot parse value as a monetary amount. Expected "${t}" as decimal separator.`,{input:r});return w(A,o)}var B={AU:{name:"Australia",locale:"en-AU",currency:"AUD",decimal:".",group:","},BR:{name:"Brazil",locale:"pt-BR",currency:"BRL",decimal:",",group:"."},CA:{name:"Canada",locale:"en-CA",currency:"CAD",decimal:".",group:","},CH:{name:"Switzerland",locale:"de-CH",currency:"CHF",decimal:".",group:"'"},CN:{name:"China",locale:"zh-CN",currency:"CNY",decimal:".",group:","},DE:{name:"Germany",locale:"de-DE",currency:"EUR",decimal:",",group:"."},FR:{name:"France",locale:"fr-FR",currency:"EUR",decimal:",",group:" "},GB:{name:"United Kingdom",locale:"en-GB",currency:"GBP",decimal:".",group:","},IN:{name:"India",locale:"en-IN",currency:"INR",decimal:".",group:","},JP:{name:"Japan",locale:"ja-JP",currency:"JPY",decimal:".",group:","},MX:{name:"Mexico",locale:"es-MX",currency:"MXN",decimal:".",group:","},PT:{name:"Portugal",locale:"pt-PT",currency:"EUR",decimal:",",group:"."},SG:{name:"Singapore",locale:"en-SG",currency:"SGD",decimal:".",group:","},US:{name:"United States",locale:"en-US",currency:"USD",decimal:".",group:","}},X={AUD:{name:"Australian Dollar",fractionDigits:2},BRL:{name:"Brazilian Real",fractionDigits:2},CAD:{name:"Canadian Dollar",fractionDigits:2},CHF:{name:"Swiss Franc",fractionDigits:2},CNY:{name:"Chinese Yuan",fractionDigits:2},EUR:{name:"Euro",fractionDigits:2},GBP:{name:"British Pound",fractionDigits:2},INR:{name:"Indian Rupee",fractionDigits:2},JPY:{name:"Japanese Yen",fractionDigits:0},MXN:{name:"Mexican Peso",fractionDigits:2},SGD:{name:"Singapore Dollar",fractionDigits:2},USD:{name:"US Dollar",fractionDigits:2}},j=Object.keys(B).join(", ");function y(r){let n=B[r];if(!n)throw new O(r,j);let{locale:e,currency:t,decimal:o,group:s}=n,{fractionDigits:a}=X[t];return {locale:e,code:t,decimal:o,group:s,fractionDigits:a}}function L(r,n,e={}){let t=e.locale??n.locale,o=e.currencyDisplay==="none",s=e.notation==="compact";return new Intl.NumberFormat(t,{style:o?"decimal":"currency",currency:o?void 0:n.code,currencySign:e.currencySign??"standard",currencyDisplay:o?void 0:e.currencyDisplay??"symbol",notation:e.notation??"standard",compactDisplay:e.compactDisplay??"short",signDisplay:e.signDisplay??"auto",useGrouping:e.useGrouping??true,minimumFractionDigits:e.minimumFractionDigits??(s?0:n.fractionDigits),maximumFractionDigits:e.maximumFractionDigits??(s?Math.min(1,n.fractionDigits):n.fractionDigits),trailingZeroDisplay:e.trailingZeroDisplay??"auto",roundingMode:e.roundingMode??"halfExpand"}).format(r)}var m=class r{#r;#i;#n;[S]=true;constructor(n,e){this.#i=10**e.fractionDigits,this.#r=e,this.#n=n;}static fromMinorUnits(n,e){if(!Number.isFinite(n))throw new i("Expected a finite number of minor units.",{input:n});if(!Number.isInteger(n))throw new i("Minor units must be an integer.",{input:n});if(!Number.isSafeInteger(n))throw new U({input:n});return new r(n,e)}static zero(n){return new r(0,n)}#a(n){if(n.currencyCode()!==this.#r.code)throw new E(this.#r.code,n.currencyCode())}#e(n){return g(n)?(this.#a(n),n.minorUnits()):w(n,this.#r.fractionDigits)}#t(n){if(!Number.isFinite(n))throw new i("Operation produced a non-finite result.",{input:n});if(!Number.isSafeInteger(n))throw new U({input:n});return new r(n,this.#r)}#o(){return new r(this.#n,this.#r)}#s(){return r.zero(this.#r)}minorUnits(){return this.#n}amount(){return this.#n/this.#i}units(){return Math.floor(Math.abs(this.#n)/this.#i)}subunits(){return Math.abs(this.#n)%this.#i}toParts(){return {units:this.units(),subunits:this.subunits(),isNegative:this.isNegative()}}currencyCode(){return this.#r.code}locale(){return this.#r.locale}isZero(){return this.#n===0}isPositive(){return this.#n>0}isNegative(){return this.#n<0}plus(n){return this.#t(this.#n+this.#e(n))}minus(n){return this.#t(this.#n-this.#e(n))}times(n,e=h){if(!Number.isFinite(n))throw new i("Factor must be a finite number.",{input:n});return n===0?this.#s():n===1?this.#o():this.#t(I[e](this.#n*n))}divide(n,e=h){if(n===0)throw new D;if(!Number.isFinite(n))throw new i("Divisor must be a finite number.",{input:n});return n===1?this.#o():this.#t(I[e](this.#n/n))}abs(){return this.#t(Math.abs(this.#n))}negate(){return this.#t(-this.#n)}max(n){let e=this.#e(n);return this.#n>=e?this.#o():this.#t(e)}min(n){let e=this.#e(n);return this.#n<=e?this.#o():this.#t(e)}round(n,e=h){if(!Number.isFinite(n)||n<=0)throw new i("Step must be a positive finite number.",{input:n});if(this.isZero())return this.#o();let t=Math.round(n*this.#i);if(t<1)throw new i("Step is too small to be represented in minor units for this currency.",{input:n});return t===1?this.#o():this.#t(I[e](this.#n/t)*t)}equals(n){return g(n)&&n.currencyCode()!==this.#r.code?false:this.#n===this.#e(n)}compare(n){let e=this.#e(n);return this.#n<e?-1:this.#n>e?1:0}greaterThan(n){return this.#n>this.#e(n)}lessThan(n){return this.#n<this.#e(n)}greaterThanOrEqual(n){return this.#n>=this.#e(n)}lessThanOrEqual(n){return this.#n<=this.#e(n)}isBetween(n,e){let t=this.#e(n),o=this.#e(e);if(t>o)throw new x;return this.#n>=t&&this.#n<=o}hasSameCurrency(n){return g(n)?this.#r.code===n.currencyCode():false}percentOf(n,e=h){if(!Number.isFinite(n))throw new d("Percentage must be a finite number.",{input:n});if(n<0)throw new d("Percentage must be non-negative.",{input:n});return n===0?this.#s():n===100?this.#o():this.#t(I[e](this.#n*(n/100)))}applyDiscount(n,e=h){if(!Number.isFinite(n))throw new d("Discount must be a finite number.",{input:n});if(n<0)throw new d("Discount cannot be negative.",{input:n});if(n>100)throw new d("Discount cannot exceed 100%.",{input:n});return n===0?this.#o():n===100?this.#s():this.minus(this.percentOf(n,e))}applySurcharge(n,e=h){if(!Number.isFinite(n))throw new d("Surcharge must be a finite number.",{input:n});if(n<0)throw new d("Surcharge must be non-negative.",{input:n});return n===0?this.#o():this.plus(this.percentOf(n,e))}allocate(n){if(!Number.isInteger(n)||n<1)throw new b("Number of parts must be a positive integer.");if(n===1)return [this.#o()];if(this.isZero())return Array.from({length:n},()=>this.#s());let t=this.isNegative(),o=Math.abs(this.#n),s=Math.floor(o/n),a=o%n;return Array.from({length:n},(u,M)=>{let C=s+(M<a?1:0);return this.#t(t?-C:C)})}allocateByRatio(n){if(n.length===0||n.some(c=>!Number.isFinite(c)||c<0))throw new b("Ratios must be a non-empty array of non-negative finite numbers.");if(n.some(c=>!Number.isInteger(c)))throw new b("Ratios must be integers. Use whole numbers like [1, 2, 3] or [30, 70].");let o=n.reduce((c,l)=>c+l,0);if(!Number.isSafeInteger(o))throw new b("The sum of ratios exceeds the safe integer range.");if(o===0)throw new b("The sum of ratios cannot be zero.");if(this.isZero())return n.map(()=>this.#s());let s=this.isNegative(),a=Math.abs(this.#n),u=n.map(c=>{let l=a*c;if(!Number.isSafeInteger(l))throw new U({input:l});return Math.floor(l/o)}),M=u.reduce((c,l)=>c+l,0),C=a-M;return u.map((c,l)=>{let A=c+(l<C?1:0);return this.#t(s?-A:A)})}format(n){return L(this.amount(),this.#r,n)}toString(){return `${this.#r.code} ${this.amount().toFixed(this.#r.fractionDigits)}`}toJSON(){return {minorUnits:this.#n,currencyCode:this.#r.code}}};function T(r){if(r==null)throw new i("Value cannot be null or undefined.",{input:r})}function Q(r,n){if(T(r),typeof r!="number")throw new i("Expected a number.",{input:r});let e=y(n),t=w(r,e.fractionDigits);return m.fromMinorUnits(t,e)}function K(r,n){if(T(r),typeof r!="string")throw new i("Expected a string.",{input:r});let e=y(n),t=G(r,e);return m.fromMinorUnits(t,e)}function W(r,n){if(T(r),!Number.isFinite(r))throw new i("fromMinorUnits(): value must be a finite number.",{input:r});if(!Number.isInteger(r))throw new i("fromMinorUnits(): value must be an integer.",{input:r});if(!Number.isSafeInteger(r))throw new i("fromMinorUnits(): value exceeds safe integer range.",{input:r});let e=y(n);return m.fromMinorUnits(r,e)}function R(r){let n=y(r);return m.zero(n)}function N(r){return !Array.isArray(r)||r.length===0}function p(r,n,e){if(r==null)throw new i(`${e} \u2014 value cannot be null or undefined.`,{input:r});if(g(r)){if(r.currencyCode()!==n.code)throw new E(n.code,r.currencyCode());return r.minorUnits()}if(typeof r!="number")throw new i(`${e} \u2014 expected a number or MoneyContract.`,{input:r});try{return w(r,n.fractionDigits)}catch(t){if(t instanceof f)throw t;throw new i(`${e} \u2014 invalid value.`,{input:r,cause:t})}}function nn(r,n){if(N(r))return R(n);let e=y(n),t=r.reduce((o,s,a)=>{if(!F(s))throw new i(`total(): index ${a} \u2014 expected { price, quantity? }.`,{input:s});let{price:u,quantity:M=1}=s;if(!Number.isInteger(M)||M<0)throw new i(`total(): index ${a} \u2014 quantity must be an integer. Fractional quantities produce ambiguous sub-minor-unit values.`,{input:M});let c=p(u,e,`total(): index ${a} \u2014 price`);return o+c*M},0);return m.fromMinorUnits(t,e)}function rn(r,n,e){let t=y(e),o=p(n,t,"percent(): total");if(o===0)throw new D;return p(r,t,"percent(): part")/o*100}function en(r,n){if(N(r))return R(n);let e=y(n),t=r.reduce((o,s,a)=>o+p(s,e,`sum(): index ${a}`),0);return m.fromMinorUnits(t,e)}function tn(r,n,e=h){if(N(r))return R(n);let t=y(n),o=r.reduce((s,a,u)=>s+p(a,t,`average(): index ${u}`),0);return m.fromMinorUnits(I[e](o/r.length),t)}function on(r,n){if(N(r))throw new i("max(): array must have at least one element.",{input:r});let e=y(n),t=r.slice(1).reduce((o,s,a)=>{let u=p(s,e,`max(): index ${a+1}`);return u>o?u:o},p(r[0],e,"max(): index 0"));return m.fromMinorUnits(t,e)}function sn(r,n){if(N(r))throw new i("min(): array must have at least one element.",{input:r});let e=y(n),t=r.slice(1).reduce((o,s,a)=>{let u=p(s,e,`min(): index ${a+1}`);return u<o?u:o},p(r[0],e,"min(): index 0"));return m.fromMinorUnits(t,e)}function an(r,n,e,t){let o=y(t),s=p(n,o,"clamp(): min"),a=p(e,o,"clamp(): max");if(s>a)throw new x;return m.fromMinorUnits(Math.min(Math.max(p(r,o,"clamp(): value"),s),a),o)}var un={};V(un,{average:()=>tn,clamp:()=>an,from:()=>Q,fromMinorUnits:()=>W,isMoney:()=>g,isMoneyInput:()=>v,max:()=>on,min:()=>sn,parse:()=>K,percent:()=>rn,sum:()=>en,total:()=>nn,zero:()=>R});/* v8 ignore if -- @preserve */
|
|
18
|
+
/* v8 ignore next -- @preserve */export{f as a,i as b,d as c,D as d,b as e,x as f,E as g,O as h,U as i,g as j,v as k,Q as l,K as m,W as n,R as o,nn as p,rn as q,en as r,tn as s,on as t,sn as u,an as v,un as w};
|