@beamimpact/web-sdk 1.57.2 → 1.57.4

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 (162) hide show
  1. package/README.md +66 -42
  2. package/dist/chunks/{_share-dialog-dependencies-DFXGKz-z.esm.js → _share-dialog-dependencies-BvaXft1r.esm.js} +2 -2
  3. package/dist/chunks/{_share-dialog-dependencies-DFXGKz-z.esm.js.map → _share-dialog-dependencies-BvaXft1r.esm.js.map} +1 -1
  4. package/dist/chunks/{cart-hrlPQg3L.esm.d.ts → cart-DCezceUX.esm.d.ts} +2 -2
  5. package/dist/chunks/index-726Vfz5u.esm.js +32 -0
  6. package/dist/chunks/index-726Vfz5u.esm.js.map +1 -0
  7. package/dist/chunks/{index-C20vHMzS.esm.js → index-B7OkmoYI.esm.js} +2 -2
  8. package/dist/chunks/{index-C20vHMzS.esm.js.map → index-B7OkmoYI.esm.js.map} +1 -1
  9. package/dist/chunks/{index-xsFjZMYP.esm.js → index-BOHlIBDq.esm.js} +6 -6
  10. package/dist/chunks/index-BOHlIBDq.esm.js.map +1 -0
  11. package/dist/chunks/index-Bc_hD09J.esm.js +32 -0
  12. package/dist/chunks/index-Bc_hD09J.esm.js.map +1 -0
  13. package/dist/chunks/{index-BXEbjPDK.esm.d.ts → index-Bi9LFICg.esm.d.ts} +1 -1
  14. package/dist/chunks/{index-D9W31jYp.esm.js → index-Bt4Ob1Fi.esm.js} +2 -2
  15. package/dist/chunks/{index-D9W31jYp.esm.js.map → index-Bt4Ob1Fi.esm.js.map} +1 -1
  16. package/dist/chunks/{index-BuLbvDL8.esm.d.ts → index-C6gns2ul.esm.d.ts} +1 -1
  17. package/dist/chunks/{index-Dc4HgxdT.esm.js → index-CVHrQ1WC.esm.js} +2 -2
  18. package/dist/chunks/{index-Dc4HgxdT.esm.js.map → index-CVHrQ1WC.esm.js.map} +1 -1
  19. package/dist/chunks/{index-D3OYVBqK.esm.d.ts → index-DQ89VjpD.esm.d.ts} +1 -1
  20. package/dist/chunks/{index-DXFRJEgw.esm.js → index-Di1IwSgk.esm.js} +6 -6
  21. package/dist/chunks/index-Di1IwSgk.esm.js.map +1 -0
  22. package/dist/chunks/{index-BZZiSTrL.esm.d.ts → index-h_-rDiMR.esm.d.ts} +1 -1
  23. package/dist/chunks/{promo-pill-label-rrCE5zhs.esm.js → promo-pill-label-D-VXaB27.esm.js} +2 -2
  24. package/dist/chunks/{promo-pill-label-rrCE5zhs.esm.js.map → promo-pill-label-D-VXaB27.esm.js.map} +1 -1
  25. package/dist/chunks/{share-button-DctAhc8i.esm.js → share-button-DFuEWa2h.esm.js} +2 -2
  26. package/dist/chunks/{share-button-DctAhc8i.esm.js.map → share-button-DFuEWa2h.esm.js.map} +1 -1
  27. package/dist/chunks/{share-button-Dob19-Da.esm.js → share-button-o8IBYAxH.esm.js} +2 -2
  28. package/dist/chunks/{share-button-Dob19-Da.esm.js.map → share-button-o8IBYAxH.esm.js.map} +1 -1
  29. package/dist/chunks/{update-cart-BclA4Tsd.esm.d.ts → update-cart-B5Tr9N3V.esm.d.ts} +1 -1
  30. package/dist/chunks/{utils-SWm8ZEfg.esm.d.ts → utils-BPcZ5h8J.esm.d.ts} +66 -0
  31. package/dist/components/beam-partner-logos.d.ts +1 -1
  32. package/dist/components/community-impact.d.ts +1 -1
  33. package/dist/components/community-impact.esm.js +13 -13
  34. package/dist/components/community-impact.esm.js.map +1 -1
  35. package/dist/components/community-impact.js +13 -13
  36. package/dist/components/community-impact.js.map +1 -1
  37. package/dist/components/cumulative-impact.d.ts +1 -1
  38. package/dist/components/cumulative-impact.esm.js +1 -1
  39. package/dist/components/cumulative-impact.js +1 -1
  40. package/dist/components/impact-overview.d.ts +1 -1
  41. package/dist/components/impact-overview.esm.js +1 -1
  42. package/dist/components/impact-overview.js +1 -1
  43. package/dist/components/index.d.ts +1 -1
  44. package/dist/components/index.esm.js +1 -1
  45. package/dist/components/index.js +1 -1
  46. package/dist/components/post-purchase.d.ts +2 -1
  47. package/dist/components/post-purchase.esm.js +1 -1
  48. package/dist/components/post-purchase.js +1 -1
  49. package/dist/components/product-details-page.d.ts +1 -1
  50. package/dist/components/product-details-page.esm.js +2 -2
  51. package/dist/components/product-details-page.esm.js.map +1 -1
  52. package/dist/components/product-details-page.js +2 -2
  53. package/dist/components/product-details-page.js.map +1 -1
  54. package/dist/components/redeem-transaction.d.ts +1 -1
  55. package/dist/components/redeem-transaction.esm.js +1 -1
  56. package/dist/components/redeem-transaction.js +1 -1
  57. package/dist/components/select-nonprofit.d.ts +1 -1
  58. package/dist/components/select-nonprofit.esm.js +2 -2
  59. package/dist/components/select-nonprofit.esm.js.map +1 -1
  60. package/dist/components/select-nonprofit.js +2 -2
  61. package/dist/components/select-nonprofit.js.map +1 -1
  62. package/dist/components/select-subscription-nonprofit.d.ts +1 -1
  63. package/dist/components/select-subscription-nonprofit.esm.js +1 -1
  64. package/dist/components/select-subscription-nonprofit.js +1 -1
  65. package/dist/components/shopify.d.ts +4 -4
  66. package/dist/components/shopify.esm.js +1 -1
  67. package/dist/components/shopify.js +1 -1
  68. package/dist/components/social-share.d.ts +1 -1
  69. package/dist/components/social-share.esm.js +1 -1
  70. package/dist/components/social-share.js +1 -1
  71. package/dist/components/subscriber-select-nonprofit.d.ts +1 -1
  72. package/dist/components/subscriber-select-nonprofit.esm.js +1 -1
  73. package/dist/components/subscriber-select-nonprofit.js +1 -1
  74. package/dist/components/subscription-impact.d.ts +1 -1
  75. package/dist/components/subscription-impact.esm.js +1 -1
  76. package/dist/components/subscription-impact.js +1 -1
  77. package/dist/components/subscription-management.d.ts +1 -1
  78. package/dist/components/subscription-management.esm.js +1 -1
  79. package/dist/components/subscription-management.js +1 -1
  80. package/dist/index.d.ts +7 -7
  81. package/dist/index.esm.js +1 -1
  82. package/dist/index.js +1 -1
  83. package/dist/integrations/beam.d.ts +1 -1
  84. package/dist/integrations/beam.esm.js +1 -1
  85. package/dist/integrations/beam.js +1 -1
  86. package/dist/integrations/cart.d.ts +2 -2
  87. package/dist/integrations/cart.esm.js +1 -1
  88. package/dist/integrations/cart.js +1 -1
  89. package/dist/integrations/logs.d.ts +2 -2
  90. package/dist/integrations/logs.esm.js +1 -1
  91. package/dist/integrations/logs.js +1 -1
  92. package/dist/integrations/promoManager.d.ts +1 -1
  93. package/dist/integrations/shopify-order.d.ts +1 -1
  94. package/dist/integrations/shopify-order.esm.js +1 -1
  95. package/dist/integrations/shopify-order.js +1 -1
  96. package/dist/integrations/shopify.d.ts +3 -3
  97. package/dist/integrations/shopify.esm.js +1 -1
  98. package/dist/integrations/shopify.js +1 -1
  99. package/dist/integrations/statsig.d.ts +1 -1
  100. package/dist/integrations/statsig.esm.js +1 -1
  101. package/dist/integrations/statsig.js +1 -1
  102. package/dist/integrations/utils.d.ts +1 -1
  103. package/dist/react/beam-partner-logos.d.ts +1 -1
  104. package/dist/react/community-impact.d.ts +1 -1
  105. package/dist/react/community-impact.esm.js +1 -1
  106. package/dist/react/community-impact.js +1 -1
  107. package/dist/react/cumulative-impact.d.ts +1 -1
  108. package/dist/react/cumulative-impact.esm.js +1 -1
  109. package/dist/react/cumulative-impact.js +1 -1
  110. package/dist/react/impact-overview.d.ts +1 -1
  111. package/dist/react/impact-overview.esm.js +1 -1
  112. package/dist/react/impact-overview.js +1 -1
  113. package/dist/react/index.d.ts +1 -1
  114. package/dist/react/index.esm.js +1 -1
  115. package/dist/react/index.js +1 -1
  116. package/dist/react/post-purchase.d.ts +1 -1
  117. package/dist/react/post-purchase.esm.js +1 -1
  118. package/dist/react/post-purchase.js +1 -1
  119. package/dist/react/product-details-page.d.ts +1 -1
  120. package/dist/react/product-details-page.esm.js +1 -1
  121. package/dist/react/product-details-page.js +1 -1
  122. package/dist/react/redeem-transaction.d.ts +1 -1
  123. package/dist/react/redeem-transaction.esm.js +1 -1
  124. package/dist/react/redeem-transaction.js +1 -1
  125. package/dist/react/select-nonprofit.d.ts +1 -1
  126. package/dist/react/select-nonprofit.esm.js +1 -1
  127. package/dist/react/select-nonprofit.js +1 -1
  128. package/dist/react/select-subscription-nonprofit.d.ts +1 -1
  129. package/dist/react/select-subscription-nonprofit.esm.js +1 -1
  130. package/dist/react/select-subscription-nonprofit.js +1 -1
  131. package/dist/react/social-share.d.ts +1 -1
  132. package/dist/react/social-share.esm.js +1 -1
  133. package/dist/react/social-share.js +1 -1
  134. package/dist/react/subscriber-select-nonprofit.d.ts +1 -1
  135. package/dist/react/subscriber-select-nonprofit.esm.js +1 -1
  136. package/dist/react/subscriber-select-nonprofit.js +1 -1
  137. package/dist/react/subscription-impact.d.ts +1 -1
  138. package/dist/react/subscription-impact.esm.js +1 -1
  139. package/dist/react/subscription-impact.js +1 -1
  140. package/dist/react/subscription-management.d.ts +1 -1
  141. package/dist/react/subscription-management.esm.js +1 -1
  142. package/dist/react/subscription-management.js +1 -1
  143. package/dist/utils/beam-errors.d.ts +1 -1
  144. package/dist/utils/cart.d.ts +1 -1
  145. package/dist/utils/clear-beam-storage.d.ts +1 -1
  146. package/dist/utils/cookies.d.ts +1 -1
  147. package/dist/utils/events.d.ts +1 -1
  148. package/dist/utils/local-storage.d.ts +1 -1
  149. package/dist/utils/logger.d.ts +1 -1
  150. package/dist/utils/makeApiKeyHeader.d.ts +1 -1
  151. package/dist/utils/memoize-last.d.ts +1 -1
  152. package/dist/utils/network-listeners.d.ts +1 -1
  153. package/dist/utils/promoManager.d.ts +1 -1
  154. package/dist/utils/remote-session.d.ts +1 -1
  155. package/dist/utils/wait-for-element.d.ts +1 -1
  156. package/package.json +1 -1
  157. package/dist/chunks/index-BW8B2iVX.esm.js +0 -32
  158. package/dist/chunks/index-BW8B2iVX.esm.js.map +0 -1
  159. package/dist/chunks/index-CxHPGblW.esm.js +0 -32
  160. package/dist/chunks/index-CxHPGblW.esm.js.map +0 -1
  161. package/dist/chunks/index-DXFRJEgw.esm.js.map +0 -1
  162. package/dist/chunks/index-xsFjZMYP.esm.js.map +0 -1
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @beamimpact/web-sdk
2
2
 
3
- The Beam SDK enables brands to connect with their customers over shared values, not transactional discounts, to build stronger loyalty. Our integration achieves this by allowing customers to (a) choose a nonprofit where the brand will donate part of their purchase from a set of curated options and (b) track their cumulative impact with every order towards quantifiable goals.
3
+ The Beam SDK enables brands to connect with their users over shared values, not transactional discounts, to build stronger loyalty. Our integration achieves this by allowing users to (a) choose a nonprofit where the brand will donate part of their purchase from a set of curated options and (b) track their cumulative impact with every order towards quantifiable goals.
4
4
 
5
5
  Beam takes care of all the nonprofit management and compliance, impact tracking, UI styling and dynamic campaignization.
6
6
 
@@ -22,14 +22,15 @@ Beam takes care of all the nonprofit management and compliance, impact tracking,
22
22
  - [React](#react)
23
23
  - [Serverside-Rendering](#serverside-rendering)
24
24
  - [Debug Mode](#debug-mode)
25
- - [Widget Options](#widget-options)
25
+ - [Component Options](#component-options)
26
26
  - [beam-community impact](#beam-community-impact)
27
27
  - [beam-cumulative-impact](#beam-cumulative-impact)
28
28
  - [beam-select-nonprofit](#beam-select-nonprofit)
29
29
  - [Events](#events)
30
+ - [**Event Types**](#event-types)
30
31
  - [beam-post-purchase](#beam-post-purchase)
31
32
  - [Events](#events-1)
32
- - [Customizing inner widgets](#customizing-inner-widgets)
33
+ - [Customizing inner components](#customizing-inner-components)
33
34
  - [Integrations](#integrations)
34
35
  - [Cart Integration](#cart-integration)
35
36
  - [Shopify](#shopify)
@@ -43,10 +44,10 @@ Beam takes care of all the nonprofit management and compliance, impact tracking,
43
44
  <br />
44
45
 
45
46
  <img src="https://sdk.beamimpact.com/assets/img/screenshots/beam-select-nonprofit.png"
46
- alt="Screenshot of Beam widget" />
47
+ alt="Screenshot of Beam component" />
47
48
 
48
49
  The Beam Web SDK provides a set of web components and framework-specific wrappers for
49
- integrating Beam widgets into an e-commerce website.
50
+ integrating Beam components into an e-commerce website.
50
51
 
51
52
  ## Installation
52
53
 
@@ -56,7 +57,7 @@ integrating Beam widgets into an e-commerce website.
56
57
 
57
58
  Most e-commerce applications will load Beam over the CDN.
58
59
 
59
- Include the script for the widget you want to use at the top of the page:
60
+ Include the script for the component you want to use at the top of the page:
60
61
 
61
62
  ```html
62
63
  <script
@@ -97,16 +98,16 @@ Beam web components are custom elements, so they can be used in HTML:
97
98
  <beam-impact-overview chainId="1000"></beam-impact-overview>
98
99
  ```
99
100
 
100
- Because they are standard HTML elements, Beam widgets can have attributes like `class`, `style`, and `data-attributes`.
101
+ Because they are standard HTML elements, Beam components can have attributes like `class`, `style`, and `data-attributes`.
101
102
 
102
103
  Components can also be created using Javascript:
103
104
 
104
105
  ```js
105
- const widget = document.createElement("beam-select-nonprofit");
106
- widget.chainId = 1000;
107
- widget.apiKey = "abc123";
106
+ const component = document.createElement("beam-select-nonprofit");
107
+ component.chainId = 1000;
108
+ component.apiKey = "abc123";
108
109
  const parent = document.querySelector("#sidebar-cart .footer");
109
- parent.appendChild(widget);
110
+ parent.appendChild(component);
110
111
  ```
111
112
 
112
113
  The elements can also have children which show up before the script loads or if it fails to parse:
@@ -140,7 +141,7 @@ import { events } from "@beamimpact/web-sdk/dist/integrations/utils";
140
141
 
141
142
  **(ie, NextJS)**
142
143
 
143
- The Beam Widgets run clientside and save data (such as the user's nonprofit selection) in localStorage and cookies.
144
+ The Beam components run clientside and save data (such as the user's nonprofit selection) in localStorage and cookies.
144
145
 
145
146
  Use [next/dynamic](https://nextjs.org/docs/pages/building-your-application/optimizing/lazy-loading) to lazy-load
146
147
  components async on the client instead of the server.
@@ -164,9 +165,9 @@ console logs.
164
165
  <beam-impact-overview chainId="1000" debug></beam-impact-overview>
165
166
  ```
166
167
 
167
- ## Widget Options
168
+ ## Component Options
168
169
 
169
- Required props for all widgets:
170
+ Required props for all components:
170
171
 
171
172
  - `apiKey` - Beam API Key
172
173
 
@@ -198,13 +199,13 @@ Shows total impact in terms of nonprofit funding goals - e.g., "9,000 lbs of oce
198
199
 
199
200
  ### beam-select-nonprofit
200
201
 
201
- Widget that integrates into a cart to allow customers to support a nonprofit as they check out.
202
+ Component that integrates into a cart to allow users to support a nonprofit as they check out.
202
203
 
203
204
  ```html
204
205
  <beam-select-nonprofit apiKey="abc-123" storeId="1"> Select a nonprofit </beam-select-nonprofit>
205
206
  ```
206
207
 
207
- - `storeId` = Beam ID for site, i.e., EU or US online store (optional) - used to show relevant nonprofits to customers
208
+ - `storeId` = Beam ID for site, i.e., EU or US online store (optional) - used to show relevant nonprofits to users
208
209
  - `countryCode` & `postalCode` = If `storeId` is not provided, location information can be provided instead (optional)
209
210
  - `cart` = Usually set automatically by the cart integration (see below), the cart property allows customizing the
210
211
  nonprofits shown based on the items in the cart
@@ -220,12 +221,12 @@ document.addEventListener("beamnonprofitselect", (evt) => {
220
221
 
221
222
  #### **Event Types**
222
223
 
223
- **Select Nonprofit Widget & Post Purchase Widget**
224
+ **Select Nonprofit Component & Post Purchase Component**
224
225
 
225
226
  - **Event:** `beamnonprofitselect`
226
- - **Description:** Emitted when the end user selects a nonprofit in the Beam widget, and when the previous selection was restored automatically
227
+ - **Description:** Emitted when the end user selects a nonprofit in the Beam component, and when the previous selection was restored automatically
227
228
 
228
- **Select Nonprofit Widget**
229
+ **Select Nonprofit Component**
229
230
 
230
231
  - **Event:** `beamcartchange`
231
232
  - **Description:** Emitted when Beam detects that cart contents have changed, and when items are added to the cart for the first time
@@ -236,9 +237,9 @@ document.addEventListener("beamnonprofitselect", (evt) => {
236
237
  **Statsig / A/B Experiment**
237
238
 
238
239
  - **Event:** `beamstatsiginitialized`
239
- - **Description:** Emitted when Statsig has completed assigning experiment variants for the current session. Contains `showBeam` (whether widgets should be shown) and `stableId` (the Statsig session Id).
240
+ - **Description:** Emitted when Statsig has completed assigning experiment variants for the current session. Contains `showBeam` (whether components should be shown) and `stableId` (the Statsig session Id).
240
241
 
241
- **Post Purchase Widget**
242
+ **Post Purchase Component**
242
243
 
243
244
  - **Event:** `beamordercreated`
244
245
  - **Description:** Emitted when an order is registered with Beam for the first time, but NOT on repeat visits, page refreshes, etc.
@@ -246,7 +247,7 @@ document.addEventListener("beamnonprofitselect", (evt) => {
246
247
  ### beam-post-purchase
247
248
 
248
249
  A wrapper component that registers transactions and renders either the `beam-impact-overview` or
249
- `beam-redeem-transaction` widget, depending on if the user made a selection before purchase or not.
250
+ `beam-redeem-transaction` component, depending on if the user made a selection before purchase or not.
250
251
 
251
252
  ```html
252
253
  <script src="https://sdk.beamimpact.com/web-sdk/v1.36.1/dist/components/post-purchase.js"></script>
@@ -255,18 +256,18 @@ A wrapper component that registers transactions and renders either the `beam-imp
255
256
  ```
256
257
 
257
258
  ```js
258
- const widget = document.createElement("beam-post-purchase");
259
+ const component = document.createElement("beam-post-purchase");
259
260
 
260
261
  // Config values:
261
- widget.apiKey = "abc123"; // Required
262
- widget.storeId = 100; // Beam Store ID
263
- widget.countryCode = "GB"; // 2-letter country code for order
264
- widget.postalCode = "11111"; // String - postalCode in country-specific format
265
- widget.orderId = String(10101); // partner provides ID
266
- widget.email = "test@beamimpact.com"; // customer email
267
- widget.cartTotal = 100.01; // Cart total before tax
268
- widget.currencyCode = "USD"; // "CAD" etc.
269
- widget.cart = {
262
+ component.apiKey = "abc123"; // Required
263
+ component.storeId = 100; // Beam Store ID
264
+ component.countryCode = "GB"; // 2-letter country code for order
265
+ component.postalCode = "11111"; // String - postalCode in country-specific format
266
+ component.orderId = String(10101); // partner provides ID
267
+ component.email = "test@beamimpact.com"; // user email
268
+ component.cartTotal = 100.01; // Cart total before tax
269
+ component.currencyCode = "USD"; // "CAD" etc.
270
+ component.cart = {
270
271
  schema: {
271
272
  source: "shopify",
272
273
  },
@@ -274,10 +275,10 @@ widget.cart = {
274
275
  items: [{ sku: "PRODUCT-100" }],
275
276
  },
276
277
  }; // see OpenAPI spec for cart formats
277
- widget.discountCodes = ["PROMO10", "CLEARANCE_50"]; // discount / promo codes
278
- widget.lang = "en"; // en | fr Language
279
- widget.domain = "example.com"; // [Optional] Base domain of the store, if subdomains for store and checkout differ
280
- widget.debug = false; // boolean
278
+ component.discountCodes = ["PROMO10", "CLEARANCE_50"]; // discount / promo codes
279
+ component.lang = "en"; // en | fr Language
280
+ component.domain = "example.com"; // [Optional] Base domain of the store, if subdomains for store and checkout differ
281
+ component.debug = false; // boolean
281
282
  ```
282
283
 
283
284
  #### Events
@@ -289,7 +290,7 @@ document.addEventListener("beamnonprofitselect", (evt) => {
289
290
  });
290
291
  ```
291
292
 
292
- #### Customizing inner widgets
293
+ #### Customizing inner components
293
294
 
294
295
  Use `beam-post-purchase::part(impact-overview)` or `beam-post-purchase::part(redeem-transaction)` to apply CSS.
295
296
 
@@ -328,8 +329,8 @@ await updateCart(beamConfig, cart);
328
329
 
329
330
  ### Shopify
330
331
 
331
- The `registerCartIntegration()` function integrates the Beam Nonprofit Select widget with the Shopify cart, which
332
- allows Beam metadata for the nonprofitId and selectionId to be added to the order as the customer goes through the
332
+ The `registerCartIntegration()` function integrates the Beam Nonprofit Select component with the Shopify cart, which
333
+ allows Beam metadata for the nonprofitId and selectionId to be added to the order as the user goes through the
333
334
  checkout flow, and to track the cart token and cart value for the Beam ROI calculation.
334
335
 
335
336
  **Add event tracking script to main layout:**
@@ -349,7 +350,7 @@ checkout flow, and to track the cart token and cart value for the Beam ROI calcu
349
350
  Post-purchase script:
350
351
 
351
352
  ```ts
352
- import { showOrderPageWidgets } from "https://sdk.beamimpact.com/web-sdk/v1.36.0/dist/integrations/shopify.esm.js";
353
+ import { showBeamOrderPageWidgets } from "https://sdk.beamimpact.com/web-sdk/v1.36.0/dist/integrations/shopify.esm.js";
353
354
 
354
355
  await showBeamOrderPageWidgets({
355
356
  apiKey: beam.apiKey,
@@ -369,6 +370,21 @@ await showBeamOrderPageWidgets({
369
370
  });
370
371
  ```
371
372
 
373
+ **Consent-driven teardown:**
374
+
375
+ If a user withdraws tracking consent, `unregisterCartIntegration()` stops the listeners set up by
376
+ `registerCartIntegration()` and can optionally wipe Beam's local storage/cookies in the same call. It's opt-in — the
377
+ SDK doesn't watch for a consent signal itself, so this must be wired into your own consent banner/flow.
378
+
379
+ ```ts
380
+ import { unregisterCartIntegration } from "https://sdk.beamimpact.com/web-sdk/v1.36.0/dist/integrations/shopify.esm.js";
381
+
382
+ await unregisterCartIntegration(
383
+ { apiKey: "abc123", storeId: 100, chainId: 10 },
384
+ { clearStorage: true }, // also clear Beam's localStorage/cookies; defaults to false
385
+ );
386
+ ```
387
+
372
388
  ### Utils
373
389
 
374
390
  Several utilities are exposed which making integrating with existing applications easier.
@@ -376,13 +392,21 @@ Several utilities are exposed which making integrating with existing application
376
392
  1. `waitForElement` returns a Promise which resolves when the selector appears.
377
393
  2. `errors` contains Beam custom error classes.
378
394
  3. `events` contains Beam custom events classes / event names.
395
+ 4. `clearBeamStorage` clears all Beam-related localStorage keys and cookies for a given config; useful for a
396
+ standalone consent-driven reset that isn't tied to `unregisterCartIntegration`.
397
+
398
+ ```js
399
+ import { clearBeamStorage } from "https://sdk.beamimpact.com/web-sdk/v1.36.1/dist/integrations/utils.js";
400
+
401
+ clearBeamStorage({ apiKey: "abc123", domain: "my-store.com" });
402
+ ```
379
403
 
380
404
  ```js
381
405
  import { waitForElement, errors, events } from "https://sdk.beamimpact.com/web-sdk/v1.36.1/dist/integrations/utils.js";
382
406
 
383
407
  try {
384
408
  const parentElement = await waitForElement("#my-selector", { timeout: 1000 });
385
- parentElement.appendChild(widget);
409
+ parentElement.appendChild(component);
386
410
  } catch (err) {
387
411
  if (err instanceof errors.BeamError) {
388
412
  /* do something */
@@ -437,7 +461,7 @@ if (beam.status !== "ready") {
437
461
 
438
462
  ##### Visibility
439
463
 
440
- Once initialized, all Beam widgets have `display: none` unless user is assigned to A/B test group that shows Beam.
464
+ Once initialized, all Beam components have `display: none` unless user is assigned to A/B test group that shows Beam.
441
465
 
442
466
  To hide additional elements, add the CSS className `beam-sync-visibility` to them. Elements with this class will
443
467
  automatically have `display: none` if the user can't see Beam.
@@ -1,2 +1,2 @@
1
- import{r as c,s as i}from"./vendor-DUOg5fL-.esm.js";import{q as t}from"./index-Dc4HgxdT.esm.js";import"./lit-BEag9MFp.esm.js";import"./utils-C5hmbxa4.esm.js";import"./lodash-CrMU6wKg.esm.js";const s="https://sdk.beamimpact.com",a=`${s}/lib/shoelace/v${t["@shoelace-style/shoelace"]}`,o=`${s}/lib/lucide-static/v${t["lucide-static"]}`;if(c("lucide",{resolver:e=>`${o}/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-DFXGKz-z.esm.js.map
1
+ import{r as c,s as i}from"./vendor-DUOg5fL-.esm.js";import{q as t}from"./index-CVHrQ1WC.esm.js";import"./lit-BEag9MFp.esm.js";import"./utils-C5hmbxa4.esm.js";import"./lodash-CrMU6wKg.esm.js";const s="https://sdk.beamimpact.com",a=`${s}/lib/shoelace/v${t["@shoelace-style/shoelace"]}`,o=`${s}/lib/lucide-static/v${t["lucide-static"]}`;if(c("lucide",{resolver:e=>`${o}/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-BvaXft1r.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"_share-dialog-dependencies-DFXGKz-z.esm.js","sources":["../../src/shared/shoelace-components.ts"],"sourcesContent":["/**\n * Shoelace is a utility library for web components like icons, dialogs, buttons, etc.\n * https://shoelace.style/\n */\n\nimport { setBasePath } from \"@shoelace-style/shoelace/dist/utilities/base-path.js\";\nimport { registerIconLibrary } from \"@shoelace-style/shoelace/dist/utilities/icon-library.js\";\nimport { dependencies } from \"../../package.json\";\n\nconst CDN_BASE = \"https://sdk.beamimpact.com\";\nconst SHOELACE_BASE = `${CDN_BASE}/lib/shoelace/v${dependencies[\"@shoelace-style/shoelace\"]}`;\nconst ICON_BASE = `${CDN_BASE}/lib/lucide-static/v${dependencies[\"lucide-static\"]}`;\n\nregisterIconLibrary(\"lucide\", {\n resolver: (name: string) => `${ICON_BASE}/icons/${name}.svg`,\n});\n\nsetBasePath(SHOELACE_BASE);\n\nif (document && !document.querySelector(\"link[data-beam-impact]\")) {\n const stylesheet = document.createElement(\"link\");\n stylesheet.href = `${SHOELACE_BASE}/themes/light.css`;\n stylesheet.rel = \"stylesheet\";\n stylesheet.setAttribute(\"data-beam-impact\", \"true\");\n document.head.appendChild(stylesheet);\n}\n"],"names":["CDN_BASE","SHOELACE_BASE","dependencies","ICON_BASE","registerIconLibrary","name","setBasePath","stylesheet"],"mappings":"+LASA,MAAMA,EAAW,6BACXC,EAAgB,GAAGD,CAAQ,kBAAkBE,EAAa,0BAA0B,CAAC,GACrFC,EAAY,GAAGH,CAAQ,uBAAuBE,EAAa,eAAe,CAAC,GAQjF,GANAE,EAAoB,SAAU,CAC5B,SAAWC,GAAiB,GAAGF,CAAS,UAAUE,CAAI,MACxD,CAAC,EAEDC,EAAYL,CAAa,EAErB,UAAY,CAAC,SAAS,cAAc,wBAAwB,EAAG,CACjE,MAAMM,EAAa,SAAS,cAAc,MAAM,EAChDA,EAAW,KAAO,GAAGN,CAAa,oBAClCM,EAAW,IAAM,aACjBA,EAAW,aAAa,mBAAoB,MAAM,EAClD,SAAS,KAAK,YAAYA,CAAU,CACtC"}
1
+ {"version":3,"file":"_share-dialog-dependencies-BvaXft1r.esm.js","sources":["../../src/shared/shoelace-components.ts"],"sourcesContent":["/**\n * Shoelace is a utility library for web components like icons, dialogs, buttons, etc.\n * https://shoelace.style/\n */\n\nimport { setBasePath } from \"@shoelace-style/shoelace/dist/utilities/base-path.js\";\nimport { registerIconLibrary } from \"@shoelace-style/shoelace/dist/utilities/icon-library.js\";\nimport { dependencies } from \"../../package.json\";\n\nconst CDN_BASE = \"https://sdk.beamimpact.com\";\nconst SHOELACE_BASE = `${CDN_BASE}/lib/shoelace/v${dependencies[\"@shoelace-style/shoelace\"]}`;\nconst ICON_BASE = `${CDN_BASE}/lib/lucide-static/v${dependencies[\"lucide-static\"]}`;\n\nregisterIconLibrary(\"lucide\", {\n resolver: (name: string) => `${ICON_BASE}/icons/${name}.svg`,\n});\n\nsetBasePath(SHOELACE_BASE);\n\nif (document && !document.querySelector(\"link[data-beam-impact]\")) {\n const stylesheet = document.createElement(\"link\");\n stylesheet.href = `${SHOELACE_BASE}/themes/light.css`;\n stylesheet.rel = \"stylesheet\";\n stylesheet.setAttribute(\"data-beam-impact\", \"true\");\n document.head.appendChild(stylesheet);\n}\n"],"names":["CDN_BASE","SHOELACE_BASE","dependencies","ICON_BASE","registerIconLibrary","name","setBasePath","stylesheet"],"mappings":"+LASA,MAAMA,EAAW,6BACXC,EAAgB,GAAGD,CAAQ,kBAAkBE,EAAa,0BAA0B,CAAC,GACrFC,EAAY,GAAGH,CAAQ,uBAAuBE,EAAa,eAAe,CAAC,GAQjF,GANAE,EAAoB,SAAU,CAC5B,SAAWC,GAAiB,GAAGF,CAAS,UAAUE,CAAI,MACxD,CAAC,EAEDC,EAAYL,CAAa,EAErB,UAAY,CAAC,SAAS,cAAc,wBAAwB,EAAG,CACjE,MAAMM,EAAa,SAAS,cAAc,MAAM,EAChDA,EAAW,KAAO,GAAGN,CAAa,oBAClCM,EAAW,IAAM,aACjBA,EAAW,aAAa,mBAAoB,MAAM,EAClD,SAAS,KAAK,YAAYA,CAAU,CACtC"}
@@ -1,6 +1,6 @@
1
1
  import * as lodash from 'lodash';
2
- import { M as MemoizedLast, d as TCart } from './utils-SWm8ZEfg.esm.js';
3
- import { B as BeamCartAPIConfig, a as BeamCartValues } from './update-cart-BclA4Tsd.esm.js';
2
+ import { M as MemoizedLast, d as TCart } from './utils-BPcZ5h8J.esm.js';
3
+ import { B as BeamCartAPIConfig, a as BeamCartValues } from './update-cart-B5Tr9N3V.esm.js';
4
4
 
5
5
  type BeamShopifyCartIntegrationConfig = BeamCartAPIConfig & {
6
6
  storeId: number;
@@ -0,0 +1,32 @@
1
+ import{n as o,r as c,a as K,b as g}from"./lit-BEag9MFp.esm.js";import{D as v,z as P,h as B,_ as M,$ as F,C as N,R as x,g as y,l as L,n as w,a1 as W,L as T,a2 as J,Y as z,u as k,F as q,P as Y,w as j}from"./utils-C5hmbxa4.esm.js";import{c as G,d as V,e as H}from"./css-card-grid-CiqEjkwR.esm.js";import{B as U,A as Q,c as X}from"./index-CVHrQ1WC.esm.js";import{p as Z,u as tt}from"./index-Di1IwSgk.esm.js";import"../components/impact-overview.js";var et=Object.defineProperty,e=(h,s,n,m)=>{for(var d=void 0,p=h.length-1,u;p>=0;p--)(u=h[p])&&(d=u(s,n,d)||d);return d&&et(s,n,d),d};const A=["baseUrl","apiKey","orderId","cartTotal","currencyCode","lang"],ot=["storeId","postalCode","countryCode","cart","discountCodes","promoCodes","htmlPromoCodes","email","partnerUserId","remoteSessionId"];class t extends K{constructor(){super(...arguments),this.baseUrl=v,this.currencyCode="USD",this.lang="en",this.debug=!1,this.activeWidget=null,this.nonprofitId=null,this.selectionId=null,this.cartId=null,this.beamCartId=null,this.userId=null,this.transactionId=null,this.excludeDonationsForRecurringTransactions=!1,this.creationMethod="",this.orderProcessedAt="",this.draftConfig=!1,this.localStorage=P(this),this.handlePostTransaction=async()=>{this.enforceConfig(),this.updateComponentState();const s=this.getManualPromoCodes(),n=B(s.map(a=>({value:a})),this.apiKey),m=M(),d={unvalidatedPromoCodes:F(s.map(a=>({value:a}))),validatedPromoCodes:m?.validatedPromoCodes??[]},p=n??d,u=p&&!N(p),I=this.remoteSessionId??x({apiKey:this.apiKey})??y("beam_statsig_session_id"),i=await Z({baseUrl:this.baseUrl,apiRoot:"/api",headers:{authorization:`Api-Key ${this.apiKey}`},requestBody:{selectionId:this.selectionId||void 0,cartId:this.cartId||void 0,beamCartId:this.beamCartId||void 0,storeId:this.storeId,orderId:this.orderId,cartTotal:this.cartTotal,email:this.email,partnerUserId:this.partnerUserId,currencyCode:this.currencyCode,postalCode:this.postalCode,countryCode:this.countryCode,cart:this.cart,...u&&{promos:p},discountCodes:this.discountCodes,orderProcessedAt:new Date().toISOString(),...I&&{remoteSessionId:I}}});let l=i;if(!i.transactionCreated&&!i.selectionId&&this.selectionId)try{const a=await tt({baseUrl:this.baseUrl,apiRoot:"/api",headers:{authorization:`Api-Key ${this.apiKey}`},pathParams:{transactionId:i.transactionId},requestBody:{selectionId:this.selectionId}});l=a,this.selectionId=a.selectionId??this.selectionId,this.localStorage.removeItem("transaction")}catch(a){L.warn(new w("Failed to attach selectionId to existing transaction via update endpoint",{cause:a}),{transactionId:i.transactionId,selectionId:this.selectionId})}this.transactionId=l.transactionId,this.userId=l.beamUserId,this.nonprofitId=l.nonprofitId,this.excludeDonationsForRecurringTransactions=!!i.reportSettings?.excludeRecurringDonations,this.creationMethod=l.creationMethod||"",this.orderProcessedAt=l.timestamp;const C=!!this.nonprofitId;return this.activeWidget=C?"impact-overview":"redeem-transaction",i.transactionCreated&&(["transaction","cart",W,T.NONPROFIT,T.NONPROFIT_SELECTED_AT].forEach(a=>{this.localStorage.removeItem(a)}),[{name:U,path:"/",domain:this.domain},{name:J,path:"/",domain:this.domain}].forEach(a=>z(a)),dispatchEvent(new k({transactionId:i.transactionId,orderId:this.orderId,cartTotal:this.cartTotal,currencyCode:this.currencyCode,selectionId:this.selectionId??null,cartId:this.cartId,beamCartId:this.beamCartId,storeId:this.storeId??null,postalCode:this.postalCode??null,countryCode:this.countryCode??null,remoteSessionId:this.remoteSessionId??null,transactionNonprofitId:i.nonprofitId,orderProcessedAt:i.timestamp}))),l},this.transactionDataController=new Q(this,this.handlePostTransaction)}get parsedPromoCodes(){return q(this.htmlPromoCodes)}updateComponentState(){this.localStorage.getItem("transaction")?.toLocaleLowerCase()==="undefined"&&this.localStorage.removeItem("transaction"),this.selectionId=this.selectionId||this.localStorage.getItem("transaction")||null,this.cartId=this.cartId||this.localStorage.getItemJson("cart")?.cartId||null,this.beamCartId=this.beamCartId||this.localStorage.getItemJson("cart")?.beamCartId||y(U)||null,this.selectionId&&this.nonprofitId&&(this.activeWidget="impact-overview")}firstUpdated(s){this.enforceConfig(),this.updateComponentState()}async updated(s){[...A,...ot].some(n=>s.has(n))&&await this.transactionDataController.exec()}enforceConfig(){if(H(A,this),!this.email&&!this.partnerUserId)throw new Y([this.email?"":"email",this.partnerUserId?"":"partnerUserId"].filter(Boolean),"At least one of [email, partnerUserId] must be provided")}getManualPromoCodes(){return this.parsedPromoCodes?.length?this.parsedPromoCodes:this.promoCodes?.length?this.promoCodes:[]}render(){const s=Date.now()-new Date(this.orderProcessedAt).getTime()<2592e6;return this.transactionDataController.loading?"":this.transactionDataController.error?this.debug?X({error:this.transactionDataController.error}):"":this.excludeDonationsForRecurringTransactions&&this.creationMethod==="recurring"?g``:this.activeWidget==="redeem-transaction"&&s?g`
2
+ <beam-redeem-transaction
3
+ part="redeem-transaction"
4
+ baseUrl="${this.baseUrl}"
5
+ apiKey="${this.apiKey}"
6
+ storeId="${this.storeId}"
7
+ postalCode="${this.postalCode}"
8
+ countryCode="${this.countryCode}"
9
+ transactionId="${this.transactionId}"
10
+ cart="${JSON.stringify(this.cart)}"
11
+ lang="${this.lang}"
12
+ excludeDonationsForRecurringTransactions="${this.excludeDonationsForRecurringTransactions}"
13
+ ?draftConfig="${this.draftConfig}"
14
+ ?debug="${this.debug}"
15
+ @beamnonprofitselect="${n=>{if(!(n instanceof CustomEvent))return;const{selectedNonprofitId:m}=n.detail;this.nonprofitId=m??null,this.activeWidget="impact-overview"}}"
16
+ ></beam-redeem-transaction>
17
+ `:this.activeWidget==="impact-overview"?g`
18
+ <beam-impact-overview
19
+ part="impact-overview"
20
+ storeId="${this.storeId}"
21
+ baseUrl="${this.baseUrl}"
22
+ apiKey="${this.apiKey}"
23
+ userId="${this.userId}"
24
+ nonprofitId="${this.nonprofitId}"
25
+ lang="${this.lang}"
26
+ discountCodes="${JSON.stringify(this.discountCodes)}"
27
+ transactionId="${this.transactionId}"
28
+ ?draftConfig="${this.draftConfig}"
29
+ ?debug="${this.debug}"
30
+ ></beam-impact-overview>
31
+ `:""}}t.tagName="beam-post-purchase",t.styles=[G],e([o({type:String})],t.prototype,"baseUrl"),e([o({type:String})],t.prototype,"apiKey"),e([o({type:Number,reflect:!0})],t.prototype,"storeId"),e([o({type:String})],t.prototype,"postalCode"),e([o({type:String})],t.prototype,"countryCode"),e([o({type:String})],t.prototype,"orderId"),e([o({type:String})],t.prototype,"email"),e([o({type:String})],t.prototype,"partnerUserId"),e([o({type:Number})],t.prototype,"cartTotal"),e([o({type:String})],t.prototype,"currencyCode"),e([o({type:String})],t.prototype,"lang"),e([o({type:Object})],t.prototype,"cart"),e([o({type:Array})],t.prototype,"discountCodes"),e([o({type:Array})],t.prototype,"promoCodes"),e([o({type:String})],t.prototype,"htmlPromoCodes"),e([o({type:String})],t.prototype,"domain"),e([o({type:String})],t.prototype,"remoteSessionId"),e([o({type:Boolean})],t.prototype,"debug"),e([c()],t.prototype,"activeWidget"),e([c()],t.prototype,"nonprofitId"),e([c()],t.prototype,"selectionId"),e([c()],t.prototype,"cartId"),e([c()],t.prototype,"beamCartId"),e([c()],t.prototype,"userId"),e([c()],t.prototype,"transactionId"),e([c()],t.prototype,"excludeDonationsForRecurringTransactions"),e([c()],t.prototype,"creationMethod"),e([c()],t.prototype,"orderProcessedAt"),e([o({type:Boolean})],t.prototype,"draftConfig"),V(t);async function rt({parentSelector:h=".step__sections",apiKey:s,baseUrl:n=v,storeId:m,postalCode:d,discountCodes:p,countryCode:u,orderId:I,email:i,cartTotal:l,cart:C,promoCodes:a,htmlPromoCodes:$,currencyCode:E="USD",domain:O,lang:D="en",debug:_=!1}){const f=document.querySelector(h)||await j(h);if(!f)throw new w(`Timed out waiting for selector '${h}'. Could not render Beam post-purchase widget.`);const S=await y("cart");if(S){const b=P({apiKey:s}),R=b.getItemJson("cart")||{};b.setItemJson("cart",{...R,cartId:S})}const r=document.createElement("beam-post-purchase");r.apiKey=s,r.baseUrl=n,r.storeId=m,r.postalCode=d,r.countryCode=u,r.orderId=String(I),r.email=i,r.cartTotal=l,r.cart=C,r.promoCodes=a,r.htmlPromoCodes=$,r.discountCodes=p,r.currencyCode=E,r.domain=O,r.lang=D,r.debug=_,f.appendChild(r)}export{t as B,rt as s};
32
+ //# sourceMappingURL=index-726Vfz5u.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-726Vfz5u.esm.js","sources":["../../src/components/post-purchase/index.ts","../../src/integrations/shopify-order/order.ts"],"sourcesContent":["import { html, LitElement, PropertyValues } from \"lit\";\nimport { property } from \"lit/decorators/property.js\";\nimport { state } from \"lit/decorators/state.js\";\nimport { BeamError, MissingConfig } from \"../../utils/beam-errors\";\nimport { deleteCookieValue, getCookieValue } from \"../../utils/cookies\";\nimport { cssReset } from \"../../shared/css-reset\";\nimport { defineCustomElement } from \"../../shared/defineCustomElement\";\nimport { createScopedLocalStorage } from \"../../utils/local-storage\";\nimport { AsyncController } from \"../../shared/controllers/async-controller\";\nimport { _errorMessage } from \"../../shared/fragments/error-message-template\";\nimport { enforceConfig } from \"../../shared/enforce-config\";\nimport { LANGUAGES } from \"../../api-sdk/types\";\nimport { DEFAULT_BASE_URL, LOCAL_STORAGE_KEYS } from \"../../api-sdk/constants\";\nimport { postTransaction, updateTransaction } from \"../../api-sdk/v4/routes\";\nimport \"../redeem-transaction\";\nimport \"../impact-overview\";\nimport { BEAM_CART_COOKIE_NAME, TBeamCartLocalStorage, TCart } from \"../../shared/cart-contents\";\nimport { BeamNonprofitSelectEvent, BeamOrderCreatedEvent } from \"../../utils/events\";\nimport {\n isEmptyPromoData,\n parseJsonStringArray,\n formatStoreAndReturnPromoCodes,\n getAllPromoCodesFromCookie,\n mapToUnvalidatedPromoCodes,\n} from \"../../utils/promoManager\";\nimport { PROMO_CODES_COOKIE_NAME, PROMO_LOCAL_STORAGE_KEY, TPromoCodeRequest } from \"../../shared/promo-types\";\nimport { getRemoteSession } from \"../../utils/remote-session\";\nimport { logger } from \"../../utils/logger\";\n\nconst REQUIRED_DATA_PROPS = [\"baseUrl\", \"apiKey\", \"orderId\", \"cartTotal\", \"currencyCode\", \"lang\"];\nconst OPTIONAL_DATA_PROPS = [\n \"storeId\",\n \"postalCode\",\n \"countryCode\",\n \"cart\",\n \"discountCodes\",\n \"promoCodes\",\n \"htmlPromoCodes\",\n \"email\",\n \"partnerUserId\",\n \"remoteSessionId\",\n];\n\nexport class BeamPostPurchase extends LitElement {\n static tagName = \"beam-post-purchase\";\n\n @property({ type: String })\n public baseUrl: string = DEFAULT_BASE_URL;\n\n @property({ type: String })\n public apiKey!: string;\n\n @property({ type: Number, reflect: true })\n public storeId?: number; // Either storeId or postalCode, countryCode must be provided\n\n @property({ type: String })\n public postalCode?: string;\n\n @property({ type: String })\n public countryCode?: string;\n\n @property({ type: String })\n public orderId!: string;\n\n /**\n * Either email or partnerUserId is required\n */\n @property({ type: String })\n public email?: string;\n\n /**\n * Either email or partnerUserId is required\n */\n @property({ type: String })\n public partnerUserId?: string;\n\n @property({ type: Number })\n public cartTotal!: number;\n\n @property({ type: String })\n public currencyCode = \"USD\";\n\n @property({ type: String })\n public lang: LANGUAGES = \"en\";\n\n @property({ type: Object })\n public cart?: TCart;\n\n /**\n * @deprecated Use `promoCodes` instead. `discountCodes` is retained for backward compatibility\n */\n @property({ type: Array })\n public discountCodes?: string[];\n\n @property({ type: Array })\n public promoCodes?: string[];\n\n @property({ type: String })\n public htmlPromoCodes?: string;\n\n @property({ type: String })\n public domain?: string;\n\n @property({ type: String })\n public remoteSessionId?: string;\n\n @property({ type: Boolean })\n public debug = false;\n\n @state() private activeWidget: \"redeem-transaction\" | \"impact-overview\" | null = null; // wait for postTransaction\n @state() private nonprofitId: number | null = null; // from localStorage or redeem-transaction result\n @state() private selectionId: string | null = null; // from localStorage\n @state() private cartId: string | null = null; // from localStorage, external cart ID\n @state() private beamCartId: string | null = null; // from cookie, Beam cart ID\n @state() private userId: string | null = null; // from postTransaction\n @state() private transactionId: string | null = null; // from postTransaction\n @state() private excludeDonationsForRecurringTransactions = false;\n @state() private creationMethod = \"\";\n @state() private orderProcessedAt = \"\";\n @property({ type: Boolean }) public draftConfig = false;\n\n private localStorage = createScopedLocalStorage(this);\n\n get parsedPromoCodes(): string[] {\n return parseJsonStringArray(this.htmlPromoCodes);\n }\n\n updateComponentState() {\n // Delete selectionId if it was saved with an invalid string (bug introduced v1.54.0)\n if (this.localStorage.getItem(\"transaction\")?.toLocaleLowerCase() === \"undefined\") {\n this.localStorage.removeItem(\"transaction\");\n }\n\n this.selectionId = this.selectionId || this.localStorage.getItem(\"transaction\") || null;\n this.cartId = this.cartId || this.localStorage.getItemJson<TBeamCartLocalStorage>(\"cart\")?.cartId || null;\n // Reading beamCartId from cookies instead of localStorage allows it to work across subdomains\n this.beamCartId =\n this.beamCartId ||\n this.localStorage.getItemJson<TBeamCartLocalStorage>(\"cart\")?.beamCartId ||\n getCookieValue(BEAM_CART_COOKIE_NAME) ||\n null;\n\n if (this.selectionId && this.nonprofitId) {\n this.activeWidget = \"impact-overview\";\n }\n }\n\n firstUpdated(_changedProperties: PropertyValues) {\n this.enforceConfig();\n this.updateComponentState();\n }\n\n async updated(previousPropertyValues: PropertyValues) {\n // Also fires on first load as props go from undefined => value\n const refreshOnChangeProps = [...REQUIRED_DATA_PROPS, ...OPTIONAL_DATA_PROPS];\n if (refreshOnChangeProps.some((p) => previousPropertyValues.has(p))) {\n await this.transactionDataController.exec();\n }\n }\n\n enforceConfig() {\n enforceConfig(REQUIRED_DATA_PROPS, this);\n if (!this.email && !this.partnerUserId) {\n throw new MissingConfig(\n [this.email ? \"\" : \"email\", this.partnerUserId ? \"\" : \"partnerUserId\"].filter(Boolean),\n \"At least one of [email, partnerUserId] must be provided\",\n );\n }\n }\n\n private getManualPromoCodes(): string[] {\n if (this.parsedPromoCodes?.length) {\n return this.parsedPromoCodes;\n }\n if (this.promoCodes?.length) {\n return this.promoCodes;\n }\n return [];\n }\n\n handlePostTransaction = async () => {\n this.enforceConfig();\n this.updateComponentState();\n\n const manualPromoCodes = this.getManualPromoCodes();\n const formattedPromosFromLocalStorage = formatStoreAndReturnPromoCodes(\n manualPromoCodes.map((code) => ({ value: code })),\n this.apiKey,\n );\n\n const promoCookieData = getAllPromoCodesFromCookie();\n const formattedPromosFromCookie: TPromoCodeRequest = {\n unvalidatedPromoCodes: mapToUnvalidatedPromoCodes(manualPromoCodes.map((code) => ({ value: code }))),\n validatedPromoCodes: promoCookieData?.validatedPromoCodes ?? [],\n };\n\n const formattedPromos = formattedPromosFromLocalStorage ?? formattedPromosFromCookie;\n\n const shouldSendPromos = formattedPromos && !isEmptyPromoData(formattedPromos);\n const remoteSessionId =\n this.remoteSessionId ?? getRemoteSession({ apiKey: this.apiKey }) ?? getCookieValue(\"beam_statsig_session_id\");\n const result = await postTransaction({\n baseUrl: this.baseUrl,\n apiRoot: \"/api\",\n headers: {\n authorization: `Api-Key ${this.apiKey}`,\n },\n requestBody: {\n selectionId: this.selectionId || undefined,\n cartId: this.cartId || undefined,\n beamCartId: this.beamCartId || undefined,\n storeId: this.storeId,\n orderId: this.orderId,\n cartTotal: this.cartTotal,\n email: this.email, // One or both of email & partnerUserId should be defined\n partnerUserId: this.partnerUserId, // One or both of email & partnerUserId should be defined\n currencyCode: this.currencyCode,\n postalCode: this.postalCode,\n countryCode: this.countryCode,\n cart: this.cart,\n ...(shouldSendPromos && { promos: formattedPromos }),\n discountCodes: this.discountCodes,\n orderProcessedAt: new Date().toISOString(),\n ...(remoteSessionId && { remoteSessionId }),\n },\n });\n\n let effectiveResult: Awaited<ReturnType<typeof postTransaction>> = result;\n const shouldAttachSelectionId = !result.transactionCreated && !result.selectionId && Boolean(this.selectionId);\n\n if (shouldAttachSelectionId) {\n try {\n const updateResult = await updateTransaction({\n baseUrl: this.baseUrl,\n apiRoot: \"/api\",\n headers: { authorization: `Api-Key ${this.apiKey}` },\n pathParams: { transactionId: result.transactionId },\n requestBody: { selectionId: this.selectionId as string },\n });\n effectiveResult = updateResult;\n this.selectionId = updateResult.selectionId ?? this.selectionId;\n // Clear the pending selectionId now that it's durably attached server-side,\n // so a future unrelated order doesn't try to reattach it (mirrors the\n // transactionCreated cleanup below).\n this.localStorage.removeItem(\"transaction\");\n } catch (err) {\n logger.warn(\n new BeamError(\"Failed to attach selectionId to existing transaction via update endpoint\", { cause: err }),\n { transactionId: result.transactionId, selectionId: this.selectionId },\n );\n // Fail softly: effectiveResult stays = result, component renders as it does today\n }\n }\n\n this.transactionId = effectiveResult.transactionId;\n this.userId = effectiveResult.beamUserId;\n this.nonprofitId = effectiveResult.nonprofitId;\n // reportSettings is absent from the update endpoint's response, so this always\n // sources from the original postTransaction result, never effectiveResult.\n this.excludeDonationsForRecurringTransactions = Boolean(result.reportSettings?.excludeRecurringDonations);\n this.creationMethod = effectiveResult.creationMethod || \"\";\n this.orderProcessedAt = effectiveResult.timestamp;\n\n const isTransactionRedeemed = !!this.nonprofitId;\n this.activeWidget = isTransactionRedeemed ? \"impact-overview\" : \"redeem-transaction\";\n\n // Emit order created event only when order is registered with Beam for the first time\n if (result.transactionCreated) {\n const localStorageKeys = [\n \"transaction\",\n \"cart\",\n PROMO_LOCAL_STORAGE_KEY,\n LOCAL_STORAGE_KEYS.NONPROFIT,\n LOCAL_STORAGE_KEYS.NONPROFIT_SELECTED_AT,\n ];\n localStorageKeys.forEach((key) => {\n this.localStorage.removeItem(key);\n });\n const cookieConfigs = [\n { name: BEAM_CART_COOKIE_NAME, path: \"/\", domain: this.domain },\n { name: PROMO_CODES_COOKIE_NAME, path: \"/\", domain: this.domain },\n ];\n\n cookieConfigs.forEach((config) => deleteCookieValue(config));\n\n // Emit order created event only when order is registered with Beam for the first time\n dispatchEvent(\n new BeamOrderCreatedEvent({\n transactionId: result.transactionId,\n orderId: this.orderId,\n cartTotal: this.cartTotal,\n currencyCode: this.currencyCode,\n selectionId: this.selectionId ?? null,\n cartId: this.cartId,\n beamCartId: this.beamCartId,\n storeId: this.storeId ?? null,\n postalCode: this.postalCode ?? null,\n countryCode: this.countryCode ?? null,\n remoteSessionId: this.remoteSessionId ?? null,\n transactionNonprofitId: result.nonprofitId,\n orderProcessedAt: result.timestamp,\n }),\n );\n }\n return effectiveResult;\n };\n\n private transactionDataController = new AsyncController<typeof this.handlePostTransaction>(\n this,\n this.handlePostTransaction,\n );\n\n render() {\n const THIRTY_DAYS_IN_MS = 30 * 24 * 60 * 60 * 1000;\n const transactionIsLessThan30DaysOld = Date.now() - new Date(this.orderProcessedAt).getTime() < THIRTY_DAYS_IN_MS;\n\n if (this.transactionDataController.loading) {\n return \"\";\n }\n if (this.transactionDataController.error) {\n if (this.debug) {\n return _errorMessage({ error: this.transactionDataController.error });\n }\n return \"\";\n }\n if (this.excludeDonationsForRecurringTransactions && this.creationMethod === \"recurring\") {\n return html``;\n }\n if (this.activeWidget === \"redeem-transaction\" && transactionIsLessThan30DaysOld) {\n return html`\n <beam-redeem-transaction\n part=\"redeem-transaction\"\n baseUrl=\"${this.baseUrl}\"\n apiKey=\"${this.apiKey}\"\n storeId=\"${this.storeId}\"\n postalCode=\"${this.postalCode}\"\n countryCode=\"${this.countryCode}\"\n transactionId=\"${this.transactionId}\"\n cart=\"${JSON.stringify(this.cart)}\"\n lang=\"${this.lang}\"\n excludeDonationsForRecurringTransactions=\"${this.excludeDonationsForRecurringTransactions}\"\n ?draftConfig=\"${this.draftConfig}\"\n ?debug=\"${this.debug}\"\n @beamnonprofitselect=\"${(event: Event) => {\n if (!(event instanceof CustomEvent)) return; // TS guard\n const { selectedNonprofitId } = (event as BeamNonprofitSelectEvent).detail;\n this.nonprofitId = selectedNonprofitId ?? null;\n this.activeWidget = \"impact-overview\";\n }}\"\n ></beam-redeem-transaction>\n `;\n }\n if (this.activeWidget === \"impact-overview\") {\n return html`\n <beam-impact-overview\n part=\"impact-overview\"\n storeId=\"${this.storeId}\"\n baseUrl=\"${this.baseUrl}\"\n apiKey=\"${this.apiKey}\"\n userId=\"${this.userId}\"\n nonprofitId=\"${this.nonprofitId}\"\n lang=\"${this.lang}\"\n discountCodes=\"${JSON.stringify(this.discountCodes)}\"\n transactionId=\"${this.transactionId}\"\n ?draftConfig=\"${this.draftConfig}\"\n ?debug=\"${this.debug}\"\n ></beam-impact-overview>\n `;\n }\n return \"\";\n }\n\n static styles = [cssReset];\n}\n\ndefineCustomElement(BeamPostPurchase);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"beam-post-purchase\": BeamPostPurchase;\n }\n}\n","/**\n * @deprecated (v1.57.0) Shopify no longer supports customized post-purchase pages directly without Extensibility apps\n */\nimport \"../../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":["v","t","m","p","r","a","o","d","l","REQUIRED_DATA_PROPS","OPTIONAL_DATA_PROPS","BeamPostPurchase","LitElement","DEFAULT_BASE_URL","createScopedLocalStorage","manualPromoCodes","formattedPromosFromLocalStorage","formatStoreAndReturnPromoCodes","code","promoCookieData","getAllPromoCodesFromCookie","formattedPromosFromCookie","mapToUnvalidatedPromoCodes","formattedPromos","shouldSendPromos","isEmptyPromoData","remoteSessionId","getRemoteSession","getCookieValue","result","postTransaction","effectiveResult","updateResult","updateTransaction","err","logger","BeamError","isTransactionRedeemed","PROMO_LOCAL_STORAGE_KEY","LOCAL_STORAGE_KEYS","key","BEAM_CART_COOKIE_NAME","PROMO_CODES_COOKIE_NAME","config","deleteCookieValue","BeamOrderCreatedEvent","AsyncController","parseJsonStringArray","_changedProperties","previousPropertyValues","enforceConfig","MissingConfig","transactionIsLessThan30DaysOld","_errorMessage","html","event","selectedNonprofitId","cssReset","__decorateClass","property","state","defineCustomElement","showBeamOrderPageWidgets","parentSelector","apiKey","baseUrl","storeId","postalCode","discountCodes","countryCode","orderId","email","cartTotal","cart","promoCodes","htmlPromoCodes","currencyCode","domain","lang","debug","parentElement","waitForElement","cartId","beamLocalStorage","existingValue","widget"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{o as j,i as k,b as x}from"./lodash-CrMU6wKg.esm.js";import{Q as D,l as u,J as q,A as M,M as F,b as Q,N as V,U as X,B as H,W as Y,K as Z,t as $,O as tt,V as et,z as at,X as nt}from"./utils-C5hmbxa4.esm.js";import{B as R}from"./index-Dc4HgxdT.esm.js";import{O as B}from"./index-D9W31jYp.esm.js";const L=window.Shopify?.routes?.root||"/";let g=null,O=!0,A=!1;const it="cart";async function U(t,c=!0){if(g)return!1;const s=new AbortController;g=s;const{signal:n}=s;Q(),window.addEventListener(V.eventName,async()=>{A=!0},{signal:n}),window.addEventListener(X.eventName,async i=>{const a=i,o=/cart\/(add|change|update|clear)/,r=a.detail.type==="xhr"?a.detail.xhr.responseURL:a.detail.response.url,e=new URL(r);if(!o.test(e.pathname))return;const p=await S(t,n);n.aborted||!p.changed||B(t,p.cart)},{signal:n});let d,l;window.addEventListener(H.eventName,async i=>{const a=i;u.debug("[cart-page][BeamNonprofitSelectEvent]",a.detail);const{source:o,selectedNonprofitId:r,selectionId:e}=a.detail;if(o===Y.select_nonprofit){if(d===r&&l===e)return;const p=await _(t);await f({...p,selectedNonprofitId:r,selectionId:e}),l=e,d=r}},{signal:n}),window.addEventListener(Z.eventName,async i=>{const a=i;u.debug("[cart-page][BeamNonprofitSelectionRemovedEvent]",a.detail);const{newNonprofitId:o,selectionId:r}=a.detail;if(d===o&&l===r)return;const e=await _(t);await f({...e,selectedNonprofitId:null,selectionId:r}),l=r,d=o},{signal:n}),window.addEventListener($.eventName,async i=>{const a=i;if(u.debug("[cart-page][BeamCartCreatedEvent]",a.detail),window.statsig||c){const o=await _(t);await f(o)}},{signal:n}),window.addEventListener(tt.eventName,async i=>{const a=i;if(u.debug("[cart-page][BeamCartChangeEvent]",a.detail),window.statsig||c){const o=await _(t);await f(o)}},{signal:n});try{if(n.aborted)return!1;const i=await S(t,n);return!(n.aborted||(await B(t,i.cart,!0),n.aborted))}catch(i){throw g===s&&(s.abort(),g=null),i}}async function W(t,{clearStorage:c=!1}={}){const s=!!g;return s&&(g?.abort(),g=null,nt(),f.reset(),J.reset(),O=!0,A=!1),c&&et(t),s}async function T(t){const c=await _(t);await f(c)}async function _(t){let c,s;if(window.statsig)try{const a=window.statsig;typeof a?.getLayer("beam_trial_layer")?.get("show_beam")=="boolean"&&(c=a.getLayer("beam_trial_layer").get("show_beam",!1),s=a.getStableID())}catch{}const n=q(it,t),d=M(R,t),{chainId:l,storeId:i}=t;return{showBeam:c??void 0,remoteSessionId:s??void 0,beamCartId:d&&d!=="null"?d:void 0,cartId:n&&n!=="null"?n:void 0,chainId:l,storeId:i}}const z=T;async function S(t,c){const{token:s,total_price:n,item_count:d,currency:l,items:i,cart_level_discount_applications:a,attributes:o}=await v();let r=!1;const e=at(t),p=e.getItemJson("cart"),I=M(R,t),C={cartId:s,beamCartId:I,subtotal:n/100,itemCount:d,currencyCode:l,schema:{source:"generic"},content:{items:i.map(({sku:m,final_line_price:b,product_id:N,line_level_discount_allocations:E})=>{const y=m||String(N),h=b/100,G=E?.map(({discount_application:K})=>({code:K?.title,applicable:!0}));return{remoteProductIdentifier:y,localAmount:h,discounts:G}}),discounts:a.map(({title:m})=>({code:m,applicable:!0}))}};let w=null;try{o?.beam&&(w=JSON.parse(o.beam))}catch(m){u.error(m)}if(w&&O&&!A&&!c?.aborted){O=!1;const{nonprofit_id:m,selection_id:b}=w,N=e.getItem("nonprofit"),E=e.getItem("transaction"),y=m!==void 0&&String(m)!==N,h=b!=null&&String(b)!==E;(y||h)&&(y&&(e.setItem("nonprofit",String(m)),e.setItem("nonprofit_selected_at",new Date().toISOString())),h&&(e.setItem("transaction",String(b)),e.setItem("nonprofit_selected_at",new Date().toISOString())),window.dispatchEvent(new F({nonprofitId:m,nonprofitIdChanged:y,selectionId:b,selectionIdChanged:h})))}return k(C,{...p,beamCartId:p?.beamCartId})||(r=!0),{changed:r,cart:C}}const P=B,v=async function(){return await window.fetch(L+"cart.js",{method:"GET",headers:{"Content-Type":"application/json"}}).then(t=>t.json())},f=D(async function({selectedNonprofitId:t,selectionId:c,beamCartId:s,cartId:n,chainId:d,storeId:l,showBeam:i,remoteSessionId:a}){const{attributes:o}=await v(),r=o?.beam;let e={};try{r&&(e=JSON.parse(r))}catch(w){u.error(w)}const p=j({nonprofit_id:t,selection_id:c,beam_cart_id:s,shopify_cart_id:n,chain_id:d,store_id:l,show_beam:i,remote_session_id:a},x),I={...e,...p};t===null&&(I.nonprofit_id=void 0);const C={beam:JSON.stringify(I)};if(!k(I,e))try{await window.fetch(L+"cart/update.js",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({attributes:C})})}catch(w){u.error(w)}}),J=D(async function({selectedNonprofitId:t,selectionId:c,beamCartId:s,cartId:n,chainId:d,storeId:l}){let i,a;if(window.statsig)try{const e=window.statsig;typeof e?.getLayer("beam_trial_layer")?.get("show_beam")=="boolean"&&(i=e.getLayer("beam_trial_layer").get("show_beam",!1),a=e.getStableID())}catch{}const o=j({nonprofit_id:t,selection_id:c,beam_cart_id:s,shopify_cart_id:n,chain_id:d,store_id:l,show_beam:i,remote_session_id:a},x);t===null&&(o.nonprofit_id=void 0);const r={beam:JSON.stringify(o)};try{await window.fetch(L+"cart/update.js",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({attributes:r})})}catch(e){u.error(e)}});var ot=Object.freeze({__proto__:null,addBeamAttributesToCart:J,appendBeamAttributesToCart:f,appendStatsigToShopifyCartAttributes:z,appendToShopifyCartBeamAttribute:T,getBeamAttributesForCart:_,getCurrentCart:S,getShopifyCart:v,registerCartIntegration:U,trackCart:P,unregisterCartIntegration:W});export{J,S as L,v as T,W as a,U as e,f as g,ot as i,z as n,P as r,T as x,_ as y};
2
- //# sourceMappingURL=index-C20vHMzS.esm.js.map
1
+ import{o as j,i as k,b as x}from"./lodash-CrMU6wKg.esm.js";import{Q as D,l as u,J as q,A as M,M as F,b as Q,N as V,U as X,B as H,W as Y,K as Z,t as $,O as tt,V as et,z as at,X as nt}from"./utils-C5hmbxa4.esm.js";import{B as R}from"./index-CVHrQ1WC.esm.js";import{O as B}from"./index-Bt4Ob1Fi.esm.js";const L=window.Shopify?.routes?.root||"/";let g=null,O=!0,A=!1;const it="cart";async function U(t,c=!0){if(g)return!1;const s=new AbortController;g=s;const{signal:n}=s;Q(),window.addEventListener(V.eventName,async()=>{A=!0},{signal:n}),window.addEventListener(X.eventName,async i=>{const a=i,o=/cart\/(add|change|update|clear)/,r=a.detail.type==="xhr"?a.detail.xhr.responseURL:a.detail.response.url,e=new URL(r);if(!o.test(e.pathname))return;const p=await S(t,n);n.aborted||!p.changed||B(t,p.cart)},{signal:n});let d,l;window.addEventListener(H.eventName,async i=>{const a=i;u.debug("[cart-page][BeamNonprofitSelectEvent]",a.detail);const{source:o,selectedNonprofitId:r,selectionId:e}=a.detail;if(o===Y.select_nonprofit){if(d===r&&l===e)return;const p=await _(t);await f({...p,selectedNonprofitId:r,selectionId:e}),l=e,d=r}},{signal:n}),window.addEventListener(Z.eventName,async i=>{const a=i;u.debug("[cart-page][BeamNonprofitSelectionRemovedEvent]",a.detail);const{newNonprofitId:o,selectionId:r}=a.detail;if(d===o&&l===r)return;const e=await _(t);await f({...e,selectedNonprofitId:null,selectionId:r}),l=r,d=o},{signal:n}),window.addEventListener($.eventName,async i=>{const a=i;if(u.debug("[cart-page][BeamCartCreatedEvent]",a.detail),window.statsig||c){const o=await _(t);await f(o)}},{signal:n}),window.addEventListener(tt.eventName,async i=>{const a=i;if(u.debug("[cart-page][BeamCartChangeEvent]",a.detail),window.statsig||c){const o=await _(t);await f(o)}},{signal:n});try{if(n.aborted)return!1;const i=await S(t,n);return!(n.aborted||(await B(t,i.cart,!0),n.aborted))}catch(i){throw g===s&&(s.abort(),g=null),i}}async function W(t,{clearStorage:c=!1}={}){const s=!!g;return s&&(g?.abort(),g=null,nt(),f.reset(),J.reset(),O=!0,A=!1),c&&et(t),s}async function T(t){const c=await _(t);await f(c)}async function _(t){let c,s;if(window.statsig)try{const a=window.statsig;typeof a?.getLayer("beam_trial_layer")?.get("show_beam")=="boolean"&&(c=a.getLayer("beam_trial_layer").get("show_beam",!1),s=a.getStableID())}catch{}const n=q(it,t),d=M(R,t),{chainId:l,storeId:i}=t;return{showBeam:c??void 0,remoteSessionId:s??void 0,beamCartId:d&&d!=="null"?d:void 0,cartId:n&&n!=="null"?n:void 0,chainId:l,storeId:i}}const z=T;async function S(t,c){const{token:s,total_price:n,item_count:d,currency:l,items:i,cart_level_discount_applications:a,attributes:o}=await v();let r=!1;const e=at(t),p=e.getItemJson("cart"),I=M(R,t),C={cartId:s,beamCartId:I,subtotal:n/100,itemCount:d,currencyCode:l,schema:{source:"generic"},content:{items:i.map(({sku:m,final_line_price:b,product_id:N,line_level_discount_allocations:E})=>{const y=m||String(N),h=b/100,G=E?.map(({discount_application:K})=>({code:K?.title,applicable:!0}));return{remoteProductIdentifier:y,localAmount:h,discounts:G}}),discounts:a.map(({title:m})=>({code:m,applicable:!0}))}};let w=null;try{o?.beam&&(w=JSON.parse(o.beam))}catch(m){u.error(m)}if(w&&O&&!A&&!c?.aborted){O=!1;const{nonprofit_id:m,selection_id:b}=w,N=e.getItem("nonprofit"),E=e.getItem("transaction"),y=m!==void 0&&String(m)!==N,h=b!=null&&String(b)!==E;(y||h)&&(y&&(e.setItem("nonprofit",String(m)),e.setItem("nonprofit_selected_at",new Date().toISOString())),h&&(e.setItem("transaction",String(b)),e.setItem("nonprofit_selected_at",new Date().toISOString())),window.dispatchEvent(new F({nonprofitId:m,nonprofitIdChanged:y,selectionId:b,selectionIdChanged:h})))}return k(C,{...p,beamCartId:p?.beamCartId})||(r=!0),{changed:r,cart:C}}const P=B,v=async function(){return await window.fetch(L+"cart.js",{method:"GET",headers:{"Content-Type":"application/json"}}).then(t=>t.json())},f=D(async function({selectedNonprofitId:t,selectionId:c,beamCartId:s,cartId:n,chainId:d,storeId:l,showBeam:i,remoteSessionId:a}){const{attributes:o}=await v(),r=o?.beam;let e={};try{r&&(e=JSON.parse(r))}catch(w){u.error(w)}const p=j({nonprofit_id:t,selection_id:c,beam_cart_id:s,shopify_cart_id:n,chain_id:d,store_id:l,show_beam:i,remote_session_id:a},x),I={...e,...p};t===null&&(I.nonprofit_id=void 0);const C={beam:JSON.stringify(I)};if(!k(I,e))try{await window.fetch(L+"cart/update.js",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({attributes:C})})}catch(w){u.error(w)}}),J=D(async function({selectedNonprofitId:t,selectionId:c,beamCartId:s,cartId:n,chainId:d,storeId:l}){let i,a;if(window.statsig)try{const e=window.statsig;typeof e?.getLayer("beam_trial_layer")?.get("show_beam")=="boolean"&&(i=e.getLayer("beam_trial_layer").get("show_beam",!1),a=e.getStableID())}catch{}const o=j({nonprofit_id:t,selection_id:c,beam_cart_id:s,shopify_cart_id:n,chain_id:d,store_id:l,show_beam:i,remote_session_id:a},x);t===null&&(o.nonprofit_id=void 0);const r={beam:JSON.stringify(o)};try{await window.fetch(L+"cart/update.js",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({attributes:r})})}catch(e){u.error(e)}});var ot=Object.freeze({__proto__:null,addBeamAttributesToCart:J,appendBeamAttributesToCart:f,appendStatsigToShopifyCartAttributes:z,appendToShopifyCartBeamAttribute:T,getBeamAttributesForCart:_,getCurrentCart:S,getShopifyCart:v,registerCartIntegration:U,trackCart:P,unregisterCartIntegration:W});export{J,S as L,v as T,W as a,U as e,f as g,ot as i,z as n,P as r,T as x,_ as y};
2
+ //# sourceMappingURL=index-B7OkmoYI.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-C20vHMzS.esm.js","sources":["../../src/integrations/shopify/cart.ts"],"sourcesContent":["/* eslint-disable camelcase */\nimport isEqual from \"lodash-es/isEqual\";\nimport isUndefined from \"lodash-es/isUndefined\";\nimport omitBy from \"lodash-es/omitBy\";\nimport { clearBeamStorage, logger, memoizeLast } from \"../../utils\";\nimport { initNetworkListeners, teardownNetworkListeners } from \"../../utils/network-listeners\";\nimport {\n BeamCartChangeEvent,\n BeamCartCreatedEvent,\n BeamNetworkCallEvent,\n BeamNonprofitSelectEvent,\n BeamNonprofitSelectionRemovedEvent,\n BeamWidgetInitialNonprofitSyncCancelEvent,\n BeamWidgetInitialNonprofitSyncEvent,\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 cartIntegrationAbortController: AbortController | null = null; // Set when registration starts; aborting removes its listeners\n\nlet allowEmitInitialNonprofitSync = true; // Skip updating local storage if already run initially\nlet skipEmitInitialNonprofitSync = false; // Allow other processes to skip the nonprofit sync from cart attributes\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 (cartIntegrationAbortController) {\n return false; // Do nothing if already registered, or a registration attempt is already in progress\n }\n\n // All listeners below are registered with this signal so that\n // unregisterCartIntegration can remove them all with a single abort()\n const abortController = new AbortController();\n cartIntegrationAbortController = abortController;\n const { signal } = abortController;\n\n // logger.debug(\"[cart-page][registerCartIntegration] initializing network listeners\");\n // Set up event listeners for AJAX events (idempotent; re-enables dispatching if previously torn down)\n initNetworkListeners();\n\n /**\n * Allow another component to cancel the loading & setting\n * of the Shopify cart selection (like if a selection is made before we've gotten the previous values)\n */\n window.addEventListener(\n BeamWidgetInitialNonprofitSyncCancelEvent.eventName,\n async () => {\n // logger.debug(\"[cart-page][BeamWidgetInitialNonprofitSyncCancelEvent]\");\n skipEmitInitialNonprofitSync = true;\n },\n { signal },\n );\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(\n BeamNetworkCallEvent.eventName,\n 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, signal);\n // Recheck: unregister can't cancel an invocation already in flight\n if (signal.aborted || !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 { signal },\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(\n BeamNonprofitSelectEvent.eventName,\n 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 { signal },\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(\n BeamNonprofitSelectionRemovedEvent.eventName,\n 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 { signal },\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(\n BeamCartCreatedEvent.eventName,\n 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 { signal },\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(\n BeamCartChangeEvent.eventName,\n 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 { signal },\n );\n\n try {\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 if (signal.aborted) {\n return false; // unregistered before we even started\n }\n const currentCart = await getCurrentCart(config, signal);\n if (signal.aborted) {\n return false; // unregistered while the GET was in flight\n }\n // logger.debug(\"[cart-page][registerCartIntegration] initial cart fetch result\", currentCart);\n await updateCart(config, currentCart.cart, true);\n if (signal.aborted) {\n return false; // unregistered while updateCart was in flight\n }\n\n return true;\n } catch (err) {\n // Undo on failure so a later call can retry instead of being stuck\n if (cartIntegrationAbortController === abortController) {\n abortController.abort();\n cartIntegrationAbortController = null;\n }\n throw err;\n }\n}\n\n/**\n * @main unregisterCartIntegration - tear down listeners set up by registerCartIntegration.\n * Pass { clearStorage: true } to also wipe Beam's localStorage/cookies in the same call\n * (clearBeamStorage from src/utils, which is also callable on its own — for cases that want\n * storage cleared without touching listeners, or independently of this integration entirely).\n * @return {boolean} true if this page load's listeners were torn down, false if\n * registerCartIntegration never ran this session (storage still clears if requested, either way)\n */\nasync function unregisterCartIntegration(\n config: BeamShopifyCartIntegrationConfig,\n { clearStorage = false }: { clearStorage?: boolean } = {},\n) {\n // Also covers an unregister call that arrives mid-registration, before this is set true\n const wasRegisteredThisSession = Boolean(cartIntegrationAbortController);\n\n if (wasRegisteredThisSession) {\n // 1. Remove ALL event listeners registered with this controller's signal\n cartIntegrationAbortController?.abort();\n cartIntegrationAbortController = null;\n\n // 2. Stop fetch/XHR hooks from dispatching (patches stay installed, just inert)\n teardownNetworkListeners();\n\n // 3. Drop memoized state so nothing stale survives a re-register\n appendBeamAttributesToCart.reset();\n addBeamAttributesToCart.reset();\n\n // 4. Reset module flags so a future opt-in can re-register cleanly\n allowEmitInitialNonprofitSync = true;\n skipEmitInitialNonprofitSync = false;\n }\n\n // 5. Optionally clear storage too. Runs regardless of wasRegisteredThisSession — that state\n // is persisted browser-side, not tied to whether a registration happened this page load.\n if (clearStorage) {\n clearBeamStorage(config);\n }\n\n return wasRegisteredThisSession;\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(\n config: BeamShopifyCartIntegrationConfig,\n signal?: AbortSignal,\n): 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 attributes,\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 let beamAttr: ShopifyCartBeamAttribute | null = null;\n\n try {\n if (attributes?.beam) {\n beamAttr = JSON.parse(attributes.beam);\n }\n } catch (err) {\n logger.error(err);\n }\n\n /**\n * Only attempt to emit BeamWidgetInitialNonprofitSyncEvent once\n * as soon as we see a \"beam\" attribute for the first time.\n * allowEmitInitialNonprofitSync is local to this file to keep this\n * from running more than once.\n * skipEmitInitialNonprofitSync is settable by an event listener\n * so other processes can stop this sync from happening.\n * signal is checked too, so a call from a since-torn-down registration doesn't consume\n * the one-shot flag on its behalf.\n */\n if (beamAttr && allowEmitInitialNonprofitSync && !skipEmitInitialNonprofitSync && !signal?.aborted) {\n allowEmitInitialNonprofitSync = false;\n\n const { nonprofit_id, selection_id } = beamAttr;\n\n const storedNonprofit = localStorage.getItem(\"nonprofit\");\n const storedSelection = localStorage.getItem(\"transaction\");\n\n const nonprofitChanged = nonprofit_id !== undefined && String(nonprofit_id) !== storedNonprofit;\n const selectionChanged = selection_id != null && String(selection_id) !== storedSelection;\n\n // Only dispatch if something changed, and if it's not skipped\n if (nonprofitChanged || selectionChanged) {\n if (nonprofitChanged) {\n localStorage.setItem(\"nonprofit\", String(nonprofit_id));\n localStorage.setItem(\"nonprofit_selected_at\", new Date().toISOString());\n }\n\n if (selectionChanged) {\n localStorage.setItem(\"transaction\", String(selection_id));\n localStorage.setItem(\"nonprofit_selected_at\", new Date().toISOString());\n }\n\n window.dispatchEvent(\n new BeamWidgetInitialNonprofitSyncEvent({\n nonprofitId: nonprofit_id,\n nonprofitIdChanged: nonprofitChanged,\n selectionId: selection_id,\n selectionIdChanged: selectionChanged,\n }),\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 statsig?: any; // attached by Statsig CDN script\n Shopify?: any;\n }\n}\n\nexport {\n trackCart,\n getCurrentCart,\n addBeamAttributesToCart,\n unregisterCartIntegration,\n appendStatsigToShopifyCartAttributes,\n appendToShopifyCartBeamAttribute,\n registerCartIntegration,\n appendBeamAttributesToCart,\n getShopifyCart,\n getBeamAttributesForCart,\n};\n"],"names":["SHOPIFY_BASE_URL","cartIntegrationAbortController","allowEmitInitialNonprofitSync","skipEmitInitialNonprofitSync","SHOPIFY_CART_COOKIE_NAME","registerCartIntegration","config","autoUpdateShopifyCartAttributes","abortController","signal","initNetworkListeners","BeamWidgetInitialNonprofitSyncCancelEvent","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","err","unregisterCartIntegration","clearStorage","wasRegisteredThisSession","teardownNetworkListeners","addBeamAttributesToCart","clearBeamStorage","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","attributes","getShopifyCart","changed","localStorage","createScopedLocalStorage","cachedCart","cart","sku","final_line_price","product_id","line_level_discount_allocations","remoteProductIdentifier","localAmount","discounts","discount_application","title","beamAttr","nonprofit_id","selection_id","storedNonprofit","storedSelection","nonprofitChanged","selectionChanged","BeamWidgetInitialNonprofitSyncEvent","isEqual","trackCart","res","memoizeLast","existingBeamCartAttrString","existingBeamCartAttr","newBeamAttrs","omitBy","isUndefined","appendedBeamAttributes","beamCartAttrs","allBeamAttributes"],"mappings":"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"}
1
+ {"version":3,"file":"index-B7OkmoYI.esm.js","sources":["../../src/integrations/shopify/cart.ts"],"sourcesContent":["/* eslint-disable camelcase */\nimport isEqual from \"lodash-es/isEqual\";\nimport isUndefined from \"lodash-es/isUndefined\";\nimport omitBy from \"lodash-es/omitBy\";\nimport { clearBeamStorage, logger, memoizeLast } from \"../../utils\";\nimport { initNetworkListeners, teardownNetworkListeners } from \"../../utils/network-listeners\";\nimport {\n BeamCartChangeEvent,\n BeamCartCreatedEvent,\n BeamNetworkCallEvent,\n BeamNonprofitSelectEvent,\n BeamNonprofitSelectionRemovedEvent,\n BeamWidgetInitialNonprofitSyncCancelEvent,\n BeamWidgetInitialNonprofitSyncEvent,\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 cartIntegrationAbortController: AbortController | null = null; // Set when registration starts; aborting removes its listeners\n\nlet allowEmitInitialNonprofitSync = true; // Skip updating local storage if already run initially\nlet skipEmitInitialNonprofitSync = false; // Allow other processes to skip the nonprofit sync from cart attributes\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 (cartIntegrationAbortController) {\n return false; // Do nothing if already registered, or a registration attempt is already in progress\n }\n\n // All listeners below are registered with this signal so that\n // unregisterCartIntegration can remove them all with a single abort()\n const abortController = new AbortController();\n cartIntegrationAbortController = abortController;\n const { signal } = abortController;\n\n // logger.debug(\"[cart-page][registerCartIntegration] initializing network listeners\");\n // Set up event listeners for AJAX events (idempotent; re-enables dispatching if previously torn down)\n initNetworkListeners();\n\n /**\n * Allow another component to cancel the loading & setting\n * of the Shopify cart selection (like if a selection is made before we've gotten the previous values)\n */\n window.addEventListener(\n BeamWidgetInitialNonprofitSyncCancelEvent.eventName,\n async () => {\n // logger.debug(\"[cart-page][BeamWidgetInitialNonprofitSyncCancelEvent]\");\n skipEmitInitialNonprofitSync = true;\n },\n { signal },\n );\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(\n BeamNetworkCallEvent.eventName,\n 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, signal);\n // Recheck: unregister can't cancel an invocation already in flight\n if (signal.aborted || !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 { signal },\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(\n BeamNonprofitSelectEvent.eventName,\n 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 { signal },\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(\n BeamNonprofitSelectionRemovedEvent.eventName,\n 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 { signal },\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(\n BeamCartCreatedEvent.eventName,\n 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 { signal },\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(\n BeamCartChangeEvent.eventName,\n 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 { signal },\n );\n\n try {\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 if (signal.aborted) {\n return false; // unregistered before we even started\n }\n const currentCart = await getCurrentCart(config, signal);\n if (signal.aborted) {\n return false; // unregistered while the GET was in flight\n }\n // logger.debug(\"[cart-page][registerCartIntegration] initial cart fetch result\", currentCart);\n await updateCart(config, currentCart.cart, true);\n if (signal.aborted) {\n return false; // unregistered while updateCart was in flight\n }\n\n return true;\n } catch (err) {\n // Undo on failure so a later call can retry instead of being stuck\n if (cartIntegrationAbortController === abortController) {\n abortController.abort();\n cartIntegrationAbortController = null;\n }\n throw err;\n }\n}\n\n/**\n * @main unregisterCartIntegration - tear down listeners set up by registerCartIntegration.\n * Pass { clearStorage: true } to also wipe Beam's localStorage/cookies in the same call\n * (clearBeamStorage from src/utils, which is also callable on its own — for cases that want\n * storage cleared without touching listeners, or independently of this integration entirely).\n * @return {boolean} true if this page load's listeners were torn down, false if\n * registerCartIntegration never ran this session (storage still clears if requested, either way)\n */\nasync function unregisterCartIntegration(\n config: BeamShopifyCartIntegrationConfig,\n { clearStorage = false }: { clearStorage?: boolean } = {},\n) {\n // Also covers an unregister call that arrives mid-registration, before this is set true\n const wasRegisteredThisSession = Boolean(cartIntegrationAbortController);\n\n if (wasRegisteredThisSession) {\n // 1. Remove ALL event listeners registered with this controller's signal\n cartIntegrationAbortController?.abort();\n cartIntegrationAbortController = null;\n\n // 2. Stop fetch/XHR hooks from dispatching (patches stay installed, just inert)\n teardownNetworkListeners();\n\n // 3. Drop memoized state so nothing stale survives a re-register\n appendBeamAttributesToCart.reset();\n addBeamAttributesToCart.reset();\n\n // 4. Reset module flags so a future opt-in can re-register cleanly\n allowEmitInitialNonprofitSync = true;\n skipEmitInitialNonprofitSync = false;\n }\n\n // 5. Optionally clear storage too. Runs regardless of wasRegisteredThisSession — that state\n // is persisted browser-side, not tied to whether a registration happened this page load.\n if (clearStorage) {\n clearBeamStorage(config);\n }\n\n return wasRegisteredThisSession;\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(\n config: BeamShopifyCartIntegrationConfig,\n signal?: AbortSignal,\n): 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 attributes,\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 let beamAttr: ShopifyCartBeamAttribute | null = null;\n\n try {\n if (attributes?.beam) {\n beamAttr = JSON.parse(attributes.beam);\n }\n } catch (err) {\n logger.error(err);\n }\n\n /**\n * Only attempt to emit BeamWidgetInitialNonprofitSyncEvent once\n * as soon as we see a \"beam\" attribute for the first time.\n * allowEmitInitialNonprofitSync is local to this file to keep this\n * from running more than once.\n * skipEmitInitialNonprofitSync is settable by an event listener\n * so other processes can stop this sync from happening.\n * signal is checked too, so a call from a since-torn-down registration doesn't consume\n * the one-shot flag on its behalf.\n */\n if (beamAttr && allowEmitInitialNonprofitSync && !skipEmitInitialNonprofitSync && !signal?.aborted) {\n allowEmitInitialNonprofitSync = false;\n\n const { nonprofit_id, selection_id } = beamAttr;\n\n const storedNonprofit = localStorage.getItem(\"nonprofit\");\n const storedSelection = localStorage.getItem(\"transaction\");\n\n const nonprofitChanged = nonprofit_id !== undefined && String(nonprofit_id) !== storedNonprofit;\n const selectionChanged = selection_id != null && String(selection_id) !== storedSelection;\n\n // Only dispatch if something changed, and if it's not skipped\n if (nonprofitChanged || selectionChanged) {\n if (nonprofitChanged) {\n localStorage.setItem(\"nonprofit\", String(nonprofit_id));\n localStorage.setItem(\"nonprofit_selected_at\", new Date().toISOString());\n }\n\n if (selectionChanged) {\n localStorage.setItem(\"transaction\", String(selection_id));\n localStorage.setItem(\"nonprofit_selected_at\", new Date().toISOString());\n }\n\n window.dispatchEvent(\n new BeamWidgetInitialNonprofitSyncEvent({\n nonprofitId: nonprofit_id,\n nonprofitIdChanged: nonprofitChanged,\n selectionId: selection_id,\n selectionIdChanged: selectionChanged,\n }),\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 statsig?: any; // attached by Statsig CDN script\n Shopify?: any;\n }\n}\n\nexport {\n trackCart,\n getCurrentCart,\n addBeamAttributesToCart,\n unregisterCartIntegration,\n appendStatsigToShopifyCartAttributes,\n appendToShopifyCartBeamAttribute,\n registerCartIntegration,\n appendBeamAttributesToCart,\n getShopifyCart,\n getBeamAttributesForCart,\n};\n"],"names":["SHOPIFY_BASE_URL","cartIntegrationAbortController","allowEmitInitialNonprofitSync","skipEmitInitialNonprofitSync","SHOPIFY_CART_COOKIE_NAME","registerCartIntegration","config","autoUpdateShopifyCartAttributes","abortController","signal","initNetworkListeners","BeamWidgetInitialNonprofitSyncCancelEvent","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","err","unregisterCartIntegration","clearStorage","wasRegisteredThisSession","teardownNetworkListeners","addBeamAttributesToCart","clearBeamStorage","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","attributes","getShopifyCart","changed","localStorage","createScopedLocalStorage","cachedCart","cart","sku","final_line_price","product_id","line_level_discount_allocations","remoteProductIdentifier","localAmount","discounts","discount_application","title","beamAttr","nonprofit_id","selection_id","storedNonprofit","storedSelection","nonprofitChanged","selectionChanged","BeamWidgetInitialNonprofitSyncEvent","isEqual","trackCart","res","memoizeLast","existingBeamCartAttrString","existingBeamCartAttr","newBeamAttrs","omitBy","isUndefined","appendedBeamAttributes","beamCartAttrs","allBeamAttributes"],"mappings":"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"}