@unchainedshop/plugins 4.6.1 → 4.7.2

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 (327) hide show
  1. package/README.md +0 -2
  2. package/lib/delivery/post/adapter.d.ts +2 -0
  3. package/lib/delivery/{post.js → post/adapter.js} +2 -3
  4. package/lib/delivery/post/index.d.ts +4 -0
  5. package/lib/delivery/post/index.js +10 -0
  6. package/lib/delivery/send-message/adapter.d.ts +2 -0
  7. package/lib/delivery/{send-message.js → send-message/adapter.js} +2 -3
  8. package/lib/delivery/send-message/index.d.ts +4 -0
  9. package/lib/delivery/send-message/index.js +10 -0
  10. package/lib/delivery/stores/adapter.d.ts +2 -0
  11. package/lib/delivery/{stores.js → stores/adapter.js} +2 -3
  12. package/lib/delivery/stores/index.d.ts +4 -0
  13. package/lib/delivery/stores/index.js +10 -0
  14. package/lib/enrollments/licensed/adapter.d.ts +6 -0
  15. package/lib/enrollments/{licensed.js → licensed/adapter.js} +2 -3
  16. package/lib/enrollments/licensed/index.d.ts +4 -0
  17. package/lib/enrollments/licensed/index.js +10 -0
  18. package/lib/events/node-event-emitter.d.ts +3 -1
  19. package/lib/events/node-event-emitter.js +3 -3
  20. package/lib/files/gridfs/adapter.d.ts +2 -2
  21. package/lib/files/gridfs/adapter.js +2 -5
  22. package/lib/files/gridfs/api.d.ts +7 -0
  23. package/lib/files/gridfs/api.js +163 -0
  24. package/lib/files/gridfs/index.d.ts +5 -4
  25. package/lib/files/gridfs/index.js +30 -3
  26. package/lib/files/minio/adapter.d.ts +4 -0
  27. package/lib/files/minio/adapter.js +160 -0
  28. package/lib/files/minio/api.d.ts +2 -0
  29. package/lib/files/minio/api.js +41 -0
  30. package/lib/files/minio/index.d.ts +4 -5
  31. package/lib/files/minio/index.js +18 -157
  32. package/lib/files/temp-upload/api.d.ts +6 -0
  33. package/lib/files/temp-upload/api.js +49 -0
  34. package/lib/files/temp-upload/index.d.ts +3 -0
  35. package/lib/files/temp-upload/index.js +15 -0
  36. package/lib/filters/local-search/adapter.d.ts +2 -0
  37. package/lib/filters/{local-search.js → local-search/adapter.js} +2 -12
  38. package/lib/filters/local-search/index.d.ts +4 -0
  39. package/lib/filters/local-search/index.js +16 -0
  40. package/lib/filters/strict-equal/adapter.d.ts +2 -0
  41. package/lib/filters/{strict-equal.js → strict-equal/adapter.js} +2 -3
  42. package/lib/filters/strict-equal/index.d.ts +4 -0
  43. package/lib/filters/strict-equal/index.js +10 -0
  44. package/lib/payment/apple-iap/adapter.d.ts +2 -1
  45. package/lib/payment/apple-iap/adapter.js +2 -3
  46. package/lib/payment/apple-iap/api.d.ts +2 -0
  47. package/lib/payment/apple-iap/{handler-fastify.js → api.js} +47 -30
  48. package/lib/payment/apple-iap/index.d.ts +6 -4
  49. package/lib/payment/apple-iap/index.js +28 -3
  50. package/lib/payment/cryptopay/adapter.d.ts +2 -0
  51. package/lib/payment/cryptopay/{plugin.js → adapter.js} +2 -4
  52. package/lib/payment/cryptopay/api.d.ts +2 -0
  53. package/lib/payment/cryptopay/api.js +23 -0
  54. package/lib/payment/cryptopay/index.d.ts +5 -4
  55. package/lib/payment/cryptopay/index.js +31 -3
  56. package/lib/payment/datatrans-v2/adapter.d.ts +2 -0
  57. package/lib/payment/datatrans-v2/adapter.js +406 -0
  58. package/lib/payment/datatrans-v2/api.d.ts +2 -0
  59. package/lib/payment/datatrans-v2/api.js +108 -0
  60. package/lib/payment/datatrans-v2/index.d.ts +4 -1
  61. package/lib/payment/datatrans-v2/index.js +17 -400
  62. package/lib/payment/invoice/adapter.d.ts +2 -0
  63. package/lib/payment/{invoice.js → invoice/adapter.js} +2 -3
  64. package/lib/payment/invoice/index.d.ts +4 -0
  65. package/lib/payment/invoice/index.js +10 -0
  66. package/lib/payment/invoice-prepaid/adapter.d.ts +2 -0
  67. package/lib/payment/{invoice-prepaid.js → invoice-prepaid/adapter.js} +2 -3
  68. package/lib/payment/invoice-prepaid/index.d.ts +4 -0
  69. package/lib/payment/invoice-prepaid/index.js +10 -0
  70. package/lib/payment/payrexx/adapter.d.ts +2 -0
  71. package/lib/payment/payrexx/adapter.js +161 -0
  72. package/lib/payment/payrexx/api.d.ts +2 -0
  73. package/lib/payment/payrexx/api.js +97 -0
  74. package/lib/payment/payrexx/index.d.ts +4 -1
  75. package/lib/payment/payrexx/index.js +19 -158
  76. package/lib/payment/postfinance-checkout/adapter.d.ts +2 -0
  77. package/lib/payment/postfinance-checkout/adapter.js +189 -0
  78. package/lib/payment/postfinance-checkout/index.d.ts +5 -0
  79. package/lib/payment/postfinance-checkout/index.js +25 -186
  80. package/lib/payment/postfinance-checkout/webhook.d.ts +2 -0
  81. package/lib/payment/postfinance-checkout/webhook.js +48 -0
  82. package/lib/payment/saferpay/adapter.js +1 -2
  83. package/lib/payment/saferpay/index.d.ts +5 -4
  84. package/lib/payment/saferpay/index.js +29 -3
  85. package/lib/payment/saferpay/webhook.d.ts +2 -0
  86. package/lib/payment/saferpay/webhook.js +64 -0
  87. package/lib/payment/stripe/adapter.d.ts +2 -0
  88. package/lib/payment/stripe/adapter.js +121 -0
  89. package/lib/payment/stripe/api.d.ts +6 -0
  90. package/lib/payment/stripe/api.js +165 -0
  91. package/lib/payment/stripe/index.d.ts +4 -1
  92. package/lib/payment/stripe/index.js +22 -116
  93. package/lib/payment/stripe/stripe.js +2 -5
  94. package/lib/presets/all.d.ts +1 -70
  95. package/lib/presets/all.js +41 -27
  96. package/lib/presets/base.d.ts +1 -25
  97. package/lib/presets/base.js +56 -25
  98. package/lib/presets/countries/ch.d.ts +1 -2
  99. package/lib/presets/countries/ch.js +7 -2
  100. package/lib/presets/crypto.d.ts +3 -7
  101. package/lib/presets/crypto.js +18 -7
  102. package/lib/pricing/{delivery-swiss-tax.d.ts → delivery-swiss-tax/adapter.d.ts} +1 -0
  103. package/lib/pricing/{delivery-swiss-tax.js → delivery-swiss-tax/adapter.js} +4 -4
  104. package/lib/pricing/delivery-swiss-tax/index.d.ts +4 -0
  105. package/lib/pricing/delivery-swiss-tax/index.js +10 -0
  106. package/lib/pricing/{discount-100-off.d.ts → discount-100-off/adapter.d.ts} +1 -0
  107. package/lib/pricing/{discount-100-off.js → discount-100-off/adapter.js} +2 -2
  108. package/lib/pricing/discount-100-off/index.d.ts +4 -0
  109. package/lib/pricing/discount-100-off/index.js +10 -0
  110. package/lib/pricing/{discount-half-price-manual.d.ts → discount-half-price-manual/adapter.d.ts} +1 -0
  111. package/lib/pricing/{discount-half-price-manual.js → discount-half-price-manual/adapter.js} +2 -2
  112. package/lib/pricing/discount-half-price-manual/index.d.ts +4 -0
  113. package/lib/pricing/discount-half-price-manual/index.js +10 -0
  114. package/lib/pricing/{free-delivery.d.ts → free-delivery/adapter.d.ts} +1 -0
  115. package/lib/pricing/{free-delivery.js → free-delivery/adapter.js} +2 -2
  116. package/lib/pricing/free-delivery/index.d.ts +4 -0
  117. package/lib/pricing/free-delivery/index.js +10 -0
  118. package/lib/pricing/{free-payment.d.ts → free-payment/adapter.d.ts} +1 -0
  119. package/lib/pricing/{free-payment.js → free-payment/adapter.js} +2 -2
  120. package/lib/pricing/free-payment/index.d.ts +4 -0
  121. package/lib/pricing/free-payment/index.js +10 -0
  122. package/lib/pricing/{order-delivery.d.ts → order-delivery/adapter.d.ts} +1 -0
  123. package/lib/pricing/{order-delivery.js → order-delivery/adapter.js} +2 -2
  124. package/lib/pricing/order-delivery/index.d.ts +4 -0
  125. package/lib/pricing/order-delivery/index.js +10 -0
  126. package/lib/pricing/{order-discount.d.ts → order-discount/adapter.d.ts} +1 -0
  127. package/lib/pricing/{order-discount.js → order-discount/adapter.js} +2 -2
  128. package/lib/pricing/order-discount/index.d.ts +4 -0
  129. package/lib/pricing/order-discount/index.js +10 -0
  130. package/lib/pricing/{order-items.d.ts → order-items/adapter.d.ts} +1 -0
  131. package/lib/pricing/{order-items.js → order-items/adapter.js} +2 -2
  132. package/lib/pricing/order-items/index.d.ts +4 -0
  133. package/lib/pricing/order-items/index.js +10 -0
  134. package/lib/pricing/{order-payment.d.ts → order-payment/adapter.d.ts} +1 -0
  135. package/lib/pricing/{order-payment.js → order-payment/adapter.js} +2 -2
  136. package/lib/pricing/order-payment/index.d.ts +4 -0
  137. package/lib/pricing/order-payment/index.js +10 -0
  138. package/lib/pricing/{product-catalog-price.d.ts → product-catalog-price/adapter.d.ts} +1 -0
  139. package/lib/pricing/{product-catalog-price.js → product-catalog-price/adapter.js} +2 -2
  140. package/lib/pricing/product-catalog-price/index.d.ts +4 -0
  141. package/lib/pricing/product-catalog-price/index.js +10 -0
  142. package/lib/pricing/{product-discount.d.ts → product-discount/adapter.d.ts} +1 -0
  143. package/lib/pricing/{product-discount.js → product-discount/adapter.js} +2 -2
  144. package/lib/pricing/product-discount/index.d.ts +4 -0
  145. package/lib/pricing/product-discount/index.js +10 -0
  146. package/lib/pricing/{product-price-rateconversion.d.ts → product-price-rateconversion/adapter.d.ts} +1 -0
  147. package/lib/pricing/{product-price-rateconversion.js → product-price-rateconversion/adapter.js} +2 -2
  148. package/lib/pricing/product-price-rateconversion/index.d.ts +4 -0
  149. package/lib/pricing/product-price-rateconversion/index.js +10 -0
  150. package/lib/pricing/{product-swiss-tax.d.ts → product-swiss-tax/adapter.d.ts} +1 -0
  151. package/lib/pricing/{product-swiss-tax.js → product-swiss-tax/adapter.js} +4 -4
  152. package/lib/pricing/product-swiss-tax/index.d.ts +4 -0
  153. package/lib/pricing/product-swiss-tax/index.js +10 -0
  154. package/lib/quotations/manual/adapter.d.ts +2 -0
  155. package/lib/quotations/{manual.js → manual/adapter.js} +2 -3
  156. package/lib/quotations/manual/index.d.ts +4 -0
  157. package/lib/quotations/manual/index.js +10 -0
  158. package/lib/warehousing/erc-metadata/api.d.ts +12 -0
  159. package/lib/warehousing/erc-metadata/api.js +43 -0
  160. package/lib/warehousing/erc-metadata/index.d.ts +3 -0
  161. package/lib/warehousing/erc-metadata/index.js +15 -0
  162. package/lib/warehousing/eth-minter/adapter.d.ts +2 -0
  163. package/lib/warehousing/{eth-minter.js → eth-minter/adapter.js} +3 -4
  164. package/lib/warehousing/eth-minter/index.d.ts +4 -0
  165. package/lib/warehousing/eth-minter/index.js +10 -0
  166. package/lib/warehousing/store/adapter.d.ts +2 -0
  167. package/lib/warehousing/{store.js → store/adapter.js} +2 -3
  168. package/lib/warehousing/store/index.d.ts +4 -0
  169. package/lib/warehousing/store/index.js +10 -0
  170. package/lib/worker/budgetsms/adapter.d.ts +22 -0
  171. package/lib/worker/{budgetsms.js → budgetsms/adapter.js} +3 -3
  172. package/lib/worker/budgetsms/index.d.ts +4 -0
  173. package/lib/worker/budgetsms/index.js +10 -0
  174. package/lib/worker/bulk-export/adapter.d.ts +3 -0
  175. package/lib/worker/{bulk-export.js → bulk-export/adapter.js} +3 -3
  176. package/lib/worker/bulk-export/index.d.ts +4 -0
  177. package/lib/worker/bulk-export/index.js +10 -0
  178. package/lib/worker/{bulk-import.d.ts → bulk-import/adapter.d.ts} +1 -0
  179. package/lib/worker/{bulk-import.js → bulk-import/adapter.js} +2 -2
  180. package/lib/worker/bulk-import/api.d.ts +7 -0
  181. package/lib/worker/bulk-import/api.js +53 -0
  182. package/lib/worker/bulk-import/index.d.ts +4 -0
  183. package/lib/worker/bulk-import/index.js +18 -0
  184. package/lib/worker/bulkgate/adapter.d.ts +12 -0
  185. package/lib/worker/{bulkgate.js → bulkgate/adapter.js} +3 -3
  186. package/lib/worker/bulkgate/index.d.ts +4 -0
  187. package/lib/worker/bulkgate/index.js +10 -0
  188. package/lib/worker/email/adapter.d.ts +9 -0
  189. package/lib/worker/{email.js → email/adapter.js} +27 -13
  190. package/lib/worker/email/index.d.ts +4 -0
  191. package/lib/worker/email/index.js +10 -0
  192. package/lib/worker/enrollment-order-generator/adapter.d.ts +4 -0
  193. package/lib/worker/{enrollment-order-generator.js → enrollment-order-generator/adapter.js} +2 -2
  194. package/lib/worker/enrollment-order-generator/index.d.ts +4 -0
  195. package/lib/worker/enrollment-order-generator/index.js +13 -0
  196. package/lib/worker/{error-notifications.d.ts → error-notifications/adapter.d.ts} +1 -0
  197. package/lib/worker/{error-notifications.js → error-notifications/adapter.js} +9 -8
  198. package/lib/worker/error-notifications/index.d.ts +4 -0
  199. package/lib/worker/error-notifications/index.js +13 -0
  200. package/lib/worker/{export-token.d.ts → export-token/adapter.d.ts} +1 -1
  201. package/lib/worker/{export-token.js → export-token/adapter.js} +2 -3
  202. package/lib/worker/export-token/index.d.ts +4 -0
  203. package/lib/worker/export-token/index.js +13 -0
  204. package/lib/worker/{external.d.ts → external/adapter.d.ts} +1 -0
  205. package/lib/worker/{external.js → external/adapter.js} +2 -2
  206. package/lib/worker/external/index.d.ts +4 -0
  207. package/lib/worker/external/index.js +10 -0
  208. package/lib/worker/heartbeat/adapter.d.ts +8 -0
  209. package/lib/worker/{heartbeat.js → heartbeat/adapter.js} +3 -3
  210. package/lib/worker/heartbeat/index.d.ts +4 -0
  211. package/lib/worker/heartbeat/index.js +10 -0
  212. package/lib/worker/{http-request.d.ts → http-request/adapter.d.ts} +1 -1
  213. package/lib/worker/{http-request.js → http-request/adapter.js} +2 -3
  214. package/lib/worker/http-request/index.d.ts +4 -0
  215. package/lib/worker/http-request/index.js +10 -0
  216. package/lib/worker/{message.d.ts → message/adapter.d.ts} +1 -0
  217. package/lib/worker/{message.js → message/adapter.js} +2 -2
  218. package/lib/worker/message/index.d.ts +4 -0
  219. package/lib/worker/message/index.js +10 -0
  220. package/lib/worker/push-notification/adapter.d.ts +9 -0
  221. package/lib/worker/{push-notification.js → push-notification/adapter.js} +3 -3
  222. package/lib/worker/push-notification/index.d.ts +4 -0
  223. package/lib/worker/push-notification/index.js +10 -0
  224. package/lib/worker/twilio/adapter.d.ts +8 -0
  225. package/lib/worker/{twilio.js → twilio/adapter.js} +3 -3
  226. package/lib/worker/twilio/index.d.ts +4 -0
  227. package/lib/worker/twilio/index.js +10 -0
  228. package/lib/worker/update-coinbase-rates/adapter.d.ts +4 -0
  229. package/lib/worker/{update-coinbase-rates.js → update-coinbase-rates/adapter.js} +8 -6
  230. package/lib/worker/update-coinbase-rates/index.d.ts +4 -0
  231. package/lib/worker/update-coinbase-rates/index.js +13 -0
  232. package/lib/worker/update-ecb-rates/adapter.d.ts +4 -0
  233. package/lib/worker/{update-ecb-rates.js → update-ecb-rates/adapter.js} +11 -9
  234. package/lib/worker/update-ecb-rates/index.d.ts +4 -0
  235. package/lib/worker/update-ecb-rates/index.js +13 -0
  236. package/lib/worker/{update-token-ownership.d.ts → update-token-ownership/adapter.d.ts} +2 -0
  237. package/lib/worker/{update-token-ownership.js → update-token-ownership/adapter.js} +8 -7
  238. package/lib/worker/update-token-ownership/index.d.ts +4 -0
  239. package/lib/worker/update-token-ownership/index.js +13 -0
  240. package/lib/worker/{zombie-killer.js → zombie-killer/adapter.js} +1 -2
  241. package/lib/worker/zombie-killer/index.d.ts +4 -0
  242. package/lib/worker/zombie-killer/index.js +10 -0
  243. package/package.json +15 -10
  244. package/lib/delivery/post.d.ts +0 -1
  245. package/lib/delivery/send-message.d.ts +0 -1
  246. package/lib/delivery/stores.d.ts +0 -1
  247. package/lib/enrollments/licensed.d.ts +0 -4
  248. package/lib/files/gridfs/handler-express.d.ts +0 -9
  249. package/lib/files/gridfs/handler-express.js +0 -110
  250. package/lib/files/gridfs/handler-fastify.d.ts +0 -3
  251. package/lib/files/gridfs/handler-fastify.js +0 -138
  252. package/lib/files/minio/handler-express.d.ts +0 -2
  253. package/lib/files/minio/handler-express.js +0 -36
  254. package/lib/files/minio/handler-fastify.d.ts +0 -3
  255. package/lib/files/minio/handler-fastify.js +0 -40
  256. package/lib/filters/local-search.d.ts +0 -3
  257. package/lib/filters/strict-equal.d.ts +0 -1
  258. package/lib/payment/apple-iap/handler-express.d.ts +0 -2
  259. package/lib/payment/apple-iap/handler-express.js +0 -103
  260. package/lib/payment/apple-iap/handler-fastify.d.ts +0 -3
  261. package/lib/payment/braintree.d.ts +0 -1
  262. package/lib/payment/braintree.js +0 -138
  263. package/lib/payment/cryptopay/handler-express.d.ts +0 -2
  264. package/lib/payment/cryptopay/handler-express.js +0 -19
  265. package/lib/payment/cryptopay/handler-fastify.d.ts +0 -3
  266. package/lib/payment/cryptopay/handler-fastify.js +0 -17
  267. package/lib/payment/cryptopay/plugin.d.ts +0 -3
  268. package/lib/payment/datatrans-v2/handler-express.d.ts +0 -1
  269. package/lib/payment/datatrans-v2/handler-express.js +0 -71
  270. package/lib/payment/datatrans-v2/handler-fastify.d.ts +0 -2
  271. package/lib/payment/datatrans-v2/handler-fastify.js +0 -71
  272. package/lib/payment/invoice-prepaid.d.ts +0 -1
  273. package/lib/payment/invoice.d.ts +0 -1
  274. package/lib/payment/paypal-checkout.d.ts +0 -1
  275. package/lib/payment/paypal-checkout.js +0 -87
  276. package/lib/payment/payrexx/handler-express.d.ts +0 -1
  277. package/lib/payment/payrexx/handler-express.js +0 -85
  278. package/lib/payment/payrexx/handler-fastify.d.ts +0 -2
  279. package/lib/payment/payrexx/handler-fastify.js +0 -91
  280. package/lib/payment/postfinance-checkout/handler-express.d.ts +0 -1
  281. package/lib/payment/postfinance-checkout/handler-express.js +0 -37
  282. package/lib/payment/postfinance-checkout/handler-fastify.d.ts +0 -2
  283. package/lib/payment/postfinance-checkout/handler-fastify.js +0 -40
  284. package/lib/payment/saferpay/handler-express.d.ts +0 -1
  285. package/lib/payment/saferpay/handler-express.js +0 -59
  286. package/lib/payment/saferpay/handler-fastify.d.ts +0 -2
  287. package/lib/payment/saferpay/handler-fastify.js +0 -62
  288. package/lib/payment/stripe/handler-express.d.ts +0 -5
  289. package/lib/payment/stripe/handler-express.js +0 -121
  290. package/lib/payment/stripe/handler-fastify.d.ts +0 -6
  291. package/lib/payment/stripe/handler-fastify.js +0 -131
  292. package/lib/presets/all-express.d.ts +0 -6
  293. package/lib/presets/all-express.js +0 -26
  294. package/lib/presets/all-fastify.d.ts +0 -6
  295. package/lib/presets/all-fastify.js +0 -49
  296. package/lib/presets/base-express.d.ts +0 -2
  297. package/lib/presets/base-express.js +0 -5
  298. package/lib/presets/base-fastify.d.ts +0 -3
  299. package/lib/presets/base-fastify.js +0 -16
  300. package/lib/presets/crypto-express.d.ts +0 -3
  301. package/lib/presets/crypto-express.js +0 -8
  302. package/lib/presets/crypto-fastify.d.ts +0 -3
  303. package/lib/presets/crypto-fastify.js +0 -11
  304. package/lib/pricing/discount-half-price.d.ts +0 -2
  305. package/lib/pricing/discount-half-price.js +0 -33
  306. package/lib/pricing/order-items-discount.d.ts +0 -2
  307. package/lib/pricing/order-items-discount.js +0 -50
  308. package/lib/pricing/order-round.d.ts +0 -10
  309. package/lib/pricing/order-round.js +0 -135
  310. package/lib/pricing/product-catalog-price-options.d.ts +0 -2
  311. package/lib/pricing/product-catalog-price-options.js +0 -51
  312. package/lib/pricing/product-round.d.ts +0 -10
  313. package/lib/pricing/product-round.js +0 -44
  314. package/lib/quotations/manual.d.ts +0 -1
  315. package/lib/warehousing/eth-minter.d.ts +0 -1
  316. package/lib/warehousing/store.d.ts +0 -1
  317. package/lib/worker/budgetsms.d.ts +0 -9
  318. package/lib/worker/bulk-export.d.ts +0 -2
  319. package/lib/worker/bulkgate.d.ts +0 -1
  320. package/lib/worker/email.d.ts +0 -1
  321. package/lib/worker/enrollment-order-generator.d.ts +0 -1
  322. package/lib/worker/heartbeat.d.ts +0 -1
  323. package/lib/worker/push-notification.d.ts +0 -1
  324. package/lib/worker/twilio.d.ts +0 -1
  325. package/lib/worker/update-coinbase-rates.d.ts +0 -1
  326. package/lib/worker/update-ecb-rates.d.ts +0 -1
  327. /package/lib/worker/{zombie-killer.d.ts → zombie-killer/adapter.d.ts} +0 -0
package/README.md CHANGED
@@ -22,7 +22,6 @@ npm install @unchainedshop/plugins
22
22
  | Stripe | `payment/stripe` | Stripe payment integration |
23
23
  | Datatrans V2 | `payment/datatrans-v2` | Datatrans payment gateway |
24
24
  | Saferpay | `payment/saferpay` | Saferpay payment gateway |
25
- | PayPal Checkout | `payment/paypal-checkout` | PayPal Checkout integration |
26
25
  | Braintree | `payment/braintree` | Braintree payments |
27
26
  | Payrexx | `payment/payrexx` | Payrexx payment gateway |
28
27
  | Apple IAP | `payment/apple-iap` | Apple In-App Purchase |
@@ -134,7 +133,6 @@ All payment plugins implement secure tokenization patterns for PCI DSS SAQ-A eli
134
133
  | Stripe | PaymentIntent/SetupIntent tokenization |
135
134
  | Datatrans | Secure Fields with HMAC-SHA-256 signatures |
136
135
  | Saferpay | Redirect with SHA-256 transaction signatures |
137
- | PayPal | Order ID references |
138
136
  | Braintree | Client SDK tokenization |
139
137
  | Cryptopay | BIP-32 HD wallet address derivation |
140
138
 
@@ -0,0 +1,2 @@
1
+ import { type IDeliveryAdapter } from '@unchainedshop/core';
2
+ export declare const Post: IDeliveryAdapter;
@@ -1,6 +1,6 @@
1
- import { DeliveryAdapter, DeliveryDirector } from '@unchainedshop/core';
1
+ import { DeliveryAdapter } from '@unchainedshop/core';
2
2
  import { DeliveryProviderType } from '@unchainedshop/core-delivery';
3
- const Post = {
3
+ export const Post = {
4
4
  ...DeliveryAdapter,
5
5
  key: 'shop.unchained.post',
6
6
  label: 'Manual',
@@ -20,4 +20,3 @@ const Post = {
20
20
  };
21
21
  },
22
22
  };
23
- DeliveryDirector.registerAdapter(Post);
@@ -0,0 +1,4 @@
1
+ import { type IPlugin } from '@unchainedshop/core';
2
+ export declare const PostPlugin: IPlugin;
3
+ export default PostPlugin;
4
+ export { Post } from './adapter.ts';
@@ -0,0 +1,10 @@
1
+ import {} from '@unchainedshop/core';
2
+ import { Post } from "./adapter.js";
3
+ export const PostPlugin = {
4
+ key: 'shop.unchained.post',
5
+ label: 'Post Delivery Plugin',
6
+ version: '1.0.0',
7
+ adapters: [Post],
8
+ };
9
+ export default PostPlugin;
10
+ export { Post } from "./adapter.js";
@@ -0,0 +1,2 @@
1
+ import { type IDeliveryAdapter } from '@unchainedshop/core';
2
+ export declare const SendMessage: IDeliveryAdapter;
@@ -1,6 +1,6 @@
1
- import { DeliveryAdapter, DeliveryDirector } from '@unchainedshop/core';
1
+ import { DeliveryAdapter } from '@unchainedshop/core';
2
2
  import { DeliveryProviderType } from '@unchainedshop/core-delivery';
3
- const SendMessage = {
3
+ export const SendMessage = {
4
4
  ...DeliveryAdapter,
5
5
  key: 'shop.unchained.delivery.send-message',
6
6
  label: 'Forward via Messaging',
@@ -37,4 +37,3 @@ const SendMessage = {
37
37
  };
38
38
  },
39
39
  };
40
- DeliveryDirector.registerAdapter(SendMessage);
@@ -0,0 +1,4 @@
1
+ import { type IPlugin } from '@unchainedshop/core';
2
+ export declare const SendMessagePlugin: IPlugin;
3
+ export default SendMessagePlugin;
4
+ export { SendMessage } from './adapter.ts';
@@ -0,0 +1,10 @@
1
+ import {} from '@unchainedshop/core';
2
+ import { SendMessage } from "./adapter.js";
3
+ export const SendMessagePlugin = {
4
+ key: 'shop.unchained.delivery.send-message',
5
+ label: 'Send Message Delivery Plugin',
6
+ version: '1.0.0',
7
+ adapters: [SendMessage],
8
+ };
9
+ export default SendMessagePlugin;
10
+ export { SendMessage } from "./adapter.js";
@@ -0,0 +1,2 @@
1
+ import { type IDeliveryAdapter } from '@unchainedshop/core';
2
+ export declare const PickMup: IDeliveryAdapter;
@@ -1,6 +1,6 @@
1
- import { DeliveryAdapter, DeliveryDirector } from '@unchainedshop/core';
1
+ import { DeliveryAdapter } from '@unchainedshop/core';
2
2
  import { DeliveryProviderType } from '@unchainedshop/core-delivery';
3
- const PickMup = {
3
+ export const PickMup = {
4
4
  ...DeliveryAdapter,
5
5
  key: 'shop.unchained.stores',
6
6
  label: 'Pre-configured Stores',
@@ -40,4 +40,3 @@ const PickMup = {
40
40
  };
41
41
  },
42
42
  };
43
- DeliveryDirector.registerAdapter(PickMup);
@@ -0,0 +1,4 @@
1
+ import { type IPlugin } from '@unchainedshop/core';
2
+ export declare const PickMupPlugin: IPlugin;
3
+ export default PickMupPlugin;
4
+ export { PickMup } from './adapter.ts';
@@ -0,0 +1,10 @@
1
+ import {} from '@unchainedshop/core';
2
+ import { PickMup } from "./adapter.js";
3
+ export const PickMupPlugin = {
4
+ key: 'shop.unchained.stores',
5
+ label: 'Pick-up Stores Delivery Plugin',
6
+ version: '1.0.0',
7
+ adapters: [PickMup],
8
+ };
9
+ export default PickMupPlugin;
10
+ export { PickMup } from "./adapter.js";
@@ -0,0 +1,6 @@
1
+ import { type IEnrollmentAdapter } from '@unchainedshop/core';
2
+ export declare const rangeMatcher: (date?: Date) => ({ start, end }: {
3
+ start: any;
4
+ end: any;
5
+ }) => boolean;
6
+ export declare const LicensedEnrollments: IEnrollmentAdapter;
@@ -1,4 +1,4 @@
1
- import { EnrollmentDirector, EnrollmentAdapter } from '@unchainedshop/core';
1
+ import { EnrollmentAdapter } from '@unchainedshop/core';
2
2
  export const rangeMatcher = (date = new Date()) => {
3
3
  const timestamp = date.getTime();
4
4
  return ({ start, end }) => {
@@ -7,7 +7,7 @@ export const rangeMatcher = (date = new Date()) => {
7
7
  return startTimestamp <= timestamp && endTimestamp >= timestamp;
8
8
  };
9
9
  };
10
- const LicensedEnrollments = {
10
+ export const LicensedEnrollments = {
11
11
  ...EnrollmentAdapter,
12
12
  key: 'shop.unchained.enrollments.licensed',
13
13
  version: '1.0.0',
@@ -49,4 +49,3 @@ const LicensedEnrollments = {
49
49
  };
50
50
  },
51
51
  };
52
- EnrollmentDirector.registerAdapter(LicensedEnrollments);
@@ -0,0 +1,4 @@
1
+ import { type IPlugin } from '@unchainedshop/core';
2
+ export declare const LicensedEnrollmentsPlugin: IPlugin;
3
+ export default LicensedEnrollmentsPlugin;
4
+ export { LicensedEnrollments, rangeMatcher } from './adapter.ts';
@@ -0,0 +1,10 @@
1
+ import {} from '@unchainedshop/core';
2
+ import { LicensedEnrollments } from "./adapter.js";
3
+ export const LicensedEnrollmentsPlugin = {
4
+ key: 'shop.unchained.enrollments.licensed',
5
+ label: 'Licensed Enrollments Plugin',
6
+ version: '1.0.0',
7
+ adapters: [LicensedEnrollments],
8
+ };
9
+ export default LicensedEnrollmentsPlugin;
10
+ export { LicensedEnrollments, rangeMatcher } from "./adapter.js";
@@ -1 +1,3 @@
1
- export {};
1
+ import { type EmitAdapter } from '@unchainedshop/events';
2
+ export declare const NodeEventEmitter: () => EmitAdapter;
3
+ export default NodeEventEmitter;
@@ -1,6 +1,6 @@
1
1
  import { EventEmitter } from 'node:events';
2
- import { setEmitAdapter } from '@unchainedshop/events';
3
- const NodeEventEmitter = () => {
2
+ import {} from '@unchainedshop/events';
3
+ export const NodeEventEmitter = () => {
4
4
  const eventEmitter = new EventEmitter();
5
5
  return {
6
6
  publish: (eventName, payload) => {
@@ -11,4 +11,4 @@ const NodeEventEmitter = () => {
11
11
  },
12
12
  };
13
13
  };
14
- setEmitAdapter(NodeEventEmitter());
14
+ export default NodeEventEmitter;
@@ -1,6 +1,6 @@
1
- import { type IFileAdapter } from '@unchainedshop/file-upload';
1
+ import { type IFileAdapter } from '@unchainedshop/core-files';
2
2
  import { type UnchainedCore } from '@unchainedshop/core';
3
- import { type GridFSFileUploadsModule } from './index.ts';
3
+ import { type GridFSFileUploadsModule } from './module.ts';
4
4
  export declare const GridFSAdapter: IFileAdapter<UnchainedCore & {
5
5
  modules: GridFSFileUploadsModule;
6
6
  }>;
@@ -1,12 +1,10 @@
1
1
  import { Readable, PassThrough } from 'node:stream';
2
2
  import { finished, pipeline } from 'node:stream/promises';
3
3
  import mime from 'mime/lite';
4
- import { FileAdapter, FileDirector, buildHashedFilename, resolveExpirationDate, } from '@unchainedshop/file-upload';
5
- import {} from '@unchainedshop/file-upload';
4
+ import { FileAdapter, buildHashedFilename, resolveExpirationDate, filesSettings, } from '@unchainedshop/core-files';
6
5
  import sign from "./sign.js";
7
- import { filesSettings } from '@unchainedshop/core-files';
8
6
  import {} from '@unchainedshop/core';
9
- import {} from "./index.js";
7
+ import {} from "./module.js";
10
8
  const { GRIDFS_PUT_SERVER_PATH = '/gridfs' } = process.env;
11
9
  const bufferToStream = (buffer) => {
12
10
  const stream = new Readable();
@@ -113,4 +111,3 @@ export const GridFSAdapter = {
113
111
  await Promise.all(files.map(async ({ _id, path }) => modules.gridfsFileUploads.removeFileFromBucket(path, _id)));
114
112
  },
115
113
  };
116
- FileDirector.registerAdapter(GridFSAdapter);
@@ -0,0 +1,7 @@
1
+ import { type UnchainedCore } from '@unchainedshop/core';
2
+ import type { GridFSFileUploadsModule } from './module.ts';
3
+ export declare const gridfsRouteHandler: (request: Request, context: UnchainedCore & {
4
+ params: Record<string, string>;
5
+ modules: GridFSFileUploadsModule;
6
+ rawRequest?: any;
7
+ }) => Promise<Response>;
@@ -0,0 +1,163 @@
1
+ import { Readable, PassThrough } from 'node:stream';
2
+ import { finished, pipeline } from 'node:stream/promises';
3
+ import { buildHashedFilename } from '@unchainedshop/core-files';
4
+ import sign from "./sign.js";
5
+ import { getFileAdapter } from '@unchainedshop/core';
6
+ import { createLogger } from '@unchainedshop/logger';
7
+ import { timingSafeStringEqual } from '@unchainedshop/utils';
8
+ const { GRIDFS_PUT_SERVER_PATH = '/gridfs' } = process.env;
9
+ const logger = createLogger('unchained:gridfs');
10
+ export const gridfsRouteHandler = async (request, context) => {
11
+ try {
12
+ const { services, modules, params } = context;
13
+ const directoryName = decodeURIComponent(params.directoryName);
14
+ const fileName = decodeURIComponent(params.fileName);
15
+ const corsHeaders = {
16
+ 'Access-Control-Allow-Methods': 'GET, PUT, OPTIONS',
17
+ 'Access-Control-Allow-Headers': 'Content-Type',
18
+ 'Access-Control-Allow-Origin': '*',
19
+ };
20
+ if (request.method === 'OPTIONS') {
21
+ return new Response(null, {
22
+ status: 200,
23
+ headers: corsHeaders,
24
+ });
25
+ }
26
+ if (request.method === 'PUT') {
27
+ const url = new URL(request.url);
28
+ const signature = url.searchParams.get('s');
29
+ const expiryTimestamp = url.searchParams.get('e');
30
+ if (!signature || !expiryTimestamp) {
31
+ return new Response(JSON.stringify({ error: 'Missing signature or expiry' }), {
32
+ status: 400,
33
+ headers: { 'Content-Type': 'application/json', ...corsHeaders },
34
+ });
35
+ }
36
+ const expiryDate = new Date(parseInt(expiryTimestamp, 10));
37
+ const fileId = await buildHashedFilename(directoryName, fileName, expiryDate);
38
+ const expectedSignature = await sign(directoryName, fileId, expiryDate.getTime());
39
+ if (!(await timingSafeStringEqual(expectedSignature, signature))) {
40
+ logger.error('Invalid signature', { fileId, expiryDate });
41
+ return new Response(JSON.stringify({ error: 'Invalid signature' }), {
42
+ status: 403,
43
+ headers: { 'Content-Type': 'application/json', ...corsHeaders },
44
+ });
45
+ }
46
+ const file = await modules.files.findFile({ fileId });
47
+ if (!file) {
48
+ logger.error('File not found', { fileId });
49
+ return new Response(JSON.stringify({ error: 'File not found' }), {
50
+ status: 404,
51
+ headers: { 'Content-Type': 'application/json', ...corsHeaders },
52
+ });
53
+ }
54
+ if (file.expires === null) {
55
+ logger.error('File already linked', { fileId });
56
+ return new Response(JSON.stringify({ error: 'File already linked' }), {
57
+ status: 400,
58
+ headers: { 'Content-Type': 'application/json', ...corsHeaders },
59
+ });
60
+ }
61
+ const contentType = request.headers.get('Content-Type');
62
+ const type = contentType === 'application/octet-stream' ? file.type || contentType : contentType || file.type;
63
+ const writeStream = await modules.gridfsFileUploads.createWriteStream(directoryName, fileId, fileName, {
64
+ chunkSizeBytes: 1024 * 1024,
65
+ metadata: { 'content-type': type },
66
+ });
67
+ const bodyStream = request.body;
68
+ if (!bodyStream) {
69
+ throw new Error('No request body');
70
+ }
71
+ await pipeline(bodyStream, new PassThrough({ highWaterMark: 1024 * 1024 * 4 }), writeStream);
72
+ await finished(writeStream, { readable: false });
73
+ const { length } = writeStream;
74
+ await services.files.linkFile({ fileId, size: length, type });
75
+ return new Response(JSON.stringify({
76
+ success: true,
77
+ fileId,
78
+ size: length,
79
+ type,
80
+ }), {
81
+ status: 200,
82
+ headers: { 'Content-Type': 'application/json', ...corsHeaders },
83
+ });
84
+ }
85
+ if (request.method === 'GET') {
86
+ const url = new URL(request.url);
87
+ const signature = url.searchParams.get('s');
88
+ const expiryTimestamp = url.searchParams.get('e');
89
+ const fileDocument = await modules.files.findFile({
90
+ url: `${GRIDFS_PUT_SERVER_PATH}/${directoryName}/${fileName}`,
91
+ });
92
+ if (!fileDocument) {
93
+ logger.error('File not found', { fileName });
94
+ return new Response(null, {
95
+ status: 404,
96
+ headers: corsHeaders,
97
+ });
98
+ }
99
+ if (fileDocument?.meta?.isPrivate) {
100
+ if (!expiryTimestamp || !signature) {
101
+ return new Response(JSON.stringify({ error: 'Missing signature or expiry' }), {
102
+ status: 403,
103
+ headers: { 'Content-Type': 'application/json', ...corsHeaders },
104
+ });
105
+ }
106
+ const expiry = parseInt(expiryTimestamp, 10);
107
+ if (expiry <= Date.now()) {
108
+ logger.error('URL Expired', { fileName, expiry });
109
+ return new Response(JSON.stringify({ error: 'Access restricted: Expired.' }), {
110
+ status: 403,
111
+ headers: { 'Content-Type': 'application/json', ...corsHeaders },
112
+ });
113
+ }
114
+ const fileUploadAdapter = getFileAdapter();
115
+ const signedUrl = await fileUploadAdapter.createDownloadURL(fileDocument, expiry);
116
+ const expectedSignature = signedUrl ? new URL(signedUrl, 'file://').searchParams.get('s') : null;
117
+ if (!signedUrl ||
118
+ !expectedSignature ||
119
+ !(await timingSafeStringEqual(expectedSignature, signature))) {
120
+ logger.error('Invalid signature', { fileName, expiry });
121
+ return new Response(JSON.stringify({ error: 'Access restricted: Invalid signature.' }), {
122
+ status: 403,
123
+ headers: { 'Content-Type': 'application/json', ...corsHeaders },
124
+ });
125
+ }
126
+ }
127
+ const file = await modules.gridfsFileUploads.getFileInfo(directoryName, fileDocument._id);
128
+ const readStream = await modules.gridfsFileUploads.createReadStream(directoryName, fileDocument._id);
129
+ const webStream = Readable.toWeb(readStream);
130
+ const headers = {
131
+ ...corsHeaders,
132
+ };
133
+ if (file?.metadata?.['content-type']) {
134
+ headers['Content-Type'] = file.metadata['content-type'];
135
+ }
136
+ if (file?.length) {
137
+ headers['Content-Length'] = file.length.toString();
138
+ }
139
+ return new Response(webStream, {
140
+ status: 200,
141
+ headers,
142
+ });
143
+ }
144
+ return new Response(null, {
145
+ status: 404,
146
+ headers: corsHeaders,
147
+ });
148
+ }
149
+ catch (e) {
150
+ logger.error(e);
151
+ if (e.code === 'ENOENT') {
152
+ return new Response(null, { status: 404 });
153
+ }
154
+ return new Response(JSON.stringify({
155
+ error: e.message || 'Internal Server Error',
156
+ name: e.name,
157
+ code: e.code,
158
+ }), {
159
+ status: 500,
160
+ headers: { 'Content-Type': 'application/json' },
161
+ });
162
+ }
163
+ };
@@ -1,4 +1,5 @@
1
- import './adapter.ts';
2
- import gridfsModules, { type GridFSFileUploadsModule } from './module.ts';
3
- export type { GridFSFileUploadsModule };
4
- export default gridfsModules;
1
+ import type { IPlugin } from '@unchainedshop/core';
2
+ export declare const GridFSPlugin: IPlugin;
3
+ export default GridFSPlugin;
4
+ export { GridFSAdapter } from './adapter.ts';
5
+ export { type GridFSFileUploadsModule } from './module.ts';
@@ -1,3 +1,30 @@
1
- import "./adapter.js";
2
- import gridfsModules, {} from "./module.js";
3
- export default gridfsModules;
1
+ import { createLogger } from '@unchainedshop/logger';
2
+ import { GridFSAdapter } from "./adapter.js";
3
+ import { configureGridFSFileUploadModule } from "./module.js";
4
+ import { gridfsRouteHandler } from "./api.js";
5
+ const { GRIDFS_PUT_SERVER_PATH = '/gridfs', UNCHAINED_GRIDFS_PUT_UPLOAD_SECRET } = process.env;
6
+ const logger = createLogger('unchained:gridfs');
7
+ export const GridFSPlugin = {
8
+ key: 'shop.unchained.file-upload-plugin.gridfs',
9
+ label: 'GridFS File Upload Plugin',
10
+ version: '1.0.0',
11
+ adapters: [GridFSAdapter],
12
+ module: ({ db }) => ({
13
+ gridfsFileUploads: configureGridFSFileUploadModule({ db }),
14
+ }),
15
+ routes: [
16
+ {
17
+ path: `${GRIDFS_PUT_SERVER_PATH}/:directoryName/:fileName`,
18
+ method: 'ALL',
19
+ handler: gridfsRouteHandler,
20
+ },
21
+ ],
22
+ onRegister: () => {
23
+ if (!UNCHAINED_GRIDFS_PUT_UPLOAD_SECRET) {
24
+ logger.warn('UNCHAINED_GRIDFS_PUT_UPLOAD_SECRET not set - PUT uploads and signed downloads will fail');
25
+ }
26
+ },
27
+ };
28
+ export default GridFSPlugin;
29
+ export { GridFSAdapter } from "./adapter.js";
30
+ export {} from "./module.js";
@@ -0,0 +1,4 @@
1
+ import { type IFileAdapter } from '@unchainedshop/core-files';
2
+ import { Client } from 'minio';
3
+ export declare function connectToMinio(): Promise<Client | null>;
4
+ export declare const MinioAdapter: IFileAdapter;
@@ -0,0 +1,160 @@
1
+ import { Readable } from 'node:stream';
2
+ import { FileAdapter, buildHashedFilename, resolveExpirationDate, expiryOffsetInMs, } from '@unchainedshop/core-files';
3
+ import mime from 'mime/lite';
4
+ import { Client } from 'minio';
5
+ import { AssumeRoleProvider } from 'minio/dist/esm/AssumeRoleProvider.mjs';
6
+ import { createLogger } from '@unchainedshop/logger';
7
+ const logger = createLogger('unchained:minio');
8
+ const { MINIO_ACCESS_KEY, MINIO_REGION, MINIO_STS_ENDPOINT, MINIO_SECRET_KEY, MINIO_ENDPOINT, MINIO_BUCKET_NAME, MINIO_UPLOAD_PREFIX, NODE_ENV, AMAZON_S3_SESSION_TOKEN, } = process.env;
9
+ let client = null;
10
+ export async function connectToMinio() {
11
+ if (!MINIO_ENDPOINT || !MINIO_BUCKET_NAME) {
12
+ logger.error('Please configure Minio/S3 by providing MINIO_ENDPOINT & MINIO_BUCKET_NAME to use upload features');
13
+ return null;
14
+ }
15
+ try {
16
+ const resolvedUrl = new URL(MINIO_ENDPOINT);
17
+ const minioClient = new Client({
18
+ endPoint: resolvedUrl.hostname,
19
+ useSSL: resolvedUrl.protocol === 'https:',
20
+ port: parseInt(resolvedUrl.port, 10) || undefined,
21
+ region: MINIO_REGION,
22
+ sessionToken: AMAZON_S3_SESSION_TOKEN,
23
+ accessKey: MINIO_ACCESS_KEY,
24
+ secretKey: MINIO_SECRET_KEY,
25
+ });
26
+ if (NODE_ENV === 'development')
27
+ minioClient?.traceOn(process.stdout);
28
+ if (MINIO_STS_ENDPOINT) {
29
+ const ap = new AssumeRoleProvider({
30
+ stsEndpoint: MINIO_STS_ENDPOINT,
31
+ accessKey: MINIO_ACCESS_KEY,
32
+ secretKey: MINIO_SECRET_KEY,
33
+ });
34
+ await minioClient.setCredentialsProvider(ap);
35
+ }
36
+ return minioClient;
37
+ }
38
+ catch (error) {
39
+ logger.error(`Exception while creating Minio client: ${error.message}`);
40
+ }
41
+ return null;
42
+ }
43
+ const generateMinioPath = (directoryName, fileName) => {
44
+ const prefix = MINIO_UPLOAD_PREFIX || '';
45
+ return [prefix, directoryName, fileName].filter(Boolean).join('/');
46
+ };
47
+ const generateMinioUrl = (directoryName, hashedFilename) => {
48
+ return `${MINIO_ENDPOINT}/${MINIO_BUCKET_NAME}/${generateMinioPath(directoryName, hashedFilename)}`;
49
+ };
50
+ connectToMinio().then(function setClient(c) {
51
+ client = c || client;
52
+ });
53
+ const getObjectStats = async (fileName) => {
54
+ if (!client)
55
+ throw new Error('Minio not connected, check env variables');
56
+ return client.statObject(MINIO_BUCKET_NAME, fileName);
57
+ };
58
+ const bufferToStream = (buffer) => {
59
+ const stream = new Readable();
60
+ stream.push(buffer);
61
+ stream.push(null);
62
+ return stream;
63
+ };
64
+ export const MinioAdapter = {
65
+ key: 'shop.unchained.file-upload-plugin.minio',
66
+ label: 'Uploads files into an S3 bucket using minio',
67
+ version: '1.1.0',
68
+ ...FileAdapter,
69
+ async createDownloadURL(file) {
70
+ if (file.meta?.isPrivate)
71
+ throw new Error("Minio Plugin doesn't support private files yet");
72
+ return generateMinioUrl(file.path, file._id);
73
+ },
74
+ async createSignedURL(directoryName, fileName) {
75
+ if (!client)
76
+ throw new Error('Minio not connected, check env variables');
77
+ const expiryDate = resolveExpirationDate();
78
+ const _id = await buildHashedFilename(directoryName, fileName, expiryDate);
79
+ const url = await client.presignedPutObject(MINIO_BUCKET_NAME, generateMinioPath(directoryName, _id), expiryOffsetInMs() / 1000);
80
+ return {
81
+ _id,
82
+ directoryName,
83
+ expiryDate,
84
+ fileName,
85
+ type: mime.getType(fileName),
86
+ putURL: url,
87
+ url: generateMinioUrl(directoryName, _id),
88
+ };
89
+ },
90
+ async removeFiles(files) {
91
+ if (!client)
92
+ throw new Error('Minio not connected, check env variables');
93
+ const fileIds = files.map(({ path, _id }) => {
94
+ return `${path}/${_id}`;
95
+ });
96
+ await client.removeObjects(MINIO_BUCKET_NAME, fileIds);
97
+ },
98
+ async uploadFileFromStream(directoryName, rawFile) {
99
+ if (!client)
100
+ throw new Error('Minio not connected, check env variables');
101
+ let stream;
102
+ let fileName;
103
+ if (rawFile instanceof Promise) {
104
+ const { filename: fname, createReadStream } = await rawFile;
105
+ fileName = fname;
106
+ stream = createReadStream();
107
+ }
108
+ else {
109
+ fileName = rawFile.filename;
110
+ stream = bufferToStream(Buffer.from(rawFile.buffer, 'base64'));
111
+ }
112
+ const _id = await buildHashedFilename(directoryName, fileName, new Date());
113
+ const type = mime.getType(fileName) || (await Promise.resolve(rawFile)).mimetype;
114
+ const metaData = {
115
+ 'Content-Type': type,
116
+ };
117
+ await client.putObject(MINIO_BUCKET_NAME, generateMinioPath(directoryName, _id), stream, undefined, metaData);
118
+ const { size } = await getObjectStats(generateMinioPath(directoryName, _id));
119
+ return {
120
+ _id,
121
+ directoryName,
122
+ expiryDate: null,
123
+ fileName,
124
+ size,
125
+ type,
126
+ url: generateMinioUrl(directoryName, _id),
127
+ };
128
+ },
129
+ async uploadFileFromURL(directoryName, { fileLink, fileName: fname, fileId, headers }) {
130
+ if (!client)
131
+ throw new Error('Minio not connected, check env variables');
132
+ const { href } = new URL(fileLink);
133
+ const fileName = fname || href.split('/').pop();
134
+ const hashedFilename = await buildHashedFilename(directoryName, fileName, new Date());
135
+ const url = new URL(fileLink);
136
+ const response = await fetch(url, { headers });
137
+ const type = mime.getType(fileName) || response.headers['content-type'];
138
+ const readable = Readable.fromWeb(response.body);
139
+ const metaData = {
140
+ 'Content-Type': type,
141
+ };
142
+ await client.putObject(MINIO_BUCKET_NAME, generateMinioPath(directoryName, hashedFilename), readable, undefined, metaData);
143
+ const { size } = await getObjectStats(generateMinioPath(directoryName, hashedFilename));
144
+ return {
145
+ _id: fileId || hashedFilename,
146
+ directoryName,
147
+ expiryDate: null,
148
+ fileName,
149
+ size,
150
+ type,
151
+ url: generateMinioUrl(directoryName, hashedFilename),
152
+ };
153
+ },
154
+ async createDownloadStream(file) {
155
+ if (!client)
156
+ throw new Error('Minio not connected, check env variables');
157
+ const stream = await client.getObject(MINIO_BUCKET_NAME, generateMinioPath(file.path, file._id));
158
+ return stream;
159
+ },
160
+ };
@@ -0,0 +1,2 @@
1
+ import type { UnchainedCore } from '@unchainedshop/core';
2
+ export declare function minioWebhookHandler(request: Request, context: UnchainedCore): Promise<Response>;
@@ -0,0 +1,41 @@
1
+ import { createLogger } from '@unchainedshop/logger';
2
+ import { timingSafeStringEqual } from '@unchainedshop/utils';
3
+ const logger = createLogger('unchained:minio');
4
+ const { MINIO_WEBHOOK_AUTH_TOKEN } = process.env;
5
+ const isAuthorized = async (authorization = '') => {
6
+ if (!MINIO_WEBHOOK_AUTH_TOKEN)
7
+ return false;
8
+ const [type, token] = authorization.split(' ');
9
+ if (type !== 'Bearer' || !token)
10
+ return false;
11
+ return timingSafeStringEqual(token, MINIO_WEBHOOK_AUTH_TOKEN);
12
+ };
13
+ export async function minioWebhookHandler(request, context) {
14
+ try {
15
+ const authorization = request.headers.get('authorization') || '';
16
+ if (!(await isAuthorized(authorization))) {
17
+ return new Response(JSON.stringify({ error: 'Unauthorized' }), {
18
+ status: 401,
19
+ headers: { 'Content-Type': 'application/json' },
20
+ });
21
+ }
22
+ const body = await request.json();
23
+ const { Records = [], EventName } = body;
24
+ if (EventName === 's3:ObjectCreated:Put') {
25
+ const [{ s3 }] = Records;
26
+ const { object } = s3;
27
+ const { size, contentType: type } = object;
28
+ const [fileId] = object.key.split('.');
29
+ await context.services.files.linkFile({ fileId, type, size });
30
+ return new Response(null, { status: 200 });
31
+ }
32
+ return new Response(null, { status: 404 });
33
+ }
34
+ catch (e) {
35
+ logger.error(e);
36
+ return new Response(JSON.stringify({ name: e.name, code: e.code, message: e.message }), {
37
+ status: 503,
38
+ headers: { 'Content-Type': 'application/json' },
39
+ });
40
+ }
41
+ }