@replohq/sdk 0.1.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 (280) hide show
  1. package/LICENSE +11 -0
  2. package/_vendor/replo-utils/lib/crypto.d.ts +30 -0
  3. package/_vendor/replo-utils/lib/errors.d.ts +83 -0
  4. package/_vendor/replo-utils/lib/json.d.ts +6 -0
  5. package/_vendor/replo-utils/lib/json.mjs +43 -0
  6. package/_vendor/replo-utils/lib/misc.d.ts +145 -0
  7. package/_vendor/replo-utils/lib/object.d.ts +31 -0
  8. package/_vendor/schemas/errors.d.ts +459 -0
  9. package/_vendor/schemas/generated/consent.d.ts +55 -0
  10. package/_vendor/schemas/generated/errors.d.ts +61 -0
  11. package/_vendor/schemas/loaderKeys.d.ts +1 -0
  12. package/_vendor/schemas/loaderKeys.mjs +27 -0
  13. package/_vendor/schemas/money.d.ts +60 -0
  14. package/_vendor/schemas/money.mjs +2051 -0
  15. package/analytics/analytics-provider.d.ts +16 -0
  16. package/analytics/analytics-provider.js +113 -0
  17. package/analytics/analytics-provider.js.map +7 -0
  18. package/analytics/analytics-sink.d.ts +26 -0
  19. package/analytics/analytics-sink.js +1 -0
  20. package/analytics/analytics-sink.js.map +7 -0
  21. package/analytics/get-analytics-sinks.d.ts +27 -0
  22. package/analytics/get-analytics-sinks.js +52 -0
  23. package/analytics/get-analytics-sinks.js.map +7 -0
  24. package/analytics/hooks/use-product-viewed-analytics.d.ts +23 -0
  25. package/analytics/hooks/use-product-viewed-analytics.js +34 -0
  26. package/analytics/hooks/use-product-viewed-analytics.js.map +7 -0
  27. package/analytics/replo-first-party-pixel.d.ts +12 -0
  28. package/analytics/replo-first-party-pixel.js +31 -0
  29. package/analytics/replo-first-party-pixel.js.map +7 -0
  30. package/analytics/replo-pixel-script.d.ts +13 -0
  31. package/analytics/replo-pixel-script.js +30 -0
  32. package/analytics/replo-pixel-script.js.map +7 -0
  33. package/analytics/sinks/ga4-sink.d.ts +15 -0
  34. package/analytics/sinks/ga4-sink.js +60 -0
  35. package/analytics/sinks/ga4-sink.js.map +7 -0
  36. package/analytics/sinks/meta-sink.d.ts +14 -0
  37. package/analytics/sinks/meta-sink.js +56 -0
  38. package/analytics/sinks/meta-sink.js.map +7 -0
  39. package/analytics/sinks/pinterest-sink.d.ts +14 -0
  40. package/analytics/sinks/pinterest-sink.js +76 -0
  41. package/analytics/sinks/pinterest-sink.js.map +7 -0
  42. package/analytics/sinks/reddit-sink.d.ts +14 -0
  43. package/analytics/sinks/reddit-sink.js +80 -0
  44. package/analytics/sinks/reddit-sink.js.map +7 -0
  45. package/analytics/sinks/replo-sink.d.ts +14 -0
  46. package/analytics/sinks/replo-sink.js +57 -0
  47. package/analytics/sinks/replo-sink.js.map +7 -0
  48. package/analytics/sinks/snapchat-sink.d.ts +14 -0
  49. package/analytics/sinks/snapchat-sink.js +67 -0
  50. package/analytics/sinks/snapchat-sink.js.map +7 -0
  51. package/analytics/sinks/tiktok-sink.d.ts +14 -0
  52. package/analytics/sinks/tiktok-sink.js +79 -0
  53. package/analytics/sinks/tiktok-sink.js.map +7 -0
  54. package/analytics/sinks/window-sink.d.ts +18 -0
  55. package/analytics/sinks/window-sink.js +46 -0
  56. package/analytics/sinks/window-sink.js.map +7 -0
  57. package/analytics/utils/analytics-utils.d.ts +7 -0
  58. package/analytics/utils/analytics-utils.js +130 -0
  59. package/analytics/utils/analytics-utils.js.map +7 -0
  60. package/analytics/utils/navigation-tracker.d.ts +16 -0
  61. package/analytics/utils/navigation-tracker.js +44 -0
  62. package/analytics/utils/navigation-tracker.js.map +7 -0
  63. package/analytics/utils/shopify-funnel-gate.d.ts +8 -0
  64. package/analytics/utils/shopify-funnel-gate.js +22 -0
  65. package/analytics/utils/shopify-funnel-gate.js.map +7 -0
  66. package/cart/buy-now-action.d.ts +21 -0
  67. package/cart/buy-now-action.js +104 -0
  68. package/cart/buy-now-action.js.map +7 -0
  69. package/cart/cart-actions.d.ts +63 -0
  70. package/cart/cart-actions.js +90 -0
  71. package/cart/cart-actions.js.map +7 -0
  72. package/cart/cart-loader.d.ts +9 -0
  73. package/cart/cart-loader.js +11 -0
  74. package/cart/cart-loader.js.map +7 -0
  75. package/cart/cart-provider.d.ts +85 -0
  76. package/cart/cart-provider.js +372 -0
  77. package/cart/cart-provider.js.map +7 -0
  78. package/cart/cart-schema.d.ts +74 -0
  79. package/cart/cart-schema.js +69 -0
  80. package/cart/cart-schema.js.map +7 -0
  81. package/cart/cart-types.d.ts +132 -0
  82. package/cart/cart-types.js +8 -0
  83. package/cart/cart-types.js.map +7 -0
  84. package/cart/gateways/cart-constants.d.ts +1 -0
  85. package/cart/gateways/cart-constants.js +5 -0
  86. package/cart/gateways/cart-constants.js.map +7 -0
  87. package/cart/gateways/cart-gateway.d.ts +10 -0
  88. package/cart/gateways/cart-gateway.js +19 -0
  89. package/cart/gateways/cart-gateway.js.map +7 -0
  90. package/cart/gateways/cookie-cart-gateway.d.ts +28 -0
  91. package/cart/gateways/cookie-cart-gateway.js +109 -0
  92. package/cart/gateways/cookie-cart-gateway.js.map +7 -0
  93. package/cart/gateways/default-cart-gateway.d.ts +19 -0
  94. package/cart/gateways/default-cart-gateway.js +30 -0
  95. package/cart/gateways/default-cart-gateway.js.map +7 -0
  96. package/cart/gateways/resolver-cart-gateway.d.ts +2 -0
  97. package/cart/gateways/resolver-cart-gateway.js +109 -0
  98. package/cart/gateways/resolver-cart-gateway.js.map +7 -0
  99. package/cart/gateways/stripe-cart-gateway.d.ts +19 -0
  100. package/cart/gateways/stripe-cart-gateway.js +28 -0
  101. package/cart/gateways/stripe-cart-gateway.js.map +7 -0
  102. package/cart/hooks/use-add-to-cart.d.ts +63 -0
  103. package/cart/hooks/use-add-to-cart.js +124 -0
  104. package/cart/hooks/use-add-to-cart.js.map +7 -0
  105. package/cart/hooks/use-buy-now.d.ts +49 -0
  106. package/cart/hooks/use-buy-now.js +62 -0
  107. package/cart/hooks/use-buy-now.js.map +7 -0
  108. package/cart/utils/cart-utils.d.ts +43 -0
  109. package/cart/utils/cart-utils.js +46 -0
  110. package/cart/utils/cart-utils.js.map +7 -0
  111. package/cart/utils/cookie-cart-persistence.d.ts +55 -0
  112. package/cart/utils/cookie-cart-persistence.js +166 -0
  113. package/cart/utils/cookie-cart-persistence.js.map +7 -0
  114. package/cart/utils/variant-to-cart-line.d.ts +74 -0
  115. package/cart/utils/variant-to-cart-line.js +162 -0
  116. package/cart/utils/variant-to-cart-line.js.map +7 -0
  117. package/chunk-UJCSKKID.mjs +27 -0
  118. package/consent/consent-action.d.ts +9 -0
  119. package/consent/consent-action.js +25 -0
  120. package/consent/consent-action.js.map +7 -0
  121. package/consent/consent-actions.d.ts +28 -0
  122. package/consent/consent-actions.js +36 -0
  123. package/consent/consent-actions.js.map +7 -0
  124. package/consent/consent-store.d.ts +69 -0
  125. package/consent/consent-store.js +194 -0
  126. package/consent/consent-store.js.map +7 -0
  127. package/consent/cookie.d.ts +36 -0
  128. package/consent/cookie.js +82 -0
  129. package/consent/cookie.js.map +7 -0
  130. package/consent/replo-scripts.d.ts +23 -0
  131. package/consent/replo-scripts.js +102 -0
  132. package/consent/replo-scripts.js.map +7 -0
  133. package/consent/script-registration-store.d.ts +25 -0
  134. package/consent/script-registration-store.js +61 -0
  135. package/consent/script-registration-store.js.map +7 -0
  136. package/consent/script-snippets.d.ts +24 -0
  137. package/consent/script-snippets.js +122 -0
  138. package/consent/script-snippets.js.map +7 -0
  139. package/consent/types.d.ts +34 -0
  140. package/consent/types.js +1 -0
  141. package/consent/types.js.map +7 -0
  142. package/consent/window-api.d.ts +41 -0
  143. package/consent/window-api.js +73 -0
  144. package/consent/window-api.js.map +7 -0
  145. package/env.d.ts +9 -0
  146. package/env.js +42 -0
  147. package/env.js.map +7 -0
  148. package/gateways/canopy-api.d.ts +83 -0
  149. package/gateways/canopy-api.js +197 -0
  150. package/gateways/canopy-api.js.map +7 -0
  151. package/hooks/use-client-value.d.ts +10 -0
  152. package/hooks/use-client-value.js +12 -0
  153. package/hooks/use-client-value.js.map +7 -0
  154. package/hooks/use-formatted-price.d.ts +15 -0
  155. package/hooks/use-formatted-price.js +20 -0
  156. package/hooks/use-formatted-price.js.map +7 -0
  157. package/lib/canopy-error.d.ts +25 -0
  158. package/lib/canopy-error.js +24 -0
  159. package/lib/canopy-error.js.map +7 -0
  160. package/lib/get-query-client.d.ts +2 -0
  161. package/lib/get-query-client.js +34 -0
  162. package/lib/get-query-client.js.map +7 -0
  163. package/lib/integration-utils.d.ts +2 -0
  164. package/lib/integration-utils.js +9 -0
  165. package/lib/integration-utils.js.map +7 -0
  166. package/lib/shopify-utils.d.ts +10 -0
  167. package/lib/shopify-utils.js +7 -0
  168. package/lib/shopify-utils.js.map +7 -0
  169. package/lib/url-utils.d.ts +4 -0
  170. package/lib/url-utils.js +8 -0
  171. package/lib/url-utils.js.map +7 -0
  172. package/loaders/collection-loader.d.ts +11 -0
  173. package/loaders/collection-loader.js +55 -0
  174. package/loaders/collection-loader.js.map +7 -0
  175. package/loaders/collection-products-loader.d.ts +12 -0
  176. package/loaders/collection-products-loader.js +58 -0
  177. package/loaders/collection-products-loader.js.map +7 -0
  178. package/loaders/contentful-entries-loader.d.ts +17 -0
  179. package/loaders/contentful-entries-loader.js +78 -0
  180. package/loaders/contentful-entries-loader.js.map +7 -0
  181. package/loaders/contentful-entry-loader.d.ts +14 -0
  182. package/loaders/contentful-entry-loader.js +60 -0
  183. package/loaders/contentful-entry-loader.js.map +7 -0
  184. package/loaders/invoke-loader-action.d.ts +11 -0
  185. package/loaders/invoke-loader-action.js +14 -0
  186. package/loaders/invoke-loader-action.js.map +7 -0
  187. package/loaders/invoke-loader-server.d.ts +18 -0
  188. package/loaders/invoke-loader-server.js +40 -0
  189. package/loaders/invoke-loader-server.js.map +7 -0
  190. package/loaders/invoke-loader.d.ts +16 -0
  191. package/loaders/invoke-loader.js +37 -0
  192. package/loaders/invoke-loader.js.map +7 -0
  193. package/loaders/levanta-product-loader.d.ts +11 -0
  194. package/loaders/levanta-product-loader.js +53 -0
  195. package/loaders/levanta-product-loader.js.map +7 -0
  196. package/loaders/loader-error-boundary.d.ts +25 -0
  197. package/loaders/loader-error-boundary.js +24 -0
  198. package/loaders/loader-error-boundary.js.map +7 -0
  199. package/loaders/loader-keys.d.ts +34 -0
  200. package/loaders/loader-keys.js +26 -0
  201. package/loaders/loader-keys.js.map +7 -0
  202. package/loaders/loader-schemas.d.ts +946 -0
  203. package/loaders/loader-schemas.js +353 -0
  204. package/loaders/loader-schemas.js.map +7 -0
  205. package/loaders/metaobject-loader.d.ts +12 -0
  206. package/loaders/metaobject-loader.js +54 -0
  207. package/loaders/metaobject-loader.js.map +7 -0
  208. package/loaders/metaobjects-loader.d.ts +14 -0
  209. package/loaders/metaobjects-loader.js +60 -0
  210. package/loaders/metaobjects-loader.js.map +7 -0
  211. package/loaders/okendo-review-aggregate-loader.d.ts +17 -0
  212. package/loaders/okendo-review-aggregate-loader.js +56 -0
  213. package/loaders/okendo-review-aggregate-loader.js.map +7 -0
  214. package/loaders/okendo-reviews-loader.d.ts +23 -0
  215. package/loaders/okendo-reviews-loader.js +54 -0
  216. package/loaders/okendo-reviews-loader.js.map +7 -0
  217. package/loaders/prefetch-loaders.d.ts +33 -0
  218. package/loaders/prefetch-loaders.js +46 -0
  219. package/loaders/prefetch-loaders.js.map +7 -0
  220. package/loaders/preview-placeholder.d.ts +25 -0
  221. package/loaders/preview-placeholder.js +222 -0
  222. package/loaders/preview-placeholder.js.map +7 -0
  223. package/loaders/product-loader-args.d.ts +21 -0
  224. package/loaders/product-loader-args.js +17 -0
  225. package/loaders/product-loader-args.js.map +7 -0
  226. package/loaders/product-loader.d.ts +10 -0
  227. package/loaders/product-loader.js +52 -0
  228. package/loaders/product-loader.js.map +7 -0
  229. package/loaders/rebuy-recommendations-loader.d.ts +165 -0
  230. package/loaders/rebuy-recommendations-loader.js +57 -0
  231. package/loaders/rebuy-recommendations-loader.js.map +7 -0
  232. package/loaders/reviews-io-review-aggregate-loader.d.ts +12 -0
  233. package/loaders/reviews-io-review-aggregate-loader.js +43 -0
  234. package/loaders/reviews-io-review-aggregate-loader.js.map +7 -0
  235. package/loaders/reviews-io-reviews-loader.d.ts +14 -0
  236. package/loaders/reviews-io-reviews-loader.js +65 -0
  237. package/loaders/reviews-io-reviews-loader.js.map +7 -0
  238. package/loaders/smile-earning-rules-loader.d.ts +19 -0
  239. package/loaders/smile-earning-rules-loader.js +44 -0
  240. package/loaders/smile-earning-rules-loader.js.map +7 -0
  241. package/loaders/smile-rewards-loader.d.ts +19 -0
  242. package/loaders/smile-rewards-loader.js +44 -0
  243. package/loaders/smile-rewards-loader.js.map +7 -0
  244. package/loaders/smile-vip-tiers-loader.d.ts +18 -0
  245. package/loaders/smile-vip-tiers-loader.js +43 -0
  246. package/loaders/smile-vip-tiers-loader.js.map +7 -0
  247. package/loaders/statsig-experiment-loader.d.ts +20 -0
  248. package/loaders/statsig-experiment-loader.js +81 -0
  249. package/loaders/statsig-experiment-loader.js.map +7 -0
  250. package/loaders/yotpo-review-aggregate-loader.d.ts +12 -0
  251. package/loaders/yotpo-review-aggregate-loader.js +50 -0
  252. package/loaders/yotpo-review-aggregate-loader.js.map +7 -0
  253. package/loaders/yotpo-reviews-loader.d.ts +14 -0
  254. package/loaders/yotpo-reviews-loader.js +65 -0
  255. package/loaders/yotpo-reviews-loader.js.map +7 -0
  256. package/money.d.ts +9 -0
  257. package/money.js +13 -0
  258. package/money.js.map +7 -0
  259. package/next/config.d.ts +4 -0
  260. package/next/config.js +91 -0
  261. package/next/config.js.map +7 -0
  262. package/next/image-loader.d.ts +2 -0
  263. package/next/image-loader.js +52 -0
  264. package/next/image-loader.js.map +7 -0
  265. package/next/open-next.d.ts +2 -0
  266. package/next/open-next.js +24 -0
  267. package/next/open-next.js.map +7 -0
  268. package/orders/order-status-schema.d.ts +161 -0
  269. package/orders/order-status-schema.js +83 -0
  270. package/orders/order-status-schema.js.map +7 -0
  271. package/orders/order-status.d.ts +11 -0
  272. package/orders/order-status.js +41 -0
  273. package/orders/order-status.js.map +7 -0
  274. package/package.json +216 -0
  275. package/providers/query-provider.d.ts +1 -0
  276. package/providers/query-provider.js +12 -0
  277. package/providers/query-provider.js.map +7 -0
  278. package/providers/replo-provider.d.ts +1 -0
  279. package/providers/replo-provider.js +22 -0
  280. package/providers/replo-provider.js.map +7 -0
@@ -0,0 +1,85 @@
1
+ import type { Cart, CartLine, CartLinePayload } from "./cart-types";
2
+ import React from "react";
3
+ /**
4
+ * Internal cart context type with full functionality.
5
+ * This is for internal use only - external code should use the limited CartContextType.
6
+ */
7
+ export interface CartContextTypeInternal {
8
+ /** The current cart (can be null) */
9
+ cartData: Cart | null;
10
+ /** Array of cart line items */
11
+ lineItems: CartLine[];
12
+ /** Total price of all items */
13
+ subtotal: number;
14
+ /** Total number of items in cart */
15
+ itemsCount: number;
16
+ /** Currency code for the cart */
17
+ currencyCode: string;
18
+ /** Function to add items to cart */
19
+ addToCart: (lines: CartLinePayload[], openCartAfterAdd?: boolean) => Promise<void>;
20
+ /** Function to update cart item quantity */
21
+ updateCartItem: (line: CartLinePayload) => Promise<void>;
22
+ /** Function to remove item from cart */
23
+ removeCartItem: (lineId: string) => Promise<void>;
24
+ /** Function to update discount codes on cart */
25
+ updateDiscountCodes: (discountCodes: string[]) => Promise<void>;
26
+ /** Function to create cart and checkout immediately */
27
+ buyNow: (lines: CartLinePayload[], discountCodes?: string[]) => Promise<Cart | null>;
28
+ /** URL to redirect to checkout */
29
+ checkoutUrl: string;
30
+ /** Whether the cart UI is open */
31
+ isCartOpen: boolean;
32
+ /** Function to open the cart UI */
33
+ openCart: () => void;
34
+ /** Function to close the cart UI */
35
+ closeCart: () => void;
36
+ }
37
+ /**
38
+ * Public cart context type for LLM use.
39
+ * For adding products to cart, use useAddToCart.
40
+ * For buy now functionality, use useBuyNow.
41
+ */
42
+ export interface CartContextType {
43
+ /** Total number of items in cart */
44
+ itemsCount: number;
45
+ /** Whether the cart UI is open */
46
+ isCartOpen: boolean;
47
+ /** Function to open the cart UI */
48
+ openCart: () => void;
49
+ /** Function to close the cart UI */
50
+ closeCart: () => void;
51
+ /** Function to update discount codes on cart */
52
+ updateDiscountCodes: (discountCodes: string[]) => Promise<void>;
53
+ }
54
+ /**
55
+ * Provider component that manages global cart state and operations. Handles both
56
+ * server-side cart synchronization and client-side optimistic updates. Supports
57
+ * editor mode for preview environments.
58
+ *
59
+ * @returns A context provider wrapping the children with cart functionality
60
+ */
61
+ export declare function CartProvider({ children, cart, }: React.PropsWithChildren<{
62
+ /** Initial cart data from the server (can be null) */
63
+ cart: Cart | null;
64
+ }>): import("react/jsx-runtime").JSX.Element;
65
+ /**
66
+ * @deprecated For internal use only. Use useAddToCart or useBuyNow
67
+ * for cart operations. Use useCart for cart UI state (itemsCount, openCart, closeCart).
68
+ */
69
+ export declare function useCartInternal(): CartContextTypeInternal;
70
+ /**
71
+ * Hook to access cart UI state and controls. For adding products to cart,
72
+ * use useAddToCart. For buy now functionality, use useBuyNow.
73
+ *
74
+ * @example
75
+ * ```tsx
76
+ * import { useCart } from "@replohq/sdk/cart/cart-provider";
77
+ *
78
+ * function MyComponent() {
79
+ * const { itemsCount, openCart } = useCart();
80
+ * ...
81
+ * }
82
+ * ```
83
+ * @throws Error if used outside of a CartProvider
84
+ */
85
+ export declare function useCart(): CartContextType;
@@ -0,0 +1,372 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import React from "react";
4
+ import { fromMinorUnitsToMajorUnits } from "../_vendor/schemas/money.mjs";
5
+ import { v4 as uuidv4 } from "uuid";
6
+ import { useAnalyticsOptional } from "../analytics/analytics-provider";
7
+ import { CanopyError } from "../lib/canopy-error";
8
+ import {
9
+ addToCartAction,
10
+ createCartAction,
11
+ getOrCreateCartAction,
12
+ removeCartLineItemsAction,
13
+ updateCartDiscountCodesAction,
14
+ updateCartLineItemAction
15
+ } from "./cart-actions";
16
+ import { createOptimisticSellingPlanAllocation } from "./utils/variant-to-cart-line";
17
+ class CartContextError extends CanopyError {
18
+ }
19
+ const isEditorMode = () => {
20
+ if (typeof window === "undefined") {
21
+ return false;
22
+ }
23
+ return window.parent !== window;
24
+ };
25
+ let cartCreationPromise = null;
26
+ function addLineToCart(cart, line) {
27
+ const existingLineIndex = cart.lines.findIndex((existingLine) => {
28
+ return existingLine.merchandise?.id === line.id && // Distinguish by selling plan to avoid merging subscription with one-time
29
+ (line.sellingPlanId ?? null) === (existingLine.sellingPlanAllocation?.sellingPlan.id ?? null);
30
+ });
31
+ if (existingLineIndex >= 0) {
32
+ const updatedLines = [...cart.lines];
33
+ updatedLines[existingLineIndex] = {
34
+ ...updatedLines[existingLineIndex],
35
+ quantity: updatedLines[existingLineIndex].quantity + line.quantity
36
+ };
37
+ return { ...cart, lines: updatedLines };
38
+ } else {
39
+ const optimisticSellingPlanAllocation = line.sellingPlanId && line.merchandise ? createOptimisticSellingPlanAllocation({
40
+ merchandise: line.merchandise,
41
+ sellingPlanId: line.sellingPlanId,
42
+ currencyCode: cart.cost?.currencyCode ?? "USD"
43
+ }) : null;
44
+ const newLine = {
45
+ id: `temp-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`,
46
+ quantity: line.quantity,
47
+ merchandise: line.merchandise ?? null,
48
+ attributes: line.properties ?? [],
49
+ sellingPlanAllocation: optimisticSellingPlanAllocation
50
+ };
51
+ return { ...cart, lines: [newLine, ...cart.lines] };
52
+ }
53
+ }
54
+ function updateLineInCart(cart, line) {
55
+ const updatedLines = cart.lines.map((existingLine) => {
56
+ return existingLine.id === line.id ? { ...existingLine, quantity: line.quantity } : existingLine;
57
+ });
58
+ return { ...cart, lines: updatedLines };
59
+ }
60
+ function removeLineFromCart(cart, lineId) {
61
+ const updatedLines = cart.lines.filter((line) => line.id !== lineId);
62
+ return { ...cart, lines: updatedLines };
63
+ }
64
+ const CartContext = React.createContext(
65
+ void 0
66
+ );
67
+ function CartProvider({
68
+ children,
69
+ cart
70
+ }) {
71
+ const [cartData, setCartData] = React.useState(cart);
72
+ const [isCartOpen, setIsCartOpen] = React.useState(false);
73
+ const hasInitialized = React.useRef(false);
74
+ const analytics = useAnalyticsOptional();
75
+ React.useEffect(() => {
76
+ if (hasInitialized.current) {
77
+ return;
78
+ }
79
+ if (cartCreationPromise) {
80
+ void cartCreationPromise.then((cart2) => {
81
+ if (cart2) {
82
+ setCartData(cart2);
83
+ }
84
+ });
85
+ return;
86
+ }
87
+ hasInitialized.current = true;
88
+ cartCreationPromise = getOrCreateCartAction().then((cart2) => {
89
+ if (cart2) {
90
+ setCartData(cart2);
91
+ } else {
92
+ console.warn(
93
+ "[Replo] Failed to get or create cart on the server. Reach out to support@replo.app if this persists."
94
+ );
95
+ }
96
+ return cart2;
97
+ }).catch((error) => {
98
+ console.error("[Replo] Error getting or creating cart:", error);
99
+ return null;
100
+ }).finally(() => {
101
+ cartCreationPromise = null;
102
+ });
103
+ }, []);
104
+ const lineItems = cartData?.lines ?? [];
105
+ const subtotal = cartData?.lines.reduce((sum, lineItem) => {
106
+ if (lineItem.quantity > 0 && lineItem.merchandise) {
107
+ sum += lineItem.merchandise.price * lineItem.quantity;
108
+ }
109
+ return sum;
110
+ }, 0) ?? 0;
111
+ const itemsCount = cartData?.lines.reduce((sum, lineItem) => {
112
+ if (lineItem.quantity > 0) {
113
+ sum += lineItem.quantity;
114
+ }
115
+ return sum;
116
+ }, 0) ?? 0;
117
+ const openCart = React.useCallback(() => {
118
+ setIsCartOpen(true);
119
+ if (analytics) {
120
+ const analyticsCurrencyCode = cartData?.cost.currencyCode ?? "USD";
121
+ void analytics.viewCart({
122
+ data: {
123
+ itemCount: itemsCount,
124
+ subtotal: fromMinorUnitsToMajorUnits({
125
+ amount: subtotal,
126
+ currencyCode: analyticsCurrencyCode
127
+ }),
128
+ currency: cartData?.cost.currencyCode,
129
+ lineItems: cartData?.lines.flatMap((item) => {
130
+ if (!item.merchandise) {
131
+ return [];
132
+ }
133
+ return [
134
+ {
135
+ productId: item.merchandise.product.id,
136
+ variantId: item.merchandise.id,
137
+ quantity: item.quantity,
138
+ price: fromMinorUnitsToMajorUnits({
139
+ amount: item.merchandise.price,
140
+ currencyCode: analyticsCurrencyCode
141
+ })
142
+ }
143
+ ];
144
+ })
145
+ }
146
+ });
147
+ }
148
+ }, [analytics, cartData, itemsCount, subtotal]);
149
+ const closeCart = React.useCallback(() => {
150
+ setIsCartOpen(false);
151
+ }, []);
152
+ const latestUpdateRequestId = React.useRef(null);
153
+ const addToCart = async (lines, openCartAfterAdd = true) => {
154
+ if (!cartData) {
155
+ console.warn(
156
+ "[Replo] Cannot add to cart: no cart exists. Reach out to support@replo.app if this persists."
157
+ );
158
+ return;
159
+ }
160
+ setCartData((currentCart) => {
161
+ if (!currentCart) {
162
+ return null;
163
+ }
164
+ let updatedCart = { ...currentCart };
165
+ for (const line of lines) {
166
+ updatedCart = addLineToCart(updatedCart, line);
167
+ }
168
+ return updatedCart;
169
+ });
170
+ if (openCartAfterAdd) {
171
+ openCart();
172
+ }
173
+ if (analytics) {
174
+ for (const line of lines) {
175
+ if (!line.merchandise) {
176
+ continue;
177
+ }
178
+ void analytics.addToCart({
179
+ data: {
180
+ productId: line.merchandise.product.id,
181
+ variantId: line.merchandise.id,
182
+ quantity: line.quantity,
183
+ price: fromMinorUnitsToMajorUnits({
184
+ amount: line.merchandise.price,
185
+ currencyCode: cartData?.cost.currencyCode ?? "USD"
186
+ }),
187
+ currency: cartData?.cost.currencyCode,
188
+ productTitle: line.merchandise.product.title,
189
+ variantTitle: line.merchandise.title
190
+ }
191
+ });
192
+ }
193
+ }
194
+ const serverCart = await addToCartAction(lines, cartData.id);
195
+ if (serverCart) {
196
+ setCartData(serverCart);
197
+ } else {
198
+ console.warn(
199
+ "[Replo] Failed to add item to cart on server. Cart may be out of sync. Reach out to support@replo.app if this persists."
200
+ );
201
+ }
202
+ };
203
+ const updateCartItem = async (line) => {
204
+ if (!cartData) {
205
+ console.warn(
206
+ "[Replo] Cannot update cart item: no cart exists. Reach out to support@replo.app if this persists."
207
+ );
208
+ return;
209
+ }
210
+ const requestId = uuidv4();
211
+ latestUpdateRequestId.current = requestId;
212
+ setCartData((currentCart) => {
213
+ if (!currentCart) {
214
+ return null;
215
+ }
216
+ return updateLineInCart(currentCart, line);
217
+ });
218
+ const serverCart = await updateCartLineItemAction(line, cartData.id);
219
+ if (latestUpdateRequestId.current === requestId) {
220
+ if (serverCart) {
221
+ setCartData(serverCart);
222
+ } else {
223
+ console.warn(
224
+ "[Replo] Failed to update cart item on server. Cart may be out of sync. Reach out to support@replo.app if this persists."
225
+ );
226
+ }
227
+ }
228
+ };
229
+ const removeCartItem = async (lineId) => {
230
+ if (!cartData) {
231
+ console.warn(
232
+ "[Replo] Cannot remove cart item: no cart exists. Reach out to support@replo.app if this persists."
233
+ );
234
+ return;
235
+ }
236
+ const itemToRemove = cartData.lines.find((item) => item.id === lineId);
237
+ if (analytics && itemToRemove && itemToRemove.merchandise) {
238
+ void analytics.removeFromCart({
239
+ data: {
240
+ productId: itemToRemove.merchandise.product.id,
241
+ variantId: itemToRemove.merchandise.id,
242
+ quantity: itemToRemove.quantity,
243
+ price: fromMinorUnitsToMajorUnits({
244
+ amount: itemToRemove.merchandise.price,
245
+ currencyCode: cartData.cost.currencyCode
246
+ }),
247
+ currency: cartData.cost.currencyCode,
248
+ productTitle: itemToRemove.merchandise.product.title,
249
+ variantTitle: itemToRemove.merchandise.title
250
+ }
251
+ });
252
+ }
253
+ setCartData((currentCart) => {
254
+ if (!currentCart) {
255
+ return null;
256
+ }
257
+ return removeLineFromCart(currentCart, lineId);
258
+ });
259
+ const serverCart = await removeCartLineItemsAction([lineId], cartData.id);
260
+ if (serverCart) {
261
+ setCartData(serverCart);
262
+ } else {
263
+ console.warn(
264
+ "[Replo] Failed to remove cart item on server. Cart may be out of sync. Reach out to support@replo.app if this persists."
265
+ );
266
+ }
267
+ };
268
+ const updateDiscountCodes = async (discountCodes) => {
269
+ if (!cartData) {
270
+ console.warn(
271
+ "[Replo] Cannot update discount codes: no cart exists. Reach out to support@replo.app if this persists."
272
+ );
273
+ return;
274
+ }
275
+ setCartData((currentCart) => {
276
+ if (!currentCart) {
277
+ return null;
278
+ }
279
+ return {
280
+ ...currentCart,
281
+ discountCodes: discountCodes.map((code) => ({
282
+ code,
283
+ applicable: true
284
+ }))
285
+ };
286
+ });
287
+ const serverCart = await updateCartDiscountCodesAction(
288
+ discountCodes,
289
+ cartData.id
290
+ );
291
+ if (serverCart) {
292
+ setCartData(serverCart);
293
+ } else {
294
+ console.warn(
295
+ "[Replo] Failed to update discount codes on server. Cart may be out of sync. Reach out to support@replo.app if this persists."
296
+ );
297
+ }
298
+ };
299
+ const buyNow = async (lines, discountCodes) => {
300
+ const cart2 = await createCartAction({
301
+ lines,
302
+ skipStoringCart: true,
303
+ discountCodes
304
+ });
305
+ if (cart2) {
306
+ return cart2;
307
+ } else {
308
+ console.warn(
309
+ "[Replo] Failed to create cart for buy now. Reach out to support@replo.app if this persists."
310
+ );
311
+ return null;
312
+ }
313
+ };
314
+ const checkoutUrl = (() => {
315
+ if (isEditorMode()) {
316
+ return "/";
317
+ }
318
+ return cartData?.checkoutUrl ?? "/";
319
+ })();
320
+ return /* @__PURE__ */ jsx(
321
+ CartContext.Provider,
322
+ {
323
+ value: {
324
+ cartData,
325
+ lineItems,
326
+ subtotal,
327
+ itemsCount,
328
+ currencyCode: cartData?.cost.currencyCode ?? "USD",
329
+ addToCart,
330
+ updateCartItem,
331
+ removeCartItem,
332
+ updateDiscountCodes,
333
+ buyNow,
334
+ checkoutUrl,
335
+ isCartOpen,
336
+ openCart,
337
+ closeCart
338
+ },
339
+ children
340
+ }
341
+ );
342
+ }
343
+ function useCartInternal() {
344
+ const context = React.useContext(CartContext);
345
+ if (context === void 0) {
346
+ throw new CartContextError({
347
+ message: "useCartInternal must be used within a CartProvider"
348
+ });
349
+ }
350
+ return context;
351
+ }
352
+ function useCart() {
353
+ const context = React.useContext(CartContext);
354
+ if (context === void 0) {
355
+ throw new CartContextError({
356
+ message: "useCart must be used within a CartProvider"
357
+ });
358
+ }
359
+ return {
360
+ itemsCount: context.itemsCount,
361
+ isCartOpen: context.isCartOpen,
362
+ openCart: context.openCart,
363
+ closeCart: context.closeCart,
364
+ updateDiscountCodes: context.updateDiscountCodes
365
+ };
366
+ }
367
+ export {
368
+ CartProvider,
369
+ useCart,
370
+ useCartInternal
371
+ };
372
+ //# sourceMappingURL=cart-provider.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../cart/cart-provider.tsx"],
4
+ "sourcesContent": ["/**\n * Use useCart() hook to access cart UI state (itemsCount, isCartOpen, openCart, closeCart). For adding products to cart, use useAddToCart. For buy now functionality, use useBuyNow.\n * @module\n */\n\"use client\";\n\nimport type { Cart, CartLine, CartLinePayload } from \"./cart-types\";\n\nimport React from \"react\";\n\nimport { fromMinorUnitsToMajorUnits } from \"schemas/money\";\nimport { v4 as uuidv4 } from \"uuid\";\n\nimport { useAnalyticsOptional } from \"../analytics/analytics-provider\";\nimport { CanopyError } from \"../lib/canopy-error\";\nimport {\n addToCartAction,\n createCartAction,\n getOrCreateCartAction,\n removeCartLineItemsAction,\n updateCartDiscountCodesAction,\n updateCartLineItemAction,\n} from \"./cart-actions\";\nimport { createOptimisticSellingPlanAllocation } from \"./utils/variant-to-cart-line\";\n\nclass CartContextError extends CanopyError {}\n\n/**\n * Detects if the app is running in editor mode (iframe).\n *\n * @returns True if running in an iframe (editor mode)\n */\nconst isEditorMode = () => {\n if (typeof window === \"undefined\") {\n return false;\n }\n\n return window.parent !== window;\n};\n\n// Global promise to prevent multiple cart creation attempts\nlet cartCreationPromise: Promise<Cart | null> | null = null;\n\n/**\n * Client-side cart operation to add a line item. Used in editor mode.\n * Merges with existing lines if they match by merchandise ID and selling plan.\n *\n * @param cart - The cart to add the line to\n * @param line - The cart line payload to add\n * @returns The updated cart\n */\nfunction addLineToCart(cart: Cart, line: CartLinePayload): Cart {\n const existingLineIndex = cart.lines.findIndex((existingLine) => {\n return (\n existingLine.merchandise?.id === line.id &&\n // Distinguish by selling plan to avoid merging subscription with one-time\n (line.sellingPlanId ?? null) ===\n (existingLine.sellingPlanAllocation?.sellingPlan.id ?? null)\n );\n });\n\n if (existingLineIndex >= 0) {\n // Update existing line\n const updatedLines = [...cart.lines];\n updatedLines[existingLineIndex] = {\n ...updatedLines[existingLineIndex]!,\n quantity: updatedLines[existingLineIndex]!.quantity + line.quantity,\n };\n return { ...cart, lines: updatedLines };\n } else {\n const optimisticSellingPlanAllocation =\n line.sellingPlanId && line.merchandise\n ? createOptimisticSellingPlanAllocation({\n merchandise: line.merchandise,\n sellingPlanId: line.sellingPlanId,\n currencyCode: cart.cost?.currencyCode ?? \"USD\",\n })\n : null;\n\n const newLine: CartLine = {\n id: `temp-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`,\n quantity: line.quantity,\n merchandise: line.merchandise ?? null,\n attributes: line.properties ?? [],\n sellingPlanAllocation: optimisticSellingPlanAllocation,\n };\n return { ...cart, lines: [newLine, ...cart.lines] };\n }\n}\n\n/**\n * Client-side cart operation to update a line item. Used in editor mode.\n *\n * @param cart - The cart containing the line to update\n * @param line - The cart line payload with updated values\n * @returns The updated cart\n */\nfunction updateLineInCart(cart: Cart, line: CartLinePayload): Cart {\n const updatedLines = cart.lines.map((existingLine) => {\n return existingLine.id === line.id\n ? { ...existingLine, quantity: line.quantity }\n : existingLine;\n });\n return { ...cart, lines: updatedLines };\n}\n\n/**\n * Client-side cart operation to remove a line item. Used in editor mode.\n *\n * @param cart - The cart containing the line to remove\n * @param lineId - The ID of the line to remove\n * @returns The updated cart\n */\nfunction removeLineFromCart(cart: Cart, lineId: string): Cart {\n const updatedLines = cart.lines.filter((line) => line.id !== lineId);\n return { ...cart, lines: updatedLines };\n}\n\n/**\n * Internal cart context type with full functionality.\n * This is for internal use only - external code should use the limited CartContextType.\n */\nexport interface CartContextTypeInternal {\n /** The current cart (can be null) */\n cartData: Cart | null;\n /** Array of cart line items */\n lineItems: CartLine[];\n /** Total price of all items */\n subtotal: number;\n /** Total number of items in cart */\n itemsCount: number;\n /** Currency code for the cart */\n currencyCode: string;\n /** Function to add items to cart */\n addToCart: (\n lines: CartLinePayload[],\n openCartAfterAdd?: boolean,\n ) => Promise<void>;\n /** Function to update cart item quantity */\n updateCartItem: (line: CartLinePayload) => Promise<void>;\n /** Function to remove item from cart */\n removeCartItem: (lineId: string) => Promise<void>;\n /** Function to update discount codes on cart */\n updateDiscountCodes: (discountCodes: string[]) => Promise<void>;\n /** Function to create cart and checkout immediately */\n buyNow: (\n lines: CartLinePayload[],\n discountCodes?: string[],\n ) => Promise<Cart | null>;\n /** URL to redirect to checkout */\n checkoutUrl: string;\n /** Whether the cart UI is open */\n isCartOpen: boolean;\n /** Function to open the cart UI */\n openCart: () => void;\n /** Function to close the cart UI */\n closeCart: () => void;\n}\n\n// NOTE (Gabe, 2026-01-08): We intentionally duplicate properties from CartContextTypeInternal\n// rather than using Pick<> so that TypeDoc generates expanded documentation for each property.\n/**\n * Public cart context type for LLM use.\n * For adding products to cart, use useAddToCart.\n * For buy now functionality, use useBuyNow.\n */\nexport interface CartContextType {\n /** Total number of items in cart */\n itemsCount: number;\n /** Whether the cart UI is open */\n isCartOpen: boolean;\n /** Function to open the cart UI */\n openCart: () => void;\n /** Function to close the cart UI */\n closeCart: () => void;\n /** Function to update discount codes on cart */\n updateDiscountCodes: (discountCodes: string[]) => Promise<void>;\n}\n\nconst CartContext = React.createContext<CartContextTypeInternal | undefined>(\n undefined,\n);\n\n/**\n * Provider component that manages global cart state and operations. Handles both\n * server-side cart synchronization and client-side optimistic updates. Supports\n * editor mode for preview environments.\n *\n * @returns A context provider wrapping the children with cart functionality\n */\nexport function CartProvider({\n children,\n cart,\n}: React.PropsWithChildren<{\n /** Initial cart data from the server (can be null) */\n cart: Cart | null;\n}>) {\n const [cartData, setCartData] = React.useState<Cart | null>(cart);\n const [isCartOpen, setIsCartOpen] = React.useState(false);\n const hasInitialized = React.useRef(false);\n const analytics = useAnalyticsOptional();\n\n // Initialize cart on mount\n // eslint-disable-next-line replo/no-use-effect -- Legacy effect - may or may not be necessary\n React.useEffect(() => {\n // Early exit if already initialized\n if (hasInitialized.current) {\n return;\n }\n\n // If there's already a creation in progress, attach to it\n if (cartCreationPromise) {\n void cartCreationPromise.then((cart) => {\n if (cart) {\n setCartData(cart);\n }\n });\n return;\n }\n\n // Mark as initialized to prevent duplicate calls\n hasInitialized.current = true;\n\n // Get existing cart or create new one\n cartCreationPromise = getOrCreateCartAction()\n .then((cart) => {\n if (cart) {\n setCartData(cart);\n } else {\n console.warn(\n \"[Replo] Failed to get or create cart on the server. Reach out to support@replo.app if this persists.\",\n );\n }\n return cart;\n })\n .catch((error) => {\n console.error(\"[Replo] Error getting or creating cart:\", error);\n return null;\n })\n .finally(() => {\n // Reset the promise after completion\n cartCreationPromise = null;\n });\n }, []);\n\n // Derived values - handle null cart gracefully\n const lineItems = cartData?.lines ?? [];\n\n const subtotal =\n cartData?.lines.reduce((sum, lineItem) => {\n if (lineItem.quantity > 0 && lineItem.merchandise) {\n sum += lineItem.merchandise.price * lineItem.quantity;\n }\n return sum;\n }, 0) ?? 0;\n\n const itemsCount =\n cartData?.lines.reduce((sum, lineItem) => {\n if (lineItem.quantity > 0) {\n sum += lineItem.quantity;\n }\n return sum;\n }, 0) ?? 0;\n\n // Cart UI state functions\n const openCart = React.useCallback(() => {\n setIsCartOpen(true);\n\n if (analytics) {\n const analyticsCurrencyCode = cartData?.cost.currencyCode ?? \"USD\";\n // NOTE (Max, 2026-08-03): cart amounts are integer minor units, but the\n // analytics payload speaks decimal major units (ad pixels + the Replo\n // store), so convert at this boundary.\n void analytics.viewCart({\n data: {\n itemCount: itemsCount,\n subtotal: fromMinorUnitsToMajorUnits({\n amount: subtotal,\n currencyCode: analyticsCurrencyCode,\n }),\n currency: cartData?.cost.currencyCode,\n lineItems: cartData?.lines.flatMap((item) => {\n if (!item.merchandise) {\n return [];\n }\n return [\n {\n productId: item.merchandise.product.id,\n variantId: item.merchandise.id,\n quantity: item.quantity,\n price: fromMinorUnitsToMajorUnits({\n amount: item.merchandise.price,\n currencyCode: analyticsCurrencyCode,\n }),\n },\n ];\n }),\n },\n });\n }\n }, [analytics, cartData, itemsCount, subtotal]);\n\n const closeCart = React.useCallback(() => {\n setIsCartOpen(false);\n }, []);\n\n // Track the latest update request to avoid updating with stale responses\n const latestUpdateRequestId = React.useRef<string | null>(null);\n\n const addToCart = async (\n lines: CartLinePayload[],\n openCartAfterAdd: boolean = true,\n ) => {\n // If no cart exists, we can't add to it\n if (!cartData) {\n console.warn(\n \"[Replo] Cannot add to cart: no cart exists. Reach out to support@replo.app if this persists.\",\n );\n return;\n }\n\n // Optimistic update - use functional form to avoid stale state\n setCartData((currentCart) => {\n if (!currentCart) {\n return null;\n }\n let updatedCart = { ...currentCart };\n for (const line of lines) {\n updatedCart = addLineToCart(updatedCart, line);\n }\n return updatedCart;\n });\n\n if (openCartAfterAdd) {\n openCart();\n }\n\n if (analytics) {\n for (const line of lines) {\n if (!line.merchandise) {\n continue;\n }\n // NOTE (Max, 2026-08-03): cart amounts are integer minor units, but the\n // analytics payload speaks decimal major units (ad pixels + the Replo\n // store), so convert at this boundary.\n void analytics.addToCart({\n data: {\n productId: line.merchandise.product.id,\n variantId: line.merchandise.id,\n quantity: line.quantity,\n price: fromMinorUnitsToMajorUnits({\n amount: line.merchandise.price,\n currencyCode: cartData?.cost.currencyCode ?? \"USD\",\n }),\n currency: cartData?.cost.currencyCode,\n productTitle: line.merchandise.product.title,\n variantTitle: line.merchandise.title,\n },\n });\n }\n }\n\n // Direct server update (no debouncing)\n const serverCart = await addToCartAction(lines, cartData.id);\n if (serverCart) {\n setCartData(serverCart);\n } else {\n console.warn(\n \"[Replo] Failed to add item to cart on server. Cart may be out of sync. Reach out to support@replo.app if this persists.\",\n );\n }\n };\n\n const updateCartItem = async (line: CartLinePayload) => {\n // If no cart exists, we can't update it\n if (!cartData) {\n console.warn(\n \"[Replo] Cannot update cart item: no cart exists. Reach out to support@replo.app if this persists.\",\n );\n return;\n }\n\n // Generate a unique request ID for this update\n const requestId = uuidv4();\n latestUpdateRequestId.current = requestId;\n\n // Optimistic update - use functional form to avoid stale state\n setCartData((currentCart) => {\n if (!currentCart) {\n return null;\n }\n return updateLineInCart(currentCart, line);\n });\n\n // Server update\n const serverCart = await updateCartLineItemAction(line, cartData.id);\n\n // Only update if this is still the latest request\n if (latestUpdateRequestId.current === requestId) {\n if (serverCart) {\n setCartData(serverCart);\n } else {\n console.warn(\n \"[Replo] Failed to update cart item on server. Cart may be out of sync. Reach out to support@replo.app if this persists.\",\n );\n }\n }\n };\n\n const removeCartItem = async (lineId: string) => {\n if (!cartData) {\n console.warn(\n \"[Replo] Cannot remove cart item: no cart exists. Reach out to support@replo.app if this persists.\",\n );\n return;\n }\n\n const itemToRemove = cartData.lines.find((item) => item.id === lineId);\n if (analytics && itemToRemove && itemToRemove.merchandise) {\n // NOTE (Max, 2026-08-03): cart amounts are integer minor units, but the\n // analytics payload speaks decimal major units (ad pixels + the Replo\n // store), so convert at this boundary.\n void analytics.removeFromCart({\n data: {\n productId: itemToRemove.merchandise.product.id,\n variantId: itemToRemove.merchandise.id,\n quantity: itemToRemove.quantity,\n price: fromMinorUnitsToMajorUnits({\n amount: itemToRemove.merchandise.price,\n currencyCode: cartData.cost.currencyCode,\n }),\n currency: cartData.cost.currencyCode,\n productTitle: itemToRemove.merchandise.product.title,\n variantTitle: itemToRemove.merchandise.title,\n },\n });\n }\n\n // Optimistic update - use functional form to avoid stale state\n setCartData((currentCart) => {\n if (!currentCart) {\n return null;\n }\n return removeLineFromCart(currentCart, lineId);\n });\n\n // Direct server update (no debouncing)\n const serverCart = await removeCartLineItemsAction([lineId], cartData.id);\n if (serverCart) {\n setCartData(serverCart);\n } else {\n console.warn(\n \"[Replo] Failed to remove cart item on server. Cart may be out of sync. Reach out to support@replo.app if this persists.\",\n );\n }\n };\n\n const updateDiscountCodes = async (discountCodes: string[]) => {\n // If no cart exists, we can't update discount codes\n if (!cartData) {\n console.warn(\n \"[Replo] Cannot update discount codes: no cart exists. Reach out to support@replo.app if this persists.\",\n );\n return;\n }\n\n // Optimistic update - use functional form to avoid stale state\n setCartData((currentCart) => {\n if (!currentCart) {\n return null;\n }\n return {\n ...currentCart,\n discountCodes: discountCodes.map((code) => ({\n code,\n applicable: true,\n })),\n };\n });\n\n // Server update\n const serverCart = await updateCartDiscountCodesAction(\n discountCodes,\n cartData.id,\n );\n if (serverCart) {\n setCartData(serverCart);\n } else {\n console.warn(\n \"[Replo] Failed to update discount codes on server. Cart may be out of sync. Reach out to support@replo.app if this persists.\",\n );\n }\n };\n\n const buyNow = async (lines: CartLinePayload[], discountCodes?: string[]) => {\n // Create a new cart with the specified lines and discount codes\n const cart = await createCartAction({\n lines,\n skipStoringCart: true,\n discountCodes,\n });\n if (cart) {\n return cart;\n } else {\n console.warn(\n \"[Replo] Failed to create cart for buy now. Reach out to support@replo.app if this persists.\",\n );\n return null;\n }\n };\n\n const checkoutUrl: string = (() => {\n if (isEditorMode()) {\n return \"/\";\n }\n\n return cartData?.checkoutUrl ?? \"/\";\n })();\n\n return (\n <CartContext.Provider\n value={{\n cartData,\n lineItems,\n subtotal,\n itemsCount,\n currencyCode: cartData?.cost.currencyCode ?? \"USD\",\n addToCart,\n updateCartItem,\n removeCartItem,\n updateDiscountCodes,\n buyNow,\n checkoutUrl,\n isCartOpen,\n openCart,\n closeCart,\n }}\n >\n {children}\n </CartContext.Provider>\n );\n}\n\n/**\n * @deprecated For internal use only. Use useAddToCart or useBuyNow\n * for cart operations. Use useCart for cart UI state (itemsCount, openCart, closeCart).\n */\nexport function useCartInternal(): CartContextTypeInternal {\n const context = React.useContext(CartContext);\n if (context === undefined) {\n throw new CartContextError({\n message: \"useCartInternal must be used within a CartProvider\",\n });\n }\n return context;\n}\n\n/**\n * Hook to access cart UI state and controls. For adding products to cart,\n * use useAddToCart. For buy now functionality, use useBuyNow.\n *\n * @example\n * ```tsx\n * import { useCart } from \"@replohq/sdk/cart/cart-provider\";\n *\n * function MyComponent() {\n * const { itemsCount, openCart } = useCart();\n * ...\n * }\n * ```\n * @throws Error if used outside of a CartProvider\n */\nexport function useCart(): CartContextType {\n const context = React.useContext(CartContext);\n if (context === undefined) {\n throw new CartContextError({\n message: \"useCart must be used within a CartProvider\",\n });\n }\n return {\n itemsCount: context.itemsCount,\n isCartOpen: context.isCartOpen,\n openCart: context.openCart,\n closeCart: context.closeCart,\n updateDiscountCodes: context.updateDiscountCodes,\n };\n}\n"],
5
+ "mappings": ";AAwgBI;AAhgBJ,OAAO,WAAW;AAElB,SAAS,kCAAkC;AAC3C,SAAS,MAAM,cAAc;AAE7B,SAAS,4BAA4B;AACrC,SAAS,mBAAmB;AAC5B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,6CAA6C;AAEtD,MAAM,yBAAyB,YAAY;AAAC;AAO5C,MAAM,eAAe,MAAM;AACzB,MAAI,OAAO,WAAW,aAAa;AACjC,WAAO;AAAA,EACT;AAEA,SAAO,OAAO,WAAW;AAC3B;AAGA,IAAI,sBAAmD;AAUvD,SAAS,cAAc,MAAY,MAA6B;AAC9D,QAAM,oBAAoB,KAAK,MAAM,UAAU,CAAC,iBAAiB;AAC/D,WACE,aAAa,aAAa,OAAO,KAAK;AAAA,KAErC,KAAK,iBAAiB,WACpB,aAAa,uBAAuB,YAAY,MAAM;AAAA,EAE7D,CAAC;AAED,MAAI,qBAAqB,GAAG;AAE1B,UAAM,eAAe,CAAC,GAAG,KAAK,KAAK;AACnC,iBAAa,iBAAiB,IAAI;AAAA,MAChC,GAAG,aAAa,iBAAiB;AAAA,MACjC,UAAU,aAAa,iBAAiB,EAAG,WAAW,KAAK;AAAA,IAC7D;AACA,WAAO,EAAE,GAAG,MAAM,OAAO,aAAa;AAAA,EACxC,OAAO;AACL,UAAM,kCACJ,KAAK,iBAAiB,KAAK,cACvB,sCAAsC;AAAA,MACpC,aAAa,KAAK;AAAA,MAClB,eAAe,KAAK;AAAA,MACpB,cAAc,KAAK,MAAM,gBAAgB;AAAA,IAC3C,CAAC,IACD;AAEN,UAAM,UAAoB;AAAA,MACxB,IAAI,QAAQ,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,EAAE,CAAC;AAAA,MACjE,UAAU,KAAK;AAAA,MACf,aAAa,KAAK,eAAe;AAAA,MACjC,YAAY,KAAK,cAAc,CAAC;AAAA,MAChC,uBAAuB;AAAA,IACzB;AACA,WAAO,EAAE,GAAG,MAAM,OAAO,CAAC,SAAS,GAAG,KAAK,KAAK,EAAE;AAAA,EACpD;AACF;AASA,SAAS,iBAAiB,MAAY,MAA6B;AACjE,QAAM,eAAe,KAAK,MAAM,IAAI,CAAC,iBAAiB;AACpD,WAAO,aAAa,OAAO,KAAK,KAC5B,EAAE,GAAG,cAAc,UAAU,KAAK,SAAS,IAC3C;AAAA,EACN,CAAC;AACD,SAAO,EAAE,GAAG,MAAM,OAAO,aAAa;AACxC;AASA,SAAS,mBAAmB,MAAY,QAAsB;AAC5D,QAAM,eAAe,KAAK,MAAM,OAAO,CAAC,SAAS,KAAK,OAAO,MAAM;AACnE,SAAO,EAAE,GAAG,MAAM,OAAO,aAAa;AACxC;AA+DA,MAAM,cAAc,MAAM;AAAA,EACxB;AACF;AASO,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AACF,GAGI;AACF,QAAM,CAAC,UAAU,WAAW,IAAI,MAAM,SAAsB,IAAI;AAChE,QAAM,CAAC,YAAY,aAAa,IAAI,MAAM,SAAS,KAAK;AACxD,QAAM,iBAAiB,MAAM,OAAO,KAAK;AACzC,QAAM,YAAY,qBAAqB;AAIvC,QAAM,UAAU,MAAM;AAEpB,QAAI,eAAe,SAAS;AAC1B;AAAA,IACF;AAGA,QAAI,qBAAqB;AACvB,WAAK,oBAAoB,KAAK,CAACA,UAAS;AACtC,YAAIA,OAAM;AACR,sBAAYA,KAAI;AAAA,QAClB;AAAA,MACF,CAAC;AACD;AAAA,IACF;AAGA,mBAAe,UAAU;AAGzB,0BAAsB,sBAAsB,EACzC,KAAK,CAACA,UAAS;AACd,UAAIA,OAAM;AACR,oBAAYA,KAAI;AAAA,MAClB,OAAO;AACL,gBAAQ;AAAA,UACN;AAAA,QACF;AAAA,MACF;AACA,aAAOA;AAAA,IACT,CAAC,EACA,MAAM,CAAC,UAAU;AAChB,cAAQ,MAAM,2CAA2C,KAAK;AAC9D,aAAO;AAAA,IACT,CAAC,EACA,QAAQ,MAAM;AAEb,4BAAsB;AAAA,IACxB,CAAC;AAAA,EACL,GAAG,CAAC,CAAC;AAGL,QAAM,YAAY,UAAU,SAAS,CAAC;AAEtC,QAAM,WACJ,UAAU,MAAM,OAAO,CAAC,KAAK,aAAa;AACxC,QAAI,SAAS,WAAW,KAAK,SAAS,aAAa;AACjD,aAAO,SAAS,YAAY,QAAQ,SAAS;AAAA,IAC/C;AACA,WAAO;AAAA,EACT,GAAG,CAAC,KAAK;AAEX,QAAM,aACJ,UAAU,MAAM,OAAO,CAAC,KAAK,aAAa;AACxC,QAAI,SAAS,WAAW,GAAG;AACzB,aAAO,SAAS;AAAA,IAClB;AACA,WAAO;AAAA,EACT,GAAG,CAAC,KAAK;AAGX,QAAM,WAAW,MAAM,YAAY,MAAM;AACvC,kBAAc,IAAI;AAElB,QAAI,WAAW;AACb,YAAM,wBAAwB,UAAU,KAAK,gBAAgB;AAI7D,WAAK,UAAU,SAAS;AAAA,QACtB,MAAM;AAAA,UACJ,WAAW;AAAA,UACX,UAAU,2BAA2B;AAAA,YACnC,QAAQ;AAAA,YACR,cAAc;AAAA,UAChB,CAAC;AAAA,UACD,UAAU,UAAU,KAAK;AAAA,UACzB,WAAW,UAAU,MAAM,QAAQ,CAAC,SAAS;AAC3C,gBAAI,CAAC,KAAK,aAAa;AACrB,qBAAO,CAAC;AAAA,YACV;AACA,mBAAO;AAAA,cACL;AAAA,gBACE,WAAW,KAAK,YAAY,QAAQ;AAAA,gBACpC,WAAW,KAAK,YAAY;AAAA,gBAC5B,UAAU,KAAK;AAAA,gBACf,OAAO,2BAA2B;AAAA,kBAChC,QAAQ,KAAK,YAAY;AAAA,kBACzB,cAAc;AAAA,gBAChB,CAAC;AAAA,cACH;AAAA,YACF;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,GAAG,CAAC,WAAW,UAAU,YAAY,QAAQ,CAAC;AAE9C,QAAM,YAAY,MAAM,YAAY,MAAM;AACxC,kBAAc,KAAK;AAAA,EACrB,GAAG,CAAC,CAAC;AAGL,QAAM,wBAAwB,MAAM,OAAsB,IAAI;AAE9D,QAAM,YAAY,OAChB,OACA,mBAA4B,SACzB;AAEH,QAAI,CAAC,UAAU;AACb,cAAQ;AAAA,QACN;AAAA,MACF;AACA;AAAA,IACF;AAGA,gBAAY,CAAC,gBAAgB;AAC3B,UAAI,CAAC,aAAa;AAChB,eAAO;AAAA,MACT;AACA,UAAI,cAAc,EAAE,GAAG,YAAY;AACnC,iBAAW,QAAQ,OAAO;AACxB,sBAAc,cAAc,aAAa,IAAI;AAAA,MAC/C;AACA,aAAO;AAAA,IACT,CAAC;AAED,QAAI,kBAAkB;AACpB,eAAS;AAAA,IACX;AAEA,QAAI,WAAW;AACb,iBAAW,QAAQ,OAAO;AACxB,YAAI,CAAC,KAAK,aAAa;AACrB;AAAA,QACF;AAIA,aAAK,UAAU,UAAU;AAAA,UACvB,MAAM;AAAA,YACJ,WAAW,KAAK,YAAY,QAAQ;AAAA,YACpC,WAAW,KAAK,YAAY;AAAA,YAC5B,UAAU,KAAK;AAAA,YACf,OAAO,2BAA2B;AAAA,cAChC,QAAQ,KAAK,YAAY;AAAA,cACzB,cAAc,UAAU,KAAK,gBAAgB;AAAA,YAC/C,CAAC;AAAA,YACD,UAAU,UAAU,KAAK;AAAA,YACzB,cAAc,KAAK,YAAY,QAAQ;AAAA,YACvC,cAAc,KAAK,YAAY;AAAA,UACjC;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAGA,UAAM,aAAa,MAAM,gBAAgB,OAAO,SAAS,EAAE;AAC3D,QAAI,YAAY;AACd,kBAAY,UAAU;AAAA,IACxB,OAAO;AACL,cAAQ;AAAA,QACN;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,iBAAiB,OAAO,SAA0B;AAEtD,QAAI,CAAC,UAAU;AACb,cAAQ;AAAA,QACN;AAAA,MACF;AACA;AAAA,IACF;AAGA,UAAM,YAAY,OAAO;AACzB,0BAAsB,UAAU;AAGhC,gBAAY,CAAC,gBAAgB;AAC3B,UAAI,CAAC,aAAa;AAChB,eAAO;AAAA,MACT;AACA,aAAO,iBAAiB,aAAa,IAAI;AAAA,IAC3C,CAAC;AAGD,UAAM,aAAa,MAAM,yBAAyB,MAAM,SAAS,EAAE;AAGnE,QAAI,sBAAsB,YAAY,WAAW;AAC/C,UAAI,YAAY;AACd,oBAAY,UAAU;AAAA,MACxB,OAAO;AACL,gBAAQ;AAAA,UACN;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,iBAAiB,OAAO,WAAmB;AAC/C,QAAI,CAAC,UAAU;AACb,cAAQ;AAAA,QACN;AAAA,MACF;AACA;AAAA,IACF;AAEA,UAAM,eAAe,SAAS,MAAM,KAAK,CAAC,SAAS,KAAK,OAAO,MAAM;AACrE,QAAI,aAAa,gBAAgB,aAAa,aAAa;AAIzD,WAAK,UAAU,eAAe;AAAA,QAC5B,MAAM;AAAA,UACJ,WAAW,aAAa,YAAY,QAAQ;AAAA,UAC5C,WAAW,aAAa,YAAY;AAAA,UACpC,UAAU,aAAa;AAAA,UACvB,OAAO,2BAA2B;AAAA,YAChC,QAAQ,aAAa,YAAY;AAAA,YACjC,cAAc,SAAS,KAAK;AAAA,UAC9B,CAAC;AAAA,UACD,UAAU,SAAS,KAAK;AAAA,UACxB,cAAc,aAAa,YAAY,QAAQ;AAAA,UAC/C,cAAc,aAAa,YAAY;AAAA,QACzC;AAAA,MACF,CAAC;AAAA,IACH;AAGA,gBAAY,CAAC,gBAAgB;AAC3B,UAAI,CAAC,aAAa;AAChB,eAAO;AAAA,MACT;AACA,aAAO,mBAAmB,aAAa,MAAM;AAAA,IAC/C,CAAC;AAGD,UAAM,aAAa,MAAM,0BAA0B,CAAC,MAAM,GAAG,SAAS,EAAE;AACxE,QAAI,YAAY;AACd,kBAAY,UAAU;AAAA,IACxB,OAAO;AACL,cAAQ;AAAA,QACN;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,sBAAsB,OAAO,kBAA4B;AAE7D,QAAI,CAAC,UAAU;AACb,cAAQ;AAAA,QACN;AAAA,MACF;AACA;AAAA,IACF;AAGA,gBAAY,CAAC,gBAAgB;AAC3B,UAAI,CAAC,aAAa;AAChB,eAAO;AAAA,MACT;AACA,aAAO;AAAA,QACL,GAAG;AAAA,QACH,eAAe,cAAc,IAAI,CAAC,UAAU;AAAA,UAC1C;AAAA,UACA,YAAY;AAAA,QACd,EAAE;AAAA,MACJ;AAAA,IACF,CAAC;AAGD,UAAM,aAAa,MAAM;AAAA,MACvB;AAAA,MACA,SAAS;AAAA,IACX;AACA,QAAI,YAAY;AACd,kBAAY,UAAU;AAAA,IACxB,OAAO;AACL,cAAQ;AAAA,QACN;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS,OAAO,OAA0B,kBAA6B;AAE3E,UAAMA,QAAO,MAAM,iBAAiB;AAAA,MAClC;AAAA,MACA,iBAAiB;AAAA,MACjB;AAAA,IACF,CAAC;AACD,QAAIA,OAAM;AACR,aAAOA;AAAA,IACT,OAAO;AACL,cAAQ;AAAA,QACN;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,eAAuB,MAAM;AACjC,QAAI,aAAa,GAAG;AAClB,aAAO;AAAA,IACT;AAEA,WAAO,UAAU,eAAe;AAAA,EAClC,GAAG;AAEH,SACE;AAAA,IAAC,YAAY;AAAA,IAAZ;AAAA,MACC,OAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,cAAc,UAAU,KAAK,gBAAgB;AAAA,QAC7C;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MAEC;AAAA;AAAA,EACH;AAEJ;AAMO,SAAS,kBAA2C;AACzD,QAAM,UAAU,MAAM,WAAW,WAAW;AAC5C,MAAI,YAAY,QAAW;AACzB,UAAM,IAAI,iBAAiB;AAAA,MACzB,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAiBO,SAAS,UAA2B;AACzC,QAAM,UAAU,MAAM,WAAW,WAAW;AAC5C,MAAI,YAAY,QAAW;AACzB,UAAM,IAAI,iBAAiB;AAAA,MACzB,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AACA,SAAO;AAAA,IACL,YAAY,QAAQ;AAAA,IACpB,YAAY,QAAQ;AAAA,IACpB,UAAU,QAAQ;AAAA,IAClB,WAAW,QAAQ;AAAA,IACnB,qBAAqB,QAAQ;AAAA,EAC/B;AACF;",
6
+ "names": ["cart"]
7
+ }
@@ -0,0 +1,74 @@
1
+ import { z } from "zod";
2
+ export declare const cartSchema: z.ZodObject<{
3
+ id: z.ZodString;
4
+ lines: z.ZodArray<z.ZodObject<{
5
+ id: z.ZodString;
6
+ quantity: z.ZodNumber;
7
+ merchandise: z.ZodObject<{
8
+ id: z.ZodString;
9
+ product: z.ZodObject<{
10
+ id: z.ZodString;
11
+ title: z.ZodString;
12
+ }, z.core.$strip>;
13
+ title: z.ZodString;
14
+ price: z.ZodNumber;
15
+ compareAtPrice: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
16
+ image: z.ZodNullable<z.ZodObject<{
17
+ url: z.ZodString;
18
+ altText: z.ZodNullable<z.ZodString>;
19
+ }, z.core.$strip>>;
20
+ selectedOptions: z.ZodArray<z.ZodObject<{
21
+ name: z.ZodString;
22
+ value: z.ZodString;
23
+ }, z.core.$strip>>;
24
+ }, z.core.$strip>;
25
+ attributes: z.ZodArray<z.ZodObject<{
26
+ key: z.ZodString;
27
+ value: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>;
28
+ }, z.core.$strip>>;
29
+ sellingPlanAllocation: z.ZodOptional<z.ZodNullable<z.ZodObject<{
30
+ sellingPlan: z.ZodObject<{
31
+ id: z.ZodString;
32
+ name: z.ZodString;
33
+ description: z.ZodNullable<z.ZodString>;
34
+ }, z.core.$strip>;
35
+ priceAdjustments: z.ZodArray<z.ZodObject<{
36
+ compareAtPrice: z.ZodObject<{
37
+ amount: z.ZodNumber;
38
+ currencyCode: z.ZodString;
39
+ }, z.core.$strip>;
40
+ perDeliveryPrice: z.ZodObject<{
41
+ amount: z.ZodNumber;
42
+ currencyCode: z.ZodString;
43
+ }, z.core.$strip>;
44
+ price: z.ZodObject<{
45
+ amount: z.ZodNumber;
46
+ currencyCode: z.ZodString;
47
+ }, z.core.$strip>;
48
+ unitPrice: z.ZodNullable<z.ZodObject<{
49
+ amount: z.ZodNumber;
50
+ currencyCode: z.ZodString;
51
+ }, z.core.$strip>>;
52
+ }, z.core.$strip>>;
53
+ checkoutChargeAmount: z.ZodObject<{
54
+ amount: z.ZodNumber;
55
+ currencyCode: z.ZodString;
56
+ }, z.core.$strip>;
57
+ remainingBalanceChargeAmount: z.ZodObject<{
58
+ amount: z.ZodNumber;
59
+ currencyCode: z.ZodString;
60
+ }, z.core.$strip>;
61
+ }, z.core.$strip>>>;
62
+ }, z.core.$strip>>;
63
+ cost: z.ZodObject<{
64
+ subtotalAmount: z.ZodNumber;
65
+ totalAmount: z.ZodNumber;
66
+ currencyCode: z.ZodString;
67
+ }, z.core.$strip>;
68
+ checkoutUrl: z.ZodOptional<z.ZodString>;
69
+ discountCodes: z.ZodOptional<z.ZodArray<z.ZodObject<{
70
+ code: z.ZodString;
71
+ applicable: z.ZodBoolean;
72
+ }, z.core.$strip>>>;
73
+ }, z.core.$strip>;
74
+ export type Cart = z.infer<typeof cartSchema>;
@@ -0,0 +1,69 @@
1
+ import { z } from "zod";
2
+ const cartLineAttributeSchema = z.object({
3
+ key: z.string(),
4
+ value: z.union([z.string(), z.number(), z.boolean()])
5
+ });
6
+ const cartImageSchema = z.object({
7
+ url: z.string(),
8
+ altText: z.string().nullable()
9
+ });
10
+ const amountSchema = z.number().int();
11
+ const amountWithCurrencyCodeSchema = z.object({
12
+ amount: amountSchema,
13
+ currencyCode: z.string()
14
+ });
15
+ const sellingPlanPriceAdjustmentSchema = z.object({
16
+ compareAtPrice: amountWithCurrencyCodeSchema,
17
+ perDeliveryPrice: amountWithCurrencyCodeSchema,
18
+ price: amountWithCurrencyCodeSchema,
19
+ unitPrice: amountWithCurrencyCodeSchema.nullable()
20
+ });
21
+ const sellingPlanAllocationSchema = z.object({
22
+ sellingPlan: z.object({
23
+ id: z.string(),
24
+ name: z.string(),
25
+ description: z.string().nullable()
26
+ }),
27
+ priceAdjustments: z.array(sellingPlanPriceAdjustmentSchema),
28
+ checkoutChargeAmount: amountWithCurrencyCodeSchema,
29
+ remainingBalanceChargeAmount: amountWithCurrencyCodeSchema
30
+ });
31
+ const cartLineMerchandiseSchema = z.object({
32
+ id: z.string(),
33
+ product: z.object({
34
+ id: z.string(),
35
+ title: z.string()
36
+ }),
37
+ title: z.string(),
38
+ price: amountSchema,
39
+ compareAtPrice: amountSchema.nullish(),
40
+ image: cartImageSchema.nullable(),
41
+ selectedOptions: z.array(z.object({ name: z.string(), value: z.string() }))
42
+ });
43
+ const cartLineSchema = z.object({
44
+ id: z.string(),
45
+ quantity: z.number(),
46
+ merchandise: cartLineMerchandiseSchema,
47
+ attributes: z.array(cartLineAttributeSchema),
48
+ sellingPlanAllocation: sellingPlanAllocationSchema.nullish()
49
+ });
50
+ const cartCostSchema = z.object({
51
+ subtotalAmount: amountSchema,
52
+ totalAmount: amountSchema,
53
+ currencyCode: z.string()
54
+ });
55
+ const cartDiscountCodeSchema = z.object({
56
+ code: z.string(),
57
+ applicable: z.boolean()
58
+ });
59
+ const cartSchema = z.object({
60
+ id: z.string(),
61
+ lines: z.array(cartLineSchema),
62
+ cost: cartCostSchema,
63
+ checkoutUrl: z.string().optional(),
64
+ discountCodes: z.array(cartDiscountCodeSchema).optional()
65
+ });
66
+ export {
67
+ cartSchema
68
+ };
69
+ //# sourceMappingURL=cart-schema.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../cart/cart-schema.ts"],
4
+ "sourcesContent": ["import { z } from \"zod\";\n\n// NOTE (Ryan, 2026-07-23, REPL-27611): Self-contained copy of the cart wire\n// schema that the SDK gateway validates on published pages, so nothing\n// shipped to a generated site imports from `schemas`. The backend keeps the\n// canonical copy in `schemas/cart.ts` (its cart services can't depend on\n// the SDK without a cycle); `cart-schema.spec.ts` keeps the two in lockstep.\n// This module is internal wire validation; public types live in `cart/cart-types`.\n\n// ---------------------------------------------------------------------------\n// Cart line attribute\n// ---------------------------------------------------------------------------\n\nconst cartLineAttributeSchema = z.object({\n key: z.string(),\n value: z.union([z.string(), z.number(), z.boolean()]),\n});\n\n// ---------------------------------------------------------------------------\n// Image (cart-scoped; lightweight compared to objectType image)\n// ---------------------------------------------------------------------------\n\nconst cartImageSchema = z.object({\n url: z.string(),\n altText: z.string().nullable(),\n});\n\n// ---------------------------------------------------------------------------\n// Selling plan types\n// ---------------------------------------------------------------------------\n\n// Integer minor units (Stripe convention): 1999 = $19.99 USD. Mirrors\n// amountSchema in schemas/money.ts, which shipped code cannot import.\nconst amountSchema = z.number().int();\nconst amountWithCurrencyCodeSchema = z.object({\n amount: amountSchema,\n currencyCode: z.string(),\n});\n\nconst sellingPlanPriceAdjustmentSchema = z.object({\n compareAtPrice: amountWithCurrencyCodeSchema,\n perDeliveryPrice: amountWithCurrencyCodeSchema,\n price: amountWithCurrencyCodeSchema,\n unitPrice: amountWithCurrencyCodeSchema.nullable(),\n});\n\nconst sellingPlanAllocationSchema = z.object({\n sellingPlan: z.object({\n id: z.string(),\n name: z.string(),\n description: z.string().nullable(),\n }),\n priceAdjustments: z.array(sellingPlanPriceAdjustmentSchema),\n checkoutChargeAmount: amountWithCurrencyCodeSchema,\n remainingBalanceChargeAmount: amountWithCurrencyCodeSchema,\n});\n\n// ---------------------------------------------------------------------------\n// Cart line merchandise\n// ---------------------------------------------------------------------------\n\nconst cartLineMerchandiseSchema = z.object({\n id: z.string(),\n product: z.object({\n id: z.string(),\n title: z.string(),\n }),\n title: z.string(),\n price: amountSchema,\n compareAtPrice: amountSchema.nullish(),\n image: cartImageSchema.nullable(),\n selectedOptions: z.array(z.object({ name: z.string(), value: z.string() })),\n});\n\n// ---------------------------------------------------------------------------\n// Cart line\n// ---------------------------------------------------------------------------\n\nconst cartLineSchema = z.object({\n id: z.string(),\n quantity: z.number(),\n merchandise: cartLineMerchandiseSchema,\n attributes: z.array(cartLineAttributeSchema),\n sellingPlanAllocation: sellingPlanAllocationSchema.nullish(),\n});\n\n// ---------------------------------------------------------------------------\n// Cart cost\n// ---------------------------------------------------------------------------\n\nconst cartCostSchema = z.object({\n subtotalAmount: amountSchema,\n totalAmount: amountSchema,\n currencyCode: z.string(),\n});\n\n// ---------------------------------------------------------------------------\n// Cart discount code\n// ---------------------------------------------------------------------------\n\nconst cartDiscountCodeSchema = z.object({\n code: z.string(),\n applicable: z.boolean(),\n});\n\n// ---------------------------------------------------------------------------\n// Cart (top level)\n// ---------------------------------------------------------------------------\n\nexport const cartSchema = z.object({\n id: z.string(),\n lines: z.array(cartLineSchema),\n cost: cartCostSchema,\n checkoutUrl: z.string().optional(),\n discountCodes: z.array(cartDiscountCodeSchema).optional(),\n});\n\nexport type Cart = z.infer<typeof cartSchema>;\n"],
5
+ "mappings": "AAAA,SAAS,SAAS;AAalB,MAAM,0BAA0B,EAAE,OAAO;AAAA,EACvC,KAAK,EAAE,OAAO;AAAA,EACd,OAAO,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC,CAAC;AACtD,CAAC;AAMD,MAAM,kBAAkB,EAAE,OAAO;AAAA,EAC/B,KAAK,EAAE,OAAO;AAAA,EACd,SAAS,EAAE,OAAO,EAAE,SAAS;AAC/B,CAAC;AAQD,MAAM,eAAe,EAAE,OAAO,EAAE,IAAI;AACpC,MAAM,+BAA+B,EAAE,OAAO;AAAA,EAC5C,QAAQ;AAAA,EACR,cAAc,EAAE,OAAO;AACzB,CAAC;AAED,MAAM,mCAAmC,EAAE,OAAO;AAAA,EAChD,gBAAgB;AAAA,EAChB,kBAAkB;AAAA,EAClB,OAAO;AAAA,EACP,WAAW,6BAA6B,SAAS;AACnD,CAAC;AAED,MAAM,8BAA8B,EAAE,OAAO;AAAA,EAC3C,aAAa,EAAE,OAAO;AAAA,IACpB,IAAI,EAAE,OAAO;AAAA,IACb,MAAM,EAAE,OAAO;AAAA,IACf,aAAa,EAAE,OAAO,EAAE,SAAS;AAAA,EACnC,CAAC;AAAA,EACD,kBAAkB,EAAE,MAAM,gCAAgC;AAAA,EAC1D,sBAAsB;AAAA,EACtB,8BAA8B;AAChC,CAAC;AAMD,MAAM,4BAA4B,EAAE,OAAO;AAAA,EACzC,IAAI,EAAE,OAAO;AAAA,EACb,SAAS,EAAE,OAAO;AAAA,IAChB,IAAI,EAAE,OAAO;AAAA,IACb,OAAO,EAAE,OAAO;AAAA,EAClB,CAAC;AAAA,EACD,OAAO,EAAE,OAAO;AAAA,EAChB,OAAO;AAAA,EACP,gBAAgB,aAAa,QAAQ;AAAA,EACrC,OAAO,gBAAgB,SAAS;AAAA,EAChC,iBAAiB,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;AAC5E,CAAC;AAMD,MAAM,iBAAiB,EAAE,OAAO;AAAA,EAC9B,IAAI,EAAE,OAAO;AAAA,EACb,UAAU,EAAE,OAAO;AAAA,EACnB,aAAa;AAAA,EACb,YAAY,EAAE,MAAM,uBAAuB;AAAA,EAC3C,uBAAuB,4BAA4B,QAAQ;AAC7D,CAAC;AAMD,MAAM,iBAAiB,EAAE,OAAO;AAAA,EAC9B,gBAAgB;AAAA,EAChB,aAAa;AAAA,EACb,cAAc,EAAE,OAAO;AACzB,CAAC;AAMD,MAAM,yBAAyB,EAAE,OAAO;AAAA,EACtC,MAAM,EAAE,OAAO;AAAA,EACf,YAAY,EAAE,QAAQ;AACxB,CAAC;AAMM,MAAM,aAAa,EAAE,OAAO;AAAA,EACjC,IAAI,EAAE,OAAO;AAAA,EACb,OAAO,EAAE,MAAM,cAAc;AAAA,EAC7B,MAAM;AAAA,EACN,aAAa,EAAE,OAAO,EAAE,SAAS;AAAA,EACjC,eAAe,EAAE,MAAM,sBAAsB,EAAE,SAAS;AAC1D,CAAC;",
6
+ "names": []
7
+ }