iso-price 1.0.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 (85) hide show
  1. package/LICENSE +21 -0
  2. package/dist/contract/index.d.ts +25 -0
  3. package/dist/contract/index.js +60 -0
  4. package/dist/contract/index.js.map +1 -0
  5. package/dist/domain.objects/IsoCurrency.d.ts +63 -0
  6. package/dist/domain.objects/IsoCurrency.js +70 -0
  7. package/dist/domain.objects/IsoCurrency.js.map +1 -0
  8. package/dist/domain.objects/IsoPrice.d.ts +16 -0
  9. package/dist/domain.objects/IsoPrice.js +3 -0
  10. package/dist/domain.objects/IsoPrice.js.map +1 -0
  11. package/dist/domain.objects/IsoPriceExponent.d.ts +28 -0
  12. package/dist/domain.objects/IsoPriceExponent.js +33 -0
  13. package/dist/domain.objects/IsoPriceExponent.js.map +1 -0
  14. package/dist/domain.objects/IsoPriceHuman.d.ts +19 -0
  15. package/dist/domain.objects/IsoPriceHuman.js +3 -0
  16. package/dist/domain.objects/IsoPriceHuman.js.map +1 -0
  17. package/dist/domain.objects/IsoPriceRoundMode.d.ts +23 -0
  18. package/dist/domain.objects/IsoPriceRoundMode.js +28 -0
  19. package/dist/domain.objects/IsoPriceRoundMode.js.map +1 -0
  20. package/dist/domain.objects/IsoPriceShape.d.ts +30 -0
  21. package/dist/domain.objects/IsoPriceShape.js +3 -0
  22. package/dist/domain.objects/IsoPriceShape.js.map +1 -0
  23. package/dist/domain.objects/IsoPriceWords.d.ts +20 -0
  24. package/dist/domain.objects/IsoPriceWords.js +3 -0
  25. package/dist/domain.objects/IsoPriceWords.js.map +1 -0
  26. package/dist/domain.operations/arithmetic/allocatePrice.d.ts +48 -0
  27. package/dist/domain.operations/arithmetic/allocatePrice.js +167 -0
  28. package/dist/domain.operations/arithmetic/allocatePrice.js.map +1 -0
  29. package/dist/domain.operations/arithmetic/dividePrice.d.ts +40 -0
  30. package/dist/domain.operations/arithmetic/dividePrice.js +127 -0
  31. package/dist/domain.operations/arithmetic/dividePrice.js.map +1 -0
  32. package/dist/domain.operations/arithmetic/multiplyPrice.d.ts +38 -0
  33. package/dist/domain.operations/arithmetic/multiplyPrice.js +89 -0
  34. package/dist/domain.operations/arithmetic/multiplyPrice.js.map +1 -0
  35. package/dist/domain.operations/arithmetic/subPrices.d.ts +28 -0
  36. package/dist/domain.operations/arithmetic/subPrices.js +62 -0
  37. package/dist/domain.operations/arithmetic/subPrices.js.map +1 -0
  38. package/dist/domain.operations/arithmetic/sumPrices.d.ts +44 -0
  39. package/dist/domain.operations/arithmetic/sumPrices.js +88 -0
  40. package/dist/domain.operations/arithmetic/sumPrices.js.map +1 -0
  41. package/dist/domain.operations/cast/asIsoPrice.d.ts +35 -0
  42. package/dist/domain.operations/cast/asIsoPrice.js +117 -0
  43. package/dist/domain.operations/cast/asIsoPrice.js.map +1 -0
  44. package/dist/domain.operations/cast/asIsoPriceHuman.d.ts +25 -0
  45. package/dist/domain.operations/cast/asIsoPriceHuman.js +106 -0
  46. package/dist/domain.operations/cast/asIsoPriceHuman.js.map +1 -0
  47. package/dist/domain.operations/cast/asIsoPriceShape.d.ts +25 -0
  48. package/dist/domain.operations/cast/asIsoPriceShape.js +164 -0
  49. package/dist/domain.operations/cast/asIsoPriceShape.js.map +1 -0
  50. package/dist/domain.operations/cast/asIsoPriceWords.d.ts +25 -0
  51. package/dist/domain.operations/cast/asIsoPriceWords.js +103 -0
  52. package/dist/domain.operations/cast/asIsoPriceWords.js.map +1 -0
  53. package/dist/domain.operations/guard/isIsoPrice.d.ts +18 -0
  54. package/dist/domain.operations/guard/isIsoPrice.js +29 -0
  55. package/dist/domain.operations/guard/isIsoPrice.js.map +1 -0
  56. package/dist/domain.operations/guard/isIsoPriceHuman.d.ts +24 -0
  57. package/dist/domain.operations/guard/isIsoPriceHuman.js +76 -0
  58. package/dist/domain.operations/guard/isIsoPriceHuman.js.map +1 -0
  59. package/dist/domain.operations/guard/isIsoPriceShape.d.ts +29 -0
  60. package/dist/domain.operations/guard/isIsoPriceShape.js +50 -0
  61. package/dist/domain.operations/guard/isIsoPriceShape.js.map +1 -0
  62. package/dist/domain.operations/guard/isIsoPriceWords.d.ts +24 -0
  63. package/dist/domain.operations/guard/isIsoPriceWords.js +48 -0
  64. package/dist/domain.operations/guard/isIsoPriceWords.js.map +1 -0
  65. package/dist/domain.operations/precision/getIsoPriceExponentByCurrency.d.ts +15 -0
  66. package/dist/domain.operations/precision/getIsoPriceExponentByCurrency.js +49 -0
  67. package/dist/domain.operations/precision/getIsoPriceExponentByCurrency.js.map +1 -0
  68. package/dist/domain.operations/precision/roundPrice.d.ts +25 -0
  69. package/dist/domain.operations/precision/roundPrice.js +24 -0
  70. package/dist/domain.operations/precision/roundPrice.js.map +1 -0
  71. package/dist/domain.operations/precision/setPricePrecision.d.ts +29 -0
  72. package/dist/domain.operations/precision/setPricePrecision.js +119 -0
  73. package/dist/domain.operations/precision/setPricePrecision.js.map +1 -0
  74. package/dist/domain.operations/statistics/calcPriceAvg.d.ts +21 -0
  75. package/dist/domain.operations/statistics/calcPriceAvg.js +92 -0
  76. package/dist/domain.operations/statistics/calcPriceAvg.js.map +1 -0
  77. package/dist/domain.operations/statistics/calcPriceStdev.d.ts +23 -0
  78. package/dist/domain.operations/statistics/calcPriceStdev.js +137 -0
  79. package/dist/domain.operations/statistics/calcPriceStdev.js.map +1 -0
  80. package/dist/index.d.ts +1 -0
  81. package/dist/index.js +18 -0
  82. package/dist/index.js.map +1 -0
  83. package/license.md +21 -0
  84. package/package.json +102 -0
  85. package/readme.md +373 -0
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.priceAdd = exports.priceSum = exports.addPrices = exports.sumPrices = void 0;
4
+ const helpful_errors_1 = require("helpful-errors");
5
+ const IsoPriceExponent_1 = require("../../domain.objects/IsoPriceExponent");
6
+ const asIsoPriceShape_1 = require("../cast/asIsoPriceShape");
7
+ const asIsoPriceWords_1 = require("../cast/asIsoPriceWords");
8
+ /**
9
+ * .what = gets the numeric exponent value from exponent string
10
+ * .why = needed for precision comparison and normalization
11
+ */
12
+ const getExponentValue = (exponent) => {
13
+ const match = exponent.match(/\^(-?\d+)$/);
14
+ if (!match)
15
+ return -2; // default to centi
16
+ return parseInt(match[1], 10);
17
+ };
18
+ function sumPrices(...args) {
19
+ // parse args: array syntax vs spread syntax
20
+ let prices;
21
+ let options;
22
+ if (Array.isArray(args[0])) {
23
+ prices = args[0];
24
+ options = args[1];
25
+ }
26
+ else {
27
+ prices = args;
28
+ options = undefined;
29
+ }
30
+ // handle empty array
31
+ if (prices.length === 0) {
32
+ throw new helpful_errors_1.BadRequestError('cannot sum empty price array', { prices });
33
+ }
34
+ // convert all to shapes
35
+ const shapes = prices.map((p) => (0, asIsoPriceShape_1.asIsoPriceShape)(p));
36
+ // verify all currencies match
37
+ const currency = shapes[0].currency;
38
+ const mismatch = shapes.find((s) => s.currency !== currency);
39
+ if (mismatch) {
40
+ throw new helpful_errors_1.BadRequestError('currency mismatch in price sum', {
41
+ expected: currency,
42
+ found: mismatch.currency,
43
+ prices,
44
+ });
45
+ }
46
+ // find the highest precision (lowest exponent value)
47
+ const exponents = shapes.map((s) => s.exponent ?? IsoPriceExponent_1.IsoPriceExponent.CENTI);
48
+ const exponentValues = exponents.map(getExponentValue);
49
+ const targetExponentValue = Math.min(...exponentValues);
50
+ const targetExponent = exponents[exponentValues.indexOf(targetExponentValue)];
51
+ // normalize all amounts to target precision and sum
52
+ let total = 0n;
53
+ for (let i = 0; i < shapes.length; i++) {
54
+ const shape = shapes[i];
55
+ const currentExp = getExponentValue(shape.exponent ?? IsoPriceExponent_1.IsoPriceExponent.CENTI);
56
+ const shift = currentExp - targetExponentValue;
57
+ const normalizedAmount = shape.amount * 10n ** BigInt(shift);
58
+ total += normalizedAmount;
59
+ }
60
+ // build result shape
61
+ const resultShape = {
62
+ amount: total,
63
+ currency,
64
+ exponent: targetExponent,
65
+ };
66
+ // return in requested format
67
+ if (options?.format === 'shape') {
68
+ return resultShape;
69
+ }
70
+ return (0, asIsoPriceWords_1.asIsoPriceWords)(resultShape);
71
+ }
72
+ exports.sumPrices = sumPrices;
73
+ /**
74
+ * .what = alias for sumPrices
75
+ * .why = provides semantic name for binary addition
76
+ */
77
+ exports.addPrices = sumPrices;
78
+ /**
79
+ * .what = alias for sumPrices
80
+ * .why = provides price-prefixed variant
81
+ */
82
+ exports.priceSum = sumPrices;
83
+ /**
84
+ * .what = alias for sumPrices
85
+ * .why = provides price-prefixed variant
86
+ */
87
+ exports.priceAdd = sumPrices;
88
+ //# sourceMappingURL=sumPrices.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sumPrices.js","sourceRoot":"","sources":["../../../src/domain.operations/arithmetic/sumPrices.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import type { IsoPrice } from '../../domain.objects/IsoPrice';
2
+ import type { IsoPriceWords } from '../../domain.objects/IsoPriceWords';
3
+ /**
4
+ * .what = normalizes any price input to IsoPriceWords format
5
+ * .why = provides a single entry point for price conversion
6
+ *
7
+ * this is the recommended entry point for all price conversion:
8
+ * - accepts human format: '$50.37', '€100.00'
9
+ * - accepts words format: 'USD 50.37', 'EUR 100.00'
10
+ * - accepts shape format: { amount: 5037n, currency: 'USD' }
11
+ * - normalizes commas to underscores in output
12
+ *
13
+ * @example
14
+ * asIsoPrice('$50.37')
15
+ * // => 'USD 50.37'
16
+ *
17
+ * @example
18
+ * asIsoPrice('$50.37', { currency: 'CAD' })
19
+ * // => 'CAD 50.37'
20
+ *
21
+ * @example
22
+ * asIsoPrice('€50.37', { currency: 'USD' })
23
+ * // throws BadRequestError (symbol/currency mismatch)
24
+ *
25
+ * @example
26
+ * asIsoPrice('USD 1,000,000.00')
27
+ * // => 'USD 1_000_000.00'
28
+ */
29
+ export declare const asIsoPrice: <TCurrency extends string = string>(input: IsoPrice<TCurrency> | string | {
30
+ amount: number | bigint;
31
+ currency: TCurrency;
32
+ exponent?: string;
33
+ }, options?: {
34
+ currency?: TCurrency;
35
+ }) => IsoPriceWords<TCurrency>;
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.asIsoPrice = void 0;
4
+ const helpful_errors_1 = require("helpful-errors");
5
+ const isIsoPriceHuman_1 = require("../guard/isIsoPriceHuman");
6
+ const asIsoPriceWords_1 = require("./asIsoPriceWords");
7
+ /**
8
+ * .what = currency symbol to code mappings
9
+ * .why = validates symbol/currency consistency
10
+ */
11
+ const SYMBOL_TO_CODE = {
12
+ $: 'USD',
13
+ '€': 'EUR',
14
+ '£': 'GBP',
15
+ '¥': 'JPY',
16
+ '₹': 'INR',
17
+ '₽': 'RUB',
18
+ '₩': 'KRW',
19
+ '₪': 'ILS',
20
+ '฿': 'THB',
21
+ '₫': 'VND',
22
+ kr: 'SEK',
23
+ R: 'ZAR',
24
+ zł: 'PLN',
25
+ Kč: 'CZK',
26
+ CHF: 'CHF',
27
+ };
28
+ /**
29
+ * .what = currencies that have unique, unambiguous symbols
30
+ * .why = throw on currency override if the target has a different unique symbol
31
+ *
32
+ * when a currency has a unique symbol (like EUR → €), a different input
33
+ * symbol (like $) with that currency is a clear mismatch.
34
+ *
35
+ * see `define.currency-symbols-lossy.md` for why symbols are ambiguous
36
+ */
37
+ const UNIQUE_SYMBOL_CURRENCIES = {
38
+ EUR: '€',
39
+ // note: most other currencies share symbols ($ used by USD/CAD/AUD, etc.)
40
+ // so we only list currencies with truly unique symbols here
41
+ };
42
+ /**
43
+ * .what = detects the symbol used in a human format string
44
+ * .why = enables symbol/currency mismatch detection
45
+ */
46
+ const detectSymbol = (value) => {
47
+ for (const symbol of Object.keys(SYMBOL_TO_CODE)) {
48
+ if (value.startsWith(symbol) ||
49
+ value.endsWith(symbol) ||
50
+ value.endsWith(` ${symbol}`)) {
51
+ return symbol;
52
+ }
53
+ }
54
+ return null;
55
+ };
56
+ /**
57
+ * .what = normalizes any price input to IsoPriceWords format
58
+ * .why = provides a single entry point for price conversion
59
+ *
60
+ * this is the recommended entry point for all price conversion:
61
+ * - accepts human format: '$50.37', '€100.00'
62
+ * - accepts words format: 'USD 50.37', 'EUR 100.00'
63
+ * - accepts shape format: { amount: 5037n, currency: 'USD' }
64
+ * - normalizes commas to underscores in output
65
+ *
66
+ * @example
67
+ * asIsoPrice('$50.37')
68
+ * // => 'USD 50.37'
69
+ *
70
+ * @example
71
+ * asIsoPrice('$50.37', { currency: 'CAD' })
72
+ * // => 'CAD 50.37'
73
+ *
74
+ * @example
75
+ * asIsoPrice('€50.37', { currency: 'USD' })
76
+ * // throws BadRequestError (symbol/currency mismatch)
77
+ *
78
+ * @example
79
+ * asIsoPrice('USD 1,000,000.00')
80
+ * // => 'USD 1_000_000.00'
81
+ */
82
+ const asIsoPrice = (input, options) => {
83
+ // validate symbol/currency consistency for human format
84
+ if (typeof input === 'string' && (0, isIsoPriceHuman_1.isIsoPriceHuman)(input)) {
85
+ const symbol = detectSymbol(input);
86
+ if (symbol && options?.currency) {
87
+ const expectedCode = SYMBOL_TO_CODE[symbol];
88
+ // check if input symbol belongs to a unique-symbol currency
89
+ const expectedUniqueSymbol = expectedCode
90
+ ? UNIQUE_SYMBOL_CURRENCIES[expectedCode]
91
+ : undefined;
92
+ // check if override currency has a unique symbol
93
+ const targetUniqueSymbol = UNIQUE_SYMBOL_CURRENCIES[options.currency];
94
+ // if input symbol is unique to a currency, override must match that currency
95
+ // e.g., €50.37 + USD → throw (€ uniquely identifies EUR)
96
+ if (expectedUniqueSymbol && expectedCode !== options.currency) {
97
+ throw new helpful_errors_1.BadRequestError('symbol/currency mismatch', {
98
+ symbol,
99
+ expectedCode,
100
+ providedCurrency: options.currency,
101
+ });
102
+ }
103
+ // if target currency has a unique symbol that differs from input, throw
104
+ // e.g., $50.37 + EUR → throw (EUR requires €, not $)
105
+ if (targetUniqueSymbol && targetUniqueSymbol !== symbol) {
106
+ throw new helpful_errors_1.BadRequestError('symbol/currency mismatch', {
107
+ symbol,
108
+ expectedCode,
109
+ providedCurrency: options.currency,
110
+ });
111
+ }
112
+ }
113
+ }
114
+ return (0, asIsoPriceWords_1.asIsoPriceWords)(input, options);
115
+ };
116
+ exports.asIsoPrice = asIsoPrice;
117
+ //# sourceMappingURL=asIsoPrice.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asIsoPrice.js","sourceRoot":"","sources":["../../../src/domain.operations/cast/asIsoPrice.ts"],"names":[],"mappings":";;;AAAA,mDAAiD;AAIjD,8DAA2D;AAC3D,uDAAoD;AAEpD;;;GAGG;AACH,MAAM,cAAc,GAA2B;IAC7C,CAAC,EAAE,KAAK;IACR,GAAG,EAAE,KAAK;IACV,GAAG,EAAE,KAAK;IACV,GAAG,EAAE,KAAK;IACV,GAAG,EAAE,KAAK;IACV,GAAG,EAAE,KAAK;IACV,GAAG,EAAE,KAAK;IACV,GAAG,EAAE,KAAK;IACV,GAAG,EAAE,KAAK;IACV,GAAG,EAAE,KAAK;IACV,EAAE,EAAE,KAAK;IACT,CAAC,EAAE,KAAK;IACR,EAAE,EAAE,KAAK;IACT,EAAE,EAAE,KAAK;IACT,GAAG,EAAE,KAAK;CACX,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,wBAAwB,GAA2B;IACvD,GAAG,EAAE,GAAG;IACR,0EAA0E;IAC1E,4DAA4D;CAC7D,CAAC;AAEF;;;GAGG;AACH,MAAM,YAAY,GAAG,CAAC,KAAa,EAAiB,EAAE;IACpD,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;QACjD,IACE,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC;YACxB,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC;YACtB,KAAK,CAAC,QAAQ,CAAC,IAAI,MAAM,EAAE,CAAC,EAC5B,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACI,MAAM,UAAU,GAAG,CACxB,KAGuE,EACvE,OAAkC,EACR,EAAE;IAC5B,wDAAwD;IACxD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,IAAA,iCAAe,EAAC,KAAK,CAAC,EAAE,CAAC;QACxD,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,MAAM,IAAI,OAAO,EAAE,QAAQ,EAAE,CAAC;YAChC,MAAM,YAAY,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;YAC5C,4DAA4D;YAC5D,MAAM,oBAAoB,GAAG,YAAY;gBACvC,CAAC,CAAC,wBAAwB,CAAC,YAAY,CAAC;gBACxC,CAAC,CAAC,SAAS,CAAC;YACd,iDAAiD;YACjD,MAAM,kBAAkB,GAAG,wBAAwB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YAEtE,6EAA6E;YAC7E,yDAAyD;YACzD,IAAI,oBAAoB,IAAI,YAAY,KAAK,OAAO,CAAC,QAAQ,EAAE,CAAC;gBAC9D,MAAM,IAAI,gCAAe,CAAC,0BAA0B,EAAE;oBACpD,MAAM;oBACN,YAAY;oBACZ,gBAAgB,EAAE,OAAO,CAAC,QAAQ;iBACnC,CAAC,CAAC;YACL,CAAC;YAED,wEAAwE;YACxE,qDAAqD;YACrD,IAAI,kBAAkB,IAAI,kBAAkB,KAAK,MAAM,EAAE,CAAC;gBACxD,MAAM,IAAI,gCAAe,CAAC,0BAA0B,EAAE;oBACpD,MAAM;oBACN,YAAY;oBACZ,gBAAgB,EAAE,OAAO,CAAC,QAAQ;iBACnC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,IAAA,iCAAe,EAAC,KAA4B,EAAE,OAAO,CAAC,CAAC;AAChE,CAAC,CAAC;AA1CW,QAAA,UAAU,cA0CrB"}
@@ -0,0 +1,25 @@
1
+ import type { IsoPrice } from '../../domain.objects/IsoPrice';
2
+ import type { IsoPriceHuman } from '../../domain.objects/IsoPriceHuman';
3
+ /**
4
+ * .what = converts any IsoPrice format to IsoPriceHuman (symbol format)
5
+ * .why = enables human-readable display with currency symbols
6
+ *
7
+ * @example
8
+ * asIsoPriceHuman('USD 50.37')
9
+ * // => '$50.37'
10
+ *
11
+ * @example
12
+ * asIsoPriceHuman({ amount: 5037n, currency: 'USD' })
13
+ * // => '$50.37'
14
+ *
15
+ * @example
16
+ * asIsoPriceHuman('USD 1_000_000.00')
17
+ * // => '$1,000,000.00'
18
+ */
19
+ export declare const asIsoPriceHuman: <TCurrency extends string = string>(input: IsoPrice<TCurrency> | {
20
+ amount: number | bigint;
21
+ currency: TCurrency;
22
+ exponent?: string;
23
+ } | string, options?: {
24
+ currency?: TCurrency;
25
+ }) => IsoPriceHuman;
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.asIsoPriceHuman = void 0;
4
+ const IsoPriceExponent_1 = require("../../domain.objects/IsoPriceExponent");
5
+ const getIsoPriceExponentByCurrency_1 = require("../precision/getIsoPriceExponentByCurrency");
6
+ const asIsoPriceShape_1 = require("./asIsoPriceShape");
7
+ /**
8
+ * .what = currency code to symbol mappings
9
+ * .why = enables conversion from iso 4217 codes to display symbols
10
+ */
11
+ const CODE_TO_SYMBOL = {
12
+ USD: '$',
13
+ EUR: '€',
14
+ GBP: '£',
15
+ JPY: '¥',
16
+ CNY: '¥',
17
+ INR: '₹',
18
+ RUB: '₽',
19
+ KRW: '₩',
20
+ ILS: '₪',
21
+ THB: '฿',
22
+ VND: '₫',
23
+ SEK: 'kr',
24
+ NOK: 'kr',
25
+ DKK: 'kr',
26
+ ZAR: 'R',
27
+ BRL: 'R$',
28
+ PLN: 'zł',
29
+ CZK: 'Kč',
30
+ CHF: 'CHF',
31
+ };
32
+ /**
33
+ * .what = gets the decimal places for an exponent
34
+ * .why = determines how to format the amount string
35
+ */
36
+ const getDecimalPlaces = (exponent) => {
37
+ const match = exponent.match(/\^(-?\d+)$/);
38
+ if (!match)
39
+ return 2;
40
+ return Math.abs(parseInt(match[1], 10));
41
+ };
42
+ /**
43
+ * .what = formats a bigint amount to human-readable string with commas
44
+ * .why = converts 5037n with exponent 2 to '50.37'
45
+ */
46
+ const formatAmountHuman = (amount, exponent = IsoPriceExponent_1.IsoPriceExponent.CENTI) => {
47
+ const decimalPlaces = getDecimalPlaces(exponent);
48
+ const isNegative = amount < 0n;
49
+ const absAmount = isNegative ? -amount : amount;
50
+ // handle zero decimal places (whole units like JPY)
51
+ if (decimalPlaces === 0) {
52
+ const formattedInt = absAmount
53
+ .toString()
54
+ .replace(/\B(?=(\d{3})+(?!\d))/g, ',');
55
+ return isNegative ? `-${formattedInt}` : formattedInt;
56
+ }
57
+ // convert to string and pad with zeros at start if needed
58
+ const amountStr = absAmount.toString().padStart(decimalPlaces + 1, '0');
59
+ // split into integer and decimal parts
60
+ const intPart = amountStr.slice(0, -decimalPlaces) || '0';
61
+ const decPart = amountStr.slice(-decimalPlaces);
62
+ // format integer part with comma thousands separators (human format)
63
+ const formattedInt = intPart.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
64
+ // build the result
65
+ const sign = isNegative ? '-' : '';
66
+ // for whole numbers at centi precision, show .00
67
+ if (decPart === '00' && decimalPlaces === 2) {
68
+ return `${sign}${formattedInt}.00`;
69
+ }
70
+ // omit zeros at end of decimal part for higher precision
71
+ const trimmedDec = decPart.replace(/0+$/, '');
72
+ if (trimmedDec.length === 0 && decimalPlaces > 2) {
73
+ return `${sign}${formattedInt}`;
74
+ }
75
+ return `${sign}${formattedInt}.${decPart}`;
76
+ };
77
+ /**
78
+ * .what = converts any IsoPrice format to IsoPriceHuman (symbol format)
79
+ * .why = enables human-readable display with currency symbols
80
+ *
81
+ * @example
82
+ * asIsoPriceHuman('USD 50.37')
83
+ * // => '$50.37'
84
+ *
85
+ * @example
86
+ * asIsoPriceHuman({ amount: 5037n, currency: 'USD' })
87
+ * // => '$50.37'
88
+ *
89
+ * @example
90
+ * asIsoPriceHuman('USD 1_000_000.00')
91
+ * // => '$1,000,000.00'
92
+ */
93
+ const asIsoPriceHuman = (input, options) => {
94
+ // convert to shape first
95
+ const shape = (0, asIsoPriceShape_1.asIsoPriceShape)(input, options);
96
+ // get the symbol for this currency
97
+ const symbol = CODE_TO_SYMBOL[shape.currency] ?? shape.currency;
98
+ // use currency's standard exponent when shape.exponent is not set
99
+ const exponent = shape.exponent ?? (0, getIsoPriceExponentByCurrency_1.getIsoPriceExponentByCurrency)(shape.currency);
100
+ // format the amount with commas
101
+ const formatted = formatAmountHuman(shape.amount, exponent);
102
+ // build the human-readable string (symbol prefix)
103
+ return `${symbol}${formatted}`;
104
+ };
105
+ exports.asIsoPriceHuman = asIsoPriceHuman;
106
+ //# sourceMappingURL=asIsoPriceHuman.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asIsoPriceHuman.js","sourceRoot":"","sources":["../../../src/domain.operations/cast/asIsoPriceHuman.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { IsoPrice } from '../../domain.objects/IsoPrice';
2
+ import type { IsoPriceShape } from '../../domain.objects/IsoPriceShape';
3
+ /**
4
+ * .what = converts any IsoPrice format to IsoPriceShape
5
+ * .why = enables uniform representation as shape for arithmetic operations
6
+ *
7
+ * @example
8
+ * asIsoPriceShape('USD 50.37')
9
+ * // => { amount: 5037n, currency: 'USD' }
10
+ *
11
+ * @example
12
+ * asIsoPriceShape({ amount: 5037, currency: 'USD' })
13
+ * // => { amount: 5037n, currency: 'USD' } // number → bigint
14
+ *
15
+ * @example
16
+ * asIsoPriceShape('$50.37')
17
+ * // => { amount: 5037n, currency: 'USD' }
18
+ */
19
+ export declare const asIsoPriceShape: <TCurrency extends string = string>(input: IsoPrice<TCurrency> | {
20
+ amount: number | bigint;
21
+ currency: TCurrency;
22
+ exponent?: string;
23
+ } | string, options?: {
24
+ currency?: TCurrency;
25
+ }) => IsoPriceShape<TCurrency>;
@@ -0,0 +1,164 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.asIsoPriceShape = void 0;
4
+ const helpful_errors_1 = require("helpful-errors");
5
+ const IsoPriceExponent_1 = require("../../domain.objects/IsoPriceExponent");
6
+ const isIsoPriceHuman_1 = require("../guard/isIsoPriceHuman");
7
+ const isIsoPriceWords_1 = require("../guard/isIsoPriceWords");
8
+ const getIsoPriceExponentByCurrency_1 = require("../precision/getIsoPriceExponentByCurrency");
9
+ /**
10
+ * .what = currency symbol to code mappings
11
+ * .why = enables conversion from human format symbols to iso 4217 codes
12
+ */
13
+ const SYMBOL_TO_CODE = {
14
+ $: 'USD',
15
+ '€': 'EUR',
16
+ '£': 'GBP',
17
+ '¥': 'JPY',
18
+ '₹': 'INR',
19
+ '₽': 'RUB',
20
+ '₩': 'KRW',
21
+ '₪': 'ILS',
22
+ '฿': 'THB',
23
+ '₫': 'VND',
24
+ kr: 'SEK',
25
+ R: 'ZAR',
26
+ zł: 'PLN',
27
+ Kč: 'CZK',
28
+ CHF: 'CHF',
29
+ };
30
+ /**
31
+ * .what = parses amount string to bigint in minor units
32
+ * .why = converts decimal string like '50.37' to bigint 5037n
33
+ */
34
+ const parseAmountToMinorUnits = (amountStr, exponent = IsoPriceExponent_1.IsoPriceExponent.CENTI) => {
35
+ // get the decimal places for this exponent
36
+ const decimalPlaces = Math.abs(parseInt(exponent.split('^')[1] ?? '-2', 10));
37
+ // clean the string: remove underscores and commas
38
+ const cleaned = amountStr.replace(/[_,]/g, '');
39
+ // split into integer and decimal parts
40
+ const [intPart, decPart = ''] = cleaned.split('.');
41
+ // pad or truncate decimal part to match exponent
42
+ const paddedDecimal = decPart.padEnd(decimalPlaces, '0');
43
+ const truncatedDecimal = paddedDecimal.slice(0, decimalPlaces);
44
+ // detect if we need higher precision
45
+ if (decPart.length > decimalPlaces) {
46
+ // use the actual decimal length to determine exponent
47
+ const actualDecPlaces = decPart.length;
48
+ const exponentMap = {
49
+ 0: IsoPriceExponent_1.IsoPriceExponent.WHOLE,
50
+ 2: IsoPriceExponent_1.IsoPriceExponent.CENTI,
51
+ 3: IsoPriceExponent_1.IsoPriceExponent.MILLI,
52
+ 6: IsoPriceExponent_1.IsoPriceExponent.MICRO,
53
+ 9: IsoPriceExponent_1.IsoPriceExponent.NANO,
54
+ 12: IsoPriceExponent_1.IsoPriceExponent.PICO,
55
+ };
56
+ // find the smallest exponent that fits
57
+ const newExponent = Object.entries(exponentMap)
58
+ .filter(([places]) => parseInt(places) >= actualDecPlaces)
59
+ .sort((a, b) => parseInt(a[0]) - parseInt(b[0]))[0]?.[1] ??
60
+ IsoPriceExponent_1.IsoPriceExponent.PICO;
61
+ const newDecPlaces = Math.abs(parseInt(newExponent.split('^')[1] ?? '-2', 10));
62
+ const fullDecimal = decPart.padEnd(newDecPlaces, '0');
63
+ return {
64
+ amount: BigInt(`${intPart ?? '0'}${fullDecimal}`),
65
+ exponent: newExponent,
66
+ };
67
+ }
68
+ // combine integer and decimal parts
69
+ const combined = `${intPart ?? '0'}${truncatedDecimal}`;
70
+ return {
71
+ amount: BigInt(combined),
72
+ exponent,
73
+ };
74
+ };
75
+ /**
76
+ * .what = extracts currency code and amount from words format
77
+ * .why = parses 'USD 50.37' into { currency: 'USD', amount: '50.37' }
78
+ */
79
+ const parseWordsFormat = (value) => {
80
+ const match = value.match(/^([A-Z]{3}) (.+)$/);
81
+ if (!match)
82
+ throw new helpful_errors_1.BadRequestError('invalid words format', { value });
83
+ return { currency: match[1], amountStr: match[2] };
84
+ };
85
+ /**
86
+ * .what = extracts currency code and amount from human format
87
+ * .why = parses '$50.37' or '50.37 €' into { currency: 'USD', amount: '50.37' }
88
+ */
89
+ const parseHumanFormat = (value, options) => {
90
+ // try prefix symbols
91
+ for (const [symbol, code] of Object.entries(SYMBOL_TO_CODE)) {
92
+ if (value.startsWith(symbol)) {
93
+ const amountStr = value.slice(symbol.length);
94
+ const currency = options?.currency ?? code;
95
+ return { currency, amountStr };
96
+ }
97
+ }
98
+ // try suffix symbols
99
+ for (const [symbol, code] of Object.entries(SYMBOL_TO_CODE)) {
100
+ if (value.endsWith(symbol) || value.endsWith(` ${symbol}`)) {
101
+ const amountStr = value.replace(new RegExp(`\\s*${symbol.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}$`), '');
102
+ const currency = options?.currency ?? code;
103
+ return { currency, amountStr };
104
+ }
105
+ }
106
+ throw new helpful_errors_1.BadRequestError('unable to parse human format', { value });
107
+ };
108
+ /**
109
+ * .what = converts any IsoPrice format to IsoPriceShape
110
+ * .why = enables uniform representation as shape for arithmetic operations
111
+ *
112
+ * @example
113
+ * asIsoPriceShape('USD 50.37')
114
+ * // => { amount: 5037n, currency: 'USD' }
115
+ *
116
+ * @example
117
+ * asIsoPriceShape({ amount: 5037, currency: 'USD' })
118
+ * // => { amount: 5037n, currency: 'USD' } // number → bigint
119
+ *
120
+ * @example
121
+ * asIsoPriceShape('$50.37')
122
+ * // => { amount: 5037n, currency: 'USD' }
123
+ */
124
+ const asIsoPriceShape = (input, options) => {
125
+ // handle shape format (may need number → bigint conversion)
126
+ if (typeof input === 'object' &&
127
+ input !== null &&
128
+ 'amount' in input &&
129
+ 'currency' in input) {
130
+ const amount = typeof input.amount === 'bigint' ? input.amount : BigInt(input.amount);
131
+ return {
132
+ amount,
133
+ currency: input.currency,
134
+ exponent: input.exponent,
135
+ };
136
+ }
137
+ // handle words format
138
+ if ((0, isIsoPriceWords_1.isIsoPriceWords)(input)) {
139
+ const { currency, amountStr } = parseWordsFormat(input);
140
+ const currencyExponent = (0, getIsoPriceExponentByCurrency_1.getIsoPriceExponentByCurrency)(currency);
141
+ const { amount, exponent } = parseAmountToMinorUnits(amountStr, currencyExponent);
142
+ // only include exponent if it differs from currency's standard exponent
143
+ return {
144
+ amount,
145
+ currency: currency,
146
+ ...(exponent !== currencyExponent ? { exponent } : {}),
147
+ };
148
+ }
149
+ // handle human format
150
+ if ((0, isIsoPriceHuman_1.isIsoPriceHuman)(input)) {
151
+ const { currency, amountStr } = parseHumanFormat(input, options);
152
+ const currencyExponent = (0, getIsoPriceExponentByCurrency_1.getIsoPriceExponentByCurrency)(currency);
153
+ const { amount, exponent } = parseAmountToMinorUnits(amountStr, currencyExponent);
154
+ // only include exponent if it differs from currency's standard exponent
155
+ return {
156
+ amount,
157
+ currency: currency,
158
+ ...(exponent !== currencyExponent ? { exponent } : {}),
159
+ };
160
+ }
161
+ throw new helpful_errors_1.BadRequestError('unable to convert to IsoPriceShape', { input });
162
+ };
163
+ exports.asIsoPriceShape = asIsoPriceShape;
164
+ //# sourceMappingURL=asIsoPriceShape.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asIsoPriceShape.js","sourceRoot":"","sources":["../../../src/domain.operations/cast/asIsoPriceShape.ts"],"names":[],"mappings":";;;AAAA,mDAAiD;AAGjD,4EAAyE;AAEzE,8DAA2D;AAC3D,8DAA2D;AAC3D,8FAA2F;AAE3F;;;GAGG;AACH,MAAM,cAAc,GAA2B;IAC7C,CAAC,EAAE,KAAK;IACR,GAAG,EAAE,KAAK;IACV,GAAG,EAAE,KAAK;IACV,GAAG,EAAE,KAAK;IACV,GAAG,EAAE,KAAK;IACV,GAAG,EAAE,KAAK;IACV,GAAG,EAAE,KAAK;IACV,GAAG,EAAE,KAAK;IACV,GAAG,EAAE,KAAK;IACV,GAAG,EAAE,KAAK;IACV,EAAE,EAAE,KAAK;IACT,CAAC,EAAE,KAAK;IACR,EAAE,EAAE,KAAK;IACT,EAAE,EAAE,KAAK;IACT,GAAG,EAAE,KAAK;CACX,CAAC;AAEF;;;GAGG;AACH,MAAM,uBAAuB,GAAG,CAC9B,SAAiB,EACjB,WAA6B,mCAAgB,CAAC,KAAK,EACH,EAAE;IAClD,2CAA2C;IAC3C,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;IAE7E,kDAAkD;IAClD,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAE/C,uCAAuC;IACvC,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAEnD,iDAAiD;IACjD,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC;IACzD,MAAM,gBAAgB,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC;IAE/D,qCAAqC;IACrC,IAAI,OAAO,CAAC,MAAM,GAAG,aAAa,EAAE,CAAC;QACnC,sDAAsD;QACtD,MAAM,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC;QACvC,MAAM,WAAW,GAAqC;YACpD,CAAC,EAAE,mCAAgB,CAAC,KAAK;YACzB,CAAC,EAAE,mCAAgB,CAAC,KAAK;YACzB,CAAC,EAAE,mCAAgB,CAAC,KAAK;YACzB,CAAC,EAAE,mCAAgB,CAAC,KAAK;YACzB,CAAC,EAAE,mCAAgB,CAAC,IAAI;YACxB,EAAE,EAAE,mCAAgB,CAAC,IAAI;SAC1B,CAAC;QACF,uCAAuC;QACvC,MAAM,WAAW,GACf,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC;aACxB,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,eAAe,CAAC;aACzD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC1D,mCAAgB,CAAC,IAAI,CAAC;QAExB,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAC3B,QAAQ,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC,CAChD,CAAC;QACF,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;QAEtD,OAAO;YACL,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,IAAI,GAAG,GAAG,WAAW,EAAE,CAAC;YACjD,QAAQ,EAAE,WAAW;SACtB,CAAC;IACJ,CAAC;IAED,oCAAoC;IACpC,MAAM,QAAQ,GAAG,GAAG,OAAO,IAAI,GAAG,GAAG,gBAAgB,EAAE,CAAC;IACxD,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC;QACxB,QAAQ;KACT,CAAC;AACJ,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,gBAAgB,GAAG,CACvB,KAAa,EAC4B,EAAE;IAC3C,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;IAC/C,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,gCAAe,CAAC,sBAAsB,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IACzE,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAE,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC,CAAE,EAAE,CAAC;AACvD,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,gBAAgB,GAAG,CACvB,KAAa,EACb,OAA+B,EACU,EAAE;IAC3C,qBAAqB;IACrB,KAAK,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;QAC5D,IAAI,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAC7B,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAC7C,MAAM,QAAQ,GAAG,OAAO,EAAE,QAAQ,IAAI,IAAI,CAAC;YAC3C,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;QACjC,CAAC;IACH,CAAC;IAED,qBAAqB;IACrB,KAAK,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;QAC5D,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,MAAM,EAAE,CAAC,EAAE,CAAC;YAC3D,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAC7B,IAAI,MAAM,CAAC,OAAO,MAAM,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,GAAG,CAAC,EACnE,EAAE,CACH,CAAC;YACF,MAAM,QAAQ,GAAG,OAAO,EAAE,QAAQ,IAAI,IAAI,CAAC;YAC3C,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;QACjC,CAAC;IACH,CAAC;IAED,MAAM,IAAI,gCAAe,CAAC,8BAA8B,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;AACvE,CAAC,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACI,MAAM,eAAe,GAAG,CAC7B,KAGU,EACV,OAAkC,EACR,EAAE;IAC5B,4DAA4D;IAC5D,IACE,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,QAAQ,IAAI,KAAK;QACjB,UAAU,IAAI,KAAK,EACnB,CAAC;QACD,MAAM,MAAM,GACV,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACzE,OAAO;YACL,MAAM;YACN,QAAQ,EAAE,KAAK,CAAC,QAAqB;YACrC,QAAQ,EAAE,KAAK,CAAC,QAAwC;SACzD,CAAC;IACJ,CAAC;IAED,sBAAsB;IACtB,IAAI,IAAA,iCAAe,EAAC,KAAK,CAAC,EAAE,CAAC;QAC3B,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;QACxD,MAAM,gBAAgB,GAAG,IAAA,6DAA6B,EAAC,QAAQ,CAAC,CAAC;QACjE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,uBAAuB,CAClD,SAAS,EACT,gBAAgB,CACjB,CAAC;QACF,wEAAwE;QACxE,OAAO;YACL,MAAM;YACN,QAAQ,EAAE,QAAqB;YAC/B,GAAG,CAAC,QAAQ,KAAK,gBAAgB,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACvD,CAAC;IACJ,CAAC;IAED,sBAAsB;IACtB,IAAI,IAAA,iCAAe,EAAC,KAAK,CAAC,EAAE,CAAC;QAC3B,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,gBAAgB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACjE,MAAM,gBAAgB,GAAG,IAAA,6DAA6B,EAAC,QAAQ,CAAC,CAAC;QACjE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,uBAAuB,CAClD,SAAS,EACT,gBAAgB,CACjB,CAAC;QACF,wEAAwE;QACxE,OAAO;YACL,MAAM;YACN,QAAQ,EAAE,QAAqB;YAC/B,GAAG,CAAC,QAAQ,KAAK,gBAAgB,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACvD,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,gCAAe,CAAC,oCAAoC,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;AAC7E,CAAC,CAAC;AAxDW,QAAA,eAAe,mBAwD1B"}
@@ -0,0 +1,25 @@
1
+ import type { IsoPrice } from '../../domain.objects/IsoPrice';
2
+ import type { IsoPriceWords } from '../../domain.objects/IsoPriceWords';
3
+ /**
4
+ * .what = converts any IsoPrice format to IsoPriceWords
5
+ * .why = enables uniform representation as words for serialization
6
+ *
7
+ * @example
8
+ * asIsoPriceWords({ amount: 5037n, currency: 'USD' })
9
+ * // => 'USD 50.37'
10
+ *
11
+ * @example
12
+ * asIsoPriceWords('$50.37')
13
+ * // => 'USD 50.37'
14
+ *
15
+ * @example
16
+ * asIsoPriceWords({ amount: 1000000n, currency: 'USD' })
17
+ * // => 'USD 10_000.00'
18
+ */
19
+ export declare const asIsoPriceWords: <TCurrency extends string = string>(input: IsoPrice<TCurrency> | {
20
+ amount: number | bigint;
21
+ currency: TCurrency;
22
+ exponent?: string;
23
+ } | string, options?: {
24
+ currency?: TCurrency;
25
+ }) => IsoPriceWords<TCurrency>;