@ducatjs/money 0.1.0 → 0.2.1

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 (253) hide show
  1. package/NOTICE +73 -0
  2. package/README.md +479 -62
  3. package/data/cash-rounding.json +123 -2
  4. package/data/cldr-cash.json +101 -0
  5. package/data/historic.json +78 -0
  6. package/data/iso4217-list-three.xml +1185 -0
  7. package/dist/adyen-fx.d.ts.map +1 -1
  8. package/dist/adyen-fx.js +22 -4
  9. package/dist/adyen-fx.js.map +1 -1
  10. package/dist/boc.d.ts +31 -0
  11. package/dist/boc.d.ts.map +1 -0
  12. package/dist/boc.js +114 -0
  13. package/dist/boc.js.map +1 -0
  14. package/dist/boe.d.ts +33 -0
  15. package/dist/boe.d.ts.map +1 -0
  16. package/dist/boe.js +114 -0
  17. package/dist/boe.js.map +1 -0
  18. package/dist/cash.d.ts +30 -1
  19. package/dist/cash.d.ts.map +1 -1
  20. package/dist/cash.js +50 -2
  21. package/dist/cash.js.map +1 -1
  22. package/dist/convert.d.ts +10 -9
  23. package/dist/convert.d.ts.map +1 -1
  24. package/dist/convert.js +13 -3
  25. package/dist/convert.js.map +1 -1
  26. package/dist/drizzle/mysql.d.ts +105 -0
  27. package/dist/drizzle/mysql.d.ts.map +1 -0
  28. package/dist/drizzle/mysql.js +60 -0
  29. package/dist/drizzle/mysql.js.map +1 -0
  30. package/dist/drizzle/pg.d.ts +103 -0
  31. package/dist/drizzle/pg.d.ts.map +1 -0
  32. package/dist/drizzle/pg.js +60 -0
  33. package/dist/drizzle/pg.js.map +1 -0
  34. package/dist/drizzle/sqlite.d.ts +102 -0
  35. package/dist/drizzle/sqlite.d.ts.map +1 -0
  36. package/dist/drizzle/sqlite.js +59 -0
  37. package/dist/drizzle/sqlite.js.map +1 -0
  38. package/dist/ecb.d.ts +37 -2
  39. package/dist/ecb.d.ts.map +1 -1
  40. package/dist/ecb.js +148 -10
  41. package/dist/ecb.js.map +1 -1
  42. package/dist/fed.d.ts +35 -0
  43. package/dist/fed.d.ts.map +1 -0
  44. package/dist/fed.js +134 -0
  45. package/dist/fed.js.map +1 -0
  46. package/dist/fetch.d.ts +45 -0
  47. package/dist/fetch.d.ts.map +1 -1
  48. package/dist/fetch.js +167 -24
  49. package/dist/fetch.js.map +1 -1
  50. package/dist/fn.d.ts +8 -1
  51. package/dist/fn.d.ts.map +1 -1
  52. package/dist/fn.js +8 -1
  53. package/dist/fn.js.map +1 -1
  54. package/dist/generated/cash.d.ts +2 -0
  55. package/dist/generated/cash.d.ts.map +1 -1
  56. package/dist/generated/cash.js +101 -0
  57. package/dist/generated/cash.js.map +1 -1
  58. package/dist/generated/historic.d.ts +337 -0
  59. package/dist/generated/historic.d.ts.map +1 -0
  60. package/dist/generated/historic.js +66 -0
  61. package/dist/generated/historic.js.map +1 -0
  62. package/dist/historic.d.ts +40 -0
  63. package/dist/historic.d.ts.map +1 -0
  64. package/dist/historic.js +43 -0
  65. package/dist/historic.js.map +1 -0
  66. package/dist/history.d.ts +96 -0
  67. package/dist/history.d.ts.map +1 -0
  68. package/dist/history.js +213 -0
  69. package/dist/history.js.map +1 -0
  70. package/dist/hmrc.d.ts +28 -0
  71. package/dist/hmrc.d.ts.map +1 -0
  72. package/dist/hmrc.js +108 -0
  73. package/dist/hmrc.js.map +1 -0
  74. package/dist/index.d.ts +1 -1
  75. package/dist/index.d.ts.map +1 -1
  76. package/dist/index.js +1 -1
  77. package/dist/index.js.map +1 -1
  78. package/dist/kysely.d.ts +120 -0
  79. package/dist/kysely.d.ts.map +1 -0
  80. package/dist/kysely.js +309 -0
  81. package/dist/kysely.js.map +1 -0
  82. package/dist/money.d.ts +93 -9
  83. package/dist/money.d.ts.map +1 -1
  84. package/dist/money.js +135 -9
  85. package/dist/money.js.map +1 -1
  86. package/dist/parse.d.ts +45 -1
  87. package/dist/parse.d.ts.map +1 -1
  88. package/dist/parse.js +290 -3
  89. package/dist/parse.js.map +1 -1
  90. package/dist/pg.d.ts +100 -0
  91. package/dist/pg.d.ts.map +1 -0
  92. package/dist/pg.js +343 -0
  93. package/dist/pg.js.map +1 -0
  94. package/dist/plugins/adyen.d.ts +1 -1
  95. package/dist/plugins/adyen.d.ts.map +1 -1
  96. package/dist/plugins/adyen.js.map +1 -1
  97. package/dist/plugins/all.d.ts +8 -1
  98. package/dist/plugins/all.d.ts.map +1 -1
  99. package/dist/plugins/all.js +8 -1
  100. package/dist/plugins/all.js.map +1 -1
  101. package/dist/plugins/allocate.d.ts +1 -1
  102. package/dist/plugins/allocate.d.ts.map +1 -1
  103. package/dist/plugins/allocate.js.map +1 -1
  104. package/dist/plugins/braintree.d.ts +1 -1
  105. package/dist/plugins/braintree.d.ts.map +1 -1
  106. package/dist/plugins/braintree.js.map +1 -1
  107. package/dist/plugins/cash.d.ts +1 -1
  108. package/dist/plugins/cash.d.ts.map +1 -1
  109. package/dist/plugins/cash.js.map +1 -1
  110. package/dist/plugins/checkout.d.ts +1 -1
  111. package/dist/plugins/checkout.d.ts.map +1 -1
  112. package/dist/plugins/checkout.js.map +1 -1
  113. package/dist/plugins/convert.d.ts +5 -5
  114. package/dist/plugins/convert.d.ts.map +1 -1
  115. package/dist/plugins/convert.js.map +1 -1
  116. package/dist/plugins/exact.d.ts +1 -1
  117. package/dist/plugins/exact.d.ts.map +1 -1
  118. package/dist/plugins/exact.js.map +1 -1
  119. package/dist/plugins/fixed.d.ts +1 -1
  120. package/dist/plugins/fixed.d.ts.map +1 -1
  121. package/dist/plugins/fixed.js.map +1 -1
  122. package/dist/plugins/format.d.ts +1 -1
  123. package/dist/plugins/format.d.ts.map +1 -1
  124. package/dist/plugins/format.js.map +1 -1
  125. package/dist/plugins/klarna.d.ts +1 -1
  126. package/dist/plugins/klarna.d.ts.map +1 -1
  127. package/dist/plugins/klarna.js.map +1 -1
  128. package/dist/plugins/paypal.d.ts +1 -1
  129. package/dist/plugins/paypal.d.ts.map +1 -1
  130. package/dist/plugins/paypal.js +0 -4
  131. package/dist/plugins/paypal.js.map +1 -1
  132. package/dist/plugins/prisma.d.ts +1 -1
  133. package/dist/plugins/prisma.d.ts.map +1 -1
  134. package/dist/plugins/prisma.js +0 -4
  135. package/dist/plugins/prisma.js.map +1 -1
  136. package/dist/plugins/stripe.d.ts +1 -1
  137. package/dist/plugins/stripe.d.ts.map +1 -1
  138. package/dist/plugins/stripe.js +0 -4
  139. package/dist/plugins/stripe.js.map +1 -1
  140. package/dist/plugins/tax.d.ts +6 -6
  141. package/dist/plugins/tax.d.ts.map +1 -1
  142. package/dist/plugins/tax.js.map +1 -1
  143. package/dist/policy.d.ts +34 -0
  144. package/dist/policy.d.ts.map +1 -0
  145. package/dist/policy.js +90 -0
  146. package/dist/policy.js.map +1 -0
  147. package/dist/prisma.d.ts +25 -14
  148. package/dist/prisma.d.ts.map +1 -1
  149. package/dist/prisma.js +29 -19
  150. package/dist/prisma.js.map +1 -1
  151. package/dist/provider.d.ts +21 -7
  152. package/dist/provider.d.ts.map +1 -1
  153. package/dist/provider.js +51 -11
  154. package/dist/provider.js.map +1 -1
  155. package/dist/rate-text.d.ts +38 -0
  156. package/dist/rate-text.d.ts.map +1 -0
  157. package/dist/rate-text.js +143 -0
  158. package/dist/rate-text.js.map +1 -0
  159. package/dist/rate.d.ts +61 -5
  160. package/dist/rate.d.ts.map +1 -1
  161. package/dist/rate.js +133 -33
  162. package/dist/rate.js.map +1 -1
  163. package/dist/rounding.js +1 -1
  164. package/dist/rounding.js.map +1 -1
  165. package/dist/schema.d.ts +43 -0
  166. package/dist/schema.d.ts.map +1 -0
  167. package/dist/schema.js +77 -0
  168. package/dist/schema.js.map +1 -0
  169. package/dist/sql.d.ts +54 -0
  170. package/dist/sql.d.ts.map +1 -0
  171. package/dist/sql.js +131 -0
  172. package/dist/sql.js.map +1 -0
  173. package/dist/tax.d.ts +13 -9
  174. package/dist/tax.d.ts.map +1 -1
  175. package/dist/tax.js +20 -4
  176. package/dist/tax.js.map +1 -1
  177. package/dist/testing/arbitraries.d.ts +43 -0
  178. package/dist/testing/arbitraries.d.ts.map +1 -0
  179. package/dist/testing/arbitraries.js +98 -0
  180. package/dist/testing/arbitraries.js.map +1 -0
  181. package/dist/testing/index.d.ts +67 -0
  182. package/dist/testing/index.d.ts.map +1 -0
  183. package/dist/testing/index.js +159 -0
  184. package/dist/testing/index.js.map +1 -0
  185. package/dist/testing/jest.d.ts +2 -0
  186. package/dist/testing/jest.d.ts.map +1 -0
  187. package/dist/testing/jest.js +15 -0
  188. package/dist/testing/jest.js.map +1 -0
  189. package/dist/testing/vitest.d.ts +7 -0
  190. package/dist/testing/vitest.d.ts.map +1 -0
  191. package/dist/testing/vitest.js +12 -0
  192. package/dist/testing/vitest.js.map +1 -0
  193. package/dist/valibot.d.ts +33 -0
  194. package/dist/valibot.d.ts.map +1 -0
  195. package/dist/valibot.js +61 -0
  196. package/dist/valibot.js.map +1 -0
  197. package/dist/zod.d.ts +36 -0
  198. package/dist/zod.d.ts.map +1 -0
  199. package/dist/zod.js +58 -0
  200. package/dist/zod.js.map +1 -0
  201. package/package.json +116 -5
  202. package/src/adyen-fx.ts +25 -4
  203. package/src/boc.ts +136 -0
  204. package/src/boe.ts +131 -0
  205. package/src/cash.ts +70 -2
  206. package/src/convert.ts +33 -15
  207. package/src/drizzle/mysql.ts +78 -0
  208. package/src/drizzle/pg.ts +78 -0
  209. package/src/drizzle/sqlite.ts +70 -0
  210. package/src/ecb.ts +179 -13
  211. package/src/fed.ts +146 -0
  212. package/src/fetch.ts +207 -28
  213. package/src/fn.ts +14 -0
  214. package/src/generated/cash.ts +103 -0
  215. package/src/generated/historic.ts +67 -0
  216. package/src/historic.ts +77 -0
  217. package/src/history.ts +333 -0
  218. package/src/hmrc.ts +125 -0
  219. package/src/index.ts +4 -0
  220. package/src/kysely.ts +588 -0
  221. package/src/money.ts +210 -12
  222. package/src/parse.ts +371 -4
  223. package/src/pg.ts +410 -0
  224. package/src/plugins/adyen.ts +3 -2
  225. package/src/plugins/all.ts +10 -0
  226. package/src/plugins/allocate.ts +3 -2
  227. package/src/plugins/braintree.ts +3 -2
  228. package/src/plugins/cash.ts +3 -2
  229. package/src/plugins/checkout.ts +3 -2
  230. package/src/plugins/convert.ts +6 -6
  231. package/src/plugins/exact.ts +3 -2
  232. package/src/plugins/fixed.ts +3 -2
  233. package/src/plugins/format.ts +3 -2
  234. package/src/plugins/klarna.ts +3 -2
  235. package/src/plugins/paypal.ts +3 -2
  236. package/src/plugins/prisma.ts +3 -2
  237. package/src/plugins/stripe.ts +3 -2
  238. package/src/plugins/tax.ts +11 -11
  239. package/src/policy.ts +124 -0
  240. package/src/prisma.ts +91 -10
  241. package/src/provider.ts +81 -16
  242. package/src/rate-text.ts +151 -0
  243. package/src/rate.ts +205 -36
  244. package/src/rounding.ts +1 -1
  245. package/src/schema.ts +119 -0
  246. package/src/sql.ts +178 -0
  247. package/src/tax.ts +40 -9
  248. package/src/testing/arbitraries.ts +134 -0
  249. package/src/testing/index.ts +247 -0
  250. package/src/testing/jest.ts +18 -0
  251. package/src/testing/vitest.ts +18 -0
  252. package/src/valibot.ts +87 -0
  253. package/src/zod.ts +78 -0
@@ -1,5 +1,5 @@
1
1
  export * from '../format.js';
2
- declare module '../money.js' {
2
+ declare module '../index.js' {
3
3
  interface Money<C extends string> {
4
4
  /** Locale formatting via Intl: `price.format('de-DE')` gives "19,99 €" */
5
5
  format(locale?: string, options?: Intl.NumberFormatOptions): string;
@@ -1 +1 @@
1
- {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/plugins/format.ts"],"names":[],"mappings":"AAOA,cAAc,cAAc,CAAC;AAE7B,OAAO,QAAQ,aAAa,CAAC;IAC3B,UAAU,KAAK,CAAC,CAAC,SAAS,MAAM;QAC9B,0EAA0E;QAC1E,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,mBAAmB,GAAG,MAAM,CAAC;QACpE,aAAa,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;KAC7F;CACF"}
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/plugins/format.ts"],"names":[],"mappings":"AAQA,cAAc,cAAc,CAAC;AAE7B,OAAO,QAAQ,aAAa,CAAC;IAC3B,UAAU,KAAK,CAAC,CAAC,SAAS,MAAM;QAC9B,0EAA0E;QAC1E,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,mBAAmB,GAAG,MAAM,CAAC;QACpE,aAAa,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;KAC7F;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/plugins/format.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,WAAW,EAAc,MAAM,aAAa,CAAC;AAEtD,cAAc,cAAc,CAAC;AAU7B,WAAW,CACT;IACE,MAAM,CAAc,MAAe,EAAE,OAAkC;QACrE,OAAO,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,CAAC;IACD,aAAa,CAAc,MAAe,EAAE,OAAkC;QAC5E,OAAO,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9C,CAAC;CACF,EACD,EAAE,KAAK,EAAE,uBAAuB,EAAE,CACnC,CAAC"}
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/plugins/format.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAErD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,cAAc,cAAc,CAAC;AAU7B,WAAW,CACT;IACE,MAAM,CAAc,MAAe,EAAE,OAAkC;QACrE,OAAO,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,CAAC;IACD,aAAa,CAAc,MAAe,EAAE,OAAkC;QAC5E,OAAO,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9C,CAAC;CACF,EACD,EAAE,KAAK,EAAE,uBAAuB,EAAE,CACnC,CAAC"}
@@ -1,7 +1,7 @@
1
1
  /** `@ducatjs/money/klarna`: Klarna's amount view. Importing this module adds `toKlarna`. */
2
2
  import { type KlarnaAmountOptions } from '../klarna.js';
3
3
  export * from '../klarna.js';
4
- declare module '../money.js' {
4
+ declare module '../index.js' {
5
5
  interface Money<C extends string> {
6
6
  /** The integer for any Klarna amount field: `money('25', 'EUR').toKlarna()` is 2500. */
7
7
  toKlarna(options?: KlarnaAmountOptions): number;
@@ -1 +1 @@
1
- {"version":3,"file":"klarna.d.ts","sourceRoot":"","sources":["../../src/plugins/klarna.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,OAAO,EAAY,KAAK,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAGlE,cAAc,cAAc,CAAC;AAE7B,OAAO,QAAQ,aAAa,CAAC;IAC3B,UAAU,KAAK,CAAC,CAAC,SAAS,MAAM;QAC9B,wFAAwF;QACxF,QAAQ,CAAC,OAAO,CAAC,EAAE,mBAAmB,GAAG,MAAM,CAAC;KACjD;CACF"}
1
+ {"version":3,"file":"klarna.d.ts","sourceRoot":"","sources":["../../src/plugins/klarna.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,OAAO,EAAY,KAAK,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAIlE,cAAc,cAAc,CAAC;AAE7B,OAAO,QAAQ,aAAa,CAAC;IAC3B,UAAU,KAAK,CAAC,CAAC,SAAS,MAAM;QAC9B,wFAAwF;QACxF,QAAQ,CAAC,OAAO,CAAC,EAAE,mBAAmB,GAAG,MAAM,CAAC;KACjD;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"klarna.js","sourceRoot":"","sources":["../../src/plugins/klarna.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,OAAO,EAAE,QAAQ,EAA4B,MAAM,cAAc,CAAC;AAClE,OAAO,EAAE,WAAW,EAAc,MAAM,aAAa,CAAC;AAEtD,cAAc,cAAc,CAAC;AAS7B,WAAW,CACT;IACE,QAAQ,CAAc,OAA6B;QACjD,OAAO,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACjC,CAAC;CACF,EACD,EAAE,KAAK,EAAE,uBAAuB,EAAE,CACnC,CAAC"}
1
+ {"version":3,"file":"klarna.js","sourceRoot":"","sources":["../../src/plugins/klarna.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,OAAO,EAAE,QAAQ,EAA4B,MAAM,cAAc,CAAC;AAElE,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,cAAc,cAAc,CAAC;AAS7B,WAAW,CACT;IACE,QAAQ,CAAc,OAA6B;QACjD,OAAO,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACjC,CAAC;CACF,EACD,EAAE,KAAK,EAAE,uBAAuB,EAAE,CACnC,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import { type PayPalAmountOptions } from '../paypal.js';
2
2
  export * from '../paypal.js';
3
- declare module '../money.js' {
3
+ declare module '../index.js' {
4
4
  interface Money<C extends string> {
5
5
  /** The exact `value` string for PayPal: `money('1000', 'HUF').toPayPalValue()` is '1000'. */
6
6
  toPayPalValue(options?: PayPalAmountOptions): string;
@@ -1 +1 @@
1
- {"version":3,"file":"paypal.d.ts","sourceRoot":"","sources":["../../src/plugins/paypal.ts"],"names":[],"mappings":"AAKA,OAAO,EAA2B,KAAK,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAEjF,cAAc,cAAc,CAAC;AAE7B,OAAO,QAAQ,aAAa,CAAC;IAC3B,UAAU,KAAK,CAAC,CAAC,SAAS,MAAM;QAC9B,6FAA6F;QAC7F,aAAa,CAAC,OAAO,CAAC,EAAE,mBAAmB,GAAG,MAAM,CAAC;QACrD,2DAA2D;QAC3D,QAAQ,CAAC,OAAO,CAAC,EAAE,mBAAmB,GAAG;YAAE,aAAa,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC;KACnF;CACF"}
1
+ {"version":3,"file":"paypal.d.ts","sourceRoot":"","sources":["../../src/plugins/paypal.ts"],"names":[],"mappings":"AAMA,OAAO,EAA2B,KAAK,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAEjF,cAAc,cAAc,CAAC;AAE7B,OAAO,QAAQ,aAAa,CAAC;IAC3B,UAAU,KAAK,CAAC,CAAC,SAAS,MAAM;QAC9B,6FAA6F;QAC7F,aAAa,CAAC,OAAO,CAAC,EAAE,mBAAmB,GAAG,MAAM,CAAC;QACrD,2DAA2D;QAC3D,QAAQ,CAAC,OAAO,CAAC,EAAE,mBAAmB,GAAG;YAAE,aAAa,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC;KACnF;CACF"}
@@ -1,7 +1,3 @@
1
- /**
2
- * `@ducatjs/money/paypal`: PayPal's amount view. Importing this module adds `toPayPal` and
3
- * `toPayPalValue`.
4
- */
5
1
  import { extendMoney } from '../money.js';
6
2
  import { toPayPal, toPayPalValue } from '../paypal.js';
7
3
  export * from '../paypal.js';
@@ -1 +1 @@
1
- {"version":3,"file":"paypal.js","sourceRoot":"","sources":["../../src/plugins/paypal.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,WAAW,EAAc,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,aAAa,EAA4B,MAAM,cAAc,CAAC;AAEjF,cAAc,cAAc,CAAC;AAW7B,WAAW,CACT;IACE,aAAa,CAAc,OAA6B;QACtD,OAAO,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACtC,CAAC;IACD,QAAQ,CAAc,OAA6B;QACjD,OAAO,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACjC,CAAC;CACF,EACD,EAAE,KAAK,EAAE,uBAAuB,EAAE,CACnC,CAAC"}
1
+ {"version":3,"file":"paypal.js","sourceRoot":"","sources":["../../src/plugins/paypal.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,aAAa,EAA4B,MAAM,cAAc,CAAC;AAEjF,cAAc,cAAc,CAAC;AAW7B,WAAW,CACT;IACE,aAAa,CAAc,OAA6B;QACtD,OAAO,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACtC,CAAC;IACD,QAAQ,CAAc,OAA6B;QACjD,OAAO,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACjC,CAAC;CACF,EACD,EAAE,KAAK,EAAE,uBAAuB,EAAE,CACnC,CAAC"}
@@ -1,5 +1,5 @@
1
1
  export * from '../prisma.js';
2
- declare module '../money.js' {
2
+ declare module '../index.js' {
3
3
  interface Money<C extends string> {
4
4
  /** A Decimal for a NUMERIC column: `m.toDecimalValue(Prisma.Decimal)`. */
5
5
  toDecimalValue<D>(Decimal: new (value: string) => D): D;
@@ -1 +1 @@
1
- {"version":3,"file":"prisma.d.ts","sourceRoot":"","sources":["../../src/plugins/prisma.ts"],"names":[],"mappings":"AAOA,cAAc,cAAc,CAAC;AAE7B,OAAO,QAAQ,aAAa,CAAC;IAC3B,UAAU,KAAK,CAAC,CAAC,SAAS,MAAM;QAC9B,0EAA0E;QAC1E,cAAc,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;KACzD;CACF"}
1
+ {"version":3,"file":"prisma.d.ts","sourceRoot":"","sources":["../../src/plugins/prisma.ts"],"names":[],"mappings":"AAQA,cAAc,cAAc,CAAC;AAE7B,OAAO,QAAQ,aAAa,CAAC;IAC3B,UAAU,KAAK,CAAC,CAAC,SAAS,MAAM;QAC9B,0EAA0E;QAC1E,cAAc,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;KACzD;CACF"}
@@ -1,7 +1,3 @@
1
- /**
2
- * `@ducatjs/money/prisma`: Prisma and SQL column helpers. Importing this module adds
3
- * `toDecimalValue`.
4
- */
5
1
  import { extendMoney } from '../money.js';
6
2
  import { toDecimalValue } from '../prisma.js';
7
3
  export * from '../prisma.js';
@@ -1 +1 @@
1
- {"version":3,"file":"prisma.js","sourceRoot":"","sources":["../../src/plugins/prisma.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,WAAW,EAAc,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,cAAc,cAAc,CAAC;AAS7B,WAAW,CACT;IACE,cAAc,CAAc,OAAuC;QACjE,OAAO,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACvC,CAAC;CACF,EACD,EAAE,KAAK,EAAE,uBAAuB,EAAE,CACnC,CAAC"}
1
+ {"version":3,"file":"prisma.js","sourceRoot":"","sources":["../../src/plugins/prisma.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,cAAc,cAAc,CAAC;AAS7B,WAAW,CACT;IACE,cAAc,CAAc,OAAuC;QACjE,OAAO,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACvC,CAAC;CACF,EACD,EAAE,KAAK,EAAE,uBAAuB,EAAE,CACnC,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import { type StripeAmountOptions } from '../stripe.js';
2
2
  export * from '../stripe.js';
3
- declare module '../money.js' {
3
+ declare module '../index.js' {
4
4
  interface Money<C extends string> {
5
5
  /** The integer `amount` to send to Stripe: `money('5', 'ISK').toStripeAmount()` is 500. */
6
6
  toStripeAmount(options?: StripeAmountOptions): number;
@@ -1 +1 @@
1
- {"version":3,"file":"stripe.d.ts","sourceRoot":"","sources":["../../src/plugins/stripe.ts"],"names":[],"mappings":"AAKA,OAAO,EAA4B,KAAK,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAElF,cAAc,cAAc,CAAC;AAE7B,OAAO,QAAQ,aAAa,CAAC;IAC3B,UAAU,KAAK,CAAC,CAAC,SAAS,MAAM;QAC9B,2FAA2F;QAC3F,cAAc,CAAC,OAAO,CAAC,EAAE,mBAAmB,GAAG,MAAM,CAAC;QACtD,+FAA+F;QAC/F,QAAQ,CAAC,OAAO,CAAC,EAAE,mBAAmB,GAAG;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,MAAM,CAAA;SAAE,CAAC;KAC/E;CACF"}
1
+ {"version":3,"file":"stripe.d.ts","sourceRoot":"","sources":["../../src/plugins/stripe.ts"],"names":[],"mappings":"AAMA,OAAO,EAA4B,KAAK,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAElF,cAAc,cAAc,CAAC;AAE7B,OAAO,QAAQ,aAAa,CAAC;IAC3B,UAAU,KAAK,CAAC,CAAC,SAAS,MAAM;QAC9B,2FAA2F;QAC3F,cAAc,CAAC,OAAO,CAAC,EAAE,mBAAmB,GAAG,MAAM,CAAC;QACtD,+FAA+F;QAC/F,QAAQ,CAAC,OAAO,CAAC,EAAE,mBAAmB,GAAG;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,MAAM,CAAA;SAAE,CAAC;KAC/E;CACF"}
@@ -1,7 +1,3 @@
1
- /**
2
- * `@ducatjs/money/stripe`: Stripe's minor-unit view. Importing this module adds `toStripe` and
3
- * `toStripeAmount`.
4
- */
5
1
  import { extendMoney } from '../money.js';
6
2
  import { toStripe, toStripeAmount } from '../stripe.js';
7
3
  export * from '../stripe.js';
@@ -1 +1 @@
1
- {"version":3,"file":"stripe.js","sourceRoot":"","sources":["../../src/plugins/stripe.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,WAAW,EAAc,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,cAAc,EAA4B,MAAM,cAAc,CAAC;AAElF,cAAc,cAAc,CAAC;AAW7B,WAAW,CACT;IACE,cAAc,CAAc,OAA6B;QACvD,OAAO,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACvC,CAAC;IACD,QAAQ,CAAc,OAA6B;QACjD,OAAO,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACjC,CAAC;CACF,EACD,EAAE,KAAK,EAAE,uBAAuB,EAAE,CACnC,CAAC"}
1
+ {"version":3,"file":"stripe.js","sourceRoot":"","sources":["../../src/plugins/stripe.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,cAAc,EAA4B,MAAM,cAAc,CAAC;AAElF,cAAc,cAAc,CAAC;AAW7B,WAAW,CACT;IACE,cAAc,CAAc,OAA6B;QACvD,OAAO,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACvC,CAAC;IACD,QAAQ,CAAc,OAA6B;QACjD,OAAO,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACjC,CAAC;CACF,EACD,EAAE,KAAK,EAAE,uBAAuB,EAAE,CACnC,CAAC"}
@@ -3,19 +3,19 @@
3
3
  * methods below.
4
4
  */
5
5
  import type { Factor } from '../decimal.js';
6
- import type { RoundingMode } from '../rounding.js';
6
+ import { type RoundingInput } from '../money.js';
7
7
  import { type TaxBreakdown } from '../tax.js';
8
8
  export * from '../tax.js';
9
- declare module '../money.js' {
9
+ declare module '../index.js' {
10
10
  interface Money<C extends string> {
11
11
  /** `percent`% of this, e.g. `price.percentage(15, 'halfEven')` */
12
- percentage(percent: Factor, rounding?: RoundingMode): Money<C>;
12
+ percentage(percent: Factor, rounding?: RoundingInput): Money<C>;
13
13
  /** this minus `percent`% */
14
- discount(percent: Factor, rounding?: RoundingMode): Money<C>;
14
+ discount(percent: Factor, rounding?: RoundingInput): Money<C>;
15
15
  /** Treats this as net: `{ net, tax, gross }`, net + tax = gross exactly. */
16
- addTax(percent: Factor, rounding?: RoundingMode): TaxBreakdown<C>;
16
+ addTax(percent: Factor, rounding?: RoundingInput): TaxBreakdown<C>;
17
17
  /** Treats this as gross: `{ net, tax, gross }`, net + tax = gross exactly. */
18
- extractTax(percent: Factor, rounding?: RoundingMode): TaxBreakdown<C>;
18
+ extractTax(percent: Factor, rounding?: RoundingInput): TaxBreakdown<C>;
19
19
  }
20
20
  }
21
21
  //# sourceMappingURL=tax.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tax.d.ts","sourceRoot":"","sources":["../../src/plugins/tax.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAA4C,KAAK,YAAY,EAAE,MAAM,WAAW,CAAC;AAExF,cAAc,WAAW,CAAC;AAE1B,OAAO,QAAQ,aAAa,CAAC;IAC3B,UAAU,KAAK,CAAC,CAAC,SAAS,MAAM;QAC9B,kEAAkE;QAClE,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,YAAY,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAC/D,4BAA4B;QAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,YAAY,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAC7D,4EAA4E;QAC5E,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,YAAY,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;QAClE,8EAA8E;QAC9E,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,YAAY,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;KACvE;CACF"}
1
+ {"version":3,"file":"tax.d.ts","sourceRoot":"","sources":["../../src/plugins/tax.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,EAAe,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAA4C,KAAK,YAAY,EAAE,MAAM,WAAW,CAAC;AAExF,cAAc,WAAW,CAAC;AAE1B,OAAO,QAAQ,aAAa,CAAC;IAC3B,UAAU,KAAK,CAAC,CAAC,SAAS,MAAM;QAC9B,kEAAkE;QAClE,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,aAAa,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAChE,4BAA4B;QAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,aAAa,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAC9D,4EAA4E;QAC5E,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,aAAa,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;QACnE,8EAA8E;QAC9E,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,aAAa,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;KACxE;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"tax.js","sourceRoot":"","sources":["../../src/plugins/tax.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAAc,MAAM,aAAa,CAAC;AAEtD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAqB,MAAM,WAAW,CAAC;AAExF,cAAc,WAAW,CAAC;AAe1B,WAAW,CACT;IACE,UAAU,CAAc,OAAe,EAAE,QAAuB;QAC9D,OAAO,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC7C,CAAC;IACD,QAAQ,CAAc,OAAe,EAAE,QAAuB;QAC5D,OAAO,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC3C,CAAC;IACD,MAAM,CAAc,OAAe,EAAE,QAAuB;QAC1D,OAAO,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;IACzC,CAAC;IACD,UAAU,CAAc,OAAe,EAAE,QAAuB;QAC9D,OAAO,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC7C,CAAC;CACF,EACD,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAChC,CAAC"}
1
+ {"version":3,"file":"tax.js","sourceRoot":"","sources":["../../src/plugins/tax.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,WAAW,EAAsB,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAqB,MAAM,WAAW,CAAC;AAExF,cAAc,WAAW,CAAC;AAe1B,WAAW,CACT;IACE,UAAU,CAAc,OAAe,EAAE,QAAwB;QAC/D,OAAO,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC7C,CAAC;IACD,QAAQ,CAAc,OAAe,EAAE,QAAwB;QAC7D,OAAO,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC3C,CAAC;IACD,MAAM,CAAc,OAAe,EAAE,QAAwB;QAC3D,OAAO,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;IACzC,CAAC;IACD,UAAU,CAAc,OAAe,EAAE,QAAwB;QAC/D,OAAO,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC7C,CAAC;CACF,EACD,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAChC,CAAC"}
@@ -0,0 +1,34 @@
1
+ import { type Money, type RoundingPolicy } from './money.js';
2
+ import { type RoundingMode } from './rounding.js';
3
+ export type { RoundingInput, RoundingPolicy } from './money.js';
4
+ /** Options for `roundingPolicy`. Every field is optional. */
5
+ export interface RoundingPolicyOptions {
6
+ /** Decimal places of the result (default: the currency's ISO exponent). */
7
+ readonly scale?: number;
8
+ /** A positive safe integer count of 10^-scale units to round to (default 1). */
9
+ readonly increment?: number;
10
+ /** The rounding mode (default 'halfExpand'). */
11
+ readonly rounding?: RoundingMode;
12
+ /** Restrict the policy to one currency. */
13
+ readonly currency?: string;
14
+ }
15
+ /**
16
+ * Builds a reusable rounding policy (see `RoundingPolicy`). The options are checked here, once, so
17
+ * applying the policy needs no checks.
18
+ *
19
+ * const unitPrice = roundingPolicy({ scale: 4, rounding: 'halfEven' })
20
+ * const fiveCents = roundingPolicy({ increment: 5 }) // 0.05 in a 2-decimal currency
21
+ */
22
+ export declare function roundingPolicy(options?: RoundingPolicyOptions): RoundingPolicy;
23
+ /**
24
+ * Rounding to the currency's ISO exponent, half up: the policy most amounts should end with.
25
+ * `assertScale(m, isoPolicy)` checks that an amount is already there.
26
+ */
27
+ export declare const isoPolicy: RoundingPolicy;
28
+ /**
29
+ * Throws a RangeError unless `money` is exactly what `policy` produces: at the policy's scale and a
30
+ * multiple of its increment (and in its currency, if it has one). Use it where an amount must
31
+ * already be rounded, such as before booking it or sending it to a processor.
32
+ */
33
+ export declare function assertScale(money: Money, policy: RoundingPolicy): void;
34
+ //# sourceMappingURL=policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"AAQA,OAAO,EAML,KAAK,KAAK,EACV,KAAK,cAAc,EACpB,MAAM,YAAY,CAAC;AACpB,OAAO,EAA8B,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAE9E,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEhE,6DAA6D;AAC7D,MAAM,WAAW,qBAAqB;IACpC,2EAA2E;IAC3E,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,gFAAgF;IAChF,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,gDAAgD;IAChD,QAAQ,CAAC,QAAQ,CAAC,EAAE,YAAY,CAAC;IACjC,2CAA2C;IAC3C,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAKD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,OAAO,GAAE,qBAA0B,GAAG,cAAc,CAoDlF;AAED;;;GAGG;AACH,eAAO,MAAM,SAAS,EAAE,cAAiD,CAAC;AAE1E;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,cAAc,GAAG,IAAI,CAetE"}
package/dist/policy.js ADDED
@@ -0,0 +1,90 @@
1
+ /**
2
+ * `@ducatjs/money/policy`: rounding policies, reusable values for a scale, an increment and a
3
+ * rounding mode ("CHF cash", "4 decimals, half even"), accepted wherever a rounding mode is. The
4
+ * core only hands the work to the policy, so none of this code is in a bundle that never imports
5
+ * this entry (or `cashPolicy` from `@ducatjs/money/cash`).
6
+ */
7
+ import { currencyExponent, isCurrency } from './currency.js';
8
+ import { MAX_DECIMAL_SCALE } from './decimal.js';
9
+ import { CurrencyMismatchError, multiply, multiplyByRatio, ratio, ROUND_PRODUCT, } from './money.js';
10
+ import { DEFAULT_ROUNDING, Rounding } from './rounding.js';
11
+ const ONE = ratio(1);
12
+ const MODES = new Set(Object.values(Rounding));
13
+ /**
14
+ * Builds a reusable rounding policy (see `RoundingPolicy`). The options are checked here, once, so
15
+ * applying the policy needs no checks.
16
+ *
17
+ * const unitPrice = roundingPolicy({ scale: 4, rounding: 'halfEven' })
18
+ * const fiveCents = roundingPolicy({ increment: 5 }) // 0.05 in a 2-decimal currency
19
+ */
20
+ export function roundingPolicy(options = {}) {
21
+ const scale = options.scale;
22
+ const increment = options.increment ?? 1;
23
+ const rounding = options.rounding ?? DEFAULT_ROUNDING;
24
+ const currency = options.currency;
25
+ if (scale !== undefined &&
26
+ !(Number.isInteger(scale) && scale >= 0 && scale <= MAX_DECIMAL_SCALE)) {
27
+ throw new RangeError(`Invalid scale ${scale}`);
28
+ }
29
+ if (!(Number.isSafeInteger(increment) && increment >= 1)) {
30
+ throw new RangeError(`Invalid increment ${increment}; it must be a positive integer`);
31
+ }
32
+ if (!MODES.has(rounding)) {
33
+ throw new RangeError(`Invalid rounding mode ${String(rounding)}`);
34
+ }
35
+ // A typo such as 'chf' would otherwise make a policy that rejects every amount.
36
+ if (currency !== undefined && !isCurrency(currency)) {
37
+ throw new RangeError(`Unknown currency ${currency}`);
38
+ }
39
+ const incrementAsBigint = BigInt(increment);
40
+ // money × factor rounded once to the policy: with an increment, count whole increments
41
+ // (money × factor / increment, rounded at the policy's scale) and multiply back, which is
42
+ // rounding to the nearest multiple of the increment. The count's ratio is left unreduced: the
43
+ // division rounds the same either way, and a gcd per call would cost more than it saves.
44
+ const roundProduct = (money, factor) => {
45
+ if (currency !== undefined && currency !== money.currency) {
46
+ throw new CurrencyMismatchError(currency, money.currency);
47
+ }
48
+ const resultScale = scale ?? currencyExponent(money.currency);
49
+ if (increment === 1) {
50
+ return multiplyByRatio(money, factor, rounding, resultScale);
51
+ }
52
+ const stepDenominator = factor.d * increment;
53
+ const perStep = {
54
+ num: factor.num,
55
+ den: factor.den * incrementAsBigint,
56
+ n: factor.n,
57
+ // NaN (not a safe integer) sends multiplyByRatio down its bigint path
58
+ d: Number.isSafeInteger(stepDenominator) ? stepDenominator : NaN,
59
+ };
60
+ return multiply(multiplyByRatio(money, perStep, rounding, resultScale), increment);
61
+ };
62
+ const policy = (money) => roundProduct(money, ONE);
63
+ return Object.freeze(Object.assign(policy, { scale, increment, rounding, currency, [ROUND_PRODUCT]: roundProduct }));
64
+ }
65
+ /**
66
+ * Rounding to the currency's ISO exponent, half up: the policy most amounts should end with.
67
+ * `assertScale(m, isoPolicy)` checks that an amount is already there.
68
+ */
69
+ export const isoPolicy = /* @__PURE__ */ roundingPolicy();
70
+ /**
71
+ * Throws a RangeError unless `money` is exactly what `policy` produces: at the policy's scale and a
72
+ * multiple of its increment (and in its currency, if it has one). Use it where an amount must
73
+ * already be rounded, such as before booking it or sending it to a processor.
74
+ */
75
+ export function assertScale(money, policy) {
76
+ if (policy.currency !== undefined && policy.currency !== money.currency) {
77
+ throw new CurrencyMismatchError(policy.currency, money.currency);
78
+ }
79
+ const scale = policy.scale ?? currencyExponent(money.currency);
80
+ if (money.scale !== scale) {
81
+ throw new RangeError(`${money} has scale ${money.scale}, expected ${scale}`);
82
+ }
83
+ const minor = money.minor;
84
+ const increment = policy.increment;
85
+ const isMultiple = typeof minor === 'number' ? minor % increment === 0 : minor % BigInt(increment) === 0n;
86
+ if (!isMultiple) {
87
+ throw new RangeError(`${money} is not a multiple of ${increment} at scale ${scale}`);
88
+ }
89
+ }
90
+ //# sourceMappingURL=policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.js","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAc,MAAM,cAAc,CAAC;AAC7D,OAAO,EACL,qBAAqB,EACrB,QAAQ,EACR,eAAe,EACf,KAAK,EACL,aAAa,GAGd,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAqB,MAAM,eAAe,CAAC;AAgB9E,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;AACrB,MAAM,KAAK,GAAG,IAAI,GAAG,CAAU,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;AAExD;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,UAAiC,EAAE;IAChE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IAC5B,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,CAAC,CAAC;IACzC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,gBAAgB,CAAC;IACtD,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAElC,IACE,KAAK,KAAK,SAAS;QACnB,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,IAAI,iBAAiB,CAAC,EACtE,CAAC;QACD,MAAM,IAAI,UAAU,CAAC,iBAAiB,KAAK,EAAE,CAAC,CAAC;IACjD,CAAC;IACD,IAAI,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,IAAI,SAAS,IAAI,CAAC,CAAC,EAAE,CAAC;QACzD,MAAM,IAAI,UAAU,CAAC,qBAAqB,SAAS,iCAAiC,CAAC,CAAC;IACxF,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,UAAU,CAAC,yBAAyB,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IACpE,CAAC;IACD,gFAAgF;IAChF,IAAI,QAAQ,KAAK,SAAS,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACpD,MAAM,IAAI,UAAU,CAAC,oBAAoB,QAAQ,EAAE,CAAC,CAAC;IACvD,CAAC;IAED,MAAM,iBAAiB,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;IAE5C,uFAAuF;IACvF,0FAA0F;IAC1F,8FAA8F;IAC9F,yFAAyF;IACzF,MAAM,YAAY,GAAG,CAAmB,KAAe,EAAE,MAAa,EAAY,EAAE;QAClF,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,KAAK,CAAC,QAAQ,EAAE,CAAC;YAC1D,MAAM,IAAI,qBAAqB,CAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC5D,CAAC;QACD,MAAM,WAAW,GAAG,KAAK,IAAI,gBAAgB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC9D,IAAI,SAAS,KAAK,CAAC,EAAE,CAAC;YACpB,OAAO,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;QAC/D,CAAC;QACD,MAAM,eAAe,GAAG,MAAM,CAAC,CAAC,GAAG,SAAS,CAAC;QAC7C,MAAM,OAAO,GAAU;YACrB,GAAG,EAAE,MAAM,CAAC,GAAG;YACf,GAAG,EAAE,MAAM,CAAC,GAAG,GAAG,iBAAiB;YACnC,CAAC,EAAE,MAAM,CAAC,CAAC;YACX,sEAAsE;YACtE,CAAC,EAAE,MAAM,CAAC,aAAa,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,GAAG;SACjE,CAAC;QACF,OAAO,QAAQ,CAAC,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,CAAC,EAAE,SAAS,CAAC,CAAC;IACrF,CAAC,CAAC;IAEF,MAAM,MAAM,GAAG,CAAmB,KAAe,EAAY,EAAE,CAAC,YAAY,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACzF,OAAO,MAAM,CAAC,MAAM,CAClB,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC,CAC/F,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,SAAS,GAAmB,eAAe,CAAC,cAAc,EAAE,CAAC;AAE1E;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,KAAY,EAAE,MAAsB;IAC9D,IAAI,MAAM,CAAC,QAAQ,KAAK,SAAS,IAAI,MAAM,CAAC,QAAQ,KAAK,KAAK,CAAC,QAAQ,EAAE,CAAC;QACxE,MAAM,IAAI,qBAAqB,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;IACnE,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,gBAAgB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC/D,IAAI,KAAK,CAAC,KAAK,KAAK,KAAK,EAAE,CAAC;QAC1B,MAAM,IAAI,UAAU,CAAC,GAAG,KAAK,cAAc,KAAK,CAAC,KAAK,cAAc,KAAK,EAAE,CAAC,CAAC;IAC/E,CAAC;IACD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IAC1B,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;IACnC,MAAM,UAAU,GACd,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,GAAG,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;IACzF,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,UAAU,CAAC,GAAG,KAAK,yBAAyB,SAAS,aAAa,KAAK,EAAE,CAAC,CAAC;IACvF,CAAC;AACH,CAAC"}
package/dist/prisma.d.ts CHANGED
@@ -1,13 +1,3 @@
1
- /**
2
- * Prisma / SQL interop with no dependency on @prisma/client (works with any Decimal class that has
3
- * toFixed(): Prisma.Decimal, decimal.js, big.js).
4
- *
5
- * Storage options (see README "Databases"):
6
- * 1. two columns: amount_minor BIGINT + currency CHAR(3)
7
- * -> minorMoneyField / toMinorColumns
8
- * 2. a DECIMAL/NUMERIC column (+ a currency column or constant)
9
- * -> decimalMoneyField / toDecimalValue
10
- */
11
1
  import { type CurrencyInput, type Money, type MoneyOptions } from './money.js';
12
2
  /** Structural type of Prisma.Decimal / decimal.js / big.js values. */
13
3
  export interface DecimalLike {
@@ -23,19 +13,38 @@ export declare function toDecimalValue<D>(money: Money, Decimal: new (value: str
23
13
  type Row<A extends string, V> = {
24
14
  [P in A]: V;
25
15
  };
16
+ /** Options for `minorMoneyField` and `toMinorColumns`: a column that records each amount's scale. */
17
+ export interface ScaleColumnOption<S extends string> {
18
+ /**
19
+ * The integer column holding the number of decimals the minor units are counted in (2 for
20
+ * cents). With it, any scale round-trips, and stored amounts keep their meaning even if a
21
+ * currency's exponent changes.
22
+ */
23
+ readonly scale: S;
24
+ }
26
25
  /**
27
26
  * A Prisma result-extension field that exposes a Money built from `amount_minor` + `currency`
28
- * columns:
27
+ * columns, and optionally a scale column:
29
28
  *
30
29
  * const db = new PrismaClient().$extends({
31
30
  * result: { order: { total: minorMoneyField('totalMinor', 'currency') } },
32
31
  * });
33
32
  * (await db.order.findFirstOrThrow()).total // Money
33
+ *
34
+ * Without a scale column the minor units are read at the currency's current exponent.
34
35
  */
35
36
  export declare function minorMoneyField<const A extends string, const K extends string>(amount: A, currency: K): {
36
- needs: { [P in A | K]: true; };
37
+ needs: {
38
+ [P in A | K]: true;
39
+ };
37
40
  compute: (row: Row<A, bigint | number> & Row<K, string>) => Money;
38
41
  };
42
+ export declare function minorMoneyField<const A extends string, const K extends string, const S extends string>(amount: A, currency: K, options: ScaleColumnOption<S>): {
43
+ needs: {
44
+ [P in A | K | S]: true;
45
+ };
46
+ compute: (row: Row<A, bigint | number> & Row<K, string> & Row<S, bigint | number>) => Money;
47
+ };
39
48
  /**
40
49
  * A Prisma result-extension field for a Decimal column, with the currency taken from another column
41
50
  * (`{ currencyField: 'currency' }`) or fixed (`{ currency: 'EUR' }`).
@@ -58,9 +67,11 @@ export declare function decimalMoneyField<const A extends string, const C extend
58
67
  };
59
68
  /**
60
69
  * Column values for writes: `data: { ...toMinorColumns(total, 'totalMinor', 'currency') }`.
61
- * Minor units are a bigint (Prisma BigInt). Throws if the value has a non-standard scale, because
62
- * the column cannot record it.
70
+ * Minor units are a bigint (Prisma BigInt). Without a scale column, throws if the value has a
71
+ * non-standard scale, because the columns cannot record it. With `{ scale: 'amountScale' }`, any
72
+ * scale is stored, next to the minor units it counts.
63
73
  */
64
74
  export declare function toMinorColumns<const A extends string, const K extends string>(money: Money, amount: A, currency: K): Row<A, bigint> & Row<K, string>;
75
+ export declare function toMinorColumns<const A extends string, const K extends string, const S extends string>(money: Money, amount: A, currency: K, options: ScaleColumnOption<S>): Row<A, bigint> & Row<K, string> & Row<S, number>;
65
76
  export {};
66
77
  //# sourceMappingURL=prisma.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"prisma.d.ts","sourceRoot":"","sources":["../src/prisma.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAKL,KAAK,aAAa,EAClB,KAAK,KAAK,EACV,KAAK,YAAY,EAClB,MAAM,YAAY,CAAC;AAEpB,sEAAsE;AACtE,MAAM,WAAW,WAAW;IAC1B,OAAO,IAAI,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,aAAa,EACjD,KAAK,EAAE,WAAW,GAAG,MAAM,EAC3B,QAAQ,EAAE,CAAC,EACX,OAAO,CAAC,EAAE,YAAY,GACrB,KAAK,CAAC,CAAC,CAAC,CAEV;AAED,yEAAyE;AACzE,wBAAgB,cAAc,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,KAAK,CAAC,GAAG,CAAC,CAEpF;AAED,KAAK,GAAG,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,IAAI;KAAG,CAAC,IAAI,CAAC,GAAG,CAAC;CAAE,CAAC;AAEhD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,KAAK,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,CAAC,CAAC,SAAS,MAAM,EAC5E,MAAM,EAAE,CAAC,EACT,QAAQ,EAAE,CAAC;WAGsC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,GAAE;mBACtD,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,KAAG,KAAK;EAGlE;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,CAAC,CAAC,SAAS,MAAM,EAC9E,MAAM,EAAE,CAAC,EACT,QAAQ,EAAE;IAAE,aAAa,EAAE,CAAC,CAAA;CAAE,GAC7B;IAAE,KAAK,EAAE;SAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI;KAAE,CAAC;IAAC,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,EAAE,WAAW,CAAC,GAAG,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,KAAK,KAAK,CAAA;CAAE,CAAC;AACpG,wBAAgB,iBAAiB,CAAC,KAAK,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,CAAC,CAAC,SAAS,aAAa,EACrF,MAAM,EAAE,CAAC,EACT,QAAQ,EAAE;IAAE,QAAQ,EAAE,CAAC,CAAA;CAAE,GACxB;IAAE,KAAK,EAAE;SAAG,CAAC,IAAI,CAAC,GAAG,IAAI;KAAE,CAAC;IAAC,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,EAAE,WAAW,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,CAAA;CAAE,CAAC;AAoBlF;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,CAAC,CAAC,SAAS,MAAM,EAC3E,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,CAAC,EACT,QAAQ,EAAE,CAAC,GACV,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAGjC"}
1
+ {"version":3,"file":"prisma.d.ts","sourceRoot":"","sources":["../src/prisma.ts"],"names":[],"mappings":"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"}
package/dist/prisma.js CHANGED
@@ -8,6 +8,7 @@
8
8
  * 2. a DECIMAL/NUMERIC column (+ a currency column or constant)
9
9
  * -> decimalMoneyField / toDecimalValue
10
10
  */
11
+ import { MAX_DECIMAL_SCALE } from './decimal.js';
11
12
  import { fromMinor, money, toDecimal, toMinor, } from './money.js';
12
13
  /**
13
14
  * Money from a Decimal (or decimal string) column. Exact; throws if it has more decimals than the
@@ -20,19 +21,30 @@ export function fromDecimal(value, currency, options) {
20
21
  export function toDecimalValue(money, Decimal) {
21
22
  return new Decimal(toDecimal(money));
22
23
  }
23
- /**
24
- * A Prisma result-extension field that exposes a Money built from `amount_minor` + `currency`
25
- * columns:
26
- *
27
- * const db = new PrismaClient().$extends({
28
- * result: { order: { total: minorMoneyField('totalMinor', 'currency') } },
29
- * });
30
- * (await db.order.findFirstOrThrow()).total // Money
31
- */
32
- export function minorMoneyField(amount, currency) {
24
+ /** A scale read from a row: a safe, non-negative integer (a SMALLINT or INT column). */
25
+ function readScale(value, column) {
26
+ const scale = typeof value === 'bigint' ? Number(value) : value;
27
+ // capped like parsed decimals: a corrupt row must not make toDecimal build a huge power of ten
28
+ const isValid = typeof scale === 'number' &&
29
+ Number.isInteger(scale) &&
30
+ scale >= 0 &&
31
+ scale <= MAX_DECIMAL_SCALE;
32
+ if (!isValid) {
33
+ throw new RangeError(`Expected an integer scale from 0 to ${MAX_DECIMAL_SCALE} in "${column}", got ${String(value)}`);
34
+ }
35
+ return scale;
36
+ }
37
+ export function minorMoneyField(amount, currency, options) {
38
+ if (options === undefined) {
39
+ return {
40
+ needs: { [amount]: true, [currency]: true },
41
+ compute: (row) => fromMinor(row[amount], row[currency]),
42
+ };
43
+ }
44
+ const scaleColumn = options.scale;
33
45
  return {
34
- needs: { [amount]: true, [currency]: true },
35
- compute: (row) => fromMinor(row[amount], row[currency]),
46
+ needs: { [amount]: true, [currency]: true, [scaleColumn]: true },
47
+ compute: (row) => fromMinor(row[amount], row[currency], readScale(row[scaleColumn], scaleColumn)),
36
48
  };
37
49
  }
38
50
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -48,13 +60,11 @@ export function decimalMoneyField(amount, currencySource) {
48
60
  compute: (row) => fromDecimal(row[amount], currencySource.currency),
49
61
  };
50
62
  }
51
- /**
52
- * Column values for writes: `data: { ...toMinorColumns(total, 'totalMinor', 'currency') }`.
53
- * Minor units are a bigint (Prisma BigInt). Throws if the value has a non-standard scale, because
54
- * the column cannot record it.
55
- */
56
- export function toMinorColumns(money, amount, currency) {
57
- return { [amount]: toMinorAtIsoScale(money), [currency]: money.currency };
63
+ export function toMinorColumns(money, amount, currency, options) {
64
+ if (options === undefined) {
65
+ return { [amount]: toMinorAtIsoScale(money), [currency]: money.currency };
66
+ }
67
+ return { [amount]: toMinor(money), [currency]: money.currency, [options.scale]: money.scale };
58
68
  }
59
69
  function toMinorAtIsoScale(money) {
60
70
  const iso = fromMinor(0, money.currency).scale;
@@ -1 +1 @@
1
- {"version":3,"file":"prisma.js","sourceRoot":"","sources":["../src/prisma.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EACL,SAAS,EACT,KAAK,EACL,SAAS,EACT,OAAO,GAIR,MAAM,YAAY,CAAC;AAOpB;;;GAGG;AACH,MAAM,UAAU,WAAW,CACzB,KAA2B,EAC3B,QAAW,EACX,OAAsB;IAEtB,OAAO,KAAK,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;AACvF,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,cAAc,CAAI,KAAY,EAAE,OAAiC;IAC/E,OAAO,IAAI,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;AACvC,CAAC;AAID;;;;;;;;GAQG;AACH,MAAM,UAAU,eAAe,CAC7B,MAAS,EACT,QAAW;IAEX,OAAO;QACL,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,QAAQ,CAAC,EAAE,IAAI,EAA4B;QACrE,OAAO,EAAE,CAAC,GAA6C,EAAS,EAAE,CAChE,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;KACxC,CAAC;AACJ,CAAC;AAcD,8DAA8D;AAC9D,MAAM,UAAU,iBAAiB,CAC/B,MAAc,EACd,cAAgE;IAEhE,IAAI,eAAe,IAAI,cAAc,EAAE,CAAC;QACtC,OAAO;YACL,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,cAAc,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE;YAC/D,OAAO,EAAE,CAAC,GAA4B,EAAE,EAAE,CACxC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAgB,EAAE,GAAG,CAAC,cAAc,CAAC,aAAa,CAAW,CAAC;SACvF,CAAC;IACJ,CAAC;IACD,OAAO;QACL,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE;QACzB,OAAO,EAAE,CAAC,GAA4B,EAAE,EAAE,CACxC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAgB,EAAE,cAAc,CAAC,QAAQ,CAAC;KACnE,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAC5B,KAAY,EACZ,MAAS,EACT,QAAW;IAEX,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,QAAQ,EACvD,CAAC;AACnB,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAY;IACrC,MAAM,GAAG,GAAG,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC;IAC/C,IAAI,KAAK,CAAC,KAAK,KAAK,GAAG,EAAE,CAAC;QACxB,MAAM,IAAI,UAAU,CAClB,GAAG,KAAK,cAAc,KAAK,CAAC,KAAK,mBAAmB,GAAG,sCAAsC,CAC9F,CAAC;IACJ,CAAC;IACD,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC;AACxB,CAAC"}
1
+ {"version":3,"file":"prisma.js","sourceRoot":"","sources":["../src/prisma.ts"],"names":[],"mappings":"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"}
@@ -16,6 +16,12 @@ export interface RateTable extends RateProvider {
16
16
  readonly base?: string;
17
17
  /** The table's date, when it has one. */
18
18
  readonly asOf?: string;
19
+ /** When the table was published, when that is known. */
20
+ readonly availableAt?: string;
21
+ /** The last day (or instant) the table applies to, for a table valid for a period. */
22
+ readonly validUntil?: string;
23
+ /** Currencies the source listed without a value (holidays, `ND`, `N/A`). */
24
+ readonly missing?: readonly string[];
19
25
  }
20
26
  /** Thrown when no provider has a rate for the pair. */
21
27
  export declare class RateUnavailableError extends Error {
@@ -28,18 +34,24 @@ export declare class RateUnavailableError extends Error {
28
34
  export declare function rateOf<From extends string, To extends string>(provider: RateProvider, from: From, to: To, query?: RateQuery): Rate<From, To>;
29
35
  /** 1:1 for a currency to itself; nothing otherwise. */
30
36
  export declare function identity(): RateProvider;
31
- /** A one-base table: `rates.USD` is the number of USD per 1 `base`. */
32
- export interface RateTableSpec extends RateInfo {
37
+ /**
38
+ * A one-base table: `rates.USD` is the number of USD per 1 `base` (or a base → USD Rate), or null
39
+ * when the source has no value for the day. For rates published the other way round or per 100
40
+ * units, see `quotedTable` in `@ducatjs/money/convert/history`.
41
+ */
42
+ export interface RateTableSpec extends Omit<RateInfo, 'quote'> {
33
43
  readonly base: string;
34
- readonly rates: Readonly<Record<string, Factor>>;
44
+ readonly rates: Readonly<Record<string, Factor | Rate | null>>;
35
45
  }
36
46
  /**
37
47
  * A fixed table of rates: one base currency against many (ECB style), or a list of Rates. Only the
38
48
  * pairs given are answered; wrap it in `reversed()` or `via()` for the others.
39
49
  *
40
- * Lookups are by whole UTC day: a query for a day before a rate's asOf gets nothing, and a query at
41
- * any time on the rate's own day gets the rate, even before its publication time (the ECB publishes
42
- * at about 15:00 UTC). If that matters, query with the previous day until the table is published.
50
+ * A query with an `asOf` gets nothing from a rate that doesn't apply then: one dated after it, one
51
+ * published (`availableAt`) after it, or one whose `validUntil` has passed. Days are UTC days, and
52
+ * a date query covers the whole day: without an `availableAt`, a query at any time on the rate's
53
+ * own day gets the rate, even before the source published it (the ECB publishes at about 15:00
54
+ * UTC). Give `availableAt` to rule that out.
43
55
  *
44
56
  * const ecb = rateTable({ base: 'EUR', source: 'ECB', asOf: '2026-11-06', rates: { USD: '1.1165' } });
45
57
  */
@@ -73,7 +85,9 @@ export interface Snapshots {
73
85
  * undefined when there is none. Days are UTC days. Loaded tables are cached by day. Misses and
74
86
  * failures are not cached, so a table that isn't published yet is tried again next time. A loader
75
87
  * that throws fails the lookup rather than falling back to an older day, so an outage doesn't
76
- * silently become a stale rate. The rates carry the day they're from.
88
+ * silently become a stale rate. The rates carry the day they're from. A table with an
89
+ * `availableAt` after an instant asked for is passed over, so a lookup at 09:00 on a publication
90
+ * day gets the day before.
77
91
  *
78
92
  * const history = snapshots(async (day) => parseEcbXml(await readFile(`ecb/${day}.xml`, 'utf8'))[0]);
79
93
  * const fx = await history.at('2026-11-08'); // a Sunday: Friday 2026-11-06's table
@@ -1 +1 @@
1
- {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,EAML,KAAK,IAAI,EACT,KAAK,QAAQ,EACd,MAAM,WAAW,CAAC;AAInB,iCAAiC;AACjC,MAAM,WAAW,SAAS;IACxB,8CAA8C;IAC9C,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED,gGAAgG;AAChG,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,IAAI,SAAS,MAAM,EAAE,EAAE,SAAS,MAAM,EACzC,IAAI,EAAE,IAAI,EACV,EAAE,EAAE,EAAE,EACN,KAAK,CAAC,EAAE,SAAS,GAChB,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,SAAS,CAAC;CAC/B;AAED,kGAAkG;AAClG,MAAM,WAAW,SAAU,SAAQ,YAAY;IAC7C,QAAQ,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,CAAC;IAChC,iDAAiD;IACjD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,yCAAyC;IACzC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,wDAAwD;IACxD,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,sFAAsF;IACtF,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,4EAA4E;IAC5E,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC;AAED,uDAAuD;AACvD,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;gBAEtB,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;CAe3D;AAOD,kFAAkF;AAClF,wBAAgB,MAAM,CAAC,IAAI,SAAS,MAAM,EAAE,EAAE,SAAS,MAAM,EAC3D,QAAQ,EAAE,YAAY,EACtB,IAAI,EAAE,IAAI,EACV,EAAE,EAAE,EAAE,EACN,KAAK,CAAC,EAAE,SAAS,GAChB,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAehB;AAED,uDAAuD;AACvD,wBAAgB,QAAQ,IAAI,YAAY,CAUvC;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAc,SAAQ,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC5D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC;CAChE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,aAAa,GAAG,SAAS,IAAI,EAAE,GAAG,SAAS,CAgE1E;AAoBD,iEAAiE;AACjE,wBAAgB,KAAK,CAAC,GAAG,SAAS,EAAE,SAAS,YAAY,EAAE,GAAG,YAAY,CAYzE;AAED,qFAAqF;AACrF,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,YAAY,GAAG,YAAY,CAM7D;AAED;;;GAGG;AACH,wBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,YAAY,CA6BtE;AAED,+BAA+B;AAC/B,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,qFAAqF;IACrF,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,sCAAsC;AACtC,MAAM,WAAW,SAAS;IACxB,gGAAgG;IAChG,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CAChD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,EACxD,OAAO,CAAC,EAAE,eAAe,GACxB,SAAS,CAgEX;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,SAAS,CAQhG"}