@fin.cx/einvoice 5.0.3 → 5.1.3

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.
Files changed (117) hide show
  1. package/dist_ts/00_commitinfo_data.js +1 -1
  2. package/dist_ts/einvoice.d.ts +4 -8
  3. package/dist_ts/einvoice.js +46 -7
  4. package/dist_ts/formats/converters/xml-to-einvoice.converter.d.ts +21 -0
  5. package/dist_ts/formats/converters/xml-to-einvoice.converter.js +127 -0
  6. package/dist_ts/formats/semantic/bt-bg.model.d.ts +445 -0
  7. package/dist_ts/formats/semantic/bt-bg.model.js +12 -0
  8. package/dist_ts/formats/semantic/semantic.adapter.d.ts +87 -0
  9. package/dist_ts/formats/semantic/semantic.adapter.js +538 -0
  10. package/dist_ts/formats/semantic/semantic.validator.d.ts +48 -0
  11. package/dist_ts/formats/semantic/semantic.validator.js +596 -0
  12. package/dist_ts/formats/utils/currency.calculator.decimal.d.ts +98 -0
  13. package/dist_ts/formats/utils/currency.calculator.decimal.js +212 -0
  14. package/dist_ts/formats/utils/currency.utils.d.ts +99 -0
  15. package/dist_ts/formats/utils/currency.utils.js +250 -0
  16. package/dist_ts/formats/utils/decimal.d.ts +151 -0
  17. package/dist_ts/formats/utils/decimal.js +435 -0
  18. package/dist_ts/formats/validation/codelist.validator.d.ts +49 -0
  19. package/dist_ts/formats/validation/codelist.validator.js +188 -0
  20. package/dist_ts/formats/validation/conformance.harness.d.ts +99 -0
  21. package/dist_ts/formats/validation/conformance.harness.js +471 -0
  22. package/dist_ts/formats/validation/en16931.business-rules.validator.d.ts +58 -0
  23. package/dist_ts/formats/validation/en16931.business-rules.validator.js +459 -0
  24. package/dist_ts/formats/validation/facturx.validator.d.ts +75 -0
  25. package/dist_ts/formats/validation/facturx.validator.js +522 -0
  26. package/dist_ts/formats/validation/integrated.validator.d.ts +82 -0
  27. package/dist_ts/formats/validation/integrated.validator.js +311 -0
  28. package/dist_ts/formats/validation/peppol.validator.d.ts +77 -0
  29. package/dist_ts/formats/validation/peppol.validator.js +529 -0
  30. package/dist_ts/formats/validation/schematron.downloader.d.ts +71 -0
  31. package/dist_ts/formats/validation/schematron.downloader.js +254 -0
  32. package/dist_ts/formats/validation/schematron.integration.d.ts +60 -0
  33. package/dist_ts/formats/validation/schematron.integration.js +230 -0
  34. package/dist_ts/formats/validation/schematron.validator.d.ts +79 -0
  35. package/dist_ts/formats/validation/schematron.validator.js +288 -0
  36. package/dist_ts/formats/validation/schematron.worker.d.ts +50 -0
  37. package/dist_ts/formats/validation/schematron.worker.js +185 -0
  38. package/dist_ts/formats/validation/validation.types.d.ts +163 -0
  39. package/dist_ts/formats/validation/validation.types.js +181 -0
  40. package/dist_ts/formats/validation/vat-categories.validator.d.ts +87 -0
  41. package/dist_ts/formats/validation/vat-categories.validator.js +497 -0
  42. package/dist_ts/formats/validation/xrechnung.validator.d.ts +92 -0
  43. package/dist_ts/formats/validation/xrechnung.validator.js +417 -0
  44. package/dist_ts/interfaces/common.d.ts +1 -0
  45. package/dist_ts/interfaces/en16931-metadata.d.ts +83 -0
  46. package/dist_ts/interfaces/en16931-metadata.js +6 -0
  47. package/dist_ts/plugins.d.ts +3 -1
  48. package/dist_ts/plugins.js +7 -2
  49. package/dist_ts_install/download-schematron.d.ts +6 -0
  50. package/dist_ts_install/download-schematron.js +62 -0
  51. package/dist_ts_install/download-test-samples.d.ts +19 -0
  52. package/dist_ts_install/download-test-samples.js +169 -0
  53. package/dist_ts_install/download-xrechnung-rules.d.ts +7 -0
  54. package/dist_ts_install/download-xrechnung-rules.js +146 -0
  55. package/dist_ts_install/index.d.ts +8 -0
  56. package/dist_ts_install/index.js +246 -0
  57. package/npmextra.json +1 -1
  58. package/package.json +12 -6
  59. package/readme.md +255 -810
  60. package/ts/00_commitinfo_data.ts +1 -1
  61. package/ts/einvoice.ts +63 -14
  62. package/ts/formats/converters/xml-to-einvoice.converter.ts +142 -0
  63. package/ts/formats/semantic/bt-bg.model.ts +524 -0
  64. package/ts/formats/semantic/semantic.adapter.ts +600 -0
  65. package/ts/formats/semantic/semantic.validator.ts +654 -0
  66. package/ts/formats/utils/currency.calculator.decimal.ts +323 -0
  67. package/ts/formats/utils/currency.utils.ts +299 -0
  68. package/ts/formats/utils/decimal.ts +509 -0
  69. package/ts/formats/validation/codelist.validator.ts +317 -0
  70. package/ts/formats/validation/conformance.harness.ts +591 -0
  71. package/ts/formats/validation/en16931.business-rules.validator.ts +694 -0
  72. package/ts/formats/validation/facturx.validator.ts +579 -0
  73. package/ts/formats/validation/integrated.validator.ts +405 -0
  74. package/ts/formats/validation/peppol.validator.ts +589 -0
  75. package/ts/formats/validation/schematron.downloader.ts +304 -0
  76. package/ts/formats/validation/schematron.integration.ts +285 -0
  77. package/ts/formats/validation/schematron.validator.ts +348 -0
  78. package/ts/formats/validation/schematron.worker.ts +221 -0
  79. package/ts/formats/validation/validation.types.ts +274 -0
  80. package/ts/formats/validation/vat-categories.validator.ts +845 -0
  81. package/ts/formats/validation/xrechnung.validator.ts +494 -0
  82. package/ts/interfaces/common.ts +1 -0
  83. package/ts/interfaces/en16931-metadata.ts +104 -0
  84. package/ts/plugins.ts +8 -0
  85. package/ts/tspublish.json +3 -0
  86. package/dist_ts/classes.decoder.d.ts +0 -40
  87. package/dist_ts/classes.decoder.js +0 -320
  88. package/dist_ts/classes.encoder.d.ts +0 -51
  89. package/dist_ts/classes.encoder.js +0 -293
  90. package/dist_ts/classes.xinvoice.d.ts +0 -136
  91. package/dist_ts/classes.xinvoice.js +0 -352
  92. package/dist_ts/formats/base.decoder.d.ts +0 -19
  93. package/dist_ts/formats/base.decoder.js +0 -130
  94. package/dist_ts/formats/base.validator.d.ts +0 -44
  95. package/dist_ts/formats/base.validator.js +0 -39
  96. package/dist_ts/formats/decoder.factory.d.ts +0 -15
  97. package/dist_ts/formats/decoder.factory.js +0 -46
  98. package/dist_ts/formats/factorx.decoder.d.ts +0 -18
  99. package/dist_ts/formats/factorx.decoder.js +0 -178
  100. package/dist_ts/formats/factorx.encoder.d.ts +0 -51
  101. package/dist_ts/formats/factorx.encoder.js +0 -293
  102. package/dist_ts/formats/facturx.decoder.d.ts +0 -18
  103. package/dist_ts/formats/facturx.decoder.js +0 -210
  104. package/dist_ts/formats/facturx.encoder.d.ts +0 -51
  105. package/dist_ts/formats/facturx.encoder.js +0 -293
  106. package/dist_ts/formats/facturx.validator.d.ts +0 -67
  107. package/dist_ts/formats/facturx.validator.js +0 -266
  108. package/dist_ts/formats/pdf/robust-pdf.extractor.d.ts +0 -40
  109. package/dist_ts/formats/pdf/robust-pdf.extractor.js +0 -324
  110. package/dist_ts/formats/ubl.validator.d.ts +0 -82
  111. package/dist_ts/formats/ubl.validator.js +0 -306
  112. package/dist_ts/formats/validator.factory.d.ts +0 -18
  113. package/dist_ts/formats/validator.factory.js +0 -78
  114. package/dist_ts/formats/xinvoice.decoder.d.ts +0 -28
  115. package/dist_ts/formats/xinvoice.decoder.js +0 -332
  116. package/dist_ts/formats/xinvoice.encoder.d.ts +0 -19
  117. package/dist_ts/formats/xinvoice.encoder.js +0 -282
@@ -0,0 +1,509 @@
1
+ /**
2
+ * Decimal Arithmetic Library for EN16931 Compliance
3
+ * Provides arbitrary precision decimal arithmetic to avoid floating-point errors
4
+ *
5
+ * Based on EN16931 requirements for financial calculations:
6
+ * - All monetary amounts must be calculated with sufficient precision
7
+ * - Rounding must be consistent and predictable
8
+ * - No loss of precision in intermediate calculations
9
+ */
10
+
11
+ /**
12
+ * Decimal class for arbitrary precision arithmetic
13
+ * Internally stores the value as an integer with a scale factor
14
+ */
15
+ export class Decimal {
16
+ private readonly value: bigint;
17
+ private readonly scale: number;
18
+
19
+ // Constants - initialized lazily to avoid initialization issues
20
+ private static _ZERO: Decimal | undefined;
21
+ private static _ONE: Decimal | undefined;
22
+ private static _TEN: Decimal | undefined;
23
+ private static _HUNDRED: Decimal | undefined;
24
+
25
+ static get ZERO(): Decimal {
26
+ if (!this._ZERO) this._ZERO = new Decimal(0);
27
+ return this._ZERO;
28
+ }
29
+
30
+ static get ONE(): Decimal {
31
+ if (!this._ONE) this._ONE = new Decimal(1);
32
+ return this._ONE;
33
+ }
34
+
35
+ static get TEN(): Decimal {
36
+ if (!this._TEN) this._TEN = new Decimal(10);
37
+ return this._TEN;
38
+ }
39
+
40
+ static get HUNDRED(): Decimal {
41
+ if (!this._HUNDRED) this._HUNDRED = new Decimal(100);
42
+ return this._HUNDRED;
43
+ }
44
+
45
+ // Default scale for monetary calculations (4 decimal places for intermediate calculations)
46
+ private static readonly DEFAULT_SCALE = 4;
47
+
48
+ /**
49
+ * Create a new Decimal from various input types
50
+ */
51
+ constructor(value: string | number | bigint | Decimal, scale?: number) {
52
+ if (value instanceof Decimal) {
53
+ this.value = value.value;
54
+ this.scale = value.scale;
55
+ return;
56
+ }
57
+
58
+ // Special handling for direct bigint with scale (internal use)
59
+ if (typeof value === 'bigint' && scale !== undefined) {
60
+ this.value = value;
61
+ this.scale = scale;
62
+ return;
63
+ }
64
+
65
+ // Determine scale if not provided
66
+ if (scale === undefined) {
67
+ if (typeof value === 'string') {
68
+ const parts = value.split('.');
69
+ scale = parts.length > 1 ? parts[1].length : 0;
70
+ } else {
71
+ scale = Decimal.DEFAULT_SCALE;
72
+ }
73
+ }
74
+
75
+ this.scale = scale;
76
+
77
+ // Convert to scaled integer
78
+ if (typeof value === 'string') {
79
+ // Remove any formatting
80
+ value = value.replace(/[^\d.-]/g, '');
81
+ const parts = value.split('.');
82
+ const integerPart = parts[0] || '0';
83
+ const decimalPart = (parts[1] || '').padEnd(scale, '0').slice(0, scale);
84
+ this.value = BigInt(integerPart + decimalPart);
85
+ } else if (typeof value === 'number') {
86
+ // Handle floating point numbers
87
+ if (!isFinite(value)) {
88
+ throw new Error(`Invalid number value: ${value}`);
89
+ }
90
+ const multiplier = Math.pow(10, scale);
91
+ this.value = BigInt(Math.round(value * multiplier));
92
+ } else {
93
+ // bigint
94
+ this.value = value * BigInt(Math.pow(10, scale));
95
+ }
96
+ }
97
+
98
+ /**
99
+ * Convert to string representation
100
+ */
101
+ toString(decimalPlaces?: number): string {
102
+ const absValue = this.value < 0n ? -this.value : this.value;
103
+ const str = absValue.toString().padStart(this.scale + 1, '0');
104
+ const integerPart = this.scale > 0 ? (str.slice(0, -this.scale) || '0') : str;
105
+ let decimalPart = this.scale > 0 ? str.slice(-this.scale) : '';
106
+
107
+ // Apply decimal places if specified
108
+ if (decimalPlaces !== undefined) {
109
+ if (decimalPlaces === 0) {
110
+ return (this.value < 0n ? '-' : '') + integerPart;
111
+ }
112
+ decimalPart = decimalPart.padEnd(decimalPlaces, '0').slice(0, decimalPlaces);
113
+ }
114
+
115
+ // Remove trailing zeros if no specific decimal places requested
116
+ if (decimalPlaces === undefined) {
117
+ decimalPart = decimalPart.replace(/0+$/, '');
118
+ }
119
+
120
+ const result = decimalPart ? `${integerPart}.${decimalPart}` : integerPart;
121
+ return this.value < 0n ? '-' + result : result;
122
+ }
123
+
124
+ /**
125
+ * Convert to number (may lose precision)
126
+ */
127
+ toNumber(): number {
128
+ return Number(this.value) / Math.pow(10, this.scale);
129
+ }
130
+
131
+ /**
132
+ * Convert to fixed decimal places string
133
+ */
134
+ toFixed(decimalPlaces: number): string {
135
+ return this.round(decimalPlaces).toString(decimalPlaces);
136
+ }
137
+
138
+ /**
139
+ * Add two decimals
140
+ */
141
+ add(other: Decimal | number | string): Decimal {
142
+ const otherDecimal = other instanceof Decimal ? other : new Decimal(other);
143
+
144
+ // Align scales
145
+ if (this.scale === otherDecimal.scale) {
146
+ return new Decimal(this.value + otherDecimal.value, this.scale);
147
+ }
148
+
149
+ const maxScale = Math.max(this.scale, otherDecimal.scale);
150
+ const thisScaled = this.rescale(maxScale);
151
+ const otherScaled = otherDecimal.rescale(maxScale);
152
+
153
+ return new Decimal(thisScaled.value + otherScaled.value, maxScale);
154
+ }
155
+
156
+ /**
157
+ * Subtract another decimal
158
+ */
159
+ subtract(other: Decimal | number | string): Decimal {
160
+ const otherDecimal = other instanceof Decimal ? other : new Decimal(other);
161
+
162
+ // Align scales
163
+ if (this.scale === otherDecimal.scale) {
164
+ return new Decimal(this.value - otherDecimal.value, this.scale);
165
+ }
166
+
167
+ const maxScale = Math.max(this.scale, otherDecimal.scale);
168
+ const thisScaled = this.rescale(maxScale);
169
+ const otherScaled = otherDecimal.rescale(maxScale);
170
+
171
+ return new Decimal(thisScaled.value - otherScaled.value, maxScale);
172
+ }
173
+
174
+ /**
175
+ * Multiply by another decimal
176
+ */
177
+ multiply(other: Decimal | number | string): Decimal {
178
+ const otherDecimal = other instanceof Decimal ? other : new Decimal(other);
179
+
180
+ // Multiply values and add scales
181
+ const newValue = this.value * otherDecimal.value;
182
+ const newScale = this.scale + otherDecimal.scale;
183
+
184
+ // Reduce scale if possible to avoid overflow
185
+ const result = new Decimal(newValue, newScale);
186
+ return result.normalize();
187
+ }
188
+
189
+ /**
190
+ * Divide by another decimal
191
+ */
192
+ divide(other: Decimal | number | string, precision: number = 10): Decimal {
193
+ const otherDecimal = other instanceof Decimal ? other : new Decimal(other);
194
+
195
+ if (otherDecimal.value === 0n) {
196
+ throw new Error('Division by zero');
197
+ }
198
+
199
+ // Scale up the dividend to maintain precision
200
+ const scaledDividend = this.value * BigInt(Math.pow(10, precision));
201
+ const quotient = scaledDividend / otherDecimal.value;
202
+
203
+ return new Decimal(quotient, this.scale + precision - otherDecimal.scale).normalize();
204
+ }
205
+
206
+ /**
207
+ * Calculate percentage (this * rate / 100)
208
+ */
209
+ percentage(rate: Decimal | number | string): Decimal {
210
+ const rateDecimal = rate instanceof Decimal ? rate : new Decimal(rate);
211
+ return this.multiply(rateDecimal).divide(100);
212
+ }
213
+
214
+ /**
215
+ * Round to specified decimal places using a specific rounding mode
216
+ */
217
+ round(decimalPlaces: number, mode: 'HALF_UP' | 'HALF_DOWN' | 'HALF_EVEN' | 'UP' | 'DOWN' | 'CEILING' | 'FLOOR' = 'HALF_UP'): Decimal {
218
+ if (decimalPlaces === this.scale) {
219
+ return this;
220
+ }
221
+
222
+ if (decimalPlaces > this.scale) {
223
+ // Just add zeros
224
+ return this.rescale(decimalPlaces);
225
+ }
226
+
227
+ // Need to round
228
+ const factor = BigInt(Math.pow(10, this.scale - decimalPlaces));
229
+ const halfFactor = factor / 2n;
230
+
231
+ let rounded: bigint;
232
+ const isNegative = this.value < 0n;
233
+ const absValue = isNegative ? -this.value : this.value;
234
+
235
+ switch (mode) {
236
+ case 'HALF_UP':
237
+ // Round half away from zero
238
+ rounded = (absValue + halfFactor) / factor;
239
+ break;
240
+
241
+ case 'HALF_DOWN':
242
+ // Round half toward zero
243
+ rounded = (absValue + halfFactor - 1n) / factor;
244
+ break;
245
+
246
+ case 'HALF_EVEN':
247
+ // Banker's rounding
248
+ const quotient = absValue / factor;
249
+ const remainder = absValue % factor;
250
+ if (remainder > halfFactor || (remainder === halfFactor && quotient % 2n === 1n)) {
251
+ rounded = quotient + 1n;
252
+ } else {
253
+ rounded = quotient;
254
+ }
255
+ break;
256
+
257
+ case 'UP':
258
+ // Round away from zero
259
+ rounded = (absValue + factor - 1n) / factor;
260
+ break;
261
+
262
+ case 'DOWN':
263
+ // Round toward zero
264
+ rounded = absValue / factor;
265
+ break;
266
+
267
+ case 'CEILING':
268
+ // Round toward positive infinity
269
+ if (isNegative) {
270
+ rounded = absValue / factor;
271
+ } else {
272
+ rounded = (absValue + factor - 1n) / factor;
273
+ }
274
+ break;
275
+
276
+ case 'FLOOR':
277
+ // Round toward negative infinity
278
+ if (isNegative) {
279
+ rounded = (absValue + factor - 1n) / factor;
280
+ } else {
281
+ rounded = absValue / factor;
282
+ }
283
+ break;
284
+
285
+ default:
286
+ throw new Error(`Unknown rounding mode: ${mode}`);
287
+ }
288
+
289
+ const finalValue = isNegative ? -rounded : rounded;
290
+ return new Decimal(finalValue, decimalPlaces);
291
+ }
292
+
293
+ /**
294
+ * Compare with another decimal
295
+ */
296
+ compareTo(other: Decimal | number | string): number {
297
+ const otherDecimal = other instanceof Decimal ? other : new Decimal(other);
298
+
299
+ // Align scales for comparison
300
+ if (this.scale === otherDecimal.scale) {
301
+ if (this.value < otherDecimal.value) return -1;
302
+ if (this.value > otherDecimal.value) return 1;
303
+ return 0;
304
+ }
305
+
306
+ const maxScale = Math.max(this.scale, otherDecimal.scale);
307
+ const thisScaled = this.rescale(maxScale);
308
+ const otherScaled = otherDecimal.rescale(maxScale);
309
+
310
+ if (thisScaled.value < otherScaled.value) return -1;
311
+ if (thisScaled.value > otherScaled.value) return 1;
312
+ return 0;
313
+ }
314
+
315
+ /**
316
+ * Check equality
317
+ */
318
+ equals(other: Decimal | number | string, tolerance?: Decimal | number | string): boolean {
319
+ if (tolerance) {
320
+ const toleranceDecimal = tolerance instanceof Decimal ? tolerance : new Decimal(tolerance);
321
+ const diff = this.subtract(other);
322
+ const absDiff = diff.abs();
323
+ return absDiff.compareTo(toleranceDecimal) <= 0;
324
+ }
325
+ return this.compareTo(other) === 0;
326
+ }
327
+
328
+ /**
329
+ * Check if less than
330
+ */
331
+ lessThan(other: Decimal | number | string): boolean {
332
+ return this.compareTo(other) < 0;
333
+ }
334
+
335
+ /**
336
+ * Check if less than or equal
337
+ */
338
+ lessThanOrEqual(other: Decimal | number | string): boolean {
339
+ return this.compareTo(other) <= 0;
340
+ }
341
+
342
+ /**
343
+ * Check if greater than
344
+ */
345
+ greaterThan(other: Decimal | number | string): boolean {
346
+ return this.compareTo(other) > 0;
347
+ }
348
+
349
+ /**
350
+ * Check if greater than or equal
351
+ */
352
+ greaterThanOrEqual(other: Decimal | number | string): boolean {
353
+ return this.compareTo(other) >= 0;
354
+ }
355
+
356
+ /**
357
+ * Get absolute value
358
+ */
359
+ abs(): Decimal {
360
+ return this.value < 0n ? new Decimal(-this.value, this.scale) : this;
361
+ }
362
+
363
+ /**
364
+ * Negate the value
365
+ */
366
+ negate(): Decimal {
367
+ return new Decimal(-this.value, this.scale);
368
+ }
369
+
370
+ /**
371
+ * Check if zero
372
+ */
373
+ isZero(): boolean {
374
+ return this.value === 0n;
375
+ }
376
+
377
+ /**
378
+ * Check if negative
379
+ */
380
+ isNegative(): boolean {
381
+ return this.value < 0n;
382
+ }
383
+
384
+ /**
385
+ * Check if positive
386
+ */
387
+ isPositive(): boolean {
388
+ return this.value > 0n;
389
+ }
390
+
391
+ /**
392
+ * Rescale to a different number of decimal places
393
+ */
394
+ private rescale(newScale: number): Decimal {
395
+ if (newScale === this.scale) {
396
+ return this;
397
+ }
398
+
399
+ if (newScale > this.scale) {
400
+ // Add zeros
401
+ const factor = BigInt(Math.pow(10, newScale - this.scale));
402
+ return new Decimal(this.value * factor, newScale);
403
+ }
404
+
405
+ // This would lose precision, use round() instead
406
+ throw new Error('Use round() to reduce scale');
407
+ }
408
+
409
+ /**
410
+ * Normalize by removing trailing zeros
411
+ */
412
+ private normalize(): Decimal {
413
+ if (this.value === 0n) {
414
+ return new Decimal(0n, 0);
415
+ }
416
+
417
+ let value = this.value;
418
+ let scale = this.scale;
419
+
420
+ while (scale > 0 && value % 10n === 0n) {
421
+ value = value / 10n;
422
+ scale--;
423
+ }
424
+
425
+ return new Decimal(value, scale);
426
+ }
427
+
428
+ /**
429
+ * Create a Decimal from a percentage string (e.g., "19%" -> 0.19)
430
+ */
431
+ static fromPercentage(value: string): Decimal {
432
+ const cleaned = value.replace('%', '').trim();
433
+ return new Decimal(cleaned).divide(100);
434
+ }
435
+
436
+ /**
437
+ * Sum an array of decimals
438
+ */
439
+ static sum(values: (Decimal | number | string)[]): Decimal {
440
+ return values.reduce<Decimal>((acc, val) => {
441
+ const decimal = val instanceof Decimal ? val : new Decimal(val);
442
+ return acc.add(decimal);
443
+ }, Decimal.ZERO);
444
+ }
445
+
446
+ /**
447
+ * Get the minimum value
448
+ */
449
+ static min(...values: (Decimal | number | string)[]): Decimal {
450
+ if (values.length === 0) {
451
+ throw new Error('No values provided');
452
+ }
453
+
454
+ let min = values[0] instanceof Decimal ? values[0] : new Decimal(values[0]);
455
+
456
+ for (let i = 1; i < values.length; i++) {
457
+ const current = values[i] instanceof Decimal ? values[i] : new Decimal(values[i]);
458
+ const currentDecimal = current instanceof Decimal ? current : new Decimal(current);
459
+ if (currentDecimal.lessThan(min)) {
460
+ min = currentDecimal;
461
+ }
462
+ }
463
+
464
+ return min;
465
+ }
466
+
467
+ /**
468
+ * Get the maximum value
469
+ */
470
+ static max(...values: (Decimal | number | string)[]): Decimal {
471
+ if (values.length === 0) {
472
+ throw new Error('No values provided');
473
+ }
474
+
475
+ let max = values[0] instanceof Decimal ? values[0] : new Decimal(values[0]);
476
+
477
+ for (let i = 1; i < values.length; i++) {
478
+ const current = values[i] instanceof Decimal ? values[i] : new Decimal(values[i]);
479
+ const currentDecimal = current instanceof Decimal ? current : new Decimal(current);
480
+ if (currentDecimal.greaterThan(max)) {
481
+ max = currentDecimal;
482
+ }
483
+ }
484
+
485
+ return max;
486
+ }
487
+ }
488
+
489
+ /**
490
+ * Helper function to create a Decimal
491
+ */
492
+ export function decimal(value: string | number | bigint | Decimal): Decimal {
493
+ return new Decimal(value);
494
+ }
495
+
496
+ /**
497
+ * Export commonly used rounding modes
498
+ */
499
+ export const RoundingMode = {
500
+ HALF_UP: 'HALF_UP' as const,
501
+ HALF_DOWN: 'HALF_DOWN' as const,
502
+ HALF_EVEN: 'HALF_EVEN' as const,
503
+ UP: 'UP' as const,
504
+ DOWN: 'DOWN' as const,
505
+ CEILING: 'CEILING' as const,
506
+ FLOOR: 'FLOOR' as const
507
+ } as const;
508
+
509
+ export type RoundingMode = typeof RoundingMode[keyof typeof RoundingMode];