@beamimpact/web-sdk 1.52.7 → 1.54.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 (274) hide show
  1. package/dist/chunks/_share-dialog-dependencies-BXp5YnfR.esm.js +2 -0
  2. package/dist/chunks/{_share-dialog-dependencies-CYeOdZWi.esm.js.map → _share-dialog-dependencies-BXp5YnfR.esm.js.map} +1 -1
  3. package/dist/chunks/_share-dialog-dependencies-CwQxKtg2.esm.js +2 -0
  4. package/dist/chunks/{_share-dialog-dependencies-FmC7lLQ6.esm.js.map → _share-dialog-dependencies-CwQxKtg2.esm.js.map} +1 -1
  5. package/dist/chunks/cart-contents-DkoytiZh.esm.js.map +1 -1
  6. package/dist/chunks/{cart-contents-CUgc4y1N.esm.d.ts → cart-contents-oArgpFbi.esm.d.ts} +1 -1
  7. package/dist/chunks/{events-BKkf9u9l.esm.d.ts → events-D7Q2jJgz.esm.d.ts} +19 -4
  8. package/dist/chunks/events-DahlkyxO.esm.js +2 -0
  9. package/dist/chunks/{events-BohmT6Lp.esm.js.map → events-DahlkyxO.esm.js.map} +1 -1
  10. package/dist/chunks/index--NDbk-eE.esm.js +389 -0
  11. package/dist/chunks/index--NDbk-eE.esm.js.map +1 -0
  12. package/dist/chunks/{index-TAxKoTC1.esm.d.ts → index-1Mhh255_.esm.d.ts} +1 -1
  13. package/dist/chunks/{index-ChmhNz41.esm.js → index-B7ij5jz8.esm.js} +2 -2
  14. package/dist/chunks/index-B7ij5jz8.esm.js.map +1 -0
  15. package/dist/chunks/index-Bydn4zMN.esm.js +2 -0
  16. package/dist/chunks/index-Bydn4zMN.esm.js.map +1 -0
  17. package/dist/chunks/{index-Dnm34FcO.esm.d.ts → index-C-TP8NdG.esm.d.ts} +1 -1
  18. package/dist/chunks/{index-DkGjP-Zg.esm.js → index-C2KsnRGC.esm.js} +2 -2
  19. package/dist/chunks/index-C2KsnRGC.esm.js.map +1 -0
  20. package/dist/chunks/{index-DvbUE31b.esm.d.ts → index-CCRz-5hA.esm.d.ts} +1 -1
  21. package/dist/chunks/index-CIey5rKC.esm.js +2 -0
  22. package/dist/chunks/index-CIey5rKC.esm.js.map +1 -0
  23. package/dist/chunks/index-CInpKPId.esm.js +2 -0
  24. package/dist/chunks/index-CInpKPId.esm.js.map +1 -0
  25. package/dist/chunks/{index-CbKkAM6h.esm.d.ts → index-CPVMm4wx.esm.d.ts} +1 -1
  26. package/dist/chunks/index-CeYpLstb.esm.js +2 -0
  27. package/dist/chunks/index-CeYpLstb.esm.js.map +1 -0
  28. package/dist/chunks/{index-BqBEii8E.esm.d.ts → index-CkuCObi0.esm.d.ts} +1 -1
  29. package/dist/chunks/index-Co6Pvowh.esm.js +2 -0
  30. package/dist/chunks/index-Co6Pvowh.esm.js.map +1 -0
  31. package/dist/chunks/{index-ki8pLX6n.esm.d.ts → index-CuzElPMZ.esm.d.ts} +4 -4
  32. package/dist/chunks/index-DDNrz43j.esm.js +389 -0
  33. package/dist/chunks/index-DDNrz43j.esm.js.map +1 -0
  34. package/dist/chunks/index-DqwTVzld.esm.js +2 -0
  35. package/dist/chunks/index-DqwTVzld.esm.js.map +1 -0
  36. package/dist/chunks/index-E5gX8_N2.esm.js +2 -0
  37. package/dist/chunks/index-E5gX8_N2.esm.js.map +1 -0
  38. package/dist/chunks/index-Ls4pNA_r.esm.js +2 -0
  39. package/dist/chunks/index-Ls4pNA_r.esm.js.map +1 -0
  40. package/dist/chunks/index-MKr3f8W9.esm.js +2 -0
  41. package/dist/chunks/index-MKr3f8W9.esm.js.map +1 -0
  42. package/dist/chunks/index-XTzV546k.esm.js +2 -0
  43. package/dist/chunks/index-XTzV546k.esm.js.map +1 -0
  44. package/dist/chunks/index-ewiV_0-t.esm.js +2 -0
  45. package/dist/chunks/index-ewiV_0-t.esm.js.map +1 -0
  46. package/dist/chunks/index-rO_5zds6.esm.js +2 -0
  47. package/dist/chunks/index-rO_5zds6.esm.js.map +1 -0
  48. package/dist/chunks/{openapi-spec-VAt3phhg.esm.d.ts → openapi-spec-x9NbL7bU.esm.d.ts} +860 -199
  49. package/dist/chunks/order-page-CJR7GRgk.esm.js +2 -0
  50. package/dist/chunks/order-page-CJR7GRgk.esm.js.map +1 -0
  51. package/dist/chunks/order-page-CtQ9OX_A.esm.js +2 -0
  52. package/dist/chunks/order-page-CtQ9OX_A.esm.js.map +1 -0
  53. package/dist/chunks/{order-page-Cerye00Q.esm.d.ts → order-page-D_p01zgd.esm.d.ts} +3 -3
  54. package/dist/chunks/{promo-types-C1unMpo2.esm.d.ts → promo-types-Cz_Zkjy1.esm.d.ts} +1 -1
  55. package/dist/chunks/promo-types-DKAOFHJr.esm.js +2 -0
  56. package/dist/chunks/promo-types-DKAOFHJr.esm.js.map +1 -0
  57. package/dist/chunks/routes-Bw7hn3RL.esm.js +2 -0
  58. package/dist/chunks/routes-Bw7hn3RL.esm.js.map +1 -0
  59. package/dist/chunks/{routes-DDRd747e.esm.d.ts → routes-BwRUVGsk.esm.d.ts} +21 -4
  60. package/dist/chunks/routes-Ck-AZVsH.esm.js +2 -0
  61. package/dist/chunks/routes-Ck-AZVsH.esm.js.map +1 -0
  62. package/dist/chunks/{share-button-C2_VjXAY.esm.js → share-button-BopORXeO.esm.js} +2 -2
  63. package/dist/chunks/{share-button-C2_VjXAY.esm.js.map → share-button-BopORXeO.esm.js.map} +1 -1
  64. package/dist/chunks/{share-button-BXEwUmT4.esm.js → share-button-BupVxILq.esm.js} +2 -2
  65. package/dist/chunks/{share-button-CLpGIG3j.esm.js.map → share-button-BupVxILq.esm.js.map} +1 -1
  66. package/dist/chunks/{share-button-DVQotZGR.esm.js → share-button-G4zNdeOS.esm.js} +2 -2
  67. package/dist/chunks/{share-button-DVQotZGR.esm.js.map → share-button-G4zNdeOS.esm.js.map} +1 -1
  68. package/dist/chunks/{share-button-CLpGIG3j.esm.js → share-button-gAbnieb4.esm.js} +2 -2
  69. package/dist/chunks/{share-button-BXEwUmT4.esm.js.map → share-button-gAbnieb4.esm.js.map} +1 -1
  70. package/dist/chunks/update-cart-CmyZ_Qmv.esm.js +2 -0
  71. package/dist/chunks/{update-cart-BpiNvvDT.esm.js.map → update-cart-CmyZ_Qmv.esm.js.map} +1 -1
  72. package/dist/chunks/update-cart-DhgjSmWJ.esm.js +2 -0
  73. package/dist/chunks/{update-cart-DIJcb6w0.esm.js.map → update-cart-DhgjSmWJ.esm.js.map} +1 -1
  74. package/dist/chunks/{update-cart-NiToHHJH.esm.d.ts → update-cart-Dp0v0m4d.esm.d.ts} +1 -1
  75. package/dist/components/community-impact.esm.js +1 -1
  76. package/dist/components/community-impact.esm.js.map +1 -1
  77. package/dist/components/community-impact.js +1 -1
  78. package/dist/components/community-impact.js.map +1 -1
  79. package/dist/components/cumulative-impact.esm.js +1 -1
  80. package/dist/components/cumulative-impact.esm.js.map +1 -1
  81. package/dist/components/cumulative-impact.js +1 -1
  82. package/dist/components/cumulative-impact.js.map +1 -1
  83. package/dist/components/impact-overview.d.ts +3 -0
  84. package/dist/components/impact-overview.esm.js +35 -35
  85. package/dist/components/impact-overview.esm.js.map +1 -1
  86. package/dist/components/impact-overview.js +35 -35
  87. package/dist/components/impact-overview.js.map +1 -1
  88. package/dist/components/index.d.ts +3 -3
  89. package/dist/components/index.esm.js +1 -1
  90. package/dist/components/index.js +1 -1
  91. package/dist/components/post-purchase.d.ts +11 -89
  92. package/dist/components/post-purchase.esm.js +3 -2
  93. package/dist/components/post-purchase.esm.js.map +1 -1
  94. package/dist/components/post-purchase.js +3 -2
  95. package/dist/components/post-purchase.js.map +1 -1
  96. package/dist/components/product-details-page.d.ts +2 -2
  97. package/dist/components/product-details-page.esm.js +7 -7
  98. package/dist/components/product-details-page.esm.js.map +1 -1
  99. package/dist/components/product-details-page.js +7 -7
  100. package/dist/components/product-details-page.js.map +1 -1
  101. package/dist/components/redeem-transaction.d.ts +3 -3
  102. package/dist/components/redeem-transaction.esm.js +1 -388
  103. package/dist/components/redeem-transaction.esm.js.map +1 -1
  104. package/dist/components/redeem-transaction.js +1 -388
  105. package/dist/components/redeem-transaction.js.map +1 -1
  106. package/dist/components/select-nonprofit.d.ts +4 -3
  107. package/dist/components/select-nonprofit.esm.js +22 -22
  108. package/dist/components/select-nonprofit.esm.js.map +1 -1
  109. package/dist/components/select-nonprofit.js +22 -22
  110. package/dist/components/select-nonprofit.js.map +1 -1
  111. package/dist/components/select-subscription-nonprofit.d.ts +1 -1
  112. package/dist/components/select-subscription-nonprofit.esm.js +16 -16
  113. package/dist/components/select-subscription-nonprofit.esm.js.map +1 -1
  114. package/dist/components/select-subscription-nonprofit.js +16 -16
  115. package/dist/components/select-subscription-nonprofit.js.map +1 -1
  116. package/dist/components/shopify.d.ts +7 -7
  117. package/dist/components/shopify.esm.js +1 -1
  118. package/dist/components/shopify.esm.js.map +1 -1
  119. package/dist/components/shopify.js +1 -1
  120. package/dist/components/shopify.js.map +1 -1
  121. package/dist/components/social-share.esm.js +1 -1
  122. package/dist/components/social-share.esm.js.map +1 -1
  123. package/dist/components/social-share.js +1 -1
  124. package/dist/components/social-share.js.map +1 -1
  125. package/dist/components/subscription-impact.d.ts +4 -1
  126. package/dist/components/subscription-impact.esm.js +14 -14
  127. package/dist/components/subscription-impact.esm.js.map +1 -1
  128. package/dist/components/subscription-impact.js +14 -14
  129. package/dist/components/subscription-impact.js.map +1 -1
  130. package/dist/components/subscription-management.d.ts +17 -4
  131. package/dist/components/subscription-management.esm.js +18 -18
  132. package/dist/components/subscription-management.esm.js.map +1 -1
  133. package/dist/components/subscription-management.js +18 -18
  134. package/dist/components/subscription-management.js.map +1 -1
  135. package/dist/index.d.ts +13 -13
  136. package/dist/index.esm.js +1 -1
  137. package/dist/index.js +1 -1
  138. package/dist/integrations/beam.esm.js +1 -1
  139. package/dist/integrations/beam.esm.js.map +1 -1
  140. package/dist/integrations/beam.js +1 -1
  141. package/dist/integrations/beam.js.map +1 -1
  142. package/dist/integrations/cart.d.ts +3 -3
  143. package/dist/integrations/cart.esm.js +1 -1
  144. package/dist/integrations/cart.js +1 -1
  145. package/dist/integrations/index.d.ts +11 -11
  146. package/dist/integrations/index.esm.js +1 -1
  147. package/dist/integrations/index.js +1 -1
  148. package/dist/integrations/logs.d.ts +2 -2
  149. package/dist/integrations/logs.esm.js +1 -1
  150. package/dist/integrations/logs.js +1 -1
  151. package/dist/integrations/promoManager.esm.js +1 -1
  152. package/dist/integrations/promoManager.esm.js.map +1 -1
  153. package/dist/integrations/promoManager.js +1 -1
  154. package/dist/integrations/promoManager.js.map +1 -1
  155. package/dist/integrations/shopify.d.ts +5 -5
  156. package/dist/integrations/shopify.esm.js +1 -1
  157. package/dist/integrations/shopify.js +1 -1
  158. package/dist/integrations/statsig.esm.js +1 -1
  159. package/dist/integrations/statsig.esm.js.map +1 -1
  160. package/dist/integrations/statsig.js +1 -1
  161. package/dist/integrations/statsig.js.map +1 -1
  162. package/dist/integrations/utils.d.ts +4 -4
  163. package/dist/integrations/utils.esm.js +1 -1
  164. package/dist/integrations/utils.js +1 -1
  165. package/dist/react/community-impact.esm.js +1 -1
  166. package/dist/react/community-impact.esm.js.map +1 -1
  167. package/dist/react/community-impact.js +1 -1
  168. package/dist/react/community-impact.js.map +1 -1
  169. package/dist/react/cumulative-impact.esm.js +1 -1
  170. package/dist/react/cumulative-impact.esm.js.map +1 -1
  171. package/dist/react/cumulative-impact.js +1 -1
  172. package/dist/react/cumulative-impact.js.map +1 -1
  173. package/dist/react/impact-overview.esm.js +1 -1
  174. package/dist/react/impact-overview.esm.js.map +1 -1
  175. package/dist/react/impact-overview.js +1 -1
  176. package/dist/react/impact-overview.js.map +1 -1
  177. package/dist/react/index.d.ts +5 -5
  178. package/dist/react/index.esm.js +1 -1
  179. package/dist/react/index.js +1 -1
  180. package/dist/react/post-purchase.d.ts +2 -2
  181. package/dist/react/post-purchase.esm.js +1 -1
  182. package/dist/react/post-purchase.esm.js.map +1 -1
  183. package/dist/react/post-purchase.js +1 -1
  184. package/dist/react/post-purchase.js.map +1 -1
  185. package/dist/react/product-details-page.d.ts +1 -1
  186. package/dist/react/product-details-page.esm.js +1 -1
  187. package/dist/react/product-details-page.esm.js.map +1 -1
  188. package/dist/react/product-details-page.js +1 -1
  189. package/dist/react/product-details-page.js.map +1 -1
  190. package/dist/react/redeem-transaction.d.ts +4 -4
  191. package/dist/react/redeem-transaction.esm.js +1 -1
  192. package/dist/react/redeem-transaction.esm.js.map +1 -1
  193. package/dist/react/redeem-transaction.js +1 -1
  194. package/dist/react/redeem-transaction.js.map +1 -1
  195. package/dist/react/select-nonprofit.d.ts +4 -4
  196. package/dist/react/select-nonprofit.esm.js +1 -1
  197. package/dist/react/select-nonprofit.esm.js.map +1 -1
  198. package/dist/react/select-nonprofit.js +1 -1
  199. package/dist/react/select-nonprofit.js.map +1 -1
  200. package/dist/react/select-subscription-nonprofit.d.ts +4 -4
  201. package/dist/react/select-subscription-nonprofit.esm.js +1 -1
  202. package/dist/react/select-subscription-nonprofit.esm.js.map +1 -1
  203. package/dist/react/select-subscription-nonprofit.js +1 -1
  204. package/dist/react/select-subscription-nonprofit.js.map +1 -1
  205. package/dist/react/social-share.esm.js +1 -1
  206. package/dist/react/social-share.esm.js.map +1 -1
  207. package/dist/react/social-share.js +1 -1
  208. package/dist/react/social-share.js.map +1 -1
  209. package/dist/react/subscription-impact.esm.js +1 -1
  210. package/dist/react/subscription-impact.esm.js.map +1 -1
  211. package/dist/react/subscription-impact.js +1 -1
  212. package/dist/react/subscription-impact.js.map +1 -1
  213. package/dist/react/subscription-management.d.ts +3 -3
  214. package/dist/react/subscription-management.esm.js +1 -1
  215. package/dist/react/subscription-management.esm.js.map +1 -1
  216. package/dist/react/subscription-management.js +1 -1
  217. package/dist/react/subscription-management.js.map +1 -1
  218. package/dist/utils/events.d.ts +4 -4
  219. package/dist/utils/events.esm.js +1 -1
  220. package/dist/utils/events.js +1 -1
  221. package/dist/utils/index.d.ts +4 -4
  222. package/dist/utils/index.esm.js +1 -1
  223. package/dist/utils/index.js +1 -1
  224. package/dist/utils/network-listeners.esm.js +1 -1
  225. package/dist/utils/network-listeners.js +1 -1
  226. package/dist/utils/promoManager.d.ts +3 -3
  227. package/dist/utils/promoManager.esm.js +1 -1
  228. package/dist/utils/promoManager.esm.js.map +1 -1
  229. package/dist/utils/promoManager.js +1 -1
  230. package/dist/utils/promoManager.js.map +1 -1
  231. package/package.json +2 -2
  232. package/dist/chunks/_share-dialog-dependencies-CYeOdZWi.esm.js +0 -2
  233. package/dist/chunks/_share-dialog-dependencies-FmC7lLQ6.esm.js +0 -2
  234. package/dist/chunks/events-BohmT6Lp.esm.js +0 -2
  235. package/dist/chunks/index-9s_WWt_5.esm.js +0 -2
  236. package/dist/chunks/index-9s_WWt_5.esm.js.map +0 -1
  237. package/dist/chunks/index-AEnQH-so.esm.js +0 -2
  238. package/dist/chunks/index-AEnQH-so.esm.js.map +0 -1
  239. package/dist/chunks/index-B-4isAGW.esm.js +0 -2
  240. package/dist/chunks/index-B-4isAGW.esm.js.map +0 -1
  241. package/dist/chunks/index-Bp28pZSn.esm.js +0 -2
  242. package/dist/chunks/index-Bp28pZSn.esm.js.map +0 -1
  243. package/dist/chunks/index-CFtmDAHb.esm.js +0 -2
  244. package/dist/chunks/index-CFtmDAHb.esm.js.map +0 -1
  245. package/dist/chunks/index-CL7fWjz1.esm.js +0 -2
  246. package/dist/chunks/index-CL7fWjz1.esm.js.map +0 -1
  247. package/dist/chunks/index-CfgpHhN1.esm.js +0 -2
  248. package/dist/chunks/index-CfgpHhN1.esm.js.map +0 -1
  249. package/dist/chunks/index-ChmhNz41.esm.js.map +0 -1
  250. package/dist/chunks/index-CtYbieoH.esm.js +0 -2
  251. package/dist/chunks/index-CtYbieoH.esm.js.map +0 -1
  252. package/dist/chunks/index-DhhPQ773.esm.js +0 -2
  253. package/dist/chunks/index-DhhPQ773.esm.js.map +0 -1
  254. package/dist/chunks/index-DkGjP-Zg.esm.js.map +0 -1
  255. package/dist/chunks/index-DrOeOk1M.esm.js +0 -2
  256. package/dist/chunks/index-DrOeOk1M.esm.js.map +0 -1
  257. package/dist/chunks/index-DtfQd6C4.esm.js +0 -2
  258. package/dist/chunks/index-DtfQd6C4.esm.js.map +0 -1
  259. package/dist/chunks/index-oGObXjk6.esm.js +0 -2
  260. package/dist/chunks/index-oGObXjk6.esm.js.map +0 -1
  261. package/dist/chunks/order-page-BPm0hcsC.esm.js +0 -2
  262. package/dist/chunks/order-page-BPm0hcsC.esm.js.map +0 -1
  263. package/dist/chunks/order-page-DFtCsDYa.esm.js +0 -2
  264. package/dist/chunks/order-page-DFtCsDYa.esm.js.map +0 -1
  265. package/dist/chunks/promoManager-B9cTR1R3.esm.js +0 -2
  266. package/dist/chunks/promoManager-B9cTR1R3.esm.js.map +0 -1
  267. package/dist/chunks/promoManager-fl54hq13.esm.js +0 -2
  268. package/dist/chunks/promoManager-fl54hq13.esm.js.map +0 -1
  269. package/dist/chunks/routes-Dl-QWRUP.esm.js +0 -2
  270. package/dist/chunks/routes-Dl-QWRUP.esm.js.map +0 -1
  271. package/dist/chunks/routes-VlLXqb7P.esm.js +0 -2
  272. package/dist/chunks/routes-VlLXqb7P.esm.js.map +0 -1
  273. package/dist/chunks/update-cart-BpiNvvDT.esm.js +0 -2
  274. package/dist/chunks/update-cart-DIJcb6w0.esm.js +0 -2
@@ -1,6 +1,6 @@
1
- import { b as TBeamCartLocalStorage } from '../chunks/cart-contents-CUgc4y1N.esm.js';
2
- import { a as TPromoCodeResponse, b as TValidatedPromoResponse, T as TPromoCodeRequest, c as TPromoCodeAttribute } from '../chunks/promo-types-C1unMpo2.esm.js';
3
- import '../chunks/openapi-spec-VAt3phhg.esm.js';
1
+ import { b as TBeamCartLocalStorage } from '../chunks/cart-contents-oArgpFbi.esm.js';
2
+ import { a as TPromoCodeResponse, b as TValidatedPromoResponse, T as TPromoCodeRequest, c as TPromoCodeAttribute } from '../chunks/promo-types-Cz_Zkjy1.esm.js';
3
+ import '../chunks/openapi-spec-x9NbL7bU.esm.js';
4
4
 
5
5
  /**
6
6
  * Retrieves all validated promo codes stored in the "beam_promo_codes" cookie and parses it
@@ -1,2 +1,2 @@
1
- import{f as m,c as d,b as i,h as C,g,a as p,i as n,m as P,j as S,e as l,p as A,s as f,k}from"../chunks/promoManager-fl54hq13.esm.js";import"../chunks/beam-errors-Ci0d3926.esm.js";import"./cookies.esm.js";import"./local-storage.esm.js";import"./logger.esm.js";export{m as formatStoreAndReturnPromoCodes,d as getAllPromoCodesFromCookie,i as getPromoCodeFromShopifyCookie,C as getPromoCodesFromCart,g as getPromoCodesLocalStorage,p as getSanitizedUrlForStorage,n as isEmptyPromoData,P as mapToUnvalidatedPromoCodes,S as mergeStoreAndReturnPromos,l as parseJsonStringArray,A as promoCodesAreEqual,f as setPromoCodeInCookie,k as setPromoCodesInLocalStorage};
1
+ import{P as n,b as m,a as l}from"../chunks/promo-types-DKAOFHJr.esm.js";import{L as u}from"../chunks/beam-errors-Ci0d3926.esm.js";import{setCookieValue as f,getCookieValue as c}from"./cookies.esm.js";import{createScopedLocalStorage as p}from"./local-storage.esm.js";import{logger as s}from"./logger.esm.js";const S=100,h="utm_",A="discount_code",O=()=>{const o=c(l);if(o)try{return JSON.parse(o)}catch(e){s.error("Failed to parse beam_promo_codes cookie:",e);return}},w=({validatedPromoCodes:o,domain:e})=>{const r={validatedPromoCodes:o},a=Date.now()+1e3*60*60*24*90;f({name:l,value:JSON.stringify(r),path:"/",domain:e,expires:a})},C=({apiKey:o})=>o?p({apiKey:o}).getItemJson(n)??{unvalidatedPromoCodes:[],validatedPromoCodes:[]}:(s.error(new u("API key is required to get promo codes")),null),P=({apiKey:o,promoCodes:e})=>{if(!o){s.error(new u("API key is required to set promo codes"));return}const r=p({apiKey:o}),a={unvalidatedPromoCodes:e?.unvalidatedPromoCodes||[],validatedPromoCodes:e?.validatedPromoCodes||[]};r.setItemJson(n,a)},v=({newPromos:o,apiKey:e})=>{const r=C({apiKey:e})??{unvalidatedPromoCodes:[],validatedPromoCodes:[]},a=(o?.unvalidatedPromoCodes||[]).filter(d=>!r.unvalidatedPromoCodes.some(i=>JSON.stringify(i)===JSON.stringify(d))),t={unvalidatedPromoCodes:[...r.unvalidatedPromoCodes,...a],validatedPromoCodes:[...r.validatedPromoCodes,...o?.validatedPromoCodes||[]]};return(t.unvalidatedPromoCodes.length>0||t.validatedPromoCodes.length>0)&&P({apiKey:e,promoCodes:t}),{...t}},g=o=>o.reduce((e,r)=>{const a=e||[];return r.url?a.push({type:m.Url,attributes:{url:r.url}}):r.value?a.push({type:m.Manual,attributes:{value:r.value}}):s.error("Invalid PromoAttribute - must contain either 'url' or 'value'",{attr:r}),a},[]),K=(o,e)=>{const r=g(o);return v({newPromos:{unvalidatedPromoCodes:r},apiKey:e})},_=o=>{if(!o?.content)return[];const e=o.content.discounts?.filter(t=>t.applicable)?.map(t=>t.code)||[],r=o.content.items?.flatMap(t=>t.discounts?.filter(d=>d.applicable)?.map(d=>d.code)||[])||[],a=[...e,...r];return[...new Set(a)]},b=()=>c(A)??null,E=o=>{if(!o)return[];try{const e=JSON.parse(o);return Array.isArray(e)&&e.every(r=>typeof r=="string")?e:[]}catch(e){return s.error("Failed to parse JSON:",e),[]}},J=()=>{try{const o=new URL(window.location.href);if(!o.search)return;const e=new URL(o.origin+o.pathname);let r=!1;o.searchParams.forEach((t,d)=>{const i=d.startsWith(h),y=t.length<=S;i&&y&&(e.searchParams.append(d,t),r=!0)});const a=e.toString();return r?{url:a}:void 0}catch{return}},L=(o,e)=>{const r=a=>(Array.isArray(a)?a:[]).map(t=>t.type==="manual"?t.attributes?.value:t.type==="url"?t.attributes?.url:"").filter(Boolean).sort().join(",");return r(o?.unvalidatedPromoCodes)===r(e?.unvalidatedPromoCodes)},k=o=>(!o.unvalidatedPromoCodes||o.unvalidatedPromoCodes.length===0)&&(!o.validatedPromoCodes||o.validatedPromoCodes.length===0);export{K as formatStoreAndReturnPromoCodes,O as getAllPromoCodesFromCookie,b as getPromoCodeFromShopifyCookie,_ as getPromoCodesFromCart,C as getPromoCodesLocalStorage,J as getSanitizedUrlForStorage,k as isEmptyPromoData,g as mapToUnvalidatedPromoCodes,v as mergeStoreAndReturnPromos,E as parseJsonStringArray,L as promoCodesAreEqual,w as setPromoCodeInCookie,P as setPromoCodesInLocalStorage};
2
2
  //# sourceMappingURL=promoManager.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"promoManager.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
1
+ {"version":3,"file":"promoManager.esm.js","sources":["../../src/utils/promoManager.ts"],"sourcesContent":["import { Discount, TBeamCartLocalStorage } from \"../shared/cart-contents\";\nimport {\n TPromoCodeAttribute,\n PromoCodeSource,\n TPromoCodeRequest,\n TPromoCodeResponse,\n TValidatedPromoResponse,\n TUnvalidatedPromoRequest,\n PROMO_LOCAL_STORAGE_KEY,\n PROMO_CODES_COOKIE_NAME,\n TUnvalidatedPromoCode,\n} from \"../shared/promo-types\";\nimport { LocalStorageError } from \"./beam-errors\";\nimport { getCookieValue, setCookieValue } from \"./cookies\";\nimport { createScopedLocalStorage } from \"./local-storage\";\nimport { logger } from \"./logger\";\n\nconst URL_QUERY_PARAM_CHAR_LIMIT = 100;\nconst ALLOWED_URL_PREFIX = \"utm_\";\n// Standard name for Shopify's discount tracking cookie\nconst DISCOUNT_CODE_COOKIE_NAME = \"discount_code\";\n// < --------- Cookie ------- >\n\n/**\n * Retrieves all validated promo codes stored in the \"beam_promo_codes\" cookie and parses it\n *\n * @returns {TPromoCodeResponse | undefined} An array of `ValidatedPromoCode` objects if found and parsed successfully, otherwise `undefined`\n */\nexport const getAllPromoCodesFromCookie = (): TPromoCodeResponse | undefined => {\n const promoCodesString = getCookieValue(PROMO_CODES_COOKIE_NAME);\n\n if (!promoCodesString) return undefined;\n\n try {\n const promoCodes: TPromoCodeResponse = JSON.parse(promoCodesString);\n return promoCodes;\n } catch (error) {\n logger.error(\"Failed to parse beam_promo_codes cookie:\", error);\n return undefined;\n }\n};\n\n/**\n * Stores the validated promo codes in the \"beam_promo_codes\" cookie, replaces and does not merge\n *\n * @param {TValidatedPromoResponse} validatedPromoCodes\n * @param {string} domain\n */\nexport const setPromoCodeInCookie = ({\n validatedPromoCodes,\n domain,\n}: {\n validatedPromoCodes: TValidatedPromoResponse;\n domain?: string;\n}) => {\n const promoCodeData = {\n validatedPromoCodes: validatedPromoCodes,\n };\n const threeMonthsFromNow = Date.now() + 1000 * 60 * 60 * 24 * 90;\n\n setCookieValue({\n name: PROMO_CODES_COOKIE_NAME,\n value: JSON.stringify(promoCodeData),\n path: \"/\",\n domain,\n // If we don't set an expiration, the cookie will be cleared when the tab is closed\n expires: threeMonthsFromNow,\n });\n};\n\n// < --------- Local Storage ------- >\n/**\n * Retrieves promo codes from localStorage, scoped by API key\n * @param {string} apiKey API key used for storage scoping\n * @returns {TPromoCodeRequest | null} - Returns stored promo codes object containing both\n * validated and unvalidated codes\n * - If no codes exist, returns a fresh object with empty arrays\n *\n */\nexport const getPromoCodesLocalStorage = ({ apiKey }: { apiKey: string }): TPromoCodeRequest | null => {\n if (!apiKey) {\n logger.error(new LocalStorageError(\"API key is required to get promo codes\"));\n return null;\n }\n\n const storage = createScopedLocalStorage({ apiKey });\n const allPromos = storage.getItemJson<TPromoCodeRequest>(PROMO_LOCAL_STORAGE_KEY) ?? {\n unvalidatedPromoCodes: [],\n validatedPromoCodes: [],\n };\n\n return allPromos;\n};\n\n/**\n * Sets promo codes in localStorage\n * @param {TPromoCodeRequest} promoCodes New promo codes to add\n * @param {string} apiKey API key for storage scoping\n */\nexport const setPromoCodesInLocalStorage = ({\n apiKey,\n promoCodes,\n}: {\n apiKey?: string;\n promoCodes: Partial<TPromoCodeRequest>;\n}): void => {\n if (!apiKey) {\n logger.error(new LocalStorageError(\"API key is required to set promo codes\"));\n return;\n }\n const storage = createScopedLocalStorage({ apiKey });\n const completePromoCodes: TPromoCodeRequest = {\n unvalidatedPromoCodes: promoCodes?.unvalidatedPromoCodes || [],\n validatedPromoCodes: promoCodes?.validatedPromoCodes || [],\n };\n storage.setItemJson(PROMO_LOCAL_STORAGE_KEY, completePromoCodes);\n};\n\n/**\n * Merges new promo codes with existing ones and returns the combined result\n * @param {Partial<TPromoCodeRequest>} newPromos New promo codes to add\n * @param {string} apiKey API key for storage scoping\n * @returns {TPromoCodeRequest} An object containing both validated and unvalidated promo codes\n * @example\n * const result = mergePromoCodes({\n * apiKey: 'beam_123',\n * newPromos: {\n * unvalidatedPromoCodes: [\n * { type: 'manual', attributes: { value: 'WINTER20' } },\n * { type: 'url', attributes: { url: 'www.example.com/?promo=HOLIDAY25' } }\n * ]\n * }\n * });\n */\nexport const mergeStoreAndReturnPromos = ({\n newPromos,\n apiKey,\n}: {\n newPromos: Partial<TPromoCodeRequest>;\n apiKey: string;\n}): TPromoCodeRequest => {\n const existing = getPromoCodesLocalStorage({ apiKey }) ?? {\n unvalidatedPromoCodes: [],\n validatedPromoCodes: [],\n };\n\n const uniqueNewUnvalidatedPromos = (newPromos?.unvalidatedPromoCodes || []).filter((newPromo) => {\n const isDuplicate = existing.unvalidatedPromoCodes.some((existingPromo) => {\n return JSON.stringify(existingPromo) === JSON.stringify(newPromo);\n });\n return !isDuplicate;\n });\n\n const mergedCodes: TPromoCodeRequest = {\n unvalidatedPromoCodes: [...existing.unvalidatedPromoCodes, ...uniqueNewUnvalidatedPromos],\n validatedPromoCodes: [...existing.validatedPromoCodes, ...(newPromos?.validatedPromoCodes || [])],\n };\n\n const shouldStore = mergedCodes.unvalidatedPromoCodes.length > 0 || mergedCodes.validatedPromoCodes.length > 0;\n\n if (shouldStore) {\n setPromoCodesInLocalStorage({ apiKey, promoCodes: mergedCodes });\n }\n return {\n ...mergedCodes,\n };\n};\n\n/**\n * Formats unvalidated promo codes by determining their source and attributes\n * The function will assign `QueryParam` as the source if a `url` exists,\n * otherwise, it will assign `Manual` as the source\n *\n * @param {TPromoCodeAttribute[]} promoAttributes An array of promo attributes to be formatted\n * @returns {TUnvalidatedPromoRequest} - An array of UnvalidatedPromoCode objects,\n * each with a source and attributes object\n */\nexport const mapToUnvalidatedPromoCodes = (promoAttributes: TPromoCodeAttribute[]): TUnvalidatedPromoRequest => {\n return promoAttributes.reduce<TUnvalidatedPromoRequest>((acc, attr) => {\n const result: TUnvalidatedPromoRequest = acc || [];\n if (attr.url) {\n result.push({\n type: PromoCodeSource.Url,\n attributes: { url: attr.url },\n });\n } else if (attr.value) {\n result.push({\n type: PromoCodeSource.Manual,\n attributes: { value: attr.value },\n });\n } else {\n logger.error(\"Invalid PromoAttribute - must contain either 'url' or 'value'\", { attr });\n }\n return result;\n }, []);\n};\n\n/**\n * @param {TPromoCodeAttribute[]} promoAttributes An array of promo attributes to be formatted\n * @param {string} apiKey API key for storage scoping\n * @returns {TPromoCodeRequest} An object containing both validated and unvalidated promo codes\n */\nexport const formatStoreAndReturnPromoCodes = (\n promoAttributes: TPromoCodeAttribute[],\n apiKey: string\n): TPromoCodeRequest => {\n const unvalidatedPromoCodes = mapToUnvalidatedPromoCodes(promoAttributes);\n return mergeStoreAndReturnPromos({ newPromos: { unvalidatedPromoCodes }, apiKey });\n};\n\n/**\n * Extracts applicable promo codes from the cart object\n * This function retrieves discounts stored in the cart's `content.discounts` array,\n * filters out only the applicable promo codes, and returns them as an array of strings\n *\n * @param {TBeamCartLocalStorage} cart The cart object retrieved from local storage\n * @returns {string[]} An array of applicable promo codes\n */\nexport const getPromoCodesFromCart = (cart: TBeamCartLocalStorage): string[] => {\n if (!cart?.content) return [];\n\n const cartLevelCodes = cart.content.discounts?.filter((d) => d.applicable)?.map((d) => d.code) || [];\n\n const itemLevelCodes =\n cart.content.items?.flatMap(\n (item) => item.discounts?.filter((d: Discount) => d.applicable)?.map((d: Discount) => d.code) || []\n ) || [];\n\n const allCodes = [...cartLevelCodes, ...itemLevelCodes];\n\n return [...new Set(allCodes)];\n};\n\n/**\n * Gets promo code exclusively from Shopify discount cookie\n * @returns {string | null} Single discount code or null if not found\n */\nexport const getPromoCodeFromShopifyCookie = (): string | null => {\n return getCookieValue(DISCOUNT_CODE_COOKIE_NAME) ?? null;\n};\n\n/**\n * Safely parses a JSON string into an array of strings\n * If parsing fails or the input is not a valid JSON array, it returns an empty array\n *\n * @param {string | undefined | null} jsonString The JSON string to parse\n * @returns {string[]} The parsed array of strings or an empty array if parsing fails\n */\nexport const parseJsonStringArray = (jsonString: string | undefined | null): string[] => {\n if (!jsonString) return [];\n try {\n const parsed = JSON.parse(jsonString);\n if (Array.isArray(parsed) && parsed.every((item) => typeof item === \"string\")) {\n return parsed;\n }\n return [];\n } catch (error) {\n logger.error(\"Failed to parse JSON:\", error);\n return [];\n }\n};\n\n/**\n * Retrieves and sanitizes the current URL for storage, preserving only safe query parameters\n *\n * @returns {TPromoCodeAttribute} Returns an object with only the `url` property set\n */\nexport const getSanitizedUrlForStorage = (): TPromoCodeAttribute | undefined => {\n try {\n const url = new URL(window.location.href);\n\n if (!url.search) return undefined;\n\n // Create NEW URL instead of modifying existing one\n const cleanUrl = new URL(url.origin + url.pathname);\n let hasValidParams = false;\n\n // Process all parameters\n url.searchParams.forEach((value, key) => {\n const isAllowed = key.startsWith(ALLOWED_URL_PREFIX);\n const isValidLength = value.length <= URL_QUERY_PARAM_CHAR_LIMIT;\n\n if (isAllowed && isValidLength) {\n cleanUrl.searchParams.append(key, value);\n hasValidParams = true;\n }\n });\n\n const finalUrl = cleanUrl.toString();\n return hasValidParams ? { url: finalUrl } : undefined;\n } catch (error) {\n return undefined;\n }\n};\n\nexport const promoCodesAreEqual = (a: TPromoCodeRequest, b: TPromoCodeRequest): boolean => {\n const extract = (codes: unknown): string => {\n const validCodes = (Array.isArray(codes) ? codes : []) as TUnvalidatedPromoCode[];\n\n const flattened = validCodes\n .map((c) => {\n if (c.type === \"manual\") {\n return c.attributes?.value;\n }\n if (c.type === \"url\") {\n return c.attributes?.url;\n }\n return \"\";\n })\n .filter(Boolean)\n .sort()\n .join(\",\");\n return flattened;\n };\n\n return extract(a?.unvalidatedPromoCodes) === extract(b?.unvalidatedPromoCodes);\n};\n\nexport const isEmptyPromoData = (promos: {\n unvalidatedPromoCodes?: unknown[];\n validatedPromoCodes?: unknown[];\n}): boolean => {\n return (\n (!promos.unvalidatedPromoCodes || promos.unvalidatedPromoCodes.length === 0) &&\n (!promos.validatedPromoCodes || promos.validatedPromoCodes.length === 0)\n );\n};\n"],"names":["URL_QUERY_PARAM_CHAR_LIMIT","ALLOWED_URL_PREFIX","DISCOUNT_CODE_COOKIE_NAME","getAllPromoCodesFromCookie","promoCodesString","getCookieValue","PROMO_CODES_COOKIE_NAME","error","logger","setPromoCodeInCookie","validatedPromoCodes","domain","promoCodeData","threeMonthsFromNow","setCookieValue","getPromoCodesLocalStorage","apiKey","createScopedLocalStorage","PROMO_LOCAL_STORAGE_KEY","LocalStorageError","setPromoCodesInLocalStorage","promoCodes","storage","completePromoCodes","mergeStoreAndReturnPromos","newPromos","existing","uniqueNewUnvalidatedPromos","newPromo","existingPromo","mergedCodes","mapToUnvalidatedPromoCodes","promoAttributes","acc","attr","result","PromoCodeSource","formatStoreAndReturnPromoCodes","unvalidatedPromoCodes","getPromoCodesFromCart","cart","cartLevelCodes","d","itemLevelCodes","item","allCodes","getPromoCodeFromShopifyCookie","parseJsonStringArray","jsonString","parsed","getSanitizedUrlForStorage","url","cleanUrl","hasValidParams","value","key","isAllowed","isValidLength","finalUrl","promoCodesAreEqual","a","b","extract","codes","c","isEmptyPromoData","promos"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{f as m,c as d,b as i,h as C,g,a as p,i as n,m as P,j as S,e as l,p as A,s as f,k}from"../chunks/promoManager-B9cTR1R3.esm.js";import"../chunks/beam-errors-Ci0d3926.esm.js";import"./cookies.js";import"./local-storage.js";import"./logger.js";export{m as formatStoreAndReturnPromoCodes,d as getAllPromoCodesFromCookie,i as getPromoCodeFromShopifyCookie,C as getPromoCodesFromCart,g as getPromoCodesLocalStorage,p as getSanitizedUrlForStorage,n as isEmptyPromoData,P as mapToUnvalidatedPromoCodes,S as mergeStoreAndReturnPromos,l as parseJsonStringArray,A as promoCodesAreEqual,f as setPromoCodeInCookie,k as setPromoCodesInLocalStorage};
1
+ import{P as n,b as m,a as l}from"../chunks/promo-types-DKAOFHJr.esm.js";import{L as u}from"../chunks/beam-errors-Ci0d3926.esm.js";import{setCookieValue as f,getCookieValue as c}from"./cookies.js";import{createScopedLocalStorage as p}from"./local-storage.js";import{logger as s}from"./logger.js";const S=100,h="utm_",A="discount_code",O=()=>{const o=c(l);if(o)try{return JSON.parse(o)}catch(e){s.error("Failed to parse beam_promo_codes cookie:",e);return}},w=({validatedPromoCodes:o,domain:e})=>{const r={validatedPromoCodes:o},a=Date.now()+1e3*60*60*24*90;f({name:l,value:JSON.stringify(r),path:"/",domain:e,expires:a})},C=({apiKey:o})=>o?p({apiKey:o}).getItemJson(n)??{unvalidatedPromoCodes:[],validatedPromoCodes:[]}:(s.error(new u("API key is required to get promo codes")),null),P=({apiKey:o,promoCodes:e})=>{if(!o){s.error(new u("API key is required to set promo codes"));return}const r=p({apiKey:o}),a={unvalidatedPromoCodes:e?.unvalidatedPromoCodes||[],validatedPromoCodes:e?.validatedPromoCodes||[]};r.setItemJson(n,a)},v=({newPromos:o,apiKey:e})=>{const r=C({apiKey:e})??{unvalidatedPromoCodes:[],validatedPromoCodes:[]},a=(o?.unvalidatedPromoCodes||[]).filter(d=>!r.unvalidatedPromoCodes.some(i=>JSON.stringify(i)===JSON.stringify(d))),t={unvalidatedPromoCodes:[...r.unvalidatedPromoCodes,...a],validatedPromoCodes:[...r.validatedPromoCodes,...o?.validatedPromoCodes||[]]};return(t.unvalidatedPromoCodes.length>0||t.validatedPromoCodes.length>0)&&P({apiKey:e,promoCodes:t}),{...t}},g=o=>o.reduce((e,r)=>{const a=e||[];return r.url?a.push({type:m.Url,attributes:{url:r.url}}):r.value?a.push({type:m.Manual,attributes:{value:r.value}}):s.error("Invalid PromoAttribute - must contain either 'url' or 'value'",{attr:r}),a},[]),K=(o,e)=>{const r=g(o);return v({newPromos:{unvalidatedPromoCodes:r},apiKey:e})},_=o=>{if(!o?.content)return[];const e=o.content.discounts?.filter(t=>t.applicable)?.map(t=>t.code)||[],r=o.content.items?.flatMap(t=>t.discounts?.filter(d=>d.applicable)?.map(d=>d.code)||[])||[],a=[...e,...r];return[...new Set(a)]},b=()=>c(A)??null,E=o=>{if(!o)return[];try{const e=JSON.parse(o);return Array.isArray(e)&&e.every(r=>typeof r=="string")?e:[]}catch(e){return s.error("Failed to parse JSON:",e),[]}},J=()=>{try{const o=new URL(window.location.href);if(!o.search)return;const e=new URL(o.origin+o.pathname);let r=!1;o.searchParams.forEach((t,d)=>{const i=d.startsWith(h),y=t.length<=S;i&&y&&(e.searchParams.append(d,t),r=!0)});const a=e.toString();return r?{url:a}:void 0}catch{return}},L=(o,e)=>{const r=a=>(Array.isArray(a)?a:[]).map(t=>t.type==="manual"?t.attributes?.value:t.type==="url"?t.attributes?.url:"").filter(Boolean).sort().join(",");return r(o?.unvalidatedPromoCodes)===r(e?.unvalidatedPromoCodes)},k=o=>(!o.unvalidatedPromoCodes||o.unvalidatedPromoCodes.length===0)&&(!o.validatedPromoCodes||o.validatedPromoCodes.length===0);export{K as formatStoreAndReturnPromoCodes,O as getAllPromoCodesFromCookie,b as getPromoCodeFromShopifyCookie,_ as getPromoCodesFromCart,C as getPromoCodesLocalStorage,J as getSanitizedUrlForStorage,k as isEmptyPromoData,g as mapToUnvalidatedPromoCodes,v as mergeStoreAndReturnPromos,E as parseJsonStringArray,L as promoCodesAreEqual,w as setPromoCodeInCookie,P as setPromoCodesInLocalStorage};
2
2
  //# sourceMappingURL=promoManager.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"promoManager.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
1
+ {"version":3,"file":"promoManager.js","sources":["../../src/utils/promoManager.ts"],"sourcesContent":["import { Discount, TBeamCartLocalStorage } from \"../shared/cart-contents\";\nimport {\n TPromoCodeAttribute,\n PromoCodeSource,\n TPromoCodeRequest,\n TPromoCodeResponse,\n TValidatedPromoResponse,\n TUnvalidatedPromoRequest,\n PROMO_LOCAL_STORAGE_KEY,\n PROMO_CODES_COOKIE_NAME,\n TUnvalidatedPromoCode,\n} from \"../shared/promo-types\";\nimport { LocalStorageError } from \"./beam-errors\";\nimport { getCookieValue, setCookieValue } from \"./cookies\";\nimport { createScopedLocalStorage } from \"./local-storage\";\nimport { logger } from \"./logger\";\n\nconst URL_QUERY_PARAM_CHAR_LIMIT = 100;\nconst ALLOWED_URL_PREFIX = \"utm_\";\n// Standard name for Shopify's discount tracking cookie\nconst DISCOUNT_CODE_COOKIE_NAME = \"discount_code\";\n// < --------- Cookie ------- >\n\n/**\n * Retrieves all validated promo codes stored in the \"beam_promo_codes\" cookie and parses it\n *\n * @returns {TPromoCodeResponse | undefined} An array of `ValidatedPromoCode` objects if found and parsed successfully, otherwise `undefined`\n */\nexport const getAllPromoCodesFromCookie = (): TPromoCodeResponse | undefined => {\n const promoCodesString = getCookieValue(PROMO_CODES_COOKIE_NAME);\n\n if (!promoCodesString) return undefined;\n\n try {\n const promoCodes: TPromoCodeResponse = JSON.parse(promoCodesString);\n return promoCodes;\n } catch (error) {\n logger.error(\"Failed to parse beam_promo_codes cookie:\", error);\n return undefined;\n }\n};\n\n/**\n * Stores the validated promo codes in the \"beam_promo_codes\" cookie, replaces and does not merge\n *\n * @param {TValidatedPromoResponse} validatedPromoCodes\n * @param {string} domain\n */\nexport const setPromoCodeInCookie = ({\n validatedPromoCodes,\n domain,\n}: {\n validatedPromoCodes: TValidatedPromoResponse;\n domain?: string;\n}) => {\n const promoCodeData = {\n validatedPromoCodes: validatedPromoCodes,\n };\n const threeMonthsFromNow = Date.now() + 1000 * 60 * 60 * 24 * 90;\n\n setCookieValue({\n name: PROMO_CODES_COOKIE_NAME,\n value: JSON.stringify(promoCodeData),\n path: \"/\",\n domain,\n // If we don't set an expiration, the cookie will be cleared when the tab is closed\n expires: threeMonthsFromNow,\n });\n};\n\n// < --------- Local Storage ------- >\n/**\n * Retrieves promo codes from localStorage, scoped by API key\n * @param {string} apiKey API key used for storage scoping\n * @returns {TPromoCodeRequest | null} - Returns stored promo codes object containing both\n * validated and unvalidated codes\n * - If no codes exist, returns a fresh object with empty arrays\n *\n */\nexport const getPromoCodesLocalStorage = ({ apiKey }: { apiKey: string }): TPromoCodeRequest | null => {\n if (!apiKey) {\n logger.error(new LocalStorageError(\"API key is required to get promo codes\"));\n return null;\n }\n\n const storage = createScopedLocalStorage({ apiKey });\n const allPromos = storage.getItemJson<TPromoCodeRequest>(PROMO_LOCAL_STORAGE_KEY) ?? {\n unvalidatedPromoCodes: [],\n validatedPromoCodes: [],\n };\n\n return allPromos;\n};\n\n/**\n * Sets promo codes in localStorage\n * @param {TPromoCodeRequest} promoCodes New promo codes to add\n * @param {string} apiKey API key for storage scoping\n */\nexport const setPromoCodesInLocalStorage = ({\n apiKey,\n promoCodes,\n}: {\n apiKey?: string;\n promoCodes: Partial<TPromoCodeRequest>;\n}): void => {\n if (!apiKey) {\n logger.error(new LocalStorageError(\"API key is required to set promo codes\"));\n return;\n }\n const storage = createScopedLocalStorage({ apiKey });\n const completePromoCodes: TPromoCodeRequest = {\n unvalidatedPromoCodes: promoCodes?.unvalidatedPromoCodes || [],\n validatedPromoCodes: promoCodes?.validatedPromoCodes || [],\n };\n storage.setItemJson(PROMO_LOCAL_STORAGE_KEY, completePromoCodes);\n};\n\n/**\n * Merges new promo codes with existing ones and returns the combined result\n * @param {Partial<TPromoCodeRequest>} newPromos New promo codes to add\n * @param {string} apiKey API key for storage scoping\n * @returns {TPromoCodeRequest} An object containing both validated and unvalidated promo codes\n * @example\n * const result = mergePromoCodes({\n * apiKey: 'beam_123',\n * newPromos: {\n * unvalidatedPromoCodes: [\n * { type: 'manual', attributes: { value: 'WINTER20' } },\n * { type: 'url', attributes: { url: 'www.example.com/?promo=HOLIDAY25' } }\n * ]\n * }\n * });\n */\nexport const mergeStoreAndReturnPromos = ({\n newPromos,\n apiKey,\n}: {\n newPromos: Partial<TPromoCodeRequest>;\n apiKey: string;\n}): TPromoCodeRequest => {\n const existing = getPromoCodesLocalStorage({ apiKey }) ?? {\n unvalidatedPromoCodes: [],\n validatedPromoCodes: [],\n };\n\n const uniqueNewUnvalidatedPromos = (newPromos?.unvalidatedPromoCodes || []).filter((newPromo) => {\n const isDuplicate = existing.unvalidatedPromoCodes.some((existingPromo) => {\n return JSON.stringify(existingPromo) === JSON.stringify(newPromo);\n });\n return !isDuplicate;\n });\n\n const mergedCodes: TPromoCodeRequest = {\n unvalidatedPromoCodes: [...existing.unvalidatedPromoCodes, ...uniqueNewUnvalidatedPromos],\n validatedPromoCodes: [...existing.validatedPromoCodes, ...(newPromos?.validatedPromoCodes || [])],\n };\n\n const shouldStore = mergedCodes.unvalidatedPromoCodes.length > 0 || mergedCodes.validatedPromoCodes.length > 0;\n\n if (shouldStore) {\n setPromoCodesInLocalStorage({ apiKey, promoCodes: mergedCodes });\n }\n return {\n ...mergedCodes,\n };\n};\n\n/**\n * Formats unvalidated promo codes by determining their source and attributes\n * The function will assign `QueryParam` as the source if a `url` exists,\n * otherwise, it will assign `Manual` as the source\n *\n * @param {TPromoCodeAttribute[]} promoAttributes An array of promo attributes to be formatted\n * @returns {TUnvalidatedPromoRequest} - An array of UnvalidatedPromoCode objects,\n * each with a source and attributes object\n */\nexport const mapToUnvalidatedPromoCodes = (promoAttributes: TPromoCodeAttribute[]): TUnvalidatedPromoRequest => {\n return promoAttributes.reduce<TUnvalidatedPromoRequest>((acc, attr) => {\n const result: TUnvalidatedPromoRequest = acc || [];\n if (attr.url) {\n result.push({\n type: PromoCodeSource.Url,\n attributes: { url: attr.url },\n });\n } else if (attr.value) {\n result.push({\n type: PromoCodeSource.Manual,\n attributes: { value: attr.value },\n });\n } else {\n logger.error(\"Invalid PromoAttribute - must contain either 'url' or 'value'\", { attr });\n }\n return result;\n }, []);\n};\n\n/**\n * @param {TPromoCodeAttribute[]} promoAttributes An array of promo attributes to be formatted\n * @param {string} apiKey API key for storage scoping\n * @returns {TPromoCodeRequest} An object containing both validated and unvalidated promo codes\n */\nexport const formatStoreAndReturnPromoCodes = (\n promoAttributes: TPromoCodeAttribute[],\n apiKey: string\n): TPromoCodeRequest => {\n const unvalidatedPromoCodes = mapToUnvalidatedPromoCodes(promoAttributes);\n return mergeStoreAndReturnPromos({ newPromos: { unvalidatedPromoCodes }, apiKey });\n};\n\n/**\n * Extracts applicable promo codes from the cart object\n * This function retrieves discounts stored in the cart's `content.discounts` array,\n * filters out only the applicable promo codes, and returns them as an array of strings\n *\n * @param {TBeamCartLocalStorage} cart The cart object retrieved from local storage\n * @returns {string[]} An array of applicable promo codes\n */\nexport const getPromoCodesFromCart = (cart: TBeamCartLocalStorage): string[] => {\n if (!cart?.content) return [];\n\n const cartLevelCodes = cart.content.discounts?.filter((d) => d.applicable)?.map((d) => d.code) || [];\n\n const itemLevelCodes =\n cart.content.items?.flatMap(\n (item) => item.discounts?.filter((d: Discount) => d.applicable)?.map((d: Discount) => d.code) || []\n ) || [];\n\n const allCodes = [...cartLevelCodes, ...itemLevelCodes];\n\n return [...new Set(allCodes)];\n};\n\n/**\n * Gets promo code exclusively from Shopify discount cookie\n * @returns {string | null} Single discount code or null if not found\n */\nexport const getPromoCodeFromShopifyCookie = (): string | null => {\n return getCookieValue(DISCOUNT_CODE_COOKIE_NAME) ?? null;\n};\n\n/**\n * Safely parses a JSON string into an array of strings\n * If parsing fails or the input is not a valid JSON array, it returns an empty array\n *\n * @param {string | undefined | null} jsonString The JSON string to parse\n * @returns {string[]} The parsed array of strings or an empty array if parsing fails\n */\nexport const parseJsonStringArray = (jsonString: string | undefined | null): string[] => {\n if (!jsonString) return [];\n try {\n const parsed = JSON.parse(jsonString);\n if (Array.isArray(parsed) && parsed.every((item) => typeof item === \"string\")) {\n return parsed;\n }\n return [];\n } catch (error) {\n logger.error(\"Failed to parse JSON:\", error);\n return [];\n }\n};\n\n/**\n * Retrieves and sanitizes the current URL for storage, preserving only safe query parameters\n *\n * @returns {TPromoCodeAttribute} Returns an object with only the `url` property set\n */\nexport const getSanitizedUrlForStorage = (): TPromoCodeAttribute | undefined => {\n try {\n const url = new URL(window.location.href);\n\n if (!url.search) return undefined;\n\n // Create NEW URL instead of modifying existing one\n const cleanUrl = new URL(url.origin + url.pathname);\n let hasValidParams = false;\n\n // Process all parameters\n url.searchParams.forEach((value, key) => {\n const isAllowed = key.startsWith(ALLOWED_URL_PREFIX);\n const isValidLength = value.length <= URL_QUERY_PARAM_CHAR_LIMIT;\n\n if (isAllowed && isValidLength) {\n cleanUrl.searchParams.append(key, value);\n hasValidParams = true;\n }\n });\n\n const finalUrl = cleanUrl.toString();\n return hasValidParams ? { url: finalUrl } : undefined;\n } catch (error) {\n return undefined;\n }\n};\n\nexport const promoCodesAreEqual = (a: TPromoCodeRequest, b: TPromoCodeRequest): boolean => {\n const extract = (codes: unknown): string => {\n const validCodes = (Array.isArray(codes) ? codes : []) as TUnvalidatedPromoCode[];\n\n const flattened = validCodes\n .map((c) => {\n if (c.type === \"manual\") {\n return c.attributes?.value;\n }\n if (c.type === \"url\") {\n return c.attributes?.url;\n }\n return \"\";\n })\n .filter(Boolean)\n .sort()\n .join(\",\");\n return flattened;\n };\n\n return extract(a?.unvalidatedPromoCodes) === extract(b?.unvalidatedPromoCodes);\n};\n\nexport const isEmptyPromoData = (promos: {\n unvalidatedPromoCodes?: unknown[];\n validatedPromoCodes?: unknown[];\n}): boolean => {\n return (\n (!promos.unvalidatedPromoCodes || promos.unvalidatedPromoCodes.length === 0) &&\n (!promos.validatedPromoCodes || promos.validatedPromoCodes.length === 0)\n );\n};\n"],"names":["URL_QUERY_PARAM_CHAR_LIMIT","ALLOWED_URL_PREFIX","DISCOUNT_CODE_COOKIE_NAME","getAllPromoCodesFromCookie","promoCodesString","getCookieValue","PROMO_CODES_COOKIE_NAME","error","logger","setPromoCodeInCookie","validatedPromoCodes","domain","promoCodeData","threeMonthsFromNow","setCookieValue","getPromoCodesLocalStorage","apiKey","createScopedLocalStorage","PROMO_LOCAL_STORAGE_KEY","LocalStorageError","setPromoCodesInLocalStorage","promoCodes","storage","completePromoCodes","mergeStoreAndReturnPromos","newPromos","existing","uniqueNewUnvalidatedPromos","newPromo","existingPromo","mergedCodes","mapToUnvalidatedPromoCodes","promoAttributes","acc","attr","result","PromoCodeSource","formatStoreAndReturnPromoCodes","unvalidatedPromoCodes","getPromoCodesFromCart","cart","cartLevelCodes","d","itemLevelCodes","item","allCodes","getPromoCodeFromShopifyCookie","parseJsonStringArray","jsonString","parsed","getSanitizedUrlForStorage","url","cleanUrl","hasValidParams","value","key","isAllowed","isValidLength","finalUrl","promoCodesAreEqual","a","b","extract","codes","c","isEmptyPromoData","promos"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@beamimpact/web-sdk",
3
3
  "private": false,
4
- "version": "1.52.7",
4
+ "version": "1.54.2",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",
@@ -50,7 +50,7 @@
50
50
  "cypress:test-components-interactive": "cypress open --component",
51
51
  "test": "npm-run-all cypress:test-components-interactive",
52
52
  "test:ci": "npm-run-all cypress:test-components",
53
- "update-openapi-schema": "cp ../beam/packages/api-schemas/src/generated/central-backend/central-backend.ts ./src/api-sdk/v3/openapi-spec.ts"
53
+ "update-openapi-schema": "cp ../beam/packages/api-schemas/src/generated/central-backend/central-backend.ts ./src/api-sdk/openapi-spec.ts"
54
54
  },
55
55
  "dependencies": {
56
56
  "@lit/react": "1.0.0",
@@ -1,2 +0,0 @@
1
- import{r as c,s as i}from"./vendor-KKSARHWL.esm.js";import{m as t}from"./routes-Dl-QWRUP.esm.js";import"./lit-WqMxC_PA.esm.js";import"./beam-errors-Ci0d3926.esm.js";import"../utils/logger.esm.js";const s="https://sdk.beamimpact.com",a=`${s}/lib/shoelace/v${t["@shoelace-style/shoelace"]}`,m=`${s}/lib/lucide-static/v${t["lucide-static"]}`;if(c("lucide",{resolver:e=>`${m}/icons/${e}.svg`}),i(a),document&&!document.querySelector("link[data-beam-impact]")){const e=document.createElement("link");e.href=`${a}/themes/light.css`,e.rel="stylesheet",e.setAttribute("data-beam-impact","true"),document.head.appendChild(e)}
2
- //# sourceMappingURL=_share-dialog-dependencies-CYeOdZWi.esm.js.map
@@ -1,2 +0,0 @@
1
- import{r as c,s as i}from"./vendor-KKSARHWL.esm.js";import{m as t}from"./routes-VlLXqb7P.esm.js";import"./lit-WqMxC_PA.esm.js";import"./beam-errors-Ci0d3926.esm.js";import"../utils/logger.js";const s="https://sdk.beamimpact.com",a=`${s}/lib/shoelace/v${t["@shoelace-style/shoelace"]}`,m=`${s}/lib/lucide-static/v${t["lucide-static"]}`;if(c("lucide",{resolver:e=>`${m}/icons/${e}.svg`}),i(a),document&&!document.querySelector("link[data-beam-impact]")){const e=document.createElement("link");e.href=`${a}/themes/light.css`,e.rel="stylesheet",e.setAttribute("data-beam-impact","true"),document.head.appendChild(e)}
2
- //# sourceMappingURL=_share-dialog-dependencies-FmC7lLQ6.esm.js.map
@@ -1,2 +0,0 @@
1
- const t=class B extends CustomEvent{constructor(e){super(B.eventName,{detail:e,bubbles:!0,composed:!0})}};t.eventName="beamnetworkcall";let s=t;const o=class g extends CustomEvent{constructor(e){super(g.eventName,{detail:e,bubbles:!0,composed:!0})}};o.eventName="beamnonprofitselect";let a=o;const n=class x extends CustomEvent{constructor(e){super(x.eventName,{detail:e,bubbles:!0,composed:!0})}};n.eventName="beamcartchange";let r=n;const m=class S extends CustomEvent{constructor(e){super(S.eventName,{detail:e,bubbles:!0,composed:!0})}};m.eventName="beamcartcreated";let c=m;const u=class f extends CustomEvent{constructor(e){super(f.eventName,{detail:e,bubbles:!0,composed:!0})}};u.eventName="beamordercreated";let d=u;const l=class h extends CustomEvent{constructor(e){super(h.eventName,{detail:e,bubbles:!0,composed:!0})}};l.eventName="beamstatuschange";let v=l;const b=class w extends CustomEvent{constructor(e){super(w.eventName,{detail:e,bubbles:!0,composed:!0})}};b.eventName="beamnonprofitselectionremoved";let p=b;const C=class P extends CustomEvent{constructor(e){super(P.eventName,{detail:e,bubbles:!0,composed:!0})}};C.eventName="beampromocodesstored";let E=C;const i=class k extends CustomEvent{constructor(e){super(k.eventName,{detail:e,bubbles:!0,composed:!0})}};i.eventName="beamwidgetstoredpromocodes";let N=i;var O=Object.freeze({__proto__:null,BeamCartChangeEvent:r,BeamCartCreatedEvent:c,BeamNetworkCallEvent:s,BeamNonprofitSelectEvent:a,BeamNonprofitSelectionRemovedEvent:p,BeamOrderCreatedEvent:d,BeamPromoCodesStoredEvent:E,BeamStatusChangeEvent:v,BeamWidgetStoredPromoCodesEvent:N});export{v as B,E as a,d as b,a as c,s as d,O as e,N as f,r as g,c as h,p as i};
2
- //# sourceMappingURL=events-BohmT6Lp.esm.js.map
@@ -1,2 +0,0 @@
1
- import{O as e}from"./update-cart-DIJcb6w0.esm.js";var r=Object.freeze({__proto__:null,updateCart:e});export{r as i};
2
- //# sourceMappingURL=index-9s_WWt_5.esm.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-9s_WWt_5.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -1,2 +0,0 @@
1
- import{b as o}from"./beam-errors-Ci0d3926.esm.js";import{e}from"./events-BohmT6Lp.esm.js";import{logger as r}from"../utils/logger.esm.js";import{initNetworkListeners as t}from"../utils/network-listeners.esm.js";import{createScopedLocalStorage as a}from"../utils/local-storage.esm.js";import{waitForElement as m}from"../utils/wait-for-element.esm.js";import{deleteCookieValue as s,getCookieMap as i,getCookieValue as d,setCookieValue as n}from"../utils/cookies.esm.js";import{getRemoteSession as C,saveRemoteSession as g}from"../utils/remote-session.esm.js";import{memoizeLast as l}from"../utils/memoize-last.esm.js";import{d as p,i as S}from"./lodash-D3TLHRR_.esm.js";import{f as P,c as f,b as k,h as u,g as c,a as A,i as F,m as L,j as E,e as R,p as v,s as b,k as y}from"./promoManager-fl54hq13.esm.js";var V=Object.freeze({__proto__:null,createScopedLocalStorage:a,debounce:p,deleteCookieValue:s,errors:o,events:e,formatStoreAndReturnPromoCodes:P,getAllPromoCodesFromCookie:f,getCookieMap:i,getCookieValue:d,getPromoCodeFromShopifyCookie:k,getPromoCodesFromCart:u,getPromoCodesLocalStorage:c,getRemoteSession:C,getSanitizedUrlForStorage:A,initNetworkListeners:t,isEmptyPromoData:F,isEqual:S,logger:r,mapToUnvalidatedPromoCodes:L,memoizeLast:l,mergeStoreAndReturnPromos:E,parseJsonStringArray:R,promoCodesAreEqual:v,saveRemoteSession:g,setCookieValue:n,setPromoCodeInCookie:b,setPromoCodesInLocalStorage:y,waitForElement:m});export{V as i};
2
- //# sourceMappingURL=index-AEnQH-so.esm.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-AEnQH-so.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -1,2 +0,0 @@
1
- import{c as i,a as n}from"./routes-VlLXqb7P.esm.js";import{logger as c}from"../utils/logger.js";async function e(o,r){const{apiKey:a,baseUrl:s}=o;try{await i({baseUrl:s||n,headers:{authorization:`Api-Key ${a}`},requestBody:{...r}})}catch(t){c.error("Failed to send log",t)}}var d=Object.freeze({__proto__:null,sendLog:e});export{d as i,e as s};
2
- //# sourceMappingURL=index-B-4isAGW.esm.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-B-4isAGW.esm.js","sources":["../../src/integrations/logs/index.ts"],"sourcesContent":["import { postLogs } from \"../../api-sdk/v3/routes\";\nimport { paths } from \"../../api-sdk/v3/openapi-spec\";\nimport { logger } from \"../../utils/logger\";\nimport { DEFAULT_LOG_URL } from \"../../api-sdk/constants\";\n\ntype PostLogsReq = paths[\"/logs\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"];\n\ninterface SendLogConfig {\n apiKey: string;\n baseUrl?: string;\n}\n\nexport async function sendLog(config: SendLogConfig, payload: PostLogsReq): Promise<void> {\n const { apiKey, baseUrl } = config;\n try {\n await postLogs({\n baseUrl: baseUrl || DEFAULT_LOG_URL,\n headers: {\n authorization: `Api-Key ${apiKey}`,\n },\n requestBody: {\n ...payload,\n },\n });\n } catch (err) {\n logger.error(\"Failed to send log\", err);\n }\n}\n"],"names":["sendLog","config","payload","apiKey","baseUrl","postLogs","DEFAULT_LOG_URL","err","logger"],"mappings":"gGAYA,eAAsBA,EAAQC,EAAuBC,EAAqC,CACxF,KAAM,CAAE,OAAAC,EAAQ,QAAAC,CAAQ,EAAIH,EAC5B,GAAI,CACF,MAAMI,EAAS,CACb,QAASD,GAAWE,EACpB,QAAS,CACP,cAAe,WAAWH,CAAM,EAClC,EACA,YAAa,CACX,GAAGD,CACL,CACF,CAAC,CACH,OAASK,EAAK,CACZC,EAAO,MAAM,qBAAsBD,CAAG,CACxC,CACF"}
@@ -1,2 +0,0 @@
1
- import{O as e}from"./update-cart-BpiNvvDT.esm.js";var r=Object.freeze({__proto__:null,updateCart:e});export{r as i};
2
- //# sourceMappingURL=index-Bp28pZSn.esm.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-Bp28pZSn.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -1,2 +0,0 @@
1
- import{BeamCommunityImpact as m}from"../components/community-impact.js";import{BeamCumulativeImpact as e}from"../components/cumulative-impact.js";import{BeamImpactOverview as a}from"../components/impact-overview.js";import{BeamSelectNonprofit as t}from"../components/select-nonprofit.js";import{BeamRedeemTransaction as o}from"../components/redeem-transaction.js";import{BeamPostPurchase as r}from"../components/post-purchase.js";import{BeamSubscriptionManagement as i}from"../components/subscription-management.js";import{BeamSubscriptionImpact as p}from"../components/subscription-impact.js";import{BeamProductDetailsPage as c}from"../components/product-details-page.js";import{BeamSelectSubscriptionNonprofit as n}from"../components/select-subscription-nonprofit.js";import{BeamSocialShare as B}from"../components/social-share.js";var u=Object.freeze({__proto__:null,BeamCommunityImpact:m,BeamCumulativeImpact:e,BeamImpactOverview:a,BeamPostPurchase:r,BeamProductDetailsPage:c,BeamRedeemTransaction:o,BeamSelectNonprofit:t,BeamSelectSubscriptionNonprofit:n,BeamSocialShare:B,BeamSubscriptionImpact:p,BeamSubscriptionManagement:i});export{u as i};
2
- //# sourceMappingURL=index-CFtmDAHb.esm.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-CFtmDAHb.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -1,2 +0,0 @@
1
- import{c as i,a as n}from"./routes-Dl-QWRUP.esm.js";import{logger as c}from"../utils/logger.esm.js";async function e(o,r){const{apiKey:a,baseUrl:s}=o;try{await i({baseUrl:s||n,headers:{authorization:`Api-Key ${a}`},requestBody:{...r}})}catch(t){c.error("Failed to send log",t)}}var d=Object.freeze({__proto__:null,sendLog:e});export{d as i,e as s};
2
- //# sourceMappingURL=index-CL7fWjz1.esm.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-CL7fWjz1.esm.js","sources":["../../src/integrations/logs/index.ts"],"sourcesContent":["import { postLogs } from \"../../api-sdk/v3/routes\";\nimport { paths } from \"../../api-sdk/v3/openapi-spec\";\nimport { logger } from \"../../utils/logger\";\nimport { DEFAULT_LOG_URL } from \"../../api-sdk/constants\";\n\ntype PostLogsReq = paths[\"/logs\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"];\n\ninterface SendLogConfig {\n apiKey: string;\n baseUrl?: string;\n}\n\nexport async function sendLog(config: SendLogConfig, payload: PostLogsReq): Promise<void> {\n const { apiKey, baseUrl } = config;\n try {\n await postLogs({\n baseUrl: baseUrl || DEFAULT_LOG_URL,\n headers: {\n authorization: `Api-Key ${apiKey}`,\n },\n requestBody: {\n ...payload,\n },\n });\n } catch (err) {\n logger.error(\"Failed to send log\", err);\n }\n}\n"],"names":["sendLog","config","payload","apiKey","baseUrl","postLogs","DEFAULT_LOG_URL","err","logger"],"mappings":"oGAYA,eAAsBA,EAAQC,EAAuBC,EAAqC,CACxF,KAAM,CAAE,OAAAC,EAAQ,QAAAC,CAAQ,EAAIH,EAC5B,GAAI,CACF,MAAMI,EAAS,CACb,QAASD,GAAWE,EACpB,QAAS,CACP,cAAe,WAAWH,CAAM,EAClC,EACA,YAAa,CACX,GAAGD,CACL,CACF,CAAC,CACH,OAASK,EAAK,CACZC,EAAO,MAAM,qBAAsBD,CAAG,CACxC,CACF"}
@@ -1,2 +0,0 @@
1
- import{i}from"./index-DtfQd6C4.esm.js";import{i as o}from"./index-ChmhNz41.esm.js";import{i as r}from"./index-BNjsFEGn.esm.js";import{i as e}from"./index-9s_WWt_5.esm.js";import{i as m}from"./index-B-4isAGW.esm.js";var s=Object.freeze({__proto__:null,Cart:e,Logs:m,Session:r,Shopify:o,Utils:i});export{s as i};
2
- //# sourceMappingURL=index-CfgpHhN1.esm.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-CfgpHhN1.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-ChmhNz41.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -1,2 +0,0 @@
1
- import{b as o}from"./beam-errors-Ci0d3926.esm.js";import{e}from"./events-BohmT6Lp.esm.js";import{logger as r}from"../utils/logger.js";import{initNetworkListeners as t}from"../utils/network-listeners.js";import{createScopedLocalStorage as a}from"../utils/local-storage.js";import{waitForElement as m}from"../utils/wait-for-element.js";import{deleteCookieValue as s,getCookieMap as i,getCookieValue as d,setCookieValue as n}from"../utils/cookies.js";import{getRemoteSession as C,saveRemoteSession as g}from"../utils/remote-session.js";import{memoizeLast as l}from"../utils/memoize-last.js";import{d as p,i as S}from"./lodash-D3TLHRR_.esm.js";import{f as P,c as f,b as k,h as u,g as c,a as A,i as F,m as L,j as E,e as R,p as v,s as b,k as y}from"./promoManager-B9cTR1R3.esm.js";var V=Object.freeze({__proto__:null,createScopedLocalStorage:a,debounce:p,deleteCookieValue:s,errors:o,events:e,formatStoreAndReturnPromoCodes:P,getAllPromoCodesFromCookie:f,getCookieMap:i,getCookieValue:d,getPromoCodeFromShopifyCookie:k,getPromoCodesFromCart:u,getPromoCodesLocalStorage:c,getRemoteSession:C,getSanitizedUrlForStorage:A,initNetworkListeners:t,isEmptyPromoData:F,isEqual:S,logger:r,mapToUnvalidatedPromoCodes:L,memoizeLast:l,mergeStoreAndReturnPromos:E,parseJsonStringArray:R,promoCodesAreEqual:v,saveRemoteSession:g,setCookieValue:n,setPromoCodeInCookie:b,setPromoCodesInLocalStorage:y,waitForElement:m});export{V as i};
2
- //# sourceMappingURL=index-CtYbieoH.esm.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-CtYbieoH.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -1,2 +0,0 @@
1
- import{b as o}from"./beam-errors-Ci0d3926.esm.js";import{e}from"./events-BohmT6Lp.esm.js";import{logger as r}from"../utils/logger.esm.js";import{initNetworkListeners as t}from"../utils/network-listeners.esm.js";import{createScopedLocalStorage as a}from"../utils/local-storage.esm.js";import{waitForElement as m}from"../utils/wait-for-element.esm.js";import{deleteCookieValue as s,getCookieMap as i,getCookieValue as d,setCookieValue as n}from"../utils/cookies.esm.js";import{getRemoteSession as C,saveRemoteSession as g}from"../utils/remote-session.esm.js";import{memoizeLast as l}from"../utils/memoize-last.esm.js";import{d as p,i as S}from"./lodash-D3TLHRR_.esm.js";import{f as P,c as f,b as k,h as u,g as c,a as A,i as F,m as L,j as E,e as R,p as v,s as b,k as y}from"./promoManager-fl54hq13.esm.js";var V=Object.freeze({__proto__:null,createScopedLocalStorage:a,debounce:p,deleteCookieValue:s,errors:o,events:e,formatStoreAndReturnPromoCodes:P,getAllPromoCodesFromCookie:f,getCookieMap:i,getCookieValue:d,getPromoCodeFromShopifyCookie:k,getPromoCodesFromCart:u,getPromoCodesLocalStorage:c,getRemoteSession:C,getSanitizedUrlForStorage:A,initNetworkListeners:t,isEmptyPromoData:F,isEqual:S,logger:r,mapToUnvalidatedPromoCodes:L,memoizeLast:l,mergeStoreAndReturnPromos:E,parseJsonStringArray:R,promoCodesAreEqual:v,saveRemoteSession:g,setCookieValue:n,setPromoCodeInCookie:b,setPromoCodesInLocalStorage:y,waitForElement:m});export{V as i};
2
- //# sourceMappingURL=index-DhhPQ773.esm.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-DhhPQ773.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-DkGjP-Zg.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -1,2 +0,0 @@
1
- import{i}from"./index-AEnQH-so.esm.js";import{i as o}from"./index-DkGjP-Zg.esm.js";import{i as r}from"./index-IKiJwo5v.esm.js";import{i as e}from"./index-Bp28pZSn.esm.js";import{i as m}from"./index-CL7fWjz1.esm.js";var s=Object.freeze({__proto__:null,Cart:e,Logs:m,Session:r,Shopify:o,Utils:i});export{s as i};
2
- //# sourceMappingURL=index-DrOeOk1M.esm.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-DrOeOk1M.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -1,2 +0,0 @@
1
- import{b as o}from"./beam-errors-Ci0d3926.esm.js";import{e}from"./events-BohmT6Lp.esm.js";import{logger as r}from"../utils/logger.js";import{initNetworkListeners as t}from"../utils/network-listeners.js";import{createScopedLocalStorage as a}from"../utils/local-storage.js";import{waitForElement as m}from"../utils/wait-for-element.js";import{deleteCookieValue as s,getCookieMap as i,getCookieValue as d,setCookieValue as n}from"../utils/cookies.js";import{getRemoteSession as C,saveRemoteSession as g}from"../utils/remote-session.js";import{memoizeLast as l}from"../utils/memoize-last.js";import{d as p,i as S}from"./lodash-D3TLHRR_.esm.js";import{f as P,c as f,b as k,h as u,g as c,a as A,i as F,m as L,j as E,e as R,p as v,s as b,k as y}from"./promoManager-B9cTR1R3.esm.js";var V=Object.freeze({__proto__:null,createScopedLocalStorage:a,debounce:p,deleteCookieValue:s,errors:o,events:e,formatStoreAndReturnPromoCodes:P,getAllPromoCodesFromCookie:f,getCookieMap:i,getCookieValue:d,getPromoCodeFromShopifyCookie:k,getPromoCodesFromCart:u,getPromoCodesLocalStorage:c,getRemoteSession:C,getSanitizedUrlForStorage:A,initNetworkListeners:t,isEmptyPromoData:F,isEqual:S,logger:r,mapToUnvalidatedPromoCodes:L,memoizeLast:l,mergeStoreAndReturnPromos:E,parseJsonStringArray:R,promoCodesAreEqual:v,saveRemoteSession:g,setCookieValue:n,setPromoCodeInCookie:b,setPromoCodesInLocalStorage:y,waitForElement:m});export{V as i};
2
- //# sourceMappingURL=index-DtfQd6C4.esm.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-DtfQd6C4.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -1,2 +0,0 @@
1
- import{BeamCommunityImpact as m}from"../components/community-impact.esm.js";import{BeamCumulativeImpact as e}from"../components/cumulative-impact.esm.js";import{BeamImpactOverview as a}from"../components/impact-overview.esm.js";import{BeamSelectNonprofit as t}from"../components/select-nonprofit.esm.js";import{BeamRedeemTransaction as o}from"../components/redeem-transaction.esm.js";import{BeamPostPurchase as r}from"../components/post-purchase.esm.js";import{BeamSubscriptionManagement as i}from"../components/subscription-management.esm.js";import{BeamSubscriptionImpact as p}from"../components/subscription-impact.esm.js";import{BeamProductDetailsPage as c}from"../components/product-details-page.esm.js";import{BeamSelectSubscriptionNonprofit as n}from"../components/select-subscription-nonprofit.esm.js";import{BeamSocialShare as B}from"../components/social-share.esm.js";var u=Object.freeze({__proto__:null,BeamCommunityImpact:m,BeamCumulativeImpact:e,BeamImpactOverview:a,BeamPostPurchase:r,BeamProductDetailsPage:c,BeamRedeemTransaction:o,BeamSelectNonprofit:t,BeamSelectSubscriptionNonprofit:n,BeamSocialShare:B,BeamSubscriptionImpact:p,BeamSubscriptionManagement:i});export{u as i};
2
- //# sourceMappingURL=index-oGObXjk6.esm.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-oGObXjk6.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -1,2 +0,0 @@
1
- import{o as L,i as T,a as O}from"./lodash-D3TLHRR_.esm.js";import{d as k,c as K,i as x,h as W,g as M}from"./events-BohmT6Lp.esm.js";import{logger as w}from"../utils/logger.esm.js";import{initNetworkListeners as q}from"../utils/network-listeners.esm.js";import{createScopedLocalStorage as U}from"../utils/local-storage.esm.js";import{memoizeLast as J}from"../utils/memoize-last.esm.js";import"./promoManager-fl54hq13.esm.js";import{B as j}from"./cart-contents-DkoytiZh.esm.js";import{O as v}from"./update-cart-BpiNvvDT.esm.js";import{W as z,D as F}from"./routes-Dl-QWRUP.esm.js";import{getBeamCartId as A,getExternalCartId as G}from"../utils/cart.esm.js";import"../components/post-purchase.esm.js";import{waitForElement as H}from"../utils/wait-for-element.esm.js";import{B as V}from"./beam-errors-Ci0d3926.esm.js";import{getCookieValue as Y}from"../utils/cookies.esm.js";const E=window.Shopify?.routes?.root||"/";let D=!1;const $="cart";async function Q(t,s=!0){if(D)return!1;q(),window.addEventListener(k.eventName,async a=>{const e=a,o=/cart\/(add|change|update|clear)/,n=e.detail.type==="xhr"?e.detail.xhr.responseURL:e.detail.response.url,d=new URL(n);if(!o.test(d.pathname))return;const i=await S(t);i.changed&&v(t,i.cart)});let l,c;window.addEventListener(K.eventName,async a=>{const e=a;w.debug("[cart-page][BeamNonprofitSelectEvent]",e.detail);const{source:o,selectedNonprofitId:n,selectionId:d}=e.detail;if(o===z.select_nonprofit){if(l===n&&c===d)return;const i=await _(t);await g({...i,selectedNonprofitId:n,selectionId:d}),c=d,l=n}}),window.addEventListener(x.eventName,async a=>{const e=a;w.debug("[cart-page][BeamNonprofitSelectionRemovedEvent]",e.detail);const{newNonprofitId:o,selectionId:n}=e.detail;if(l===o&&c===n)return;const d=await _(t);await g({...d,selectedNonprofitId:null,selectionId:n}),c=n,l=o}),window.addEventListener(W.eventName,async a=>{const e=a;if(w.debug("[cart-page][BeamCartCreatedEvent]",e.detail),window.statsig||s){const o=await _(t);await g(o)}}),window.addEventListener(M.eventName,async a=>{const e=a;if(w.debug("[cart-page][BeamCartChangeEvent]",e.detail),window.statsig||s){const o=await _(t);await g(o)}});const m=await S(t);return await v(t,m.cart,!0),D=!0,!0}async function P(t){const s=await _(t);await g(s)}async function _(t){let s,l;if(window.statsig)try{const o=window.statsig;typeof o?.getLayer("beam_trial_layer")?.get("show_beam")=="boolean"&&(s=o.getLayer("beam_trial_layer").get("show_beam",!1),l=o.getStableID())}catch{}const c=G($,t),m=A(j,t),{chainId:a,storeId:e}=t;return{showBeam:s??void 0,remoteSessionId:l??void 0,beamCartId:m&&m!=="null"?m:void 0,cartId:c&&c!=="null"?c:void 0,chainId:a,storeId:e}}const X=P;async function S(t){const{token:s,total_price:l,item_count:c,currency:m,items:a,cart_level_discount_applications:e}=await N();let o=!1;const n=U(t).getItemJson("cart"),d=A(j,t),i={cartId:s,beamCartId:d,subtotal:l/100,itemCount:c,currencyCode:m,schema:{source:"generic"},content:{items:a.map(({sku:p,final_line_price:u,product_id:y,line_level_discount_allocations:f})=>{const b=p||String(y),C=u/100,h=f?.map(({discount_application:I})=>({code:I?.title,applicable:!0}));return{remoteProductIdentifier:b,localAmount:C,discounts:h}}),discounts:e.map(({title:p})=>({code:p,applicable:!0}))}};return T(i,{...n,beamCartId:n?.beamCartId})||(o=!0),{changed:o,cart:i}}const Z=v,N=async function(){return await window.fetch(E+"cart.js",{method:"GET",headers:{"Content-Type":"application/json"}}).then(t=>t.json())},g=J(async function({selectedNonprofitId:t,selectionId:s,beamCartId:l,cartId:c,chainId:m,storeId:a,showBeam:e,remoteSessionId:o}){const{attributes:n}=await N(),d=n?.beam;let i={};try{d&&(i=JSON.parse(d))}catch(f){w.error(f)}const p=L({nonprofit_id:t,selection_id:s,beam_cart_id:l,shopify_cart_id:c,chain_id:m,store_id:a,show_beam:e,remote_session_id:o},O),u={...i,...p};t===null&&(u.nonprofit_id=void 0);const y={beam:JSON.stringify(u)};if(!T(u,i))try{await window.fetch(E+"cart/update.js",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({attributes:y})})}catch(f){w.error(f)}}),tt=J(async function({selectedNonprofitId:t,selectionId:s,beamCartId:l,cartId:c,chainId:m,storeId:a}){let e,o;if(window.statsig)try{const i=window.statsig;typeof i?.getLayer("beam_trial_layer")?.get("show_beam")=="boolean"&&(e=i.getLayer("beam_trial_layer").get("show_beam",!1),o=i.getStableID())}catch{}const n=L({nonprofit_id:t,selection_id:s,beam_cart_id:l,shopify_cart_id:c,chain_id:m,store_id:a,show_beam:e,remote_session_id:o},O);t===null&&(n.nonprofit_id=void 0);const d={beam:JSON.stringify(n)};try{await window.fetch(E+"cart/update.js",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({attributes:d})})}catch(i){w.error(i)}});async function et({parentSelector:t=".step__sections",apiKey:s,baseUrl:l=F,storeId:c,postalCode:m,discountCodes:a,countryCode:e,orderId:o,email:n,cartTotal:d,cart:i,promoCodes:p,htmlPromoCodes:u,currencyCode:y="USD",domain:f,lang:b="en",debug:C=!1}){const h=document.querySelector(t)||await H(t);if(!h)throw new V(`Timed out waiting for selector '${t}'. Could not render Beam post-purchase widget.`);const I=await Y("cart");if(I){const B=U({apiKey:s}),R=B.getItemJson("cart")||{};B.setItemJson("cart",{...R,cartId:I})}const r=document.createElement("beam-post-purchase");r.apiKey=s,r.baseUrl=l,r.storeId=c,r.postalCode=m,r.countryCode=e,r.orderId=String(o),r.email=n,r.cartTotal=d,r.cart=i,r.promoCodes=p,r.htmlPromoCodes=u,r.discountCodes=a,r.currencyCode=y,r.domain=f,r.lang=b,r.debug=C,h.appendChild(r)}export{N as I,Q as K,P as T,X as W,Z as Y,S as _,_ as f,g,et as s,tt as z};
2
- //# sourceMappingURL=order-page-BPm0hcsC.esm.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"order-page-BPm0hcsC.esm.js","sources":["../../src/integrations/shopify/cart-page.ts","../../src/integrations/shopify/order-page.ts"],"sourcesContent":["/* eslint-disable camelcase */\nimport isEqual from \"lodash-es/isEqual\";\nimport isUndefined from \"lodash-es/isUndefined\";\nimport omitBy from \"lodash-es/omitBy\";\nimport { logger, memoizeLast } from \"../../utils\";\nimport { initNetworkListeners } from \"../../utils/network-listeners\";\nimport {\n BeamCartChangeEvent,\n BeamCartCreatedEvent,\n BeamNetworkCallEvent,\n BeamNonprofitSelectEvent,\n BeamNonprofitSelectionRemovedEvent,\n} from \"../../utils/events\";\nimport { createScopedLocalStorage } from \"../../utils/local-storage\";\nimport { BEAM_CART_COOKIE_NAME, TBeamCartLocalStorage, TCart, TCartItems } from \"../../shared/cart-contents\";\nimport { BeamCartAPIConfig, updateCart } from \"../cart\";\nimport { WIDGET_NAMES } from \"../../api-sdk/constants\";\nimport { getBeamCartId, getExternalCartId } from \"../../utils/cart\";\n\nexport type BeamShopifyCartIntegrationConfig = BeamCartAPIConfig & {\n storeId: number; // will be added to cart custom_attributes, and used in cart API call\n chainId?: number; // will be added to cart custom_attributes\n};\n\ntype ShopifyDiscountApplication = {\n title: string;\n value: string;\n};\n\ntype ShopifyLineLevelDiscountAllocations = {\n amount?: string;\n discount_application: ShopifyDiscountApplication;\n};\n\ntype ShopifyCartBeamAttribute = {\n nonprofit_id?: number | null;\n selection_id?: string;\n beam_cart_id?: string;\n shopify_cart_id?: string;\n chain_id?: number;\n store_id?: number;\n show_beam?: boolean;\n remote_session_id?: string;\n};\n\nconst SHOPIFY_BASE_URL = window.Shopify?.routes?.root || \"/\"; // see window.d.ts\n\nlet isBeamCartIntegrationRegistered = false; // Skip registering event listeners if already set up\n\nconst SHOPIFY_CART_COOKIE_NAME = \"cart\";\n\n/**\n * @main registerCartIntegration - set up event listeners to integrate Beam with Shopify cart\n * @return {boolean} returns true if NEW listeners were created, false if setup was already done\n */\nasync function registerCartIntegration(\n config: BeamShopifyCartIntegrationConfig,\n autoUpdateShopifyCartAttributes = true\n) {\n if (isBeamCartIntegrationRegistered) {\n return false; // Do nothing if listeners are already attached\n }\n\n // logger.debug(\"[cart-page][registerCartIntegration] initializing network listeners\");\n // Set up event listeners for AJAX events\n initNetworkListeners();\n\n // When any network call happens, check if it's for the Shopify /cart AJAX Api.\n // If so, and the cart is updated, send the cart to Beam\n window.addEventListener(BeamNetworkCallEvent.eventName, async (_event: Event) => {\n const event = _event as BeamNetworkCallEvent;\n const cartChangePaths = /cart\\/(add|change|update|clear)/;\n // note: response urls below follow redirects\n const requestUrlStr = event.detail.type === \"xhr\" ? event.detail.xhr.responseURL : event.detail.response.url;\n const url = new URL(requestUrlStr);\n if (!cartChangePaths.test(url.pathname)) {\n return;\n }\n // logger.debug(\"[cart-page][BeamNetworkCallEvent] getting current cart\");\n const currentCart = await getCurrentCart(config);\n if (!currentCart.changed) {\n // logger.debug(`[cart-page][BeamNetworkCallEvent] cart has not changed from URL ${requestUrlStr}`, currentCart.cart);\n return;\n }\n // Send cart to Beam to update timestamp, which is used for cart abandonment / ROI calc\n // logger.debug(`[cart-page][BeamNetworkCallEvent] cart has changed from URL ${requestUrlStr}`, currentCart.cart);\n updateCart(config, currentCart.cart);\n });\n\n // Listen to Beam's own events to integrate Beam data into Shopify order\n let lastNonprofitId: number | null | undefined;\n let lastSelectionId: string | null | undefined;\n window.addEventListener(BeamNonprofitSelectEvent.eventName, async (_event) => {\n const event = _event as BeamNonprofitSelectEvent;\n logger.debug(\"[cart-page][BeamNonprofitSelectEvent]\", event.detail);\n const { source, selectedNonprofitId, selectionId } = event.detail;\n\n // On nonprofit selection, we always write Beam's attributes\n // to the Shopify cart attributes\n if (source === WIDGET_NAMES.select_nonprofit) {\n // Skip update if nothing changed (can happen if widget is re-initialized and\n // emits event after cache restoration, i.e., on cart re-render).\n if (lastNonprofitId === selectedNonprofitId && lastSelectionId === selectionId) {\n return;\n }\n\n const beamCartData = await getBeamAttributesForCart(config);\n await appendBeamAttributesToCart({\n ...beamCartData,\n selectedNonprofitId,\n selectionId,\n });\n lastSelectionId = selectionId;\n lastNonprofitId = selectedNonprofitId;\n }\n });\n\n /**\n * Upon removal of the selected nonprofit from the widget and local storage,\n * an event is emitted and that event is then used to update the cart attributes accordingly\n * This event listener updates the cart attributes based on the emitted event\n */\n window.addEventListener(BeamNonprofitSelectionRemovedEvent.eventName, async (_event) => {\n const event = _event as BeamNonprofitSelectionRemovedEvent;\n logger.debug(\"[cart-page][BeamNonprofitSelectionRemovedEvent]\", event.detail);\n const { newNonprofitId, selectionId } = event.detail;\n\n if (lastNonprofitId === newNonprofitId && lastSelectionId === selectionId) {\n return;\n }\n\n // On nonprofit deselection, we always write Beam's attributes\n // to the Shopify cart attributes\n const beamCartData = await getBeamAttributesForCart(config);\n await appendBeamAttributesToCart({\n ...beamCartData,\n selectedNonprofitId: null,\n selectionId,\n });\n lastSelectionId = selectionId;\n lastNonprofitId = newNonprofitId;\n });\n\n /**\n * When a BeamCart is created, write beam metadata to the Shopify cart if\n * we need to capture it for Statsig or Extensibility\n */\n window.addEventListener(BeamCartCreatedEvent.eventName, async (_event: Event) => {\n const event = _event as BeamCartCreatedEvent;\n logger.debug(\"[cart-page][BeamCartCreatedEvent]\", event.detail);\n if (window.statsig || autoUpdateShopifyCartAttributes) {\n const beamCartData = await getBeamAttributesForCart(config);\n await appendBeamAttributesToCart(beamCartData);\n }\n });\n\n /**\n * On any cart changes, write beam metadata to the Shopify cart if\n * we need to capture it for Statsig or Extensibility\n */\n window.addEventListener(BeamCartChangeEvent.eventName, async (_event: Event) => {\n const event = _event as BeamCartChangeEvent;\n logger.debug(\"[cart-page][BeamCartChangeEvent]\", event.detail);\n if (window.statsig || autoUpdateShopifyCartAttributes) {\n const beamCartData = await getBeamAttributesForCart(config);\n await appendBeamAttributesToCart(beamCartData);\n }\n });\n\n // Handle full-page load, ie, first-time page load and reloads from form submit events\n // This creates a GET to /cart.js\n const currentCart = await getCurrentCart(config);\n // logger.debug(\"[cart-page][registerCartIntegration] initial cart fetch result\", currentCart);\n await updateCart(config, currentCart.cart, true);\n\n isBeamCartIntegrationRegistered = true;\n\n return true;\n}\n\n/* ***************************************** HELPER FUNCTIONS *****************************************\n These may be used individually to integrate with carts if the registerCartIntegration\n script doesn't work for some reason.\n ****************************************************************************************************/\n\nasync function appendToShopifyCartBeamAttribute(config: BeamShopifyCartIntegrationConfig) {\n const beamCartData = await getBeamAttributesForCart(config);\n await appendBeamAttributesToCart(beamCartData);\n}\n\n/**\n * Gathers the base Beam data needed for updating a Shopify cart's metadata\n */\nasync function getBeamAttributesForCart(config: BeamShopifyCartIntegrationConfig) {\n let showBeam;\n let remoteSessionId;\n\n if (window.statsig) {\n // If the site is using Statsig, but not for Beam, we need to ignore it\n try {\n const statsig = window.statsig as any;\n const statsigLayerProperty = statsig?.getLayer(\"beam_trial_layer\")?.get(\"show_beam\");\n if (typeof statsigLayerProperty === \"boolean\") {\n showBeam = statsig.getLayer(\"beam_trial_layer\").get(\"show_beam\", false /* default to hide */) as boolean;\n remoteSessionId = statsig.getStableID();\n }\n } catch (err) {\n // logger.error(err)\n }\n }\n\n const cartId = getExternalCartId(SHOPIFY_CART_COOKIE_NAME, config);\n const beamCartId = getBeamCartId(BEAM_CART_COOKIE_NAME, config);\n const { chainId, storeId } = config;\n\n return {\n showBeam: showBeam ?? undefined,\n remoteSessionId: remoteSessionId ?? undefined,\n beamCartId: beamCartId && beamCartId !== \"null\" ? beamCartId : undefined,\n cartId: cartId && cartId !== \"null\" ? cartId : undefined,\n chainId,\n storeId,\n };\n}\n\n/**\n * Adds Statsig data to a Shopify cart\n */\nconst appendStatsigToShopifyCartAttributes = appendToShopifyCartBeamAttribute;\n\n/**\n * Detects change in cart since last page load,\n * by calling GET /cart.js, and returns cart values.\n * Used for:\n * - Form-based carts where the page refreshes to modify cart instead of using AJAX calls\n * - Hydrogen/GraphQL based carts (needs to be integrated manually)\n */\nasync function getCurrentCart(config: BeamShopifyCartIntegrationConfig): Promise<{\n changed: boolean;\n cart: {\n cartId: string;\n subtotal: number;\n itemCount: number;\n currencyCode: string;\n } & TCart;\n}> {\n const {\n token, // equal to \"cart\" cookie\n total_price, // this is the pretax value, after discounts, and multiplied by 100 (integer from decimal)\n item_count,\n currency,\n items,\n cart_level_discount_applications,\n } = await getShopifyCart();\n\n let changed = false;\n\n const localStorage = createScopedLocalStorage(config);\n\n // The cart cache is used to detect changes after page refreshes / across tabs\n const cachedCart: TBeamCartLocalStorage | null = localStorage.getItemJson(\"cart\");\n // The Beam cart cookie is used to identify the cart across subdomains\n // Use explicit null if empty because API requires it\n const beamCartId: string | null = getBeamCartId(BEAM_CART_COOKIE_NAME, config);\n\n const cart = {\n cartId: token,\n beamCartId,\n subtotal: total_price / 100,\n itemCount: item_count,\n currencyCode: currency,\n schema: { source: \"generic\" } as const,\n content: {\n // pull out minimal fields from full line items\n items: (items as TCartItems).map(({ sku, final_line_price, product_id, line_level_discount_allocations }) => {\n const remoteProductIdentifier = sku || String(product_id);\n const localAmount = final_line_price / 100;\n const discounts = (line_level_discount_allocations as ShopifyLineLevelDiscountAllocations[])?.map(\n ({ discount_application }) => {\n return { code: discount_application?.title, applicable: true };\n }\n );\n return { remoteProductIdentifier, localAmount, discounts };\n }),\n discounts: (cart_level_discount_applications as ShopifyDiscountApplication[]).map(({ title }) => {\n return { code: title, applicable: true };\n }),\n },\n };\n\n if (\n !isEqual(cart, {\n ...cachedCart,\n beamCartId: cachedCart?.beamCartId,\n })\n ) {\n changed = true;\n }\n\n // logger.debug(\"[cart-page][getCurrentCart] has cart changed?\", changed, cart);\n\n return { changed, cart };\n}\n\n/**\n * trackCart - Backwards-compatible alias for updateCart\n */\nconst trackCart = updateCart;\n\n/**\n * Helper function to get the Shopify cart attributes\n */\nconst getShopifyCart = async function () {\n const cart = await window\n .fetch(SHOPIFY_BASE_URL + \"cart.js\", {\n method: \"GET\",\n headers: { \"Content-Type\": \"application/json\" },\n })\n .then((res) => res.json());\n return cart;\n};\n\n/**\n * Sends Beam data to Shopify to integrate with order as custom attributes.\n * Memoized so that calls with the same data as the previous don't create additional API calls to Shopify.\n * This will do an append, not a full overwrite of the attributes in the beam property\n */\nconst appendBeamAttributesToCart = memoizeLast(async function appendBeamAttributesToCart({\n selectedNonprofitId,\n selectionId,\n beamCartId,\n cartId,\n chainId,\n storeId,\n showBeam,\n remoteSessionId,\n}: {\n selectedNonprofitId?: number | null;\n selectionId?: string;\n beamCartId?: string;\n cartId?: string;\n chainId?: number;\n storeId?: number;\n showBeam?: boolean;\n remoteSessionId?: string;\n}) {\n // logger.debug(\"[cart-page][appendBeamAttributesToCart] fetching existing cart\");\n const { attributes } = await getShopifyCart();\n\n // Get only the Beam attribute, if it exists\n const existingBeamCartAttrString = attributes?.beam;\n let existingBeamCartAttr = {};\n try {\n if (existingBeamCartAttrString) {\n existingBeamCartAttr = JSON.parse(existingBeamCartAttrString);\n }\n } catch (err) {\n logger.error(err);\n }\n\n const newBeamAttrs = omitBy(\n {\n nonprofit_id: selectedNonprofitId,\n selection_id: selectionId,\n beam_cart_id: beamCartId,\n shopify_cart_id: cartId,\n chain_id: chainId,\n store_id: storeId,\n show_beam: showBeam,\n remote_session_id: remoteSessionId,\n },\n isUndefined\n );\n\n const appendedBeamAttributes = {\n ...existingBeamCartAttr,\n ...newBeamAttrs,\n } as ShopifyCartBeamAttribute;\n\n // For the nonprofitId, if we specifically get a null value here,\n // we want to remove it from the cart attributes, not just write \"null\"\n if (selectedNonprofitId === null) {\n appendedBeamAttributes.nonprofit_id = undefined;\n }\n\n const beamCartAttrs = {\n beam: JSON.stringify(appendedBeamAttributes),\n };\n\n // If the attributes match, no reason to update the cart\n if (isEqual(appendedBeamAttributes, existingBeamCartAttr)) {\n // logger.debug(\"[cart-page][appendBeamAttributesToCart] cart attributes match, skipping update\");\n return;\n }\n\n try {\n // logger.debug(\"[cart-page][appendBeamAttributesToCart] updating Shopify cart\");\n await window.fetch(SHOPIFY_BASE_URL + \"cart/update.js\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ attributes: beamCartAttrs }),\n });\n } catch (err) {\n logger.error(err); // don't throw, allow later calls to continue\n }\n});\n\n/**\n * Sends Beam data to Shopify to integrate with order as custom attributes.\n * Memoized so that calls with the same data as the previous don't create additional API calls to Shopify.\n * This method force-updates the \"beam\" attribute with the values passed in\n */\nconst addBeamAttributesToCart = memoizeLast(async function addBeamAttributesToCart({\n selectedNonprofitId,\n selectionId,\n beamCartId,\n cartId,\n chainId,\n storeId,\n}: {\n selectedNonprofitId?: number | null;\n selectionId?: string;\n beamCartId?: string;\n cartId?: string;\n chainId?: number;\n storeId?: number;\n}) {\n let showBeam;\n let remoteSessionId;\n\n if (window.statsig) {\n // If the site is using Statsig, but not for Beam, we need to ignore it\n try {\n const statsig = window.statsig as any;\n const statsigLayerProperty = statsig?.getLayer(\"beam_trial_layer\")?.get(\"show_beam\");\n if (typeof statsigLayerProperty === \"boolean\") {\n showBeam = statsig.getLayer(\"beam_trial_layer\").get(\"show_beam\", false /* default to hide */) as boolean;\n remoteSessionId = statsig.getStableID();\n }\n } catch (err) {\n // logger.error(err)\n }\n }\n\n const allBeamAttributes = omitBy(\n {\n nonprofit_id: selectedNonprofitId,\n selection_id: selectionId,\n beam_cart_id: beamCartId,\n shopify_cart_id: cartId,\n chain_id: chainId,\n store_id: storeId,\n show_beam: showBeam,\n remote_session_id: remoteSessionId,\n },\n isUndefined\n ) as ShopifyCartBeamAttribute;\n\n // For the nonprofitId, if we specifically get a null value here,\n // we want to remove it from the cart attributes, not just write \"null\"\n if (selectedNonprofitId === null) {\n allBeamAttributes.nonprofit_id = undefined;\n }\n\n const beamCartAttrs = {\n beam: JSON.stringify(allBeamAttributes),\n };\n\n try {\n await window.fetch(SHOPIFY_BASE_URL + \"cart/update.js\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ attributes: beamCartAttrs }),\n });\n } catch (err) {\n logger.error(err); // don't throw, allow later calls to continue\n }\n});\n\ndeclare global {\n interface Window {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n statsig?: any; // attached by Statsig CDN script\n }\n}\nexport {\n trackCart,\n getCurrentCart,\n addBeamAttributesToCart,\n appendStatsigToShopifyCartAttributes,\n appendToShopifyCartBeamAttribute,\n registerCartIntegration,\n appendBeamAttributesToCart,\n getShopifyCart,\n getBeamAttributesForCart,\n};\n","import \"../../components/post-purchase\";\nimport { postTransaction } from \"../../api-sdk/v3/routes\";\nimport { DEFAULT_BASE_URL } from \"../../api-sdk/constants\";\nimport { LANGUAGES, TUrl } from \"../../api-sdk/types\";\nimport { waitForElement } from \"../../utils/wait-for-element\";\nimport { BeamError } from \"../../utils/beam-errors\";\nimport { getCookieValue } from \"../../utils/cookies\";\nimport { createScopedLocalStorage } from \"../../utils/local-storage\";\nimport { TCart } from \"../../shared/cart-contents\";\n\n// Shopify admin page: admin/settings/checkout\n\nexport type TBeamOrderPageParams = Parameters<typeof postTransaction>[0][\"requestBody\"] & {\n // Either storeId or postalCode + countryCode must be provided\n storeId?: number;\n postalCode?: string;\n countryCode?: string;\n orderId: string;\n email: string;\n cartTotal: number;\n cart: TCart;\n discountCodes: string[];\n promoCodes: string[];\n htmlPromoCodes: string;\n currencyCode: string;\n parentSelector: string; // CSS Selector for parent of widget to be inserted into DOM\n apiKey: string;\n baseUrl: TUrl;\n domain?: string; // Base domain for setting cookies\n lang: LANGUAGES;\n debug: boolean;\n};\n\nexport async function showBeamOrderPageWidgets({\n parentSelector = \".step__sections\",\n apiKey,\n baseUrl = DEFAULT_BASE_URL,\n storeId,\n postalCode,\n discountCodes,\n countryCode,\n orderId,\n email,\n cartTotal,\n cart,\n promoCodes,\n htmlPromoCodes,\n currencyCode = \"USD\",\n domain,\n lang = \"en\",\n debug = false,\n}: TBeamOrderPageParams) {\n const parentElement = document.querySelector(parentSelector) || (await waitForElement(parentSelector));\n if (!parentElement) {\n throw new BeamError(\n `Timed out waiting for selector '${parentSelector}'. Could not render Beam post-purchase widget.`\n );\n }\n\n // If checkout and order page are on different subdomains, we can't access localStorage\n // We can make postTransaction work by copying the cart cookie to the expected localStorage key on the current domain\n const cartId = await getCookieValue(\"cart\"); // Shopify-only cart identifier\n if (cartId) {\n const beamLocalStorage = createScopedLocalStorage({ apiKey });\n const existingValue = beamLocalStorage.getItemJson(\"cart\") || {};\n beamLocalStorage.setItemJson(\"cart\", { ...existingValue, cartId });\n }\n\n // Note: assign properties one by one instead of bulk Object.assign to type check assignments\n const widget = document.createElement(\"beam-post-purchase\");\n widget.apiKey = apiKey;\n widget.baseUrl = baseUrl;\n widget.storeId = storeId;\n widget.postalCode = postalCode;\n widget.countryCode = countryCode;\n widget.orderId = String(orderId);\n widget.email = email;\n widget.cartTotal = cartTotal;\n widget.cart = cart;\n widget.promoCodes = promoCodes;\n widget.htmlPromoCodes = htmlPromoCodes;\n widget.discountCodes = discountCodes;\n widget.currencyCode = currencyCode;\n widget.domain = domain;\n widget.lang = lang;\n widget.debug = debug;\n\n // Insert widget into DOM\n parentElement.appendChild(widget);\n}\n"],"names":["SHOPIFY_BASE_URL","isBeamCartIntegrationRegistered","SHOPIFY_CART_COOKIE_NAME","registerCartIntegration","config","autoUpdateShopifyCartAttributes","initNetworkListeners","BeamNetworkCallEvent","_event","event","cartChangePaths","requestUrlStr","url","currentCart","getCurrentCart","updateCart","lastNonprofitId","lastSelectionId","BeamNonprofitSelectEvent","logger","source","selectedNonprofitId","selectionId","WIDGET_NAMES","beamCartData","getBeamAttributesForCart","appendBeamAttributesToCart","BeamNonprofitSelectionRemovedEvent","newNonprofitId","BeamCartCreatedEvent","BeamCartChangeEvent","appendToShopifyCartBeamAttribute","showBeam","remoteSessionId","statsig","cartId","getExternalCartId","beamCartId","getBeamCartId","BEAM_CART_COOKIE_NAME","chainId","storeId","appendStatsigToShopifyCartAttributes","token","total_price","item_count","currency","items","cart_level_discount_applications","getShopifyCart","changed","cachedCart","createScopedLocalStorage","cart","sku","final_line_price","product_id","line_level_discount_allocations","remoteProductIdentifier","localAmount","discounts","discount_application","title","isEqual","trackCart","res","memoizeLast","attributes","existingBeamCartAttrString","existingBeamCartAttr","err","newBeamAttrs","omitBy","isUndefined","appendedBeamAttributes","beamCartAttrs","addBeamAttributesToCart","allBeamAttributes","showBeamOrderPageWidgets","parentSelector","apiKey","baseUrl","DEFAULT_BASE_URL","postalCode","discountCodes","countryCode","orderId","email","cartTotal","promoCodes","htmlPromoCodes","currencyCode","domain","lang","debug","parentElement","waitForElement","BeamError","getCookieValue","beamLocalStorage","existingValue","widget"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- import{o as L,i as T,a as O}from"./lodash-D3TLHRR_.esm.js";import{d as k,c as K,i as x,h as W,g as M}from"./events-BohmT6Lp.esm.js";import{logger as w}from"../utils/logger.js";import{initNetworkListeners as q}from"../utils/network-listeners.js";import{createScopedLocalStorage as U}from"../utils/local-storage.js";import{memoizeLast as J}from"../utils/memoize-last.js";import"./promoManager-B9cTR1R3.esm.js";import{B as j}from"./cart-contents-DkoytiZh.esm.js";import{O as v}from"./update-cart-DIJcb6w0.esm.js";import{W as z,D as F}from"./routes-VlLXqb7P.esm.js";import{getBeamCartId as A,getExternalCartId as G}from"../utils/cart.js";import"../components/post-purchase.js";import{waitForElement as H}from"../utils/wait-for-element.js";import{B as V}from"./beam-errors-Ci0d3926.esm.js";import{getCookieValue as Y}from"../utils/cookies.js";const E=window.Shopify?.routes?.root||"/";let D=!1;const $="cart";async function Q(t,s=!0){if(D)return!1;q(),window.addEventListener(k.eventName,async a=>{const e=a,o=/cart\/(add|change|update|clear)/,n=e.detail.type==="xhr"?e.detail.xhr.responseURL:e.detail.response.url,d=new URL(n);if(!o.test(d.pathname))return;const i=await S(t);i.changed&&v(t,i.cart)});let l,c;window.addEventListener(K.eventName,async a=>{const e=a;w.debug("[cart-page][BeamNonprofitSelectEvent]",e.detail);const{source:o,selectedNonprofitId:n,selectionId:d}=e.detail;if(o===z.select_nonprofit){if(l===n&&c===d)return;const i=await _(t);await g({...i,selectedNonprofitId:n,selectionId:d}),c=d,l=n}}),window.addEventListener(x.eventName,async a=>{const e=a;w.debug("[cart-page][BeamNonprofitSelectionRemovedEvent]",e.detail);const{newNonprofitId:o,selectionId:n}=e.detail;if(l===o&&c===n)return;const d=await _(t);await g({...d,selectedNonprofitId:null,selectionId:n}),c=n,l=o}),window.addEventListener(W.eventName,async a=>{const e=a;if(w.debug("[cart-page][BeamCartCreatedEvent]",e.detail),window.statsig||s){const o=await _(t);await g(o)}}),window.addEventListener(M.eventName,async a=>{const e=a;if(w.debug("[cart-page][BeamCartChangeEvent]",e.detail),window.statsig||s){const o=await _(t);await g(o)}});const m=await S(t);return await v(t,m.cart,!0),D=!0,!0}async function P(t){const s=await _(t);await g(s)}async function _(t){let s,l;if(window.statsig)try{const o=window.statsig;typeof o?.getLayer("beam_trial_layer")?.get("show_beam")=="boolean"&&(s=o.getLayer("beam_trial_layer").get("show_beam",!1),l=o.getStableID())}catch{}const c=G($,t),m=A(j,t),{chainId:a,storeId:e}=t;return{showBeam:s??void 0,remoteSessionId:l??void 0,beamCartId:m&&m!=="null"?m:void 0,cartId:c&&c!=="null"?c:void 0,chainId:a,storeId:e}}const X=P;async function S(t){const{token:s,total_price:l,item_count:c,currency:m,items:a,cart_level_discount_applications:e}=await N();let o=!1;const n=U(t).getItemJson("cart"),d=A(j,t),i={cartId:s,beamCartId:d,subtotal:l/100,itemCount:c,currencyCode:m,schema:{source:"generic"},content:{items:a.map(({sku:p,final_line_price:u,product_id:y,line_level_discount_allocations:f})=>{const b=p||String(y),C=u/100,h=f?.map(({discount_application:I})=>({code:I?.title,applicable:!0}));return{remoteProductIdentifier:b,localAmount:C,discounts:h}}),discounts:e.map(({title:p})=>({code:p,applicable:!0}))}};return T(i,{...n,beamCartId:n?.beamCartId})||(o=!0),{changed:o,cart:i}}const Z=v,N=async function(){return await window.fetch(E+"cart.js",{method:"GET",headers:{"Content-Type":"application/json"}}).then(t=>t.json())},g=J(async function({selectedNonprofitId:t,selectionId:s,beamCartId:l,cartId:c,chainId:m,storeId:a,showBeam:e,remoteSessionId:o}){const{attributes:n}=await N(),d=n?.beam;let i={};try{d&&(i=JSON.parse(d))}catch(f){w.error(f)}const p=L({nonprofit_id:t,selection_id:s,beam_cart_id:l,shopify_cart_id:c,chain_id:m,store_id:a,show_beam:e,remote_session_id:o},O),u={...i,...p};t===null&&(u.nonprofit_id=void 0);const y={beam:JSON.stringify(u)};if(!T(u,i))try{await window.fetch(E+"cart/update.js",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({attributes:y})})}catch(f){w.error(f)}}),tt=J(async function({selectedNonprofitId:t,selectionId:s,beamCartId:l,cartId:c,chainId:m,storeId:a}){let e,o;if(window.statsig)try{const i=window.statsig;typeof i?.getLayer("beam_trial_layer")?.get("show_beam")=="boolean"&&(e=i.getLayer("beam_trial_layer").get("show_beam",!1),o=i.getStableID())}catch{}const n=L({nonprofit_id:t,selection_id:s,beam_cart_id:l,shopify_cart_id:c,chain_id:m,store_id:a,show_beam:e,remote_session_id:o},O);t===null&&(n.nonprofit_id=void 0);const d={beam:JSON.stringify(n)};try{await window.fetch(E+"cart/update.js",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({attributes:d})})}catch(i){w.error(i)}});async function et({parentSelector:t=".step__sections",apiKey:s,baseUrl:l=F,storeId:c,postalCode:m,discountCodes:a,countryCode:e,orderId:o,email:n,cartTotal:d,cart:i,promoCodes:p,htmlPromoCodes:u,currencyCode:y="USD",domain:f,lang:b="en",debug:C=!1}){const h=document.querySelector(t)||await H(t);if(!h)throw new V(`Timed out waiting for selector '${t}'. Could not render Beam post-purchase widget.`);const I=await Y("cart");if(I){const B=U({apiKey:s}),R=B.getItemJson("cart")||{};B.setItemJson("cart",{...R,cartId:I})}const r=document.createElement("beam-post-purchase");r.apiKey=s,r.baseUrl=l,r.storeId=c,r.postalCode=m,r.countryCode=e,r.orderId=String(o),r.email=n,r.cartTotal=d,r.cart=i,r.promoCodes=p,r.htmlPromoCodes=u,r.discountCodes=a,r.currencyCode=y,r.domain=f,r.lang=b,r.debug=C,h.appendChild(r)}export{N as I,Q as K,P as T,X as W,Z as Y,S as _,_ as f,g,et as s,tt as z};
2
- //# sourceMappingURL=order-page-DFtCsDYa.esm.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"order-page-DFtCsDYa.esm.js","sources":["../../src/integrations/shopify/cart-page.ts","../../src/integrations/shopify/order-page.ts"],"sourcesContent":["/* eslint-disable camelcase */\nimport isEqual from \"lodash-es/isEqual\";\nimport isUndefined from \"lodash-es/isUndefined\";\nimport omitBy from \"lodash-es/omitBy\";\nimport { logger, memoizeLast } from \"../../utils\";\nimport { initNetworkListeners } from \"../../utils/network-listeners\";\nimport {\n BeamCartChangeEvent,\n BeamCartCreatedEvent,\n BeamNetworkCallEvent,\n BeamNonprofitSelectEvent,\n BeamNonprofitSelectionRemovedEvent,\n} from \"../../utils/events\";\nimport { createScopedLocalStorage } from \"../../utils/local-storage\";\nimport { BEAM_CART_COOKIE_NAME, TBeamCartLocalStorage, TCart, TCartItems } from \"../../shared/cart-contents\";\nimport { BeamCartAPIConfig, updateCart } from \"../cart\";\nimport { WIDGET_NAMES } from \"../../api-sdk/constants\";\nimport { getBeamCartId, getExternalCartId } from \"../../utils/cart\";\n\nexport type BeamShopifyCartIntegrationConfig = BeamCartAPIConfig & {\n storeId: number; // will be added to cart custom_attributes, and used in cart API call\n chainId?: number; // will be added to cart custom_attributes\n};\n\ntype ShopifyDiscountApplication = {\n title: string;\n value: string;\n};\n\ntype ShopifyLineLevelDiscountAllocations = {\n amount?: string;\n discount_application: ShopifyDiscountApplication;\n};\n\ntype ShopifyCartBeamAttribute = {\n nonprofit_id?: number | null;\n selection_id?: string;\n beam_cart_id?: string;\n shopify_cart_id?: string;\n chain_id?: number;\n store_id?: number;\n show_beam?: boolean;\n remote_session_id?: string;\n};\n\nconst SHOPIFY_BASE_URL = window.Shopify?.routes?.root || \"/\"; // see window.d.ts\n\nlet isBeamCartIntegrationRegistered = false; // Skip registering event listeners if already set up\n\nconst SHOPIFY_CART_COOKIE_NAME = \"cart\";\n\n/**\n * @main registerCartIntegration - set up event listeners to integrate Beam with Shopify cart\n * @return {boolean} returns true if NEW listeners were created, false if setup was already done\n */\nasync function registerCartIntegration(\n config: BeamShopifyCartIntegrationConfig,\n autoUpdateShopifyCartAttributes = true\n) {\n if (isBeamCartIntegrationRegistered) {\n return false; // Do nothing if listeners are already attached\n }\n\n // logger.debug(\"[cart-page][registerCartIntegration] initializing network listeners\");\n // Set up event listeners for AJAX events\n initNetworkListeners();\n\n // When any network call happens, check if it's for the Shopify /cart AJAX Api.\n // If so, and the cart is updated, send the cart to Beam\n window.addEventListener(BeamNetworkCallEvent.eventName, async (_event: Event) => {\n const event = _event as BeamNetworkCallEvent;\n const cartChangePaths = /cart\\/(add|change|update|clear)/;\n // note: response urls below follow redirects\n const requestUrlStr = event.detail.type === \"xhr\" ? event.detail.xhr.responseURL : event.detail.response.url;\n const url = new URL(requestUrlStr);\n if (!cartChangePaths.test(url.pathname)) {\n return;\n }\n // logger.debug(\"[cart-page][BeamNetworkCallEvent] getting current cart\");\n const currentCart = await getCurrentCart(config);\n if (!currentCart.changed) {\n // logger.debug(`[cart-page][BeamNetworkCallEvent] cart has not changed from URL ${requestUrlStr}`, currentCart.cart);\n return;\n }\n // Send cart to Beam to update timestamp, which is used for cart abandonment / ROI calc\n // logger.debug(`[cart-page][BeamNetworkCallEvent] cart has changed from URL ${requestUrlStr}`, currentCart.cart);\n updateCart(config, currentCart.cart);\n });\n\n // Listen to Beam's own events to integrate Beam data into Shopify order\n let lastNonprofitId: number | null | undefined;\n let lastSelectionId: string | null | undefined;\n window.addEventListener(BeamNonprofitSelectEvent.eventName, async (_event) => {\n const event = _event as BeamNonprofitSelectEvent;\n logger.debug(\"[cart-page][BeamNonprofitSelectEvent]\", event.detail);\n const { source, selectedNonprofitId, selectionId } = event.detail;\n\n // On nonprofit selection, we always write Beam's attributes\n // to the Shopify cart attributes\n if (source === WIDGET_NAMES.select_nonprofit) {\n // Skip update if nothing changed (can happen if widget is re-initialized and\n // emits event after cache restoration, i.e., on cart re-render).\n if (lastNonprofitId === selectedNonprofitId && lastSelectionId === selectionId) {\n return;\n }\n\n const beamCartData = await getBeamAttributesForCart(config);\n await appendBeamAttributesToCart({\n ...beamCartData,\n selectedNonprofitId,\n selectionId,\n });\n lastSelectionId = selectionId;\n lastNonprofitId = selectedNonprofitId;\n }\n });\n\n /**\n * Upon removal of the selected nonprofit from the widget and local storage,\n * an event is emitted and that event is then used to update the cart attributes accordingly\n * This event listener updates the cart attributes based on the emitted event\n */\n window.addEventListener(BeamNonprofitSelectionRemovedEvent.eventName, async (_event) => {\n const event = _event as BeamNonprofitSelectionRemovedEvent;\n logger.debug(\"[cart-page][BeamNonprofitSelectionRemovedEvent]\", event.detail);\n const { newNonprofitId, selectionId } = event.detail;\n\n if (lastNonprofitId === newNonprofitId && lastSelectionId === selectionId) {\n return;\n }\n\n // On nonprofit deselection, we always write Beam's attributes\n // to the Shopify cart attributes\n const beamCartData = await getBeamAttributesForCart(config);\n await appendBeamAttributesToCart({\n ...beamCartData,\n selectedNonprofitId: null,\n selectionId,\n });\n lastSelectionId = selectionId;\n lastNonprofitId = newNonprofitId;\n });\n\n /**\n * When a BeamCart is created, write beam metadata to the Shopify cart if\n * we need to capture it for Statsig or Extensibility\n */\n window.addEventListener(BeamCartCreatedEvent.eventName, async (_event: Event) => {\n const event = _event as BeamCartCreatedEvent;\n logger.debug(\"[cart-page][BeamCartCreatedEvent]\", event.detail);\n if (window.statsig || autoUpdateShopifyCartAttributes) {\n const beamCartData = await getBeamAttributesForCart(config);\n await appendBeamAttributesToCart(beamCartData);\n }\n });\n\n /**\n * On any cart changes, write beam metadata to the Shopify cart if\n * we need to capture it for Statsig or Extensibility\n */\n window.addEventListener(BeamCartChangeEvent.eventName, async (_event: Event) => {\n const event = _event as BeamCartChangeEvent;\n logger.debug(\"[cart-page][BeamCartChangeEvent]\", event.detail);\n if (window.statsig || autoUpdateShopifyCartAttributes) {\n const beamCartData = await getBeamAttributesForCart(config);\n await appendBeamAttributesToCart(beamCartData);\n }\n });\n\n // Handle full-page load, ie, first-time page load and reloads from form submit events\n // This creates a GET to /cart.js\n const currentCart = await getCurrentCart(config);\n // logger.debug(\"[cart-page][registerCartIntegration] initial cart fetch result\", currentCart);\n await updateCart(config, currentCart.cart, true);\n\n isBeamCartIntegrationRegistered = true;\n\n return true;\n}\n\n/* ***************************************** HELPER FUNCTIONS *****************************************\n These may be used individually to integrate with carts if the registerCartIntegration\n script doesn't work for some reason.\n ****************************************************************************************************/\n\nasync function appendToShopifyCartBeamAttribute(config: BeamShopifyCartIntegrationConfig) {\n const beamCartData = await getBeamAttributesForCart(config);\n await appendBeamAttributesToCart(beamCartData);\n}\n\n/**\n * Gathers the base Beam data needed for updating a Shopify cart's metadata\n */\nasync function getBeamAttributesForCart(config: BeamShopifyCartIntegrationConfig) {\n let showBeam;\n let remoteSessionId;\n\n if (window.statsig) {\n // If the site is using Statsig, but not for Beam, we need to ignore it\n try {\n const statsig = window.statsig as any;\n const statsigLayerProperty = statsig?.getLayer(\"beam_trial_layer\")?.get(\"show_beam\");\n if (typeof statsigLayerProperty === \"boolean\") {\n showBeam = statsig.getLayer(\"beam_trial_layer\").get(\"show_beam\", false /* default to hide */) as boolean;\n remoteSessionId = statsig.getStableID();\n }\n } catch (err) {\n // logger.error(err)\n }\n }\n\n const cartId = getExternalCartId(SHOPIFY_CART_COOKIE_NAME, config);\n const beamCartId = getBeamCartId(BEAM_CART_COOKIE_NAME, config);\n const { chainId, storeId } = config;\n\n return {\n showBeam: showBeam ?? undefined,\n remoteSessionId: remoteSessionId ?? undefined,\n beamCartId: beamCartId && beamCartId !== \"null\" ? beamCartId : undefined,\n cartId: cartId && cartId !== \"null\" ? cartId : undefined,\n chainId,\n storeId,\n };\n}\n\n/**\n * Adds Statsig data to a Shopify cart\n */\nconst appendStatsigToShopifyCartAttributes = appendToShopifyCartBeamAttribute;\n\n/**\n * Detects change in cart since last page load,\n * by calling GET /cart.js, and returns cart values.\n * Used for:\n * - Form-based carts where the page refreshes to modify cart instead of using AJAX calls\n * - Hydrogen/GraphQL based carts (needs to be integrated manually)\n */\nasync function getCurrentCart(config: BeamShopifyCartIntegrationConfig): Promise<{\n changed: boolean;\n cart: {\n cartId: string;\n subtotal: number;\n itemCount: number;\n currencyCode: string;\n } & TCart;\n}> {\n const {\n token, // equal to \"cart\" cookie\n total_price, // this is the pretax value, after discounts, and multiplied by 100 (integer from decimal)\n item_count,\n currency,\n items,\n cart_level_discount_applications,\n } = await getShopifyCart();\n\n let changed = false;\n\n const localStorage = createScopedLocalStorage(config);\n\n // The cart cache is used to detect changes after page refreshes / across tabs\n const cachedCart: TBeamCartLocalStorage | null = localStorage.getItemJson(\"cart\");\n // The Beam cart cookie is used to identify the cart across subdomains\n // Use explicit null if empty because API requires it\n const beamCartId: string | null = getBeamCartId(BEAM_CART_COOKIE_NAME, config);\n\n const cart = {\n cartId: token,\n beamCartId,\n subtotal: total_price / 100,\n itemCount: item_count,\n currencyCode: currency,\n schema: { source: \"generic\" } as const,\n content: {\n // pull out minimal fields from full line items\n items: (items as TCartItems).map(({ sku, final_line_price, product_id, line_level_discount_allocations }) => {\n const remoteProductIdentifier = sku || String(product_id);\n const localAmount = final_line_price / 100;\n const discounts = (line_level_discount_allocations as ShopifyLineLevelDiscountAllocations[])?.map(\n ({ discount_application }) => {\n return { code: discount_application?.title, applicable: true };\n }\n );\n return { remoteProductIdentifier, localAmount, discounts };\n }),\n discounts: (cart_level_discount_applications as ShopifyDiscountApplication[]).map(({ title }) => {\n return { code: title, applicable: true };\n }),\n },\n };\n\n if (\n !isEqual(cart, {\n ...cachedCart,\n beamCartId: cachedCart?.beamCartId,\n })\n ) {\n changed = true;\n }\n\n // logger.debug(\"[cart-page][getCurrentCart] has cart changed?\", changed, cart);\n\n return { changed, cart };\n}\n\n/**\n * trackCart - Backwards-compatible alias for updateCart\n */\nconst trackCart = updateCart;\n\n/**\n * Helper function to get the Shopify cart attributes\n */\nconst getShopifyCart = async function () {\n const cart = await window\n .fetch(SHOPIFY_BASE_URL + \"cart.js\", {\n method: \"GET\",\n headers: { \"Content-Type\": \"application/json\" },\n })\n .then((res) => res.json());\n return cart;\n};\n\n/**\n * Sends Beam data to Shopify to integrate with order as custom attributes.\n * Memoized so that calls with the same data as the previous don't create additional API calls to Shopify.\n * This will do an append, not a full overwrite of the attributes in the beam property\n */\nconst appendBeamAttributesToCart = memoizeLast(async function appendBeamAttributesToCart({\n selectedNonprofitId,\n selectionId,\n beamCartId,\n cartId,\n chainId,\n storeId,\n showBeam,\n remoteSessionId,\n}: {\n selectedNonprofitId?: number | null;\n selectionId?: string;\n beamCartId?: string;\n cartId?: string;\n chainId?: number;\n storeId?: number;\n showBeam?: boolean;\n remoteSessionId?: string;\n}) {\n // logger.debug(\"[cart-page][appendBeamAttributesToCart] fetching existing cart\");\n const { attributes } = await getShopifyCart();\n\n // Get only the Beam attribute, if it exists\n const existingBeamCartAttrString = attributes?.beam;\n let existingBeamCartAttr = {};\n try {\n if (existingBeamCartAttrString) {\n existingBeamCartAttr = JSON.parse(existingBeamCartAttrString);\n }\n } catch (err) {\n logger.error(err);\n }\n\n const newBeamAttrs = omitBy(\n {\n nonprofit_id: selectedNonprofitId,\n selection_id: selectionId,\n beam_cart_id: beamCartId,\n shopify_cart_id: cartId,\n chain_id: chainId,\n store_id: storeId,\n show_beam: showBeam,\n remote_session_id: remoteSessionId,\n },\n isUndefined\n );\n\n const appendedBeamAttributes = {\n ...existingBeamCartAttr,\n ...newBeamAttrs,\n } as ShopifyCartBeamAttribute;\n\n // For the nonprofitId, if we specifically get a null value here,\n // we want to remove it from the cart attributes, not just write \"null\"\n if (selectedNonprofitId === null) {\n appendedBeamAttributes.nonprofit_id = undefined;\n }\n\n const beamCartAttrs = {\n beam: JSON.stringify(appendedBeamAttributes),\n };\n\n // If the attributes match, no reason to update the cart\n if (isEqual(appendedBeamAttributes, existingBeamCartAttr)) {\n // logger.debug(\"[cart-page][appendBeamAttributesToCart] cart attributes match, skipping update\");\n return;\n }\n\n try {\n // logger.debug(\"[cart-page][appendBeamAttributesToCart] updating Shopify cart\");\n await window.fetch(SHOPIFY_BASE_URL + \"cart/update.js\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ attributes: beamCartAttrs }),\n });\n } catch (err) {\n logger.error(err); // don't throw, allow later calls to continue\n }\n});\n\n/**\n * Sends Beam data to Shopify to integrate with order as custom attributes.\n * Memoized so that calls with the same data as the previous don't create additional API calls to Shopify.\n * This method force-updates the \"beam\" attribute with the values passed in\n */\nconst addBeamAttributesToCart = memoizeLast(async function addBeamAttributesToCart({\n selectedNonprofitId,\n selectionId,\n beamCartId,\n cartId,\n chainId,\n storeId,\n}: {\n selectedNonprofitId?: number | null;\n selectionId?: string;\n beamCartId?: string;\n cartId?: string;\n chainId?: number;\n storeId?: number;\n}) {\n let showBeam;\n let remoteSessionId;\n\n if (window.statsig) {\n // If the site is using Statsig, but not for Beam, we need to ignore it\n try {\n const statsig = window.statsig as any;\n const statsigLayerProperty = statsig?.getLayer(\"beam_trial_layer\")?.get(\"show_beam\");\n if (typeof statsigLayerProperty === \"boolean\") {\n showBeam = statsig.getLayer(\"beam_trial_layer\").get(\"show_beam\", false /* default to hide */) as boolean;\n remoteSessionId = statsig.getStableID();\n }\n } catch (err) {\n // logger.error(err)\n }\n }\n\n const allBeamAttributes = omitBy(\n {\n nonprofit_id: selectedNonprofitId,\n selection_id: selectionId,\n beam_cart_id: beamCartId,\n shopify_cart_id: cartId,\n chain_id: chainId,\n store_id: storeId,\n show_beam: showBeam,\n remote_session_id: remoteSessionId,\n },\n isUndefined\n ) as ShopifyCartBeamAttribute;\n\n // For the nonprofitId, if we specifically get a null value here,\n // we want to remove it from the cart attributes, not just write \"null\"\n if (selectedNonprofitId === null) {\n allBeamAttributes.nonprofit_id = undefined;\n }\n\n const beamCartAttrs = {\n beam: JSON.stringify(allBeamAttributes),\n };\n\n try {\n await window.fetch(SHOPIFY_BASE_URL + \"cart/update.js\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ attributes: beamCartAttrs }),\n });\n } catch (err) {\n logger.error(err); // don't throw, allow later calls to continue\n }\n});\n\ndeclare global {\n interface Window {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n statsig?: any; // attached by Statsig CDN script\n }\n}\nexport {\n trackCart,\n getCurrentCart,\n addBeamAttributesToCart,\n appendStatsigToShopifyCartAttributes,\n appendToShopifyCartBeamAttribute,\n registerCartIntegration,\n appendBeamAttributesToCart,\n getShopifyCart,\n getBeamAttributesForCart,\n};\n","import \"../../components/post-purchase\";\nimport { postTransaction } from \"../../api-sdk/v3/routes\";\nimport { DEFAULT_BASE_URL } from \"../../api-sdk/constants\";\nimport { LANGUAGES, TUrl } from \"../../api-sdk/types\";\nimport { waitForElement } from \"../../utils/wait-for-element\";\nimport { BeamError } from \"../../utils/beam-errors\";\nimport { getCookieValue } from \"../../utils/cookies\";\nimport { createScopedLocalStorage } from \"../../utils/local-storage\";\nimport { TCart } from \"../../shared/cart-contents\";\n\n// Shopify admin page: admin/settings/checkout\n\nexport type TBeamOrderPageParams = Parameters<typeof postTransaction>[0][\"requestBody\"] & {\n // Either storeId or postalCode + countryCode must be provided\n storeId?: number;\n postalCode?: string;\n countryCode?: string;\n orderId: string;\n email: string;\n cartTotal: number;\n cart: TCart;\n discountCodes: string[];\n promoCodes: string[];\n htmlPromoCodes: string;\n currencyCode: string;\n parentSelector: string; // CSS Selector for parent of widget to be inserted into DOM\n apiKey: string;\n baseUrl: TUrl;\n domain?: string; // Base domain for setting cookies\n lang: LANGUAGES;\n debug: boolean;\n};\n\nexport async function showBeamOrderPageWidgets({\n parentSelector = \".step__sections\",\n apiKey,\n baseUrl = DEFAULT_BASE_URL,\n storeId,\n postalCode,\n discountCodes,\n countryCode,\n orderId,\n email,\n cartTotal,\n cart,\n promoCodes,\n htmlPromoCodes,\n currencyCode = \"USD\",\n domain,\n lang = \"en\",\n debug = false,\n}: TBeamOrderPageParams) {\n const parentElement = document.querySelector(parentSelector) || (await waitForElement(parentSelector));\n if (!parentElement) {\n throw new BeamError(\n `Timed out waiting for selector '${parentSelector}'. Could not render Beam post-purchase widget.`\n );\n }\n\n // If checkout and order page are on different subdomains, we can't access localStorage\n // We can make postTransaction work by copying the cart cookie to the expected localStorage key on the current domain\n const cartId = await getCookieValue(\"cart\"); // Shopify-only cart identifier\n if (cartId) {\n const beamLocalStorage = createScopedLocalStorage({ apiKey });\n const existingValue = beamLocalStorage.getItemJson(\"cart\") || {};\n beamLocalStorage.setItemJson(\"cart\", { ...existingValue, cartId });\n }\n\n // Note: assign properties one by one instead of bulk Object.assign to type check assignments\n const widget = document.createElement(\"beam-post-purchase\");\n widget.apiKey = apiKey;\n widget.baseUrl = baseUrl;\n widget.storeId = storeId;\n widget.postalCode = postalCode;\n widget.countryCode = countryCode;\n widget.orderId = String(orderId);\n widget.email = email;\n widget.cartTotal = cartTotal;\n widget.cart = cart;\n widget.promoCodes = promoCodes;\n widget.htmlPromoCodes = htmlPromoCodes;\n widget.discountCodes = discountCodes;\n widget.currencyCode = currencyCode;\n widget.domain = domain;\n widget.lang = lang;\n widget.debug = debug;\n\n // Insert widget into DOM\n parentElement.appendChild(widget);\n}\n"],"names":["SHOPIFY_BASE_URL","isBeamCartIntegrationRegistered","SHOPIFY_CART_COOKIE_NAME","registerCartIntegration","config","autoUpdateShopifyCartAttributes","initNetworkListeners","BeamNetworkCallEvent","_event","event","cartChangePaths","requestUrlStr","url","currentCart","getCurrentCart","updateCart","lastNonprofitId","lastSelectionId","BeamNonprofitSelectEvent","logger","source","selectedNonprofitId","selectionId","WIDGET_NAMES","beamCartData","getBeamAttributesForCart","appendBeamAttributesToCart","BeamNonprofitSelectionRemovedEvent","newNonprofitId","BeamCartCreatedEvent","BeamCartChangeEvent","appendToShopifyCartBeamAttribute","showBeam","remoteSessionId","statsig","cartId","getExternalCartId","beamCartId","getBeamCartId","BEAM_CART_COOKIE_NAME","chainId","storeId","appendStatsigToShopifyCartAttributes","token","total_price","item_count","currency","items","cart_level_discount_applications","getShopifyCart","changed","cachedCart","createScopedLocalStorage","cart","sku","final_line_price","product_id","line_level_discount_allocations","remoteProductIdentifier","localAmount","discounts","discount_application","title","isEqual","trackCart","res","memoizeLast","attributes","existingBeamCartAttrString","existingBeamCartAttr","err","newBeamAttrs","omitBy","isUndefined","appendedBeamAttributes","beamCartAttrs","addBeamAttributesToCart","allBeamAttributes","showBeamOrderPageWidgets","parentSelector","apiKey","baseUrl","DEFAULT_BASE_URL","postalCode","discountCodes","countryCode","orderId","email","cartTotal","promoCodes","htmlPromoCodes","currencyCode","domain","lang","debug","parentElement","waitForElement","BeamError","getCookieValue","beamLocalStorage","existingValue","widget"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- import{L as u}from"./beam-errors-Ci0d3926.esm.js";import{setCookieValue as f,getCookieValue as c}from"../utils/cookies.js";import{createScopedLocalStorage as p}from"../utils/local-storage.js";import{logger as d}from"../utils/logger.js";var i=(o=>(o.Manual="manual",o.Url="url",o))(i||{});const m="promos",l="beam_promo_codes",S=100,h="utm_",A="discount_code",O=()=>{const o=c(l);if(o)try{return JSON.parse(o)}catch(e){d.error("Failed to parse beam_promo_codes cookie:",e);return}},_=({validatedPromoCodes:o,domain:e})=>{const r={validatedPromoCodes:o},a=Date.now()+1e3*60*60*24*90;f({name:l,value:JSON.stringify(r),path:"/",domain:e,expires:a})},C=({apiKey:o})=>o?p({apiKey:o}).getItemJson(m)??{unvalidatedPromoCodes:[],validatedPromoCodes:[]}:(d.error(new u("API key is required to get promo codes")),null),P=({apiKey:o,promoCodes:e})=>{if(!o){d.error(new u("API key is required to set promo codes"));return}const r=p({apiKey:o}),a={unvalidatedPromoCodes:e?.unvalidatedPromoCodes||[],validatedPromoCodes:e?.validatedPromoCodes||[]};r.setItemJson(m,a)},v=({newPromos:o,apiKey:e})=>{const r=C({apiKey:e})??{unvalidatedPromoCodes:[],validatedPromoCodes:[]},a=(o?.unvalidatedPromoCodes||[]).filter(s=>!r.unvalidatedPromoCodes.some(n=>JSON.stringify(n)===JSON.stringify(s))),t={unvalidatedPromoCodes:[...r.unvalidatedPromoCodes,...a],validatedPromoCodes:[...r.validatedPromoCodes,...o?.validatedPromoCodes||[]]};return(t.unvalidatedPromoCodes.length>0||t.validatedPromoCodes.length>0)&&P({apiKey:e,promoCodes:t}),{...t}},g=o=>o.reduce((e,r)=>{const a=e||[];return r.url?a.push({type:i.Url,attributes:{url:r.url}}):r.value?a.push({type:i.Manual,attributes:{value:r.value}}):d.error("Invalid PromoAttribute - must contain either 'url' or 'value'",{attr:r}),a},[]),b=(o,e)=>{const r=g(o);return v({newPromos:{unvalidatedPromoCodes:r},apiKey:e})},w=o=>{if(!o?.content)return[];const e=o.content.discounts?.filter(t=>t.applicable)?.map(t=>t.code)||[],r=o.content.items?.flatMap(t=>t.discounts?.filter(s=>s.applicable)?.map(s=>s.code)||[])||[],a=[...e,...r];return[...new Set(a)]},K=()=>c(A)??null,k=o=>{if(!o)return[];try{const e=JSON.parse(o);return Array.isArray(e)&&e.every(r=>typeof r=="string")?e:[]}catch(e){return d.error("Failed to parse JSON:",e),[]}},E=()=>{try{const o=new URL(window.location.href);if(!o.search)return;const e=new URL(o.origin+o.pathname);let r=!1;o.searchParams.forEach((t,s)=>{const n=s.startsWith(h),y=t.length<=S;n&&y&&(e.searchParams.append(s,t),r=!0)});const a=e.toString();return r?{url:a}:void 0}catch{return}},J=(o,e)=>{const r=a=>(Array.isArray(a)?a:[]).map(t=>t.type==="manual"?t.attributes?.value:t.type==="url"?t.attributes?.url:"").filter(Boolean).sort().join(",");return r(o?.unvalidatedPromoCodes)===r(e?.unvalidatedPromoCodes)},L=o=>(!o.unvalidatedPromoCodes||o.unvalidatedPromoCodes.length===0)&&(!o.validatedPromoCodes||o.validatedPromoCodes.length===0);export{m as P,E as a,K as b,O as c,l as d,k as e,b as f,C as g,w as h,L as i,v as j,P as k,g as m,J as p,_ as s};
2
- //# sourceMappingURL=promoManager-B9cTR1R3.esm.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"promoManager-B9cTR1R3.esm.js","sources":["../../src/shared/promo-types.ts","../../src/utils/promoManager.ts"],"sourcesContent":["import { paths } from \"../api-sdk/v3/openapi-spec\";\n\nexport type TPromoCodeRequest =\n paths[\"/productDetailsPage\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"][\"promos\"];\nexport type TUnvalidatedPromoRequest = NonNullable<TPromoCodeRequest>[\"unvalidatedPromoCodes\"];\n\nexport type TPromoCodeAttribute = { value: string; url?: never } | { url: string; value?: never };\n\nexport type TPromoCodeResponse =\n paths[\"/productDetailsPage\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"][\"promos\"];\nexport type TValidatedPromoResponse = NonNullable<TPromoCodeResponse>[\"validatedPromoCodes\"];\n\nexport enum PromoCodeSource {\n Manual = \"manual\",\n Url = \"url\",\n}\n\ntype TManualPromoCode = {\n type: \"manual\";\n attributes: { value: string };\n};\n\ntype TUrlPromoCode = {\n type: \"url\";\n attributes: { url: string };\n};\n\nexport type TUnvalidatedPromoCode = TManualPromoCode | TUrlPromoCode;\n\nexport const PROMO_LOCAL_STORAGE_KEY = \"promos\";\nexport const PROMO_CODES_COOKIE_NAME = \"beam_promo_codes\";\n","import { Discount, TBeamCartLocalStorage } from \"../shared/cart-contents\";\nimport {\n TPromoCodeAttribute,\n PromoCodeSource,\n TPromoCodeRequest,\n TPromoCodeResponse,\n TValidatedPromoResponse,\n TUnvalidatedPromoRequest,\n PROMO_LOCAL_STORAGE_KEY,\n PROMO_CODES_COOKIE_NAME,\n TUnvalidatedPromoCode,\n} from \"../shared/promo-types\";\nimport { LocalStorageError } from \"./beam-errors\";\nimport { getCookieValue, setCookieValue } from \"./cookies\";\nimport { createScopedLocalStorage } from \"./local-storage\";\nimport { logger } from \"./logger\";\n\nconst URL_QUERY_PARAM_CHAR_LIMIT = 100;\nconst ALLOWED_URL_PREFIX = \"utm_\";\n// Standard name for Shopify's discount tracking cookie\nconst DISCOUNT_CODE_COOKIE_NAME = \"discount_code\";\n// < --------- Cookie ------- >\n\n/**\n * Retrieves all validated promo codes stored in the \"beam_promo_codes\" cookie and parses it\n *\n * @returns {TPromoCodeResponse | undefined} An array of `ValidatedPromoCode` objects if found and parsed successfully, otherwise `undefined`\n */\nexport const getAllPromoCodesFromCookie = (): TPromoCodeResponse | undefined => {\n const promoCodesString = getCookieValue(PROMO_CODES_COOKIE_NAME);\n\n if (!promoCodesString) return undefined;\n\n try {\n const promoCodes: TPromoCodeResponse = JSON.parse(promoCodesString);\n return promoCodes;\n } catch (error) {\n logger.error(\"Failed to parse beam_promo_codes cookie:\", error);\n return undefined;\n }\n};\n\n/**\n * Stores the validated promo codes in the \"beam_promo_codes\" cookie, replaces and does not merge\n *\n * @param {TValidatedPromoResponse} validatedPromoCodes\n * @param {string} domain\n */\nexport const setPromoCodeInCookie = ({\n validatedPromoCodes,\n domain,\n}: {\n validatedPromoCodes: TValidatedPromoResponse;\n domain?: string;\n}) => {\n const promoCodeData = {\n validatedPromoCodes: validatedPromoCodes,\n };\n const threeMonthsFromNow = Date.now() + 1000 * 60 * 60 * 24 * 90;\n\n setCookieValue({\n name: PROMO_CODES_COOKIE_NAME,\n value: JSON.stringify(promoCodeData),\n path: \"/\",\n domain,\n // If we don't set an expiration, the cookie will be cleared when the tab is closed\n expires: threeMonthsFromNow,\n });\n};\n\n// < --------- Local Storage ------- >\n/**\n * Retrieves promo codes from localStorage, scoped by API key\n * @param {string} apiKey API key used for storage scoping\n * @returns {TPromoCodeRequest | null} - Returns stored promo codes object containing both\n * validated and unvalidated codes\n * - If no codes exist, returns a fresh object with empty arrays\n *\n */\nexport const getPromoCodesLocalStorage = ({ apiKey }: { apiKey: string }): TPromoCodeRequest | null => {\n if (!apiKey) {\n logger.error(new LocalStorageError(\"API key is required to get promo codes\"));\n return null;\n }\n\n const storage = createScopedLocalStorage({ apiKey });\n const allPromos = storage.getItemJson<TPromoCodeRequest>(PROMO_LOCAL_STORAGE_KEY) ?? {\n unvalidatedPromoCodes: [],\n validatedPromoCodes: [],\n };\n\n return allPromos;\n};\n\n/**\n * Sets promo codes in localStorage\n * @param {TPromoCodeRequest} promoCodes New promo codes to add\n * @param {string} apiKey API key for storage scoping\n */\nexport const setPromoCodesInLocalStorage = ({\n apiKey,\n promoCodes,\n}: {\n apiKey?: string;\n promoCodes: Partial<TPromoCodeRequest>;\n}): void => {\n if (!apiKey) {\n logger.error(new LocalStorageError(\"API key is required to set promo codes\"));\n return;\n }\n const storage = createScopedLocalStorage({ apiKey });\n const completePromoCodes: TPromoCodeRequest = {\n unvalidatedPromoCodes: promoCodes?.unvalidatedPromoCodes || [],\n validatedPromoCodes: promoCodes?.validatedPromoCodes || [],\n };\n storage.setItemJson(PROMO_LOCAL_STORAGE_KEY, completePromoCodes);\n};\n\n/**\n * Merges new promo codes with existing ones and returns the combined result\n * @param {Partial<TPromoCodeRequest>} newPromos New promo codes to add\n * @param {string} apiKey API key for storage scoping\n * @returns {TPromoCodeRequest} An object containing both validated and unvalidated promo codes\n * @example\n * const result = mergePromoCodes({\n * apiKey: 'beam_123',\n * newPromos: {\n * unvalidatedPromoCodes: [\n * { type: 'manual', attributes: { value: 'WINTER20' } },\n * { type: 'url', attributes: { url: 'www.example.com/?promo=HOLIDAY25' } }\n * ]\n * }\n * });\n */\nexport const mergeStoreAndReturnPromos = ({\n newPromos,\n apiKey,\n}: {\n newPromos: Partial<TPromoCodeRequest>;\n apiKey: string;\n}): TPromoCodeRequest => {\n const existing = getPromoCodesLocalStorage({ apiKey }) ?? {\n unvalidatedPromoCodes: [],\n validatedPromoCodes: [],\n };\n\n const uniqueNewUnvalidatedPromos = (newPromos?.unvalidatedPromoCodes || []).filter((newPromo) => {\n const isDuplicate = existing.unvalidatedPromoCodes.some((existingPromo) => {\n return JSON.stringify(existingPromo) === JSON.stringify(newPromo);\n });\n return !isDuplicate;\n });\n\n const mergedCodes: TPromoCodeRequest = {\n unvalidatedPromoCodes: [...existing.unvalidatedPromoCodes, ...uniqueNewUnvalidatedPromos],\n validatedPromoCodes: [...existing.validatedPromoCodes, ...(newPromos?.validatedPromoCodes || [])],\n };\n\n const shouldStore = mergedCodes.unvalidatedPromoCodes.length > 0 || mergedCodes.validatedPromoCodes.length > 0;\n\n if (shouldStore) {\n setPromoCodesInLocalStorage({ apiKey, promoCodes: mergedCodes });\n }\n return {\n ...mergedCodes,\n };\n};\n\n/**\n * Formats unvalidated promo codes by determining their source and attributes\n * The function will assign `QueryParam` as the source if a `url` exists,\n * otherwise, it will assign `Manual` as the source\n *\n * @param {TPromoCodeAttribute[]} promoAttributes An array of promo attributes to be formatted\n * @returns {TUnvalidatedPromoRequest} - An array of UnvalidatedPromoCode objects,\n * each with a source and attributes object\n */\nexport const mapToUnvalidatedPromoCodes = (promoAttributes: TPromoCodeAttribute[]): TUnvalidatedPromoRequest => {\n return promoAttributes.reduce<TUnvalidatedPromoRequest>((acc, attr) => {\n const result: TUnvalidatedPromoRequest = acc || [];\n if (attr.url) {\n result.push({\n type: PromoCodeSource.Url,\n attributes: { url: attr.url },\n });\n } else if (attr.value) {\n result.push({\n type: PromoCodeSource.Manual,\n attributes: { value: attr.value },\n });\n } else {\n logger.error(\"Invalid PromoAttribute - must contain either 'url' or 'value'\", { attr });\n }\n return result;\n }, []);\n};\n\n/**\n * @param {TPromoCodeAttribute[]} promoAttributes An array of promo attributes to be formatted\n * @param {string} apiKey API key for storage scoping\n * @returns {TPromoCodeRequest} An object containing both validated and unvalidated promo codes\n */\nexport const formatStoreAndReturnPromoCodes = (\n promoAttributes: TPromoCodeAttribute[],\n apiKey: string\n): TPromoCodeRequest => {\n const unvalidatedPromoCodes = mapToUnvalidatedPromoCodes(promoAttributes);\n return mergeStoreAndReturnPromos({ newPromos: { unvalidatedPromoCodes }, apiKey });\n};\n\n/**\n * Extracts applicable promo codes from the cart object\n * This function retrieves discounts stored in the cart's `content.discounts` array,\n * filters out only the applicable promo codes, and returns them as an array of strings\n *\n * @param {TBeamCartLocalStorage} cart The cart object retrieved from local storage\n * @returns {string[]} An array of applicable promo codes\n */\nexport const getPromoCodesFromCart = (cart: TBeamCartLocalStorage): string[] => {\n if (!cart?.content) return [];\n\n const cartLevelCodes = cart.content.discounts?.filter((d) => d.applicable)?.map((d) => d.code) || [];\n\n const itemLevelCodes =\n cart.content.items?.flatMap(\n (item) => item.discounts?.filter((d: Discount) => d.applicable)?.map((d: Discount) => d.code) || []\n ) || [];\n\n const allCodes = [...cartLevelCodes, ...itemLevelCodes];\n\n return [...new Set(allCodes)];\n};\n\n/**\n * Gets promo code exclusively from Shopify discount cookie\n * @returns {string | null} Single discount code or null if not found\n */\nexport const getPromoCodeFromShopifyCookie = (): string | null => {\n return getCookieValue(DISCOUNT_CODE_COOKIE_NAME) ?? null;\n};\n\n/**\n * Safely parses a JSON string into an array of strings\n * If parsing fails or the input is not a valid JSON array, it returns an empty array\n *\n * @param {string | undefined | null} jsonString The JSON string to parse\n * @returns {string[]} The parsed array of strings or an empty array if parsing fails\n */\nexport const parseJsonStringArray = (jsonString: string | undefined | null): string[] => {\n if (!jsonString) return [];\n try {\n const parsed = JSON.parse(jsonString);\n if (Array.isArray(parsed) && parsed.every((item) => typeof item === \"string\")) {\n return parsed;\n }\n return [];\n } catch (error) {\n logger.error(\"Failed to parse JSON:\", error);\n return [];\n }\n};\n\n/**\n * Retrieves and sanitizes the current URL for storage, preserving only safe query parameters\n *\n * @returns {TPromoCodeAttribute} Returns an object with only the `url` property set\n */\nexport const getSanitizedUrlForStorage = (): TPromoCodeAttribute | undefined => {\n try {\n const url = new URL(window.location.href);\n\n if (!url.search) return undefined;\n\n // Create NEW URL instead of modifying existing one\n const cleanUrl = new URL(url.origin + url.pathname);\n let hasValidParams = false;\n\n // Process all parameters\n url.searchParams.forEach((value, key) => {\n const isAllowed = key.startsWith(ALLOWED_URL_PREFIX);\n const isValidLength = value.length <= URL_QUERY_PARAM_CHAR_LIMIT;\n\n if (isAllowed && isValidLength) {\n cleanUrl.searchParams.append(key, value);\n hasValidParams = true;\n }\n });\n\n const finalUrl = cleanUrl.toString();\n return hasValidParams ? { url: finalUrl } : undefined;\n } catch (error) {\n return undefined;\n }\n};\n\nexport const promoCodesAreEqual = (a: TPromoCodeRequest, b: TPromoCodeRequest): boolean => {\n const extract = (codes: unknown): string => {\n const validCodes = (Array.isArray(codes) ? codes : []) as TUnvalidatedPromoCode[];\n\n const flattened = validCodes\n .map((c) => {\n if (c.type === \"manual\") {\n return c.attributes?.value;\n }\n if (c.type === \"url\") {\n return c.attributes?.url;\n }\n return \"\";\n })\n .filter(Boolean)\n .sort()\n .join(\",\");\n return flattened;\n };\n\n return extract(a?.unvalidatedPromoCodes) === extract(b?.unvalidatedPromoCodes);\n};\n\nexport const isEmptyPromoData = (promos: {\n unvalidatedPromoCodes?: unknown[];\n validatedPromoCodes?: unknown[];\n}): boolean => {\n return (\n (!promos.unvalidatedPromoCodes || promos.unvalidatedPromoCodes.length === 0) &&\n (!promos.validatedPromoCodes || promos.validatedPromoCodes.length === 0)\n );\n};\n"],"names":["PromoCodeSource","PROMO_LOCAL_STORAGE_KEY","PROMO_CODES_COOKIE_NAME","URL_QUERY_PARAM_CHAR_LIMIT","ALLOWED_URL_PREFIX","DISCOUNT_CODE_COOKIE_NAME","getAllPromoCodesFromCookie","promoCodesString","getCookieValue","error","logger","setPromoCodeInCookie","validatedPromoCodes","domain","promoCodeData","threeMonthsFromNow","setCookieValue","getPromoCodesLocalStorage","apiKey","createScopedLocalStorage","LocalStorageError","setPromoCodesInLocalStorage","promoCodes","storage","completePromoCodes","mergeStoreAndReturnPromos","newPromos","existing","uniqueNewUnvalidatedPromos","newPromo","existingPromo","mergedCodes","mapToUnvalidatedPromoCodes","promoAttributes","acc","attr","result","formatStoreAndReturnPromoCodes","unvalidatedPromoCodes","getPromoCodesFromCart","cart","cartLevelCodes","d","itemLevelCodes","item","allCodes","getPromoCodeFromShopifyCookie","parseJsonStringArray","jsonString","parsed","getSanitizedUrlForStorage","url","cleanUrl","hasValidParams","value","key","isAllowed","isValidLength","finalUrl","promoCodesAreEqual","a","b","extract","codes","c","isEmptyPromoData","promos"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- import{L as u}from"./beam-errors-Ci0d3926.esm.js";import{setCookieValue as f,getCookieValue as c}from"../utils/cookies.esm.js";import{createScopedLocalStorage as p}from"../utils/local-storage.esm.js";import{logger as d}from"../utils/logger.esm.js";var i=(o=>(o.Manual="manual",o.Url="url",o))(i||{});const m="promos",l="beam_promo_codes",S=100,h="utm_",A="discount_code",O=()=>{const o=c(l);if(o)try{return JSON.parse(o)}catch(e){d.error("Failed to parse beam_promo_codes cookie:",e);return}},_=({validatedPromoCodes:o,domain:e})=>{const r={validatedPromoCodes:o},a=Date.now()+1e3*60*60*24*90;f({name:l,value:JSON.stringify(r),path:"/",domain:e,expires:a})},C=({apiKey:o})=>o?p({apiKey:o}).getItemJson(m)??{unvalidatedPromoCodes:[],validatedPromoCodes:[]}:(d.error(new u("API key is required to get promo codes")),null),P=({apiKey:o,promoCodes:e})=>{if(!o){d.error(new u("API key is required to set promo codes"));return}const r=p({apiKey:o}),a={unvalidatedPromoCodes:e?.unvalidatedPromoCodes||[],validatedPromoCodes:e?.validatedPromoCodes||[]};r.setItemJson(m,a)},v=({newPromos:o,apiKey:e})=>{const r=C({apiKey:e})??{unvalidatedPromoCodes:[],validatedPromoCodes:[]},a=(o?.unvalidatedPromoCodes||[]).filter(s=>!r.unvalidatedPromoCodes.some(n=>JSON.stringify(n)===JSON.stringify(s))),t={unvalidatedPromoCodes:[...r.unvalidatedPromoCodes,...a],validatedPromoCodes:[...r.validatedPromoCodes,...o?.validatedPromoCodes||[]]};return(t.unvalidatedPromoCodes.length>0||t.validatedPromoCodes.length>0)&&P({apiKey:e,promoCodes:t}),{...t}},g=o=>o.reduce((e,r)=>{const a=e||[];return r.url?a.push({type:i.Url,attributes:{url:r.url}}):r.value?a.push({type:i.Manual,attributes:{value:r.value}}):d.error("Invalid PromoAttribute - must contain either 'url' or 'value'",{attr:r}),a},[]),b=(o,e)=>{const r=g(o);return v({newPromos:{unvalidatedPromoCodes:r},apiKey:e})},w=o=>{if(!o?.content)return[];const e=o.content.discounts?.filter(t=>t.applicable)?.map(t=>t.code)||[],r=o.content.items?.flatMap(t=>t.discounts?.filter(s=>s.applicable)?.map(s=>s.code)||[])||[],a=[...e,...r];return[...new Set(a)]},K=()=>c(A)??null,k=o=>{if(!o)return[];try{const e=JSON.parse(o);return Array.isArray(e)&&e.every(r=>typeof r=="string")?e:[]}catch(e){return d.error("Failed to parse JSON:",e),[]}},E=()=>{try{const o=new URL(window.location.href);if(!o.search)return;const e=new URL(o.origin+o.pathname);let r=!1;o.searchParams.forEach((t,s)=>{const n=s.startsWith(h),y=t.length<=S;n&&y&&(e.searchParams.append(s,t),r=!0)});const a=e.toString();return r?{url:a}:void 0}catch{return}},J=(o,e)=>{const r=a=>(Array.isArray(a)?a:[]).map(t=>t.type==="manual"?t.attributes?.value:t.type==="url"?t.attributes?.url:"").filter(Boolean).sort().join(",");return r(o?.unvalidatedPromoCodes)===r(e?.unvalidatedPromoCodes)},L=o=>(!o.unvalidatedPromoCodes||o.unvalidatedPromoCodes.length===0)&&(!o.validatedPromoCodes||o.validatedPromoCodes.length===0);export{m as P,E as a,K as b,O as c,l as d,k as e,b as f,C as g,w as h,L as i,v as j,P as k,g as m,J as p,_ as s};
2
- //# sourceMappingURL=promoManager-fl54hq13.esm.js.map