@ducatjs/money 0.0.0 → 0.2.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 (398) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE +51 -0
  3. package/README.md +1034 -3
  4. package/assets/CREDITS.md +12 -0
  5. package/data/adyen-fx.json +19 -0
  6. package/data/adyen.json +171 -0
  7. package/data/braintree.json +223 -0
  8. package/data/cash-rounding.json +520 -0
  9. package/data/checkout.json +230 -0
  10. package/data/cldr-cash.json +101 -0
  11. package/data/historic.json +78 -0
  12. package/data/iso4217-list-one.xml +1956 -0
  13. package/data/iso4217-list-three.xml +1185 -0
  14. package/data/klarna.json +95 -0
  15. package/data/paypal.json +65 -0
  16. package/data/stripe-fx.json +17 -0
  17. package/data/stripe.json +285 -0
  18. package/dist/adyen-fx.d.ts +25 -0
  19. package/dist/adyen-fx.d.ts.map +1 -0
  20. package/dist/adyen-fx.js +140 -0
  21. package/dist/adyen-fx.js.map +1 -0
  22. package/dist/adyen.d.ts +25 -0
  23. package/dist/adyen.d.ts.map +1 -0
  24. package/dist/adyen.js +34 -0
  25. package/dist/adyen.js.map +1 -0
  26. package/dist/allocate.d.ts +72 -0
  27. package/dist/allocate.d.ts.map +1 -0
  28. package/dist/allocate.js +314 -0
  29. package/dist/allocate.js.map +1 -0
  30. package/dist/bag.d.ts +58 -0
  31. package/dist/bag.d.ts.map +1 -0
  32. package/dist/bag.js +122 -0
  33. package/dist/bag.js.map +1 -0
  34. package/dist/boc.d.ts +31 -0
  35. package/dist/boc.d.ts.map +1 -0
  36. package/dist/boc.js +114 -0
  37. package/dist/boc.js.map +1 -0
  38. package/dist/boe.d.ts +33 -0
  39. package/dist/boe.d.ts.map +1 -0
  40. package/dist/boe.js +114 -0
  41. package/dist/boe.js.map +1 -0
  42. package/dist/braintree.d.ts +34 -0
  43. package/dist/braintree.d.ts.map +1 -0
  44. package/dist/braintree.js +45 -0
  45. package/dist/braintree.js.map +1 -0
  46. package/dist/cash.d.ts +64 -0
  47. package/dist/cash.d.ts.map +1 -0
  48. package/dist/cash.js +134 -0
  49. package/dist/cash.js.map +1 -0
  50. package/dist/checkout.d.ts +42 -0
  51. package/dist/checkout.d.ts.map +1 -0
  52. package/dist/checkout.js +52 -0
  53. package/dist/checkout.js.map +1 -0
  54. package/dist/convert.d.ts +52 -0
  55. package/dist/convert.d.ts.map +1 -0
  56. package/dist/convert.js +65 -0
  57. package/dist/convert.js.map +1 -0
  58. package/dist/currency.d.ts +22 -0
  59. package/dist/currency.d.ts.map +1 -0
  60. package/dist/currency.js +38 -0
  61. package/dist/currency.js.map +1 -0
  62. package/dist/decimal.d.ts +52 -0
  63. package/dist/decimal.d.ts.map +1 -0
  64. package/dist/decimal.js +251 -0
  65. package/dist/decimal.js.map +1 -0
  66. package/dist/drizzle/mysql.d.ts +105 -0
  67. package/dist/drizzle/mysql.d.ts.map +1 -0
  68. package/dist/drizzle/mysql.js +60 -0
  69. package/dist/drizzle/mysql.js.map +1 -0
  70. package/dist/drizzle/pg.d.ts +103 -0
  71. package/dist/drizzle/pg.d.ts.map +1 -0
  72. package/dist/drizzle/pg.js +60 -0
  73. package/dist/drizzle/pg.js.map +1 -0
  74. package/dist/drizzle/sqlite.d.ts +102 -0
  75. package/dist/drizzle/sqlite.d.ts.map +1 -0
  76. package/dist/drizzle/sqlite.js +59 -0
  77. package/dist/drizzle/sqlite.js.map +1 -0
  78. package/dist/ecb.d.ts +52 -0
  79. package/dist/ecb.d.ts.map +1 -0
  80. package/dist/ecb.js +285 -0
  81. package/dist/ecb.js.map +1 -0
  82. package/dist/exact.d.ts +62 -0
  83. package/dist/exact.d.ts.map +1 -0
  84. package/dist/exact.js +147 -0
  85. package/dist/exact.js.map +1 -0
  86. package/dist/fed.d.ts +35 -0
  87. package/dist/fed.d.ts.map +1 -0
  88. package/dist/fed.js +134 -0
  89. package/dist/fed.js.map +1 -0
  90. package/dist/fetch.d.ts +103 -0
  91. package/dist/fetch.d.ts.map +1 -0
  92. package/dist/fetch.js +222 -0
  93. package/dist/fetch.js.map +1 -0
  94. package/dist/fixed.d.ts +121 -0
  95. package/dist/fixed.d.ts.map +1 -0
  96. package/dist/fixed.js +420 -0
  97. package/dist/fixed.js.map +1 -0
  98. package/dist/fn.d.ts +34 -0
  99. package/dist/fn.d.ts.map +1 -0
  100. package/dist/fn.js +37 -0
  101. package/dist/fn.js.map +1 -0
  102. package/dist/format.d.ts +13 -0
  103. package/dist/format.d.ts.map +1 -0
  104. package/dist/format.js +90 -0
  105. package/dist/format.js.map +1 -0
  106. package/dist/generated/adyen.d.ts +3 -0
  107. package/dist/generated/adyen.d.ts.map +1 -0
  108. package/dist/generated/adyen.js +144 -0
  109. package/dist/generated/adyen.js.map +1 -0
  110. package/dist/generated/braintree.d.ts +3 -0
  111. package/dist/generated/braintree.d.ts.map +1 -0
  112. package/dist/generated/braintree.js +140 -0
  113. package/dist/generated/braintree.js.map +1 -0
  114. package/dist/generated/cash.d.ts +14 -0
  115. package/dist/generated/cash.d.ts.map +1 -0
  116. package/dist/generated/cash.js +465 -0
  117. package/dist/generated/cash.js.map +1 -0
  118. package/dist/generated/checkout.d.ts +3 -0
  119. package/dist/generated/checkout.d.ts.map +1 -0
  120. package/dist/generated/checkout.js +151 -0
  121. package/dist/generated/checkout.js.map +1 -0
  122. package/dist/generated/historic.d.ts +337 -0
  123. package/dist/generated/historic.d.ts.map +1 -0
  124. package/dist/generated/historic.js +66 -0
  125. package/dist/generated/historic.js.map +1 -0
  126. package/dist/generated/iso4217.d.ts +174 -0
  127. package/dist/generated/iso4217.d.ts.map +1 -0
  128. package/dist/generated/iso4217.js +175 -0
  129. package/dist/generated/iso4217.js.map +1 -0
  130. package/dist/generated/kernel.d.ts +17 -0
  131. package/dist/generated/kernel.d.ts.map +1 -0
  132. package/dist/generated/kernel.js +208 -0
  133. package/dist/generated/kernel.js.map +1 -0
  134. package/dist/generated/klarna.d.ts +3 -0
  135. package/dist/generated/klarna.d.ts.map +1 -0
  136. package/dist/generated/klarna.js +21 -0
  137. package/dist/generated/klarna.js.map +1 -0
  138. package/dist/generated/paypal.d.ts +3 -0
  139. package/dist/generated/paypal.d.ts.map +1 -0
  140. package/dist/generated/paypal.js +31 -0
  141. package/dist/generated/paypal.js.map +1 -0
  142. package/dist/generated/stripe.d.ts +8 -0
  143. package/dist/generated/stripe.d.ts.map +1 -0
  144. package/dist/generated/stripe.js +150 -0
  145. package/dist/generated/stripe.js.map +1 -0
  146. package/dist/historic.d.ts +40 -0
  147. package/dist/historic.d.ts.map +1 -0
  148. package/dist/historic.js +43 -0
  149. package/dist/historic.js.map +1 -0
  150. package/dist/history.d.ts +96 -0
  151. package/dist/history.d.ts.map +1 -0
  152. package/dist/history.js +213 -0
  153. package/dist/history.js.map +1 -0
  154. package/dist/hmrc.d.ts +28 -0
  155. package/dist/hmrc.d.ts.map +1 -0
  156. package/dist/hmrc.js +108 -0
  157. package/dist/hmrc.js.map +1 -0
  158. package/dist/index.d.ts +11 -0
  159. package/dist/index.d.ts.map +1 -0
  160. package/dist/index.js +11 -0
  161. package/dist/index.js.map +1 -0
  162. package/dist/klarna.d.ts +31 -0
  163. package/dist/klarna.d.ts.map +1 -0
  164. package/dist/klarna.js +38 -0
  165. package/dist/klarna.js.map +1 -0
  166. package/dist/kysely.d.ts +120 -0
  167. package/dist/kysely.d.ts.map +1 -0
  168. package/dist/kysely.js +309 -0
  169. package/dist/kysely.js.map +1 -0
  170. package/dist/money.d.ts +302 -0
  171. package/dist/money.d.ts.map +1 -0
  172. package/dist/money.js +703 -0
  173. package/dist/money.js.map +1 -0
  174. package/dist/parse.d.ts +55 -0
  175. package/dist/parse.d.ts.map +1 -0
  176. package/dist/parse.js +419 -0
  177. package/dist/parse.js.map +1 -0
  178. package/dist/paypal.d.ts +41 -0
  179. package/dist/paypal.d.ts.map +1 -0
  180. package/dist/paypal.js +58 -0
  181. package/dist/paypal.js.map +1 -0
  182. package/dist/pg.d.ts +100 -0
  183. package/dist/pg.d.ts.map +1 -0
  184. package/dist/pg.js +343 -0
  185. package/dist/pg.js.map +1 -0
  186. package/dist/plugins/adyen.d.ts +15 -0
  187. package/dist/plugins/adyen.d.ts.map +1 -0
  188. package/dist/plugins/adyen.js +10 -0
  189. package/dist/plugins/adyen.js.map +1 -0
  190. package/dist/plugins/all.d.ts +29 -0
  191. package/dist/plugins/all.d.ts.map +1 -0
  192. package/dist/plugins/all.js +30 -0
  193. package/dist/plugins/all.js.map +1 -0
  194. package/dist/plugins/allocate.d.ts +20 -0
  195. package/dist/plugins/allocate.d.ts.map +1 -0
  196. package/dist/plugins/allocate.js +26 -0
  197. package/dist/plugins/allocate.js.map +1 -0
  198. package/dist/plugins/braintree.d.ts +12 -0
  199. package/dist/plugins/braintree.d.ts.map +1 -0
  200. package/dist/plugins/braintree.js +12 -0
  201. package/dist/plugins/braintree.js.map +1 -0
  202. package/dist/plugins/cash.d.ts +19 -0
  203. package/dist/plugins/cash.d.ts.map +1 -0
  204. package/dist/plugins/cash.js +16 -0
  205. package/dist/plugins/cash.js.map +1 -0
  206. package/dist/plugins/checkout.d.ts +21 -0
  207. package/dist/plugins/checkout.d.ts.map +1 -0
  208. package/dist/plugins/checkout.js +16 -0
  209. package/dist/plugins/checkout.js.map +1 -0
  210. package/dist/plugins/convert.d.ts +19 -0
  211. package/dist/plugins/convert.d.ts.map +1 -0
  212. package/dist/plugins/convert.js +13 -0
  213. package/dist/plugins/convert.js.map +1 -0
  214. package/dist/plugins/exact.d.ts +15 -0
  215. package/dist/plugins/exact.d.ts.map +1 -0
  216. package/dist/plugins/exact.js +13 -0
  217. package/dist/plugins/exact.js.map +1 -0
  218. package/dist/plugins/fixed.d.ts +17 -0
  219. package/dist/plugins/fixed.d.ts.map +1 -0
  220. package/dist/plugins/fixed.js +13 -0
  221. package/dist/plugins/fixed.js.map +1 -0
  222. package/dist/plugins/format.d.ts +9 -0
  223. package/dist/plugins/format.d.ts.map +1 -0
  224. package/dist/plugins/format.js +16 -0
  225. package/dist/plugins/format.js.map +1 -0
  226. package/dist/plugins/klarna.d.ts +10 -0
  227. package/dist/plugins/klarna.d.ts.map +1 -0
  228. package/dist/plugins/klarna.js +10 -0
  229. package/dist/plugins/klarna.js.map +1 -0
  230. package/dist/plugins/paypal.d.ts +14 -0
  231. package/dist/plugins/paypal.d.ts.map +1 -0
  232. package/dist/plugins/paypal.js +16 -0
  233. package/dist/plugins/paypal.js.map +1 -0
  234. package/dist/plugins/prisma.d.ts +8 -0
  235. package/dist/plugins/prisma.d.ts.map +1 -0
  236. package/dist/plugins/prisma.js +13 -0
  237. package/dist/plugins/prisma.js.map +1 -0
  238. package/dist/plugins/stripe.d.ts +14 -0
  239. package/dist/plugins/stripe.d.ts.map +1 -0
  240. package/dist/plugins/stripe.js +16 -0
  241. package/dist/plugins/stripe.js.map +1 -0
  242. package/dist/plugins/tax.d.ts +20 -0
  243. package/dist/plugins/tax.d.ts.map +1 -0
  244. package/dist/plugins/tax.js +18 -0
  245. package/dist/plugins/tax.js.map +1 -0
  246. package/dist/policy.d.ts +34 -0
  247. package/dist/policy.d.ts.map +1 -0
  248. package/dist/policy.js +90 -0
  249. package/dist/policy.js.map +1 -0
  250. package/dist/prisma.d.ts +77 -0
  251. package/dist/prisma.d.ts.map +1 -0
  252. package/dist/prisma.js +76 -0
  253. package/dist/prisma.js.map +1 -0
  254. package/dist/processor.d.ts +28 -0
  255. package/dist/processor.d.ts.map +1 -0
  256. package/dist/processor.js +118 -0
  257. package/dist/processor.js.map +1 -0
  258. package/dist/provider.d.ts +103 -0
  259. package/dist/provider.d.ts.map +1 -0
  260. package/dist/provider.js +280 -0
  261. package/dist/provider.js.map +1 -0
  262. package/dist/rate-text.d.ts +38 -0
  263. package/dist/rate-text.d.ts.map +1 -0
  264. package/dist/rate-text.js +143 -0
  265. package/dist/rate-text.js.map +1 -0
  266. package/dist/rate.d.ts +175 -0
  267. package/dist/rate.d.ts.map +1 -0
  268. package/dist/rate.js +371 -0
  269. package/dist/rate.js.map +1 -0
  270. package/dist/rounding-error.d.ts +9 -0
  271. package/dist/rounding-error.d.ts.map +1 -0
  272. package/dist/rounding-error.js +9 -0
  273. package/dist/rounding-error.js.map +1 -0
  274. package/dist/rounding.d.ts +50 -0
  275. package/dist/rounding.d.ts.map +1 -0
  276. package/dist/rounding.js +87 -0
  277. package/dist/rounding.js.map +1 -0
  278. package/dist/schema.d.ts +43 -0
  279. package/dist/schema.d.ts.map +1 -0
  280. package/dist/schema.js +77 -0
  281. package/dist/schema.js.map +1 -0
  282. package/dist/sql.d.ts +54 -0
  283. package/dist/sql.d.ts.map +1 -0
  284. package/dist/sql.js +131 -0
  285. package/dist/sql.js.map +1 -0
  286. package/dist/stripe-fx.d.ts +22 -0
  287. package/dist/stripe-fx.d.ts.map +1 -0
  288. package/dist/stripe-fx.js +30 -0
  289. package/dist/stripe-fx.js.map +1 -0
  290. package/dist/stripe.d.ts +36 -0
  291. package/dist/stripe.d.ts.map +1 -0
  292. package/dist/stripe.js +39 -0
  293. package/dist/stripe.js.map +1 -0
  294. package/dist/tax.d.ts +33 -0
  295. package/dist/tax.d.ts.map +1 -0
  296. package/dist/tax.js +55 -0
  297. package/dist/tax.js.map +1 -0
  298. package/dist/testing/arbitraries.d.ts +43 -0
  299. package/dist/testing/arbitraries.d.ts.map +1 -0
  300. package/dist/testing/arbitraries.js +98 -0
  301. package/dist/testing/arbitraries.js.map +1 -0
  302. package/dist/testing/index.d.ts +67 -0
  303. package/dist/testing/index.d.ts.map +1 -0
  304. package/dist/testing/index.js +159 -0
  305. package/dist/testing/index.js.map +1 -0
  306. package/dist/testing/jest.d.ts +2 -0
  307. package/dist/testing/jest.d.ts.map +1 -0
  308. package/dist/testing/jest.js +15 -0
  309. package/dist/testing/jest.js.map +1 -0
  310. package/dist/testing/vitest.d.ts +7 -0
  311. package/dist/testing/vitest.d.ts.map +1 -0
  312. package/dist/testing/vitest.js +12 -0
  313. package/dist/testing/vitest.js.map +1 -0
  314. package/dist/valibot.d.ts +33 -0
  315. package/dist/valibot.d.ts.map +1 -0
  316. package/dist/valibot.js +61 -0
  317. package/dist/valibot.js.map +1 -0
  318. package/dist/zod.d.ts +36 -0
  319. package/dist/zod.d.ts.map +1 -0
  320. package/dist/zod.js +58 -0
  321. package/dist/zod.js.map +1 -0
  322. package/package.json +280 -5
  323. package/src/adyen-fx.ts +175 -0
  324. package/src/adyen.ts +46 -0
  325. package/src/allocate.ts +393 -0
  326. package/src/bag.ts +170 -0
  327. package/src/boc.ts +136 -0
  328. package/src/boe.ts +131 -0
  329. package/src/braintree.ts +71 -0
  330. package/src/cash.ts +183 -0
  331. package/src/checkout.ts +77 -0
  332. package/src/convert.ts +177 -0
  333. package/src/currency.ts +61 -0
  334. package/src/decimal.ts +283 -0
  335. package/src/drizzle/mysql.ts +78 -0
  336. package/src/drizzle/pg.ts +78 -0
  337. package/src/drizzle/sqlite.ts +70 -0
  338. package/src/ecb.ts +328 -0
  339. package/src/exact.ts +182 -0
  340. package/src/fed.ts +146 -0
  341. package/src/fetch.ts +306 -0
  342. package/src/fixed.ts +558 -0
  343. package/src/fn.ts +94 -0
  344. package/src/format.ts +106 -0
  345. package/src/generated/adyen.ts +144 -0
  346. package/src/generated/braintree.ts +140 -0
  347. package/src/generated/cash.ts +478 -0
  348. package/src/generated/checkout.ts +151 -0
  349. package/src/generated/historic.ts +67 -0
  350. package/src/generated/iso4217.ts +179 -0
  351. package/src/generated/kernel.ts +230 -0
  352. package/src/generated/klarna.ts +21 -0
  353. package/src/generated/paypal.ts +31 -0
  354. package/src/generated/stripe.ts +150 -0
  355. package/src/historic.ts +77 -0
  356. package/src/history.ts +333 -0
  357. package/src/hmrc.ts +125 -0
  358. package/src/index.ts +41 -0
  359. package/src/klarna.ts +54 -0
  360. package/src/kysely.ts +588 -0
  361. package/src/money.ts +979 -0
  362. package/src/parse.ts +511 -0
  363. package/src/paypal.ts +93 -0
  364. package/src/pg.ts +410 -0
  365. package/src/plugins/adyen.ts +25 -0
  366. package/src/plugins/all.ts +57 -0
  367. package/src/plugins/allocate.ts +53 -0
  368. package/src/plugins/braintree.ts +23 -0
  369. package/src/plugins/cash.ts +33 -0
  370. package/src/plugins/checkout.ts +32 -0
  371. package/src/plugins/convert.ts +49 -0
  372. package/src/plugins/exact.ts +23 -0
  373. package/src/plugins/fixed.ts +28 -0
  374. package/src/plugins/format.ts +28 -0
  375. package/src/plugins/klarna.ts +21 -0
  376. package/src/plugins/paypal.ts +29 -0
  377. package/src/plugins/prisma.ts +24 -0
  378. package/src/plugins/stripe.ts +29 -0
  379. package/src/plugins/tax.ts +40 -0
  380. package/src/policy.ts +124 -0
  381. package/src/prisma.ts +199 -0
  382. package/src/processor.ts +181 -0
  383. package/src/provider.ts +389 -0
  384. package/src/rate-text.ts +151 -0
  385. package/src/rate.ts +546 -0
  386. package/src/rounding-error.ts +8 -0
  387. package/src/rounding.ts +122 -0
  388. package/src/schema.ts +119 -0
  389. package/src/sql.ts +178 -0
  390. package/src/stripe-fx.ts +49 -0
  391. package/src/stripe.ts +69 -0
  392. package/src/tax.ts +102 -0
  393. package/src/testing/arbitraries.ts +134 -0
  394. package/src/testing/index.ts +247 -0
  395. package/src/testing/jest.ts +18 -0
  396. package/src/testing/vitest.ts +18 -0
  397. package/src/valibot.ts +87 -0
  398. package/src/zod.ts +78 -0
@@ -0,0 +1,251 @@
1
+ // Exact decimal-string handling. No floating point is used on amounts: numbers given as factors are
2
+ // converted through their shortest round-trip decimal representation (String(x)), never multiplied.
3
+ /** The largest minor-unit count held as a number (2^53 - 1); larger values are bigints. */
4
+ const MAX_SAFE_MINOR = Number.MAX_SAFE_INTEGER;
5
+ const MAXN = BigInt(MAX_SAFE_MINOR);
6
+ const POW10N = [];
7
+ /** 10^exponent as a bigint, cached. */
8
+ export function pow10n(exponent) {
9
+ return (POW10N[exponent] ??= 10n ** BigInt(exponent));
10
+ }
11
+ /** 10^e as a number for 0 <= e <= 15 (all exact and safe). */
12
+ export const POW10 = [
13
+ 1, 10, 100, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15,
14
+ ];
15
+ /**
16
+ * A bigint as a number when it is a safe integer, else unchanged: the representation Money keeps.
17
+ */
18
+ export const normalizeMinor = (value) => value <= MAXN && value >= -MAXN ? Number(value) : value;
19
+ /**
20
+ * Parses a plain decimal string ("-12.345", "+7", "0.50") into digits/10^scale. Returns the integer
21
+ * of all digits (number when safe, else bigint) and the count of fraction digits. Hand-rolled (no
22
+ * regex, no BigInt for short inputs): this is the hot path of `money("12.34", ...)`.
23
+ */
24
+ export function parsePlainDecimal(input) {
25
+ const len = input.length;
26
+ let i = 0;
27
+ let neg = false;
28
+ let code = input.charCodeAt(0);
29
+ if (code === 45 /* - */ || code === 43 /* + */) {
30
+ neg = code === 45;
31
+ i = 1;
32
+ }
33
+ let acc = 0;
34
+ let digitsSeen = 0;
35
+ let scale = -1;
36
+ let big = false;
37
+ const start = i;
38
+ for (; i < len; i++) {
39
+ code = input.charCodeAt(i);
40
+ if (code >= 48 && code <= 57) {
41
+ digitsSeen++;
42
+ if (scale >= 0) {
43
+ scale++;
44
+ }
45
+ if (!big) {
46
+ // 15 digits always fit exactly in a double; beyond that use BigInt
47
+ if (digitsSeen > 15) {
48
+ big = true;
49
+ }
50
+ else {
51
+ acc = acc * 10 + (code - 48);
52
+ }
53
+ }
54
+ }
55
+ else if (code === 46 /* . */ && scale < 0 && digitsSeen > 0) {
56
+ scale = 0;
57
+ }
58
+ else {
59
+ return null;
60
+ }
61
+ }
62
+ // "", "-" and "12." are not decimals
63
+ if (digitsSeen === 0 || scale === 0) {
64
+ return null;
65
+ }
66
+ // parseDecimal reports fractions longer than MAX_DECIMAL_SCALE
67
+ if (scale > MAX_DECIMAL_SCALE) {
68
+ return null;
69
+ }
70
+ if (scale < 0) {
71
+ scale = 0;
72
+ }
73
+ if (big) {
74
+ const raw = input.slice(start).replace('.', '');
75
+ const value = BigInt(raw);
76
+ return { digits: normalizeMinor(neg ? -value : value), scale };
77
+ }
78
+ return { digits: neg ? 0 - acc : acc, scale };
79
+ }
80
+ const EXP_RE = /^([+-]?)(\d+)(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/;
81
+ /**
82
+ * The largest exponent and number of fraction digits a decimal string may have. Far beyond any real
83
+ * amount or rate, and it keeps input such as "1e999999999" from building enormous powers of ten.
84
+ */
85
+ export const MAX_DECIMAL_SCALE = 1000;
86
+ /** Parses a decimal string, allowing exponent notation ("1e-7", as produced by String(1e-7)). */
87
+ export function parseDecimal(input) {
88
+ const match = EXP_RE.exec(input.trim());
89
+ if (!match) {
90
+ throw new SyntaxError(`Invalid decimal string "${input}"`);
91
+ }
92
+ const [, sign, int, frac = '', exp = '0'] = match;
93
+ const exponent = Number(exp);
94
+ let scale = frac.length - exponent;
95
+ if (!(Math.abs(exponent) <= MAX_DECIMAL_SCALE) || scale > MAX_DECIMAL_SCALE) {
96
+ // The input itself is not quoted: it may be huge.
97
+ throw new RangeError(`Decimal string exponent or fraction digits beyond ${MAX_DECIMAL_SCALE}`);
98
+ }
99
+ let digits = BigInt(int + frac);
100
+ if (scale < 0) {
101
+ digits *= pow10n(-scale);
102
+ scale = 0;
103
+ }
104
+ return { digits: sign === '-' ? -digits : digits, scale };
105
+ }
106
+ function gcd(left, right) {
107
+ if (left < 0n) {
108
+ left = -left;
109
+ }
110
+ // a temporary, not a destructuring swap: `[a, b] = [b, a % b]` builds an array per step until the
111
+ // optimiser removes it, and this loop runs for every ratio that is built
112
+ while (right) {
113
+ const remainder = left % right;
114
+ left = right;
115
+ right = remainder;
116
+ }
117
+ return left;
118
+ }
119
+ /** The value as a number when it is a safe integer, otherwise NaN (a Ratio's `n` and `d`). */
120
+ function safeNumberOrNaN(value) {
121
+ return value <= MAXN && value >= -MAXN ? Number(value) : NaN;
122
+ }
123
+ function makeRatio(num, den) {
124
+ if (den === 0n) {
125
+ throw new RangeError('Division by zero');
126
+ }
127
+ if (den < 0n) {
128
+ num = -num;
129
+ den = -den;
130
+ }
131
+ // an integer (den 1) is already in lowest terms
132
+ if (den !== 1n) {
133
+ const divisor = gcd(num, den);
134
+ if (divisor > 1n) {
135
+ num /= divisor;
136
+ den /= divisor;
137
+ }
138
+ }
139
+ return { num, den, n: safeNumberOrNaN(num), d: safeNumberOrNaN(den) };
140
+ }
141
+ const cache = new Map();
142
+ const INT_RATIOS = [];
143
+ /**
144
+ * Builds an exact ratio. `ratio('1.075')`, `ratio(3, 4)`, `ratio(10n)`, `ratio('1/3')`.
145
+ * Numbers are taken at their shortest decimal representation: `ratio(0.1)` is exactly 1/10.
146
+ * Pre-build ratios you use in hot loops; strings are also cached (up to 1024 entries).
147
+ */
148
+ export function ratio(value, den) {
149
+ if (den !== undefined) {
150
+ // two bigints (divide, percentages, tax): one reduction instead of three
151
+ if (typeof value === 'bigint' && typeof den === 'bigint') {
152
+ return makeRatio(value, den);
153
+ }
154
+ const numeratorRatio = ratio(value);
155
+ const denominatorRatio = ratio(den);
156
+ return makeRatio(numeratorRatio.num * denominatorRatio.den, numeratorRatio.den * denominatorRatio.num);
157
+ }
158
+ if (typeof value === 'object') {
159
+ return value;
160
+ }
161
+ if (typeof value === 'number') {
162
+ if (Number.isSafeInteger(value)) {
163
+ if (value >= 0 && value < 128) {
164
+ return (INT_RATIOS[value] ??= makeRatio(BigInt(value), 1n));
165
+ }
166
+ return makeRatio(BigInt(value), 1n);
167
+ }
168
+ if (!Number.isFinite(value)) {
169
+ throw new RangeError(`Invalid factor ${value}`);
170
+ }
171
+ value = String(value);
172
+ }
173
+ if (typeof value === 'bigint') {
174
+ return makeRatio(value, 1n);
175
+ }
176
+ let cached = cache.get(value);
177
+ if (cached === undefined) {
178
+ const slash = value.indexOf('/');
179
+ if (slash > 0) {
180
+ cached = ratio(value.slice(0, slash).trim(), value.slice(slash + 1).trim());
181
+ }
182
+ else {
183
+ const { digits, scale } = parseDecimal(value);
184
+ cached = makeRatio(digits, pow10n(scale));
185
+ }
186
+ if (cache.size >= 1024) {
187
+ cache.clear();
188
+ }
189
+ cache.set(value, cached);
190
+ }
191
+ return cached;
192
+ }
193
+ /** num/den -> exact decimal string if the expansion terminates, else null. */
194
+ export function ratioToDecimal(value) {
195
+ let remainingDenominator = value.den;
196
+ let twos = 0;
197
+ let fives = 0;
198
+ while (remainingDenominator % 2n === 0n) {
199
+ remainingDenominator /= 2n;
200
+ twos++;
201
+ }
202
+ while (remainingDenominator % 5n === 0n) {
203
+ remainingDenominator /= 5n;
204
+ fives++;
205
+ }
206
+ if (remainingDenominator !== 1n) {
207
+ return null;
208
+ }
209
+ const scale = Math.max(twos, fives);
210
+ return formatScaled(value.num * (pow10n(scale) / value.den), scale);
211
+ }
212
+ // Zero padding for the fraction digits, built once: indexing it is faster than padStart.
213
+ const ZPAD = Array.from({ length: 16 }, (_, length) => '0'.repeat(length));
214
+ /** Formats an integer at `scale` as a plain decimal string ("-0.05"). */
215
+ export function formatScaled(minor, scale) {
216
+ if (typeof minor === 'number' && scale <= 15) {
217
+ if (scale === 0) {
218
+ return String(minor);
219
+ }
220
+ // integer/fraction split with exact integer arithmetic (the float quotient is corrected)
221
+ const magnitude = minor < 0 ? 0 - minor : minor;
222
+ const unit = POW10[scale];
223
+ if (magnitude + unit <= MAX_SAFE_MINOR) {
224
+ let whole = Math.floor(magnitude / unit);
225
+ let fraction = magnitude - whole * unit;
226
+ if (fraction < 0) {
227
+ whole -= 1;
228
+ fraction += unit;
229
+ }
230
+ else if (fraction >= unit) {
231
+ whole += 1;
232
+ fraction -= unit;
233
+ }
234
+ let fractionDigits = String(fraction);
235
+ if (fractionDigits.length < scale) {
236
+ fractionDigits = ZPAD[scale - fractionDigits.length] + fractionDigits;
237
+ }
238
+ return (minor < 0 ? '-' : '') + whole + '.' + fractionDigits;
239
+ }
240
+ }
241
+ const neg = minor < 0;
242
+ let digits = typeof minor === 'number' ? String(neg ? 0 - minor : minor) : (neg ? -minor : minor).toString();
243
+ if (scale > 0) {
244
+ if (digits.length <= scale) {
245
+ digits = '0'.repeat(scale - digits.length + 1) + digits;
246
+ }
247
+ digits = digits.slice(0, digits.length - scale) + '.' + digits.slice(digits.length - scale);
248
+ }
249
+ return neg ? '-' + digits : digits;
250
+ }
251
+ //# sourceMappingURL=decimal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decimal.js","sourceRoot":"","sources":["../src/decimal.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,105 @@
1
+ import type { CurrencyInput, Money, MoneyJSON } from '../money.js';
2
+ import { type DecimalColumnSize } from '../sql.js';
3
+ export { DEFAULT_DECIMAL_SIZE, type DecimalColumnSize } from '../sql.js';
4
+ /**
5
+ * A BIGINT column of minor units in a fixed currency (`1234` is 12.34 EUR), read back as
6
+ * `Money<C>`. Exact up to the column's limit of ±9.2·10^18 minor units. mysql2 returns BIGINT as a
7
+ * number by default, which is exact only below 2^53; beyond that it throws, so set
8
+ * `supportBigNumbers: true` (with `bigNumberStrings: true`) on the connection for larger amounts.
9
+ * Writing another currency, or a value at a scale other than the currency's, throws.
10
+ *
11
+ * total: moneyMinor('EUR')('total_minor').notNull()
12
+ */
13
+ export declare function moneyMinor<const C extends CurrencyInput>(currency: C): {
14
+ (): import("drizzle-orm/mysql-core").MySqlCustomColumnBuilder<{
15
+ name: "";
16
+ dataType: "custom";
17
+ columnType: "MySqlCustomColumn";
18
+ data: Money<C>;
19
+ driverParam: string | number | bigint;
20
+ enumValues: undefined;
21
+ }>;
22
+ <TConfig extends Record<string, any>>(fieldConfig?: TConfig | undefined): import("drizzle-orm/mysql-core").MySqlCustomColumnBuilder<{
23
+ name: "";
24
+ dataType: "custom";
25
+ columnType: "MySqlCustomColumn";
26
+ data: Money<C>;
27
+ driverParam: string | number | bigint;
28
+ enumValues: undefined;
29
+ }>;
30
+ <TName extends string>(dbName: TName, fieldConfig?: unknown): import("drizzle-orm/mysql-core").MySqlCustomColumnBuilder<{
31
+ name: TName;
32
+ dataType: "custom";
33
+ columnType: "MySqlCustomColumn";
34
+ data: Money<C>;
35
+ driverParam: string | number | bigint;
36
+ enumValues: undefined;
37
+ }>;
38
+ };
39
+ /**
40
+ * A DECIMAL(precision, scale) column, DECIMAL(19,4) by default, read back as `Money<C>`. The driver
41
+ * must return DECIMAL as a string (mysql2's default; don't set `decimalNumbers`): a number has been
42
+ * through a float and throws. Writing a value the column could not hold unchanged throws (outside
43
+ * strict mode MySQL would clamp it), and so does a column scale below the currency's exponent.
44
+ *
45
+ * price: moneyDecimal('EUR', { precision: 19, scale: 4 })('price').notNull()
46
+ */
47
+ export declare function moneyDecimal<const C extends CurrencyInput>(currency: C, size?: DecimalColumnSize): {
48
+ (): import("drizzle-orm/mysql-core").MySqlCustomColumnBuilder<{
49
+ name: "";
50
+ dataType: "custom";
51
+ columnType: "MySqlCustomColumn";
52
+ data: Money<C>;
53
+ driverParam: string;
54
+ enumValues: undefined;
55
+ }>;
56
+ <TConfig extends Record<string, any>>(fieldConfig?: TConfig | undefined): import("drizzle-orm/mysql-core").MySqlCustomColumnBuilder<{
57
+ name: "";
58
+ dataType: "custom";
59
+ columnType: "MySqlCustomColumn";
60
+ data: Money<C>;
61
+ driverParam: string;
62
+ enumValues: undefined;
63
+ }>;
64
+ <TName extends string>(dbName: TName, fieldConfig?: unknown): import("drizzle-orm/mysql-core").MySqlCustomColumnBuilder<{
65
+ name: TName;
66
+ dataType: "custom";
67
+ columnType: "MySqlCustomColumn";
68
+ data: Money<C>;
69
+ driverParam: string;
70
+ enumValues: undefined;
71
+ }>;
72
+ };
73
+ /**
74
+ * A JSON column holding `{"amount":"12.34","currency":"EUR"}`, with the currency in each value.
75
+ * Pass a currency to fix it: then a value in another currency throws, on write and on read.
76
+ *
77
+ * refund: moneyJson()('refund')
78
+ */
79
+ export declare function moneyJson<const C extends CurrencyInput = CurrencyInput>(currency?: C): {
80
+ (): import("drizzle-orm/mysql-core").MySqlCustomColumnBuilder<{
81
+ name: "";
82
+ dataType: "custom";
83
+ columnType: "MySqlCustomColumn";
84
+ data: Money<C>;
85
+ driverParam: string | MoneyJSON<string>;
86
+ enumValues: undefined;
87
+ }>;
88
+ <TConfig extends Record<string, any>>(fieldConfig?: TConfig | undefined): import("drizzle-orm/mysql-core").MySqlCustomColumnBuilder<{
89
+ name: "";
90
+ dataType: "custom";
91
+ columnType: "MySqlCustomColumn";
92
+ data: Money<C>;
93
+ driverParam: string | MoneyJSON<string>;
94
+ enumValues: undefined;
95
+ }>;
96
+ <TName extends string>(dbName: TName, fieldConfig?: unknown): import("drizzle-orm/mysql-core").MySqlCustomColumnBuilder<{
97
+ name: TName;
98
+ dataType: "custom";
99
+ columnType: "MySqlCustomColumn";
100
+ data: Money<C>;
101
+ driverParam: string | MoneyJSON<string>;
102
+ enumValues: undefined;
103
+ }>;
104
+ };
105
+ //# sourceMappingURL=mysql.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mysql.d.ts","sourceRoot":"","sources":["../../src/drizzle/mysql.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EASL,KAAK,iBAAiB,EACvB,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,oBAAoB,EAAE,KAAK,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAEzE;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,KAAK,CAAC,CAAC,SAAS,aAAa,EAAE,QAAQ,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;EAMpE;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,KAAK,CAAC,CAAC,SAAS,aAAa,EACxD,QAAQ,EAAE,CAAC,EACX,IAAI,GAAE,iBAAwC;;;;;;;;;;;;;;;;;;;;;;;;;EAS/C;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,KAAK,CAAC,CAAC,SAAS,aAAa,GAAG,aAAa,EAAE,QAAQ,CAAC,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;EAOpF"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * `@ducatjs/money/drizzle/mysql`: Drizzle ORM column types for MySQL and MariaDB (mysql2,
3
+ * PlanetScale). Selects return `Money`, inserts and updates accept it, and the currency is part of
4
+ * the column's type.
5
+ *
6
+ * import { mysqlTable } from 'drizzle-orm/mysql-core';
7
+ * import { moneyMinor } from '@ducatjs/money/drizzle/mysql';
8
+ *
9
+ * const orders = mysqlTable('orders', { total: moneyMinor('EUR')('total_minor').notNull() });
10
+ */
11
+ import { customType } from 'drizzle-orm/mysql-core';
12
+ import { checkDecimalSize, decimalFromDriver, decimalToDriver, DEFAULT_DECIMAL_SIZE, jsonFromDriver, jsonToDriver, minorFromDriver, minorToDriver, } from '../sql.js';
13
+ export { DEFAULT_DECIMAL_SIZE } from '../sql.js';
14
+ /**
15
+ * A BIGINT column of minor units in a fixed currency (`1234` is 12.34 EUR), read back as
16
+ * `Money<C>`. Exact up to the column's limit of ±9.2·10^18 minor units. mysql2 returns BIGINT as a
17
+ * number by default, which is exact only below 2^53; beyond that it throws, so set
18
+ * `supportBigNumbers: true` (with `bigNumberStrings: true`) on the connection for larger amounts.
19
+ * Writing another currency, or a value at a scale other than the currency's, throws.
20
+ *
21
+ * total: moneyMinor('EUR')('total_minor').notNull()
22
+ */
23
+ export function moneyMinor(currency) {
24
+ return customType({
25
+ dataType: () => 'bigint',
26
+ toDriver: (money) => minorToDriver(money, currency).toString(),
27
+ fromDriver: (value) => minorFromDriver(value, currency),
28
+ });
29
+ }
30
+ /**
31
+ * A DECIMAL(precision, scale) column, DECIMAL(19,4) by default, read back as `Money<C>`. The driver
32
+ * must return DECIMAL as a string (mysql2's default; don't set `decimalNumbers`): a number has been
33
+ * through a float and throws. Writing a value the column could not hold unchanged throws (outside
34
+ * strict mode MySQL would clamp it), and so does a column scale below the currency's exponent.
35
+ *
36
+ * price: moneyDecimal('EUR', { precision: 19, scale: 4 })('price').notNull()
37
+ */
38
+ export function moneyDecimal(currency, size = DEFAULT_DECIMAL_SIZE) {
39
+ checkDecimalSize(currency, size);
40
+ return customType({
41
+ dataType: () => `decimal(${size.precision}, ${size.scale})`,
42
+ toDriver: (money) => decimalToDriver(money, currency, size),
43
+ fromDriver: (value) => decimalFromDriver(value, currency),
44
+ });
45
+ }
46
+ /**
47
+ * A JSON column holding `{"amount":"12.34","currency":"EUR"}`, with the currency in each value.
48
+ * Pass a currency to fix it: then a value in another currency throws, on write and on read.
49
+ *
50
+ * refund: moneyJson()('refund')
51
+ */
52
+ export function moneyJson(currency) {
53
+ return customType({
54
+ dataType: () => 'json',
55
+ toDriver: (money) => jsonToDriver(money, currency),
56
+ // mysql2 parses JSON columns itself; other drivers may return the text
57
+ fromDriver: (value) => jsonFromDriver(value, currency),
58
+ });
59
+ }
60
+ //# sourceMappingURL=mysql.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mysql.js","sourceRoot":"","sources":["../../src/drizzle/mysql.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEpD,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,oBAAoB,EACpB,cAAc,EACd,YAAY,EACZ,eAAe,EACf,aAAa,GAEd,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,oBAAoB,EAA0B,MAAM,WAAW,CAAC;AAEzE;;;;;;;;GAQG;AACH,MAAM,UAAU,UAAU,CAAgC,QAAW;IACnE,OAAO,UAAU,CAA2D;QAC1E,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ;QACxB,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,QAAQ,EAAE;QAC9D,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,eAAe,CAAC,KAAK,EAAE,QAAQ,CAAC;KACxD,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAC1B,QAAW,EACX,OAA0B,oBAAoB;IAE9C,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAEjC,OAAO,UAAU,CAAyC;QACxD,QAAQ,EAAE,GAAG,EAAE,CAAC,WAAW,IAAI,CAAC,SAAS,KAAK,IAAI,CAAC,KAAK,GAAG;QAC3D,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,eAAe,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAC;QAC3D,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,iBAAiB,CAAC,KAAK,EAAE,QAAQ,CAAC;KAC1D,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAgD,QAAY;IACnF,OAAO,UAAU,CAAqD;QACpE,QAAQ,EAAE,GAAG,EAAE,CAAC,MAAM;QACtB,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,YAAY,CAAC,KAAK,EAAE,QAAQ,CAAC;QAClD,uEAAuE;QACvE,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,cAAc,CAAC,KAAK,EAAE,QAAQ,CAAC;KACvD,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,103 @@
1
+ import type { CurrencyInput, Money, MoneyJSON } from '../money.js';
2
+ import { type DecimalColumnSize } from '../sql.js';
3
+ export { DEFAULT_DECIMAL_SIZE, type DecimalColumnSize } from '../sql.js';
4
+ /**
5
+ * A BIGINT column of minor units in a fixed currency (`1234` is 12.34 EUR), read back as
6
+ * `Money<C>`. Exact up to the column's limit of ±9.2·10^18 minor units. Writing another currency, or
7
+ * a value at a scale other than the currency's, throws.
8
+ *
9
+ * total: moneyMinor('EUR')('total_minor').notNull()
10
+ */
11
+ export declare function moneyMinor<const C extends CurrencyInput>(currency: C): {
12
+ (): import("drizzle-orm/pg-core").PgCustomColumnBuilder<{
13
+ name: "";
14
+ dataType: "custom";
15
+ columnType: "PgCustomColumn";
16
+ data: Money<C>;
17
+ driverParam: string | number | bigint;
18
+ enumValues: undefined;
19
+ }>;
20
+ <TConfig extends Record<string, any>>(fieldConfig?: TConfig | undefined): import("drizzle-orm/pg-core").PgCustomColumnBuilder<{
21
+ name: "";
22
+ dataType: "custom";
23
+ columnType: "PgCustomColumn";
24
+ data: Money<C>;
25
+ driverParam: string | number | bigint;
26
+ enumValues: undefined;
27
+ }>;
28
+ <TName extends string>(dbName: TName, fieldConfig?: unknown): import("drizzle-orm/pg-core").PgCustomColumnBuilder<{
29
+ name: TName;
30
+ dataType: "custom";
31
+ columnType: "PgCustomColumn";
32
+ data: Money<C>;
33
+ driverParam: string | number | bigint;
34
+ enumValues: undefined;
35
+ }>;
36
+ };
37
+ /**
38
+ * A NUMERIC(precision, scale) column, NUMERIC(19,4) by default, read back as `Money<C>`. The
39
+ * driver must return NUMERIC as a string (node-postgres and postgres.js do); a number has been
40
+ * through a float and throws, as do `NaN` and `Infinity`. Writing a value the column could not hold
41
+ * unchanged throws, and so does a column scale below the currency's exponent.
42
+ *
43
+ * price: moneyDecimal('EUR', { precision: 19, scale: 4 })('price').notNull()
44
+ */
45
+ export declare function moneyDecimal<const C extends CurrencyInput>(currency: C, size?: DecimalColumnSize): {
46
+ (): import("drizzle-orm/pg-core").PgCustomColumnBuilder<{
47
+ name: "";
48
+ dataType: "custom";
49
+ columnType: "PgCustomColumn";
50
+ data: Money<C>;
51
+ driverParam: string;
52
+ enumValues: undefined;
53
+ }>;
54
+ <TConfig extends Record<string, any>>(fieldConfig?: TConfig | undefined): import("drizzle-orm/pg-core").PgCustomColumnBuilder<{
55
+ name: "";
56
+ dataType: "custom";
57
+ columnType: "PgCustomColumn";
58
+ data: Money<C>;
59
+ driverParam: string;
60
+ enumValues: undefined;
61
+ }>;
62
+ <TName extends string>(dbName: TName, fieldConfig?: unknown): import("drizzle-orm/pg-core").PgCustomColumnBuilder<{
63
+ name: TName;
64
+ dataType: "custom";
65
+ columnType: "PgCustomColumn";
66
+ data: Money<C>;
67
+ driverParam: string;
68
+ enumValues: undefined;
69
+ }>;
70
+ };
71
+ /**
72
+ * A JSONB column holding `{"amount":"12.34","currency":"EUR"}`, with the currency in each value.
73
+ * Pass a currency to fix it: then a value in another currency throws, on write and on read.
74
+ *
75
+ * refund: moneyJson()('refund')
76
+ */
77
+ export declare function moneyJson<const C extends CurrencyInput = CurrencyInput>(currency?: C): {
78
+ (): import("drizzle-orm/pg-core").PgCustomColumnBuilder<{
79
+ name: "";
80
+ dataType: "custom";
81
+ columnType: "PgCustomColumn";
82
+ data: Money<C>;
83
+ driverParam: string | MoneyJSON<string>;
84
+ enumValues: undefined;
85
+ }>;
86
+ <TConfig extends Record<string, any>>(fieldConfig?: TConfig | undefined): import("drizzle-orm/pg-core").PgCustomColumnBuilder<{
87
+ name: "";
88
+ dataType: "custom";
89
+ columnType: "PgCustomColumn";
90
+ data: Money<C>;
91
+ driverParam: string | MoneyJSON<string>;
92
+ enumValues: undefined;
93
+ }>;
94
+ <TName extends string>(dbName: TName, fieldConfig?: unknown): import("drizzle-orm/pg-core").PgCustomColumnBuilder<{
95
+ name: TName;
96
+ dataType: "custom";
97
+ columnType: "PgCustomColumn";
98
+ data: Money<C>;
99
+ driverParam: string | MoneyJSON<string>;
100
+ enumValues: undefined;
101
+ }>;
102
+ };
103
+ //# sourceMappingURL=pg.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pg.d.ts","sourceRoot":"","sources":["../../src/drizzle/pg.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EASL,KAAK,iBAAiB,EACvB,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,oBAAoB,EAAE,KAAK,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAEzE;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,KAAK,CAAC,CAAC,SAAS,aAAa,EAAE,QAAQ,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;EAQpE;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,KAAK,CAAC,CAAC,SAAS,aAAa,EACxD,QAAQ,EAAE,CAAC,EACX,IAAI,GAAE,iBAAwC;;;;;;;;;;;;;;;;;;;;;;;;;EAS/C;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,KAAK,CAAC,CAAC,SAAS,aAAa,GAAG,aAAa,EAAE,QAAQ,CAAC,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;EAOpF"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * `@ducatjs/money/drizzle/pg`: Drizzle ORM column types for Postgres (node-postgres, postgres.js,
3
+ * PGlite, Neon). Selects return `Money`, inserts and updates accept it, and the currency is part of
4
+ * the column's type.
5
+ *
6
+ * import { pgTable } from 'drizzle-orm/pg-core';
7
+ * import { moneyMinor } from '@ducatjs/money/drizzle/pg';
8
+ *
9
+ * const orders = pgTable('orders', { total: moneyMinor('EUR')('total_minor').notNull() });
10
+ */
11
+ import { customType } from 'drizzle-orm/pg-core';
12
+ import { checkDecimalSize, decimalFromDriver, decimalToDriver, DEFAULT_DECIMAL_SIZE, jsonFromDriver, jsonToDriver, minorFromDriver, minorToDriver, } from '../sql.js';
13
+ export { DEFAULT_DECIMAL_SIZE } from '../sql.js';
14
+ /**
15
+ * A BIGINT column of minor units in a fixed currency (`1234` is 12.34 EUR), read back as
16
+ * `Money<C>`. Exact up to the column's limit of ±9.2·10^18 minor units. Writing another currency, or
17
+ * a value at a scale other than the currency's, throws.
18
+ *
19
+ * total: moneyMinor('EUR')('total_minor').notNull()
20
+ */
21
+ export function moneyMinor(currency) {
22
+ return customType({
23
+ dataType: () => 'bigint',
24
+ // a string, not a bigint: node-postgres cannot bind a bigint parameter
25
+ toDriver: (money) => minorToDriver(money, currency).toString(),
26
+ // node-postgres returns int8 as a string, postgres.js as a string or a bigint
27
+ fromDriver: (value) => minorFromDriver(value, currency),
28
+ });
29
+ }
30
+ /**
31
+ * A NUMERIC(precision, scale) column, NUMERIC(19,4) by default, read back as `Money<C>`. The
32
+ * driver must return NUMERIC as a string (node-postgres and postgres.js do); a number has been
33
+ * through a float and throws, as do `NaN` and `Infinity`. Writing a value the column could not hold
34
+ * unchanged throws, and so does a column scale below the currency's exponent.
35
+ *
36
+ * price: moneyDecimal('EUR', { precision: 19, scale: 4 })('price').notNull()
37
+ */
38
+ export function moneyDecimal(currency, size = DEFAULT_DECIMAL_SIZE) {
39
+ checkDecimalSize(currency, size);
40
+ return customType({
41
+ dataType: () => `numeric(${size.precision}, ${size.scale})`,
42
+ toDriver: (money) => decimalToDriver(money, currency, size),
43
+ fromDriver: (value) => decimalFromDriver(value, currency),
44
+ });
45
+ }
46
+ /**
47
+ * A JSONB column holding `{"amount":"12.34","currency":"EUR"}`, with the currency in each value.
48
+ * Pass a currency to fix it: then a value in another currency throws, on write and on read.
49
+ *
50
+ * refund: moneyJson()('refund')
51
+ */
52
+ export function moneyJson(currency) {
53
+ return customType({
54
+ dataType: () => 'jsonb',
55
+ toDriver: (money) => jsonToDriver(money, currency),
56
+ // node-postgres parses JSONB itself; other drivers may return the text
57
+ fromDriver: (value) => jsonFromDriver(value, currency),
58
+ });
59
+ }
60
+ //# sourceMappingURL=pg.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pg.js","sourceRoot":"","sources":["../../src/drizzle/pg.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,oBAAoB,EACpB,cAAc,EACd,YAAY,EACZ,eAAe,EACf,aAAa,GAEd,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,oBAAoB,EAA0B,MAAM,WAAW,CAAC;AAEzE;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CAAgC,QAAW;IACnE,OAAO,UAAU,CAA2D;QAC1E,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ;QACxB,uEAAuE;QACvE,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,QAAQ,EAAE;QAC9D,8EAA8E;QAC9E,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,eAAe,CAAC,KAAK,EAAE,QAAQ,CAAC;KACxD,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAC1B,QAAW,EACX,OAA0B,oBAAoB;IAE9C,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAEjC,OAAO,UAAU,CAAyC;QACxD,QAAQ,EAAE,GAAG,EAAE,CAAC,WAAW,IAAI,CAAC,SAAS,KAAK,IAAI,CAAC,KAAK,GAAG;QAC3D,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,eAAe,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAC;QAC3D,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,iBAAiB,CAAC,KAAK,EAAE,QAAQ,CAAC;KAC1D,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAgD,QAAY;IACnF,OAAO,UAAU,CAAqD;QACpE,QAAQ,EAAE,GAAG,EAAE,CAAC,OAAO;QACvB,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,YAAY,CAAC,KAAK,EAAE,QAAQ,CAAC;QAClD,uEAAuE;QACvE,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,cAAc,CAAC,KAAK,EAAE,QAAQ,CAAC;KACvD,CAAC,CAAC;AACL,CAAC"}