@replohq/sdk 1.7.2 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (250) hide show
  1. package/_vendor/replo-utils/lib/string.d.ts +0 -2
  2. package/_vendor/schemas/errors.d.ts +0 -3
  3. package/_vendor/schemas/loaderKeys.mjs +0 -1
  4. package/_vendor/schemas/money.d.ts +1 -1
  5. package/_vendor/schemas/money.mjs +0 -6
  6. package/_vendor/schemas/routing/rules.mjs +0 -1
  7. package/analytics/analytics-provider.js +0 -1
  8. package/analytics/analytics-sink.js +0 -1
  9. package/analytics/get-analytics-sinks.js +0 -1
  10. package/analytics/hooks/use-collection-viewed-analytics.d.ts +19 -0
  11. package/analytics/hooks/use-collection-viewed-analytics.js +26 -0
  12. package/analytics/hooks/use-product-viewed-analytics.js +0 -1
  13. package/analytics/replo-first-party-pixel.js +0 -1
  14. package/analytics/replo-pixel-script.js +0 -1
  15. package/analytics/sinks/converge-event-mapper.js +0 -1
  16. package/analytics/sinks/converge-sink.js +0 -1
  17. package/analytics/sinks/elevar-sink.js +1 -4
  18. package/analytics/sinks/ga4-sink.js +23 -5
  19. package/analytics/sinks/meta-sink.js +0 -4
  20. package/analytics/sinks/northbeam-sink.js +0 -1
  21. package/analytics/sinks/pinterest-sink.js +19 -5
  22. package/analytics/sinks/reddit-sink.js +16 -5
  23. package/analytics/sinks/replo-sink.js +0 -2
  24. package/analytics/sinks/snapchat-sink.js +0 -4
  25. package/analytics/sinks/tiktok-sink.js +18 -5
  26. package/analytics/sinks/window-sink.js +0 -3
  27. package/analytics/utils/analytics-products.d.ts +36 -0
  28. package/analytics/utils/analytics-products.js +57 -0
  29. package/analytics/utils/analytics-utils.js +0 -1
  30. package/analytics/utils/collection-analytics.d.ts +44 -0
  31. package/analytics/utils/collection-analytics.js +41 -0
  32. package/analytics/utils/navigation-tracker.js +0 -1
  33. package/analytics/utils/shopify-funnel-gate.js +0 -1
  34. package/cart/buy-now-action.js +0 -3
  35. package/cart/cart-actions.js +0 -1
  36. package/cart/cart-loader.js +0 -1
  37. package/cart/cart-provider.js +1 -2
  38. package/cart/cart-schema.js +0 -1
  39. package/cart/cart-types.js +0 -1
  40. package/cart/gateways/cart-constants.js +0 -2
  41. package/cart/gateways/cart-gateway.js +0 -1
  42. package/cart/gateways/cookie-cart-gateway.js +0 -5
  43. package/cart/gateways/default-cart-gateway.js +0 -1
  44. package/cart/gateways/resolver-cart-gateway.js +0 -5
  45. package/cart/gateways/stripe-cart-gateway.js +0 -1
  46. package/cart/hooks/use-add-to-cart.js +0 -4
  47. package/cart/hooks/use-buy-now.js +0 -1
  48. package/cart/return-urls.js +0 -1
  49. package/cart/storefront-urls.js +0 -1
  50. package/cart/utils/cart-adjustments.js +0 -1
  51. package/cart/utils/cart-analytics.js +0 -1
  52. package/cart/utils/cart-error.js +0 -1
  53. package/cart/utils/cart-utils.js +0 -1
  54. package/cart/utils/cookie-cart-persistence.js +0 -1
  55. package/cart/utils/variant-to-cart-line.js +0 -6
  56. package/chunk-7OPH5UFQ.mjs +0 -1
  57. package/chunk-AL3F36PH.mjs +5 -127
  58. package/chunk-EUQVEPSD.mjs +0 -1
  59. package/chunk-GV5FY7ZZ.mjs +0 -11
  60. package/chunk-UJCSKKID.mjs +0 -4
  61. package/chunk-VKO7P3ED.mjs +0 -2
  62. package/chunk-VPEVERWE.mjs +0 -1
  63. package/chunk-YJQVNUW7.mjs +0 -16
  64. package/consent/consent-action.js +0 -1
  65. package/consent/consent-actions.js +0 -1
  66. package/consent/consent-platform.js +0 -3
  67. package/consent/consent-store.js +0 -5
  68. package/consent/cookie.js +0 -1
  69. package/consent/inject-script-descriptors.js +0 -1
  70. package/consent/replo-scripts.js +0 -1
  71. package/consent/script-registration-store.js +0 -2
  72. package/consent/script-snippets.js +0 -7
  73. package/consent/types.js +0 -1
  74. package/consent/window-api.js +0 -1
  75. package/content.js +0 -1
  76. package/env.js +0 -1
  77. package/gateways/canopy-api.js +0 -10
  78. package/hooks/use-client-value.d.ts +1 -1
  79. package/hooks/use-client-value.js +0 -1
  80. package/hooks/use-formatted-price.js +0 -1
  81. package/lib/buildMetadata.js +3 -3
  82. package/lib/canopy-error.js +0 -1
  83. package/lib/external-navigation.d.ts +1 -1
  84. package/lib/external-navigation.js +0 -1
  85. package/lib/get-query-client.js +0 -1
  86. package/lib/integration-utils.js +0 -1
  87. package/lib/shopify-utils.js +0 -1
  88. package/lib/url-utils.js +0 -1
  89. package/loaders/collection-loader-args.js +0 -1
  90. package/loaders/collection-loader.js +0 -1
  91. package/loaders/collection-products-loader-args.js +0 -1
  92. package/loaders/collection-products-loader.js +0 -1
  93. package/loaders/contentful-entries-loader.js +0 -1
  94. package/loaders/contentful-entry-loader.js +0 -1
  95. package/loaders/invoke-loader-action.js +0 -1
  96. package/loaders/invoke-loader-server.js +0 -1
  97. package/loaders/invoke-loader.js +0 -1
  98. package/loaders/judgeme-review-aggregate-loader.js +0 -1
  99. package/loaders/judgeme-reviews-loader.js +0 -1
  100. package/loaders/levanta-product-loader.js +0 -1
  101. package/loaders/loader-error-boundary.d.ts +11 -2
  102. package/loaders/loader-error-boundary.js +52 -9
  103. package/loaders/loader-error-details.d.ts +2 -0
  104. package/loaders/loader-error-details.js +7 -0
  105. package/loaders/loader-keys.js +0 -1
  106. package/loaders/loader-schemas.js +0 -4
  107. package/loaders/loox-review-aggregate-loader.js +0 -1
  108. package/loaders/loox-reviews-loader.js +0 -1
  109. package/loaders/metaobject-loader.js +0 -1
  110. package/loaders/metaobjects-loader.js +0 -1
  111. package/loaders/okendo-review-aggregate-loader.js +0 -1
  112. package/loaders/okendo-reviews-loader.js +0 -1
  113. package/loaders/prefetch-loaders.js +0 -1
  114. package/loaders/preview-placeholder.js +0 -5
  115. package/loaders/product-loader-args.js +0 -1
  116. package/loaders/product-loader.js +0 -1
  117. package/loaders/rebuy-recommendations-loader.js +0 -1
  118. package/loaders/reviews-io-review-aggregate-loader.js +0 -1
  119. package/loaders/reviews-io-reviews-loader.js +0 -1
  120. package/loaders/smile-earning-rules-loader.js +0 -1
  121. package/loaders/smile-rewards-loader.js +0 -1
  122. package/loaders/smile-vip-tiers-loader.js +0 -1
  123. package/loaders/statsig-experiment-loader.js +0 -1
  124. package/loaders/yotpo-review-aggregate-loader.js +0 -1
  125. package/loaders/yotpo-reviews-loader.js +0 -1
  126. package/money.js +0 -1
  127. package/next/config.js +0 -18
  128. package/next/image-loader.js +0 -1
  129. package/next/open-next.js +0 -1
  130. package/orders/order-status-schema.js +0 -4
  131. package/orders/order-status.js +0 -3
  132. package/package.json +8 -4
  133. package/providers/query-provider.js +0 -1
  134. package/providers/replo-provider.js +4 -3
  135. package/routing/evaluate.js +0 -1
  136. package/routing/geo.js +0 -1
  137. package/routing/locale.js +0 -1
  138. package/routing/rules.js +0 -1
  139. package/analytics/analytics-provider.js.map +0 -7
  140. package/analytics/analytics-sink.js.map +0 -7
  141. package/analytics/get-analytics-sinks.js.map +0 -7
  142. package/analytics/hooks/use-product-viewed-analytics.js.map +0 -7
  143. package/analytics/replo-first-party-pixel.js.map +0 -7
  144. package/analytics/replo-pixel-script.js.map +0 -7
  145. package/analytics/sinks/converge-event-mapper.js.map +0 -7
  146. package/analytics/sinks/converge-sink.js.map +0 -7
  147. package/analytics/sinks/elevar-sink.js.map +0 -7
  148. package/analytics/sinks/ga4-sink.js.map +0 -7
  149. package/analytics/sinks/meta-sink.js.map +0 -7
  150. package/analytics/sinks/northbeam-sink.js.map +0 -7
  151. package/analytics/sinks/pinterest-sink.js.map +0 -7
  152. package/analytics/sinks/reddit-sink.js.map +0 -7
  153. package/analytics/sinks/replo-sink.js.map +0 -7
  154. package/analytics/sinks/snapchat-sink.js.map +0 -7
  155. package/analytics/sinks/tiktok-sink.js.map +0 -7
  156. package/analytics/sinks/window-sink.js.map +0 -7
  157. package/analytics/utils/analytics-utils.js.map +0 -7
  158. package/analytics/utils/navigation-tracker.js.map +0 -7
  159. package/analytics/utils/shopify-funnel-gate.js.map +0 -7
  160. package/cart/buy-now-action.js.map +0 -7
  161. package/cart/cart-actions.js.map +0 -7
  162. package/cart/cart-loader.js.map +0 -7
  163. package/cart/cart-provider.js.map +0 -7
  164. package/cart/cart-schema.js.map +0 -7
  165. package/cart/cart-types.js.map +0 -7
  166. package/cart/gateways/cart-constants.js.map +0 -7
  167. package/cart/gateways/cart-gateway.js.map +0 -7
  168. package/cart/gateways/cookie-cart-gateway.js.map +0 -7
  169. package/cart/gateways/default-cart-gateway.js.map +0 -7
  170. package/cart/gateways/resolver-cart-gateway.js.map +0 -7
  171. package/cart/gateways/stripe-cart-gateway.js.map +0 -7
  172. package/cart/hooks/use-add-to-cart.js.map +0 -7
  173. package/cart/hooks/use-buy-now.js.map +0 -7
  174. package/cart/return-urls.js.map +0 -7
  175. package/cart/storefront-urls.js.map +0 -7
  176. package/cart/utils/cart-adjustments.js.map +0 -7
  177. package/cart/utils/cart-analytics.js.map +0 -7
  178. package/cart/utils/cart-error.js.map +0 -7
  179. package/cart/utils/cart-utils.js.map +0 -7
  180. package/cart/utils/cookie-cart-persistence.js.map +0 -7
  181. package/cart/utils/variant-to-cart-line.js.map +0 -7
  182. package/consent/consent-action.js.map +0 -7
  183. package/consent/consent-actions.js.map +0 -7
  184. package/consent/consent-platform.js.map +0 -7
  185. package/consent/consent-store.js.map +0 -7
  186. package/consent/cookie.js.map +0 -7
  187. package/consent/inject-script-descriptors.js.map +0 -7
  188. package/consent/replo-scripts.js.map +0 -7
  189. package/consent/script-registration-store.js.map +0 -7
  190. package/consent/script-snippets.js.map +0 -7
  191. package/consent/types.js.map +0 -7
  192. package/consent/window-api.js.map +0 -7
  193. package/content.js.map +0 -7
  194. package/env.js.map +0 -7
  195. package/gateways/canopy-api.js.map +0 -7
  196. package/hooks/use-client-value.js.map +0 -7
  197. package/hooks/use-formatted-price.js.map +0 -7
  198. package/lib/buildMetadata.js.map +0 -7
  199. package/lib/canopy-error.js.map +0 -7
  200. package/lib/external-navigation.js.map +0 -7
  201. package/lib/get-query-client.js.map +0 -7
  202. package/lib/integration-utils.js.map +0 -7
  203. package/lib/shopify-utils.js.map +0 -7
  204. package/lib/url-utils.js.map +0 -7
  205. package/loaders/collection-loader-args.js.map +0 -7
  206. package/loaders/collection-loader.js.map +0 -7
  207. package/loaders/collection-products-loader-args.js.map +0 -7
  208. package/loaders/collection-products-loader.js.map +0 -7
  209. package/loaders/contentful-entries-loader.js.map +0 -7
  210. package/loaders/contentful-entry-loader.js.map +0 -7
  211. package/loaders/invoke-loader-action.js.map +0 -7
  212. package/loaders/invoke-loader-server.js.map +0 -7
  213. package/loaders/invoke-loader.js.map +0 -7
  214. package/loaders/judgeme-review-aggregate-loader.js.map +0 -7
  215. package/loaders/judgeme-reviews-loader.js.map +0 -7
  216. package/loaders/levanta-product-loader.js.map +0 -7
  217. package/loaders/loader-error-boundary.js.map +0 -7
  218. package/loaders/loader-keys.js.map +0 -7
  219. package/loaders/loader-schemas.js.map +0 -7
  220. package/loaders/loox-review-aggregate-loader.js.map +0 -7
  221. package/loaders/loox-reviews-loader.js.map +0 -7
  222. package/loaders/metaobject-loader.js.map +0 -7
  223. package/loaders/metaobjects-loader.js.map +0 -7
  224. package/loaders/okendo-review-aggregate-loader.js.map +0 -7
  225. package/loaders/okendo-reviews-loader.js.map +0 -7
  226. package/loaders/prefetch-loaders.js.map +0 -7
  227. package/loaders/preview-placeholder.js.map +0 -7
  228. package/loaders/product-loader-args.js.map +0 -7
  229. package/loaders/product-loader.js.map +0 -7
  230. package/loaders/rebuy-recommendations-loader.js.map +0 -7
  231. package/loaders/reviews-io-review-aggregate-loader.js.map +0 -7
  232. package/loaders/reviews-io-reviews-loader.js.map +0 -7
  233. package/loaders/smile-earning-rules-loader.js.map +0 -7
  234. package/loaders/smile-rewards-loader.js.map +0 -7
  235. package/loaders/smile-vip-tiers-loader.js.map +0 -7
  236. package/loaders/statsig-experiment-loader.js.map +0 -7
  237. package/loaders/yotpo-review-aggregate-loader.js.map +0 -7
  238. package/loaders/yotpo-reviews-loader.js.map +0 -7
  239. package/money.js.map +0 -7
  240. package/next/config.js.map +0 -7
  241. package/next/image-loader.js.map +0 -7
  242. package/next/open-next.js.map +0 -7
  243. package/orders/order-status-schema.js.map +0 -7
  244. package/orders/order-status.js.map +0 -7
  245. package/providers/query-provider.js.map +0 -7
  246. package/providers/replo-provider.js.map +0 -7
  247. package/routing/evaluate.js.map +0 -7
  248. package/routing/geo.js.map +0 -7
  249. package/routing/locale.js.map +0 -7
  250. package/routing/rules.js.map +0 -7
@@ -4,8 +4,6 @@ export declare function metafieldContainsHtml(metafieldValue: string): boolean;
4
4
  export declare function capitalizeFirstLetter(inputString: string): string;
5
5
  /**
6
6
  * Get url without query params.
7
- *
8
- * @author Kurt 2024-10-14
9
7
  */
10
8
  export declare const getUrlWithoutQueryParams: (url: string) => string | undefined;
11
9
  /**
@@ -186,9 +186,6 @@ export type ErrorDetails = {
186
186
  * Map of error keys to custom user-facing details. Should ONLY be used
187
187
  * in cases where we want to override the default behavior of ErrorUserFacingDetails
188
188
  * from the backend.
189
- *
190
- * TODO (Noah, 2024-01-15): Clean up these custom configs, all of them
191
- * are only used by Django (and 'base' can be moved directly into the reducer function)
192
189
  */
193
190
  export declare const CUSTOM_ERROR_KEY_TO_PROPS: {
194
191
  "shopifyArticle.failedToPublish": () => {
@@ -1,6 +1,5 @@
1
1
  import '../../chunk-UJCSKKID.mjs';
2
2
 
3
- // loaders/loader-keys.ts
4
3
  var DATA_LOADER_KEYS = {
5
4
  SHOPIFY_PRODUCT: "shopify_storefront.product",
6
5
  SHOPIFY_COLLECTION: "shopify_storefront.collection",
@@ -15,7 +15,7 @@ export declare function fromMajorUnitsToMinorUnits({ amount, currencyCode, }: {
15
15
  currencyCode: string;
16
16
  }): number;
17
17
  /**
18
- * NOTE (Max, 2026-08-03): safe companion to fromMajorUnitsToMinorUnits for
18
+ * safe companion to fromMajorUnitsToMinorUnits for
19
19
  * possibly-blank or user/CSV/provider-entered decimal strings — returns null
20
20
  * for blank or non-numeric input instead of throwing. Callers with a
21
21
  * source-specific cleaning or validation policy sanitize first, then convert
@@ -4,7 +4,6 @@ import '../../chunk-GV5FY7ZZ.mjs';
4
4
  import { __commonJS, __toESM } from '../../chunk-UJCSKKID.mjs';
5
5
  import { z } from 'zod';
6
6
 
7
- // ../../node_modules/.pnpm/first-match@0.0.1/node_modules/first-match/index.js
8
7
  var require_first_match = __commonJS({
9
8
  "../../node_modules/.pnpm/first-match@0.0.1/node_modules/first-match/index.js"(exports, module) {
10
9
  function truthy(d) {
@@ -20,7 +19,6 @@ var require_first_match = __commonJS({
20
19
  }
21
20
  });
22
21
 
23
- // ../../node_modules/.pnpm/nub@0.0.0/node_modules/nub/index.js
24
22
  var require_nub = __commonJS({
25
23
  "../../node_modules/.pnpm/nub@0.0.0/node_modules/nub/index.js"(exports, module) {
26
24
  var nub = module.exports = function(xs, cmp) {
@@ -75,7 +73,6 @@ var require_nub = __commonJS({
75
73
  }
76
74
  });
77
75
 
78
- // ../../node_modules/.pnpm/currency-codes@2.2.0/node_modules/currency-codes/data.js
79
76
  var require_data = __commonJS({
80
77
  "../../node_modules/.pnpm/currency-codes@2.2.0/node_modules/currency-codes/data.js"(exports, module) {
81
78
  module.exports = [
@@ -1792,14 +1789,12 @@ var require_data = __commonJS({
1792
1789
  }
1793
1790
  });
1794
1791
 
1795
- // ../../node_modules/.pnpm/currency-codes@2.2.0/node_modules/currency-codes/iso-4217-publish-date.js
1796
1792
  var require_iso_4217_publish_date = __commonJS({
1797
1793
  "../../node_modules/.pnpm/currency-codes@2.2.0/node_modules/currency-codes/iso-4217-publish-date.js"(exports, module) {
1798
1794
  module.exports = "2024-06-25";
1799
1795
  }
1800
1796
  });
1801
1797
 
1802
- // ../../node_modules/.pnpm/currency-codes@2.2.0/node_modules/currency-codes/index.js
1803
1798
  var require_currency_codes = __commonJS({
1804
1799
  "../../node_modules/.pnpm/currency-codes@2.2.0/node_modules/currency-codes/index.js"(exports) {
1805
1800
  var first = require_first_match();
@@ -1859,7 +1854,6 @@ var require_currency_codes = __commonJS({
1859
1854
  }
1860
1855
  });
1861
1856
 
1862
- // ../schemas/money.ts
1863
1857
  var import_currency_codes = __toESM(require_currency_codes());
1864
1858
  var InvalidAmountError = class extends ReploError {
1865
1859
  };
@@ -5,7 +5,6 @@ import '../../../chunk-GV5FY7ZZ.mjs';
5
5
  import '../../../chunk-UJCSKKID.mjs';
6
6
  import { z } from 'zod';
7
7
 
8
- // ../replo-utils/lib/url.ts
9
8
  function parseUrl(value, base) {
10
9
  try {
11
10
  return new URL(value, base);
@@ -112,4 +112,3 @@ export {
112
112
  useAnalytics,
113
113
  useAnalyticsOptional
114
114
  };
115
- //# sourceMappingURL=analytics-provider.js.map
@@ -1 +0,0 @@
1
- //# sourceMappingURL=analytics-sink.js.map
@@ -68,4 +68,3 @@ function getAnalyticsSinks({
68
68
  export {
69
69
  getAnalyticsSinks
70
70
  };
71
- //# sourceMappingURL=get-analytics-sinks.js.map
@@ -0,0 +1,19 @@
1
+ import type { AnalyticsCollection, AnalyticsCollectionProduct } from "../utils/collection-analytics";
2
+ interface UseCollectionViewedAnalyticsProps {
3
+ collection: AnalyticsCollection | null | undefined;
4
+ /**
5
+ * The collection's products as the collection-products loader returns them.
6
+ * Pass `undefined` while they are still loading so the event carries the
7
+ * list when it fires.
8
+ */
9
+ products: AnalyticsCollectionProduct[] | null | undefined;
10
+ }
11
+ /**
12
+ * Fires a `viewCollection` analytics event carrying the collection's products
13
+ * once the collection and its product list are both available. Re-renders
14
+ * and product-list updates for the same collection do not fire again; a
15
+ * different collection does, and returning to an earlier one counts as a new
16
+ * view, matching `useProductViewedAnalytics`.
17
+ */
18
+ export declare function useCollectionViewedAnalytics({ collection, products, }: UseCollectionViewedAnalyticsProps): void;
19
+ export {};
@@ -0,0 +1,26 @@
1
+ "use client";
2
+ import { useEffect, useRef } from "react";
3
+ import { useAnalytics } from "../analytics-provider";
4
+ import { buildCollectionViewedAnalyticsData } from "../utils/collection-analytics";
5
+ function useCollectionViewedAnalytics({
6
+ collection,
7
+ products
8
+ }) {
9
+ const analytics = useAnalytics();
10
+ const lastTrackedRef = useRef(null);
11
+ useEffect(() => {
12
+ if (!analytics || !collection || !products) {
13
+ return;
14
+ }
15
+ if (lastTrackedRef.current === collection.id) {
16
+ return;
17
+ }
18
+ lastTrackedRef.current = collection.id;
19
+ void analytics.viewCollection({
20
+ data: buildCollectionViewedAnalyticsData({ collection, products })
21
+ });
22
+ }, [analytics, collection, products]);
23
+ }
24
+ export {
25
+ useCollectionViewedAnalytics
26
+ };
@@ -34,4 +34,3 @@ function useProductViewedAnalytics({
34
34
  export {
35
35
  useProductViewedAnalytics
36
36
  };
37
- //# sourceMappingURL=use-product-viewed-analytics.js.map
@@ -28,4 +28,3 @@ async function ReploFirstPartyPixel() {
28
28
  export {
29
29
  ReploFirstPartyPixel
30
30
  };
31
- //# sourceMappingURL=replo-first-party-pixel.js.map
@@ -35,4 +35,3 @@ function ReploPixelScript({
35
35
  export {
36
36
  ReploPixelScript
37
37
  };
38
- //# sourceMappingURL=replo-pixel-script.js.map
@@ -179,4 +179,3 @@ export {
179
179
  mapConvergeOrder,
180
180
  mapConvergeProduct
181
181
  };
182
- //# sourceMappingURL=converge-event-mapper.js.map
@@ -70,4 +70,3 @@ class ConvergeSink {
70
70
  export {
71
71
  ConvergeSink
72
72
  };
73
- //# sourceMappingURL=converge-sink.js.map
@@ -1,4 +1,5 @@
1
1
  import { z } from "zod";
2
+ import { legacyResourceId } from "../utils/analytics-products";
2
3
  const GUEST_USER_PROPERTIES = { visitor_type: "guest" };
3
4
  const FALLBACK_CURRENCY_CODE = "USD";
4
5
  const nonEmptyStringSchema = z.union([z.string().min(1), z.number().finite().transform(String)]).optional().catch(void 0);
@@ -45,9 +46,6 @@ const collectionPayloadSchema = z.object({
45
46
  function formatMoney(amount) {
46
47
  return amount.toFixed(2);
47
48
  }
48
- function legacyResourceId(id) {
49
- return id.replace(/^gid:\/\/shopify\/\w+\//, "");
50
- }
51
49
  function parseCheckoutLine(line) {
52
50
  const parsed = checkoutLineSchema.safeParse(line);
53
51
  if (!parsed.success || !parsed.data.merchandise) {
@@ -257,4 +255,3 @@ class ElevarSink {
257
255
  export {
258
256
  ElevarSink
259
257
  };
260
- //# sourceMappingURL=elevar-sink.js.map
@@ -1,11 +1,13 @@
1
+ import {
2
+ legacyResourceId,
3
+ splitCollectionProducts,
4
+ withoutUndefined
5
+ } from "../utils/analytics-products";
1
6
  import { createEventQueue } from "../utils/analytics-utils";
2
7
  class GA4Sink {
3
- // oxlint-disable-next-line typescript/no-explicit-any -- legacy any, may or may not be needed
4
8
  send;
5
9
  constructor() {
6
10
  this.send = createEventQueue(
7
- // Legacy cast - may or may not be necessary
8
- // oxlint-disable-next-line replo/no-as-cast, typescript/no-explicit-any -- legacy any/cast, may or may not be needed
9
11
  () => typeof window !== "undefined" && Boolean(window.gtag),
10
12
  (event, params) => {
11
13
  const gtag = window.gtag;
@@ -51,10 +53,26 @@ class GA4Sink {
51
53
  this.send("begin_checkout", data);
52
54
  }
53
55
  async viewCollection({ data }) {
54
- this.send("view_item_list", data);
56
+ const { products, rest } = splitCollectionProducts(data);
57
+ this.send("view_item_list", {
58
+ item_list_id: data.collectionId,
59
+ item_list_name: data.collectionTitle,
60
+ currency: data.currency,
61
+ ...products.length > 0 ? {
62
+ items: products.map((product, index) => {
63
+ return withoutUndefined({
64
+ item_id: legacyResourceId(product.productId),
65
+ item_name: product.productTitle,
66
+ item_variant: product.variantTitle,
67
+ price: product.price,
68
+ index
69
+ });
70
+ })
71
+ } : {},
72
+ ...rest
73
+ });
55
74
  }
56
75
  }
57
76
  export {
58
77
  GA4Sink
59
78
  };
60
- //# sourceMappingURL=ga4-sink.js.map
@@ -1,11 +1,8 @@
1
1
  import { createEventQueue } from "../utils/analytics-utils";
2
2
  class MetaSink {
3
- // oxlint-disable-next-line typescript/no-explicit-any -- legacy any, may or may not be needed
4
3
  track;
5
4
  constructor() {
6
5
  this.track = createEventQueue(
7
- // Legacy cast - may or may not be necessary
8
- // oxlint-disable-next-line replo/no-as-cast, typescript/no-explicit-any -- legacy any/cast, may or may not be needed
9
6
  () => typeof window !== "undefined" && Boolean(window.fbq),
10
7
  (event, params) => {
11
8
  const fbq = window.fbq;
@@ -53,4 +50,3 @@ class MetaSink {
53
50
  export {
54
51
  MetaSink
55
52
  };
56
- //# sourceMappingURL=meta-sink.js.map
@@ -35,4 +35,3 @@ class NorthbeamSink {
35
35
  export {
36
36
  NorthbeamSink
37
37
  };
38
- //# sourceMappingURL=northbeam-sink.js.map
@@ -1,11 +1,13 @@
1
+ import {
2
+ legacyResourceId,
3
+ splitCollectionProducts,
4
+ withoutUndefined
5
+ } from "../utils/analytics-products";
1
6
  import { createEventQueue } from "../utils/analytics-utils";
2
7
  class PinterestSink {
3
- // oxlint-disable-next-line typescript/no-explicit-any -- legacy any, may or may not be needed
4
8
  track;
5
9
  constructor() {
6
10
  this.track = createEventQueue(
7
- // Legacy cast - may or may not be necessary
8
- // oxlint-disable-next-line replo/no-as-cast, typescript/no-explicit-any -- legacy any/cast, may or may not be needed
9
11
  () => typeof window !== "undefined" && Boolean(window.pintrk),
10
12
  (event, params) => {
11
13
  const pintrk = window.pintrk;
@@ -64,13 +66,25 @@ class PinterestSink {
64
66
  });
65
67
  }
66
68
  async viewCollection({ data }) {
69
+ const { products, rest } = splitCollectionProducts(data);
67
70
  this.track("viewcategory", {
68
71
  product_category: data.category,
69
- ...data
72
+ currency: data.currency,
73
+ ...products.length > 0 ? {
74
+ line_items: products.map((product) => {
75
+ return withoutUndefined({
76
+ product_id: legacyResourceId(product.productId),
77
+ product_name: product.productTitle,
78
+ product_price: product.price,
79
+ product_variant_id: product.variantId === void 0 ? void 0 : legacyResourceId(product.variantId),
80
+ product_variant: product.variantTitle
81
+ });
82
+ })
83
+ } : {},
84
+ ...rest
70
85
  });
71
86
  }
72
87
  }
73
88
  export {
74
89
  PinterestSink
75
90
  };
76
- //# sourceMappingURL=pinterest-sink.js.map
@@ -1,11 +1,13 @@
1
+ import {
2
+ legacyResourceId,
3
+ splitCollectionProducts,
4
+ withoutUndefined
5
+ } from "../utils/analytics-products";
1
6
  import { createEventQueue } from "../utils/analytics-utils";
2
7
  class RedditSink {
3
- // oxlint-disable-next-line typescript/no-explicit-any -- legacy any, may or may not be needed
4
8
  track;
5
9
  constructor() {
6
10
  this.track = createEventQueue(
7
- // Legacy cast - may or may not be necessary
8
- // oxlint-disable-next-line replo/no-as-cast, typescript/no-explicit-any -- legacy any/cast, may or may not be needed
9
11
  () => typeof window !== "undefined" && Boolean(window.rdt),
10
12
  (event, params) => {
11
13
  const rdt = window.rdt;
@@ -67,14 +69,23 @@ class RedditSink {
67
69
  });
68
70
  }
69
71
  async viewCollection({ data }) {
72
+ const { products, rest } = splitCollectionProducts(data);
70
73
  this.track("ViewContent", {
71
74
  content_category: data.category,
72
75
  content_type: "category",
73
- ...data
76
+ currency: data.currency,
77
+ ...products.length > 0 ? {
78
+ products: products.map((product) => {
79
+ return withoutUndefined({
80
+ id: legacyResourceId(product.productId),
81
+ name: product.productTitle
82
+ });
83
+ })
84
+ } : {},
85
+ ...rest
74
86
  });
75
87
  }
76
88
  }
77
89
  export {
78
90
  RedditSink
79
91
  };
80
- //# sourceMappingURL=reddit-sink.js.map
@@ -1,6 +1,5 @@
1
1
  import { createMethodQueue } from "../utils/analytics-utils";
2
2
  class ReploSink {
3
- // oxlint-disable-next-line typescript/no-explicit-any -- legacy any, may or may not be needed
4
3
  forward;
5
4
  constructor() {
6
5
  this.forward = createMethodQueue(
@@ -54,4 +53,3 @@ class ReploSink {
54
53
  export {
55
54
  ReploSink
56
55
  };
57
- //# sourceMappingURL=replo-sink.js.map
@@ -1,11 +1,8 @@
1
1
  import { createEventQueue } from "../utils/analytics-utils";
2
2
  class SnapchatSink {
3
- // oxlint-disable-next-line typescript/no-explicit-any -- legacy any, may or may not be needed
4
3
  track;
5
4
  constructor() {
6
5
  this.track = createEventQueue(
7
- // Legacy cast - may or may not be necessary
8
- // oxlint-disable-next-line replo/no-as-cast, typescript/no-explicit-any -- legacy any/cast, may or may not be needed
9
6
  () => typeof window !== "undefined" && Boolean(window.snaptr),
10
7
  (event, params) => {
11
8
  const snaptr = window.snaptr;
@@ -64,4 +61,3 @@ class SnapchatSink {
64
61
  export {
65
62
  SnapchatSink
66
63
  };
67
- //# sourceMappingURL=snapchat-sink.js.map
@@ -1,11 +1,13 @@
1
+ import {
2
+ legacyResourceId,
3
+ splitCollectionProducts,
4
+ withoutUndefined
5
+ } from "../utils/analytics-products";
1
6
  import { createEventQueue } from "../utils/analytics-utils";
2
7
  class TikTokSink {
3
- // oxlint-disable-next-line typescript/no-explicit-any -- legacy any, may or may not be needed
4
8
  track;
5
9
  constructor() {
6
10
  this.track = createEventQueue(
7
- // Legacy cast - may or may not be necessary
8
- // oxlint-disable-next-line replo/no-as-cast, typescript/no-explicit-any -- legacy any/cast, may or may not be needed
9
11
  () => typeof window !== "undefined" && Boolean(window.ttq),
10
12
  (event, params) => {
11
13
  const ttq = window.ttq;
@@ -66,14 +68,25 @@ class TikTokSink {
66
68
  });
67
69
  }
68
70
  async viewCollection({ data }) {
71
+ const { products, rest } = splitCollectionProducts(data);
69
72
  this.track("ViewContent", {
70
73
  content_type: "product_group",
71
74
  content_category: data.category,
72
- ...data
75
+ currency: data.currency,
76
+ ...products.length > 0 ? {
77
+ contents: products.map((product) => {
78
+ return withoutUndefined({
79
+ content_id: legacyResourceId(product.productId),
80
+ content_type: "product_group",
81
+ content_name: product.productTitle,
82
+ price: product.price
83
+ });
84
+ })
85
+ } : {},
86
+ ...rest
73
87
  });
74
88
  }
75
89
  }
76
90
  export {
77
91
  TikTokSink
78
92
  };
79
- //# sourceMappingURL=tiktok-sink.js.map
@@ -1,5 +1,4 @@
1
1
  class WindowSink {
2
- // oxlint-disable-next-line typescript/no-explicit-any -- legacy any, may or may not be needed
3
2
  dispatch(eventType, payload) {
4
3
  window.dispatchEvent(
5
4
  new CustomEvent("replo:analytics", {
@@ -11,7 +10,6 @@ class WindowSink {
11
10
  })
12
11
  );
13
12
  }
14
- // oxlint-disable-next-line typescript/no-explicit-any -- legacy any, may or may not be needed
15
13
  async pageView(payload) {
16
14
  this.dispatch("page_viewed", payload);
17
15
  }
@@ -43,4 +41,3 @@ class WindowSink {
43
41
  export {
44
42
  WindowSink
45
43
  };
46
- //# sourceMappingURL=window-sink.js.map
@@ -0,0 +1,36 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * The flat per-product line the cart provider and the viewed hooks emit.
4
+ * Prices are decimal major units.
5
+ */
6
+ declare const analyticsProductLineSchema: z.ZodObject<{
7
+ productId: z.ZodCatch<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodPipe<z.ZodNumber, z.ZodTransform<string, number>>]>>>;
8
+ productTitle: z.ZodCatch<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodPipe<z.ZodNumber, z.ZodTransform<string, number>>]>>>;
9
+ variantId: z.ZodCatch<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodPipe<z.ZodNumber, z.ZodTransform<string, number>>]>>>;
10
+ variantTitle: z.ZodCatch<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodPipe<z.ZodNumber, z.ZodTransform<string, number>>]>>>;
11
+ variantSku: z.ZodCatch<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodPipe<z.ZodNumber, z.ZodTransform<string, number>>]>>>;
12
+ price: z.ZodCatch<z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<number, string>>, z.ZodNumber>]>>>;
13
+ currency: z.ZodCatch<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodPipe<z.ZodNumber, z.ZodTransform<string, number>>]>>>;
14
+ quantity: z.ZodCatch<z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<number, string>>, z.ZodNumber>]>>>;
15
+ }, z.core.$strip>;
16
+ export type AnalyticsProductLine = z.infer<typeof analyticsProductLineSchema> & {
17
+ productId: string;
18
+ };
19
+ export declare function parseAnalyticsProductLines(value: unknown): AnalyticsProductLine[];
20
+ /**
21
+ * Separates a collection-view payload's `products` list from the scalar
22
+ * fields, so a sink can map the list into its own item shape and forward the
23
+ * rest untouched.
24
+ */
25
+ export declare function splitCollectionProducts(data: Record<string, unknown>): {
26
+ products: AnalyticsProductLine[];
27
+ rest: Record<string, unknown>;
28
+ };
29
+ /**
30
+ * Shopify catalogs synced into ad platforms key on legacy numeric ids, while
31
+ * the Storefront API hands sites GIDs (`gid://shopify/Product/123`). Pixel
32
+ * catalog matching is an exact string match, so ids are sent bare.
33
+ */
34
+ export declare function legacyResourceId(id: string): string;
35
+ export declare function withoutUndefined<RecordType extends Record<string, unknown>>(record: RecordType): Partial<RecordType>;
36
+ export {};
@@ -0,0 +1,57 @@
1
+ import { z } from "zod";
2
+ const nonEmptyStringSchema = z.union([z.string().min(1), z.number().finite().transform(String)]).optional().catch(void 0);
3
+ const finiteNumberSchema = z.union([
4
+ z.number().finite(),
5
+ z.string().trim().min(1).transform(Number).pipe(z.number().finite())
6
+ ]).optional().catch(void 0);
7
+ const analyticsProductLineSchema = z.object({
8
+ productId: nonEmptyStringSchema,
9
+ productTitle: nonEmptyStringSchema,
10
+ variantId: nonEmptyStringSchema,
11
+ variantTitle: nonEmptyStringSchema,
12
+ variantSku: nonEmptyStringSchema,
13
+ price: finiteNumberSchema,
14
+ currency: nonEmptyStringSchema,
15
+ quantity: finiteNumberSchema
16
+ });
17
+ function parseAnalyticsProductLines(value) {
18
+ if (!Array.isArray(value)) {
19
+ return [];
20
+ }
21
+ return value.flatMap((item) => {
22
+ const parsed = analyticsProductLineSchema.safeParse(item);
23
+ if (!parsed.success || !parsed.data.productId) {
24
+ return [];
25
+ }
26
+ return [{ ...parsed.data, productId: parsed.data.productId }];
27
+ });
28
+ }
29
+ function splitCollectionProducts(data) {
30
+ const { products, ...rest } = data;
31
+ const lines = parseAnalyticsProductLines(products);
32
+ if (Array.isArray(products) && products.length > 0 && lines.length === 0) {
33
+ console.warn(
34
+ "[analytics] collection view products did not match the per-line shape and were dropped",
35
+ { products }
36
+ );
37
+ }
38
+ return { products: lines, rest };
39
+ }
40
+ function legacyResourceId(id) {
41
+ return id.replace(/^gid:\/\/shopify\/\w+\//, "");
42
+ }
43
+ function withoutUndefined(record) {
44
+ const compacted = {};
45
+ for (const key in record) {
46
+ if (record[key] !== void 0) {
47
+ compacted[key] = record[key];
48
+ }
49
+ }
50
+ return compacted;
51
+ }
52
+ export {
53
+ legacyResourceId,
54
+ parseAnalyticsProductLines,
55
+ splitCollectionProducts,
56
+ withoutUndefined
57
+ };
@@ -139,4 +139,3 @@ export {
139
139
  createEventQueue,
140
140
  createMethodQueue
141
141
  };
142
- //# sourceMappingURL=analytics-utils.js.map
@@ -0,0 +1,44 @@
1
+ export interface AnalyticsMoney {
2
+ amount: number | string;
3
+ currencyCode: string;
4
+ }
5
+ export interface AnalyticsCollection {
6
+ id: string;
7
+ title?: string | null;
8
+ handle?: string | null;
9
+ }
10
+ export interface AnalyticsCollectionProductVariant {
11
+ id: string;
12
+ title?: string | null;
13
+ sku?: string | null;
14
+ price?: AnalyticsMoney | null;
15
+ }
16
+ export interface AnalyticsCollectionProduct {
17
+ id: string;
18
+ title?: string | null;
19
+ variants?: AnalyticsCollectionProductVariant[] | null;
20
+ minPrice?: AnalyticsMoney | null;
21
+ }
22
+ /**
23
+ * The `viewCollection` payload: collection identity plus one line per product
24
+ * in the same shape the cart events use, priced from the first variant (or
25
+ * the product's minimum price) with no quantity.
26
+ */
27
+ export declare function buildCollectionViewedAnalyticsData({ collection, products, }: {
28
+ collection: AnalyticsCollection;
29
+ products: AnalyticsCollectionProduct[];
30
+ }): {
31
+ collectionTitle?: string | undefined;
32
+ collectionHandle?: string | undefined;
33
+ currency?: string | undefined;
34
+ collectionId: string;
35
+ products: {
36
+ productTitle?: string | undefined;
37
+ variantId?: string | undefined;
38
+ variantTitle?: string | undefined;
39
+ variantSku?: string | undefined;
40
+ price?: number | undefined;
41
+ currency?: string | undefined;
42
+ productId: string;
43
+ }[];
44
+ };
@@ -0,0 +1,41 @@
1
+ import { withoutUndefined } from "./analytics-products";
2
+ function parseAmount(money) {
3
+ if (!money) {
4
+ return void 0;
5
+ }
6
+ const amount = Number(money.amount);
7
+ return Number.isFinite(amount) ? amount : void 0;
8
+ }
9
+ function buildCollectionProductLine(product) {
10
+ const variant = product.variants?.[0];
11
+ const money = variant?.price ?? product.minPrice ?? void 0;
12
+ return {
13
+ productId: product.id,
14
+ ...withoutUndefined({
15
+ productTitle: product.title ?? void 0,
16
+ variantId: variant?.id,
17
+ variantTitle: variant?.title ?? void 0,
18
+ variantSku: variant?.sku ?? void 0,
19
+ price: parseAmount(money),
20
+ currency: money?.currencyCode
21
+ })
22
+ };
23
+ }
24
+ function buildCollectionViewedAnalyticsData({
25
+ collection,
26
+ products
27
+ }) {
28
+ const lines = products.map(buildCollectionProductLine);
29
+ return {
30
+ collectionId: collection.id,
31
+ products: lines,
32
+ ...withoutUndefined({
33
+ collectionTitle: collection.title ?? void 0,
34
+ collectionHandle: collection.handle ?? void 0,
35
+ currency: lines.find((line) => line.currency)?.currency
36
+ })
37
+ };
38
+ }
39
+ export {
40
+ buildCollectionViewedAnalyticsData
41
+ };
@@ -45,4 +45,3 @@ class NavigationTracker {
45
45
  export {
46
46
  NavigationTracker
47
47
  };
48
- //# sourceMappingURL=navigation-tracker.js.map
@@ -19,4 +19,3 @@ function gateShopifyOwnedFunnelEvents(sink) {
19
19
  export {
20
20
  gateShopifyOwnedFunnelEvents
21
21
  };
22
- //# sourceMappingURL=shopify-funnel-gate.js.map