@amboras-dev/money 0.2.0 → 0.4.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.
Files changed (78) hide show
  1. package/README.md +22 -11
  2. package/dist/ai.cjs +12 -13
  3. package/dist/ai.d.cts +5 -9
  4. package/dist/ai.d.ts +5 -9
  5. package/dist/ai.js +12 -13
  6. package/dist/{allocate-CZRg4TOP.cjs → allocate-AusholrC.cjs} +3 -4
  7. package/dist/{allocate-X7_jAtOj.js → allocate-BBRfdaSC.js} +3 -4
  8. package/dist/{amount-BV0O-aN8.cjs → amount-Bzxw9aD4.cjs} +32 -14
  9. package/dist/{amount-BoYBMgK9.js → amount-off8IMBJ.js} +32 -14
  10. package/dist/{arithmetic-BhNwisjb.js → arithmetic-C97-YafD.js} +4 -5
  11. package/dist/{arithmetic-DjT4Kzgt.cjs → arithmetic-D8A6IeZ0.cjs} +4 -5
  12. package/dist/billing.cjs +5 -8
  13. package/dist/billing.d.cts +1 -9
  14. package/dist/billing.d.ts +1 -9
  15. package/dist/billing.js +5 -8
  16. package/dist/commerce.cjs +15 -23
  17. package/dist/commerce.d.cts +2 -16
  18. package/dist/commerce.d.ts +2 -16
  19. package/dist/commerce.js +15 -23
  20. package/dist/{format-DLhno7eX.cjs → format-92fzvTXY.cjs} +9 -9
  21. package/dist/{format-BdPnijvn.js → format-BJC513u4.js} +9 -9
  22. package/dist/fx.cjs +12 -18
  23. package/dist/fx.d.cts +5 -15
  24. package/dist/fx.d.ts +5 -15
  25. package/dist/fx.js +12 -18
  26. package/dist/index.cjs +10 -12
  27. package/dist/index.d.cts +17 -23
  28. package/dist/index.d.ts +17 -23
  29. package/dist/index.js +10 -12
  30. package/dist/input.cjs +7 -10
  31. package/dist/input.d.cts +16 -22
  32. package/dist/input.d.ts +16 -22
  33. package/dist/input.js +7 -10
  34. package/dist/{iso-minor-wSwJN57T.cjs → iso-minor-DyNjT9A1.cjs} +2 -3
  35. package/dist/{iso-minor-CqkWDxHS.js → iso-minor-odkY-e6I.js} +2 -3
  36. package/dist/{medusa-lRY9xlsf.cjs → medusa-CzVK0bth.cjs} +3 -4
  37. package/dist/{medusa-DBXJXXvF.d.ts → medusa-DofdvIgQ.d.cts} +1 -3
  38. package/dist/{medusa-4K8N1pUc.d.cts → medusa-DrbYmD2Y.d.ts} +1 -3
  39. package/dist/{medusa-DqJY1qpj.js → medusa-pKGlImn9.js} +3 -4
  40. package/dist/{money-B-3aFjNJ.d.cts → money-BkMeYDEW.d.cts} +0 -6
  41. package/dist/{money-B-3aFjNJ.d.ts → money-BkMeYDEW.d.ts} +0 -6
  42. package/dist/{money-WhnGiI00.js → money-BxbAw7BP.js} +7 -15
  43. package/dist/{money-B3wH_Z4S.cjs → money-DWBjuuEK.cjs} +7 -15
  44. package/dist/{number-text-DE-q4jO5.js → number-text-Bj-gZXiF.js} +3 -4
  45. package/dist/{number-text-BWu67jUq.cjs → number-text-CWuVwrlg.cjs} +3 -4
  46. package/dist/{own-oP9DXFWv.cjs → own-C5imDkyB.cjs} +1 -2
  47. package/dist/{own-D7544D3k.js → own-DHxqIYqL.js} +1 -2
  48. package/dist/{percent-D1VB9xXG.js → percent-CB3Ixjc_.js} +2 -3
  49. package/dist/{percent-C0InC2t2.cjs → percent-DABHiSBs.cjs} +2 -3
  50. package/dist/{rate-DBPiYgT1.d.ts → rate-BvvZUdSu.d.ts} +1 -3
  51. package/dist/{rate-tqK8ijG0.d.cts → rate-CEakW3ia.d.cts} +1 -3
  52. package/dist/{rate-CVeMii4a.cjs → rate-CEjWTATc.cjs} +3 -4
  53. package/dist/{rate-DicStBue.js → rate-D6S2_wgZ.js} +3 -4
  54. package/dist/{reporting-tpGJbqYp.d.ts → reporting-DFNyDBdi.d.cts} +2 -4
  55. package/dist/{reporting-CG-ai2sM.d.cts → reporting-jIBILvnr.d.ts} +2 -4
  56. package/dist/{retail-DRUTTQoJ.d.ts → retail-B04CjW3b.d.ts} +1 -3
  57. package/dist/{retail-Cml8YSKg.cjs → retail-CYGPU4ea.cjs} +4 -5
  58. package/dist/{retail-C_BPLvMj.d.cts → retail-CmEyJQOH.d.cts} +1 -3
  59. package/dist/{retail-1mu888J1.js → retail-DXgs11ov.js} +4 -5
  60. package/dist/{rounding-DHBtNCHG.cjs → rounding-4QKTRbMQ.cjs} +2 -3
  61. package/dist/{rounding-g9rvye0k.js → rounding-CA1PVP3b.js} +2 -3
  62. package/dist/sql.cjs +9 -15
  63. package/dist/sql.d.cts +2 -12
  64. package/dist/sql.d.ts +2 -12
  65. package/dist/sql.js +9 -15
  66. package/dist/testing.cjs +39198 -12
  67. package/dist/testing.d.cts +20 -13
  68. package/dist/testing.d.ts +20 -13
  69. package/dist/testing.js +39198 -13
  70. package/dist/{wire-sW0yzqth.js → wire-B4QU8O3W.js} +350 -93
  71. package/dist/{wire-CaUN9Vf_.d.ts → wire-CVNicirK.d.ts} +165 -46
  72. package/dist/{wire-xjYXv4go.d.cts → wire-CtNJmWVP.d.cts} +165 -46
  73. package/dist/{wire-Bhuut8cW.cjs → wire-u2tmHY0Y.cjs} +403 -92
  74. package/dist/wire.cjs +10 -1
  75. package/dist/wire.d.cts +2 -2
  76. package/dist/wire.d.ts +2 -2
  77. package/dist/wire.js +1 -2
  78. package/package.json +4 -3
@@ -1,5 +1,4 @@
1
- import { R as DecimalText, i as Money } from "./money-B-3aFjNJ.cjs";
2
- //#region src/billing/usage.d.ts
1
+ import { R as DecimalText, i as Money } from "./money-BkMeYDEW.cjs";
3
2
  /** USD with sub-cent precision, as canonical decimal text (`'0.001234'`). Never merchant money. */
4
3
  type UsdAmount = DecimalText;
5
4
  interface UsdCostLine {
@@ -18,8 +17,6 @@ interface UsdCostLine {
18
17
  * the cloner's `estimateCost`). Each line needs exactly one of `usdPerMillion` / `usdPerUnit`.
19
18
  */
20
19
  export declare function usdCost(lines: readonly UsdCostLine[]): UsdAmount;
21
- //#endregion
22
- //#region src/billing/credits.d.ts
23
20
  /**
24
21
  * Credits for a USD cost: `ceil(usd x 100)` (0.07 gives 7, 1.1 gives 110, 0.0049 and 1e-7
25
22
  * give 1). Text and Money are exact. A number is first rounded half-even to 8 decimals, so
@@ -37,8 +34,6 @@ export declare function creditsToUsd(credits: number): UsdAmount;
37
34
  export declare function prorateCredits(quoted: number, share: number | DecimalText): number;
38
35
  /** Credits rounded up to a whole `step` (default 50) for a quote: `ceil(credits / step) x step`. */
39
36
  export declare function bucketCredits(credits: number, step?: number): number;
40
- //#endregion
41
- //#region src/billing/plans.d.ts
42
37
  /** The yearly price: `yearly` when set, else `monthly x 12`. */
43
38
  export declare function annualPrice(input: {
44
39
  monthly: Money;
@@ -73,9 +68,6 @@ export declare function applyCoupons(m: Money, coupons: readonly Coupon[], optio
73
68
  * the coupons take to 10).
74
69
  */
75
70
  export declare function grossUpForPercentOffs(m: Money, percents: readonly (number | DecimalText)[]): Money;
76
- //#endregion
77
- //#region src/billing.d.ts
78
71
  /** USD cents: Money in USD (USD stored amounts are cents). */
79
72
  export type UsdCents = Money;
80
- //#endregion
81
73
  export type { Coupon, UsdAmount, UsdCostLine };
package/dist/billing.d.ts CHANGED
@@ -1,5 +1,4 @@
1
- import { R as DecimalText, i as Money } from "./money-B-3aFjNJ.js";
2
- //#region src/billing/usage.d.ts
1
+ import { R as DecimalText, i as Money } from "./money-BkMeYDEW.js";
3
2
  /** USD with sub-cent precision, as canonical decimal text (`'0.001234'`). Never merchant money. */
4
3
  type UsdAmount = DecimalText;
5
4
  interface UsdCostLine {
@@ -18,8 +17,6 @@ interface UsdCostLine {
18
17
  * the cloner's `estimateCost`). Each line needs exactly one of `usdPerMillion` / `usdPerUnit`.
19
18
  */
20
19
  export declare function usdCost(lines: readonly UsdCostLine[]): UsdAmount;
21
- //#endregion
22
- //#region src/billing/credits.d.ts
23
20
  /**
24
21
  * Credits for a USD cost: `ceil(usd x 100)` (0.07 gives 7, 1.1 gives 110, 0.0049 and 1e-7
25
22
  * give 1). Text and Money are exact. A number is first rounded half-even to 8 decimals, so
@@ -37,8 +34,6 @@ export declare function creditsToUsd(credits: number): UsdAmount;
37
34
  export declare function prorateCredits(quoted: number, share: number | DecimalText): number;
38
35
  /** Credits rounded up to a whole `step` (default 50) for a quote: `ceil(credits / step) x step`. */
39
36
  export declare function bucketCredits(credits: number, step?: number): number;
40
- //#endregion
41
- //#region src/billing/plans.d.ts
42
37
  /** The yearly price: `yearly` when set, else `monthly x 12`. */
43
38
  export declare function annualPrice(input: {
44
39
  monthly: Money;
@@ -73,9 +68,6 @@ export declare function applyCoupons(m: Money, coupons: readonly Coupon[], optio
73
68
  * the coupons take to 10).
74
69
  */
75
70
  export declare function grossUpForPercentOffs(m: Money, percents: readonly (number | DecimalText)[]): Money;
76
- //#endregion
77
- //#region src/billing.d.ts
78
71
  /** USD cents: Money in USD (USD stored amounts are cents). */
79
72
  export type UsdCents = Money;
80
- //#endregion
81
73
  export type { Coupon, UsdAmount, UsdCostLine };
package/dist/billing.js CHANGED
@@ -1,6 +1,6 @@
1
- import { $ as describeValue, B as decimalOf, Q as MoneyError, dt as roundToScale, et as addDecimal, it as formatDecimal, n as fromMajor, pt as toDecimalText, rt as divRound, s as storedDecimal, st as multiplyDecimal, t as boundedMoney } from "./money-WhnGiI00.js";
2
- import { n as hundredPercent, r as percentOfUnits } from "./percent-D1VB9xXG.js";
3
- //#region src/billing/credits.ts
1
+ import { $ as describeValue, B as decimalOf, Q as MoneyError, dt as roundToScale, et as addDecimal, it as formatDecimal, n as fromMajor, pt as toDecimalText, rt as divRound, s as storedDecimal, st as multiplyDecimal, t as boundedMoney } from "./money-BxbAw7BP.js";
2
+ import { n as hundredPercent, r as percentOfUnits } from "./percent-CB3Ixjc_.js";
3
+ // src/billing/credits.ts
4
4
  function wholeNumber(value, name, min) {
5
5
  if (typeof value !== "number" || !Number.isSafeInteger(value) || value < min) throw new MoneyError("amount_invalid", `${name} must be an integer >= ${min}, got ${describeValue(value)}`);
6
6
  return BigInt(value);
@@ -63,8 +63,7 @@ function bucketCredits(credits, step = 50) {
63
63
  const s = wholeNumber(step, "step", 1);
64
64
  return Number(divRound(c, s, "ceil") * s);
65
65
  }
66
- //#endregion
67
- //#region src/billing/plans.ts
66
+ // src/billing/plans.ts
68
67
  function checkSame(m, other, verb) {
69
68
  const info = storedDecimal(m).info;
70
69
  const own = storedDecimal(other).info;
@@ -143,8 +142,7 @@ function grossUpForPercentOffs(m, percents) {
143
142
  if (!(kept > 0)) return m;
144
143
  return boundedMoney(BigInt(Math.round(m.amount / kept)), info);
145
144
  }
146
- //#endregion
147
- //#region src/billing/usage.ts
145
+ // src/billing/usage.ts
148
146
  const USD_DIGITS = 6;
149
147
  /**
150
148
  * The exact sum of `quantity x rate x multiplier` over `lines`, rounded half-up once to 6
@@ -171,5 +169,4 @@ function usdCost(lines) {
171
169
  }
172
170
  return toDecimalText(roundToScale(total, USD_DIGITS, "half-up"));
173
171
  }
174
- //#endregion
175
172
  export { annualPrice, applyCoupons, bucketCredits, creditsToUsd, grossUpForPercentOffs, monthlyEquivalent, prorateCredits, usdCost, usdToCredits };
package/dist/commerce.cjs CHANGED
@@ -1,12 +1,12 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_money = require("./money-B3wH_Z4S.cjs");
3
- const require_rounding = require("./rounding-DHBtNCHG.cjs");
4
- const require_allocate = require("./allocate-CZRg4TOP.cjs");
5
- const require_percent = require("./percent-C0InC2t2.cjs");
6
- const require_format = require("./format-DLhno7eX.cjs");
7
- const require_medusa = require("./medusa-lRY9xlsf.cjs");
8
- const require_retail = require("./retail-Cml8YSKg.cjs");
9
- //#region src/commerce/convention.ts
2
+ const require_money = require("./money-DWBjuuEK.cjs");
3
+ const require_rounding = require("./rounding-4QKTRbMQ.cjs");
4
+ const require_allocate = require("./allocate-AusholrC.cjs");
5
+ const require_percent = require("./percent-DABHiSBs.cjs");
6
+ const require_format = require("./format-92fzvTXY.cjs");
7
+ const require_medusa = require("./medusa-CzVK0bth.cjs");
8
+ const require_retail = require("./retail-CYGPU4ea.cjs");
9
+ // src/commerce/convention.ts
10
10
  /**
11
11
  * Currencies with storage digits: step 1, `'x100'`. Zero-decimal currencies: step 100 when
12
12
  * there is a positive sample and every positive sample is a multiple of 100 (the platform
@@ -29,8 +29,7 @@ function storageConventionOf(currency, samples) {
29
29
  convention: "whole-unit"
30
30
  };
31
31
  }
32
- //#endregion
33
- //#region src/commerce/shared.ts
32
+ // src/commerce/shared.ts
34
33
  /** The one currency of `amounts` (the first defined one decides) and their stored integers. Throws `currency_mismatch`. */
35
34
  function oneCurrency(amounts, verb) {
36
35
  let info;
@@ -75,8 +74,7 @@ function digitsOf(decimals, name = "decimals") {
75
74
  if (typeof decimals !== "number" || !Number.isSafeInteger(decimals) || decimals < 0 || decimals > 20) throw new require_money.MoneyError("amount_invalid", `${name} must be an integer from 0 to 20, got ${require_money.describeValue(decimals)}`);
76
75
  return decimals;
77
76
  }
78
- //#endregion
79
- //#region src/commerce/cost.ts
77
+ // src/commerce/cost.ts
80
78
  const scaleOf = (scale) => digitsOf(scale ?? 4, "scale");
81
79
  function quantityOf(value, name) {
82
80
  if (typeof value !== "number" || !Number.isSafeInteger(value)) throw new require_money.MoneyError("amount_invalid", `${name} must be an integer, got ${require_money.describeValue(value)}`);
@@ -139,8 +137,7 @@ function weightedAverageCost(current, receipt, options = {}) {
139
137
  }, cost));
140
138
  return require_money.toDecimalText(require_money.ratioToDecimal(sum.units, require_money.pow10(sum.scale) * (onHand + quantity), scale));
141
139
  }
142
- //#endregion
143
- //#region src/commerce/discount.ts
140
+ // src/commerce/discount.ts
144
141
  const isMoney = (value) => typeof value === "object" && value !== null;
145
142
  /**
146
143
  * The discount `spec` takes off `base` (a line or order total), clamped to `[0, base]`; a
@@ -204,8 +201,7 @@ function formatDiscount(spec, currency, options = {}) {
204
201
  }
205
202
  throw new require_money.MoneyError("amount_invalid", `Not a discount: ${require_money.describeValue(spec)}`);
206
203
  }
207
- //#endregion
208
- //#region src/commerce/order-value.ts
204
+ // src/commerce/order-value.ts
209
205
  const negate = (a) => ({
210
206
  units: -a.units,
211
207
  scale: a.scale
@@ -270,8 +266,7 @@ function resolveOrderValue(input) {
270
266
  source: "items"
271
267
  } : null;
272
268
  }
273
- //#endregion
274
- //#region src/commerce/payable.ts
269
+ // src/commerce/payable.ts
275
270
  /**
276
271
  * `false` when the cart can complete with no payment (`total <= 0` and no negative credit-line
277
272
  * balance: `credit_line_total >= 0 && total <= 0`), `true` when it must be paid, `undefined`
@@ -285,8 +280,7 @@ function requiresPayment(input, currency) {
285
280
  const credit = input.creditLineTotal;
286
281
  return !(total <= 0 && (credit == null || credit >= 0));
287
282
  }
288
- //#endregion
289
- //#region src/commerce/pricing.ts
283
+ // src/commerce/pricing.ts
290
284
  /**
291
285
  * `m` with a markup: exact percent and flat in `order`, one rounding to a storage unit, then
292
286
  * clamped to `[floor, ceiling]`, then to `>= 0`. A non-positive `m` (a failed quote) is
@@ -379,8 +373,7 @@ function netOfFee(m, fee) {
379
373
  const [amount, fixed] = units;
380
374
  return require_money.boundedMoney(amount - require_percent.basisPointsOf(amount, bps, "half-up") - fixed, info);
381
375
  }
382
- //#endregion
383
- //#region src/commerce/tax.ts
376
+ // src/commerce/tax.ts
384
377
  /**
385
378
  * The tax rate in percent that `tax` on `net` implies, snapped half-up to a multiple of `snap`
386
379
  * (default 0.5, every real EU VAT rate; 0 = no snap, 10 decimals). `net <= 0` gives 0.
@@ -513,7 +506,6 @@ function displayTotals(totals, currency, options) {
513
506
  taxIncluded: options.taxInclusive
514
507
  };
515
508
  }
516
- //#endregion
517
509
  exports.allocateWithTax = allocateWithTax;
518
510
  exports.applyMarkup = applyMarkup;
519
511
  exports.buyGetReward = buyGetReward;
@@ -1,6 +1,5 @@
1
- import { R as DecimalText, i as Money, z as RoundingMode } from "./money-B-3aFjNJ.cjs";
2
- import { t as RetailRounding } from "./retail-C_BPLvMj.cjs";
3
- //#region src/commerce/convention.d.ts
1
+ import { R as DecimalText, i as Money, z as RoundingMode } from "./money-BkMeYDEW.cjs";
2
+ import { t as RetailRounding } from "./retail-CmEyJQOH.cjs";
4
3
  /**
5
4
  * Currencies with storage digits: step 1, `'x100'`. Zero-decimal currencies: step 100 when
6
5
  * there is a positive sample and every positive sample is a multiple of 100 (the platform
@@ -10,8 +9,6 @@ export declare function storageConventionOf(currency: string, samples: readonly
10
9
  step: 1 | 100;
11
10
  convention: 'x100' | 'whole-unit';
12
11
  };
13
- //#endregion
14
- //#region src/commerce/cost.d.ts
15
12
  /**
16
13
  * Extra costs (freight, duties) spread over receipt lines by quantity, exactly: `extras`
17
14
  * (rounded half-up to `scale`, default 4) is allocated with the last line absorbing the
@@ -41,8 +38,6 @@ export declare function weightedAverageCost(current: {
41
38
  }, options?: {
42
39
  scale?: number;
43
40
  }): DecimalText;
44
- //#endregion
45
- //#region src/commerce/discount.d.ts
46
41
  interface DiscountSpec {
47
42
  readonly type: 'percentage' | 'fixed';
48
43
  /** A percent (0..100, clamped) for `'percentage'`; Money (currency-carrying) for `'fixed'`. */
@@ -91,8 +86,6 @@ export declare function buyGetReward(input: {
91
86
  export declare function formatDiscount(spec: DiscountSpec, currency: string, options?: {
92
87
  locale?: string;
93
88
  }): string;
94
- //#endregion
95
- //#region src/commerce/order-value.d.ts
96
89
  interface OrderValueInput {
97
90
  currency: string;
98
91
  /** The query.graph `order.total`; used only with `trustGraph` and only when positive. */
@@ -124,8 +117,6 @@ export declare function resolveOrderValue(input: OrderValueInput): {
124
117
  value: Money;
125
118
  source: 'graph' | 'summary' | 'items';
126
119
  } | null;
127
- //#endregion
128
- //#region src/commerce/payable.d.ts
129
120
  /**
130
121
  * `false` when the cart can complete with no payment (`total <= 0` and no negative credit-line
131
122
  * balance: `credit_line_total >= 0 && total <= 0`), `true` when it must be paid, `undefined`
@@ -136,8 +127,6 @@ export declare function requiresPayment(input: {
136
127
  total: unknown;
137
128
  creditLineTotal?: unknown;
138
129
  }, currency: string): boolean | undefined;
139
- //#endregion
140
- //#region src/commerce/pricing.d.ts
141
130
  interface MarkupOptions {
142
131
  /** Percent added (negative = a discount). */
143
132
  percent?: number | DecimalText;
@@ -207,8 +196,6 @@ export declare function netOfFee(m: Money, fee: {
207
196
  bps: number;
208
197
  fixed: Money;
209
198
  }): Money;
210
- //#endregion
211
- //#region src/commerce/tax.d.ts
212
199
  /**
213
200
  * The tax rate in percent that `tax` on `net` implies, snapped half-up to a multiple of `snap`
214
201
  * (default 0.5, every real EU VAT rate; 0 = no snap, 10 decimals). `net <= 0` gives 0.
@@ -289,5 +276,4 @@ interface DisplayTotals {
289
276
  export declare function displayTotals(totals: MedusaTotalsLike, currency: string, options: {
290
277
  taxInclusive: boolean;
291
278
  }): DisplayTotals;
292
- //#endregion
293
279
  export type { BuyGetRewardSpec, DiscountAmountOptions, DiscountSpec, DisplayTotals, MarkupOptions, MedusaTotalsLike, OrderValueInput, RetailMarkup, RetailPriceInput };
@@ -1,6 +1,5 @@
1
- import { R as DecimalText, i as Money, z as RoundingMode } from "./money-B-3aFjNJ.js";
2
- import { t as RetailRounding } from "./retail-DRUTTQoJ.js";
3
- //#region src/commerce/convention.d.ts
1
+ import { R as DecimalText, i as Money, z as RoundingMode } from "./money-BkMeYDEW.js";
2
+ import { t as RetailRounding } from "./retail-B04CjW3b.js";
4
3
  /**
5
4
  * Currencies with storage digits: step 1, `'x100'`. Zero-decimal currencies: step 100 when
6
5
  * there is a positive sample and every positive sample is a multiple of 100 (the platform
@@ -10,8 +9,6 @@ export declare function storageConventionOf(currency: string, samples: readonly
10
9
  step: 1 | 100;
11
10
  convention: 'x100' | 'whole-unit';
12
11
  };
13
- //#endregion
14
- //#region src/commerce/cost.d.ts
15
12
  /**
16
13
  * Extra costs (freight, duties) spread over receipt lines by quantity, exactly: `extras`
17
14
  * (rounded half-up to `scale`, default 4) is allocated with the last line absorbing the
@@ -41,8 +38,6 @@ export declare function weightedAverageCost(current: {
41
38
  }, options?: {
42
39
  scale?: number;
43
40
  }): DecimalText;
44
- //#endregion
45
- //#region src/commerce/discount.d.ts
46
41
  interface DiscountSpec {
47
42
  readonly type: 'percentage' | 'fixed';
48
43
  /** A percent (0..100, clamped) for `'percentage'`; Money (currency-carrying) for `'fixed'`. */
@@ -91,8 +86,6 @@ export declare function buyGetReward(input: {
91
86
  export declare function formatDiscount(spec: DiscountSpec, currency: string, options?: {
92
87
  locale?: string;
93
88
  }): string;
94
- //#endregion
95
- //#region src/commerce/order-value.d.ts
96
89
  interface OrderValueInput {
97
90
  currency: string;
98
91
  /** The query.graph `order.total`; used only with `trustGraph` and only when positive. */
@@ -124,8 +117,6 @@ export declare function resolveOrderValue(input: OrderValueInput): {
124
117
  value: Money;
125
118
  source: 'graph' | 'summary' | 'items';
126
119
  } | null;
127
- //#endregion
128
- //#region src/commerce/payable.d.ts
129
120
  /**
130
121
  * `false` when the cart can complete with no payment (`total <= 0` and no negative credit-line
131
122
  * balance: `credit_line_total >= 0 && total <= 0`), `true` when it must be paid, `undefined`
@@ -136,8 +127,6 @@ export declare function requiresPayment(input: {
136
127
  total: unknown;
137
128
  creditLineTotal?: unknown;
138
129
  }, currency: string): boolean | undefined;
139
- //#endregion
140
- //#region src/commerce/pricing.d.ts
141
130
  interface MarkupOptions {
142
131
  /** Percent added (negative = a discount). */
143
132
  percent?: number | DecimalText;
@@ -207,8 +196,6 @@ export declare function netOfFee(m: Money, fee: {
207
196
  bps: number;
208
197
  fixed: Money;
209
198
  }): Money;
210
- //#endregion
211
- //#region src/commerce/tax.d.ts
212
199
  /**
213
200
  * The tax rate in percent that `tax` on `net` implies, snapped half-up to a multiple of `snap`
214
201
  * (default 0.5, every real EU VAT rate; 0 = no snap, 10 decimals). `net <= 0` gives 0.
@@ -289,5 +276,4 @@ interface DisplayTotals {
289
276
  export declare function displayTotals(totals: MedusaTotalsLike, currency: string, options: {
290
277
  taxInclusive: boolean;
291
278
  }): DisplayTotals;
292
- //#endregion
293
279
  export type { BuyGetRewardSpec, DiscountAmountOptions, DiscountSpec, DisplayTotals, MarkupOptions, MedusaTotalsLike, OrderValueInput, RetailMarkup, RetailPriceInput };
package/dist/commerce.js CHANGED
@@ -1,11 +1,11 @@
1
- import { $ as describeValue, B as decimalOf, E as resolveCurrency, Q as MoneyError, X as mulDiv, Z as ratioToDecimal, dt as roundToScale, et as addDecimal, i as medusaAmountDecimal, pt as toDecimalText, rt as divRound, s as storedDecimal, st as multiplyDecimal, t as boundedMoney, ut as pow10 } from "./money-WhnGiI00.js";
2
- import { a as unitSize, r as roundStoredDecimal, t as mulDivToUnit } from "./rounding-g9rvye0k.js";
3
- import { n as allocateUnits, t as allocate } from "./allocate-X7_jAtOj.js";
4
- import { i as percentRatio, n as hundredPercent, t as basisPointsOf } from "./percent-D1VB9xXG.js";
5
- import { t as formatMoney } from "./format-BdPnijvn.js";
6
- import { a as readStoredDecimal, c as storedFieldValue } from "./medusa-DqJY1qpj.js";
7
- import { n as retailUnits } from "./retail-1mu888J1.js";
8
- //#region src/commerce/convention.ts
1
+ import { $ as describeValue, B as decimalOf, E as resolveCurrency, Q as MoneyError, X as mulDiv, Z as ratioToDecimal, dt as roundToScale, et as addDecimal, i as medusaAmountDecimal, pt as toDecimalText, rt as divRound, s as storedDecimal, st as multiplyDecimal, t as boundedMoney, ut as pow10 } from "./money-BxbAw7BP.js";
2
+ import { a as unitSize, r as roundStoredDecimal, t as mulDivToUnit } from "./rounding-CA1PVP3b.js";
3
+ import { n as allocateUnits, t as allocate } from "./allocate-BBRfdaSC.js";
4
+ import { i as percentRatio, n as hundredPercent, t as basisPointsOf } from "./percent-CB3Ixjc_.js";
5
+ import { t as formatMoney } from "./format-BJC513u4.js";
6
+ import { a as readStoredDecimal, c as storedFieldValue } from "./medusa-pKGlImn9.js";
7
+ import { n as retailUnits } from "./retail-DXgs11ov.js";
8
+ // src/commerce/convention.ts
9
9
  /**
10
10
  * Currencies with storage digits: step 1, `'x100'`. Zero-decimal currencies: step 100 when
11
11
  * there is a positive sample and every positive sample is a multiple of 100 (the platform
@@ -28,8 +28,7 @@ function storageConventionOf(currency, samples) {
28
28
  convention: "whole-unit"
29
29
  };
30
30
  }
31
- //#endregion
32
- //#region src/commerce/shared.ts
31
+ // src/commerce/shared.ts
33
32
  /** The one currency of `amounts` (the first defined one decides) and their stored integers. Throws `currency_mismatch`. */
34
33
  function oneCurrency(amounts, verb) {
35
34
  let info;
@@ -74,8 +73,7 @@ function digitsOf(decimals, name = "decimals") {
74
73
  if (typeof decimals !== "number" || !Number.isSafeInteger(decimals) || decimals < 0 || decimals > 20) throw new MoneyError("amount_invalid", `${name} must be an integer from 0 to 20, got ${describeValue(decimals)}`);
75
74
  return decimals;
76
75
  }
77
- //#endregion
78
- //#region src/commerce/cost.ts
76
+ // src/commerce/cost.ts
79
77
  const scaleOf = (scale) => digitsOf(scale ?? 4, "scale");
80
78
  function quantityOf(value, name) {
81
79
  if (typeof value !== "number" || !Number.isSafeInteger(value)) throw new MoneyError("amount_invalid", `${name} must be an integer, got ${describeValue(value)}`);
@@ -138,8 +136,7 @@ function weightedAverageCost(current, receipt, options = {}) {
138
136
  }, cost));
139
137
  return toDecimalText(ratioToDecimal(sum.units, pow10(sum.scale) * (onHand + quantity), scale));
140
138
  }
141
- //#endregion
142
- //#region src/commerce/discount.ts
139
+ // src/commerce/discount.ts
143
140
  const isMoney = (value) => typeof value === "object" && value !== null;
144
141
  /**
145
142
  * The discount `spec` takes off `base` (a line or order total), clamped to `[0, base]`; a
@@ -203,8 +200,7 @@ function formatDiscount(spec, currency, options = {}) {
203
200
  }
204
201
  throw new MoneyError("amount_invalid", `Not a discount: ${describeValue(spec)}`);
205
202
  }
206
- //#endregion
207
- //#region src/commerce/order-value.ts
203
+ // src/commerce/order-value.ts
208
204
  const negate = (a) => ({
209
205
  units: -a.units,
210
206
  scale: a.scale
@@ -269,8 +265,7 @@ function resolveOrderValue(input) {
269
265
  source: "items"
270
266
  } : null;
271
267
  }
272
- //#endregion
273
- //#region src/commerce/payable.ts
268
+ // src/commerce/payable.ts
274
269
  /**
275
270
  * `false` when the cart can complete with no payment (`total <= 0` and no negative credit-line
276
271
  * balance: `credit_line_total >= 0 && total <= 0`), `true` when it must be paid, `undefined`
@@ -284,8 +279,7 @@ function requiresPayment(input, currency) {
284
279
  const credit = input.creditLineTotal;
285
280
  return !(total <= 0 && (credit == null || credit >= 0));
286
281
  }
287
- //#endregion
288
- //#region src/commerce/pricing.ts
282
+ // src/commerce/pricing.ts
289
283
  /**
290
284
  * `m` with a markup: exact percent and flat in `order`, one rounding to a storage unit, then
291
285
  * clamped to `[floor, ceiling]`, then to `>= 0`. A non-positive `m` (a failed quote) is
@@ -378,8 +372,7 @@ function netOfFee(m, fee) {
378
372
  const [amount, fixed] = units;
379
373
  return boundedMoney(amount - basisPointsOf(amount, bps, "half-up") - fixed, info);
380
374
  }
381
- //#endregion
382
- //#region src/commerce/tax.ts
375
+ // src/commerce/tax.ts
383
376
  /**
384
377
  * The tax rate in percent that `tax` on `net` implies, snapped half-up to a multiple of `snap`
385
378
  * (default 0.5, every real EU VAT rate; 0 = no snap, 10 decimals). `net <= 0` gives 0.
@@ -512,5 +505,4 @@ function displayTotals(totals, currency, options) {
512
505
  taxIncluded: options.taxInclusive
513
506
  };
514
507
  }
515
- //#endregion
516
508
  export { allocateWithTax, applyMarkup, buyGetReward, discountAmount, displayTotals, formatDiscount, inferTaxRatePercent, inferTaxesIncluded, landedUnitCosts, marginPercent, netOfFee, percentChange, requiresPayment, resolveOrderValue, retailPrice, solveTaxRate, splitGross, storageConventionOf, unitNetOfTax, weightedAverageCost };
@@ -1,6 +1,6 @@
1
- const require_money = require("./money-B3wH_Z4S.cjs");
2
- const require_rounding = require("./rounding-DHBtNCHG.cjs");
3
- //#region src/format.ts
1
+ const require_money = require("./money-DWBjuuEK.cjs");
2
+ const require_rounding = require("./rounding-4QKTRbMQ.cjs");
3
+ // src/format.ts
4
4
  function intlDisplay(options) {
5
5
  const display = options.currencyDisplay ?? "symbol";
6
6
  return display === "symbol+code" ? "symbol" : display;
@@ -12,14 +12,14 @@ function finish(text, code, options) {
12
12
  const asIntlValue = (text) => text;
13
13
  /**
14
14
  * Money for people: `'$1,234.50'`, `'¥1,200'`, `'KWD 1.005'`, `'-€5.00'`. Locale, currency
15
- * display, digits and sign are explicit options; the active app locale is the caller's to
16
- * pass. If Intl throws, `'<CODE> <decimal>'`.
15
+ * display, digits, sign and rounding (half-up by default, `'down'` for caps) are explicit
16
+ * options; the active app locale is the caller's to pass. If Intl throws, `'<CODE> <decimal>'`.
17
17
  */
18
18
  function formatMoney(m, options = {}) {
19
19
  const { info, value } = require_money.storedDecimal(m);
20
20
  const whole = require_money.fractionDigitsOf(value) === 0;
21
21
  const digits = options.digits === "widen" ? Math.max(info.displayDigits, require_money.fractionDigitsOf(value)) : options.digits === "trim-zero" && whole ? 0 : info.displayDigits;
22
- const text = require_money.formatDecimal(require_money.roundToScale(value, digits, "half-up"));
22
+ const text = require_money.formatDecimal(require_money.roundToScale(value, digits, options.rounding ?? "half-up"));
23
23
  try {
24
24
  return finish(require_money.numberFormat(require_money.resolveLocale(options.locale), {
25
25
  style: "currency",
@@ -35,11 +35,12 @@ function formatMoney(m, options = {}) {
35
35
  }
36
36
  /**
37
37
  * A stored amount that may be fractional (a Medusa total, 107.8175; a percentage promotion) for
38
- * people: rounded half-up to a whole storage unit (`roundToUnit`), then `formatMoney` with `options`.
38
+ * people: rounded to a whole storage unit by `options.rounding` (`roundToUnit`; half-up by default,
39
+ * `'down'` toward zero for a cap), then `formatMoney` with `options`.
39
40
  * A number must be finite; text is plain decimal; an unknown currency throws `currency_invalid`.
40
41
  */
41
42
  function formatStored(amount, currency, options = {}) {
42
- return formatMoney(require_rounding.roundToUnit(amount, currency), options);
43
+ return formatMoney(require_rounding.roundToUnit(amount, currency, { rounding: options.rounding ?? "half-up" }), options);
43
44
  }
44
45
  function compact(currency, major, options, significant) {
45
46
  return require_money.numberFormat(require_money.resolveLocale(options.locale), {
@@ -95,7 +96,6 @@ function moneyAxisFormatter(currency, options = {}) {
95
96
  }
96
97
  };
97
98
  }
98
- //#endregion
99
99
  Object.defineProperty(exports, "formatMoney", {
100
100
  enumerable: true,
101
101
  get: function() {
@@ -1,6 +1,6 @@
1
- import { B as decimalOf, E as resolveCurrency, M as resolveLocale, Q as MoneyError, at as fractionDigitsOf, dt as roundToScale, it as formatDecimal, j as numberFormat, nt as decimalFromNumber, s as storedDecimal, tt as compareDecimal } from "./money-WhnGiI00.js";
2
- import { i as roundToUnit } from "./rounding-g9rvye0k.js";
3
- //#region src/format.ts
1
+ import { B as decimalOf, E as resolveCurrency, M as resolveLocale, Q as MoneyError, at as fractionDigitsOf, dt as roundToScale, it as formatDecimal, j as numberFormat, nt as decimalFromNumber, s as storedDecimal, tt as compareDecimal } from "./money-BxbAw7BP.js";
2
+ import { i as roundToUnit } from "./rounding-CA1PVP3b.js";
3
+ // src/format.ts
4
4
  function intlDisplay(options) {
5
5
  const display = options.currencyDisplay ?? "symbol";
6
6
  return display === "symbol+code" ? "symbol" : display;
@@ -12,14 +12,14 @@ function finish(text, code, options) {
12
12
  const asIntlValue = (text) => text;
13
13
  /**
14
14
  * Money for people: `'$1,234.50'`, `'¥1,200'`, `'KWD 1.005'`, `'-€5.00'`. Locale, currency
15
- * display, digits and sign are explicit options; the active app locale is the caller's to
16
- * pass. If Intl throws, `'<CODE> <decimal>'`.
15
+ * display, digits, sign and rounding (half-up by default, `'down'` for caps) are explicit
16
+ * options; the active app locale is the caller's to pass. If Intl throws, `'<CODE> <decimal>'`.
17
17
  */
18
18
  function formatMoney(m, options = {}) {
19
19
  const { info, value } = storedDecimal(m);
20
20
  const whole = fractionDigitsOf(value) === 0;
21
21
  const digits = options.digits === "widen" ? Math.max(info.displayDigits, fractionDigitsOf(value)) : options.digits === "trim-zero" && whole ? 0 : info.displayDigits;
22
- const text = formatDecimal(roundToScale(value, digits, "half-up"));
22
+ const text = formatDecimal(roundToScale(value, digits, options.rounding ?? "half-up"));
23
23
  try {
24
24
  return finish(numberFormat(resolveLocale(options.locale), {
25
25
  style: "currency",
@@ -35,11 +35,12 @@ function formatMoney(m, options = {}) {
35
35
  }
36
36
  /**
37
37
  * A stored amount that may be fractional (a Medusa total, 107.8175; a percentage promotion) for
38
- * people: rounded half-up to a whole storage unit (`roundToUnit`), then `formatMoney` with `options`.
38
+ * people: rounded to a whole storage unit by `options.rounding` (`roundToUnit`; half-up by default,
39
+ * `'down'` toward zero for a cap), then `formatMoney` with `options`.
39
40
  * A number must be finite; text is plain decimal; an unknown currency throws `currency_invalid`.
40
41
  */
41
42
  function formatStored(amount, currency, options = {}) {
42
- return formatMoney(roundToUnit(amount, currency), options);
43
+ return formatMoney(roundToUnit(amount, currency, { rounding: options.rounding ?? "half-up" }), options);
43
44
  }
44
45
  function compact(currency, major, options, significant) {
45
46
  return numberFormat(resolveLocale(options.locale), {
@@ -95,5 +96,4 @@ function moneyAxisFormatter(currency, options = {}) {
95
96
  }
96
97
  };
97
98
  }
98
- //#endregion
99
99
  export { moneyAxisFormatter as a, formatStored as i, formatMoneyCompact as n, formatMoneyRange as r, formatMoney as t };
package/dist/fx.cjs CHANGED
@@ -1,11 +1,11 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_money = require("./money-B3wH_Z4S.cjs");
3
- const require_rounding = require("./rounding-DHBtNCHG.cjs");
4
- const require_own = require("./own-oP9DXFWv.cjs");
5
- const require_medusa = require("./medusa-lRY9xlsf.cjs");
6
- const require_rate = require("./rate-CVeMii4a.cjs");
7
- const require_retail = require("./retail-Cml8YSKg.cjs");
8
- //#region src/fx/convert.ts
2
+ const require_money = require("./money-DWBjuuEK.cjs");
3
+ const require_rounding = require("./rounding-4QKTRbMQ.cjs");
4
+ const require_own = require("./own-C5imDkyB.cjs");
5
+ const require_medusa = require("./medusa-CzVK0bth.cjs");
6
+ const require_rate = require("./rate-CEjWTATc.cjs");
7
+ const require_retail = require("./retail-CYGPU4ea.cjs");
8
+ // src/fx/convert.ts
9
9
  const infoOf = (code) => require_money.resolveCurrency(code, { allowHistoric: true });
10
10
  /**
11
11
  * The factor taking a stored `from` amount to a stored `to` amount for the major rate `r`
@@ -47,8 +47,7 @@ function impliedRate(a, b) {
47
47
  denominator: denominator / divisor
48
48
  };
49
49
  }
50
- //#endregion
51
- //#region src/fx/format-rate.ts
50
+ // src/fx/format-rate.ts
52
51
  /** `floor(log10(n / d))` of a positive ratio, exactly. */
53
52
  function exponentOf(n, d) {
54
53
  let e = n.toString().length - d.toString().length;
@@ -77,8 +76,7 @@ function formatRate(r, from, to, options = {}) {
77
76
  maximumFractionDigits: digits
78
77
  }).format(asIntlValue(require_money.formatDecimal(value)))} ${toCode}`;
79
78
  }
80
- //#endregion
81
- //#region src/fx/plausibility.ts
79
+ // src/fx/plausibility.ts
82
80
  /** Medusa PRICE_SEED_RATE_MAX_DEVIATION's default. */
83
81
  const DEFAULT_RATE_MAX_DEVIATION = 2;
84
82
  /** chooseFactor's tolerance between the conventional factor and the observed median. */
@@ -206,8 +204,7 @@ function rateConsensus(rates, options = {}) {
206
204
  })
207
205
  };
208
206
  }
209
- //#endregion
210
- //#region src/fx/reporting.ts
207
+ // src/fx/reporting.ts
211
208
  const FACTOR_DIGITS = 20;
212
209
  /**
213
210
  * The reporting factors of a store whose locked rates say `1 default = n/d <code>`:
@@ -260,8 +257,7 @@ function toReporting(items, table) {
260
257
  missing: [...missing].sort()
261
258
  };
262
259
  }
263
- //#endregion
264
- //#region src/fx/settings.ts
260
+ // src/fx/settings.ts
265
261
  const RATE_MODES = ["manual", "dynamic"];
266
262
  const PRICE_ROUNDINGS = ["none", "nearest"];
267
263
  /** `store_currency_rate.rate_mode` as readers coerce it: `'manual'` exactly, else `'dynamic'`. */
@@ -299,8 +295,7 @@ function resolveMoneyByCurrency(setting, currency, options) {
299
295
  }
300
296
  return null;
301
297
  }
302
- //#endregion
303
- //#region src/fx/tables.ts
298
+ // src/fx/tables.ts
304
299
  /** 1 USD = rate units of the currency, exact (see data/pegs.ts for the sources). Upper-case keys. */
305
300
  const USD_PEGS = Object.freeze(Object.fromEntries(Object.entries({
306
301
  AED: [36725n, 10000n],
@@ -371,7 +366,6 @@ function pegFallback(from, to, ratesPerUsd, pegs = USD_PEGS) {
371
366
  const fromPeg = own(pegs, f);
372
367
  return fromPeg !== void 0 && t === "USD" ? require_rate.invertRate(fromPeg) : null;
373
368
  }
374
- //#endregion
375
369
  exports.DEFAULT_RATE_MAX_DEVIATION = DEFAULT_RATE_MAX_DEVIATION;
376
370
  exports.FACTOR_TOLERANCE = FACTOR_TOLERANCE;
377
371
  exports.PRICE_ROUNDINGS = PRICE_ROUNDINGS;