@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
package/dist/paypal.js ADDED
@@ -0,0 +1,58 @@
1
+ /**
2
+ * PayPal's amount view for the REST APIs (Orders v2, Payments v2):
3
+ * https://developer.paypal.com/api/rest/reference/currency-codes/, encoded in data/paypal.json.
4
+ * `value` is a decimal string in major units, with at most 15 digits before the point:
5
+ * - HUF, JPY and TWD don't support decimals: "1000", never "1000.00" (ISO 4217 gives HUF and TWD
6
+ * 2);
7
+ * - every other listed currency has 2 decimals: "10.99".
8
+ * BRL, CNY and MYR are for in-country accounts only; that isn't checked here.
9
+ */
10
+ import { PAYPAL_EXPONENTS } from './generated/paypal.js';
11
+ import {} from './money.js';
12
+ import { fromProcessorDecimal, toProcessorDecimal } from './processor.js';
13
+ export { PAYPAL_EXPONENTS };
14
+ /** The `value` pattern from PayPal's Orders v2 schema. */
15
+ const VALUE_PATTERN = /^((-?[0-9]+)|(-?([0-9]+)?[.][0-9]+))$/;
16
+ /** PayPal allows at most 15 digits before the decimal point. */
17
+ const MAX_INTEGER_DIGITS = 15;
18
+ /** The `value` field's maxLength in the Orders v2 schema. */
19
+ const MAX_VALUE_LENGTH = 32;
20
+ /** The number of decimals PayPal takes for a currency (JPY, HUF, TWD 0; the others 2). */
21
+ export function paypalExponent(currency) {
22
+ const exponent = PAYPAL_EXPONENTS[currency.toUpperCase()];
23
+ if (exponent === undefined) {
24
+ throw new RangeError(`${currency} is not a PayPal currency`);
25
+ }
26
+ return exponent;
27
+ }
28
+ /** Whether PayPal lists the currency (case-insensitive). */
29
+ export function isPayPalCurrency(currency) {
30
+ return PAYPAL_EXPONENTS[currency.toUpperCase()] !== undefined;
31
+ }
32
+ /**
33
+ * The exact `value` string: toPayPalValue(money('10.99', 'USD')) === '10.99', HUF 1000 -> '1000'.
34
+ * Throws a RangeError for negative amounts (refunds are sent as positive amounts).
35
+ */
36
+ export function toPayPalValue(money, options) {
37
+ const rounding = options?.rounding ?? 'unnecessary';
38
+ // "The amount must be a positive number"; zero stays allowed because the same money object is
39
+ // used for breakdown fields such as a zero tax_total. Refunds are positive amounts.
40
+ const value = toProcessorDecimal('PayPal', money, paypalExponent(money.currency), rounding, 'nonNegative');
41
+ const integerDigits = value.replace('-', '').split('.')[0];
42
+ if (integerDigits.length > MAX_INTEGER_DIGITS) {
43
+ throw new RangeError(`${money} is too large for PayPal (at most 15 digits before the decimal point)`);
44
+ }
45
+ return value;
46
+ }
47
+ /** A PayPal `money` object: `{ currency_code, value }`. */
48
+ export function toPayPal(money, options) {
49
+ return { currency_code: money.currency.toUpperCase(), value: toPayPalValue(money, options) };
50
+ }
51
+ /** Reads a PayPal `money` object exactly: fromPayPal({ currency_code: 'USD', value: '230.00' }). */
52
+ export function fromPayPal(amount) {
53
+ const code = amount.currency_code.toUpperCase();
54
+ // Validates the currency before parsing, so an unlisted currency is the error reported.
55
+ paypalExponent(code);
56
+ return fromProcessorDecimal('PayPal', amount.value, code, VALUE_PATTERN, MAX_VALUE_LENGTH);
57
+ }
58
+ //# sourceMappingURL=paypal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paypal.js","sourceRoot":"","sources":["../src/paypal.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAkC,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAG1E,OAAO,EAAE,gBAAgB,EAAE,CAAC;AAE5B,0DAA0D;AAC1D,MAAM,aAAa,GAAG,uCAAuC,CAAC;AAE9D,gEAAgE;AAChE,MAAM,kBAAkB,GAAG,EAAE,CAAC;AAE9B,6DAA6D;AAC7D,MAAM,gBAAgB,GAAG,EAAE,CAAC;AAE5B,0FAA0F;AAC1F,MAAM,UAAU,cAAc,CAAC,QAAgB;IAC7C,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC;IAC1D,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,MAAM,IAAI,UAAU,CAAC,GAAG,QAAQ,2BAA2B,CAAC,CAAC;IAC/D,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC/C,OAAO,gBAAgB,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,KAAK,SAAS,CAAC;AAChE,CAAC;AAWD;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,KAAY,EAAE,OAA6B;IACvE,MAAM,QAAQ,GAAG,OAAO,EAAE,QAAQ,IAAI,aAAa,CAAC;IAEpD,8FAA8F;IAC9F,oFAAoF;IACpF,MAAM,KAAK,GAAG,kBAAkB,CAC9B,QAAQ,EACR,KAAK,EACL,cAAc,CAAC,KAAK,CAAC,QAAQ,CAAC,EAC9B,QAAQ,EACR,aAAa,CACd,CAAC;IAEF,MAAM,aAAa,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC;IAC5D,IAAI,aAAa,CAAC,MAAM,GAAG,kBAAkB,EAAE,CAAC;QAC9C,MAAM,IAAI,UAAU,CAClB,GAAG,KAAK,uEAAuE,CAChF,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,QAAQ,CACtB,KAAY,EACZ,OAA6B;IAE7B,OAAO,EAAE,aAAa,EAAE,KAAK,CAAC,QAAQ,CAAC,WAAW,EAAE,EAAE,KAAK,EAAE,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,CAAC;AAC/F,CAAC;AAED,oGAAoG;AACpG,MAAM,UAAU,UAAU,CAA0B,MAGnD;IACC,MAAM,IAAI,GAAG,MAAM,CAAC,aAAa,CAAC,WAAW,EAAkB,CAAC;IAEhE,wFAAwF;IACxF,cAAc,CAAC,IAAI,CAAC,CAAC;IACrB,OAAO,oBAAoB,CAAC,QAAQ,EAAE,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,gBAAgB,CAAC,CAAC;AAC7F,CAAC"}
package/dist/pg.d.ts ADDED
@@ -0,0 +1,100 @@
1
+ import { type CurrencyInput, type Money } from './money.js';
2
+ import { type DecimalColumnSize } from './sql.js';
3
+ export { DEFAULT_DECIMAL_SIZE, type DecimalColumnSize } from './sql.js';
4
+ /** A text-format value parser, as node-postgres calls it. */
5
+ export type TypeParser = (text: string) => unknown;
6
+ /** The part of `pg.types` (or a client's `types` option) these parsers build on. */
7
+ export interface TypeParserSource {
8
+ getTypeParser(oid: number, format?: 'text' | 'binary'): TypeParser;
9
+ }
10
+ /** The OIDs of a composite money type and its array type, from `moneyTypeOids`. */
11
+ export interface MoneyTypeOids {
12
+ readonly oid: number;
13
+ readonly arrayOid: number;
14
+ }
15
+ /** Options for `exactTypes`. */
16
+ export interface ExactTypesOptions {
17
+ /** Also parse this composite money type (and its array) into Money. */
18
+ readonly money?: MoneyTypeOids;
19
+ /**
20
+ * How BIGINT (and BIGINT[]) values come back: `'bigint'` (the default) or `'string'`, pg's own
21
+ * exact format. A bigint is what `fromMinor` takes, but it applies to every BIGINT on the client,
22
+ * `count(*)` and bigserial ids included, and `JSON.stringify` throws on it.
23
+ */
24
+ readonly int8?: 'bigint' | 'string';
25
+ }
26
+ /**
27
+ * BIGINT text as a bigint. node-postgres returns it as a string by default, which is exact but not
28
+ * a number type the Money constructors accept.
29
+ */
30
+ export declare function parseBigInt(text: string): bigint;
31
+ /**
32
+ * NUMERIC text, checked and returned as the exact decimal string. Postgres NUMERIC can hold `NaN`
33
+ * and `±Infinity`, which are not amounts, so they throw.
34
+ */
35
+ export declare function parseNumeric(text: string): string;
36
+ /**
37
+ * Splits Postgres array text (`{1,2,NULL}`, `{{1,2},{3,4}}`, `{"(1.00,EUR)"}`) into nested arrays of
38
+ * element text, with `null` for NULL. Quoted elements are unescaped.
39
+ */
40
+ export declare function parseArray(text: string): unknown[];
41
+ /**
42
+ * Money from the text of the composite type, `(12.34,EUR)`. The amount keeps the scale it was
43
+ * stored with, and never less than the currency's exponent. NULL fields, `NaN`, `Infinity` and
44
+ * malformed text throw.
45
+ */
46
+ export declare function parseMoneyComposite(text: string): Money;
47
+ /**
48
+ * The composite type's text for a query parameter: `(12.34,"EUR")`, at the Money's own scale. The
49
+ * currency is always quoted and escaped, so custom codes containing `\`, `"`, `,` or `)` survive.
50
+ * Cast it in SQL (`$1::ducat_money`) where Postgres can't infer the type.
51
+ */
52
+ export declare function toMoneyComposite(money: Money): string;
53
+ /**
54
+ * Type parsers for node-postgres that never turn an amount into a float: BIGINT as bigint, NUMERIC
55
+ * as an exact string (rejecting `NaN` and `Infinity`), their arrays the same way (pg's default
56
+ * parses NUMERIC arrays as floats), and optionally the composite money type as Money. Every other
57
+ * type uses `base`.
58
+ *
59
+ * new pg.Pool({ types: exactTypes(pg.types, { money: await moneyTypeOids(client) }) })
60
+ */
61
+ export declare function exactTypes(base: TypeParserSource, options?: ExactTypesOptions): TypeParserSource;
62
+ /** The default name of the composite money type. */
63
+ export declare const MONEY_TYPE_NAME = "ducat_money";
64
+ /**
65
+ * The DDL for a composite money type, `(amount numeric, currency text)`, and a `sum` aggregate over
66
+ * it that throws on mixed currencies, and on a value with a NULL amount or currency. The amount is
67
+ * an unconstrained NUMERIC, so it keeps every digit and its scale. A schema-qualified name puts the
68
+ * type, its add function and the aggregate in that schema.
69
+ *
70
+ * Run the statements once, in order, in a migration: they are not idempotent, and a second run
71
+ * fails with `duplicate_object`.
72
+ *
73
+ * for (const statement of moneyTypeSql()) await client.query(statement);
74
+ * SELECT sum(price) FROM items; -- (37.50,EUR)
75
+ */
76
+ export declare function moneyTypeSql(name?: string): string[];
77
+ /** The part of a pg Client or Pool that `moneyTypeOids` uses. */
78
+ export interface Queryable {
79
+ query(sql: string, values: unknown[]): Promise<{
80
+ rows: {
81
+ oid: number | string;
82
+ typarray: number | string;
83
+ }[];
84
+ }>;
85
+ }
86
+ /**
87
+ * Looks up the OIDs of the composite money type, for `exactTypes`. Run it once at start-up on a
88
+ * client without the money parser. OIDs differ between databases, and change if the type is
89
+ * dropped and recreated; values of a type whose OID `exactTypes` wasn't given come back as pg's
90
+ * raw text. With a type per schema, look up and pass each one's OIDs.
91
+ */
92
+ export declare function moneyTypeOids(client: Queryable, name?: string): Promise<MoneyTypeOids>;
93
+ /**
94
+ * The exact decimal string for a NUMERIC(precision, scale) column, or a throw if Postgres would
95
+ * change it: it rounds extra decimals silently on insert, and rejects too many integer digits.
96
+ * Unlike the column types, any scale up to the column's is accepted, and trailing zeros beyond it
97
+ * are dropped since they don't change the value.
98
+ */
99
+ export declare function toNumeric<C extends CurrencyInput>(money: Money<C>, size: DecimalColumnSize): string;
100
+ //# sourceMappingURL=pg.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pg.d.ts","sourceRoot":"","sources":["../src/pg.ts"],"names":[],"mappings":"AAYA,OAAO,EAAkC,KAAK,aAAa,EAAE,KAAK,KAAK,EAAE,MAAM,YAAY,CAAC;AAC5F,OAAO,EAAwC,KAAK,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAExF,OAAO,EAAE,oBAAoB,EAAE,KAAK,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAExE,6DAA6D;AAC7D,MAAM,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;AAEnD,oFAAoF;AACpF,MAAM,WAAW,gBAAgB;IAC/B,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,UAAU,CAAC;CACpE;AAED,mFAAmF;AACnF,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,gCAAgC;AAChC,MAAM,WAAW,iBAAiB;IAChC,uEAAuE;IACvE,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC;IAC/B;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC;CACrC;AAUD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKhD;AAQD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKjD;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,EAAE,CA+DlD;AAyED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,CAcvD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAGrD;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,gBAAgB,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,gBAAgB,CA+BhG;AAED,oDAAoD;AACpD,eAAO,MAAM,eAAe,gBAAgB,CAAC;AAM7C;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,IAAI,GAAE,MAAwB,GAAG,MAAM,EAAE,CAsCrE;AAED,iEAAiE;AACjE,MAAM,WAAW,SAAS;IACxB,KAAK,CACH,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,OAAO,EAAE,GAChB,OAAO,CAAC;QAAE,IAAI,EAAE;YAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;YAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;SAAE,EAAE,CAAA;KAAE,CAAC,CAAC;CAC7E;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,SAAS,EACjB,IAAI,GAAE,MAAwB,GAC7B,OAAO,CAAC,aAAa,CAAC,CAUxB;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,aAAa,EAC/C,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EACf,IAAI,EAAE,iBAAiB,GACtB,MAAM,CAqBR"}
package/dist/pg.js ADDED
@@ -0,0 +1,343 @@
1
+ /**
2
+ * `@ducatjs/money/pg`: node-postgres type parsers that keep NUMERIC and BIGINT exact, a Postgres
3
+ * composite type for Money with a `sum` aggregate, and a guard for NUMERIC(p, s) columns.
4
+ *
5
+ * import pg from 'pg';
6
+ * import { exactTypes } from '@ducatjs/money/pg';
7
+ *
8
+ * const pool = new pg.Pool({ types: exactTypes(pg.types) });
9
+ *
10
+ * It imports nothing from pg at run time: pass `pg.types` in.
11
+ */
12
+ import { currencyExponent } from './currency.js';
13
+ import { money as parseMoney, toDecimal } from './money.js';
14
+ import { checkDecimalSize, checkIntegerDigits } from './sql.js';
15
+ export { DEFAULT_DECIMAL_SIZE } from './sql.js';
16
+ const INT8_OID = 20;
17
+ const NUMERIC_OID = 1700;
18
+ const INT8_ARRAY_OID = 1016;
19
+ const NUMERIC_ARRAY_OID = 1231;
20
+ const INTEGER_TEXT = /^-?\d+$/;
21
+ const NUMERIC_TEXT = /^-?\d+(?:\.\d+)?$/;
22
+ /**
23
+ * BIGINT text as a bigint. node-postgres returns it as a string by default, which is exact but not
24
+ * a number type the Money constructors accept.
25
+ */
26
+ export function parseBigInt(text) {
27
+ if (!INTEGER_TEXT.test(text)) {
28
+ throw new SyntaxError(`Expected BIGINT text, got "${text}"`);
29
+ }
30
+ return BigInt(text);
31
+ }
32
+ /** BIGINT text, checked and kept as the string. */
33
+ function checkBigIntText(text) {
34
+ parseBigInt(text);
35
+ return text;
36
+ }
37
+ /**
38
+ * NUMERIC text, checked and returned as the exact decimal string. Postgres NUMERIC can hold `NaN`
39
+ * and `±Infinity`, which are not amounts, so they throw.
40
+ */
41
+ export function parseNumeric(text) {
42
+ if (!NUMERIC_TEXT.test(text)) {
43
+ throw new SyntaxError(`Expected a finite NUMERIC, got "${text}"`);
44
+ }
45
+ return text;
46
+ }
47
+ /**
48
+ * Splits Postgres array text (`{1,2,NULL}`, `{{1,2},{3,4}}`, `{"(1.00,EUR)"}`) into nested arrays of
49
+ * element text, with `null` for NULL. Quoted elements are unescaped.
50
+ */
51
+ export function parseArray(text) {
52
+ let position = 0;
53
+ // an array may start with explicit bounds, `[1:2]={...}`
54
+ if (text.startsWith('[')) {
55
+ position = text.indexOf('=') + 1;
56
+ }
57
+ function parseLevel() {
58
+ if (text[position] !== '{') {
59
+ throw new SyntaxError(`Malformed array text "${text}"`);
60
+ }
61
+ position++;
62
+ const items = [];
63
+ if (text[position] === '}') {
64
+ position++;
65
+ return items;
66
+ }
67
+ for (;;) {
68
+ if (text[position] === '{') {
69
+ items.push(parseLevel());
70
+ }
71
+ else if (text[position] === '"') {
72
+ position++;
73
+ let value = '';
74
+ while (text[position] !== '"') {
75
+ if (position >= text.length) {
76
+ throw new SyntaxError(`Unterminated quote in array text "${text}"`);
77
+ }
78
+ if (text[position] === '\\') {
79
+ position++;
80
+ }
81
+ value += text[position];
82
+ position++;
83
+ }
84
+ position++;
85
+ items.push(value);
86
+ }
87
+ else {
88
+ const start = position;
89
+ while (position < text.length && text[position] !== ',' && text[position] !== '}') {
90
+ position++;
91
+ }
92
+ const value = text.slice(start, position);
93
+ items.push(value === 'NULL' ? null : value);
94
+ }
95
+ if (text[position] === ',') {
96
+ position++;
97
+ continue;
98
+ }
99
+ if (text[position] === '}') {
100
+ position++;
101
+ return items;
102
+ }
103
+ throw new SyntaxError(`Malformed array text "${text}"`);
104
+ }
105
+ }
106
+ const result = parseLevel();
107
+ if (position !== text.length) {
108
+ throw new SyntaxError(`Malformed array text "${text}"`);
109
+ }
110
+ return result;
111
+ }
112
+ function mapArray(items, parseElement) {
113
+ return items.map((item) => {
114
+ if (item === null) {
115
+ return null;
116
+ }
117
+ if (Array.isArray(item)) {
118
+ return mapArray(item, parseElement);
119
+ }
120
+ return parseElement(item);
121
+ });
122
+ }
123
+ /**
124
+ * Splits record text, `(12.34,EUR)` or `(12.34,"A\\B")`, into its fields, with `null` for an empty
125
+ * unquoted field. Quoted fields are unescaped: Postgres doubles `"` and `\` inside them on output,
126
+ * and accepts a backslash before any character on input.
127
+ */
128
+ function parseRecord(text) {
129
+ if (!text.startsWith('(') || !text.endsWith(')')) {
130
+ throw new SyntaxError(`Expected record text in parentheses, got "${text}"`);
131
+ }
132
+ const fields = [];
133
+ let position = 1;
134
+ const end = text.length - 1;
135
+ for (;;) {
136
+ let field = '';
137
+ let isQuotedOrNonEmpty = false;
138
+ while (position < end && text[position] !== ',') {
139
+ const character = text[position];
140
+ if (character === '"') {
141
+ isQuotedOrNonEmpty = true;
142
+ position++;
143
+ for (;;) {
144
+ if (position >= end) {
145
+ throw new SyntaxError(`Unbalanced quote in record text "${text}"`);
146
+ }
147
+ const quoted = text[position];
148
+ if (quoted === '\\') {
149
+ field += text[position + 1] ?? '';
150
+ position += 2;
151
+ }
152
+ else if (quoted === '"' && text[position + 1] === '"') {
153
+ field += '"';
154
+ position += 2;
155
+ }
156
+ else if (quoted === '"') {
157
+ position++;
158
+ break;
159
+ }
160
+ else {
161
+ field += quoted;
162
+ position++;
163
+ }
164
+ }
165
+ continue;
166
+ }
167
+ if (character === '\\') {
168
+ field += text[position + 1] ?? '';
169
+ position += 2;
170
+ }
171
+ else {
172
+ field += character;
173
+ position++;
174
+ }
175
+ isQuotedOrNonEmpty = true;
176
+ }
177
+ fields.push(isQuotedOrNonEmpty ? field : null);
178
+ if (position >= end) {
179
+ return fields;
180
+ }
181
+ position++;
182
+ }
183
+ }
184
+ /**
185
+ * Money from the text of the composite type, `(12.34,EUR)`. The amount keeps the scale it was
186
+ * stored with, and never less than the currency's exponent. NULL fields, `NaN`, `Infinity` and
187
+ * malformed text throw.
188
+ */
189
+ export function parseMoneyComposite(text) {
190
+ const fields = parseRecord(text);
191
+ if (fields.length !== 2) {
192
+ throw new SyntaxError(`Expected (amount,currency) composite text, got "${text}"`);
193
+ }
194
+ const [amount, currency] = fields;
195
+ if (amount === null || amount === undefined || currency === null || currency === undefined) {
196
+ throw new TypeError(`A money composite needs both an amount and a currency, got "${text}"`);
197
+ }
198
+ parseNumeric(amount);
199
+ const fractionDigits = amount.includes('.') ? amount.length - amount.indexOf('.') - 1 : 0;
200
+ const scale = Math.max(fractionDigits, currencyExponent(currency));
201
+ return parseMoney(amount, currency, { scale });
202
+ }
203
+ /**
204
+ * The composite type's text for a query parameter: `(12.34,"EUR")`, at the Money's own scale. The
205
+ * currency is always quoted and escaped, so custom codes containing `\`, `"`, `,` or `)` survive.
206
+ * Cast it in SQL (`$1::ducat_money`) where Postgres can't infer the type.
207
+ */
208
+ export function toMoneyComposite(money) {
209
+ const currency = money.currency.replace(/["\\]/g, (character) => `\\${character}`);
210
+ return `(${toDecimal(money)},"${currency}")`;
211
+ }
212
+ /**
213
+ * Type parsers for node-postgres that never turn an amount into a float: BIGINT as bigint, NUMERIC
214
+ * as an exact string (rejecting `NaN` and `Infinity`), their arrays the same way (pg's default
215
+ * parses NUMERIC arrays as floats), and optionally the composite money type as Money. Every other
216
+ * type uses `base`.
217
+ *
218
+ * new pg.Pool({ types: exactTypes(pg.types, { money: await moneyTypeOids(client) }) })
219
+ */
220
+ export function exactTypes(base, options) {
221
+ const moneyOids = options?.money;
222
+ const parseInt8 = options?.int8 === 'string' ? checkBigIntText : parseBigInt;
223
+ return {
224
+ getTypeParser(oid, format) {
225
+ // the binary format is only used when a query asks for it; leave it to pg
226
+ if (format === 'binary') {
227
+ return base.getTypeParser(oid, format);
228
+ }
229
+ if (oid === INT8_OID) {
230
+ return parseInt8;
231
+ }
232
+ if (oid === NUMERIC_OID) {
233
+ return parseNumeric;
234
+ }
235
+ if (oid === INT8_ARRAY_OID) {
236
+ return (text) => mapArray(parseArray(text), parseInt8);
237
+ }
238
+ if (oid === NUMERIC_ARRAY_OID) {
239
+ return (text) => mapArray(parseArray(text), parseNumeric);
240
+ }
241
+ if (moneyOids !== undefined && oid === moneyOids.oid) {
242
+ return parseMoneyComposite;
243
+ }
244
+ if (moneyOids !== undefined && oid === moneyOids.arrayOid) {
245
+ return (text) => mapArray(parseArray(text), parseMoneyComposite);
246
+ }
247
+ return base.getTypeParser(oid, format);
248
+ },
249
+ };
250
+ }
251
+ /** The default name of the composite money type. */
252
+ export const MONEY_TYPE_NAME = 'ducat_money';
253
+ const IDENTIFIER = /^[a-z_][a-z0-9_]*(?:\.[a-z_][a-z0-9_]*)?$/;
254
+ // Postgres truncates longer names, which would make `name` and `name_add` collide with others
255
+ const MAX_IDENTIFIER_LENGTH = 63;
256
+ /**
257
+ * The DDL for a composite money type, `(amount numeric, currency text)`, and a `sum` aggregate over
258
+ * it that throws on mixed currencies, and on a value with a NULL amount or currency. The amount is
259
+ * an unconstrained NUMERIC, so it keeps every digit and its scale. A schema-qualified name puts the
260
+ * type, its add function and the aggregate in that schema.
261
+ *
262
+ * Run the statements once, in order, in a migration: they are not idempotent, and a second run
263
+ * fails with `duplicate_object`.
264
+ *
265
+ * for (const statement of moneyTypeSql()) await client.query(statement);
266
+ * SELECT sum(price) FROM items; -- (37.50,EUR)
267
+ */
268
+ export function moneyTypeSql(name = MONEY_TYPE_NAME) {
269
+ if (!IDENTIFIER.test(name)) {
270
+ throw new RangeError(`"${name}" is not a plain lower-case SQL name (optionally schema.name)`);
271
+ }
272
+ const dot = name.indexOf('.');
273
+ const schemaPrefix = dot < 0 ? '' : name.slice(0, dot + 1);
274
+ const typeName = name.slice(dot + 1);
275
+ if (`${typeName}_add`.length > MAX_IDENTIFIER_LENGTH) {
276
+ throw new RangeError(`"${typeName}" is too long for a Postgres name with an "_add" suffix`);
277
+ }
278
+ const add = `${name}_add`;
279
+ return [
280
+ `CREATE TYPE ${name} AS (amount numeric, currency text)`,
281
+ // search_path FROM CURRENT: the cast below resolves the same way whatever the caller's path
282
+ `CREATE FUNCTION ${add}(total ${name}, item ${name}) RETURNS ${name}
283
+ LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE SET search_path FROM CURRENT AS $$
284
+ BEGIN
285
+ IF item IS NULL THEN
286
+ RETURN total;
287
+ END IF;
288
+ IF item.amount IS NULL OR item.currency IS NULL THEN
289
+ RAISE EXCEPTION 'a money value needs both an amount and a currency'
290
+ USING ERRCODE = 'null_value_not_allowed';
291
+ END IF;
292
+ IF total IS NULL THEN
293
+ RETURN item;
294
+ END IF;
295
+ IF total.currency IS DISTINCT FROM item.currency THEN
296
+ RAISE EXCEPTION 'cannot add % and % amounts', total.currency, item.currency
297
+ USING ERRCODE = 'data_exception';
298
+ END IF;
299
+ RETURN ROW(total.amount + item.amount, total.currency)::${name};
300
+ END
301
+ $$`,
302
+ `CREATE AGGREGATE ${schemaPrefix}sum(${name}) ` +
303
+ `(SFUNC = ${add}, STYPE = ${name}, COMBINEFUNC = ${add}, PARALLEL = SAFE)`,
304
+ ];
305
+ }
306
+ /**
307
+ * Looks up the OIDs of the composite money type, for `exactTypes`. Run it once at start-up on a
308
+ * client without the money parser. OIDs differ between databases, and change if the type is
309
+ * dropped and recreated; values of a type whose OID `exactTypes` wasn't given come back as pg's
310
+ * raw text. With a type per schema, look up and pass each one's OIDs.
311
+ */
312
+ export async function moneyTypeOids(client, name = MONEY_TYPE_NAME) {
313
+ const result = await client.query('SELECT oid, typarray FROM pg_type WHERE oid = to_regtype($1)', [name]);
314
+ const row = result.rows[0];
315
+ if (row === undefined) {
316
+ throw new RangeError(`No type "${name}" in this database; run moneyTypeSql() first`);
317
+ }
318
+ return { oid: Number(row.oid), arrayOid: Number(row.typarray) };
319
+ }
320
+ /**
321
+ * The exact decimal string for a NUMERIC(precision, scale) column, or a throw if Postgres would
322
+ * change it: it rounds extra decimals silently on insert, and rejects too many integer digits.
323
+ * Unlike the column types, any scale up to the column's is accepted, and trailing zeros beyond it
324
+ * are dropped since they don't change the value.
325
+ */
326
+ export function toNumeric(money, size) {
327
+ checkDecimalSize(money.currency, size);
328
+ const decimal = toDecimal(money);
329
+ const [integerPart, fraction = ''] = decimal.replace('-', '').split('.');
330
+ const significantFraction = fraction.replace(/0+$/, '');
331
+ if (significantFraction.length > size.scale) {
332
+ throw new RangeError(`${money} has ${significantFraction.length} decimals; NUMERIC(${size.precision},${size.scale}) ` +
333
+ `would round it to ${size.scale}`);
334
+ }
335
+ checkIntegerDigits(money, decimal, size);
336
+ if (fraction.length <= size.scale) {
337
+ return decimal;
338
+ }
339
+ const sign = decimal.startsWith('-') ? '-' : '';
340
+ const kept = fraction.slice(0, size.scale);
341
+ return kept === '' ? `${sign}${integerPart}` : `${sign}${integerPart}.${kept}`;
342
+ }
343
+ //# sourceMappingURL=pg.js.map
package/dist/pg.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pg.js","sourceRoot":"","sources":["../src/pg.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { RoundingMode } from '../rounding.js';
2
+ export * from '../adyen.js';
3
+ declare module '../money.js' {
4
+ interface Money<C extends string> {
5
+ /**
6
+ * Adyen `amount` object: `money('15000', 'IDR').toAdyen()` is `{ value: 15000, currency: 'IDR'
7
+ * }`.
8
+ */
9
+ toAdyen(rounding?: RoundingMode): {
10
+ value: number;
11
+ currency: string;
12
+ };
13
+ }
14
+ }
15
+ //# sourceMappingURL=adyen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adyen.d.ts","sourceRoot":"","sources":["../../src/plugins/adyen.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,cAAc,aAAa,CAAC;AAE5B,OAAO,QAAQ,aAAa,CAAC;IAC3B,UAAU,KAAK,CAAC,CAAC,SAAS,MAAM;QAC9B;;;WAGG;QACH,OAAO,CAAC,QAAQ,CAAC,EAAE,YAAY,GAAG;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,MAAM,CAAA;SAAE,CAAC;KACvE;CACF"}
@@ -0,0 +1,10 @@
1
+ /** `@ducatjs/money/adyen`: Adyen's minor-unit view. Importing this module adds `toAdyen`. */
2
+ import { toAdyen } from '../adyen.js';
3
+ import { extendMoney } from '../money.js';
4
+ export * from '../adyen.js';
5
+ extendMoney({
6
+ toAdyen(rounding) {
7
+ return toAdyen(this, rounding);
8
+ },
9
+ }, { owner: '@ducatjs/money/adyen' });
10
+ //# sourceMappingURL=adyen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adyen.js","sourceRoot":"","sources":["../../src/plugins/adyen.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAC7F,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,WAAW,EAAc,MAAM,aAAa,CAAC;AAGtD,cAAc,aAAa,CAAC;AAY5B,WAAW,CACT;IACE,OAAO,CAAc,QAAuB;QAC1C,OAAO,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IACjC,CAAC;CACF,EACD,EAAE,KAAK,EAAE,sBAAsB,EAAE,CAClC,CAAC"}
@@ -0,0 +1,29 @@
1
+ /** `@ducatjs/money/all`: core plus every opt-in module, with all methods installed. */
2
+ export * from '../index.js';
3
+ export { add, subtract, negate, abs, multiply, divide, round, toScale, compare, equals, identical, lessThan, lessThanOrEqual, greaterThan, greaterThanOrEqual, isZero, isPositive, isNegative, sign, min, max, clamp, majorPart, minorPart, toDecimal, toMinor, toMinorNumber, } from '../money.js';
4
+ export { roundingPolicy, isoPolicy, assertScale, type RoundingPolicyOptions } from '../policy.js';
5
+ export * from './allocate.js';
6
+ export * from './tax.js';
7
+ export * from './convert.js';
8
+ export * from './exact.js';
9
+ export * from '../ecb.js';
10
+ export * from '../boc.js';
11
+ export * from '../boe.js';
12
+ export * from '../hmrc.js';
13
+ export * from '../fed.js';
14
+ export * from '../history.js';
15
+ export * from '../stripe-fx.js';
16
+ export * from '../adyen-fx.js';
17
+ export * from './cash.js';
18
+ export * from '../historic.js';
19
+ export * from './format.js';
20
+ export * from '../parse.js';
21
+ export * from './stripe.js';
22
+ export * from './adyen.js';
23
+ export * from './checkout.js';
24
+ export * from './paypal.js';
25
+ export * from './braintree.js';
26
+ export * from './klarna.js';
27
+ export * from './prisma.js';
28
+ export * from './fixed.js';
29
+ //# sourceMappingURL=all.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"all.d.ts","sourceRoot":"","sources":["../../src/plugins/all.ts"],"names":[],"mappings":"AAAA,uFAAuF;AACvF,cAAc,aAAa,CAAC;AAE5B,OAAO,EACL,GAAG,EACH,QAAQ,EACR,MAAM,EACN,GAAG,EACH,QAAQ,EACR,MAAM,EACN,KAAK,EACL,OAAO,EACP,OAAO,EACP,MAAM,EACN,SAAS,EACT,QAAQ,EACR,eAAe,EACf,WAAW,EACX,kBAAkB,EAClB,MAAM,EACN,UAAU,EACV,UAAU,EACV,IAAI,EACJ,GAAG,EACH,GAAG,EACH,KAAK,EACL,SAAS,EACT,SAAS,EACT,SAAS,EACT,OAAO,EACP,aAAa,GACd,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,WAAW,EAAE,KAAK,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAClG,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
@@ -0,0 +1,30 @@
1
+ /** `@ducatjs/money/all`: core plus every opt-in module, with all methods installed. */
2
+ export * from '../index.js';
3
+ // The core Money methods as plain functions too, as in /fn: /all is everything.
4
+ export { add, subtract, negate, abs, multiply, divide, round, toScale, compare, equals, identical, lessThan, lessThanOrEqual, greaterThan, greaterThanOrEqual, isZero, isPositive, isNegative, sign, min, max, clamp, majorPart, minorPart, toDecimal, toMinor, toMinorNumber, } from '../money.js';
5
+ export { roundingPolicy, isoPolicy, assertScale } from '../policy.js';
6
+ export * from './allocate.js';
7
+ export * from './tax.js';
8
+ export * from './convert.js';
9
+ export * from './exact.js';
10
+ export * from '../ecb.js';
11
+ export * from '../boc.js';
12
+ export * from '../boe.js';
13
+ export * from '../hmrc.js';
14
+ export * from '../fed.js';
15
+ export * from '../history.js';
16
+ export * from '../stripe-fx.js';
17
+ export * from '../adyen-fx.js';
18
+ export * from './cash.js';
19
+ export * from '../historic.js';
20
+ export * from './format.js';
21
+ export * from '../parse.js';
22
+ export * from './stripe.js';
23
+ export * from './adyen.js';
24
+ export * from './checkout.js';
25
+ export * from './paypal.js';
26
+ export * from './braintree.js';
27
+ export * from './klarna.js';
28
+ export * from './prisma.js';
29
+ export * from './fixed.js';
30
+ //# sourceMappingURL=all.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"all.js","sourceRoot":"","sources":["../../src/plugins/all.ts"],"names":[],"mappings":"AAAA,uFAAuF;AACvF,cAAc,aAAa,CAAC;AAC5B,gFAAgF;AAChF,OAAO,EACL,GAAG,EACH,QAAQ,EACR,MAAM,EACN,GAAG,EACH,QAAQ,EACR,MAAM,EACN,KAAK,EACL,OAAO,EACP,OAAO,EACP,MAAM,EACN,SAAS,EACT,QAAQ,EACR,eAAe,EACf,WAAW,EACX,kBAAkB,EAClB,MAAM,EACN,UAAU,EACV,UAAU,EACV,IAAI,EACJ,GAAG,EACH,GAAG,EACH,KAAK,EACL,SAAS,EACT,SAAS,EACT,SAAS,EACT,OAAO,EACP,aAAa,GACd,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,WAAW,EAA8B,MAAM,cAAc,CAAC;AAClG,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}