@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
@@ -53,4 +53,3 @@ function OkendoReviewAggregateLoader({
53
53
  export {
54
54
  OkendoReviewAggregateLoader
55
55
  };
56
- //# sourceMappingURL=okendo-review-aggregate-loader.js.map
@@ -51,4 +51,3 @@ function OkendoReviewsLoader({
51
51
  export {
52
52
  OkendoReviewsLoader
53
53
  };
54
- //# sourceMappingURL=okendo-reviews-loader.js.map
@@ -43,4 +43,3 @@ async function PrefetchedLoaders({
43
43
  export {
44
44
  PrefetchedLoaders
45
45
  };
46
- //# sourceMappingURL=prefetch-loaders.js.map
@@ -33,7 +33,6 @@ const SAMPLE_VARIANTS = SAMPLE_SIZES.flatMap(
33
33
  ],
34
34
  image: null,
35
35
  price: { amount: size.priceAmount, currencyCode: "USD" },
36
- // Every variant is "on sale" so strikethrough pricing renders.
37
36
  compareAtPrice: { amount: "56.00", currencyCode: "USD" },
38
37
  sellingPlanIds: []
39
38
  };
@@ -48,9 +47,6 @@ const SAMPLE_PRODUCT = {
48
47
  descriptionHtml: "<p>This is sample product data for previewing this page. Open the page from a real product link to see live details.</p><p>The sample includes:</p><ul><li>Three sizes and two colors to try the option pickers</li><li>Sale pricing with a compare-at price</li><li>One sold-out combination (Large / Sand)</li></ul>",
49
48
  availableForSale: true,
50
49
  featuredImage: null,
51
- // `id` is optional in the schema but always present on real data, and
52
- // generated pages key option lists on it — omit it and previews log React
53
- // "missing key" console errors, which the dev overlay counts as page errors.
54
50
  options: [
55
51
  {
56
52
  id: "replo-sample-option-size",
@@ -219,4 +215,3 @@ export {
219
215
  resolvePreviewPlaceholderData,
220
216
  useReportPreviewPlaceholderRender
221
217
  };
222
- //# sourceMappingURL=preview-placeholder.js.map
@@ -18,4 +18,3 @@ function buildProductLoaderArgs({
18
18
  export {
19
19
  buildProductLoaderArgs
20
20
  };
21
- //# sourceMappingURL=product-loader-args.js.map
@@ -54,4 +54,3 @@ function ProductLoader({
54
54
  export {
55
55
  ProductLoader
56
56
  };
57
- //# sourceMappingURL=product-loader.js.map
@@ -54,4 +54,3 @@ function RebuyRecommendationsLoader({
54
54
  export {
55
55
  RebuyRecommendationsLoader
56
56
  };
57
- //# sourceMappingURL=rebuy-recommendations-loader.js.map
@@ -40,4 +40,3 @@ function ReviewsIoReviewAggregateLoader({
40
40
  export {
41
41
  ReviewsIoReviewAggregateLoader
42
42
  };
43
- //# sourceMappingURL=reviews-io-review-aggregate-loader.js.map
@@ -62,4 +62,3 @@ function ReviewsIoReviewsLoader({
62
62
  export {
63
63
  ReviewsIoReviewsLoader
64
64
  };
65
- //# sourceMappingURL=reviews-io-reviews-loader.js.map
@@ -41,4 +41,3 @@ function SmileEarningRulesLoader({
41
41
  export {
42
42
  SmileEarningRulesLoader
43
43
  };
44
- //# sourceMappingURL=smile-earning-rules-loader.js.map
@@ -41,4 +41,3 @@ function SmileRewardsLoader({
41
41
  export {
42
42
  SmileRewardsLoader
43
43
  };
44
- //# sourceMappingURL=smile-rewards-loader.js.map
@@ -40,4 +40,3 @@ function SmileVipTiersLoader({
40
40
  export {
41
41
  SmileVipTiersLoader
42
42
  };
43
- //# sourceMappingURL=smile-vip-tiers-loader.js.map
@@ -78,4 +78,3 @@ function StatsigExperimentLoader({
78
78
  export {
79
79
  StatsigExperimentLoader
80
80
  };
81
- //# sourceMappingURL=statsig-experiment-loader.js.map
@@ -47,4 +47,3 @@ function YotpoReviewAggregateLoader({
47
47
  export {
48
48
  YotpoReviewAggregateLoader
49
49
  };
50
- //# sourceMappingURL=yotpo-review-aggregate-loader.js.map
@@ -62,4 +62,3 @@ function YotpoReviewsLoader({
62
62
  export {
63
63
  YotpoReviewsLoader
64
64
  };
65
- //# sourceMappingURL=yotpo-reviews-loader.js.map
package/money.js CHANGED
@@ -10,4 +10,3 @@ export {
10
10
  fromMinorUnitsToMajorUnits,
11
11
  fromMinorUnitsToMajorUnitsString
12
12
  };
13
- //# sourceMappingURL=money.js.map
package/next/config.js CHANGED
@@ -48,31 +48,18 @@ function siteConfig(overrides = {}) {
48
48
  } = overrides;
49
49
  const { serverActions: overrideServerActions, ...restOverrideExperimental } = overrideExperimental ?? {};
50
50
  return {
51
- // Site-overridable defaults.
52
51
  reactStrictMode: true,
53
52
  devIndicators: false,
54
53
  ...restOverrides,
55
- // Platform invariants — re-asserted after the spread so a site override
56
- // can never break sandbox builds, publish, or the dev server.
57
54
  output: "standalone",
58
55
  distDir: isBuild ? ".next" : ".next-dev",
59
56
  pageExtensions: resolvePageExtensions(overridePageExtensions),
60
57
  typescript: resolvePublishTypescriptConfig(overrideTypescript),
61
- // NOTE (Cole, 2026-04-30, REPL-26637): The publish tool patches
62
- // required-server-files.json to clear this value before OpenNext bundles,
63
- // since "/" makes esbuild emit absolute-path requires that break in Workers.
64
- // NOTE (Patrick Lu, 2026-07-06, REPL-28775): Leave outputFileTracingRoot
65
- // unset outside builds because Next 15.5+ otherwise forces turbopack.root to
66
- // "/" and makes the dev watcher retain whole-filesystem state.
67
58
  outputFileTracingRoot: isBuild ? "/" : void 0,
68
- // NOTE (Patrick Lu, 2026-07-06, REPL-28775): Match build tracing at publish
69
- // time; keep dev's watcher on the user app tree.
70
59
  turbopack: {
71
60
  ...overrideTurbopack,
72
61
  root: isBuild ? "/" : devRoot
73
62
  },
74
- // @replohq/sdk ships as raw source with zero workspace deps, so we can't pull
75
- // in lodash-es `uniq` here — dedupe inline via a Set instead.
76
63
  allowedDevOrigins: Array.from(
77
64
  /* @__PURE__ */ new Set([...overrideDevOrigins ?? [], ...PLATFORM_DEV_ORIGINS])
78
65
  ),
@@ -89,10 +76,6 @@ function siteConfig(overrides = {}) {
89
76
  },
90
77
  experimental: {
91
78
  ...restOverrideExperimental,
92
- // NOTE (Cole, 2026-06-18, REPL-28180): Next sizes its build worker pool
93
- // off os.cpus().length = host cores (~64) inside a cgroup-limited sandbox,
94
- // not the 2 the container actually has — a worker swarm that OOMs the
95
- // 4 GiB box. availableParallelism() is cgroup-aware. Gated to prod build.
96
79
  cpus: isBuild ? os.availableParallelism() : void 0,
97
80
  serverActions: {
98
81
  ...overrideServerActions,
@@ -112,4 +95,3 @@ export {
112
95
  config_default as default,
113
96
  siteConfig
114
97
  };
115
- //# sourceMappingURL=config.js.map
@@ -51,4 +51,3 @@ function cloudflareLoader({
51
51
  export {
52
52
  cloudflareLoader as default
53
53
  };
54
- //# sourceMappingURL=image-loader.js.map
package/next/open-next.js CHANGED
@@ -21,4 +21,3 @@ var open_next_default = defineCloudflareConfig({
21
21
  export {
22
22
  open_next_default as default
23
23
  };
24
- //# sourceMappingURL=open-next.js.map
@@ -6,7 +6,6 @@ const orderStatusAddressSchema = z.object({
6
6
  city: z.string(),
7
7
  state: z.string().nullable(),
8
8
  postalCode: z.string(),
9
- // ISO 3166-1 alpha-2, as written by Stripe checkout.
10
9
  country: z.string()
11
10
  });
12
11
  const orderStatusItemSchema = z.object({
@@ -62,9 +61,7 @@ const checkoutSessionSummarySchema = z.object({
62
61
  )
63
62
  });
64
63
  const orderStatusResultSchema = z.discriminatedUnion("state", [
65
- // Our order row — the durable Order status page.
66
64
  z.object({ state: z.literal("order"), order: orderStatusSummarySchema }),
67
- // Stripe's session — the Thank you page, before our row exists.
68
65
  z.object({
69
66
  state: z.literal("session"),
70
67
  session: checkoutSessionSummarySchema
@@ -80,4 +77,3 @@ export {
80
77
  orderStatusShipmentSchema,
81
78
  orderStatusSummarySchema
82
79
  };
83
- //# sourceMappingURL=order-status-schema.js.map
@@ -11,8 +11,6 @@ async function getOrderStatus({
11
11
  method: "POST",
12
12
  headers: { "Content-Type": "application/json" },
13
13
  body: JSON.stringify({ reference, projectId: env.PROJECT_ID }),
14
- // The page must reflect the webhook race resolving (session → order on
15
- // refresh), so never serve a cached resolution.
16
14
  cache: "no-store"
17
15
  });
18
16
  if (!response.ok) {
@@ -38,4 +36,3 @@ async function getOrderStatus({
38
36
  export {
39
37
  getOrderStatus
40
38
  };
41
- //# sourceMappingURL=order-status.js.map
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@replohq/sdk",
3
- "version": "1.7.2",
3
+ "version": "1.8.0",
4
4
  "reploBuild": {
5
5
  "packageName": "@replohq/sdk",
6
- "version": "1.7.2",
6
+ "version": "1.8.0",
7
7
  "branch": "HEAD",
8
- "commit": "5d0cc60f9bd67d3ed2c181939fca1a8cacc979e9",
9
- "builtAt": "2026-09-14T22:55:35.132Z"
8
+ "commit": "b651d52d898d9c6fc4fdca33165feed30505e056",
9
+ "builtAt": "2026-09-15T18:43:12.533Z"
10
10
  },
11
11
  "description": "Replo SDK — cart, analytics, and data loaders for agent-built Next.js sites.",
12
12
  "license": "SEE LICENSE IN LICENSE",
@@ -89,6 +89,10 @@
89
89
  "types": "./analytics/hooks/use-product-viewed-analytics.d.ts",
90
90
  "default": "./analytics/hooks/use-product-viewed-analytics.js"
91
91
  },
92
+ "./analytics/hooks/use-collection-viewed-analytics": {
93
+ "types": "./analytics/hooks/use-collection-viewed-analytics.d.ts",
94
+ "default": "./analytics/hooks/use-collection-viewed-analytics.js"
95
+ },
92
96
  "./loaders/collection-loader": {
93
97
  "types": "./loaders/collection-loader.d.ts",
94
98
  "default": "./loaders/collection-loader.js"
@@ -9,4 +9,3 @@ function QueryProvider({ children }) {
9
9
  export {
10
10
  QueryProvider
11
11
  };
12
- //# sourceMappingURL=query-provider.js.map
@@ -3,6 +3,8 @@ import { AnalyticsProvider } from "../analytics/analytics-provider";
3
3
  import { ReploFirstPartyPixel } from "../analytics/replo-first-party-pixel";
4
4
  import { CartLoader } from "../cart/cart-loader";
5
5
  import { getCheckoutProvider } from "../lib/integration-utils";
6
+ import { LoaderErrorDetailsProvider } from "../loaders/loader-error-boundary";
7
+ import { shouldShowLoaderErrorDetails } from "../loaders/loader-error-details";
6
8
  import { QueryProvider } from "./query-provider";
7
9
  async function ReploProvider({ children }) {
8
10
  let checkoutProvider = "none";
@@ -11,12 +13,11 @@ async function ReploProvider({ children }) {
11
13
  } catch {
12
14
  checkoutProvider = "none";
13
15
  }
14
- return /* @__PURE__ */ jsx(QueryProvider, { children: /* @__PURE__ */ jsxs(AnalyticsProvider, { checkoutProvider, children: [
16
+ return /* @__PURE__ */ jsx(QueryProvider, { children: /* @__PURE__ */ jsx(LoaderErrorDetailsProvider, { enabled: shouldShowLoaderErrorDetails(), children: /* @__PURE__ */ jsxs(AnalyticsProvider, { checkoutProvider, children: [
15
17
  /* @__PURE__ */ jsx(ReploFirstPartyPixel, {}),
16
18
  /* @__PURE__ */ jsx(CartLoader, { children })
17
- ] }) });
19
+ ] }) }) });
18
20
  }
19
21
  export {
20
22
  ReploProvider
21
23
  };
22
- //# sourceMappingURL=replo-provider.js.map
@@ -187,4 +187,3 @@ function normalizePath(pathname) {
187
187
  export {
188
188
  evaluateRouting
189
189
  };
190
- //# sourceMappingURL=evaluate.js.map
package/routing/geo.js CHANGED
@@ -14,4 +14,3 @@ function ipCountry(request) {
14
14
  export {
15
15
  ipCountry
16
16
  };
17
- //# sourceMappingURL=geo.js.map
package/routing/locale.js CHANGED
@@ -10,4 +10,3 @@ export {
10
10
  localeUrl,
11
11
  reploLocaleRouting
12
12
  };
13
- //# sourceMappingURL=locale.js.map
package/routing/rules.js CHANGED
@@ -2,4 +2,3 @@ import { reploRedirect } from "../_vendor/schemas/routing/rules.mjs";
2
2
  export {
3
3
  reploRedirect
4
4
  };
5
- //# sourceMappingURL=rules.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../analytics/analytics-provider.tsx"],
4
- "sourcesContent": ["\"use client\";\n\nimport type React from \"react\";\nimport type { CheckoutProvider } from \"../lib/integration-utils\";\nimport type { AnalyticsSink } from \"./analytics-sink\";\nimport type { PageMetadata } from \"./utils/navigation-tracker\";\n\nimport { createContext, useContext, useEffect, useMemo, useRef } from \"react\";\n\nimport { useConsent } from \"../consent/consent-store\";\nimport { useRegisteredScripts } from \"../consent/script-registration-store\";\nimport { getAnalyticsSinks } from \"./get-analytics-sinks\";\nimport { NavigationTracker } from \"./utils/navigation-tracker\";\n\nfunction combineSinks(sinks: AnalyticsSink[]): AnalyticsSink {\n // oxlint-disable-next-line typescript/no-explicit-any -- legacy any, may or may not be needed\n const broadcast = async (method: keyof AnalyticsSink, ...args: any[]) => {\n if (typeof window !== \"undefined\") {\n console.debug(\n \"[analytics] broadcast\",\n method,\n \"to\",\n sinks.length,\n \"sinks\",\n { args },\n );\n }\n\n await Promise.all(\n sinks.map(async (sink) => {\n try {\n // Legacy cast - may or may not be necessary\n // oxlint-disable-next-line replo/no-as-cast, typescript/no-explicit-any -- legacy any/cast, may or may not be needed\n const sinkMethod = sink[method] as (...args: any[]) => Promise<void>;\n await sinkMethod.apply(sink, args);\n } catch {\n if (typeof window !== \"undefined\") {\n console.warn(\"[analytics] sink error\", { method, sink });\n }\n }\n }),\n );\n };\n\n return {\n pageView: (...args) => broadcast(\"pageView\", ...args),\n purchase: (...args) => broadcast(\"purchase\", ...args),\n click: (...args) => broadcast(\"click\", ...args),\n productViewed: (...args) => broadcast(\"productViewed\", ...args),\n addToCart: (...args) => broadcast(\"addToCart\", ...args),\n removeFromCart: (...args) => broadcast(\"removeFromCart\", ...args),\n viewCart: (...args) => broadcast(\"viewCart\", ...args),\n startCheckout: (...args) => broadcast(\"startCheckout\", ...args),\n viewCollection: (...args) => broadcast(\"viewCollection\", ...args),\n };\n}\n\ninterface AnalyticsContextType {\n analytics: AnalyticsSink | null;\n}\n\nconst AnalyticsContext = createContext<AnalyticsContextType | null>(null);\n\nexport function AnalyticsProvider({\n children,\n checkoutProvider,\n}: React.PropsWithChildren<{ checkoutProvider?: CheckoutProvider }>) {\n const consent = useConsent();\n const registeredScripts = useRegisteredScripts();\n\n // Sinks are derived from consent + which managed scripts are on the page, so\n // the set rebuilds whenever the visitor changes consent or a script mounts.\n const analytics = useMemo(() => {\n return combineSinks(\n getAnalyticsSinks({\n consent: {\n cmp: consent.cmp,\n mode: consent.mode,\n categories: consent.categories,\n decidedAt: consent.decidedAt,\n },\n registeredScripts,\n checkoutProvider,\n }),\n );\n }, [\n consent.cmp,\n consent.mode,\n consent.categories,\n consent.decidedAt,\n registeredScripts,\n checkoutProvider,\n ]);\n\n // The navigation tracker is set up once, but always dispatches to the latest\n // combined sink via a ref so consent/registration changes take effect.\n const analyticsRef = useRef(analytics);\n analyticsRef.current = analytics;\n const navigationTracker = useRef<NavigationTracker | null>(null);\n\n // eslint-disable-next-line replo/no-use-effect -- one-time SPA navigation tracking setup; dispatches through analyticsRef to stay current\n useEffect(() => {\n if (typeof window === \"undefined\") {\n return;\n }\n navigationTracker.current = new NavigationTracker(\n (metadata: PageMetadata) => {\n void analyticsRef.current.pageView(metadata);\n },\n );\n navigationTracker.current.init();\n\n return () => {\n navigationTracker.current?.cleanup();\n };\n }, []);\n\n return (\n <AnalyticsContext.Provider value={{ analytics }}>\n {children}\n </AnalyticsContext.Provider>\n );\n}\n\nclass AnalyticsContextError extends Error {\n constructor({ message }: { message: string }) {\n super(message);\n }\n}\n\n/**\n * Returns the AnalyticsSink from the nearest AnalyticsProvider.\n * Throws if used outside of an AnalyticsProvider.\n */\nexport function useAnalytics(): AnalyticsSink | null {\n const context = useContext(AnalyticsContext);\n if (!context) {\n throw new AnalyticsContextError({\n message: \"useAnalytics must be used within <AnalyticsProvider>\",\n });\n }\n return context.analytics;\n}\n\n/**\n * Returns the AnalyticsSink if an AnalyticsProvider is present, or null otherwise.\n * Does not throw -- safe to use in components that may render with or without analytics.\n */\nexport function useAnalyticsOptional(): AnalyticsSink | null {\n const context = useContext(AnalyticsContext);\n return context?.analytics ?? null;\n}\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": [],
4
- "sourcesContent": [],
5
- "mappings": "",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../analytics/get-analytics-sinks.ts"],
4
- "sourcesContent": ["import type { ReploScriptType } from \"schemas/generated/consent\";\nimport type { ConsentState } from \"../consent/consent-store\";\nimport type { RegisteredScript } from \"../consent/script-registration-store\";\nimport type { CheckoutProvider } from \"../lib/integration-utils\";\nimport type { AnalyticsSink } from \"./analytics-sink\";\n\nimport { isConsentAllowed } from \"../consent/consent-store\";\nimport { snippetScriptId } from \"../consent/script-registration-store\";\nimport { ConvergeSink } from \"./sinks/converge-sink\";\nimport { ElevarSink } from \"./sinks/elevar-sink\";\nimport { GA4Sink } from \"./sinks/ga4-sink\";\nimport { MetaSink } from \"./sinks/meta-sink\";\nimport { NorthbeamSink } from \"./sinks/northbeam-sink\";\nimport { PinterestSink } from \"./sinks/pinterest-sink\";\nimport { RedditSink } from \"./sinks/reddit-sink\";\nimport { ReploSink } from \"./sinks/replo-sink\";\nimport { SnapchatSink } from \"./sinks/snapchat-sink\";\nimport { TikTokSink } from \"./sinks/tiktok-sink\";\nimport { WindowSink } from \"./sinks/window-sink\";\nimport { gateShopifyOwnedFunnelEvents } from \"./utils/shopify-funnel-gate\";\n\n/**\n * Named providers that have a corresponding ecommerce-event sink. The other\n * managed providers (GoogleTagManager, Hotjar, MicrosoftClarity, Segment,\n * Gorgias) and `custom` entries load scripts but do not map to\n * `AnalyticsSink` events today, so they never produce a sink here.\n */\nconst PROVIDER_SINK_FACTORIES: Partial<\n Record<ReploScriptType, () => AnalyticsSink>\n> = {\n GA4: () => new GA4Sink(),\n Meta: () => new MetaSink(),\n TikTok: () => new TikTokSink(),\n Snapchat: () => new SnapchatSink(),\n Pinterest: () => new PinterestSink(),\n Reddit: () => new RedditSink(),\n Northbeam: () => new NorthbeamSink(),\n Converge: () => new ConvergeSink(),\n};\n\n/**\n * Snippet providers share the `snippet` type, so their sinks key on the\n * registration id instead. Elevar's pasted snippet only forwards what the page\n * pushes to its data layer, and this sink is what pushes it.\n */\nconst SNIPPET_PROVIDER_SINK_FACTORIES: Record<string, () => AnalyticsSink> = {\n [snippetScriptId(\"Elevar\")]: () => new ElevarSink(),\n};\n\nfunction findSinkFactory(script: RegisteredScript) {\n if (script.type === \"snippet\") {\n return SNIPPET_PROVIDER_SINK_FACTORIES[script.id] ?? null;\n }\n return PROVIDER_SINK_FACTORIES[script.type] ?? null;\n}\n\n/**\n * Builds the set of analytics sinks that may fire given the current consent\n * state and which managed scripts are registered on the page.\n *\n * Consent gates data egress, not in-page plumbing:\n * - `WindowSink` is a local `CustomEvent` bus (no data leaves the device), so it\n * always ships regardless of consent. Its consumers self-gate: managed pixels\n * are already gated at the injection layer (they never mount without consent,\n * so they never subscribe), and unmanaged custom scripts are the author's\n * responsibility.\n * - `ReploSink` forwards into Replo's first-party analytics pipeline (real\n * egress / processing), so it counts as `analytics`-category tracking and is\n * gated by that consent. It is an implicit sink this scaffold always ships\n * (not tied to a registered entry) and is never editable in the miniapp.\n * Under a delegated platform, `analytics` reflects that platform's answer.\n *\n * Third-party provider sinks are created only when a matching `<ReploScripts>`\n * entry is registered AND its required consent is granted.\n */\nexport function getAnalyticsSinks({\n consent,\n registeredScripts,\n checkoutProvider,\n}: {\n consent: ConsentState;\n registeredScripts: RegisteredScript[];\n checkoutProvider?: CheckoutProvider;\n}): AnalyticsSink[] {\n const sinks: AnalyticsSink[] = [new WindowSink()];\n\n const firstPartyAllowed = isConsentAllowed({\n state: consent,\n requiredConsent: [\"analytics\"],\n });\n if (firstPartyAllowed) {\n sinks.push(new ReploSink());\n }\n\n // When Shopify hosts checkout, its native channels report the checkout-funnel\n // events to ad platforms server-side. Suppress those events on third-party\n // storefront pixels so they don't double-count Shopify's copy.\n const shopifyOwnsCheckout = checkoutProvider === \"shopify\";\n\n // One sink per provider: typed providers dedupe on type, snippet providers\n // on their registration id.\n const addedProviders = new Set<string>();\n for (const script of registeredScripts) {\n const providerKey = script.type === \"snippet\" ? script.id : script.type;\n const factory = findSinkFactory(script);\n if (!factory || addedProviders.has(providerKey)) {\n continue;\n }\n if (\n isConsentAllowed({\n state: consent,\n requiredConsent: script.requiredConsent,\n })\n ) {\n const sink = factory();\n sinks.push(\n shopifyOwnsCheckout ? gateShopifyOwnedFunnelEvents(sink) : sink,\n );\n addedProviders.add(providerKey);\n }\n }\n\n return sinks;\n}\n"],
5
- "mappings": "AAMA,SAAS,wBAAwB;AACjC,SAAS,uBAAuB;AAChC,SAAS,oBAAoB;AAC7B,SAAS,kBAAkB;AAC3B,SAAS,eAAe;AACxB,SAAS,gBAAgB;AACzB,SAAS,qBAAqB;AAC9B,SAAS,qBAAqB;AAC9B,SAAS,kBAAkB;AAC3B,SAAS,iBAAiB;AAC1B,SAAS,oBAAoB;AAC7B,SAAS,kBAAkB;AAC3B,SAAS,kBAAkB;AAC3B,SAAS,oCAAoC;AAQ7C,MAAM,0BAEF;AAAA,EACF,KAAK,MAAM,IAAI,QAAQ;AAAA,EACvB,MAAM,MAAM,IAAI,SAAS;AAAA,EACzB,QAAQ,MAAM,IAAI,WAAW;AAAA,EAC7B,UAAU,MAAM,IAAI,aAAa;AAAA,EACjC,WAAW,MAAM,IAAI,cAAc;AAAA,EACnC,QAAQ,MAAM,IAAI,WAAW;AAAA,EAC7B,WAAW,MAAM,IAAI,cAAc;AAAA,EACnC,UAAU,MAAM,IAAI,aAAa;AACnC;AAOA,MAAM,kCAAuE;AAAA,EAC3E,CAAC,gBAAgB,QAAQ,CAAC,GAAG,MAAM,IAAI,WAAW;AACpD;AAEA,SAAS,gBAAgB,QAA0B;AACjD,MAAI,OAAO,SAAS,WAAW;AAC7B,WAAO,gCAAgC,OAAO,EAAE,KAAK;AAAA,EACvD;AACA,SAAO,wBAAwB,OAAO,IAAI,KAAK;AACjD;AAqBO,SAAS,kBAAkB;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AACF,GAIoB;AAClB,QAAM,QAAyB,CAAC,IAAI,WAAW,CAAC;AAEhD,QAAM,oBAAoB,iBAAiB;AAAA,IACzC,OAAO;AAAA,IACP,iBAAiB,CAAC,WAAW;AAAA,EAC/B,CAAC;AACD,MAAI,mBAAmB;AACrB,UAAM,KAAK,IAAI,UAAU,CAAC;AAAA,EAC5B;AAKA,QAAM,sBAAsB,qBAAqB;AAIjD,QAAM,iBAAiB,oBAAI,IAAY;AACvC,aAAW,UAAU,mBAAmB;AACtC,UAAM,cAAc,OAAO,SAAS,YAAY,OAAO,KAAK,OAAO;AACnE,UAAM,UAAU,gBAAgB,MAAM;AACtC,QAAI,CAAC,WAAW,eAAe,IAAI,WAAW,GAAG;AAC/C;AAAA,IACF;AACA,QACE,iBAAiB;AAAA,MACf,OAAO;AAAA,MACP,iBAAiB,OAAO;AAAA,IAC1B,CAAC,GACD;AACA,YAAM,OAAO,QAAQ;AACrB,YAAM;AAAA,QACJ,sBAAsB,6BAA6B,IAAI,IAAI;AAAA,MAC7D;AACA,qBAAe,IAAI,WAAW;AAAA,IAChC;AAAA,EACF;AAEA,SAAO;AACT;",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../analytics/hooks/use-product-viewed-analytics.ts"],
4
- "sourcesContent": ["\"use client\";\n\nimport { useEffect, useRef } from \"react\";\n\nimport { useAnalytics } from \"../analytics-provider\";\n\ninterface AnalyticsProduct {\n id: string;\n title: string;\n slug?: string;\n description?: string;\n}\n\ninterface AnalyticsProductVariant {\n id: string;\n title?: string;\n sku?: string;\n price?: number | { amount: number | string; currencyCode: string };\n currency?: string;\n priceCurrencyCode?: string | null;\n}\n\ninterface UseProductViewedAnalyticsProps {\n product: AnalyticsProduct | null;\n selectedVariant?: AnalyticsProductVariant | null;\n}\n\n/**\n * Fires a `productViewed` analytics event when the product or selected variant\n * changes. Deduplicates by product+variant ID so the same combination is only\n * tracked once per component lifecycle.\n */\nexport function useProductViewedAnalytics({\n product,\n selectedVariant,\n}: UseProductViewedAnalyticsProps) {\n const analytics = useAnalytics();\n const lastTrackedRef = useRef<string | null>(null);\n\n // eslint-disable-next-line replo/no-use-effect -- Legacy effect - may or may not be necessary\n useEffect(() => {\n if (analytics && product && selectedVariant) {\n const trackingKey = `${product.id}-${selectedVariant.id}`;\n\n if (lastTrackedRef.current !== trackingKey) {\n lastTrackedRef.current = trackingKey;\n\n const price =\n typeof selectedVariant.price === \"object\"\n ? Number(selectedVariant.price.amount)\n : selectedVariant.price ?? 0;\n const currency =\n typeof selectedVariant.price === \"object\"\n ? selectedVariant.price.currencyCode\n : selectedVariant.currency ??\n selectedVariant.priceCurrencyCode ??\n undefined;\n\n void analytics.productViewed({\n data: {\n productId: product.id,\n productTitle: product.title,\n productSlug: product.slug,\n productDescription: product.description,\n variantId: selectedVariant.id ?? \"\",\n variantTitle: selectedVariant.title ?? \"\",\n variantSku: selectedVariant.sku ?? \"\",\n price,\n currency,\n },\n });\n }\n }\n }, [analytics, product, selectedVariant]);\n}\n"],
5
- "mappings": ";AAEA,SAAS,WAAW,cAAc;AAElC,SAAS,oBAAoB;AA4BtB,SAAS,0BAA0B;AAAA,EACxC;AAAA,EACA;AACF,GAAmC;AACjC,QAAM,YAAY,aAAa;AAC/B,QAAM,iBAAiB,OAAsB,IAAI;AAGjD,YAAU,MAAM;AACd,QAAI,aAAa,WAAW,iBAAiB;AAC3C,YAAM,cAAc,GAAG,QAAQ,EAAE,IAAI,gBAAgB,EAAE;AAEvD,UAAI,eAAe,YAAY,aAAa;AAC1C,uBAAe,UAAU;AAEzB,cAAM,QACJ,OAAO,gBAAgB,UAAU,WAC7B,OAAO,gBAAgB,MAAM,MAAM,IACnC,gBAAgB,SAAS;AAC/B,cAAM,WACJ,OAAO,gBAAgB,UAAU,WAC7B,gBAAgB,MAAM,eACtB,gBAAgB,YAChB,gBAAgB,qBAChB;AAEN,aAAK,UAAU,cAAc;AAAA,UAC3B,MAAM;AAAA,YACJ,WAAW,QAAQ;AAAA,YACnB,cAAc,QAAQ;AAAA,YACtB,aAAa,QAAQ;AAAA,YACrB,oBAAoB,QAAQ;AAAA,YAC5B,WAAW,gBAAgB,MAAM;AAAA,YACjC,cAAc,gBAAgB,SAAS;AAAA,YACvC,YAAY,gBAAgB,OAAO;AAAA,YACnC;AAAA,YACA;AAAA,UACF;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF,GAAG,CAAC,WAAW,SAAS,eAAe,CAAC;AAC1C;",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../analytics/replo-first-party-pixel.tsx"],
4
- "sourcesContent": ["import { getEnv } from \"../env\";\nimport { ReploPixelScript } from \"./replo-pixel-script\";\n\n/**\n * Resolves the Replo first-party pixel's config from the worker env and hands it\n * to the consent-gated client injector. This lives inside `ReploProvider` (not\n * the site's `app/layout.tsx`) so every agent site ships the implicit\n * first-party pixel automatically \u2014 mirroring how `ReploSink` is an always-on\n * sink that is never authored in the layout or editable in the miniapp.\n *\n * Renders nothing when the analytics pipeline isn't wired (e.g. lean local dev,\n * where `REPLO_ANALYTICS_PIXEL_URL` / `ANALYTICS_FIRE_API_URL` are unset),\n * mirroring the self-disabling consent action.\n */\nexport async function ReploFirstPartyPixel() {\n let pixelUrl: string | undefined;\n let apiUrl: string | undefined;\n let projectId: string | undefined;\n try {\n const env = await getEnv();\n pixelUrl = env.REPLO_ANALYTICS_PIXEL_URL;\n apiUrl = env.ANALYTICS_FIRE_API_URL;\n projectId = env.PROJECT_ID;\n } catch {\n // No Cloudflare env (e.g. running the site outside the worker): no pixel.\n return null;\n }\n\n if (!pixelUrl || !apiUrl || !projectId) {\n return null;\n }\n\n return (\n <ReploPixelScript\n pixelUrl={pixelUrl}\n apiUrl={apiUrl}\n projectId={projectId}\n />\n );\n}\n"],
5
- "mappings": "AAiCI;AAjCJ,SAAS,cAAc;AACvB,SAAS,wBAAwB;AAajC,eAAsB,uBAAuB;AAC3C,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,MAAM,OAAO;AACzB,eAAW,IAAI;AACf,aAAS,IAAI;AACb,gBAAY,IAAI;AAAA,EAClB,QAAQ;AAEN,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,YAAY,CAAC,UAAU,CAAC,WAAW;AACtC,WAAO;AAAA,EACT;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA;AAAA,EACF;AAEJ;",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../analytics/replo-pixel-script.tsx"],
4
- "sourcesContent": ["\"use client\";\n\nimport type { ScriptTagDescriptor } from \"schemas/generated/consent\";\n\nimport { findDelegatedPlatform } from \"../consent/consent-platform\";\nimport { isConsentAllowed, useConsent } from \"../consent/consent-store\";\nimport { InjectedScript } from \"../consent/replo-scripts\";\n\n// Stable injection id so re-renders and React Strict Mode double-invokes never\n// inject the pixel twice (the loader itself also guards via `__reploPixelLoaded`).\nconst PIXEL_SCRIPT_ID = \"replo:first-party-pixel\";\n\n/**\n * Consent-gated injector for Replo's first-party analytics pixel. The loaded\n * script sets `window.ReploPixel`, which the always-on `ReploSink` forwards\n * events into, so gating it on `analytics` consent keeps the first-party sink\n * consent-correct without the pixel loading unconditionally in `<head>` the way\n * the legacy scaffold does. `analytics` consent here matches the\n * `firstPartyAllowed` gate that controls whether `ReploSink` is created at all.\n *\n * Under a consent platform the tag is rendered regardless and `InjectedScript`\n * stamps the blocking attributes at mount time, since delegation is not yet\n * set here.\n */\nexport function ReploPixelScript({\n pixelUrl,\n apiUrl,\n projectId,\n}: {\n pixelUrl: string;\n apiUrl: string;\n projectId: string;\n}) {\n const consent = useConsent();\n if (\n !findDelegatedPlatform() &&\n !isConsentAllowed({ state: consent, requiredConsent: [\"analytics\"] })\n ) {\n return null;\n }\n\n const descriptors: ScriptTagDescriptor[] = [\n {\n kind: \"external\",\n src: `${pixelUrl}/latest.js`,\n attributes: {\n \"data-api-url\": apiUrl,\n \"data-project-id\": projectId,\n },\n },\n ];\n\n return (\n <InjectedScript\n baseId={PIXEL_SCRIPT_ID}\n descriptors={descriptors}\n requiredConsent={[\"analytics\"]}\n />\n );\n}\n"],
5
- "mappings": ";AAqDI;AAjDJ,SAAS,6BAA6B;AACtC,SAAS,kBAAkB,kBAAkB;AAC7C,SAAS,sBAAsB;AAI/B,MAAM,kBAAkB;AAcjB,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,QAAM,UAAU,WAAW;AAC3B,MACE,CAAC,sBAAsB,KACvB,CAAC,iBAAiB,EAAE,OAAO,SAAS,iBAAiB,CAAC,WAAW,EAAE,CAAC,GACpE;AACA,WAAO;AAAA,EACT;AAEA,QAAM,cAAqC;AAAA,IACzC;AAAA,MACE,MAAM;AAAA,MACN,KAAK,GAAG,QAAQ;AAAA,MAChB,YAAY;AAAA,QACV,gBAAgB;AAAA,QAChB,mBAAmB;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,QAAQ;AAAA,MACR;AAAA,MACA,iBAAiB,CAAC,WAAW;AAAA;AAAA,EAC/B;AAEJ;",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../analytics/sinks/converge-event-mapper.ts"],
4
- "sourcesContent": ["import type { PurchasePayload } from \"../analytics-sink\";\n\nimport { z } from \"zod\";\n\ntype AnalyticsRecord = Record<string, unknown>;\n\nconst analyticsRecordSchema = z.record(z.string(), z.unknown());\nconst nonEmptyStringSchema = z.union([\n z.string().min(1),\n z.number().finite().transform(String),\n]);\nconst finiteNumberSchema = z.union([\n z.number().finite(),\n z.string().trim().min(1).transform(Number).pipe(z.number().finite()),\n]);\nconst couponSchema = z.union([z.string(), z.array(z.string())]);\n\nexport type ConvergeProductProperties = {\n product_id: string;\n name: string;\n price: number;\n currency: string;\n variant_id?: string;\n sku?: string;\n variant_name?: string;\n vendor?: string;\n url?: string;\n image_url?: string;\n};\n\ntype ConvergeCartItem = ConvergeProductProperties & { quantity: number };\ntype MappedConvergeProduct = ConvergeProductProperties & {\n quantity?: number;\n};\n\nexport type ConvergeCartProperties = {\n total_price: number;\n total_tax: number;\n total_shipping: number;\n currency: string;\n items?: ConvergeCartItem[];\n total_discount?: number;\n coupon?: string | string[];\n};\n\nexport type ConvergeOrderProperties = ConvergeCartProperties & { id: string };\n\nexport type ConvergeCollectionProperties = {\n id: string;\n name: string;\n description?: string;\n items?: ConvergeProductProperties[];\n};\n\nfunction parseRecord(value: unknown): AnalyticsRecord | null {\n const result = analyticsRecordSchema.safeParse(value);\n return result.success ? result.data : null;\n}\n\nfunction firstValue(record: AnalyticsRecord, keys: string[]): unknown {\n for (const key of keys) {\n const value = record[key];\n if (value !== null && value !== undefined) {\n return value;\n }\n }\n return undefined;\n}\n\nfunction parseString(value: unknown): string | undefined {\n const result = nonEmptyStringSchema.safeParse(value);\n return result.success ? result.data : undefined;\n}\n\nfunction numberValue(value: unknown): number | undefined {\n const result = finiteNumberSchema.safeParse(value);\n return result.success ? result.data : undefined;\n}\n\nfunction stringFrom(record: AnalyticsRecord, keys: string[]) {\n return parseString(firstValue(record, keys));\n}\n\nfunction numberFrom(record: AnalyticsRecord, keys: string[]) {\n return numberValue(firstValue(record, keys));\n}\n\nfunction moneyFrom(value: unknown) {\n const record = parseRecord(value);\n if (!record) {\n return null;\n }\n return {\n amount: numberFrom(record, [\"amount\"]),\n currency: stringFrom(record, [\"currencyCode\", \"currency\"]),\n };\n}\n\nfunction optionalProductProperties({\n source,\n variant,\n product,\n}: {\n source: AnalyticsRecord;\n variant: AnalyticsRecord;\n product: AnalyticsRecord;\n}) {\n return {\n variant_id:\n stringFrom(source, [\"variant_id\", \"variantId\"]) ??\n stringFrom(variant, [\"id\"]),\n sku:\n stringFrom(source, [\"sku\", \"variantSku\"]) ?? stringFrom(variant, [\"sku\"]),\n variant_name:\n stringFrom(source, [\"variant_name\", \"variantTitle\"]) ??\n stringFrom(variant, [\"title\"]),\n vendor:\n stringFrom(source, [\"vendor\", \"productVendor\"]) ??\n stringFrom(product, [\"vendor\"]),\n url:\n stringFrom(source, [\"url\", \"productUrl\"]) ?? stringFrom(product, [\"url\"]),\n image_url:\n stringFrom(source, [\"image_url\", \"imageUrl\", \"productImageUrl\"]) ??\n stringFrom(product, [\"imageUrl\", \"image_url\"]),\n };\n}\n\nfunction withoutUndefined<RecordType extends AnalyticsRecord>(\n record: RecordType,\n): Partial<RecordType> {\n // oxlint-disable-next-line replo/no-as-cast -- Object.fromEntries cannot preserve the input key mapping after filtering\n return Object.fromEntries(\n Object.entries(record).filter(([, value]) => value !== undefined),\n ) as Partial<RecordType>;\n}\n\nfunction mapProduct(\n value: unknown,\n defaults: { currency?: string; quantity?: number } = {},\n): MappedConvergeProduct | null {\n const source = parseRecord(value);\n if (!source) {\n return null;\n }\n\n const variant = parseRecord(source.variant) ?? {};\n const product =\n parseRecord(variant.product) ?? parseRecord(source.product) ?? {};\n const variantPrice = moneyFrom(variant.price);\n const sourcePrice = moneyFrom(source.price);\n\n const productId =\n stringFrom(source, [\"product_id\", \"productId\"]) ??\n stringFrom(product, [\"id\"]);\n const name =\n stringFrom(source, [\"name\", \"productTitle\", \"title\"]) ??\n stringFrom(product, [\"title\", \"name\"]);\n const price =\n numberFrom(source, [\"price\"]) ??\n sourcePrice?.amount ??\n variantPrice?.amount;\n const currency =\n stringFrom(source, [\"currency\", \"currencyCode\"]) ??\n sourcePrice?.currency ??\n variantPrice?.currency ??\n defaults.currency;\n\n if (!productId || !name || price === undefined || !currency) {\n return null;\n }\n\n const quantity = numberFrom(source, [\"quantity\"]) ?? defaults.quantity;\n const mapped: MappedConvergeProduct = {\n product_id: productId,\n name,\n price,\n currency,\n ...withoutUndefined(\n optionalProductProperties({ source, variant, product }),\n ),\n ...(quantity === undefined ? {} : { quantity }),\n };\n return mapped;\n}\n\nfunction listFrom(record: AnalyticsRecord, keys: string[]): unknown[] {\n const value = firstValue(record, keys);\n return Array.isArray(value) ? value : [];\n}\n\nfunction couponFrom(record: AnalyticsRecord): string | string[] | undefined {\n const result = couponSchema.safeParse(\n firstValue(record, [\"coupon\", \"discountCode\"]),\n );\n return result.success ? result.data : undefined;\n}\n\nexport function mapConvergeProduct(\n data: AnalyticsRecord,\n): ConvergeProductProperties | null {\n const product = mapProduct(data);\n if (!product) {\n return null;\n }\n const { quantity: _quantity, ...properties } = product;\n return properties;\n}\n\nexport function mapConvergeCartItem(\n data: AnalyticsRecord,\n): ConvergeCartItem | null {\n const product = mapProduct(data, { quantity: 1 });\n if (!product || product.quantity === undefined) {\n return null;\n }\n return { ...product, quantity: product.quantity };\n}\n\nexport function mapConvergeCollection(\n data: AnalyticsRecord,\n): ConvergeCollectionProperties | null {\n const id = stringFrom(data, [\"id\", \"collectionId\"]);\n const name = stringFrom(data, [\"name\", \"collectionTitle\"]);\n if (!id || !name) {\n return null;\n }\n const items = listFrom(data, [\"items\", \"products\"])\n .map((item) => mapProduct(item))\n .filter((item): item is MappedConvergeProduct => item !== null)\n .map(({ quantity: _quantity, ...item }) => item);\n\n return {\n id,\n name,\n ...withoutUndefined({\n description: stringFrom(data, [\"description\", \"collectionDescription\"]),\n items: items.length > 0 ? items : undefined,\n }),\n };\n}\n\nexport function mapConvergeCart(\n data: AnalyticsRecord,\n): ConvergeCartProperties | null {\n const totalPriceMoney = moneyFrom(firstValue(data, [\"totalPrice\"]));\n const subtotalMoney = moneyFrom(firstValue(data, [\"subtotalPrice\"]));\n const currency =\n stringFrom(data, [\"currency\", \"currencyCode\"]) ??\n totalPriceMoney?.currency ??\n subtotalMoney?.currency;\n const totalPrice =\n numberFrom(data, [\"total_price\", \"totalAmount\", \"subtotal\"]) ??\n totalPriceMoney?.amount ??\n subtotalMoney?.amount;\n if (totalPrice === undefined || !currency) {\n return null;\n }\n\n const items = listFrom(data, [\"items\", \"lineItems\"])\n .map((item) => mapProduct(item, { currency, quantity: 1 }))\n .filter((item): item is ConvergeCartItem => item?.quantity !== undefined);\n\n return {\n total_price: totalPrice,\n total_tax: numberFrom(data, [\"total_tax\", \"totalTax\"]) ?? 0,\n total_shipping: numberFrom(data, [\"total_shipping\", \"totalShipping\"]) ?? 0,\n currency,\n ...withoutUndefined({\n total_discount: numberFrom(data, [\"total_discount\", \"totalDiscount\"]),\n coupon: couponFrom(data),\n items: items.length > 0 ? items : undefined,\n }),\n };\n}\n\nexport function mapConvergeOrder({\n amount,\n currency,\n data,\n}: PurchasePayload): ConvergeOrderProperties | null {\n const id = stringFrom(data, [\"id\", \"order_id\", \"orderId\"]);\n if (!id) {\n return null;\n }\n const cart = mapConvergeCart({\n ...data,\n total_price: amount,\n currency,\n });\n return cart ? { id, ...cart } : null;\n}\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../analytics/sinks/converge-sink.ts"],
4
- "sourcesContent": ["import type {\n AnalyticsSink,\n DataPayload,\n PurchasePayload,\n} from \"../analytics-sink\";\nimport type { PageMetadata } from \"../utils/navigation-tracker\";\n\nimport { createAnalyticsQueue } from \"../utils/analytics-utils\";\nimport {\n mapConvergeCart,\n mapConvergeCartItem,\n mapConvergeCollection,\n mapConvergeOrder,\n mapConvergeProduct,\n} from \"./converge-event-mapper\";\n\ntype ConvergeCall =\n | {\n method: \"track\";\n eventName: string;\n properties?: Record<string, unknown>;\n }\n | {\n method: \"forward\";\n eventName: \"Placed Order\";\n eventID: string;\n properties: Record<string, unknown>;\n };\n\ndeclare global {\n interface Window {\n cvg?: (call: ConvergeCall) => void;\n }\n}\n\nfunction findConvergeQueue(): ((call: ConvergeCall) => void) | null {\n if (typeof window === \"undefined\") {\n return null;\n }\n return window.cvg ?? null;\n}\n\n/**\n * The consent-gated Converge snippet owns the initial pageview. This sink maps\n * Replo's analytics payloads to Converge's strict event spec and adds SPA\n * pageviews after client-side navigations.\n */\nexport class ConvergeSink implements AnalyticsSink {\n private send = createAnalyticsQueue<ConvergeCall>({\n isReady: () => Boolean(findConvergeQueue()),\n send: (call) => {\n findConvergeQueue()?.(call);\n },\n queueName: \"Converge\",\n });\n\n private trackIfValid(\n eventName: string,\n properties: Record<string, unknown> | null,\n ) {\n if (!properties) {\n console.warn(`[analytics] skipped invalid Converge ${eventName} event`);\n return;\n }\n this.send({ method: \"track\", eventName, properties });\n }\n\n async pageView(metadata?: PageMetadata) {\n if (metadata?.navigationType === \"initial\") {\n return;\n }\n this.send({ method: \"track\", eventName: \"$page_load\" });\n }\n\n async purchase(payload: PurchasePayload) {\n const properties = mapConvergeOrder(payload);\n if (!properties) {\n console.warn(\"[analytics] skipped invalid Converge Placed Order event\");\n return;\n }\n this.send({\n method: \"forward\",\n eventName: \"Placed Order\",\n eventID: properties.id,\n properties,\n });\n }\n\n async click() {\n // No Converge equivalent\n }\n\n async productViewed({ data }: DataPayload) {\n this.trackIfValid(\"Viewed Product\", mapConvergeProduct(data));\n }\n\n async addToCart({ data }: DataPayload) {\n this.trackIfValid(\"Added To Cart\", mapConvergeCartItem(data));\n }\n\n async removeFromCart({ data }: DataPayload) {\n this.trackIfValid(\"Removed From Cart\", mapConvergeCartItem(data));\n }\n\n async viewCart({ data }: DataPayload) {\n this.trackIfValid(\"Viewed Cart\", mapConvergeCart(data));\n }\n\n async startCheckout({ data }: DataPayload) {\n this.trackIfValid(\"Started Checkout\", mapConvergeCart(data));\n }\n\n async viewCollection({ data }: DataPayload) {\n this.trackIfValid(\"Viewed Collection\", mapConvergeCollection(data));\n }\n}\n"],
5
- "mappings": "AAOA,SAAS,4BAA4B;AACrC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAqBP,SAAS,oBAA2D;AAClE,MAAI,OAAO,WAAW,aAAa;AACjC,WAAO;AAAA,EACT;AACA,SAAO,OAAO,OAAO;AACvB;AAOO,MAAM,aAAsC;AAAA,EACzC,OAAO,qBAAmC;AAAA,IAChD,SAAS,MAAM,QAAQ,kBAAkB,CAAC;AAAA,IAC1C,MAAM,CAAC,SAAS;AACd,wBAAkB,IAAI,IAAI;AAAA,IAC5B;AAAA,IACA,WAAW;AAAA,EACb,CAAC;AAAA,EAEO,aACN,WACA,YACA;AACA,QAAI,CAAC,YAAY;AACf,cAAQ,KAAK,wCAAwC,SAAS,QAAQ;AACtE;AAAA,IACF;AACA,SAAK,KAAK,EAAE,QAAQ,SAAS,WAAW,WAAW,CAAC;AAAA,EACtD;AAAA,EAEA,MAAM,SAAS,UAAyB;AACtC,QAAI,UAAU,mBAAmB,WAAW;AAC1C;AAAA,IACF;AACA,SAAK,KAAK,EAAE,QAAQ,SAAS,WAAW,aAAa,CAAC;AAAA,EACxD;AAAA,EAEA,MAAM,SAAS,SAA0B;AACvC,UAAM,aAAa,iBAAiB,OAAO;AAC3C,QAAI,CAAC,YAAY;AACf,cAAQ,KAAK,yDAAyD;AACtE;AAAA,IACF;AACA,SAAK,KAAK;AAAA,MACR,QAAQ;AAAA,MACR,WAAW;AAAA,MACX,SAAS,WAAW;AAAA,MACpB;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,QAAQ;AAAA,EAEd;AAAA,EAEA,MAAM,cAAc,EAAE,KAAK,GAAgB;AACzC,SAAK,aAAa,kBAAkB,mBAAmB,IAAI,CAAC;AAAA,EAC9D;AAAA,EAEA,MAAM,UAAU,EAAE,KAAK,GAAgB;AACrC,SAAK,aAAa,iBAAiB,oBAAoB,IAAI,CAAC;AAAA,EAC9D;AAAA,EAEA,MAAM,eAAe,EAAE,KAAK,GAAgB;AAC1C,SAAK,aAAa,qBAAqB,oBAAoB,IAAI,CAAC;AAAA,EAClE;AAAA,EAEA,MAAM,SAAS,EAAE,KAAK,GAAgB;AACpC,SAAK,aAAa,eAAe,gBAAgB,IAAI,CAAC;AAAA,EACxD;AAAA,EAEA,MAAM,cAAc,EAAE,KAAK,GAAgB;AACzC,SAAK,aAAa,oBAAoB,gBAAgB,IAAI,CAAC;AAAA,EAC7D;AAAA,EAEA,MAAM,eAAe,EAAE,KAAK,GAAgB;AAC1C,SAAK,aAAa,qBAAqB,sBAAsB,IAAI,CAAC;AAAA,EACpE;AACF;",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../analytics/sinks/elevar-sink.ts"],
4
- "sourcesContent": ["import type { AnalyticsSink, DataPayload } from \"../analytics-sink\";\nimport type { PageMetadata } from \"../utils/navigation-tracker\";\n\nimport { z } from \"zod\";\n\n/**\n * Elevar's data layer contract for headless storefronts:\n * https://docs.getelevar.com/docs/headless-implementing-the-data-layer\n * Every value is a string, `dl_user_data` must precede every other event on a\n * page, and events are only processed when pushed to `window.ElevarDataLayer`.\n */\ntype ElevarProduct = {\n id: string;\n name: string;\n brand: string;\n category: string;\n variant: string;\n price: string;\n quantity?: string;\n position?: string;\n list: string;\n product_id: string;\n variant_id: string;\n compare_at_price: string;\n image: string;\n url?: string;\n};\n\ntype ElevarUserProperties = { visitor_type: \"guest\" | \"logged_in\" };\n\ntype ElevarDataLayerEvent = {\n event: string;\n user_properties: ElevarUserProperties;\n cart_total?: string;\n ecommerce: Record<string, unknown>;\n};\n\ndeclare global {\n interface Window {\n ElevarDataLayer?: ElevarDataLayerEvent[];\n ElevarInvalidateContext?: () => void;\n }\n}\n\n// The storefront has no customer identity to hand Elevar; logged-in customer\n// fields come from the merchant's Shopify source on Elevar's side.\nconst GUEST_USER_PROPERTIES: ElevarUserProperties = { visitor_type: \"guest\" };\n\n// Matches the cart provider's own fallback when a cart has no currency yet.\nconst FALLBACK_CURRENCY_CODE = \"USD\";\n\nconst nonEmptyStringSchema = z\n .union([z.string().min(1), z.number().finite().transform(String)])\n .optional()\n .catch(undefined);\nconst finiteNumberSchema = z\n .union([\n z.number().finite(),\n z.string().trim().min(1).transform(Number).pipe(z.number().finite()),\n ])\n .optional()\n .catch(undefined);\n\n/** The flat product fields the SDK's cart provider and product-view hook emit. */\nconst analyticsProductSchema = z.object({\n productId: nonEmptyStringSchema,\n productTitle: nonEmptyStringSchema,\n variantId: nonEmptyStringSchema,\n variantTitle: nonEmptyStringSchema,\n variantSku: nonEmptyStringSchema,\n price: finiteNumberSchema,\n currency: nonEmptyStringSchema,\n quantity: finiteNumberSchema,\n});\n\n/** The nested line shape the starter site's checkout button emits. */\nconst checkoutLineSchema = z.object({\n quantity: finiteNumberSchema,\n merchandise: z\n .object({\n id: nonEmptyStringSchema,\n title: nonEmptyStringSchema,\n sku: nonEmptyStringSchema,\n price: z\n .object({\n amount: finiteNumberSchema,\n currencyCode: nonEmptyStringSchema,\n })\n .optional(),\n product: z\n .object({ id: nonEmptyStringSchema, title: nonEmptyStringSchema })\n .optional(),\n })\n .optional(),\n});\n\nconst productListSchema = z.array(z.unknown()).optional().catch(undefined);\n\nconst cartPayloadSchema = z.object({\n currency: nonEmptyStringSchema,\n currencyCode: nonEmptyStringSchema,\n subtotal: finiteNumberSchema,\n totalPrice: z.object({ amount: finiteNumberSchema }).optional(),\n lineItems: productListSchema,\n});\n\nconst collectionPayloadSchema = z.object({\n currency: nonEmptyStringSchema,\n currencyCode: nonEmptyStringSchema,\n products: productListSchema,\n});\n\ntype AnalyticsProduct = z.infer<typeof analyticsProductSchema>;\n\nfunction formatMoney(amount: number) {\n return amount.toFixed(2);\n}\n\n// Elevar's Shopify destinations key on legacy numeric ids, while the cart\n// carries Storefront API GIDs (`gid://shopify/ProductVariant/123`).\nfunction legacyResourceId(id: string) {\n return id.replace(/^gid:\\/\\/shopify\\/\\w+\\//, \"\");\n}\n\nfunction parseCheckoutLine(line: unknown): AnalyticsProduct | null {\n const parsed = checkoutLineSchema.safeParse(line);\n if (!parsed.success || !parsed.data.merchandise) {\n return null;\n }\n const { merchandise, quantity } = parsed.data;\n return {\n productId: merchandise.product?.id,\n productTitle: merchandise.product?.title,\n variantId: merchandise.id,\n variantTitle: merchandise.title,\n variantSku: merchandise.sku,\n price: merchandise.price?.amount,\n currency: merchandise.price?.currencyCode,\n quantity,\n };\n}\n\nfunction parseAnalyticsProduct(value: unknown): AnalyticsProduct | null {\n const parsed = analyticsProductSchema.safeParse(value);\n if (!parsed.success) {\n return null;\n }\n return parsed.data.productId ? parsed.data : parseCheckoutLine(value);\n}\n\n/**\n * Brand, category, compare-at price, image, and the originating collection\n * path are not part of Replo's analytics payloads today, so they carry the\n * empty-value fallbacks Elevar's spec prescribes.\n */\nfunction toElevarProduct(\n product: AnalyticsProduct,\n options: { list: string; withQuantity: boolean; position?: number },\n): ElevarProduct | null {\n const productId = product.productId;\n if (!productId) {\n return null;\n }\n const variantId = product.variantId ?? productId;\n return {\n id: product.variantSku ?? legacyResourceId(variantId),\n name: product.productTitle ?? \"\",\n brand: \"\",\n category: \"\",\n variant: product.variantTitle ?? \"\",\n price: formatMoney(product.price ?? 0),\n ...(options.withQuantity\n ? { quantity: String(product.quantity ?? 1) }\n : {}),\n ...(options.position === undefined\n ? {}\n : { position: String(options.position) }),\n list: options.list,\n product_id: legacyResourceId(productId),\n variant_id: legacyResourceId(variantId),\n compare_at_price: \"0.0\",\n image: \"\",\n };\n}\n\nfunction toElevarProducts(\n products: unknown[],\n options: { list: string; withQuantity: boolean; currency?: string },\n): { products: ElevarProduct[]; currencyCode: string } {\n const parsedProducts = products\n .map(parseAnalyticsProduct)\n .filter((product): product is AnalyticsProduct => product !== null);\n const currencyCode =\n options.currency ??\n parsedProducts.find((product) => product.currency)?.currency ??\n FALLBACK_CURRENCY_CODE;\n const elevarProducts = parsedProducts\n .map((product, index) => {\n return toElevarProduct(product, { ...options, position: index + 1 });\n })\n .filter((product): product is ElevarProduct => product !== null);\n return { products: elevarProducts, currencyCode };\n}\n\nfunction pushToElevarDataLayer(event: ElevarDataLayerEvent) {\n if (typeof window === \"undefined\") {\n return;\n }\n window.ElevarDataLayer = window.ElevarDataLayer ?? [];\n window.ElevarDataLayer.push(event);\n}\n\n// Sinks are rebuilt whenever consent or script registration changes, so the\n// \"already announced this page\" marker lives outside the instance; otherwise\n// every rebuild would push a second `dl_user_data` for the same page.\nlet lastUserDataUrl: string | null = null;\n\nfunction pushUserData() {\n lastUserDataUrl = window.location.href;\n // Cart contents live in the cart provider's React state, which the sink\n // cannot read, so the base event reports an empty cart. Cart totals reach\n // Elevar on `dl_view_cart` instead.\n pushToElevarDataLayer({\n event: \"dl_user_data\",\n cart_total: formatMoney(0),\n user_properties: GUEST_USER_PROPERTIES,\n ecommerce: {\n currencyCode: FALLBACK_CURRENCY_CODE,\n cart_contents: { products: [] },\n },\n });\n}\n\nfunction ensureUserDataForCurrentPage() {\n if (\n typeof window === \"undefined\" ||\n lastUserDataUrl === window.location.href\n ) {\n return;\n }\n pushUserData();\n}\n\n/**\n * Pushes Elevar's `dl_*` data layer events for a storefront whose Elevar\n * headless snippet is installed as a `snippet` script entry. The snippet only\n * forwards what the page pushes to `window.ElevarDataLayer`, and a Replo page\n * (unlike a Shopify theme) pushes nothing on its own.\n */\nexport class ElevarSink implements AnalyticsSink {\n constructor() {\n // The snippet registers after the initial pageview has already been\n // broadcast, so the sink announces the page it was created on itself.\n ensureUserDataForCurrentPage();\n }\n\n private pushEcommerceEvent(\n event: string,\n ecommerce: Record<string, unknown>,\n cartTotal?: string,\n ) {\n ensureUserDataForCurrentPage();\n pushToElevarDataLayer({\n event,\n user_properties: GUEST_USER_PROPERTIES,\n ...(cartTotal === undefined ? {} : { cart_total: cartTotal }),\n ecommerce,\n });\n }\n\n private pushProductEvent(\n event: string,\n action: \"detail\" | \"add\" | \"remove\",\n { data }: DataPayload,\n options: { withQuantity: boolean; withUrl?: boolean },\n ) {\n const product = parseAnalyticsProduct(data);\n const elevarProduct =\n product &&\n toElevarProduct(product, {\n list: \"\",\n withQuantity: options.withQuantity,\n });\n if (!elevarProduct) {\n console.warn(`[analytics] skipped Elevar ${event}: no product id`);\n return;\n }\n if (options.withUrl) {\n // The add-to-cart payload has no product URL; the page the shopper added\n // from is the closest available stand-in.\n elevarProduct.url = window.location.href;\n }\n this.pushEcommerceEvent(event, {\n currencyCode: product.currency ?? FALLBACK_CURRENCY_CODE,\n [action]: {\n actionField:\n action === \"detail\"\n ? { list: window.location.pathname, action }\n : { list: window.location.pathname },\n products: [elevarProduct],\n },\n });\n }\n\n async pageView(metadata?: PageMetadata) {\n if (typeof window === \"undefined\") {\n return;\n }\n // A repeated pageView for the current URL must not invalidate Elevar's\n // context and re-announce the page.\n if (\n metadata?.navigationType === \"soft\" &&\n lastUserDataUrl !== window.location.href\n ) {\n window.ElevarInvalidateContext?.();\n }\n ensureUserDataForCurrentPage();\n }\n\n async purchase() {\n // Orders complete on Shopify-hosted checkout, where the merchant's Elevar\n // Shopify source reports dl_purchase; a storefront copy would double count.\n }\n\n async click() {\n // Replo's click event carries no product, so there is no dl_select_item to build.\n }\n\n async productViewed(payload: DataPayload) {\n this.pushProductEvent(\"dl_view_item\", \"detail\", payload, {\n withQuantity: false,\n });\n }\n\n async addToCart(payload: DataPayload) {\n this.pushProductEvent(\"dl_add_to_cart\", \"add\", payload, {\n withQuantity: true,\n withUrl: true,\n });\n }\n\n async removeFromCart(payload: DataPayload) {\n this.pushProductEvent(\"dl_remove_from_cart\", \"remove\", payload, {\n withQuantity: true,\n });\n }\n\n async viewCart({ data }: DataPayload) {\n const cart = cartPayloadSchema.safeParse(data);\n if (!cart.success) {\n return;\n }\n const { products, currencyCode } = toElevarProducts(\n cart.data.lineItems ?? [],\n {\n list: \"\",\n withQuantity: true,\n currency: cart.data.currency ?? cart.data.currencyCode,\n },\n );\n this.pushEcommerceEvent(\n \"dl_view_cart\",\n {\n currencyCode,\n actionField: { list: \"Shopping Cart\" },\n impressions: products,\n },\n formatMoney(cart.data.subtotal ?? cart.data.totalPrice?.amount ?? 0),\n );\n }\n\n async startCheckout({ data }: DataPayload) {\n const cart = cartPayloadSchema.safeParse(data);\n if (!cart.success) {\n return;\n }\n const { products, currencyCode } = toElevarProducts(\n cart.data.lineItems ?? [],\n {\n list: \"\",\n withQuantity: true,\n currency: cart.data.currencyCode ?? cart.data.currency,\n },\n );\n this.pushEcommerceEvent(\"dl_begin_checkout\", {\n currencyCode,\n checkout: {\n actionField: { step: \"1\", action: \"checkout\" },\n products,\n },\n });\n }\n\n async viewCollection({ data }: DataPayload) {\n const collection = collectionPayloadSchema.safeParse(data);\n if (!collection.success) {\n return;\n }\n const { products, currencyCode } = toElevarProducts(\n collection.data.products ?? [],\n {\n list: window.location.pathname,\n withQuantity: false,\n currency: collection.data.currency ?? collection.data.currencyCode,\n },\n );\n this.pushEcommerceEvent(\"dl_view_item_list\", {\n currencyCode,\n impressions: products,\n });\n }\n}\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../analytics/sinks/ga4-sink.ts"],
4
- "sourcesContent": ["import type {\n AnalyticsSink,\n DataPayload,\n PurchasePayload,\n} from \"../analytics-sink\";\nimport type { PageMetadata } from \"../utils/navigation-tracker\";\n\nimport { createEventQueue } from \"../utils/analytics-utils\";\n\nexport class GA4Sink implements AnalyticsSink {\n // oxlint-disable-next-line typescript/no-explicit-any -- legacy any, may or may not be needed\n private send: (event: string, params?: Record<string, any>) => void;\n\n constructor() {\n this.send = createEventQueue(\n // Legacy cast - may or may not be necessary\n // oxlint-disable-next-line replo/no-as-cast, typescript/no-explicit-any -- legacy any/cast, may or may not be needed\n () => typeof window !== \"undefined\" && Boolean((window as any).gtag),\n (event, params) => {\n // Legacy cast - may or may not be necessary\n // oxlint-disable-next-line replo/no-as-cast, typescript/no-explicit-any -- legacy any/cast, may or may not be needed\n const gtag = (window as any).gtag;\n gtag(\"event\", event, params);\n },\n \"GA4\",\n );\n }\n\n async pageView(metadata?: PageMetadata) {\n const params = metadata\n ? {\n page_title: metadata.title,\n page_location: metadata.url,\n }\n : {};\n this.send(\"page_view\", params);\n }\n\n async purchase({ amount, currency, data }: PurchasePayload) {\n this.send(\"purchase\", { value: amount, currency, ...data });\n }\n\n async click({ data }: DataPayload) {\n this.send(\"select_content\", data);\n }\n\n async productViewed({ data }: DataPayload) {\n this.send(\"view_item\", {\n value: data.price,\n currency: data.currency,\n ...data,\n });\n }\n\n async addToCart({ data }: DataPayload) {\n this.send(\"add_to_cart\", {\n value: data.price,\n currency: data.currency,\n ...data,\n });\n }\n\n async removeFromCart({ data }: DataPayload) {\n this.send(\"remove_from_cart\", data);\n }\n\n async viewCart({ data }: DataPayload) {\n this.send(\"view_cart\", data);\n }\n\n async startCheckout({ data }: DataPayload) {\n this.send(\"begin_checkout\", data);\n }\n\n async viewCollection({ data }: DataPayload) {\n this.send(\"view_item_list\", data);\n }\n}\n"],
5
- "mappings": "AAOA,SAAS,wBAAwB;AAE1B,MAAM,QAAiC;AAAA;AAAA,EAEpC;AAAA,EAER,cAAc;AACZ,SAAK,OAAO;AAAA;AAAA;AAAA,MAGV,MAAM,OAAO,WAAW,eAAe,QAAS,OAAe,IAAI;AAAA,MACnE,CAAC,OAAO,WAAW;AAGjB,cAAM,OAAQ,OAAe;AAC7B,aAAK,SAAS,OAAO,MAAM;AAAA,MAC7B;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,SAAS,UAAyB;AACtC,UAAM,SAAS,WACX;AAAA,MACE,YAAY,SAAS;AAAA,MACrB,eAAe,SAAS;AAAA,IAC1B,IACA,CAAC;AACL,SAAK,KAAK,aAAa,MAAM;AAAA,EAC/B;AAAA,EAEA,MAAM,SAAS,EAAE,QAAQ,UAAU,KAAK,GAAoB;AAC1D,SAAK,KAAK,YAAY,EAAE,OAAO,QAAQ,UAAU,GAAG,KAAK,CAAC;AAAA,EAC5D;AAAA,EAEA,MAAM,MAAM,EAAE,KAAK,GAAgB;AACjC,SAAK,KAAK,kBAAkB,IAAI;AAAA,EAClC;AAAA,EAEA,MAAM,cAAc,EAAE,KAAK,GAAgB;AACzC,SAAK,KAAK,aAAa;AAAA,MACrB,OAAO,KAAK;AAAA,MACZ,UAAU,KAAK;AAAA,MACf,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,UAAU,EAAE,KAAK,GAAgB;AACrC,SAAK,KAAK,eAAe;AAAA,MACvB,OAAO,KAAK;AAAA,MACZ,UAAU,KAAK;AAAA,MACf,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,eAAe,EAAE,KAAK,GAAgB;AAC1C,SAAK,KAAK,oBAAoB,IAAI;AAAA,EACpC;AAAA,EAEA,MAAM,SAAS,EAAE,KAAK,GAAgB;AACpC,SAAK,KAAK,aAAa,IAAI;AAAA,EAC7B;AAAA,EAEA,MAAM,cAAc,EAAE,KAAK,GAAgB;AACzC,SAAK,KAAK,kBAAkB,IAAI;AAAA,EAClC;AAAA,EAEA,MAAM,eAAe,EAAE,KAAK,GAAgB;AAC1C,SAAK,KAAK,kBAAkB,IAAI;AAAA,EAClC;AACF;",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../analytics/sinks/meta-sink.ts"],
4
- "sourcesContent": ["import type {\n AnalyticsSink,\n DataPayload,\n PurchasePayload,\n} from \"../analytics-sink\";\n\nimport { createEventQueue } from \"../utils/analytics-utils\";\n\nexport class MetaSink implements AnalyticsSink {\n // oxlint-disable-next-line typescript/no-explicit-any -- legacy any, may or may not be needed\n private track: (event: string, params?: Record<string, any>) => void;\n\n constructor() {\n this.track = createEventQueue(\n // Legacy cast - may or may not be necessary\n // oxlint-disable-next-line replo/no-as-cast, typescript/no-explicit-any -- legacy any/cast, may or may not be needed\n () => typeof window !== \"undefined\" && Boolean((window as any).fbq),\n (event, params) => {\n // Legacy cast - may or may not be necessary\n // oxlint-disable-next-line replo/no-as-cast, typescript/no-explicit-any -- legacy any/cast, may or may not be needed\n const fbq = (window as any).fbq;\n fbq(\"track\", event, params);\n },\n \"Meta\",\n );\n }\n\n async pageView() {\n this.track(\"PageView\");\n }\n\n async purchase({ amount, currency, data }: PurchasePayload) {\n this.track(\"Purchase\", { value: amount, currency, ...data });\n }\n\n async click() {\n // No direct equivalent in Meta\n }\n\n async productViewed({ data }: DataPayload) {\n this.track(\"ViewContent\", {\n value: data.price,\n currency: data.currency,\n ...data,\n });\n }\n\n async addToCart({ data }: DataPayload) {\n this.track(\"AddToCart\", {\n value: data.price,\n currency: data.currency,\n ...data,\n });\n }\n\n async removeFromCart() {\n // No direct equivalent in Meta\n }\n\n async viewCart() {\n // No direct equivalent in Meta\n }\n\n async startCheckout({ data }: DataPayload) {\n this.track(\"InitiateCheckout\", {\n value: data.totalPrice?.amount,\n currency: data.currencyCode,\n ...data,\n });\n }\n\n async viewCollection() {\n // No direct equivalent in Meta\n }\n}\n"],
5
- "mappings": "AAMA,SAAS,wBAAwB;AAE1B,MAAM,SAAkC;AAAA;AAAA,EAErC;AAAA,EAER,cAAc;AACZ,SAAK,QAAQ;AAAA;AAAA;AAAA,MAGX,MAAM,OAAO,WAAW,eAAe,QAAS,OAAe,GAAG;AAAA,MAClE,CAAC,OAAO,WAAW;AAGjB,cAAM,MAAO,OAAe;AAC5B,YAAI,SAAS,OAAO,MAAM;AAAA,MAC5B;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,WAAW;AACf,SAAK,MAAM,UAAU;AAAA,EACvB;AAAA,EAEA,MAAM,SAAS,EAAE,QAAQ,UAAU,KAAK,GAAoB;AAC1D,SAAK,MAAM,YAAY,EAAE,OAAO,QAAQ,UAAU,GAAG,KAAK,CAAC;AAAA,EAC7D;AAAA,EAEA,MAAM,QAAQ;AAAA,EAEd;AAAA,EAEA,MAAM,cAAc,EAAE,KAAK,GAAgB;AACzC,SAAK,MAAM,eAAe;AAAA,MACxB,OAAO,KAAK;AAAA,MACZ,UAAU,KAAK;AAAA,MACf,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,UAAU,EAAE,KAAK,GAAgB;AACrC,SAAK,MAAM,aAAa;AAAA,MACtB,OAAO,KAAK;AAAA,MACZ,UAAU,KAAK;AAAA,MACf,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,iBAAiB;AAAA,EAEvB;AAAA,EAEA,MAAM,WAAW;AAAA,EAEjB;AAAA,EAEA,MAAM,cAAc,EAAE,KAAK,GAAgB;AACzC,SAAK,MAAM,oBAAoB;AAAA,MAC7B,OAAO,KAAK,YAAY;AAAA,MACxB,UAAU,KAAK;AAAA,MACf,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,iBAAiB;AAAA,EAEvB;AACF;",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../analytics/sinks/northbeam-sink.ts"],
4
- "sourcesContent": ["import type { AnalyticsSink } from \"../analytics-sink\";\nimport type { PageMetadata } from \"../utils/navigation-tracker\";\n\nimport { createMethodQueue } from \"../utils/analytics-utils\";\n\ntype NorthbeamPixel = Record<string, (...args: unknown[]) => void>;\n\ntype WindowWithNorthbeam = Window & { Northbeam?: NorthbeamPixel };\n\nfunction northbeamPixel(): NorthbeamPixel | null {\n if (typeof window === \"undefined\") {\n return null;\n }\n // oxlint-disable-next-line replo/no-as-cast -- the pixel's method map is an untyped window global; this is the one place it's narrowed to its known shape\n return (window as WindowWithNorthbeam).Northbeam ?? null;\n}\n\n/**\n * The consent-gated Northbeam snippet owns the initial pageview. This sink only\n * adds the virtual pageviews that Northbeam requires for SPA navigations.\n */\nexport class NorthbeamSink implements AnalyticsSink {\n private call = createMethodQueue<NorthbeamPixel>(northbeamPixel, {\n queueName: \"Northbeam\",\n });\n\n async pageView(metadata?: PageMetadata) {\n if (metadata?.navigationType === \"initial\") {\n return;\n }\n this.call(\"trackPageView\");\n }\n\n async purchase() {\n // Northbeam ingests orders server-side via its commerce integrations\n }\n\n async click() {\n // No Northbeam equivalent\n }\n\n async productViewed() {\n // No Northbeam equivalent\n }\n\n async addToCart() {\n // No Northbeam equivalent\n }\n\n async removeFromCart() {\n // No Northbeam equivalent\n }\n\n async viewCart() {\n // No Northbeam equivalent\n }\n\n async startCheckout() {\n // No Northbeam equivalent\n }\n\n async viewCollection() {\n // No Northbeam equivalent\n }\n}\n"],
5
- "mappings": "AAGA,SAAS,yBAAyB;AAMlC,SAAS,iBAAwC;AAC/C,MAAI,OAAO,WAAW,aAAa;AACjC,WAAO;AAAA,EACT;AAEA,SAAQ,OAA+B,aAAa;AACtD;AAMO,MAAM,cAAuC;AAAA,EAC1C,OAAO,kBAAkC,gBAAgB;AAAA,IAC/D,WAAW;AAAA,EACb,CAAC;AAAA,EAED,MAAM,SAAS,UAAyB;AACtC,QAAI,UAAU,mBAAmB,WAAW;AAC1C;AAAA,IACF;AACA,SAAK,KAAK,eAAe;AAAA,EAC3B;AAAA,EAEA,MAAM,WAAW;AAAA,EAEjB;AAAA,EAEA,MAAM,QAAQ;AAAA,EAEd;AAAA,EAEA,MAAM,gBAAgB;AAAA,EAEtB;AAAA,EAEA,MAAM,YAAY;AAAA,EAElB;AAAA,EAEA,MAAM,iBAAiB;AAAA,EAEvB;AAAA,EAEA,MAAM,WAAW;AAAA,EAEjB;AAAA,EAEA,MAAM,gBAAgB;AAAA,EAEtB;AAAA,EAEA,MAAM,iBAAiB;AAAA,EAEvB;AACF;",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../analytics/sinks/pinterest-sink.ts"],
4
- "sourcesContent": ["import type {\n AnalyticsSink,\n DataPayload,\n PurchasePayload,\n} from \"../analytics-sink\";\n\nimport { createEventQueue } from \"../utils/analytics-utils\";\n\nexport class PinterestSink implements AnalyticsSink {\n // oxlint-disable-next-line typescript/no-explicit-any -- legacy any, may or may not be needed\n private track: (event: string, params?: Record<string, any>) => void;\n\n constructor() {\n this.track = createEventQueue(\n // Legacy cast - may or may not be necessary\n // oxlint-disable-next-line replo/no-as-cast, typescript/no-explicit-any -- legacy any/cast, may or may not be needed\n () => typeof window !== \"undefined\" && Boolean((window as any).pintrk),\n (event, params) => {\n // Legacy cast - may or may not be necessary\n // oxlint-disable-next-line replo/no-as-cast, typescript/no-explicit-any -- legacy any/cast, may or may not be needed\n const pintrk = (window as any).pintrk;\n pintrk(\"track\", event, params);\n },\n \"Pinterest\",\n );\n }\n\n async pageView() {\n this.track(\"pagevisit\");\n }\n\n async purchase({ amount, currency, data }: PurchasePayload) {\n this.track(\"checkout\", {\n value: amount,\n currency,\n order_quantity: data.quantity ?? 1,\n order_id: data.order_id,\n ...data,\n });\n }\n\n async click({ data }: DataPayload) {\n this.track(\"custom\", data);\n }\n\n async productViewed({ data }: DataPayload) {\n this.track(\"pagevisit\", {\n product_id: data.product_id,\n product_category: data.category,\n product_name: data.name,\n product_price: data.price,\n currency: data.currency,\n ...data,\n });\n }\n\n async addToCart({ data }: DataPayload) {\n this.track(\"addtocart\", {\n value: data.price,\n currency: data.currency,\n order_quantity: data.quantity ?? 1,\n product_id: data.product_id,\n product_category: data.category,\n product_name: data.name,\n ...data,\n });\n }\n\n async removeFromCart() {\n // No direct equivalent in Pinterest\n }\n\n async viewCart() {\n this.track(\"pagevisit\");\n }\n\n async startCheckout({ data }: DataPayload) {\n this.track(\"checkout\", {\n value: data.price,\n currency: data.currency,\n order_quantity: data.quantity,\n ...data,\n });\n }\n\n async viewCollection({ data }: DataPayload) {\n this.track(\"viewcategory\", {\n product_category: data.category,\n ...data,\n });\n }\n}\n"],
5
- "mappings": "AAMA,SAAS,wBAAwB;AAE1B,MAAM,cAAuC;AAAA;AAAA,EAE1C;AAAA,EAER,cAAc;AACZ,SAAK,QAAQ;AAAA;AAAA;AAAA,MAGX,MAAM,OAAO,WAAW,eAAe,QAAS,OAAe,MAAM;AAAA,MACrE,CAAC,OAAO,WAAW;AAGjB,cAAM,SAAU,OAAe;AAC/B,eAAO,SAAS,OAAO,MAAM;AAAA,MAC/B;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,WAAW;AACf,SAAK,MAAM,WAAW;AAAA,EACxB;AAAA,EAEA,MAAM,SAAS,EAAE,QAAQ,UAAU,KAAK,GAAoB;AAC1D,SAAK,MAAM,YAAY;AAAA,MACrB,OAAO;AAAA,MACP;AAAA,MACA,gBAAgB,KAAK,YAAY;AAAA,MACjC,UAAU,KAAK;AAAA,MACf,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,MAAM,EAAE,KAAK,GAAgB;AACjC,SAAK,MAAM,UAAU,IAAI;AAAA,EAC3B;AAAA,EAEA,MAAM,cAAc,EAAE,KAAK,GAAgB;AACzC,SAAK,MAAM,aAAa;AAAA,MACtB,YAAY,KAAK;AAAA,MACjB,kBAAkB,KAAK;AAAA,MACvB,cAAc,KAAK;AAAA,MACnB,eAAe,KAAK;AAAA,MACpB,UAAU,KAAK;AAAA,MACf,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,UAAU,EAAE,KAAK,GAAgB;AACrC,SAAK,MAAM,aAAa;AAAA,MACtB,OAAO,KAAK;AAAA,MACZ,UAAU,KAAK;AAAA,MACf,gBAAgB,KAAK,YAAY;AAAA,MACjC,YAAY,KAAK;AAAA,MACjB,kBAAkB,KAAK;AAAA,MACvB,cAAc,KAAK;AAAA,MACnB,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,iBAAiB;AAAA,EAEvB;AAAA,EAEA,MAAM,WAAW;AACf,SAAK,MAAM,WAAW;AAAA,EACxB;AAAA,EAEA,MAAM,cAAc,EAAE,KAAK,GAAgB;AACzC,SAAK,MAAM,YAAY;AAAA,MACrB,OAAO,KAAK;AAAA,MACZ,UAAU,KAAK;AAAA,MACf,gBAAgB,KAAK;AAAA,MACrB,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,eAAe,EAAE,KAAK,GAAgB;AAC1C,SAAK,MAAM,gBAAgB;AAAA,MACzB,kBAAkB,KAAK;AAAA,MACvB,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AACF;",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../analytics/sinks/reddit-sink.ts"],
4
- "sourcesContent": ["import type {\n AnalyticsSink,\n DataPayload,\n PurchasePayload,\n} from \"../analytics-sink\";\n\nimport { createEventQueue } from \"../utils/analytics-utils\";\n\nexport class RedditSink implements AnalyticsSink {\n // oxlint-disable-next-line typescript/no-explicit-any -- legacy any, may or may not be needed\n private track: (event: string, params?: Record<string, any>) => void;\n\n constructor() {\n this.track = createEventQueue(\n // Legacy cast - may or may not be necessary\n // oxlint-disable-next-line replo/no-as-cast, typescript/no-explicit-any -- legacy any/cast, may or may not be needed\n () => typeof window !== \"undefined\" && Boolean((window as any).rdt),\n (event, params) => {\n // Legacy cast - may or may not be necessary\n // oxlint-disable-next-line replo/no-as-cast, typescript/no-explicit-any -- legacy any/cast, may or may not be needed\n const rdt = (window as any).rdt;\n rdt(\"track\", event, params);\n },\n \"Reddit\",\n );\n }\n\n async pageView() {\n this.track(\"PageVisit\");\n }\n\n async purchase({ amount, currency, data }: PurchasePayload) {\n this.track(\"Purchase\", {\n value: amount,\n currency,\n itemCount: data.quantity ?? 1,\n transactionId: data.order_id,\n ...data,\n });\n }\n\n async click({ data }: DataPayload) {\n this.track(\"Custom\", data);\n }\n\n async productViewed({ data }: DataPayload) {\n this.track(\"ViewContent\", {\n value: data.price,\n currency: data.currency,\n content_category: data.category,\n content_name: data.name,\n content_ids: data.product_id ? [data.product_id] : undefined,\n ...data,\n });\n }\n\n async addToCart({ data }: DataPayload) {\n this.track(\"AddToCart\", {\n value: data.price,\n currency: data.currency,\n itemCount: data.quantity ?? 1,\n content_category: data.category,\n content_name: data.name,\n content_ids: data.product_id ? [data.product_id] : undefined,\n ...data,\n });\n }\n\n async removeFromCart() {\n // No direct equivalent in Reddit\n }\n\n async viewCart({ data }: DataPayload) {\n this.track(\"ViewContent\", {\n content_type: \"cart\",\n ...data,\n });\n }\n\n async startCheckout({ data }: DataPayload) {\n this.track(\"Lead\", {\n value: data.price,\n currency: data.currency,\n itemCount: data.quantity,\n ...data,\n });\n }\n\n async viewCollection({ data }: DataPayload) {\n this.track(\"ViewContent\", {\n content_category: data.category,\n content_type: \"category\",\n ...data,\n });\n }\n}\n"],
5
- "mappings": "AAMA,SAAS,wBAAwB;AAE1B,MAAM,WAAoC;AAAA;AAAA,EAEvC;AAAA,EAER,cAAc;AACZ,SAAK,QAAQ;AAAA;AAAA;AAAA,MAGX,MAAM,OAAO,WAAW,eAAe,QAAS,OAAe,GAAG;AAAA,MAClE,CAAC,OAAO,WAAW;AAGjB,cAAM,MAAO,OAAe;AAC5B,YAAI,SAAS,OAAO,MAAM;AAAA,MAC5B;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,WAAW;AACf,SAAK,MAAM,WAAW;AAAA,EACxB;AAAA,EAEA,MAAM,SAAS,EAAE,QAAQ,UAAU,KAAK,GAAoB;AAC1D,SAAK,MAAM,YAAY;AAAA,MACrB,OAAO;AAAA,MACP;AAAA,MACA,WAAW,KAAK,YAAY;AAAA,MAC5B,eAAe,KAAK;AAAA,MACpB,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,MAAM,EAAE,KAAK,GAAgB;AACjC,SAAK,MAAM,UAAU,IAAI;AAAA,EAC3B;AAAA,EAEA,MAAM,cAAc,EAAE,KAAK,GAAgB;AACzC,SAAK,MAAM,eAAe;AAAA,MACxB,OAAO,KAAK;AAAA,MACZ,UAAU,KAAK;AAAA,MACf,kBAAkB,KAAK;AAAA,MACvB,cAAc,KAAK;AAAA,MACnB,aAAa,KAAK,aAAa,CAAC,KAAK,UAAU,IAAI;AAAA,MACnD,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,UAAU,EAAE,KAAK,GAAgB;AACrC,SAAK,MAAM,aAAa;AAAA,MACtB,OAAO,KAAK;AAAA,MACZ,UAAU,KAAK;AAAA,MACf,WAAW,KAAK,YAAY;AAAA,MAC5B,kBAAkB,KAAK;AAAA,MACvB,cAAc,KAAK;AAAA,MACnB,aAAa,KAAK,aAAa,CAAC,KAAK,UAAU,IAAI;AAAA,MACnD,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,iBAAiB;AAAA,EAEvB;AAAA,EAEA,MAAM,SAAS,EAAE,KAAK,GAAgB;AACpC,SAAK,MAAM,eAAe;AAAA,MACxB,cAAc;AAAA,MACd,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,cAAc,EAAE,KAAK,GAAgB;AACzC,SAAK,MAAM,QAAQ;AAAA,MACjB,OAAO,KAAK;AAAA,MACZ,UAAU,KAAK;AAAA,MACf,WAAW,KAAK;AAAA,MAChB,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,eAAe,EAAE,KAAK,GAAgB;AAC1C,SAAK,MAAM,eAAe;AAAA,MACxB,kBAAkB,KAAK;AAAA,MACvB,cAAc;AAAA,MACd,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AACF;",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../analytics/sinks/replo-sink.ts"],
4
- "sourcesContent": ["import type {\n AnalyticsSink,\n DataPayload,\n PurchasePayload,\n} from \"../analytics-sink\";\n\nimport { createMethodQueue } from \"../utils/analytics-utils\";\n\nexport class ReploSink implements AnalyticsSink {\n // oxlint-disable-next-line typescript/no-explicit-any -- legacy any, may or may not be needed\n private forward: (method: keyof AnalyticsSink, ...args: any[]) => void;\n\n constructor() {\n this.forward = createMethodQueue(\n () => {\n if (typeof window === \"undefined\") {\n return null;\n }\n // Legacy cast - may or may not be necessary\n // oxlint-disable-next-line replo/no-as-cast, typescript/no-explicit-any -- legacy any/cast, may or may not be needed\n const pixel = (window as any).ReploPixel;\n return pixel?.analyticsInstance ?? null;\n },\n { queueName: \"Replo analytics sink\" },\n );\n }\n\n async pageView() {\n this.forward(\"pageView\");\n return Promise.resolve();\n }\n purchase(payload: PurchasePayload) {\n this.forward(\"purchase\", payload);\n return Promise.resolve();\n }\n click(payload: DataPayload) {\n this.forward(\"click\", payload);\n return Promise.resolve();\n }\n productViewed(payload: DataPayload) {\n this.forward(\"productViewed\", payload);\n return Promise.resolve();\n }\n addToCart(payload: DataPayload) {\n this.forward(\"addToCart\", payload);\n return Promise.resolve();\n }\n removeFromCart(payload: DataPayload) {\n this.forward(\"removeFromCart\", payload);\n return Promise.resolve();\n }\n viewCart(payload: DataPayload) {\n this.forward(\"viewCart\", payload);\n return Promise.resolve();\n }\n startCheckout(payload: DataPayload) {\n this.forward(\"startCheckout\", payload);\n return Promise.resolve();\n }\n viewCollection(payload: DataPayload) {\n this.forward(\"viewCollection\", payload);\n return Promise.resolve();\n }\n}\n"],
5
- "mappings": "AAMA,SAAS,yBAAyB;AAE3B,MAAM,UAAmC;AAAA;AAAA,EAEtC;AAAA,EAER,cAAc;AACZ,SAAK,UAAU;AAAA,MACb,MAAM;AACJ,YAAI,OAAO,WAAW,aAAa;AACjC,iBAAO;AAAA,QACT;AAGA,cAAM,QAAS,OAAe;AAC9B,eAAO,OAAO,qBAAqB;AAAA,MACrC;AAAA,MACA,EAAE,WAAW,uBAAuB;AAAA,IACtC;AAAA,EACF;AAAA,EAEA,MAAM,WAAW;AACf,SAAK,QAAQ,UAAU;AACvB,WAAO,QAAQ,QAAQ;AAAA,EACzB;AAAA,EACA,SAAS,SAA0B;AACjC,SAAK,QAAQ,YAAY,OAAO;AAChC,WAAO,QAAQ,QAAQ;AAAA,EACzB;AAAA,EACA,MAAM,SAAsB;AAC1B,SAAK,QAAQ,SAAS,OAAO;AAC7B,WAAO,QAAQ,QAAQ;AAAA,EACzB;AAAA,EACA,cAAc,SAAsB;AAClC,SAAK,QAAQ,iBAAiB,OAAO;AACrC,WAAO,QAAQ,QAAQ;AAAA,EACzB;AAAA,EACA,UAAU,SAAsB;AAC9B,SAAK,QAAQ,aAAa,OAAO;AACjC,WAAO,QAAQ,QAAQ;AAAA,EACzB;AAAA,EACA,eAAe,SAAsB;AACnC,SAAK,QAAQ,kBAAkB,OAAO;AACtC,WAAO,QAAQ,QAAQ;AAAA,EACzB;AAAA,EACA,SAAS,SAAsB;AAC7B,SAAK,QAAQ,YAAY,OAAO;AAChC,WAAO,QAAQ,QAAQ;AAAA,EACzB;AAAA,EACA,cAAc,SAAsB;AAClC,SAAK,QAAQ,iBAAiB,OAAO;AACrC,WAAO,QAAQ,QAAQ;AAAA,EACzB;AAAA,EACA,eAAe,SAAsB;AACnC,SAAK,QAAQ,kBAAkB,OAAO;AACtC,WAAO,QAAQ,QAAQ;AAAA,EACzB;AACF;",
6
- "names": []
7
- }