@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.
- package/LICENSE +11 -0
- package/_vendor/replo-utils/lib/crypto.d.ts +30 -0
- package/_vendor/replo-utils/lib/errors.d.ts +83 -0
- package/_vendor/replo-utils/lib/json.d.ts +6 -0
- package/_vendor/replo-utils/lib/json.mjs +43 -0
- package/_vendor/replo-utils/lib/misc.d.ts +145 -0
- package/_vendor/replo-utils/lib/object.d.ts +31 -0
- package/_vendor/schemas/errors.d.ts +459 -0
- package/_vendor/schemas/generated/consent.d.ts +55 -0
- package/_vendor/schemas/generated/errors.d.ts +61 -0
- package/_vendor/schemas/loaderKeys.d.ts +1 -0
- package/_vendor/schemas/loaderKeys.mjs +27 -0
- package/_vendor/schemas/money.d.ts +60 -0
- package/_vendor/schemas/money.mjs +2051 -0
- package/analytics/analytics-provider.d.ts +16 -0
- package/analytics/analytics-provider.js +113 -0
- package/analytics/analytics-provider.js.map +7 -0
- package/analytics/analytics-sink.d.ts +26 -0
- package/analytics/analytics-sink.js +1 -0
- package/analytics/analytics-sink.js.map +7 -0
- package/analytics/get-analytics-sinks.d.ts +27 -0
- package/analytics/get-analytics-sinks.js +52 -0
- package/analytics/get-analytics-sinks.js.map +7 -0
- package/analytics/hooks/use-product-viewed-analytics.d.ts +23 -0
- package/analytics/hooks/use-product-viewed-analytics.js +34 -0
- package/analytics/hooks/use-product-viewed-analytics.js.map +7 -0
- package/analytics/replo-first-party-pixel.d.ts +12 -0
- package/analytics/replo-first-party-pixel.js +31 -0
- package/analytics/replo-first-party-pixel.js.map +7 -0
- package/analytics/replo-pixel-script.d.ts +13 -0
- package/analytics/replo-pixel-script.js +30 -0
- package/analytics/replo-pixel-script.js.map +7 -0
- package/analytics/sinks/ga4-sink.d.ts +15 -0
- package/analytics/sinks/ga4-sink.js +60 -0
- package/analytics/sinks/ga4-sink.js.map +7 -0
- package/analytics/sinks/meta-sink.d.ts +14 -0
- package/analytics/sinks/meta-sink.js +56 -0
- package/analytics/sinks/meta-sink.js.map +7 -0
- package/analytics/sinks/pinterest-sink.d.ts +14 -0
- package/analytics/sinks/pinterest-sink.js +76 -0
- package/analytics/sinks/pinterest-sink.js.map +7 -0
- package/analytics/sinks/reddit-sink.d.ts +14 -0
- package/analytics/sinks/reddit-sink.js +80 -0
- package/analytics/sinks/reddit-sink.js.map +7 -0
- package/analytics/sinks/replo-sink.d.ts +14 -0
- package/analytics/sinks/replo-sink.js +57 -0
- package/analytics/sinks/replo-sink.js.map +7 -0
- package/analytics/sinks/snapchat-sink.d.ts +14 -0
- package/analytics/sinks/snapchat-sink.js +67 -0
- package/analytics/sinks/snapchat-sink.js.map +7 -0
- package/analytics/sinks/tiktok-sink.d.ts +14 -0
- package/analytics/sinks/tiktok-sink.js +79 -0
- package/analytics/sinks/tiktok-sink.js.map +7 -0
- package/analytics/sinks/window-sink.d.ts +18 -0
- package/analytics/sinks/window-sink.js +46 -0
- package/analytics/sinks/window-sink.js.map +7 -0
- package/analytics/utils/analytics-utils.d.ts +7 -0
- package/analytics/utils/analytics-utils.js +130 -0
- package/analytics/utils/analytics-utils.js.map +7 -0
- package/analytics/utils/navigation-tracker.d.ts +16 -0
- package/analytics/utils/navigation-tracker.js +44 -0
- package/analytics/utils/navigation-tracker.js.map +7 -0
- package/analytics/utils/shopify-funnel-gate.d.ts +8 -0
- package/analytics/utils/shopify-funnel-gate.js +22 -0
- package/analytics/utils/shopify-funnel-gate.js.map +7 -0
- package/cart/buy-now-action.d.ts +21 -0
- package/cart/buy-now-action.js +104 -0
- package/cart/buy-now-action.js.map +7 -0
- package/cart/cart-actions.d.ts +63 -0
- package/cart/cart-actions.js +90 -0
- package/cart/cart-actions.js.map +7 -0
- package/cart/cart-loader.d.ts +9 -0
- package/cart/cart-loader.js +11 -0
- package/cart/cart-loader.js.map +7 -0
- package/cart/cart-provider.d.ts +85 -0
- package/cart/cart-provider.js +372 -0
- package/cart/cart-provider.js.map +7 -0
- package/cart/cart-schema.d.ts +74 -0
- package/cart/cart-schema.js +69 -0
- package/cart/cart-schema.js.map +7 -0
- package/cart/cart-types.d.ts +132 -0
- package/cart/cart-types.js +8 -0
- package/cart/cart-types.js.map +7 -0
- package/cart/gateways/cart-constants.d.ts +1 -0
- package/cart/gateways/cart-constants.js +5 -0
- package/cart/gateways/cart-constants.js.map +7 -0
- package/cart/gateways/cart-gateway.d.ts +10 -0
- package/cart/gateways/cart-gateway.js +19 -0
- package/cart/gateways/cart-gateway.js.map +7 -0
- package/cart/gateways/cookie-cart-gateway.d.ts +28 -0
- package/cart/gateways/cookie-cart-gateway.js +109 -0
- package/cart/gateways/cookie-cart-gateway.js.map +7 -0
- package/cart/gateways/default-cart-gateway.d.ts +19 -0
- package/cart/gateways/default-cart-gateway.js +30 -0
- package/cart/gateways/default-cart-gateway.js.map +7 -0
- package/cart/gateways/resolver-cart-gateway.d.ts +2 -0
- package/cart/gateways/resolver-cart-gateway.js +109 -0
- package/cart/gateways/resolver-cart-gateway.js.map +7 -0
- package/cart/gateways/stripe-cart-gateway.d.ts +19 -0
- package/cart/gateways/stripe-cart-gateway.js +28 -0
- package/cart/gateways/stripe-cart-gateway.js.map +7 -0
- package/cart/hooks/use-add-to-cart.d.ts +63 -0
- package/cart/hooks/use-add-to-cart.js +124 -0
- package/cart/hooks/use-add-to-cart.js.map +7 -0
- package/cart/hooks/use-buy-now.d.ts +49 -0
- package/cart/hooks/use-buy-now.js +62 -0
- package/cart/hooks/use-buy-now.js.map +7 -0
- package/cart/utils/cart-utils.d.ts +43 -0
- package/cart/utils/cart-utils.js +46 -0
- package/cart/utils/cart-utils.js.map +7 -0
- package/cart/utils/cookie-cart-persistence.d.ts +55 -0
- package/cart/utils/cookie-cart-persistence.js +166 -0
- package/cart/utils/cookie-cart-persistence.js.map +7 -0
- package/cart/utils/variant-to-cart-line.d.ts +74 -0
- package/cart/utils/variant-to-cart-line.js +162 -0
- package/cart/utils/variant-to-cart-line.js.map +7 -0
- package/chunk-UJCSKKID.mjs +27 -0
- package/consent/consent-action.d.ts +9 -0
- package/consent/consent-action.js +25 -0
- package/consent/consent-action.js.map +7 -0
- package/consent/consent-actions.d.ts +28 -0
- package/consent/consent-actions.js +36 -0
- package/consent/consent-actions.js.map +7 -0
- package/consent/consent-store.d.ts +69 -0
- package/consent/consent-store.js +194 -0
- package/consent/consent-store.js.map +7 -0
- package/consent/cookie.d.ts +36 -0
- package/consent/cookie.js +82 -0
- package/consent/cookie.js.map +7 -0
- package/consent/replo-scripts.d.ts +23 -0
- package/consent/replo-scripts.js +102 -0
- package/consent/replo-scripts.js.map +7 -0
- package/consent/script-registration-store.d.ts +25 -0
- package/consent/script-registration-store.js +61 -0
- package/consent/script-registration-store.js.map +7 -0
- package/consent/script-snippets.d.ts +24 -0
- package/consent/script-snippets.js +122 -0
- package/consent/script-snippets.js.map +7 -0
- package/consent/types.d.ts +34 -0
- package/consent/types.js +1 -0
- package/consent/types.js.map +7 -0
- package/consent/window-api.d.ts +41 -0
- package/consent/window-api.js +73 -0
- package/consent/window-api.js.map +7 -0
- package/env.d.ts +9 -0
- package/env.js +42 -0
- package/env.js.map +7 -0
- package/gateways/canopy-api.d.ts +83 -0
- package/gateways/canopy-api.js +197 -0
- package/gateways/canopy-api.js.map +7 -0
- package/hooks/use-client-value.d.ts +10 -0
- package/hooks/use-client-value.js +12 -0
- package/hooks/use-client-value.js.map +7 -0
- package/hooks/use-formatted-price.d.ts +15 -0
- package/hooks/use-formatted-price.js +20 -0
- package/hooks/use-formatted-price.js.map +7 -0
- package/lib/canopy-error.d.ts +25 -0
- package/lib/canopy-error.js +24 -0
- package/lib/canopy-error.js.map +7 -0
- package/lib/get-query-client.d.ts +2 -0
- package/lib/get-query-client.js +34 -0
- package/lib/get-query-client.js.map +7 -0
- package/lib/integration-utils.d.ts +2 -0
- package/lib/integration-utils.js +9 -0
- package/lib/integration-utils.js.map +7 -0
- package/lib/shopify-utils.d.ts +10 -0
- package/lib/shopify-utils.js +7 -0
- package/lib/shopify-utils.js.map +7 -0
- package/lib/url-utils.d.ts +4 -0
- package/lib/url-utils.js +8 -0
- package/lib/url-utils.js.map +7 -0
- package/loaders/collection-loader.d.ts +11 -0
- package/loaders/collection-loader.js +55 -0
- package/loaders/collection-loader.js.map +7 -0
- package/loaders/collection-products-loader.d.ts +12 -0
- package/loaders/collection-products-loader.js +58 -0
- package/loaders/collection-products-loader.js.map +7 -0
- package/loaders/contentful-entries-loader.d.ts +17 -0
- package/loaders/contentful-entries-loader.js +78 -0
- package/loaders/contentful-entries-loader.js.map +7 -0
- package/loaders/contentful-entry-loader.d.ts +14 -0
- package/loaders/contentful-entry-loader.js +60 -0
- package/loaders/contentful-entry-loader.js.map +7 -0
- package/loaders/invoke-loader-action.d.ts +11 -0
- package/loaders/invoke-loader-action.js +14 -0
- package/loaders/invoke-loader-action.js.map +7 -0
- package/loaders/invoke-loader-server.d.ts +18 -0
- package/loaders/invoke-loader-server.js +40 -0
- package/loaders/invoke-loader-server.js.map +7 -0
- package/loaders/invoke-loader.d.ts +16 -0
- package/loaders/invoke-loader.js +37 -0
- package/loaders/invoke-loader.js.map +7 -0
- package/loaders/levanta-product-loader.d.ts +11 -0
- package/loaders/levanta-product-loader.js +53 -0
- package/loaders/levanta-product-loader.js.map +7 -0
- package/loaders/loader-error-boundary.d.ts +25 -0
- package/loaders/loader-error-boundary.js +24 -0
- package/loaders/loader-error-boundary.js.map +7 -0
- package/loaders/loader-keys.d.ts +34 -0
- package/loaders/loader-keys.js +26 -0
- package/loaders/loader-keys.js.map +7 -0
- package/loaders/loader-schemas.d.ts +946 -0
- package/loaders/loader-schemas.js +353 -0
- package/loaders/loader-schemas.js.map +7 -0
- package/loaders/metaobject-loader.d.ts +12 -0
- package/loaders/metaobject-loader.js +54 -0
- package/loaders/metaobject-loader.js.map +7 -0
- package/loaders/metaobjects-loader.d.ts +14 -0
- package/loaders/metaobjects-loader.js +60 -0
- package/loaders/metaobjects-loader.js.map +7 -0
- package/loaders/okendo-review-aggregate-loader.d.ts +17 -0
- package/loaders/okendo-review-aggregate-loader.js +56 -0
- package/loaders/okendo-review-aggregate-loader.js.map +7 -0
- package/loaders/okendo-reviews-loader.d.ts +23 -0
- package/loaders/okendo-reviews-loader.js +54 -0
- package/loaders/okendo-reviews-loader.js.map +7 -0
- package/loaders/prefetch-loaders.d.ts +33 -0
- package/loaders/prefetch-loaders.js +46 -0
- package/loaders/prefetch-loaders.js.map +7 -0
- package/loaders/preview-placeholder.d.ts +25 -0
- package/loaders/preview-placeholder.js +222 -0
- package/loaders/preview-placeholder.js.map +7 -0
- package/loaders/product-loader-args.d.ts +21 -0
- package/loaders/product-loader-args.js +17 -0
- package/loaders/product-loader-args.js.map +7 -0
- package/loaders/product-loader.d.ts +10 -0
- package/loaders/product-loader.js +52 -0
- package/loaders/product-loader.js.map +7 -0
- package/loaders/rebuy-recommendations-loader.d.ts +165 -0
- package/loaders/rebuy-recommendations-loader.js +57 -0
- package/loaders/rebuy-recommendations-loader.js.map +7 -0
- package/loaders/reviews-io-review-aggregate-loader.d.ts +12 -0
- package/loaders/reviews-io-review-aggregate-loader.js +43 -0
- package/loaders/reviews-io-review-aggregate-loader.js.map +7 -0
- package/loaders/reviews-io-reviews-loader.d.ts +14 -0
- package/loaders/reviews-io-reviews-loader.js +65 -0
- package/loaders/reviews-io-reviews-loader.js.map +7 -0
- package/loaders/smile-earning-rules-loader.d.ts +19 -0
- package/loaders/smile-earning-rules-loader.js +44 -0
- package/loaders/smile-earning-rules-loader.js.map +7 -0
- package/loaders/smile-rewards-loader.d.ts +19 -0
- package/loaders/smile-rewards-loader.js +44 -0
- package/loaders/smile-rewards-loader.js.map +7 -0
- package/loaders/smile-vip-tiers-loader.d.ts +18 -0
- package/loaders/smile-vip-tiers-loader.js +43 -0
- package/loaders/smile-vip-tiers-loader.js.map +7 -0
- package/loaders/statsig-experiment-loader.d.ts +20 -0
- package/loaders/statsig-experiment-loader.js +81 -0
- package/loaders/statsig-experiment-loader.js.map +7 -0
- package/loaders/yotpo-review-aggregate-loader.d.ts +12 -0
- package/loaders/yotpo-review-aggregate-loader.js +50 -0
- package/loaders/yotpo-review-aggregate-loader.js.map +7 -0
- package/loaders/yotpo-reviews-loader.d.ts +14 -0
- package/loaders/yotpo-reviews-loader.js +65 -0
- package/loaders/yotpo-reviews-loader.js.map +7 -0
- package/money.d.ts +9 -0
- package/money.js +13 -0
- package/money.js.map +7 -0
- package/next/config.d.ts +4 -0
- package/next/config.js +91 -0
- package/next/config.js.map +7 -0
- package/next/image-loader.d.ts +2 -0
- package/next/image-loader.js +52 -0
- package/next/image-loader.js.map +7 -0
- package/next/open-next.d.ts +2 -0
- package/next/open-next.js +24 -0
- package/next/open-next.js.map +7 -0
- package/orders/order-status-schema.d.ts +161 -0
- package/orders/order-status-schema.js +83 -0
- package/orders/order-status-schema.js.map +7 -0
- package/orders/order-status.d.ts +11 -0
- package/orders/order-status.js +41 -0
- package/orders/order-status.js.map +7 -0
- package/package.json +216 -0
- package/providers/query-provider.d.ts +1 -0
- package/providers/query-provider.js +12 -0
- package/providers/query-provider.js.map +7 -0
- package/providers/replo-provider.d.ts +1 -0
- package/providers/replo-provider.js +22 -0
- package/providers/replo-provider.js.map +7 -0
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
const PROVIDER_SNIPPETS = {
|
|
2
|
+
GA4: {
|
|
3
|
+
defaultConsent: ["analytics"],
|
|
4
|
+
buildTags: (id) => [
|
|
5
|
+
{
|
|
6
|
+
kind: "external",
|
|
7
|
+
src: `https://www.googletagmanager.com/gtag/js?id=${id}`
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
kind: "inline",
|
|
11
|
+
body: `window.dataLayer = window.dataLayer || [];
|
|
12
|
+
function gtag(){dataLayer.push(arguments);}
|
|
13
|
+
gtag('js', new Date());
|
|
14
|
+
gtag('config', '${id}');`
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
},
|
|
18
|
+
GoogleTagManager: {
|
|
19
|
+
defaultConsent: ["analytics", "marketing"],
|
|
20
|
+
buildTags: (id) => [
|
|
21
|
+
{
|
|
22
|
+
kind: "inline",
|
|
23
|
+
body: `(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);})(window,document,'script','dataLayer','${id}');`
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
},
|
|
27
|
+
Meta: {
|
|
28
|
+
defaultConsent: ["marketing"],
|
|
29
|
+
buildTags: (id) => [
|
|
30
|
+
{
|
|
31
|
+
kind: "inline",
|
|
32
|
+
body: `!function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod?n.callMethod.apply(n,arguments):n.queue.push(arguments)};if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0;t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}(window,document,'script','https://connect.facebook.net/en_US/fbevents.js');fbq('init','${id}');fbq('track','PageView');`
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
},
|
|
36
|
+
TikTok: {
|
|
37
|
+
defaultConsent: ["marketing"],
|
|
38
|
+
buildTags: (id) => [
|
|
39
|
+
{
|
|
40
|
+
kind: "inline",
|
|
41
|
+
body: `!function(w,d,t){w.TiktokAnalyticsObject=t;var ttq=w[t]=w[t]||[];ttq.methods=["page","track","identify","instances","debug","on","off","once","ready","alias","group","enableCookie","disableCookie","holdConsent","revokeConsent","grantConsent"],ttq.setAndDefer=function(t,e){t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}};for(var i=0;i<ttq.methods.length;i++)ttq.setAndDefer(ttq,ttq.methods[i]);ttq.instance=function(t){for(var e=ttq._i[t]||[],n=0;n<ttq.methods.length;n++)ttq.setAndDefer(e,ttq.methods[n]);return e};ttq.load=function(e,n){var r="https://analytics.tiktok.com/i18n/pixel/events.js",o=n&&n.partner;ttq._i=ttq._i||{},ttq._i[e]=[],ttq._i[e]._u=r,ttq._t=ttq._t||{},ttq._t[e]=+new Date,ttq._o=ttq._o||{},ttq._o[e]=n||{};var a=document.createElement("script");a.type="text/javascript",a.async=!0,a.src=r+"?sdkid="+e+"&lib="+t;var s=document.getElementsByTagName("script")[0];s.parentNode.insertBefore(a,s)};ttq.load('${id}');ttq.page();}(window,document,'ttq');`
|
|
42
|
+
}
|
|
43
|
+
]
|
|
44
|
+
},
|
|
45
|
+
Pinterest: {
|
|
46
|
+
defaultConsent: ["marketing"],
|
|
47
|
+
buildTags: (id) => [
|
|
48
|
+
{
|
|
49
|
+
kind: "inline",
|
|
50
|
+
body: `!function(e){if(!window.pintrk){window.pintrk=function(){window.pintrk.queue.push(Array.prototype.slice.call(arguments))};var n=window.pintrk;n.queue=[],n.version="3.0";var t=document.createElement("script");t.async=!0,t.src=e;var r=document.getElementsByTagName("script")[0];r.parentNode.insertBefore(t,r)}}("https://s.pinimg.com/ct/core.js");pintrk('load','${id}');pintrk('page');`
|
|
51
|
+
}
|
|
52
|
+
]
|
|
53
|
+
},
|
|
54
|
+
Reddit: {
|
|
55
|
+
defaultConsent: ["marketing"],
|
|
56
|
+
buildTags: (id) => [
|
|
57
|
+
{
|
|
58
|
+
kind: "inline",
|
|
59
|
+
body: `!function(w,d){if(!w.rdt){var p=w.rdt=function(){p.sendEvent?p.sendEvent.apply(p,arguments):p.callQueue.push(arguments)};p.callQueue=[];var t=d.createElement("script");t.src="https://www.redditstatic.com/ads/pixel.js",t.async=!0;var s=d.getElementsByTagName("script")[0];s.parentNode.insertBefore(t,s)}}(window,document);rdt('init','${id}');rdt('track','PageVisit');`
|
|
60
|
+
}
|
|
61
|
+
]
|
|
62
|
+
},
|
|
63
|
+
Snapchat: {
|
|
64
|
+
defaultConsent: ["marketing"],
|
|
65
|
+
buildTags: (id) => [
|
|
66
|
+
{
|
|
67
|
+
kind: "inline",
|
|
68
|
+
body: `(function(e,t,n){if(e.snaptr)return;var a=e.snaptr=function(){a.handleRequest?a.handleRequest.apply(a,arguments):a.queue.push(arguments)};a.queue=[];var s='script';var r=t.createElement(s);r.async=!0;r.src=n;var u=t.getElementsByTagName(s)[0];u.parentNode.insertBefore(r,u);})(window,document,'https://sc-static.net/scevent.min.js');snaptr('init','${id}',{});snaptr('track','PAGE_VIEW');`
|
|
69
|
+
}
|
|
70
|
+
]
|
|
71
|
+
},
|
|
72
|
+
Hotjar: {
|
|
73
|
+
defaultConsent: ["analytics"],
|
|
74
|
+
buildTags: (id) => [
|
|
75
|
+
{
|
|
76
|
+
kind: "inline",
|
|
77
|
+
body: `(function(h,o,t,j,a,r){h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)};h._hjSettings={hjid:${id},hjsv:6};a=o.getElementsByTagName('head')[0];r=o.createElement('script');r.async=1;r.src=t+h._hjSettings.hjid+j+h._hjSettings.hjsv;a.appendChild(r);})(window,document,'https://static.hotjar.com/c/hotjar-','.js?sv=');`
|
|
78
|
+
}
|
|
79
|
+
]
|
|
80
|
+
},
|
|
81
|
+
MicrosoftClarity: {
|
|
82
|
+
defaultConsent: ["analytics"],
|
|
83
|
+
buildTags: (id) => [
|
|
84
|
+
{
|
|
85
|
+
kind: "inline",
|
|
86
|
+
body: `(function(c,l,a,r,i,t,y){c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)};t=l.createElement(r);t.async=1;t.src="https://www.clarity.ms/tag/"+i;y=l.getElementsByTagName(r)[0];y.parentNode.insertBefore(t,y);})(window,document,"clarity","script","${id}");`
|
|
87
|
+
}
|
|
88
|
+
]
|
|
89
|
+
},
|
|
90
|
+
Segment: {
|
|
91
|
+
defaultConsent: ["analytics", "marketing"],
|
|
92
|
+
buildTags: (id) => [
|
|
93
|
+
{
|
|
94
|
+
kind: "inline",
|
|
95
|
+
body: `!function(){var i="analytics",analytics=window[i]=window[i]||[];if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error("Segment snippet included twice.");else{analytics.invoked=!0;analytics.methods=["trackSubmit","trackClick","trackLink","trackForm","pageview","identify","reset","group","track","ready","alias","debug","page","screen","once","off","on","addSourceMiddleware","addIntegrationMiddleware","setAnonymousId","addDestinationMiddleware","register"];analytics.factory=function(e){return function(){var t=Array.prototype.slice.call(arguments);t.unshift(e);analytics.push(t);return analytics}};for(var e=0;e<analytics.methods.length;e++){var key=analytics.methods[e];analytics[key]=analytics.factory(key)}analytics.load=function(key,e){var t=document.createElement("script");t.type="text/javascript";t.async=!0;t.src="https://cdn.segment.com/analytics.js/v1/"+key+"/analytics.min.js";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(t,n);analytics._loadOptions=e};analytics._writeKey="${id}";analytics.SNIPPET_VERSION="5.2.0";analytics.load("${id}");analytics.page();}}();`
|
|
96
|
+
}
|
|
97
|
+
]
|
|
98
|
+
},
|
|
99
|
+
Northbeam: {
|
|
100
|
+
defaultConsent: ["analytics", "marketing"],
|
|
101
|
+
buildTags: (id) => [
|
|
102
|
+
{
|
|
103
|
+
kind: "inline",
|
|
104
|
+
body: `(function(){var t;(n=t=t||{}).A="identify",n.B="trackPageView",n.C="fireEmailCaptureEvent",n.D="fireCustomGoal",n.E="firePurchaseEvent",n.F="trackPageViewInitial",n.G="fireSlimPurchaseEvent",n.H="identifyCustomerId";var n="https://j.northbeam.io/ota-sp/${id}.js";function r(n){for(var e=[],t=1;t<arguments.length;t++)e[t-1]=arguments[t];i.push({fnName:n,args:e})}var e,i=[],a=((e={})[t.F]=function(n){r(t.F,n)},(a={_q:i})[t.A]=function(n,e){return r(t.A,n,e)},a[t.B]=function(){return r(t.B)},a[t.C]=function(n,e){return r(t.C,n,e)},a[t.D]=function(n,e){return r(t.D,n,e)},a[t.E]=function(n){return r(t.E,n)},a[t.G]=function(n){return r(t.G,n)},a[t.H]=function(n,e){return r(t.H,n,e)},Object.assign(function(n){for(var e=[],t=1;t<arguments.length;t++)e.push(arguments[t]);return r.apply(null,[n].concat(e))},a));window.Northbeam=a,(a=document.createElement("script")).async=!0,a.src=n,document.head.appendChild(a),e.trackPageViewInitial(window.location.href);})()`
|
|
105
|
+
}
|
|
106
|
+
]
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
function buildScriptTags({
|
|
110
|
+
type,
|
|
111
|
+
identifier
|
|
112
|
+
}) {
|
|
113
|
+
return PROVIDER_SNIPPETS[type].buildTags(identifier);
|
|
114
|
+
}
|
|
115
|
+
function defaultConsentFor(type) {
|
|
116
|
+
return PROVIDER_SNIPPETS[type].defaultConsent;
|
|
117
|
+
}
|
|
118
|
+
export {
|
|
119
|
+
buildScriptTags,
|
|
120
|
+
defaultConsentFor
|
|
121
|
+
};
|
|
122
|
+
//# sourceMappingURL=script-snippets.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../consent/script-snippets.ts"],
|
|
4
|
+
"sourcesContent": ["import type {\n ConsentCategory,\n ReploScriptType,\n ScriptTagDescriptor,\n} from \"schemas/generated/consent\";\n\n// Identifier providers: those whose script the runtime synthesizes from an ID.\n// `snippet` (pasted whole) and `custom` carry their own bodies instead.\ntype ProviderType = Exclude<ReploScriptType, \"custom\" | \"snippet\">;\n\n/**\n * Runtime-safe per-provider data for the consent system. This is the subset of\n * the website-builder miniapp's `scriptConstants.ts` that must ship in the\n * customer site bundle: how to materialize each provider's script tags, and the\n * default consent category that gates it. Miniapp-only concerns (LLM detection\n * schemas, logos, marketing copy) intentionally stay in the miniapp.\n *\n * Unlike the miniapp's `buildSnippet`, which returns a JSX *string* for the\n * agent to paste into `layout.tsx`, this returns structured descriptors so the\n * runtime can inject real DOM nodes (inline `<script>` bodies set via React's\n * `dangerouslySetInnerHTML` never execute).\n */\ntype ProviderSnippet = {\n defaultConsent: ConsentCategory[];\n buildTags: (identifier: string) => ScriptTagDescriptor[];\n};\n\n/**\n * NOTE (Ryan, 2026-05-28, REPL-27515): `defaultConsent` is net-new,\n * legally-sensitive categorization that does not exist elsewhere in the repo.\n * These are conservative defaults a customer can override per entry via\n * `requiredConsent`; container/CDP providers that fan out to multiple vendors\n * (GTM, Segment) require the union of categories they can serve.\n */\nconst PROVIDER_SNIPPETS: Record<ProviderType, ProviderSnippet> = {\n GA4: {\n defaultConsent: [\"analytics\"],\n buildTags: (id) => [\n {\n kind: \"external\",\n src: `https://www.googletagmanager.com/gtag/js?id=${id}`,\n },\n {\n kind: \"inline\",\n body: `window.dataLayer = window.dataLayer || [];\\nfunction gtag(){dataLayer.push(arguments);}\\ngtag('js', new Date());\\ngtag('config', '${id}');`,\n },\n ],\n },\n GoogleTagManager: {\n defaultConsent: [\"analytics\", \"marketing\"],\n buildTags: (id) => [\n {\n kind: \"inline\",\n body: `(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);})(window,document,'script','dataLayer','${id}');`,\n },\n ],\n },\n Meta: {\n defaultConsent: [\"marketing\"],\n buildTags: (id) => [\n {\n kind: \"inline\",\n body: `!function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod?n.callMethod.apply(n,arguments):n.queue.push(arguments)};if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0;t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}(window,document,'script','https://connect.facebook.net/en_US/fbevents.js');fbq('init','${id}');fbq('track','PageView');`,\n },\n ],\n },\n TikTok: {\n defaultConsent: [\"marketing\"],\n buildTags: (id) => [\n {\n kind: \"inline\",\n body: `!function(w,d,t){w.TiktokAnalyticsObject=t;var ttq=w[t]=w[t]||[];ttq.methods=[\"page\",\"track\",\"identify\",\"instances\",\"debug\",\"on\",\"off\",\"once\",\"ready\",\"alias\",\"group\",\"enableCookie\",\"disableCookie\",\"holdConsent\",\"revokeConsent\",\"grantConsent\"],ttq.setAndDefer=function(t,e){t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}};for(var i=0;i<ttq.methods.length;i++)ttq.setAndDefer(ttq,ttq.methods[i]);ttq.instance=function(t){for(var e=ttq._i[t]||[],n=0;n<ttq.methods.length;n++)ttq.setAndDefer(e,ttq.methods[n]);return e};ttq.load=function(e,n){var r=\"https://analytics.tiktok.com/i18n/pixel/events.js\",o=n&&n.partner;ttq._i=ttq._i||{},ttq._i[e]=[],ttq._i[e]._u=r,ttq._t=ttq._t||{},ttq._t[e]=+new Date,ttq._o=ttq._o||{},ttq._o[e]=n||{};var a=document.createElement(\"script\");a.type=\"text/javascript\",a.async=!0,a.src=r+\"?sdkid=\"+e+\"&lib=\"+t;var s=document.getElementsByTagName(\"script\")[0];s.parentNode.insertBefore(a,s)};ttq.load('${id}');ttq.page();}(window,document,'ttq');`,\n },\n ],\n },\n Pinterest: {\n defaultConsent: [\"marketing\"],\n buildTags: (id) => [\n {\n kind: \"inline\",\n body: `!function(e){if(!window.pintrk){window.pintrk=function(){window.pintrk.queue.push(Array.prototype.slice.call(arguments))};var n=window.pintrk;n.queue=[],n.version=\"3.0\";var t=document.createElement(\"script\");t.async=!0,t.src=e;var r=document.getElementsByTagName(\"script\")[0];r.parentNode.insertBefore(t,r)}}(\"https://s.pinimg.com/ct/core.js\");pintrk('load','${id}');pintrk('page');`,\n },\n ],\n },\n Reddit: {\n defaultConsent: [\"marketing\"],\n buildTags: (id) => [\n {\n kind: \"inline\",\n body: `!function(w,d){if(!w.rdt){var p=w.rdt=function(){p.sendEvent?p.sendEvent.apply(p,arguments):p.callQueue.push(arguments)};p.callQueue=[];var t=d.createElement(\"script\");t.src=\"https://www.redditstatic.com/ads/pixel.js\",t.async=!0;var s=d.getElementsByTagName(\"script\")[0];s.parentNode.insertBefore(t,s)}}(window,document);rdt('init','${id}');rdt('track','PageVisit');`,\n },\n ],\n },\n Snapchat: {\n defaultConsent: [\"marketing\"],\n buildTags: (id) => [\n {\n kind: \"inline\",\n body: `(function(e,t,n){if(e.snaptr)return;var a=e.snaptr=function(){a.handleRequest?a.handleRequest.apply(a,arguments):a.queue.push(arguments)};a.queue=[];var s='script';var r=t.createElement(s);r.async=!0;r.src=n;var u=t.getElementsByTagName(s)[0];u.parentNode.insertBefore(r,u);})(window,document,'https://sc-static.net/scevent.min.js');snaptr('init','${id}',{});snaptr('track','PAGE_VIEW');`,\n },\n ],\n },\n Hotjar: {\n defaultConsent: [\"analytics\"],\n buildTags: (id) => [\n {\n kind: \"inline\",\n body: `(function(h,o,t,j,a,r){h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)};h._hjSettings={hjid:${id},hjsv:6};a=o.getElementsByTagName('head')[0];r=o.createElement('script');r.async=1;r.src=t+h._hjSettings.hjid+j+h._hjSettings.hjsv;a.appendChild(r);})(window,document,'https://static.hotjar.com/c/hotjar-','.js?sv=');`,\n },\n ],\n },\n MicrosoftClarity: {\n defaultConsent: [\"analytics\"],\n buildTags: (id) => [\n {\n kind: \"inline\",\n body: `(function(c,l,a,r,i,t,y){c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)};t=l.createElement(r);t.async=1;t.src=\"https://www.clarity.ms/tag/\"+i;y=l.getElementsByTagName(r)[0];y.parentNode.insertBefore(t,y);})(window,document,\"clarity\",\"script\",\"${id}\");`,\n },\n ],\n },\n Segment: {\n defaultConsent: [\"analytics\", \"marketing\"],\n buildTags: (id) => [\n {\n kind: \"inline\",\n body: `!function(){var i=\"analytics\",analytics=window[i]=window[i]||[];if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error(\"Segment snippet included twice.\");else{analytics.invoked=!0;analytics.methods=[\"trackSubmit\",\"trackClick\",\"trackLink\",\"trackForm\",\"pageview\",\"identify\",\"reset\",\"group\",\"track\",\"ready\",\"alias\",\"debug\",\"page\",\"screen\",\"once\",\"off\",\"on\",\"addSourceMiddleware\",\"addIntegrationMiddleware\",\"setAnonymousId\",\"addDestinationMiddleware\",\"register\"];analytics.factory=function(e){return function(){var t=Array.prototype.slice.call(arguments);t.unshift(e);analytics.push(t);return analytics}};for(var e=0;e<analytics.methods.length;e++){var key=analytics.methods[e];analytics[key]=analytics.factory(key)}analytics.load=function(key,e){var t=document.createElement(\"script\");t.type=\"text/javascript\";t.async=!0;t.src=\"https://cdn.segment.com/analytics.js/v1/\"+key+\"/analytics.min.js\";var n=document.getElementsByTagName(\"script\")[0];n.parentNode.insertBefore(t,n);analytics._loadOptions=e};analytics._writeKey=\"${id}\";analytics.SNIPPET_VERSION=\"5.2.0\";analytics.load(\"${id}\");analytics.page();}}();`,\n },\n ],\n },\n Northbeam: {\n defaultConsent: [\"analytics\", \"marketing\"],\n buildTags: (id) => [\n {\n kind: \"inline\",\n body: `(function(){var t;(n=t=t||{}).A=\"identify\",n.B=\"trackPageView\",n.C=\"fireEmailCaptureEvent\",n.D=\"fireCustomGoal\",n.E=\"firePurchaseEvent\",n.F=\"trackPageViewInitial\",n.G=\"fireSlimPurchaseEvent\",n.H=\"identifyCustomerId\";var n=\"https://j.northbeam.io/ota-sp/${id}.js\";function r(n){for(var e=[],t=1;t<arguments.length;t++)e[t-1]=arguments[t];i.push({fnName:n,args:e})}var e,i=[],a=((e={})[t.F]=function(n){r(t.F,n)},(a={_q:i})[t.A]=function(n,e){return r(t.A,n,e)},a[t.B]=function(){return r(t.B)},a[t.C]=function(n,e){return r(t.C,n,e)},a[t.D]=function(n,e){return r(t.D,n,e)},a[t.E]=function(n){return r(t.E,n)},a[t.G]=function(n){return r(t.G,n)},a[t.H]=function(n,e){return r(t.H,n,e)},Object.assign(function(n){for(var e=[],t=1;t<arguments.length;t++)e.push(arguments[t]);return r.apply(null,[n].concat(e))},a));window.Northbeam=a,(a=document.createElement(\"script\")).async=!0,a.src=n,document.head.appendChild(a),e.trackPageViewInitial(window.location.href);})()`,\n },\n ],\n },\n};\n\n/**\n * Snippet providers don't synthesize tags (the user pastes the provider-issued\n * snippet as the entry's `body`), but they still get a first-class default\n * consent categorization like identifier providers.\n */\n/**\n * Returns the structured tag descriptors for a named provider. A single provider\n * can produce multiple tags (e.g. GA4 = external loader + inline config), which\n * the runtime injects in order.\n */\nexport function buildScriptTags({\n type,\n identifier,\n}: {\n type: ProviderType;\n identifier: string;\n}): ScriptTagDescriptor[] {\n return PROVIDER_SNIPPETS[type].buildTags(identifier);\n}\n\n/**\n * The default consent categories that gate an identifier-provider script when an\n * entry does not specify `requiredConsent`. `snippet` and `custom` entries carry\n * `requiredConsent` explicitly (the runtime has no default for them), so this is\n * only consulted for identifier providers. Overridable per entry by the customer.\n */\nexport function defaultConsentFor(type: ProviderType): ConsentCategory[] {\n return PROVIDER_SNIPPETS[type].defaultConsent;\n}\n"],
|
|
5
|
+
"mappings": "AAkCA,MAAM,oBAA2D;AAAA,EAC/D,KAAK;AAAA,IACH,gBAAgB,CAAC,WAAW;AAAA,IAC5B,WAAW,CAAC,OAAO;AAAA,MACjB;AAAA,QACE,MAAM;AAAA,QACN,KAAK,+CAA+C,EAAE;AAAA,MACxD;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA;AAAA;AAAA,kBAAqI,EAAE;AAAA,MAC/I;AAAA,IACF;AAAA,EACF;AAAA,EACA,kBAAkB;AAAA,IAChB,gBAAgB,CAAC,aAAa,WAAW;AAAA,IACzC,WAAW,CAAC,OAAO;AAAA,MACjB;AAAA,QACE,MAAM;AAAA,QACN,MAAM,sUAAsU,EAAE;AAAA,MAChV;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM;AAAA,IACJ,gBAAgB,CAAC,WAAW;AAAA,IAC5B,WAAW,CAAC,OAAO;AAAA,MACjB;AAAA,QACE,MAAM;AAAA,QACN,MAAM,uYAAuY,EAAE;AAAA,MACjZ;AAAA,IACF;AAAA,EACF;AAAA,EACA,QAAQ;AAAA,IACN,gBAAgB,CAAC,WAAW;AAAA,IAC5B,WAAW,CAAC,OAAO;AAAA,MACjB;AAAA,QACE,MAAM;AAAA,QACN,MAAM,+7BAA+7B,EAAE;AAAA,MACz8B;AAAA,IACF;AAAA,EACF;AAAA,EACA,WAAW;AAAA,IACT,gBAAgB,CAAC,WAAW;AAAA,IAC5B,WAAW,CAAC,OAAO;AAAA,MACjB;AAAA,QACE,MAAM;AAAA,QACN,MAAM,0WAA0W,EAAE;AAAA,MACpX;AAAA,IACF;AAAA,EACF;AAAA,EACA,QAAQ;AAAA,IACN,gBAAgB,CAAC,WAAW;AAAA,IAC5B,WAAW,CAAC,OAAO;AAAA,MACjB;AAAA,QACE,MAAM;AAAA,QACN,MAAM,gVAAgV,EAAE;AAAA,MAC1V;AAAA,IACF;AAAA,EACF;AAAA,EACA,UAAU;AAAA,IACR,gBAAgB,CAAC,WAAW;AAAA,IAC5B,WAAW,CAAC,OAAO;AAAA,MACjB;AAAA,QACE,MAAM;AAAA,QACN,MAAM,+VAA+V,EAAE;AAAA,MACzW;AAAA,IACF;AAAA,EACF;AAAA,EACA,QAAQ;AAAA,IACN,gBAAgB,CAAC,WAAW;AAAA,IAC5B,WAAW,CAAC,OAAO;AAAA,MACjB;AAAA,QACE,MAAM;AAAA,QACN,MAAM,yGAAyG,EAAE;AAAA,MACnH;AAAA,IACF;AAAA,EACF;AAAA,EACA,kBAAkB;AAAA,IAChB,gBAAgB,CAAC,WAAW;AAAA,IAC5B,WAAW,CAAC,OAAO;AAAA,MACjB;AAAA,QACE,MAAM;AAAA,QACN,MAAM,iQAAiQ,EAAE;AAAA,MAC3Q;AAAA,IACF;AAAA,EACF;AAAA,EACA,SAAS;AAAA,IACP,gBAAgB,CAAC,aAAa,WAAW;AAAA,IACzC,WAAW,CAAC,OAAO;AAAA,MACjB;AAAA,QACE,MAAM;AAAA,QACN,MAAM,iiCAAiiC,EAAE,uDAAuD,EAAE;AAAA,MACpmC;AAAA,IACF;AAAA,EACF;AAAA,EACA,WAAW;AAAA,IACT,gBAAgB,CAAC,aAAa,WAAW;AAAA,IACzC,WAAW,CAAC,OAAO;AAAA,MACjB;AAAA,QACE,MAAM;AAAA,QACN,MAAM,gQAAgQ,EAAE;AAAA,MAC1Q;AAAA,IACF;AAAA,EACF;AACF;AAYO,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AACF,GAG0B;AACxB,SAAO,kBAAkB,IAAI,EAAE,UAAU,UAAU;AACrD;AAQO,SAAS,kBAAkB,MAAuC;AACvE,SAAO,kBAAkB,IAAI,EAAE;AACjC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export type ReploScriptType = "GA4" | "GoogleTagManager" | "Meta" | "TikTok" | "Pinterest" | "Reddit" | "Snapchat" | "Hotjar" | "MicrosoftClarity" | "Segment" | "Northbeam" | "snippet" | "custom";
|
|
2
|
+
export type ConsentCategory = "necessary" | "analytics" | "marketing" | "preferences" | "sale_of_data";
|
|
3
|
+
export type ConsentMode = "off" | "simple" | "per-category";
|
|
4
|
+
declare module "react" {
|
|
5
|
+
interface HtmlHTMLAttributes<T> {
|
|
6
|
+
"data-replo-consent-mode"?: ConsentMode;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
export type ScriptTagDescriptor = {
|
|
10
|
+
kind: "external";
|
|
11
|
+
src: string;
|
|
12
|
+
attributes?: {
|
|
13
|
+
[x: string]: string;
|
|
14
|
+
};
|
|
15
|
+
} | {
|
|
16
|
+
kind: "inline";
|
|
17
|
+
body: string;
|
|
18
|
+
};
|
|
19
|
+
export type ReploScriptEntry = {
|
|
20
|
+
type: "GA4" | "GoogleTagManager" | "Meta" | "TikTok" | "Pinterest" | "Reddit" | "Snapchat" | "Hotjar" | "MicrosoftClarity" | "Segment" | "Northbeam";
|
|
21
|
+
identifier: string;
|
|
22
|
+
requiredConsent?: ConsentCategory[];
|
|
23
|
+
} | {
|
|
24
|
+
type: "snippet";
|
|
25
|
+
id: string;
|
|
26
|
+
body: string;
|
|
27
|
+
requiredConsent: ConsentCategory[];
|
|
28
|
+
} | {
|
|
29
|
+
type: "custom";
|
|
30
|
+
id: string;
|
|
31
|
+
requiredConsent: ConsentCategory[];
|
|
32
|
+
src?: string;
|
|
33
|
+
body?: string;
|
|
34
|
+
};
|
package/consent/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { ConsentCategory } from "../_vendor/schemas/generated/consent";
|
|
2
|
+
/**
|
|
3
|
+
* Global, framework-agnostic consent API exposed on `window.Replo.customerPrivacy`,
|
|
4
|
+
* mirroring Shopify's Customer Privacy API surface so on-page (third-party)
|
|
5
|
+
* scripts can query consent and react to changes without importing canopy.
|
|
6
|
+
*
|
|
7
|
+
* It deliberately lives under our own `window.Replo` namespace rather than
|
|
8
|
+
* `window.Shopify` to avoid colliding with Shopify's real API on Shopify-backed
|
|
9
|
+
* sites.
|
|
10
|
+
*/
|
|
11
|
+
type ToggleableCategory = Exclude<ConsentCategory, "necessary">;
|
|
12
|
+
/** Shopify-style tri-state: declared-allowed, declared-denied, or undeclared. */
|
|
13
|
+
type ConsentSignal = "yes" | "no" | "";
|
|
14
|
+
export interface ReploCustomerPrivacyApi {
|
|
15
|
+
/** Per-category declaration, or "" when the visitor has not decided. */
|
|
16
|
+
currentVisitorConsent(): Record<ToggleableCategory, ConsentSignal>;
|
|
17
|
+
analyticsProcessingAllowed(): boolean;
|
|
18
|
+
marketingAllowed(): boolean;
|
|
19
|
+
preferencesProcessingAllowed(): boolean;
|
|
20
|
+
saleOfDataAllowed(): boolean;
|
|
21
|
+
/** Whether the consent banner should still be shown (mode on + undecided). */
|
|
22
|
+
shouldShowBanner(): boolean;
|
|
23
|
+
/** Update a subset of categories; runs the optional callback once persisted. */
|
|
24
|
+
setTrackingConsent(consent: Partial<Record<ToggleableCategory, boolean>>, callback?: () => void): void;
|
|
25
|
+
}
|
|
26
|
+
declare global {
|
|
27
|
+
interface Window {
|
|
28
|
+
Replo?: {
|
|
29
|
+
customerPrivacy?: ReploCustomerPrivacyApi;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/** DOM event dispatched on `document` whenever consent changes. */
|
|
34
|
+
export declare const CONSENT_CHANGE_EVENT = "visitorConsentCollected";
|
|
35
|
+
/**
|
|
36
|
+
* Installs `window.Replo.customerPrivacy` and dispatches `visitorConsentCollected`
|
|
37
|
+
* on `document` whenever consent changes. Idempotent; returns a teardown that
|
|
38
|
+
* removes the change subscription. Safe to call on the server (no-op).
|
|
39
|
+
*/
|
|
40
|
+
export declare function installConsentWindowApi(): () => void;
|
|
41
|
+
export {};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { consentStore, isConsentAllowed } from "./consent-store";
|
|
3
|
+
const CONSENT_CHANGE_EVENT = "visitorConsentCollected";
|
|
4
|
+
function isAllowed(category) {
|
|
5
|
+
return isConsentAllowed({
|
|
6
|
+
state: consentStore.getSnapshot(),
|
|
7
|
+
requiredConsent: [category]
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
function currentVisitorConsent() {
|
|
11
|
+
const state = consentStore.getSnapshot();
|
|
12
|
+
const signal = (category) => {
|
|
13
|
+
if (state.decidedAt === null) {
|
|
14
|
+
return "";
|
|
15
|
+
}
|
|
16
|
+
return state.categories[category] ? "yes" : "no";
|
|
17
|
+
};
|
|
18
|
+
return {
|
|
19
|
+
analytics: signal("analytics"),
|
|
20
|
+
marketing: signal("marketing"),
|
|
21
|
+
preferences: signal("preferences"),
|
|
22
|
+
sale_of_data: signal("sale_of_data")
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
const api = {
|
|
26
|
+
currentVisitorConsent,
|
|
27
|
+
analyticsProcessingAllowed: () => isAllowed("analytics"),
|
|
28
|
+
marketingAllowed: () => isAllowed("marketing"),
|
|
29
|
+
preferencesProcessingAllowed: () => isAllowed("preferences"),
|
|
30
|
+
saleOfDataAllowed: () => isAllowed("sale_of_data"),
|
|
31
|
+
shouldShowBanner: () => {
|
|
32
|
+
const state = consentStore.getSnapshot();
|
|
33
|
+
return state.mode !== "off" && state.decidedAt === null;
|
|
34
|
+
},
|
|
35
|
+
setTrackingConsent: (consent, callback) => {
|
|
36
|
+
consentStore.updateCategories({ next: consent });
|
|
37
|
+
callback?.();
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
function consentChangeDetail() {
|
|
41
|
+
return {
|
|
42
|
+
analyticsAllowed: isAllowed("analytics"),
|
|
43
|
+
marketingAllowed: isAllowed("marketing"),
|
|
44
|
+
preferencesAllowed: isAllowed("preferences"),
|
|
45
|
+
saleOfDataAllowed: isAllowed("sale_of_data")
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
let teardown = null;
|
|
49
|
+
function installConsentWindowApi() {
|
|
50
|
+
if (typeof window === "undefined") {
|
|
51
|
+
return () => {
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
if (teardown) {
|
|
55
|
+
return teardown;
|
|
56
|
+
}
|
|
57
|
+
window.Replo = { ...window.Replo, customerPrivacy: api };
|
|
58
|
+
const unsubscribe = consentStore.subscribe(() => {
|
|
59
|
+
document.dispatchEvent(
|
|
60
|
+
new CustomEvent(CONSENT_CHANGE_EVENT, { detail: consentChangeDetail() })
|
|
61
|
+
);
|
|
62
|
+
});
|
|
63
|
+
teardown = () => {
|
|
64
|
+
unsubscribe();
|
|
65
|
+
teardown = null;
|
|
66
|
+
};
|
|
67
|
+
return teardown;
|
|
68
|
+
}
|
|
69
|
+
export {
|
|
70
|
+
CONSENT_CHANGE_EVENT,
|
|
71
|
+
installConsentWindowApi
|
|
72
|
+
};
|
|
73
|
+
//# sourceMappingURL=window-api.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../consent/window-api.ts"],
|
|
4
|
+
"sourcesContent": ["\"use client\";\n\nimport type { ConsentCategory } from \"schemas/generated/consent\";\n\nimport { consentStore, isConsentAllowed } from \"./consent-store\";\n\n/**\n * Global, framework-agnostic consent API exposed on `window.Replo.customerPrivacy`,\n * mirroring Shopify's Customer Privacy API surface so on-page (third-party)\n * scripts can query consent and react to changes without importing canopy.\n *\n * It deliberately lives under our own `window.Replo` namespace rather than\n * `window.Shopify` to avoid colliding with Shopify's real API on Shopify-backed\n * sites.\n */\n\ntype ToggleableCategory = Exclude<ConsentCategory, \"necessary\">;\n\n/** Shopify-style tri-state: declared-allowed, declared-denied, or undeclared. */\ntype ConsentSignal = \"yes\" | \"no\" | \"\";\n\nexport interface ReploCustomerPrivacyApi {\n /** Per-category declaration, or \"\" when the visitor has not decided. */\n currentVisitorConsent(): Record<ToggleableCategory, ConsentSignal>;\n analyticsProcessingAllowed(): boolean;\n marketingAllowed(): boolean;\n preferencesProcessingAllowed(): boolean;\n saleOfDataAllowed(): boolean;\n /** Whether the consent banner should still be shown (mode on + undecided). */\n shouldShowBanner(): boolean;\n /** Update a subset of categories; runs the optional callback once persisted. */\n setTrackingConsent(\n consent: Partial<Record<ToggleableCategory, boolean>>,\n callback?: () => void,\n ): void;\n}\n\ndeclare global {\n interface Window {\n Replo?: { customerPrivacy?: ReploCustomerPrivacyApi };\n }\n}\n\n/** DOM event dispatched on `document` whenever consent changes. */\nexport const CONSENT_CHANGE_EVENT = \"visitorConsentCollected\";\n\nfunction isAllowed(category: ConsentCategory): boolean {\n return isConsentAllowed({\n state: consentStore.getSnapshot(),\n requiredConsent: [category],\n });\n}\n\nfunction currentVisitorConsent(): Record<ToggleableCategory, ConsentSignal> {\n const state = consentStore.getSnapshot();\n const signal = (category: ToggleableCategory): ConsentSignal => {\n if (state.decidedAt === null) {\n return \"\";\n }\n return state.categories[category] ? \"yes\" : \"no\";\n };\n return {\n analytics: signal(\"analytics\"),\n marketing: signal(\"marketing\"),\n preferences: signal(\"preferences\"),\n sale_of_data: signal(\"sale_of_data\"),\n };\n}\n\nconst api: ReploCustomerPrivacyApi = {\n currentVisitorConsent,\n analyticsProcessingAllowed: () => isAllowed(\"analytics\"),\n marketingAllowed: () => isAllowed(\"marketing\"),\n preferencesProcessingAllowed: () => isAllowed(\"preferences\"),\n saleOfDataAllowed: () => isAllowed(\"sale_of_data\"),\n shouldShowBanner: () => {\n const state = consentStore.getSnapshot();\n return state.mode !== \"off\" && state.decidedAt === null;\n },\n setTrackingConsent: (consent, callback) => {\n consentStore.updateCategories({ next: consent });\n callback?.();\n },\n};\n\nfunction consentChangeDetail() {\n return {\n analyticsAllowed: isAllowed(\"analytics\"),\n marketingAllowed: isAllowed(\"marketing\"),\n preferencesAllowed: isAllowed(\"preferences\"),\n saleOfDataAllowed: isAllowed(\"sale_of_data\"),\n };\n}\n\nlet teardown: (() => void) | null = null;\n\n/**\n * Installs `window.Replo.customerPrivacy` and dispatches `visitorConsentCollected`\n * on `document` whenever consent changes. Idempotent; returns a teardown that\n * removes the change subscription. Safe to call on the server (no-op).\n */\nexport function installConsentWindowApi(): () => void {\n if (typeof window === \"undefined\") {\n return () => {\n // no-op on the server\n };\n }\n if (teardown) {\n return teardown;\n }\n window.Replo = { ...window.Replo, customerPrivacy: api };\n const unsubscribe = consentStore.subscribe(() => {\n document.dispatchEvent(\n new CustomEvent(CONSENT_CHANGE_EVENT, { detail: consentChangeDetail() }),\n );\n });\n teardown = () => {\n unsubscribe();\n teardown = null;\n };\n return teardown;\n}\n"],
|
|
5
|
+
"mappings": ";AAIA,SAAS,cAAc,wBAAwB;AAwCxC,MAAM,uBAAuB;AAEpC,SAAS,UAAU,UAAoC;AACrD,SAAO,iBAAiB;AAAA,IACtB,OAAO,aAAa,YAAY;AAAA,IAChC,iBAAiB,CAAC,QAAQ;AAAA,EAC5B,CAAC;AACH;AAEA,SAAS,wBAAmE;AAC1E,QAAM,QAAQ,aAAa,YAAY;AACvC,QAAM,SAAS,CAAC,aAAgD;AAC9D,QAAI,MAAM,cAAc,MAAM;AAC5B,aAAO;AAAA,IACT;AACA,WAAO,MAAM,WAAW,QAAQ,IAAI,QAAQ;AAAA,EAC9C;AACA,SAAO;AAAA,IACL,WAAW,OAAO,WAAW;AAAA,IAC7B,WAAW,OAAO,WAAW;AAAA,IAC7B,aAAa,OAAO,aAAa;AAAA,IACjC,cAAc,OAAO,cAAc;AAAA,EACrC;AACF;AAEA,MAAM,MAA+B;AAAA,EACnC;AAAA,EACA,4BAA4B,MAAM,UAAU,WAAW;AAAA,EACvD,kBAAkB,MAAM,UAAU,WAAW;AAAA,EAC7C,8BAA8B,MAAM,UAAU,aAAa;AAAA,EAC3D,mBAAmB,MAAM,UAAU,cAAc;AAAA,EACjD,kBAAkB,MAAM;AACtB,UAAM,QAAQ,aAAa,YAAY;AACvC,WAAO,MAAM,SAAS,SAAS,MAAM,cAAc;AAAA,EACrD;AAAA,EACA,oBAAoB,CAAC,SAAS,aAAa;AACzC,iBAAa,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAC/C,eAAW;AAAA,EACb;AACF;AAEA,SAAS,sBAAsB;AAC7B,SAAO;AAAA,IACL,kBAAkB,UAAU,WAAW;AAAA,IACvC,kBAAkB,UAAU,WAAW;AAAA,IACvC,oBAAoB,UAAU,aAAa;AAAA,IAC3C,mBAAmB,UAAU,cAAc;AAAA,EAC7C;AACF;AAEA,IAAI,WAAgC;AAO7B,SAAS,0BAAsC;AACpD,MAAI,OAAO,WAAW,aAAa;AACjC,WAAO,MAAM;AAAA,IAEb;AAAA,EACF;AACA,MAAI,UAAU;AACZ,WAAO;AAAA,EACT;AACA,SAAO,QAAQ,EAAE,GAAG,OAAO,OAAO,iBAAiB,IAAI;AACvD,QAAM,cAAc,aAAa,UAAU,MAAM;AAC/C,aAAS;AAAA,MACP,IAAI,YAAY,sBAAsB,EAAE,QAAQ,oBAAoB,EAAE,CAAC;AAAA,IACzE;AAAA,EACF,CAAC;AACD,aAAW,MAAM;AACf,gBAAY;AACZ,eAAW;AAAA,EACb;AACA,SAAO;AACT;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/env.d.ts
ADDED
package/env.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { getCloudflareContext } from "@opennextjs/cloudflare";
|
|
2
|
+
import JSONC from "tiny-jsonc";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import { CanopyError } from "./lib/canopy-error";
|
|
5
|
+
const envSchema = z.object({
|
|
6
|
+
CANOPY_API_HOST: z.string().min(1),
|
|
7
|
+
PROJECT_ID: z.uuid(),
|
|
8
|
+
ANALYTICS_FIRE_API_URL: z.string().optional(),
|
|
9
|
+
REPLO_ANALYTICS_PIXEL_URL: z.string().optional(),
|
|
10
|
+
CHECKOUT_PROVIDER: z.enum(["shopify", "stripe", "none"]).optional()
|
|
11
|
+
});
|
|
12
|
+
const wranglerConfigSchema = z.object({ vars: envSchema });
|
|
13
|
+
class MissingWranglerConfigError extends CanopyError {
|
|
14
|
+
}
|
|
15
|
+
const isDeployedWorker = () => {
|
|
16
|
+
return process.env.NODE_ENV === "production" && process.env.BUILD_ENV !== "build" && process.env.NEXT_PHASE !== "phase-production-build";
|
|
17
|
+
};
|
|
18
|
+
const getEnv = async () => {
|
|
19
|
+
if (isDeployedWorker()) {
|
|
20
|
+
const { env } = await getCloudflareContext({ async: true });
|
|
21
|
+
return envSchema.parse(env);
|
|
22
|
+
}
|
|
23
|
+
const { promises: fs } = await import(
|
|
24
|
+
/* turbopackIgnore: true */
|
|
25
|
+
/* webpackIgnore: true */
|
|
26
|
+
"node:fs"
|
|
27
|
+
);
|
|
28
|
+
let raw;
|
|
29
|
+
try {
|
|
30
|
+
raw = await fs.readFile(`${process.cwd()}/wrangler.jsonc`, "utf8");
|
|
31
|
+
} catch (error) {
|
|
32
|
+
throw new MissingWranglerConfigError({
|
|
33
|
+
message: `wrangler.jsonc not found in ${process.cwd()}. It holds this site's Replo project config (project id, API host) and is required to run outside the deployed worker. If this clone predates the committed config, open the site in Replo once \u2014 the dev server regenerates and commits it \u2014 then git pull.`,
|
|
34
|
+
cause: error
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
return wranglerConfigSchema.parse(JSONC.parse(raw)).vars;
|
|
38
|
+
};
|
|
39
|
+
export {
|
|
40
|
+
getEnv
|
|
41
|
+
};
|
|
42
|
+
//# sourceMappingURL=env.js.map
|
package/env.js.map
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../env.ts"],
|
|
4
|
+
"sourcesContent": ["import { getCloudflareContext } from \"@opennextjs/cloudflare\";\nimport JSONC from \"tiny-jsonc\";\nimport { z } from \"zod\";\n\nimport { CanopyError } from \"./lib/canopy-error\";\n\ntype Env = {\n CANOPY_API_HOST: string;\n PROJECT_ID: string;\n\n // Base URL of analytics-fire (e.g. https://data.replo.app). Read server-side by\n // the consent action (`consent/consent-actions.ts`) to forward proof-of-consent\n // records. Optional: absent in environments where the audit pipeline isn't\n // wired (e.g. local dev), where consent recording simply no-ops.\n ANALYTICS_FIRE_API_URL?: string;\n\n // Base URL of the Replo first-party analytics pixel CDN (e.g.\n // https://pixel.replo.app). `<ReploFirstPartyPixel>` loads\n // `${REPLO_ANALYTICS_PIXEL_URL}/latest.js` into the page once analytics consent\n // is granted; the browser fetches it directly. Optional: absent when the pixel\n // isn't configured (e.g. lean local dev), where the pixel simply isn't injected.\n REPLO_ANALYTICS_PIXEL_URL?: string;\n\n CHECKOUT_PROVIDER?: \"shopify\" | \"stripe\" | \"none\";\n};\n\nconst envSchema = z.object({\n CANOPY_API_HOST: z.string().min(1),\n PROJECT_ID: z.uuid(),\n ANALYTICS_FIRE_API_URL: z.string().optional(),\n REPLO_ANALYTICS_PIXEL_URL: z.string().optional(),\n CHECKOUT_PROVIDER: z.enum([\"shopify\", \"stripe\", \"none\"]).optional(),\n});\n\nconst wranglerConfigSchema = z.object({ vars: envSchema });\n\nclass MissingWranglerConfigError extends CanopyError {}\n\n// NOTE (Cole, 2026-07-28, REPL-29501): outside the deployed worker, read wrangler.jsonc directly \u2014 concurrent workerd boots race on the shared .wrangler/state SQLite (SQLITE_BUSY).\nconst isDeployedWorker = () => {\n return (\n process.env.NODE_ENV === \"production\" &&\n process.env.BUILD_ENV !== \"build\" &&\n process.env.NEXT_PHASE !== \"phase-production-build\"\n );\n};\n\nexport const getEnv = async (): Promise<Env> => {\n if (isDeployedWorker()) {\n const { env } = await getCloudflareContext({ async: true });\n return envSchema.parse(env);\n }\n // NOTE (Cole, 2026-07-29, REPL-29501): client chunks bundle this module (integration-utils has client consumers). A static node:fs broke those chunks in 0.16.3, and a computed specifier fails Turbopack too (\"expression is too dynamic\") \u2014 only the ignore-annotated literal import compiles; postbuild.mjs asserts the annotation survives into dist.\n const { promises: fs }: typeof import(\"node:fs\") = await import(\n /* turbopackIgnore: true */ /* webpackIgnore: true */ \"node:fs\"\n );\n let raw: string;\n try {\n raw = await fs.readFile(`${process.cwd()}/wrangler.jsonc`, \"utf8\");\n } catch (error) {\n throw new MissingWranglerConfigError({\n message:\n `wrangler.jsonc not found in ${process.cwd()}. It holds this site's Replo project config ` +\n `(project id, API host) and is required to run outside the deployed worker. ` +\n `If this clone predates the committed config, open the site in Replo once \u2014 the dev ` +\n `server regenerates and commits it \u2014 then git pull.`,\n cause: error,\n });\n }\n return wranglerConfigSchema.parse(JSONC.parse(raw)).vars;\n};\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,4BAA4B;AACrC,OAAO,WAAW;AAClB,SAAS,SAAS;AAElB,SAAS,mBAAmB;AAsB5B,MAAM,YAAY,EAAE,OAAO;AAAA,EACzB,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACjC,YAAY,EAAE,KAAK;AAAA,EACnB,wBAAwB,EAAE,OAAO,EAAE,SAAS;AAAA,EAC5C,2BAA2B,EAAE,OAAO,EAAE,SAAS;AAAA,EAC/C,mBAAmB,EAAE,KAAK,CAAC,WAAW,UAAU,MAAM,CAAC,EAAE,SAAS;AACpE,CAAC;AAED,MAAM,uBAAuB,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAEzD,MAAM,mCAAmC,YAAY;AAAC;AAGtD,MAAM,mBAAmB,MAAM;AAC7B,SACE,QAAQ,IAAI,aAAa,gBACzB,QAAQ,IAAI,cAAc,WAC1B,QAAQ,IAAI,eAAe;AAE/B;AAEO,MAAM,SAAS,YAA0B;AAC9C,MAAI,iBAAiB,GAAG;AACtB,UAAM,EAAE,IAAI,IAAI,MAAM,qBAAqB,EAAE,OAAO,KAAK,CAAC;AAC1D,WAAO,UAAU,MAAM,GAAG;AAAA,EAC5B;AAEA,QAAM,EAAE,UAAU,GAAG,IAA8B,MAAM;AAAA;AAAA;AAAA,IACD;AAAA,EACxD;AACA,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,GAAG,SAAS,GAAG,QAAQ,IAAI,CAAC,mBAAmB,MAAM;AAAA,EACnE,SAAS,OAAO;AACd,UAAM,IAAI,2BAA2B;AAAA,MACnC,SACE,+BAA+B,QAAQ,IAAI,CAAC;AAAA,MAI9C,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AACA,SAAO,qBAAqB,MAAM,MAAM,MAAM,GAAG,CAAC,EAAE;AACtD;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { Cart } from "../cart/cart-schema";
|
|
2
|
+
import { CanopyError } from "../lib/canopy-error";
|
|
3
|
+
type CanopyApiGatewayErrorConfig = {
|
|
4
|
+
message: string;
|
|
5
|
+
statusCode?: number;
|
|
6
|
+
cause?: unknown;
|
|
7
|
+
additionalData?: Record<string, unknown>;
|
|
8
|
+
};
|
|
9
|
+
export declare class CanopyApiGatewayError extends CanopyError {
|
|
10
|
+
statusCode: number;
|
|
11
|
+
constructor(config: CanopyApiGatewayErrorConfig);
|
|
12
|
+
}
|
|
13
|
+
declare class CanopyApiGateway {
|
|
14
|
+
private apiHost;
|
|
15
|
+
private baseUrl;
|
|
16
|
+
constructor(apiHost: string);
|
|
17
|
+
private static readonly REQUEST_TIMEOUT_MILLISECONDS;
|
|
18
|
+
static setup(): Promise<CanopyApiGateway>;
|
|
19
|
+
private _post;
|
|
20
|
+
private _get;
|
|
21
|
+
invokeLoader({ loaderKey, args, }: {
|
|
22
|
+
loaderKey: string;
|
|
23
|
+
args: Record<string, unknown>;
|
|
24
|
+
}): Promise<{
|
|
25
|
+
data: unknown;
|
|
26
|
+
meta?: {
|
|
27
|
+
cache: {
|
|
28
|
+
hit: boolean;
|
|
29
|
+
ttlSeconds: number;
|
|
30
|
+
};
|
|
31
|
+
} | undefined;
|
|
32
|
+
}>;
|
|
33
|
+
private _cartPost;
|
|
34
|
+
cartGet({ cartId }: {
|
|
35
|
+
cartId: string;
|
|
36
|
+
}): Promise<Cart | null>;
|
|
37
|
+
cartCreate(options?: {
|
|
38
|
+
lines?: {
|
|
39
|
+
merchandiseId: string;
|
|
40
|
+
quantity: number;
|
|
41
|
+
attributes?: {
|
|
42
|
+
key: string;
|
|
43
|
+
value: string;
|
|
44
|
+
}[];
|
|
45
|
+
sellingPlanId?: string | null;
|
|
46
|
+
}[];
|
|
47
|
+
discountCodes?: string[];
|
|
48
|
+
}): Promise<Cart>;
|
|
49
|
+
cartAddLines({ cartId, lines, }: {
|
|
50
|
+
cartId: string;
|
|
51
|
+
lines: {
|
|
52
|
+
merchandiseId: string;
|
|
53
|
+
quantity: number;
|
|
54
|
+
attributes?: {
|
|
55
|
+
key: string;
|
|
56
|
+
value: string;
|
|
57
|
+
}[];
|
|
58
|
+
sellingPlanId?: string | null;
|
|
59
|
+
}[];
|
|
60
|
+
}): Promise<Cart>;
|
|
61
|
+
cartUpdateLines({ cartId, lines, }: {
|
|
62
|
+
cartId: string;
|
|
63
|
+
lines: {
|
|
64
|
+
lineId: string;
|
|
65
|
+
quantity: number;
|
|
66
|
+
attributes?: {
|
|
67
|
+
key: string;
|
|
68
|
+
value: string;
|
|
69
|
+
}[];
|
|
70
|
+
sellingPlanId?: string | null;
|
|
71
|
+
}[];
|
|
72
|
+
}): Promise<Cart>;
|
|
73
|
+
cartRemoveLines({ cartId, lineIds, }: {
|
|
74
|
+
cartId: string;
|
|
75
|
+
lineIds: string[];
|
|
76
|
+
}): Promise<Cart>;
|
|
77
|
+
cartUpdateDiscountCodes({ cartId, discountCodes, }: {
|
|
78
|
+
cartId: string;
|
|
79
|
+
discountCodes: string[];
|
|
80
|
+
}): Promise<Cart>;
|
|
81
|
+
}
|
|
82
|
+
export declare function getCanopyApiGateway(): Promise<CanopyApiGateway>;
|
|
83
|
+
export {};
|