@tagadapay/headless-sdk 1.14.1 → 1.16.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 (81) hide show
  1. package/dist/core/client.d.ts +7 -0
  2. package/dist/core/client.d.ts.map +1 -1
  3. package/dist/core/client.js +10 -3
  4. package/dist/core/client.js.map +1 -1
  5. package/dist/core/index.d.ts +3 -1
  6. package/dist/core/index.d.ts.map +1 -1
  7. package/dist/core/index.js +1 -0
  8. package/dist/core/index.js.map +1 -1
  9. package/dist/core/modules/checkout.d.ts +5 -1
  10. package/dist/core/modules/checkout.d.ts.map +1 -1
  11. package/dist/core/modules/checkout.js +10 -1
  12. package/dist/core/modules/checkout.js.map +1 -1
  13. package/dist/core/modules/payment.d.ts +19 -1
  14. package/dist/core/modules/payment.d.ts.map +1 -1
  15. package/dist/core/modules/payment.js +42 -3
  16. package/dist/core/modules/payment.js.map +1 -1
  17. package/dist/core/modules/rx.d.ts +32 -1
  18. package/dist/core/modules/rx.d.ts.map +1 -1
  19. package/dist/core/modules/rx.js +17 -1
  20. package/dist/core/modules/rx.js.map +1 -1
  21. package/dist/core/modules/track.d.ts +127 -0
  22. package/dist/core/modules/track.d.ts.map +1 -0
  23. package/dist/core/modules/track.js +371 -0
  24. package/dist/core/modules/track.js.map +1 -0
  25. package/dist/core/types.d.ts +2 -0
  26. package/dist/core/types.d.ts.map +1 -1
  27. package/dist/core/version.d.ts +4 -0
  28. package/dist/core/version.d.ts.map +1 -0
  29. package/dist/core/version.js +4 -0
  30. package/dist/core/version.js.map +1 -0
  31. package/dist/pixels/engine.d.ts +56 -0
  32. package/dist/pixels/engine.d.ts.map +1 -0
  33. package/dist/pixels/engine.js +263 -0
  34. package/dist/pixels/engine.js.map +1 -0
  35. package/dist/pixels/index.d.ts +10 -0
  36. package/dist/pixels/index.d.ts.map +1 -0
  37. package/dist/pixels/index.js +5 -0
  38. package/dist/pixels/index.js.map +1 -0
  39. package/dist/pixels/metaEventId.d.ts +15 -0
  40. package/dist/pixels/metaEventId.d.ts.map +1 -0
  41. package/dist/pixels/metaEventId.js +17 -0
  42. package/dist/pixels/metaEventId.js.map +1 -0
  43. package/dist/pixels/pixelIdentity.d.ts +34 -0
  44. package/dist/pixels/pixelIdentity.d.ts.map +1 -0
  45. package/dist/pixels/pixelIdentity.js +65 -0
  46. package/dist/pixels/pixelIdentity.js.map +1 -0
  47. package/dist/pixels/pixelMapping.d.ts +172 -0
  48. package/dist/pixels/pixelMapping.d.ts.map +1 -0
  49. package/dist/pixels/pixelMapping.js +574 -0
  50. package/dist/pixels/pixelMapping.js.map +1 -0
  51. package/dist/pixels/pixelTracker.d.ts +81 -0
  52. package/dist/pixels/pixelTracker.d.ts.map +1 -0
  53. package/dist/pixels/pixelTracker.js +795 -0
  54. package/dist/pixels/pixelTracker.js.map +1 -0
  55. package/dist/pixels/types.d.ts +103 -0
  56. package/dist/pixels/types.d.ts.map +1 -0
  57. package/dist/pixels/types.js +14 -0
  58. package/dist/pixels/types.js.map +1 -0
  59. package/dist/react/hooks/useStep.d.ts +7 -0
  60. package/dist/react/hooks/useStep.d.ts.map +1 -0
  61. package/dist/react/hooks/useStep.js +14 -0
  62. package/dist/react/hooks/useStep.js.map +1 -0
  63. package/dist/react/index.d.ts +1 -0
  64. package/dist/react/index.d.ts.map +1 -1
  65. package/dist/react/index.js +1 -0
  66. package/dist/react/index.js.map +1 -1
  67. package/dist/stripe/index.d.ts +3 -1
  68. package/dist/stripe/index.d.ts.map +1 -1
  69. package/dist/stripe/index.js +13 -6
  70. package/dist/stripe/index.js.map +1 -1
  71. package/dist/stripe/useStripeExpress.d.ts.map +1 -1
  72. package/dist/stripe/useStripeExpress.js +15 -1
  73. package/dist/stripe/useStripeExpress.js.map +1 -1
  74. package/dist/tagada-headless-react.min.js +2 -2
  75. package/dist/tagada-headless-react.min.js.map +4 -4
  76. package/dist/tagada-headless.js +439 -16
  77. package/dist/tagada-headless.min.js +2 -2
  78. package/dist/tagada-headless.min.js.map +4 -4
  79. package/dist/tagada-pixels.min.js +7 -0
  80. package/dist/tagada-pixels.min.js.map +7 -0
  81. package/package.json +8 -1
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @tagadapay/headless-sdk v1.16.0
3
+ * Headless checkout, payments, offers, and CRM
4
+ * @license MIT
5
+ */
6
+ "use strict";var TagadaPixels=(()=>{var F=Object.defineProperty;var le=Object.getOwnPropertyDescriptor;var fe=Object.getOwnPropertyNames;var ge=Object.prototype.hasOwnProperty;var pe=(e,i)=>{for(var t in i)F(e,t,{get:i[t],enumerable:!0})},me=(e,i,t,n)=>{if(i&&typeof i=="object"||typeof i=="function")for(let r of fe(i))!ge.call(e,r)&&r!==t&&F(e,r,{get:()=>i[r],enumerable:!(n=le(i,r))||n.enumerable});return e};var ye=e=>me(F({},"__esModule",{value:!0}),e);var dn={};pe(dn,{SDK_PIXEL_PROVIDERS:()=>H,bootstrapPixelTrackerFromWindow:()=>se,buildGa4PurchasePayload:()=>ee,createPixelEngine:()=>de,createPixelTracker:()=>K,getEligiblePixels:()=>S,isEventEnabled:()=>X,isSafePixelId:()=>O,makeMetaEventId:()=>ue,pixelIdKeyOf:()=>A,resolvePixelEvents:()=>U});function A(e){if(e&&typeof e=="object"){if("containerId"in e)return"containerId";if("projectId"in e)return"projectId"}return"pixelId"}var V="_ga4";function Pe(e){let i=(e.promotions??[]).map(t=>{var n;return t.code??((n=t.promotion)==null?void 0:n.code)}).filter(t=>typeof t=="string"&&t.length>0);if(i.length!==0)return[...new Set(i)].join(",")}function ee(e){var I,k,E,x,s,d,P;let i=e.items??[],t=Pe(e),n=((I=e.summaries)==null?void 0:I.find(a=>a.currency===e.currency))??((k=e.summaries)==null?void 0:k[0]),r=i.reduce((a,u)=>a+(u.adjustedAmount??0)*(u.quantity??0),0),o=i.reduce((a,u)=>a+Math.max(0,(u.amount??u.adjustedAmount??0)-(u.adjustedAmount??0))*(u.quantity??0),0),f=Math.min(Math.max(0,((n==null?void 0:n.totalPromotionAmount)??0)-o),r),l=f,y=i.map((a,u)=>{var D,G,j;let _=a.quantity??0,w=a.adjustedAmount??0,C=w*_,b=f===0||r===0?0:u===i.length-1?l:Math.round(f*C/r);l-=b;let T=_>0?b/_:0,M=Math.max(0,(a.amount??w)-w)+T,L={item_id:a.productId||void 0,item_name:((D=a.orderLineItemProduct)==null?void 0:D.name)||((G=a.orderLineItemVariant)==null?void 0:G.name)||void 0,item_variant:((j=a.orderLineItemVariant)==null?void 0:j.name)||void 0,price:w-T,quantity:a.quantity};return M>0&&(L.discount=M,t&&(L.coupon=t)),L}),g=e.paidAmount&&e.paidAmount>0?e.paidAmount:(n==null?void 0:n.totalAdjustedAmount)??r,p={items:y,value:g};(n==null?void 0:n.totalTaxAmount)!=null&&(p.tax=n.totalTaxAmount),(n==null?void 0:n.shippingCost)!=null&&(p.shipping=n.shippingCost),t&&(p.coupon=t),(E=e.customer)!=null&&E.id&&(p.user_id=e.customer.id);let c=e.billingAddress??e.shippingAddress,h={};(x=e.customer)!=null&&x.email&&(h.email_address=e.customer.email);let v=((s=e.customer)==null?void 0:s.phone)||(c==null?void 0:c.phone);if(v&&(h.phone_number=v),c){let a={first_name:c.firstName||((d=e.customer)==null?void 0:d.firstName)||void 0,last_name:c.lastName||((P=e.customer)==null?void 0:P.lastName)||void 0,street:c.address1||void 0,city:c.city||void 0,region:c.state||void 0,postal_code:c.postal||void 0,country:c.country||void 0};Object.values(a).some(u=>u!=null)&&(h.address=a)}return Object.keys(h).length>0&&(p.user_data=h),p}var he=new Set(["BIF","CLP","DJF","GNF","ISK","JPY","KMF","KRW","PYG","RWF","UGX","VND","VUV","XAF","XOF","XPF"]),_e=new Set(["BHD","IQD","JOD","KWD","LYD","OMR","TND"]);function N(e,i){let t=i.toUpperCase();return he.has(t)?e:_e.has(t)?e/1e3:e/100}function X(e,i){if(!("events"in e)||!e.events)return!0;let t=e.events;return i in t?t[i]===!0:!0}function S(e,i){return e?e.filter(t=>t.enabled&&X(t,i)):[]}function ke(e){return e.currency&&typeof e.currency=="string"?{...e,currency:e.currency.toUpperCase()}:{...e}}function ve(e){if(e.currency&&e.value!=null){let i=String(e.currency),t=N(Number(e.value),i);return{...e,value:t}}return e}function xe(e){let i=e.currency?String(e.currency):null;if(!i)return e;let t={...e};for(let n of["shipping","tax","subtotal","total_discount"])t[n]!=null&&(t[n]=N(Number(t[n]),i));return t}function Ie(e){if(!e.contents||!Array.isArray(e.contents))return e;let i=e.currency?String(e.currency):null,t={...e};return t.contents=e.contents.map(n=>{let r=n.currency?String(n.currency):i;if(!r)return{...n};let o={...n};return o.price!=null&&(o.price=N(Number(o.price),r)),o.original_price!=null&&(o.original_price=N(Number(o.original_price),r)),o}),t}function q(e){let i=ke(e);return i=ve(i),i=xe(i),i=Ie(i),V in i&&(i={...i},delete i[V]),i}var Ee={PageView:"PageView",ViewContent:"ViewContent",AddToCart:"AddToCart",AddToWishlist:"AddToWishlist",Search:"Search",InitiateCheckout:"InitiateCheckout",AddPaymentInfo:"AddPaymentInfo",Purchase:"Purchase",Lead:"Lead",CompleteRegistration:"CompleteRegistration"};function we(e,i){let t=Ee[e]??e,n=q(i);return n.contents&&Array.isArray(n.contents)&&(n.content_ids=n.contents.map(r=>r.content_id).filter(Boolean),n.content_type=n.content_type??"product",n.contents=n.contents.map(r=>({id:r.content_id,quantity:r.quantity!=null?Number(r.quantity):void 0,item_price:r.price!=null?Number(r.price):void 0,content_name:r.content_name,content_category:r.content_category}))),{name:t,params:n}}var Ce={PageView:"Pageview",ViewContent:"ViewContent",AddToCart:"AddToCart",AddToWishlist:"AddToWishlist",Search:"Search",InitiateCheckout:"InitiateCheckout",AddPaymentInfo:"AddPaymentInfo",Purchase:"Purchase",Lead:"SubmitForm",CompleteRegistration:"CompleteRegistration"};function be(e,i){let t=Ce[e]??e,n=q(i);if(delete n.coupon,n.contents&&Array.isArray(n.contents)){let r=n.contents.map(o=>o.content_id).filter(Boolean);!n.content_id&&r.length>0&&(n.content_id=r.length===1?r[0]:JSON.stringify(r)),n.content_ids||(n.content_ids=r),n.contents=n.contents.map(o=>({content_id:o.content_id,content_name:o.content_name,content_type:o.content_type??"product",content_category:o.content_category,price:o.price!=null?Number(o.price):void 0,original_price:o.original_price!=null?Number(o.original_price):void 0,quantity:o.quantity!=null?Number(o.quantity):void 0,description:o.description}))}return e==="InitiateCheckout"&&(n.content_type=n.content_type??"product",n.delivery_category||(n.delivery_category="home_delivery")),{name:t,params:n}}var Te={PageView:"PAGE_VIEW",ViewContent:"VIEW_CONTENT",AddToCart:"ADD_CART",AddToWishlist:"ADD_TO_WISHLIST",Search:"SEARCH",InitiateCheckout:"START_CHECKOUT",AddPaymentInfo:"ADD_BILLING",Purchase:"PURCHASE",Lead:"LEAD",CompleteRegistration:"SIGN_UP"};function Se(e,i){let t=Te[e]??e,n=q(i);return delete n.coupon,"value"in n&&(n={...n,price:n.value},delete n.value),"num_items"in n&&(n={...n,number_items:n.num_items},delete n.num_items),n.contents&&Array.isArray(n.contents)&&(n.item_ids=n.contents.map(r=>r.content_id).filter(Boolean)),{name:t,params:n}}var Ae={PageView:"pagevisit",ViewContent:"viewcontent",AddToCart:"addtocart",AddToWishlist:"addtowishlist",Search:"search",InitiateCheckout:"initiatecheckout",AddPaymentInfo:"addpaymentinfo",Purchase:"checkout",Lead:"lead",CompleteRegistration:"signup"};function Re(e,i){let t=Ae[e]??e.toLowerCase(),n=q(i);return n.coupon!=null&&(n.promo_code=n.coupon,delete n.coupon),n.order_quantity!==void 0&&(n.order_quantity=Number(n.order_quantity)),n.contents&&Array.isArray(n.contents)&&(n.line_items=n.contents.map(r=>({product_id:r.content_id,product_name:r.content_name,product_category:r.content_category,product_price:r.price!=null?Number(r.price):void 0,product_quantity:r.quantity!=null?Number(r.quantity):void 0}))),{name:t,params:n}}var Le={PageView:"page_view",ViewContent:"view_item",AddToCart:"add_to_cart",AddToWishlist:"add_to_wishlist",Search:"search",InitiateCheckout:"begin_checkout",AddPaymentInfo:"add_payment_info",Purchase:"purchase",Lead:"generate_lead",CompleteRegistration:"sign_up",Conversion:"conversion"};function qe(e,i){let t=Le[e]??e.toLowerCase(),n=i[V];if(n){let o=typeof i.currency=="string"?i.currency.toUpperCase():void 0,f=g=>g==null||!o?g:N(Number(g),o),l={transaction_id:i.transaction_id,currency:o,value:f(n.value)};n.tax!=null&&(l.tax=f(n.tax)),n.shipping!=null&&(l.shipping=f(n.shipping)),n.coupon&&(l.coupon=n.coupon),l.items=(n.items??[]).map(g=>({item_id:g.item_id,item_name:g.item_name,item_variant:g.item_variant,price:f(g.price),quantity:g.quantity!=null?Number(g.quantity):void 0,...g.discount!=null?{discount:f(g.discount)}:{},...g.coupon?{coupon:g.coupon}:{}}));let y={ecommerce:l};return n.user_id&&(y.user_id=n.user_id),n.user_data&&(y.user_data=n.user_data),{name:t,params:y}}let r=q(i);return r.num_items!==void 0&&(r.num_items=Number(r.num_items)),r.contents&&Array.isArray(r.contents)&&(r.items=r.contents.map(o=>({item_id:o.content_id,item_name:o.content_name,item_category:o.content_category,price:o.price!=null?Number(o.price):void 0,quantity:o.quantity!=null?Number(o.quantity):void 0})),r.contents=r.contents.map(o=>({id:o.content_id,name:o.content_name,category:o.content_category,price:o.price!=null?Number(o.price):void 0,quantity:o.quantity!=null?Number(o.quantity):void 0}))),{name:t,params:r}}var Me={PageView:"PageView",ViewContent:"ViewContent",AddToCart:"AddToCart",AddToWishlist:"AddToWishlist",Search:"Search",InitiateCheckout:"InitiateCheckout",AddPaymentInfo:"AddPaymentInfo",Purchase:"Purchase",Lead:"Lead",CompleteRegistration:"CompleteRegistration"};function De(e,i){return{name:Me[e]??e,params:q(i)}}function Ge(e,i,t){return(i==="Purchase"||i==="Conversion")&&t.googleAdsConversionId&&t.googleAdsConversionLabel?{...e,send_to:`${t.googleAdsConversionId}/${t.googleAdsConversionLabel}`}:e}function U(e,i,t){let n=[],r=S(e.facebook,i);if(r.length>0){let p=we(i,t);r.forEach(c=>n.push({provider:"facebook",mapped:p,pixel:c}))}let o=S(e.tiktok,i);if(o.length>0){let p=be(i,t);o.forEach(c=>n.push({provider:"tiktok",mapped:p,pixel:c}))}let f=S(e.snapchat,i);if(f.length>0){let p=Se(i,t);f.forEach(c=>n.push({provider:"snapchat",mapped:p,pixel:c}))}let l=S(e.pinterest,i);if(l.length>0){let p=Re(i,t);l.forEach(c=>n.push({provider:"pinterest",mapped:p,pixel:c}))}let y=S(e.clarity,i);if(y.length>0){let p=De(i,t);y.forEach(c=>n.push({provider:"clarity",mapped:p,pixel:c}))}let g=S(e.gtm,i);if(g.length>0){let p=qe(i,t);g.forEach(c=>{let h=Ge(p.params,i,c);n.push({provider:"gtm",mapped:{name:p.name,params:h},pixel:c})})}return n}function je(e){return e.trim().toLowerCase()}function Ve(e){let i=e.trim(),t=i.startsWith("+"),n=i.replace(/[^0-9]/g,"");return n?(t?"+":"")+n:""}async function z(e){let i=new TextEncoder().encode(e),t=await crypto.subtle.digest("SHA-256",i);return Array.from(new Uint8Array(t)).map(n=>n.toString(16).padStart(2,"0")).join("")}function ne(){return typeof crypto<"u"&&typeof crypto.subtle<"u"&&typeof crypto.subtle.digest=="function"}async function te(e){let i={};if(e.email){let t=je(e.email);t&&(i.email=await z(t))}if(e.phone){let t=Ve(e.phone);t&&(i.phone=await z(t))}if(e.externalId){let t=e.externalId.trim();t&&(i.externalId=await z(t))}return i}function Ne(e){let i=new Map;return(t,n,r)=>{try{let o=JSON.stringify({eventName:t,parameters:n,eventId:r}),f=Date.now(),l=i.get(o);return l&&f-l<e?!1:(i.set(o,f),!0)}catch{return!0}}}function Z(e){if(!e)return null;let i=e[A(e)];return typeof i=="string"&&i?i:null}function ie(e,i,t,n,r={}){var l,y,g,p,c,h,v,I,k,E;if(typeof window>"u")return;let o=window,f=r.eventId;switch(e){case"facebook":{let x=Z(n);if(!x)break;f?(l=o.fbq)==null||l.call(o,"trackSingle",x,i,t,{eventID:f}):(y=o.fbq)==null||y.call(o,"trackSingle",x,i,t);break}case"tiktok":{let x=Z(n),s=x&&((g=o.ttq)!=null&&g.instance)?o.ttq.instance(x):o.ttq;i==="Pageview"?(p=s==null?void 0:s.page)==null||p.call(s):f?(c=s==null?void 0:s.track)==null||c.call(s,i,t,{event_id:f}):(h=s==null?void 0:s.track)==null||h.call(s,i,t);break}case"snapchat":(v=o.snaptr)==null||v.call(o,"track",i,t);break;case"pinterest":i==="pagevisit"?(I=o.pintrk)==null||I.call(o,"page"):(k=o.pintrk)==null||k.call(o,"track",i,t);break;case"gtm":Ue(i,t);break;case"clarity":(E=o.clarity)==null||E.call(o,"event",i);break}}function Oe(e,i,t){if(!(e!=null&&e.snaptr))return;let n={};t.email&&(n.user_hashed_email=t.email),t.phone&&(n.user_hashed_phone_number=t.phone),Object.keys(n).length!==0&&e.snaptr("init",i,n)}function Ke(e,i,t){var o;let n=(o=e==null?void 0:e.ttq)!=null&&o.instance?e.ttq.instance(i):e==null?void 0:e.ttq;if(!(n!=null&&n.identify))return;let r={};t.email&&(r.email=t.email),t.phone&&(r.phone_number=t.phone),t.externalId&&(r.external_id=t.externalId),Object.keys(r).length!==0&&n.identify(r)}function He(e,i,t){if(!(e!=null&&e.fbq))return;let n={};if(t.email&&(n.em=t.email.trim().toLowerCase()),t.phone){let r=t.phone.replace(/[^0-9]/g,"");r&&(n.ph=r)}t.externalId&&(n.external_id=t.externalId.trim()),Object.keys(n).length!==0&&e.fbq("init",i,n)}function re(e,i){if(typeof(e==null?void 0:e.gtag)!="function")return;let t={};if(i.email_address&&(t.email=i.email_address.trim().toLowerCase()),i.phone_number){let n=i.phone_number.replace(/[^0-9+]/g,"");/^\+[0-9]{10,14}$/.test(n)&&(t.phone_number=n)}if(i.address){let n=i.address,r={};n.first_name&&(r.first_name=n.first_name),n.last_name&&(r.last_name=n.last_name),n.street&&(r.street=n.street),n.city&&(r.city=n.city),n.region&&(r.region=n.region),n.postal_code&&(r.postal_code=n.postal_code),n.country&&(r.country=n.country),Object.keys(r).length>0&&(t.address=r)}Object.keys(t).length!==0&&e.gtag("set","user_data",t)}function Ue(e,i){try{let t=window,n=i&&typeof i=="object"&&"ecommerce"in i;if(t.gtag)if(n){let{ecommerce:r,...o}=i;t.gtag("event",e,{...o,...r})}else t.gtag("event",e,i);else t.dataLayer&&(n&&t.dataLayer.push({ecommerce:null}),t.dataLayer.push({event:e,...i}))}catch(t){console.error("[SDK GTM] Error:",t)}}var m=typeof window<"u"?window:void 0,Be=5e3;function R(e){return e.dataset.loaded?Promise.resolve():new Promise(i=>{let t=()=>{e.dataset.loaded="1",clearTimeout(n),i()},n=setTimeout(t,Be);e.addEventListener("load",t,{once:!0}),e.addEventListener("error",t,{once:!0})})}var J=null;function We(e){var i;if(!m)return Promise.resolve();if(!m.fbq){let t=function(...o){t.callMethod?t.callMethod(...o):t.queue.push(o)};t.queue=[],t.loaded=!0,t.version="2.0",m.fbq=t,m._fbq||(m._fbq=t);let n=document.createElement("script");n.async=!0,n.src="https://connect.facebook.net/en_US/fbevents.js";let r=document.getElementsByTagName("script")[0];(i=r==null?void 0:r.parentNode)==null||i.insertBefore(n,r),J=n}return m.fbq("init",e),J?R(J):Promise.resolve()}var oe=!1;function $e(e){var n;if(!m)return Promise.resolve();if(!oe){oe=!0,m.TiktokAnalyticsObject="ttq";let r=m.ttq=m.ttq||[];r.methods=["page","track","identify","instances","debug","on","off","once","ready","alias","group","enableCookie","disableCookie","holdConsent","revokeConsent","grantConsent"],r.setAndDefer=function(o,f){o[f]=function(...l){o.push([f,...l])}};for(let o of r.methods)r.setAndDefer(r,o);r.instance=function(o){let f=r._i[o]||[];for(let l of r.methods)r.setAndDefer(f,l);return f},r.load=function(o,f){var p;let l="https://analytics.tiktok.com/i18n/pixel/events.js";r._i=r._i||{},r._i[o]=[],r._i[o]._u=l,r._t=r._t||{},r._t[o]=+new Date,r._o=r._o||{},r._o[o]=f||{};let y=document.createElement("script");y.type="text/javascript",y.async=!0,y.src=l+"?sdkid="+o+"&lib=ttq";let g=document.getElementsByTagName("script")[0];(p=g==null?void 0:g.parentNode)==null||p.insertBefore(y,g)}}if((n=m.ttq._i)!=null&&n[e])return Promise.resolve();m.ttq.load(e);let i=document.querySelectorAll('script[src*="analytics.tiktok.com/i18n/pixel/events.js"]'),t=i[i.length-1];return t?R(t):Promise.resolve()}var Y=null;function Fe(e){var i;if(!m)return Promise.resolve();if(!m.snaptr){let t=function(...o){t.handleRequest?t.handleRequest(...o):t.queue.push(o)};t.queue=[],m.snaptr=t;let n=document.createElement("script");n.async=!0,n.src="https://sc-static.net/scevent.min.js";let r=document.getElementsByTagName("script")[0];(i=r==null?void 0:r.parentNode)==null||i.insertBefore(n,r),Y=n}return m.snaptr("init",e),Y?R(Y):Promise.resolve()}var Q=null;function Xe(e){var i;if(!m)return Promise.resolve();if(!m.pintrk){let t=function(...o){t.queue.push(o)};t.queue=[],m.pintrk=t;let n=document.createElement("script");n.async=!0,n.src="https://s.pinimg.com/ct/core.js";let r=document.getElementsByTagName("script")[0];(i=r==null?void 0:r.parentNode)==null||i.insertBefore(n,r),Q=n}return m.pintrk("load",e),Q?R(Q):Promise.resolve()}function ze(e){var n;if(!m||!e||document.querySelector(`script[src*="clarity.ms/tag/${e}"]`))return Promise.resolve();if(!m.clarity){let r=function(...o){r.q.push(o)};r.q=[],m.clarity=r}let i=document.createElement("script");i.async=!0,i.src=`https://www.clarity.ms/tag/${e}`;let t=document.getElementsByTagName("script")[0];return t!=null&&t.parentNode?t.parentNode.insertBefore(i,t):(n=document.head||document.getElementsByTagName("head")[0])==null||n.appendChild(i),R(i)}function Je(e){var n,r,o,f;if(!m||!e)return Promise.resolve();let i=e.startsWith("GTM-"),t=i?`googletagmanager.com/gtm.js?id=${e}`:`googletagmanager.com/gtag/js?id=${e}`;if(document.querySelector(`script[src*="${t}"]`))return Promise.resolve();m.dataLayer=m.dataLayer||[];try{let l=document.referrer&&new URL(document.referrer).hostname;l&&l!==window.location.hostname&&m.dataLayer.push({tagada_referrer_domain:l})}catch{}if(i){m.dataLayer.push({"gtm.start":new Date().getTime(),event:"gtm.js"});let l=document.getElementsByTagName("script")[0],y=document.createElement("script");y.async=!0,y.src="https://www.googletagmanager.com/gtm.js?id="+e,l!=null&&l.parentNode?l.parentNode.insertBefore(y,l):(n=document.head||document.getElementsByTagName("head")[0])==null||n.appendChild(y);let g=document.createElement("noscript"),p=document.createElement("iframe");return p.src=`https://www.googletagmanager.com/ns.html?id=${e}`,p.height="0",p.width="0",p.style.display="none",p.style.visibility="hidden",g.appendChild(p),(o=document.body||document.getElementsByTagName("body")[0])==null||o.insertBefore(g,((r=document.body)==null?void 0:r.firstChild)??null),R(y)}else{m.gtag||(m.gtag=function(...p){m.dataLayer.push(arguments)}),m.gtag("js",new Date);let l={accept_incoming:!0};try{let p=document.referrer&&new URL(document.referrer).hostname;p&&p!==window.location.hostname&&(l.domains=[p,window.location.hostname])}catch{}m.gtag("config",e,{linker:l});let y=document.createElement("script");y.async=!0,y.src="https://www.googletagmanager.com/gtag/js?id="+e;let g=document.getElementsByTagName("script")[0];return g!=null&&g.parentNode?g.parentNode.insertBefore(y,g):(f=document.head||document.getElementsByTagName("head")[0])==null||f.appendChild(y),R(y)}}var Ye=64,Qe=new RegExp(`^[A-Za-z0-9_-]{1,${Ye}}$`);function O(e){return typeof e=="string"&&Qe.test(e.trim())}function Ze(e){let i={},t=[];for(let[n,r]of Object.entries(e)){if(!Array.isArray(r))continue;let o=[];for(let f of r){let l=A(f),y=f==null?void 0:f[l];if(!O(y)){t.push(y);continue}o.push({...f,[l]:y.trim()})}i[n]=o}return t.length>0&&console.warn(`[SDK Pixels] Ignored ${t.length} malformed pixel ID(s) \u2014 tracking for those entries is disabled.`,t),i}var en=1500;function nn(){return typeof window>"u"?Promise.resolve():new Promise(e=>{let i=!1,t=()=>{i||(i=!0,clearTimeout(r),e())},n=typeof(m==null?void 0:m.requestAnimationFrame)=="function"?m.requestAnimationFrame.bind(m):void 0,r=setTimeout(t,n?en:0);n&&n(()=>n(t))})}function K(e,i){let t=e&&Ze(e),n=Ne(5e3),r=!1,o=(async()=>{var h,v,I,k,E,x;if(!t||typeof window>"u")return;await nn();let c=[];try{(h=t.facebook)==null||h.forEach(s=>{s.enabled&&s.pixelId&&c.push(We(s.pixelId))}),(v=t.tiktok)==null||v.forEach(s=>{s.enabled&&s.pixelId&&c.push($e(s.pixelId))}),(I=t.snapchat)==null||I.forEach(s=>{s.enabled&&s.pixelId&&c.push(Fe(s.pixelId))}),(k=t.pinterest)==null||k.forEach(s=>{s.enabled&&s.pixelId&&c.push(Xe(s.pixelId))}),(E=t.gtm)==null||E.forEach(s=>{s.enabled&&s.containerId&&c.push(Je(s.containerId))}),(x=t.clarity)==null||x.forEach(s=>{s.enabled&&s.projectId&&c.push(ze(s.projectId))}),await Promise.all(c)}catch(s){console.error("[SDK Pixels] Initialization error:",s)}r=!0})(),f=null,l=null,y=c=>{var v,I;if(!t||!c.email&&!c.phone&&!c.externalId)return null;let h=`${c.email??""}|${c.phone??""}|${c.externalId??""}`;return f===h&&l?l:(f=h,(v=t.facebook)==null||v.forEach(k=>{k.enabled&&k.pixelId&&He(m,k.pixelId,c)}),(I=t.gtm)!=null&&I.some(k=>k.enabled)&&re(m,{email_address:c.email,phone_number:c.phone}),ne()?(l=(async()=>{var k,E;try{let x=await te(c);(k=t.snapchat)==null||k.forEach(s=>{s.enabled&&s.pixelId&&Oe(m,s.pixelId,x)}),(E=t.tiktok)==null||E.forEach(s=>{s.enabled&&s.pixelId&&Ke(m,s.pixelId,x)})}catch(x){console.error("[SDK Pixels] identify error:",x)}})(),l):l=Promise.resolve())},g=c=>{var I;let h=c[V],v=h==null?void 0:h.user_data;return v?((I=t==null?void 0:t.gtm)!=null&&I.some(k=>k.enabled)&&re(m,v),y({email:v.email_address,phone:v.phone_number,externalId:h==null?void 0:h.user_id})):null},p=(c,h={},v={})=>{if(!(!t||!r)&&n(c,h,v.eventId))try{let I=g(h),k=U(t,c,h),E=new Set,x=new Set;for(let{provider:s,mapped:d,pixel:P}of k){let a=I&&(s==="snapchat"||s==="tiktok")?u=>{I.then(u)}:u=>{u()};if(s==="gtm"||s==="tiktok"||s==="facebook"){let u=`${s}:${Z(P)??""}`;if(x.has(u))continue;x.add(u),a(()=>ie(s,d.name,d.params,P,v))}else E.has(s)||(a(()=>ie(s,d.name,d.params,void 0,v)),E.add(s))}}catch(I){console.error("[SDK Pixels] Tracking error:",I)}};return(i==null?void 0:i.autoPageView)!==!1&&o.then(()=>{typeof window>"u"||p("PageView",{path:window.location.pathname})}),{initPromise:o,get pixelsInitialized(){return r},track:p,identify:c=>{y(c)}}}function tn(){if(typeof window>"u")return;let e=window.__TGD_STEP_CONFIG__;if(e)try{let i=typeof e=="string"?JSON.parse(e):e,t=i==null?void 0:i.pixels;return t&&typeof t=="object"?t:void 0}catch{return}}function se(){if(typeof window>"u")return null;if(window.__TGD_PIXEL_TRACKER__)return window.__TGD_PIXEL_TRACKER__;let e=tn();if(!e)return null;let i=K(e);return window.__TGD_PIXEL_TRACKER__=i,i}var H=["facebook","tiktok","snapchat","gtm","clarity"],rn={facebook:"https://connect.facebook.net",tiktok:"https://analytics.tiktok.com",snapchat:"https://sc-static.net",gtm:"https://www.googletagmanager.com",clarity:"https://www.clarity.ms"},on={facebook:"fbq",tiktok:"ttq",snapchat:"snaptr",gtm:"dataLayer",clarity:"clarity"},sn=50,ae=1e3;function an(e){return H.includes(e)}function cn(e){let i={};return e.facebook&&(i.facebook=e.facebook),e.tiktok&&(i.tiktok=e.tiktok),e.snapchat&&(i.snapchat=e.snapchat),e.gtm&&(i.gtm=e.gtm),e.clarity&&(i.clarity=e.clarity),i}function B(e,i){let t=e[i];return Array.isArray(t)?t:[]}function ce(e){let i=e[A(e)];return O(i)?i.trim():null}function de(e){let i=cn(e.pixels),t=new Map,n=new Map,r=new Set,o=[],f=e.requireConsent!==!0,l=!1,y=!1,g=null,p=(d,P,a)=>{var _;let u=`${P}|${d}`;if(!r.has(u)){r.add(u);try{(_=e.onSignal)==null||_.call(e,{kind:d,provider:P,detail:a})}catch{}}},c=()=>H.filter(d=>B(i,d).length>0),h=(d,P)=>{var u,_,w,C;return(d==="InitiateCheckout"||d==="Purchase"?((u=e.checkout)==null?void 0:u[d])??[]:((C=(w=(_=e.steps)==null?void 0:_[P??""])==null?void 0:w.events)==null?void 0:C[d])??[]).filter(an)},v=d=>{var P;for(let a of c()){let u=typeof((P=d.location)==null?void 0:P.host)=="string"?d.location.host:"";if(a==="gtm"){let _=d.google_tag_manager;B(i,"gtm").some(C=>{let b=ce(C);return b!==null&&(_==null?void 0:_[b])!==void 0})&&p("pixel_duplicate","gtm",{origin:u});continue}d[on[a]]!==void 0&&p("pixel_duplicate",a,{origin:u})}},I=d=>{g=P=>{let a=P,u=typeof a.blockedURI=="string"?a.blockedURI:"";for(let _ of H)if(u.startsWith(rn[_])){p("pixel_blocked",_,{reason:"csp",directive:a.violatedDirective??""});return}},d.addEventListener("securitypolicyviolation",g)},k=d=>{l||(o.length>=sn&&o.shift(),o.push(d))},E=d=>{try{if(sessionStorage.getItem(`__tgd_px:${d}`))return!1}catch{}return!0},x=d=>{try{sessionStorage.setItem(`__tgd_px:${d}`,"1")}catch{}},s={async init(){if(y||typeof window>"u"||!f)return;y=!0;let d=window;v(d),I(d);let P=[];for(let a of c()){let u=K({[a]:B(i,a)},{autoPageView:!1});t.set(a,u),P.push(u.initPromise)}await Promise.all(P)},pageView(d,P){var C;if(typeof window>"u")return;if(!f){k(()=>s.pageView(d,P));return}let a=`${(P==null?void 0:P.stepId)??""}|${d}`,u=Date.now(),_=n.get(a);if(_!==void 0&&u-_<ae)return;for(let[b,T]of n)u-T>=ae&&n.delete(b);n.set(a,u);let w=h("PageView",P==null?void 0:P.stepId);if(w.length!==0)for(let b of w)(C=t.get(b))==null||C.track("PageView",{path:d},{eventId:`PageView_${a}|${u}`})},track(d,P,a){var _;if(typeof window>"u")return;if(!f){k(()=>s.track(d,P,a));return}if((d==="InitiateCheckout"||d==="Purchase")&&(!(a!=null&&a.eventId)||!E(a.eventId)))return;let u=h(d,a==null?void 0:a.stepId);if(u.length!==0){for(let w of u)(_=t.get(w))==null||_.track(d,P??{},a!=null&&a.eventId?{eventId:a.eventId}:void 0);a!=null&&a.eventId&&x(a.eventId)}},trackCustom(d,P,a){var w,C,b,T,W,M,L,D;if(typeof window>"u")return;if(!f){k(()=>s.trackCustom(d,P,a));return}let u=window,_=P??{};for(let G of h(d,a==null?void 0:a.stepId))for(let j of B(i,G)){if(!j.enabled)continue;let $=ce(j);if($!==null)switch(G){case"facebook":(w=u.fbq)==null||w.call(u,"trackSingleCustom",$,d,_);break;case"tiktok":(W=(T=(b=(C=u.ttq)==null?void 0:C.instance)==null?void 0:b.call(C,$))==null?void 0:T.track)==null||W.call(T,d,_);break;case"snapchat":(M=u.snaptr)==null||M.call(u,"track",d,_);break;case"gtm":(L=u.gtag)==null||L.call(u,"event",d,_);break;case"clarity":(D=u.clarity)==null||D.call(u,"event",d);break}}},identify(d){if(!(typeof window>"u"))for(let P of t.values())P.identify(d)},consent(d){if(!d.marketing){o.length=0,l=!0,f=!1;return}l||f||(f=!0,s.init().then(()=>{let P=o.splice(0,o.length);for(let a of P)a()}))},destroy(){o.length=0,g&&typeof window<"u"&&window.removeEventListener("securitypolicyviolation",g),g=null,t.clear()}};return s}function ue(e,i){return`${e}_${i}`}return ye(dn);})();
7
+ //# sourceMappingURL=tagada-pixels.min.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/pixels/index.ts", "../src/pixels/pixelMapping.ts", "../src/pixels/pixelIdentity.ts", "../src/pixels/pixelTracker.ts", "../src/pixels/engine.ts", "../src/pixels/metaEventId.ts"],
4
+ "sourcesContent": ["export { createPixelEngine, SDK_PIXEL_PROVIDERS } from './engine.js';\nexport type {\n PixelEngine, PixelEngineConfig, PixelSignal, PixelSignalKind, SdkPixelProvider,\n} from './engine.js';\n\nexport { makeMetaEventId } from './metaEventId.js';\nexport { bootstrapPixelTrackerFromWindow, createPixelTracker, isSafePixelId } from './pixelTracker.js';\nexport type { PixelTracker, TrackOptions } from './pixelTracker.js';\nexport { buildGa4PurchasePayload, getEligiblePixels, isEventEnabled, pixelIdKeyOf, resolvePixelEvents } from './pixelMapping.js';\nexport type { PixelProviderKey, StandardPixelEvent } from './pixelMapping.js';\nexport type { PixelRawIdentity } from './pixelIdentity.js';\nexport type { PixelConfig, PixelsConfig } from './types.js';\n", "/**\n * Core pixel event mapping, parameter transformation, and event gating.\n *\n * This module is framework-agnostic (no React, no DOM) so it can be shared\n * between the React `PixelTrackingProvider` and the standalone vanilla SDK.\n *\n * Official event name references (verified Feb 2026 against vendor docs):\n * Meta: fbq('track', 'Purchase', { value, currency }) \u2014 developers.facebook.com/docs/meta-pixel/reference\n * TikTok: ttq.track('Purchase', { value, currency }) \u2014 ads.tiktok.com/help/article/standard-events-parameters (Sep 2025)\n * Snapchat: snaptr('track', 'PURCHASE', { price, currency }) \u2014 developers.snap.com/api/marketing-api/Conversions-API/Parameters\n * Pinterest: pintrk('track', 'checkout', { value, currency }) \u2014 help.pinterest.com/en/business/article/add-event-codes\n * GTM/GA4: gtag('event', 'purchase', { value, currency, items })\n * Clarity: clarity('event', 'Purchase') \u2014 learn.microsoft.com/en-us/clarity/setup-and-installation/clarity-api\n */\n\nimport type {\n PixelTrackingConfig,\n SnapchatTrackingConfig,\n GTMTrackingConfig,\n ClarityTrackingConfig,\n PixelConfig,\n PixelsConfig,\n} from './types.js';\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport type StandardPixelEvent =\n | 'PageView'\n | 'ViewContent'\n | 'AddToCart'\n | 'AddToWishlist'\n | 'Search'\n | 'InitiateCheckout'\n | 'AddPaymentInfo'\n | 'Purchase'\n | 'Lead'\n | 'CompleteRegistration'\n | 'Conversion';\n\nexport type PixelProviderKey = 'facebook' | 'tiktok' | 'snapchat' | 'pinterest' | 'gtm' | 'clarity';\n\n/** The field a pixel entry carries its tracking id in. */\nexport type PixelIdKey = 'pixelId' | 'containerId' | 'projectId';\n\n/**\n * Which key holds this entry's id: GTM stores a `containerId`, Clarity a\n * `projectId`, every other provider a `pixelId`. Callers that sanitize, split\n * or display an id go through here rather than testing the keys themselves,\n * so a new provider with its own field name is one edit, not six.\n */\nexport function pixelIdKeyOf(pixel: unknown): PixelIdKey {\n if (pixel && typeof pixel === 'object') {\n if ('containerId' in pixel) return 'containerId';\n if ('projectId' in pixel) return 'projectId';\n }\n return 'pixelId';\n}\n\nexport interface MappedEvent {\n name: string;\n params: Record<string, unknown>;\n}\n\n// ---------------------------------------------------------------------------\n// GA4-only enrichment\n//\n// Canonical GA4 ecommerce `purchase` data carries user identity + a nested\n// `ecommerce` object that the flat Meta/TikTok payload does not. We attach it\n// to the shared track() params under the reserved `_ga4` key. ONLY mapGTMEvent\n// reads it; `baseTransform` strips it so it can never leak into the\n// Meta/TikTok/Snapchat/Pinterest payloads (those would otherwise spread it,\n// shipping unhashed PII to those pixels). All monetary fields are in MINOR\n// units here \u2014 mapGTMEvent converts to major via the same currency helpers.\n// ---------------------------------------------------------------------------\n\nexport const GA4_PARAM_KEY = '_ga4' as const;\n\nexport interface Ga4UserData {\n email_address?: string;\n phone_number?: string;\n address?: {\n first_name?: string;\n last_name?: string;\n street?: string;\n city?: string;\n region?: string;\n postal_code?: string;\n country?: string;\n };\n}\n\nexport interface Ga4Item {\n item_id?: string;\n item_name?: string;\n item_variant?: string;\n /** Minor units (cents). Post-discount unit price (GA4 spec). Converted to major by mapGTMEvent. */\n price?: number;\n quantity?: number;\n /** Minor units (cents). Per-unit monetary discount (line-level + allocated order-level). */\n discount?: number;\n /** Coupon code(s) that discounted this item. */\n coupon?: string;\n}\n\nexport interface Ga4PurchasePayload {\n user_id?: string;\n user_data?: Ga4UserData;\n /** Minor units (cents). */\n value?: number;\n /** Minor units (cents). */\n tax?: number;\n /** Minor units (cents). */\n shipping?: number;\n /** Order-level coupon code(s), comma-joined. */\n coupon?: string;\n items: Ga4Item[];\n}\n\n/** Loose order shape accepted by buildGa4PurchasePayload (subset of SDK Order). */\nexport interface Ga4OrderInput {\n id?: string;\n currency?: string;\n paidAmount?: number;\n items?: Array<{\n productId?: string;\n variantId?: string | null;\n quantity?: number;\n /** Pre-discount unit amount (minor units). */\n amount?: number;\n adjustedAmount?: number;\n orderLineItemProduct?: { name?: string };\n orderLineItemVariant?: { name?: string };\n }>;\n summaries?: Array<{\n currency?: string;\n totalTaxAmount?: number;\n shippingCost?: number;\n totalAdjustedAmount?: number;\n totalPromotionAmount?: number;\n }>;\n /**\n * Applied promotions. Accepts both shapes seen in the wild:\n * promotion-usage rows with a nested `promotion` (CMS order endpoint) and\n * flat promotion summaries with a `code` (SDK OrderWithRelations).\n */\n promotions?: Array<{\n code?: string | null;\n promotion?: { code?: string | null } | null;\n }>;\n customer?: { id?: string; email?: string; phone?: string; firstName?: string; lastName?: string };\n billingAddress?: Ga4Address;\n shippingAddress?: Ga4Address;\n}\n\n/**\n * Extract the distinct coupon codes applied to an order, comma-joined.\n * Returns undefined when the order carries no coded promotions (automatic\n * promotions have `code: null` and are deliberately excluded \u2014 GA4's `coupon`\n * dimension is for codes the shopper entered).\n */\nexport function extractCouponCodes(order: Pick<Ga4OrderInput, 'promotions'>): string | undefined {\n const codes = (order.promotions ?? [])\n .map((p) => p.code ?? p.promotion?.code)\n .filter((c): c is string => typeof c === 'string' && c.length > 0);\n if (codes.length === 0) return undefined;\n return [...new Set(codes)].join(',');\n}\n\ninterface Ga4Address {\n firstName?: string;\n lastName?: string;\n address1?: string;\n city?: string;\n state?: string;\n postal?: string;\n country?: string;\n phone?: string;\n}\n\n/**\n * Build the GA4-only enrichment payload (`_ga4`) from an order. Pure, defensive,\n * framework-agnostic \u2014 shared by the native ThankYouPage and the Studio\n * OrderConfirmation island so both emit an identical canonical GA4 purchase.\n * Returns minor-unit amounts; mapGTMEvent converts them to major units.\n */\nexport function buildGa4PurchasePayload(order: Ga4OrderInput): Ga4PurchasePayload {\n const sourceItems = order.items ?? [];\n const coupon = extractCouponCodes(order);\n\n const summary =\n order.summaries?.find((s) => s.currency === order.currency) ?? order.summaries?.[0];\n\n const itemsSum = sourceItems.reduce(\n (sum, i) => sum + (i.adjustedAmount ?? 0) * (i.quantity ?? 0),\n 0,\n );\n\n // GA4 requires order-level discounts to be allocated across items: `price`\n // must be the post-discount unit price and `discount` the per-unit monetary\n // discount. Line-level discounts are already baked into adjustedAmount; the\n // order-level remainder (totalPromotionAmount minus line-level discounts,\n // capped to the item subtotal \u2014 promos can also cover shipping) is spread\n // proportionally by line value.\n const lineLevelDiscountTotal = sourceItems.reduce(\n (sum, i) => sum + Math.max(0, (i.amount ?? i.adjustedAmount ?? 0) - (i.adjustedAmount ?? 0)) * (i.quantity ?? 0),\n 0,\n );\n const orderLevelDiscount = Math.min(\n Math.max(0, (summary?.totalPromotionAmount ?? 0) - lineLevelDiscountTotal),\n itemsSum,\n );\n\n let remainingAllocation = orderLevelDiscount;\n const items: Ga4Item[] = sourceItems.map((item, index) => {\n const quantity = item.quantity ?? 0;\n const unitAdjusted = item.adjustedAmount ?? 0;\n const lineValue = unitAdjusted * quantity;\n\n // Last item takes the remainder so allocations sum exactly.\n const lineAllocation =\n orderLevelDiscount === 0 || itemsSum === 0\n ? 0\n : index === sourceItems.length - 1\n ? remainingAllocation\n : Math.round((orderLevelDiscount * lineValue) / itemsSum);\n remainingAllocation -= lineAllocation;\n\n const unitAllocation = quantity > 0 ? lineAllocation / quantity : 0;\n const lineLevelUnitDiscount = Math.max(0, (item.amount ?? unitAdjusted) - unitAdjusted);\n const unitDiscount = lineLevelUnitDiscount + unitAllocation;\n\n const ga4Item: Ga4Item = {\n item_id: item.productId || undefined,\n // GA4 convention: item_name = product, item_variant = variant.\n item_name: item.orderLineItemProduct?.name || item.orderLineItemVariant?.name || undefined,\n item_variant: item.orderLineItemVariant?.name || undefined,\n price: unitAdjusted - unitAllocation,\n quantity: item.quantity,\n };\n if (unitDiscount > 0) {\n ga4Item.discount = unitDiscount;\n if (coupon) ga4Item.coupon = coupon;\n }\n return ga4Item;\n });\n\n // Prefer the captured paid amount; fall back to the summary total, then to\n // the sum of line items. Guards against the value:0 seen in the field.\n const value =\n order.paidAmount && order.paidAmount > 0\n ? order.paidAmount\n : (summary?.totalAdjustedAmount ?? itemsSum);\n\n const payload: Ga4PurchasePayload = { items, value };\n if (summary?.totalTaxAmount != null) payload.tax = summary.totalTaxAmount;\n if (summary?.shippingCost != null) payload.shipping = summary.shippingCost;\n if (coupon) payload.coupon = coupon;\n\n if (order.customer?.id) payload.user_id = order.customer.id;\n\n const addr = order.billingAddress ?? order.shippingAddress;\n const userData: Ga4UserData = {};\n if (order.customer?.email) userData.email_address = order.customer.email;\n const phone = order.customer?.phone || addr?.phone;\n if (phone) userData.phone_number = phone;\n if (addr) {\n const address = {\n first_name: addr.firstName || order.customer?.firstName || undefined,\n last_name: addr.lastName || order.customer?.lastName || undefined,\n street: addr.address1 || undefined,\n city: addr.city || undefined,\n region: addr.state || undefined,\n postal_code: addr.postal || undefined,\n country: addr.country || undefined,\n };\n if (Object.values(address).some((v) => v != null)) userData.address = address;\n }\n if (Object.keys(userData).length > 0) payload.user_data = userData;\n\n return payload;\n}\n\n// ---------------------------------------------------------------------------\n// Currency conversion helper (inline, zero-dep)\n// ---------------------------------------------------------------------------\n\n/**\n * Convert minor units (cents) to major units using ISO 4217 digit counts.\n * Falls back to \u00F7100 for unknown currencies.\n */\nconst ZERO_DECIMAL_CURRENCIES = new Set([\n 'BIF', 'CLP', 'DJF', 'GNF', 'ISK', 'JPY', 'KMF', 'KRW',\n 'PYG', 'RWF', 'UGX', 'VND', 'VUV', 'XAF', 'XOF', 'XPF',\n]);\n\nconst THREE_DECIMAL_CURRENCIES = new Set(['BHD', 'IQD', 'JOD', 'KWD', 'LYD', 'OMR', 'TND']);\n\nfunction minorToMajor(amount: number, currency: string): number {\n const code = currency.toUpperCase();\n if (ZERO_DECIMAL_CURRENCIES.has(code)) return amount;\n if (THREE_DECIMAL_CURRENCIES.has(code)) return amount / 1000;\n return amount / 100;\n}\n\n// ---------------------------------------------------------------------------\n// Event gating \u2013 respects per-event toggles\n// ---------------------------------------------------------------------------\n\n/**\n * Returns `true` if the given event is enabled on the pixel config.\n * If the pixel has no `events` map (e.g. MetaConversionTrackingConfig) we allow all.\n */\nexport function isEventEnabled(pixel: PixelConfig, eventName: StandardPixelEvent): boolean {\n if (!('events' in pixel) || !pixel.events) return true;\n const events = pixel.events as Record<string, boolean>;\n if (!(eventName in events)) return true; // unknown event \u2192 allow\n return events[eventName] === true;\n}\n\n/**\n * Filter an array of pixel configs to only those that are globally enabled\n * AND have the specific event toggled on.\n */\nexport function getEligiblePixels<T extends PixelConfig>(\n pixels: T[] | undefined,\n eventName: StandardPixelEvent,\n): T[] {\n if (!pixels) return [];\n return pixels.filter((p) => p.enabled && isEventEnabled(p, eventName));\n}\n\n// ---------------------------------------------------------------------------\n// Shared parameter transforms\n// ---------------------------------------------------------------------------\n\nfunction ensureCurrencyUppercase(params: Record<string, unknown>): Record<string, unknown> {\n if (params.currency && typeof params.currency === 'string') {\n return { ...params, currency: params.currency.toUpperCase() };\n }\n return { ...params };\n}\n\nfunction convertValueToMajor(params: Record<string, unknown>): Record<string, unknown> {\n if (params.currency && params.value != null) {\n const currency = String(params.currency);\n const major = minorToMajor(Number(params.value), currency);\n return { ...params, value: major };\n }\n return params;\n}\n\n/** Convert top-level monetary fields (shipping, tax, subtotal, total_discount) from minor \u2192 major units. */\nfunction convertMonetaryFieldsToMajor(params: Record<string, unknown>): Record<string, unknown> {\n const currency = params.currency ? String(params.currency) : null;\n if (!currency) return params;\n const result = { ...params };\n for (const field of ['shipping', 'tax', 'subtotal', 'total_discount'] as const) {\n if (result[field] != null) {\n result[field] = minorToMajor(Number(result[field]), currency);\n }\n }\n return result;\n}\n\n/** Convert price fields inside contents[] items from minor \u2192 major units. */\nfunction convertContentsPricesToMajor(params: Record<string, unknown>): Record<string, unknown> {\n if (!params.contents || !Array.isArray(params.contents)) return params;\n const currency = params.currency ? String(params.currency) : null;\n const result = { ...params };\n result.contents = (params.contents as Record<string, unknown>[]).map((item) => {\n const itemCurrency = item.currency ? String(item.currency) : currency;\n if (!itemCurrency) return { ...item };\n const converted = { ...item };\n if (converted.price != null) converted.price = minorToMajor(Number(converted.price), itemCurrency);\n if (converted.original_price != null) converted.original_price = minorToMajor(Number(converted.original_price), itemCurrency);\n return converted;\n });\n return result;\n}\n\nfunction baseTransform(params: Record<string, unknown>): Record<string, unknown> {\n let p = ensureCurrencyUppercase(params);\n p = convertValueToMajor(p);\n p = convertMonetaryFieldsToMajor(p);\n p = convertContentsPricesToMajor(p);\n // Strip GA4-only enrichment so it never reaches Meta/TikTok/Snapchat/Pinterest\n // (those mappers spread all params). mapGTMEvent reads it from the raw input.\n if (GA4_PARAM_KEY in p) {\n p = { ...p };\n delete p[GA4_PARAM_KEY];\n }\n return p;\n}\n\n// ---------------------------------------------------------------------------\n// Meta / Facebook\n// ---------------------------------------------------------------------------\n\nconst META_EVENT_MAP: Partial<Record<StandardPixelEvent, string>> = {\n PageView: 'PageView',\n ViewContent: 'ViewContent',\n AddToCart: 'AddToCart',\n AddToWishlist: 'AddToWishlist',\n Search: 'Search',\n InitiateCheckout: 'InitiateCheckout',\n AddPaymentInfo: 'AddPaymentInfo',\n Purchase: 'Purchase',\n Lead: 'Lead',\n CompleteRegistration: 'CompleteRegistration',\n};\n\nexport function mapMetaEvent(eventName: StandardPixelEvent, parameters: Record<string, unknown>): MappedEvent {\n const name = META_EVENT_MAP[eventName] ?? eventName;\n // `coupon` intentionally flows through: Meta has no standard coupon param but\n // accepts custom parameters on standard events (usable in custom conversions).\n const params = baseTransform(parameters);\n\n if (params.contents && Array.isArray(params.contents)) {\n params.content_ids = (params.contents as Record<string, unknown>[]).map((i) => i.content_id).filter(Boolean);\n params.content_type = params.content_type ?? 'product';\n\n // Reshape contents to Meta's expected format (prices already converted by baseTransform)\n params.contents = (params.contents as Record<string, unknown>[]).map((item) => ({\n id: item.content_id,\n quantity: item.quantity != null ? Number(item.quantity) : undefined,\n item_price: item.price != null ? Number(item.price) : undefined,\n content_name: item.content_name,\n content_category: item.content_category,\n }));\n }\n\n return { name, params };\n}\n\n// ---------------------------------------------------------------------------\n// TikTok\n// Official: ttq.track('Purchase', { value, currency })\n// Source: ads.tiktok.com/help/article/standard-events-parameters (Sep 2025)\n// Standard events use PascalCase. Note: TikTok has no standard PageView event\n// (page views use ttq.page()), so we pass it as-is for custom tracking.\n// TikTok has no Lead event; SubmitForm is the closest standard equivalent.\n// ---------------------------------------------------------------------------\n\nconst TIKTOK_EVENT_MAP: Partial<Record<StandardPixelEvent, string>> = {\n PageView: 'Pageview',\n ViewContent: 'ViewContent',\n AddToCart: 'AddToCart',\n AddToWishlist: 'AddToWishlist',\n Search: 'Search',\n InitiateCheckout: 'InitiateCheckout',\n AddPaymentInfo: 'AddPaymentInfo',\n Purchase: 'Purchase',\n Lead: 'SubmitForm',\n CompleteRegistration: 'CompleteRegistration',\n};\n\nexport function mapTikTokEvent(eventName: StandardPixelEvent, parameters: Record<string, unknown>): MappedEvent {\n const name = TIKTOK_EVENT_MAP[eventName] ?? eventName;\n const params = baseTransform(parameters);\n\n // TikTok's event spec has no coupon/discount parameter \u2014 strip it to keep\n // the payload within spec (avoids Events Manager diagnostics warnings).\n delete params.coupon;\n\n if (params.contents && Array.isArray(params.contents)) {\n const ids = (params.contents as Record<string, unknown>[])\n .map((i) => i.content_id)\n .filter(Boolean) as string[];\n\n // TikTok requires content_id (singular) at the top level for VSA\n if (!params.content_id && ids.length > 0) {\n params.content_id = ids.length === 1 ? ids[0] : JSON.stringify(ids);\n }\n\n // Also keep content_ids for backwards compatibility\n if (!params.content_ids) {\n params.content_ids = ids;\n }\n\n // Reshape contents to TikTok's expected format (prices already converted by baseTransform)\n params.contents = (params.contents as Record<string, unknown>[]).map((item) => ({\n content_id: item.content_id,\n content_name: item.content_name,\n content_type: item.content_type ?? 'product',\n content_category: item.content_category,\n price: item.price != null ? Number(item.price) : undefined,\n original_price: item.original_price != null ? Number(item.original_price) : undefined,\n quantity: item.quantity != null ? Number(item.quantity) : undefined,\n description: item.description,\n }));\n }\n\n // Set required fields for InitiateCheckout\n if (eventName === 'InitiateCheckout') {\n params.content_type = params.content_type ?? 'product';\n if (!params.delivery_category) {\n params.delivery_category = 'home_delivery';\n }\n }\n\n return { name, params };\n}\n\n// ---------------------------------------------------------------------------\n// Snapchat\n// Official: snaptr('track', 'PURCHASE', { price, currency })\n// Source: developers.snap.com/api/marketing-api/Conversions-API/Parameters\n// All event names are UPPER_SNAKE_CASE.\n// Note: Snapchat has no LEAD standard event; we pass it as-is (custom event).\n// ---------------------------------------------------------------------------\n\nconst SNAPCHAT_EVENT_MAP: Partial<Record<StandardPixelEvent, string>> = {\n PageView: 'PAGE_VIEW',\n ViewContent: 'VIEW_CONTENT',\n AddToCart: 'ADD_CART',\n AddToWishlist: 'ADD_TO_WISHLIST',\n Search: 'SEARCH',\n InitiateCheckout: 'START_CHECKOUT',\n AddPaymentInfo: 'ADD_BILLING',\n Purchase: 'PURCHASE',\n Lead: 'LEAD',\n CompleteRegistration: 'SIGN_UP',\n};\n\nexport function mapSnapchatEvent(eventName: StandardPixelEvent, parameters: Record<string, unknown>): MappedEvent {\n const name = SNAPCHAT_EVENT_MAP[eventName] ?? eventName;\n let params = baseTransform(parameters);\n\n // Snap's parameter spec has no coupon/discount field \u2014 strip it.\n delete params.coupon;\n\n // Snapchat uses `price` not `value`\n if ('value' in params) {\n params = { ...params, price: params.value };\n delete params.value;\n }\n\n // Snapchat uses `number_items` not `num_items`\n if ('num_items' in params) {\n params = { ...params, number_items: params.num_items };\n delete params.num_items;\n }\n\n if (params.contents && Array.isArray(params.contents)) {\n params.item_ids = (params.contents as { content_id?: string }[]).map((i) => i.content_id).filter(Boolean);\n }\n\n return { name, params };\n}\n\n// ---------------------------------------------------------------------------\n// Pinterest\n// Official: pintrk('track', 'checkout', { value, currency, line_items })\n// Event names are all lowercase.\n// ---------------------------------------------------------------------------\n\nconst PINTEREST_EVENT_MAP: Partial<Record<StandardPixelEvent, string>> = {\n PageView: 'pagevisit',\n ViewContent: 'viewcontent',\n AddToCart: 'addtocart',\n AddToWishlist: 'addtowishlist',\n Search: 'search',\n InitiateCheckout: 'initiatecheckout',\n AddPaymentInfo: 'addpaymentinfo',\n Purchase: 'checkout',\n Lead: 'lead',\n CompleteRegistration: 'signup',\n};\n\nexport function mapPinterestEvent(eventName: StandardPixelEvent, parameters: Record<string, unknown>): MappedEvent {\n const name = PINTEREST_EVENT_MAP[eventName] ?? eventName.toLowerCase();\n const params = baseTransform(parameters);\n\n // Pinterest's official field for coupon codes is `promo_code`.\n if (params.coupon != null) {\n params.promo_code = params.coupon;\n delete params.coupon;\n }\n\n if (params.order_quantity !== undefined) {\n params.order_quantity = Number(params.order_quantity);\n }\n\n if (params.contents && Array.isArray(params.contents)) {\n // Reshape to Pinterest line_items format (prices already converted by baseTransform)\n params.line_items = (params.contents as Record<string, unknown>[]).map((item) => ({\n product_id: item.content_id,\n product_name: item.content_name,\n product_category: item.content_category,\n product_price: item.price != null ? Number(item.price) : undefined,\n product_quantity: item.quantity != null ? Number(item.quantity) : undefined,\n }));\n }\n\n return { name, params };\n}\n\n// ---------------------------------------------------------------------------\n// GTM / GA4 / Google Ads\n// Official: gtag('event', 'purchase', { value, currency, items })\n// Event names are snake_case (GA4 convention).\n// ---------------------------------------------------------------------------\n\nconst GTM_EVENT_MAP: Partial<Record<StandardPixelEvent, string>> = {\n PageView: 'page_view',\n ViewContent: 'view_item',\n AddToCart: 'add_to_cart',\n AddToWishlist: 'add_to_wishlist',\n Search: 'search',\n InitiateCheckout: 'begin_checkout',\n AddPaymentInfo: 'add_payment_info',\n Purchase: 'purchase',\n Lead: 'generate_lead',\n CompleteRegistration: 'sign_up',\n Conversion: 'conversion',\n};\n\nexport function mapGTMEvent(eventName: StandardPixelEvent, parameters: Record<string, unknown>): MappedEvent {\n const name = GTM_EVENT_MAP[eventName] ?? eventName.toLowerCase();\n\n // Canonical GA4 ecommerce shape: when the caller attached `_ga4` enrichment\n // (purchase from the thank-you page) emit a nested `ecommerce` object plus\n // user identity instead of the legacy flat payload. baseTransform strips\n // `_ga4`, so read it from the raw input first.\n const ga4 = parameters[GA4_PARAM_KEY] as Ga4PurchasePayload | undefined;\n if (ga4) {\n const currency =\n typeof parameters.currency === 'string' ? parameters.currency.toUpperCase() : undefined;\n const toMajor = (v: number | undefined): number | undefined =>\n v == null || !currency ? v : minorToMajor(Number(v), currency);\n\n const ecommerce: Record<string, unknown> = {\n transaction_id: parameters.transaction_id,\n currency,\n value: toMajor(ga4.value),\n };\n if (ga4.tax != null) ecommerce.tax = toMajor(ga4.tax);\n if (ga4.shipping != null) ecommerce.shipping = toMajor(ga4.shipping);\n if (ga4.coupon) ecommerce.coupon = ga4.coupon;\n ecommerce.items = (ga4.items ?? []).map((item) => ({\n item_id: item.item_id,\n item_name: item.item_name,\n item_variant: item.item_variant,\n price: toMajor(item.price),\n quantity: item.quantity != null ? Number(item.quantity) : undefined,\n ...(item.discount != null ? { discount: toMajor(item.discount) } : {}),\n ...(item.coupon ? { coupon: item.coupon } : {}),\n }));\n\n const out: Record<string, unknown> = { ecommerce };\n if (ga4.user_id) out.user_id = ga4.user_id;\n if (ga4.user_data) out.user_data = ga4.user_data;\n return { name, params: out };\n }\n\n const params = baseTransform(parameters);\n\n if (params.num_items !== undefined) {\n params.num_items = Number(params.num_items);\n }\n\n if (params.contents && Array.isArray(params.contents)) {\n // Reshape to GA4 items format (prices already converted by baseTransform)\n params.items = (params.contents as Record<string, unknown>[]).map((item) => ({\n item_id: item.content_id,\n item_name: item.content_name,\n item_category: item.content_category,\n price: item.price != null ? Number(item.price) : undefined,\n quantity: item.quantity != null ? Number(item.quantity) : undefined,\n }));\n\n params.contents = (params.contents as Record<string, unknown>[]).map((item) => ({\n id: item.content_id,\n name: item.content_name,\n category: item.content_category,\n price: item.price != null ? Number(item.price) : undefined,\n quantity: item.quantity != null ? Number(item.quantity) : undefined,\n }));\n }\n\n return { name, params };\n}\n\n// ---------------------------------------------------------------------------\n// Microsoft Clarity\n// Official: clarity('event', 'Purchase') \u2014 custom (\"smart\") events take a name\n// and no parameters, so the mapped params are carried for the dedup guard only.\n// Clarity records page views by itself; the PageView toggle still emits a named\n// event so a merchant can filter recordings on it like any other funnel step.\n// ---------------------------------------------------------------------------\n\nconst CLARITY_EVENT_MAP: Partial<Record<StandardPixelEvent, string>> = {\n PageView: 'PageView',\n ViewContent: 'ViewContent',\n AddToCart: 'AddToCart',\n AddToWishlist: 'AddToWishlist',\n Search: 'Search',\n InitiateCheckout: 'InitiateCheckout',\n AddPaymentInfo: 'AddPaymentInfo',\n Purchase: 'Purchase',\n Lead: 'Lead',\n CompleteRegistration: 'CompleteRegistration',\n};\n\nexport function mapClarityEvent(\n eventName: StandardPixelEvent,\n parameters: Record<string, unknown>,\n): MappedEvent {\n const name = CLARITY_EVENT_MAP[eventName] ?? eventName;\n return { name, params: baseTransform(parameters) };\n}\n\n/**\n * Append Google Ads `send_to` parameter when conversion tracking is configured.\n */\nexport function applyGoogleAdsConversion(\n params: Record<string, unknown>,\n eventName: StandardPixelEvent,\n pixel: GTMTrackingConfig,\n): Record<string, unknown> {\n if (\n (eventName === 'Purchase' || eventName === 'Conversion') &&\n pixel.googleAdsConversionId &&\n pixel.googleAdsConversionLabel\n ) {\n return { ...params, send_to: `${pixel.googleAdsConversionId}/${pixel.googleAdsConversionLabel}` };\n }\n return params;\n}\n\n// ---------------------------------------------------------------------------\n// Dispatcher \u2013 maps a StandardPixelEvent to all providers in one call\n// ---------------------------------------------------------------------------\n\nexport interface ProviderEvent {\n provider: PixelProviderKey;\n mapped: MappedEvent;\n pixel: PixelConfig;\n}\n\n/**\n * Given a PixelsConfig and an event, return per-provider mapped events\n * for every eligible (enabled + event-toggled-on) pixel.\n */\nexport function resolvePixelEvents(\n pixels: PixelsConfig,\n eventName: StandardPixelEvent,\n parameters: Record<string, unknown>,\n): ProviderEvent[] {\n const results: ProviderEvent[] = [];\n\n const fb = getEligiblePixels(pixels.facebook, eventName);\n if (fb.length > 0) {\n const mapped = mapMetaEvent(eventName, parameters);\n fb.forEach((pixel) => results.push({ provider: 'facebook', mapped, pixel }));\n }\n\n const tt = getEligiblePixels(pixels.tiktok, eventName);\n if (tt.length > 0) {\n const mapped = mapTikTokEvent(eventName, parameters);\n tt.forEach((pixel) => results.push({ provider: 'tiktok', mapped, pixel }));\n }\n\n const sc = getEligiblePixels(pixels.snapchat as SnapchatTrackingConfig[] | undefined, eventName);\n if (sc.length > 0) {\n const mapped = mapSnapchatEvent(eventName, parameters);\n sc.forEach((pixel) => results.push({ provider: 'snapchat', mapped, pixel }));\n }\n\n const pt = getEligiblePixels(pixels.pinterest, eventName);\n if (pt.length > 0) {\n const mapped = mapPinterestEvent(eventName, parameters);\n pt.forEach((pixel) => results.push({ provider: 'pinterest', mapped, pixel }));\n }\n\n const clarity = getEligiblePixels(pixels.clarity as ClarityTrackingConfig[] | undefined, eventName);\n if (clarity.length > 0) {\n const mapped = mapClarityEvent(eventName, parameters);\n clarity.forEach((pixel) => results.push({ provider: 'clarity', mapped, pixel }));\n }\n\n const gtm = getEligiblePixels(pixels.gtm as GTMTrackingConfig[] | undefined, eventName);\n if (gtm.length > 0) {\n const mapped = mapGTMEvent(eventName, parameters);\n gtm.forEach((pixel) => {\n const finalParams = applyGoogleAdsConversion(mapped.params, eventName, pixel as GTMTrackingConfig);\n results.push({ provider: 'gtm', mapped: { name: mapped.name, params: finalParams }, pixel });\n });\n }\n\n return results;\n}\n", "/**\n * Client-side identity hashing for pixel advanced matching.\n *\n * Framework-agnostic (no DOM). Normalizes + SHA-256-hashes the customer\n * identifiers (email / phone / external id) so the tracker can feed match\n * keys to Snapchat (`user_hashed_email`/`user_hashed_phone_number`) and TikTok\n * (`ttq.identify`). We hash in the browser ourselves so raw PII never leaves\n * the page \u2014 TikTok requires pre-hashed values anyway, and Snap/Meta accept\n * pre-hashed too.\n */\n\nexport interface PixelRawIdentity {\n /** Raw email (any case). */\n email?: string;\n /** Raw phone in any format. */\n phone?: string;\n /** Stable external id (e.g. Tagada customer id). */\n externalId?: string;\n}\n\nexport interface PixelHashedIdentity {\n /** SHA-256 hex of the normalized email. */\n email?: string;\n /** SHA-256 hex of the E.164-normalized phone. */\n phone?: string;\n /** SHA-256 hex of the trimmed external id. */\n externalId?: string;\n}\n\n/** Lowercase + trim \u2014 the normalization Meta/Snap/TikTok all expect for email. */\nfunction normalizeEmail(email: string): string {\n return email.trim().toLowerCase();\n}\n\n/**\n * Normalize to E.164-ish: keep a single leading `+` (if present) and digits.\n * Snap and TikTok both expect E.164 with the country-code `+`, so a single\n * hash satisfies both. (Meta wants digits-only \u2014 add a per-provider variant\n * here if Meta browser matching is added later.)\n */\nfunction normalizePhone(phone: string): string {\n const trimmed = phone.trim();\n const hasPlus = trimmed.startsWith('+');\n const digits = trimmed.replace(/[^0-9]/g, '');\n if (!digits) return '';\n return (hasPlus ? '+' : '') + digits;\n}\n\nasync function sha256Hex(input: string): Promise<string> {\n const data = new TextEncoder().encode(input);\n const buf = await crypto.subtle.digest('SHA-256', data);\n return Array.from(new Uint8Array(buf))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n}\n\n/** True when SubtleCrypto is usable (secure context). */\nexport function canHashIdentity(): boolean {\n return (\n typeof crypto !== 'undefined' &&\n typeof crypto.subtle !== 'undefined' &&\n typeof crypto.subtle.digest === 'function'\n );\n}\n\n/**\n * Hash whichever identifiers are present. Empty/whitespace-only fields are\n * skipped so we never emit a hash of \"\". Returns `{}` when nothing usable.\n */\nexport async function buildHashedIdentity(id: PixelRawIdentity): Promise<PixelHashedIdentity> {\n const out: PixelHashedIdentity = {};\n\n if (id.email) {\n const n = normalizeEmail(id.email);\n if (n) out.email = await sha256Hex(n);\n }\n if (id.phone) {\n const n = normalizePhone(id.phone);\n if (n) out.phone = await sha256Hex(n);\n }\n if (id.externalId) {\n const n = id.externalId.trim();\n if (n) out.externalId = await sha256Hex(n);\n }\n\n return out;\n}\n", "/**\n * Framework-agnostic pixel tracker.\n *\n * Init / fire logic for Meta, TikTok, Snapchat, Pinterest, GTM/GA4 and\n * Microsoft Clarity pixels \u2014\n * extracted from `react/hooks/usePixelTracking.tsx` so non-React entry points\n * (Studio islands hydrator, full-SPA runtime) can fire pixel events from\n * `window.__TGD_STEP_CONFIG__.pixels`.\n *\n * The React provider is a thin adapter on top of this module.\n */\n\nimport type { ClarityTrackingConfig, GTMTrackingConfig, PixelConfig, PixelsConfig } from './types.js';\nimport {\n resolvePixelEvents,\n pixelIdKeyOf,\n GA4_PARAM_KEY,\n type Ga4PurchasePayload,\n type Ga4UserData,\n type PixelProviderKey,\n type StandardPixelEvent,\n} from './pixelMapping.js';\nimport {\n buildHashedIdentity,\n canHashIdentity,\n type PixelHashedIdentity,\n type PixelRawIdentity,\n} from './pixelIdentity.js';\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\n/**\n * Optional per-event tracking metadata. `eventId` is the cross-channel dedup\n * key that the SDK threads to `fbq` (Meta) and `ttq` (TikTok) so the same\n * eventID/event_id can be matched against a server-side CAPI event. Use the\n * `makeMetaEventId(eventName, entityId)` helper from `core/utils/metaEventId`\n * to keep the formula in lockstep with the server.\n */\nexport interface TrackOptions {\n eventId?: string;\n}\n\nexport interface PixelTracker {\n /** Resolves once all pixel scripts have loaded (or hit their load timeout). */\n readonly initPromise: Promise<void>;\n /** True after `initPromise` resolves. */\n readonly pixelsInitialized: boolean;\n /** Track a standard pixel event. No-ops until init resolves. */\n track(\n eventName: StandardPixelEvent,\n parameters?: Record<string, unknown>,\n options?: TrackOptions,\n ): void;\n /**\n * Feed customer identifiers for advanced matching. Applies to Meta (fbq init,\n * raw \u2014 Meta hashes in-browser), Google (gtag set user_data, raw \u2014 enhanced\n * conversions), Snapchat (re-init) + TikTok (identify), the last two with\n * client-side SHA-256 hashing. Each provider persists the keys onto\n * subsequent events, so call this as soon as the email is known to lift\n * match quality on InitiateCheckout + Purchase. Idempotent per identity; safe\n * to call repeatedly.\n */\n identify(identity: PixelRawIdentity): void;\n}\n\n// ---------------------------------------------------------------------------\n// Duplicate guard (time-window based)\n// ---------------------------------------------------------------------------\n\nfunction createDuplicateGuard(windowMs: number) {\n const lastEvents = new Map<string, number>();\n return (\n eventName: StandardPixelEvent,\n parameters: Record<string, unknown>,\n eventId?: string,\n ): boolean => {\n try {\n // Include eventId in the dedup key so two distinct logical events with the\n // same name+params (e.g. two Purchases) are not collapsed by the guard.\n const key = JSON.stringify({ eventName, parameters, eventId });\n const now = Date.now();\n const last = lastEvents.get(key);\n if (last && now - last < windowMs) return false;\n lastEvents.set(key, now);\n return true;\n } catch {\n return true;\n }\n };\n}\n\n// ---------------------------------------------------------------------------\n// Browser-specific: fire an event to the correct global pixel function\n// ---------------------------------------------------------------------------\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/**\n * The entry's own identifier, read at whichever key its provider uses \u2014\n * `pixelId`, or `containerId` / `projectId` for GTM and Clarity.\n */\nfunction pixelIdOf(pixel?: PixelConfig): string | null {\n if (!pixel) return null;\n const value = (pixel as unknown as Record<string, unknown>)[pixelIdKeyOf(pixel)];\n return typeof value === 'string' && value ? value : null;\n}\n\nfunction fire(\n provider: PixelProviderKey,\n name: string,\n params: Record<string, unknown>,\n pixel?: PixelConfig,\n options: TrackOptions = {},\n) {\n if (typeof window === 'undefined') return;\n const w = window as any;\n const eventId = options.eventId;\n switch (provider) {\n case 'facebook': {\n // Target this pixel by id rather than calling the global `fbq('track')`,\n // which Meta broadcasts to EVERY pixel registered on the page \u2014 including\n // ones a merchant initialised from a pasted script we don't manage. That\n // broadcast made our Purchase land on foreign pixels, undeduplicated.\n // Mirrors the per-pixel targeting already used for TikTok below.\n //\n // Meta dedup: pass eventID as the trailing `eventID` option so this\n // browser-pixel event matches a server-side CAPI event with the same id.\n // See https://developers.facebook.com/docs/marketing-api/conversions-api/deduplicate-pixel-and-server-events\n // No id means no addressable pixel: stay silent rather than fall back to\n // the broadcast this change exists to remove. `sanitizePixels` drops every\n // entry without a usable id, so this is unreachable today.\n const pixelId = pixelIdOf(pixel);\n if (!pixelId) break;\n if (eventId) w.fbq?.('trackSingle', pixelId, name, params, { eventID: eventId });\n else w.fbq?.('trackSingle', pixelId, name, params);\n break;\n }\n case 'tiktok': {\n // Use ttq.instance(pixelId) to target each pixel individually,\n // since the global ttq.track() only fires for the sdkid pixel.\n const pixelId = pixelIdOf(pixel);\n const target = pixelId && w.ttq?.instance ? w.ttq.instance(pixelId) : w.ttq;\n if (name === 'Pageview') { target?.page?.(); }\n else if (eventId) { target?.track?.(name, params, { event_id: eventId }); }\n else { target?.track?.(name, params); }\n break;\n }\n case 'snapchat': w.snaptr?.('track', name, params); break;\n case 'pinterest':\n // Pinterest handles page views via pintrk('page'), not pintrk('track', 'pagevisit')\n if (name === 'pagevisit') { w.pintrk?.('page'); }\n else { w.pintrk?.('track', name, params); }\n break;\n case 'gtm': fireGTM(name, params); break;\n // Clarity's custom-event API takes a name and nothing else; params stay\n // out rather than being stringified into the event name.\n case 'clarity': w.clarity?.('event', name); break;\n }\n}\n\n/**\n * Apply advanced matching to a single Snapchat pixel. Snap reads user info set\n * at init and attaches it to every event fired afterwards; re-calling init with\n * the (now-known) hashed identifiers updates it. We pass pre-hashed values via\n * the `user_hashed_*` keys.\n */\nfunction applySnapchatIdentity(w: any, pixelId: string, h: PixelHashedIdentity) {\n if (!w?.snaptr) return;\n const userInfo: Record<string, string> = {};\n if (h.email) userInfo.user_hashed_email = h.email;\n if (h.phone) userInfo.user_hashed_phone_number = h.phone;\n if (Object.keys(userInfo).length === 0) return;\n w.snaptr('init', pixelId, userInfo);\n}\n\n/**\n * Apply advanced matching to a single TikTok pixel via `ttq.identify`. TikTok\n * applies identified data to subsequent events and accepts pre-hashed SHA-256\n * values (it detects 64-char hex and won't double-hash). Target the specific\n * pixel instance, mirroring the per-pixel track() targeting.\n */\nfunction applyTikTokIdentity(w: any, pixelId: string, h: PixelHashedIdentity) {\n const target = w?.ttq?.instance ? w.ttq.instance(pixelId) : w?.ttq;\n if (!target?.identify) return;\n const info: Record<string, string> = {};\n if (h.email) info.email = h.email;\n if (h.phone) info.phone_number = h.phone;\n if (h.externalId) info.external_id = h.externalId;\n if (Object.keys(info).length === 0) return;\n target.identify(info);\n}\n\n/**\n * Apply advanced matching to a single Meta pixel. Meta reads advanced-matching\n * data passed to `fbq('init', pixelId, userData)` and attaches it to every\n * event fired afterwards; re-calling init with the (now-known) identifiers\n * updates it (init is idempotent and never auto-fires PageView). We pass RAW\n * values \u2014 `fbevents.js` normalizes + SHA-256-hashes them in-browser before\n * they leave the page \u2014 because Meta's phone normalization (digits-only) differs\n * from Snap/TikTok's E.164, so letting Meta hash avoids a mismatch.\n */\nfunction applyMetaIdentity(w: any, pixelId: string, raw: PixelRawIdentity) {\n if (!w?.fbq) return;\n const ud: Record<string, string> = {};\n if (raw.email) ud.em = raw.email.trim().toLowerCase();\n if (raw.phone) { const d = raw.phone.replace(/[^0-9]/g, ''); if (d) ud.ph = d; }\n if (raw.externalId) ud.external_id = raw.externalId.trim();\n if (Object.keys(ud).length === 0) return;\n w.fbq('init', pixelId, ud);\n}\n\n/**\n * Google Ads enhanced conversions / GA4 user-provided data.\n *\n * Google's documented mechanism is `gtag('set', 'user_data', {...})` BEFORE the\n * conversion event fires (support.google.com/google-ads/answer/13258081) \u2014\n * `user_data` as an event parameter is not read for enhanced conversions. We\n * pass RAW values; the Google tag normalizes + SHA-256 hashes in-browser.\n * Field names per spec: `email`, `phone_number` (strict E.164 \u2014 dropped when\n * not in that shape, email is the preferred key anyway), and\n * `address.{first_name,last_name,street,city,region,postal_code,country}`.\n * Exported for unit tests.\n */\nexport function applyGoogleIdentity(w: any, ud: Ga4UserData) {\n if (typeof w?.gtag !== 'function') return;\n\n const userData: Record<string, unknown> = {};\n if (ud.email_address) userData.email = ud.email_address.trim().toLowerCase();\n\n if (ud.phone_number) {\n const phone = ud.phone_number.replace(/[^0-9+]/g, '');\n if (/^\\+[0-9]{10,14}$/.test(phone)) userData.phone_number = phone;\n }\n\n if (ud.address) {\n const a = ud.address;\n const address: Record<string, string> = {};\n if (a.first_name) address.first_name = a.first_name;\n if (a.last_name) address.last_name = a.last_name;\n if (a.street) address.street = a.street;\n if (a.city) address.city = a.city;\n if (a.region) address.region = a.region;\n if (a.postal_code) address.postal_code = a.postal_code;\n if (a.country) address.country = a.country;\n if (Object.keys(address).length > 0) userData.address = address;\n }\n\n if (Object.keys(userData).length === 0) return;\n w.gtag('set', 'user_data', userData);\n}\n\nfunction fireGTM(event: string, params: Record<string, unknown>) {\n try {\n const w = window as any;\n const hasEcommerce = params && typeof params === 'object' && 'ecommerce' in params;\n if (w.gtag) {\n // gtag.js (GA4 config tag) reads ecommerce fields at the top level of the\n // event, not under a nested `ecommerce` key \u2014 flatten it back out.\n if (hasEcommerce) {\n const { ecommerce, ...rest } = params as Record<string, unknown>;\n w.gtag('event', event, { ...rest, ...(ecommerce as Record<string, unknown>) });\n } else {\n w.gtag('event', event, params);\n }\n } else if (w.dataLayer) {\n // GA4 best practice: clear the previous ecommerce object before pushing a\n // new one so item arrays from earlier events don't bleed through.\n if (hasEcommerce) w.dataLayer.push({ ecommerce: null });\n w.dataLayer.push({ event, ...params });\n }\n } catch (error) {\n console.error('[SDK GTM] Error:', error);\n }\n}\n/* eslint-enable @typescript-eslint/no-explicit-any */\n\n// ===========================================================================\n// Pixel initialization (browser-only)\n// All pixel globals are accessed via `win` typed as `any` to avoid\n// `declare global` augmentation issues across tsconfig scopes.\n// ===========================================================================\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\nconst win = (typeof window !== 'undefined' ? window : undefined) as any;\n\nconst SCRIPT_LOAD_TIMEOUT_MS = 5000;\n\nfunction waitForScriptLoad(script: HTMLScriptElement): Promise<void> {\n // If the script has already loaded, resolve immediately\n if (script.dataset.loaded) return Promise.resolve();\n\n return new Promise((resolve) => {\n const done = () => { script.dataset.loaded = '1'; clearTimeout(timer); resolve(); };\n const timer = setTimeout(done, SCRIPT_LOAD_TIMEOUT_MS);\n script.addEventListener('load', done, { once: true });\n script.addEventListener('error', done, { once: true });\n });\n}\n\nlet _metaScriptEl: HTMLScriptElement | null = null;\n\nfunction initMetaPixel(pixelId: string): Promise<void> {\n if (!win) return Promise.resolve();\n\n // Initialize Meta base code once\n if (!win.fbq) {\n const n = function (...args: any[]) {\n if (n.callMethod) n.callMethod(...args); else n.queue.push(args);\n } as any;\n n.queue = [];\n n.loaded = true;\n n.version = '2.0';\n win.fbq = n;\n if (!win._fbq) win._fbq = n;\n const t = document.createElement('script') as HTMLScriptElement;\n t.async = true;\n t.src = 'https://connect.facebook.net/en_US/fbevents.js';\n const s = document.getElementsByTagName('script')[0];\n s?.parentNode?.insertBefore(t, s);\n _metaScriptEl = t;\n }\n\n // Register each pixel ID (fbq supports multiple pixels via multiple init calls)\n win.fbq('init', pixelId);\n return _metaScriptEl ? waitForScriptLoad(_metaScriptEl) : Promise.resolve();\n}\n\nlet _tiktokBaseInitialized = false;\n\nfunction initTikTokPixel(pixelId: string): Promise<void> {\n if (!win) return Promise.resolve();\n\n // Initialize TikTok base code once\n if (!_tiktokBaseInitialized) {\n _tiktokBaseInitialized = true;\n win.TiktokAnalyticsObject = 'ttq';\n const ttq = (win.ttq = win.ttq || []) as any;\n ttq.methods = [\n 'page', 'track', 'identify', 'instances', 'debug', 'on', 'off',\n 'once', 'ready', 'alias', 'group', 'enableCookie', 'disableCookie',\n 'holdConsent', 'revokeConsent', 'grantConsent',\n ];\n ttq.setAndDefer = function (t: any, e: string) {\n t[e] = function (...args: any[]) { t.push([e, ...args]); };\n };\n for (const method of ttq.methods) {\n ttq.setAndDefer(ttq, method);\n }\n ttq.instance = function (t: string) {\n const e = ttq._i[t] || [];\n for (const method of ttq.methods) {\n ttq.setAndDefer(e, method);\n }\n return e;\n };\n ttq.load = function (e: string, n?: any) {\n const r = 'https://analytics.tiktok.com/i18n/pixel/events.js';\n ttq._i = ttq._i || {};\n ttq._i[e] = [];\n ttq._i[e]._u = r;\n ttq._t = ttq._t || {};\n ttq._t[e] = +new Date();\n ttq._o = ttq._o || {};\n ttq._o[e] = n || {};\n const s = document.createElement('script') as HTMLScriptElement;\n s.type = 'text/javascript';\n s.async = true;\n s.src = r + '?sdkid=' + e + '&lib=ttq';\n const p = document.getElementsByTagName('script')[0];\n p?.parentNode?.insertBefore(s, p);\n };\n }\n\n // Skip if this specific pixel ID is already registered\n if (win.ttq._i?.[pixelId]) return Promise.resolve();\n\n // Register pixel and load its script\n win.ttq.load(pixelId);\n\n // Find the script we just created and wait for it\n const scripts = document.querySelectorAll<HTMLScriptElement>(\n 'script[src*=\"analytics.tiktok.com/i18n/pixel/events.js\"]'\n );\n const lastScript = scripts[scripts.length - 1];\n return lastScript ? waitForScriptLoad(lastScript) : Promise.resolve();\n}\n\nlet _snapchatScriptEl: HTMLScriptElement | null = null;\n\nfunction initSnapchatPixel(pixelId: string): Promise<void> {\n if (!win) return Promise.resolve();\n\n // Initialize Snapchat base code once\n if (!win.snaptr) {\n const a = function (...args: any[]) {\n if (a.handleRequest) a.handleRequest(...args); else a.queue.push(args);\n } as any;\n a.queue = [];\n win.snaptr = a;\n const r = document.createElement('script') as HTMLScriptElement;\n r.async = true;\n r.src = 'https://sc-static.net/scevent.min.js';\n const u = document.getElementsByTagName('script')[0];\n u?.parentNode?.insertBefore(r, u);\n _snapchatScriptEl = r;\n }\n\n // Register each pixel ID (snaptr supports multiple pixels via multiple init calls)\n win.snaptr('init', pixelId);\n return _snapchatScriptEl ? waitForScriptLoad(_snapchatScriptEl) : Promise.resolve();\n}\n\nlet _pinterestScriptEl: HTMLScriptElement | null = null;\n\nfunction initPinterestPixel(pixelId: string): Promise<void> {\n if (!win) return Promise.resolve();\n\n // Initialize Pinterest base code once\n if (!win.pintrk) {\n const a = function (...args: any[]) { a.queue.push(args); } as any;\n a.queue = [];\n win.pintrk = a;\n const s = document.createElement('script') as HTMLScriptElement;\n s.async = true;\n s.src = 'https://s.pinimg.com/ct/core.js';\n const u = document.getElementsByTagName('script')[0];\n u?.parentNode?.insertBefore(s, u);\n _pinterestScriptEl = s;\n }\n\n // Register each pixel ID (pintrk supports multiple pixels via multiple load calls)\n win.pintrk('load', pixelId);\n // Note: pintrk('page') is NOT called here \u2014 the auto page-view fires via fire().\n return _pinterestScriptEl ? waitForScriptLoad(_pinterestScriptEl) : Promise.resolve();\n}\n\n/**\n * Load the Microsoft Clarity tag for one project.\n *\n * Mirrors the vendor snippet: a queueing stub so `clarity(...)` calls made\n * before the script lands are replayed, then the tag itself. Clarity ignores a\n * second project on the same page, so a project already present is a no-op.\n */\nfunction initClarity(projectId: string): Promise<void> {\n if (!win || !projectId) return Promise.resolve();\n if (document.querySelector(`script[src*=\"clarity.ms/tag/${projectId}\"]`)) return Promise.resolve();\n\n if (!win.clarity) {\n const q = function (...args: any[]) { q.q.push(args); } as any;\n q.q = [];\n win.clarity = q;\n }\n\n const s = document.createElement('script') as HTMLScriptElement;\n s.async = true;\n s.src = `https://www.clarity.ms/tag/${projectId}`;\n const first = document.getElementsByTagName('script')[0];\n if (first?.parentNode) first.parentNode.insertBefore(s, first);\n else (document.head || document.getElementsByTagName('head')[0])?.appendChild(s);\n\n return waitForScriptLoad(s);\n}\n\nfunction initGTM(containerId: string): Promise<void> {\n if (!win || !containerId) return Promise.resolve();\n const isGtmContainer = containerId.startsWith('GTM-');\n const scriptUrlPart = isGtmContainer\n ? `googletagmanager.com/gtm.js?id=${containerId}`\n : `googletagmanager.com/gtag/js?id=${containerId}`;\n if (document.querySelector(`script[src*=\"${scriptUrlPart}\"]`)) return Promise.resolve();\n\n win.dataLayer = win.dataLayer || [];\n\n // Push referrer domain context into dataLayer before GTM loads, so tags\n // inside the container can use it for cross-domain tracking configuration.\n try {\n const ref = document.referrer && new URL(document.referrer).hostname;\n if (ref && ref !== window.location.hostname) {\n win.dataLayer.push({ tagada_referrer_domain: ref });\n }\n } catch { /* ignore invalid referrer */ }\n\n if (isGtmContainer) {\n win.dataLayer.push({ 'gtm.start': new Date().getTime(), event: 'gtm.js' });\n const f = document.getElementsByTagName('script')[0];\n const j = document.createElement('script') as HTMLScriptElement;\n j.async = true;\n j.src = 'https://www.googletagmanager.com/gtm.js?id=' + containerId;\n if (f?.parentNode) f.parentNode.insertBefore(j, f);\n else (document.head || document.getElementsByTagName('head')[0])?.appendChild(j);\n const noscript = document.createElement('noscript');\n const iframe = document.createElement('iframe');\n iframe.src = `https://www.googletagmanager.com/ns.html?id=${containerId}`;\n iframe.height = '0'; iframe.width = '0';\n iframe.style.display = 'none'; iframe.style.visibility = 'hidden';\n noscript.appendChild(iframe);\n (document.body || document.getElementsByTagName('body')[0])?.insertBefore(noscript, document.body?.firstChild ?? null);\n return waitForScriptLoad(j);\n } else {\n if (!win.gtag) {\n win.gtag = function (..._args: any[]) { win.dataLayer.push(arguments); };\n }\n win.gtag('js', new Date());\n\n // Enable cross-domain tracking: accept incoming _gl parameter from referring\n // domains (e.g. Shopify store \u2192 TagadaPay checkout) so Google preserves the\n // client-id/session across the redirect.\n const linkerConfig: Record<string, unknown> = { accept_incoming: true };\n try {\n const ref = document.referrer && new URL(document.referrer).hostname;\n if (ref && ref !== window.location.hostname) {\n linkerConfig.domains = [ref, window.location.hostname];\n }\n } catch { /* ignore invalid referrer */ }\n\n win.gtag('config', containerId, { linker: linkerConfig });\n const script = document.createElement('script') as HTMLScriptElement;\n script.async = true;\n script.src = 'https://www.googletagmanager.com/gtag/js?id=' + containerId;\n const firstScript = document.getElementsByTagName('script')[0];\n if (firstScript?.parentNode) firstScript.parentNode.insertBefore(script, firstScript);\n else (document.head || document.getElementsByTagName('head')[0])?.appendChild(script);\n return waitForScriptLoad(script);\n }\n}\n/* eslint-enable @typescript-eslint/no-explicit-any */\n\n// ---------------------------------------------------------------------------\n// Tracker factory\n// ---------------------------------------------------------------------------\n\n// ---------------------------------------------------------------------------\n// Config sanitisation (TAG-1871)\n// ---------------------------------------------------------------------------\n\n/** Longest ID we accept \u2014 real IDs top out around 20 chars. */\nconst MAX_PIXEL_ID_LENGTH = 64;\n\n/**\n * The only shape any supported pixel / container / project ID takes: Meta\n * digits, TikTok alphanumerics, Snapchat alphanumerics + dashes, Pinterest\n * digits, Clarity project ids and `GTM-`/`AW-`/`G-` containers are all drawn\n * from `[A-Za-z0-9_-]`.\n */\nconst SAFE_PIXEL_ID_PATTERN = new RegExp(`^[A-Za-z0-9_-]{1,${MAX_PIXEL_ID_LENGTH}}$`);\n\n/** True when `value` is a single, well-formed pixel / container ID. */\nexport function isSafePixelId(value: unknown): value is string {\n return typeof value === 'string' && SAFE_PIXEL_ID_PATTERN.test(value.trim());\n}\n\n/**\n * Trim every pixel/container ID and DROP the ones that aren't plausibly IDs.\n *\n * The trim keeps per-pixel event targeting (TikTok `ttq.instance`) working when\n * the CRM stored stray whitespace. The drop is the load-bearing part: a\n * merchant once pasted a whole TikTok `<script>` snippet into the Pixel ID\n * field, the CRM split it on every comma into 56 \"pixels\", and handing those\n * fragments to `ttq.load()` sent TikTok's SDK into a hot loop that pinned the\n * renderer at 100% CPU *before first paint* \u2014 a blank checkout for days.\n *\n * The CRM now rejects such values at input, but this guard is deliberately\n * independent: it neutralises configs that are ALREADY polluted, on pages that\n * were baked before the fix, with no data migration and no re-publish.\n */\nfunction sanitizePixels(pixels: PixelsConfig): PixelsConfig {\n const out: Record<string, PixelConfig[]> = {};\n const dropped: unknown[] = [];\n\n for (const [provider, list] of Object.entries(pixels)) {\n if (!Array.isArray(list)) continue;\n const kept: PixelConfig[] = [];\n for (const px of list) {\n // GTM keys off containerId, Clarity off projectId, everyone else pixelId.\n const key = pixelIdKeyOf(px);\n const raw = (px as unknown as Record<string, unknown>)?.[key];\n if (!isSafePixelId(raw)) {\n dropped.push(raw);\n continue;\n }\n kept.push({ ...px, [key]: (raw as string).trim() } as PixelConfig);\n }\n out[provider] = kept;\n }\n\n if (dropped.length > 0) {\n console.warn(\n `[SDK Pixels] Ignored ${dropped.length} malformed pixel ID(s) \u2014 tracking for those entries is disabled.`,\n dropped,\n );\n }\n return out as PixelsConfig;\n}\n\n/**\n * Resolve once the browser has had a chance to paint.\n *\n * Third-party pixel SDKs run arbitrary vendor code on the main thread and can\n * stall it (TikTok's did, indefinitely \u2014 TAG-1871). Injecting them before first\n * paint turns any such stall into a blank page. Deferring past the first frame\n * means the worst case degrades to \"no tracking\" instead of \"no checkout\".\n *\n * Double-rAF is the standard \"after paint\" signal. The timer is a fallback for\n * backgrounded tabs (where rAF may never fire) and for non-browser environments\n * that expose a `window` without `requestAnimationFrame`.\n */\nconst PAINT_FALLBACK_MS = 1500;\n\nfunction afterFirstPaint(): Promise<void> {\n if (typeof window === 'undefined') return Promise.resolve();\n return new Promise<void>((resolve) => {\n let settled = false;\n const finish = () => {\n if (settled) return;\n settled = true;\n clearTimeout(fallback);\n resolve();\n };\n const raf: ((cb: () => void) => void) | undefined =\n typeof win?.requestAnimationFrame === 'function'\n ? win.requestAnimationFrame.bind(win)\n : undefined;\n const fallback = setTimeout(finish, raf ? PAINT_FALLBACK_MS : 0);\n if (raf) raf(() => raf(finish));\n });\n}\n\n/**\n * Create a pixel tracker for a given pixels config.\n * Kicks off pixel script init once the first frame has painted, fires PageView\n * when init resolves, and returns a `track()` function that no-ops until then.\n */\nexport function createPixelTracker(rawPixels: PixelsConfig | undefined, opts?: { autoPageView?: boolean }): PixelTracker {\n const pixels = rawPixels ? sanitizePixels(rawPixels) : rawPixels;\n const shouldTrackEvent = createDuplicateGuard(5000);\n let pixelsInitialized = false;\n\n const initPromise: Promise<void> = (async () => {\n if (!pixels || typeof window === 'undefined') return;\n\n // Never inject a third-party tag before the page has painted (TAG-1871).\n await afterFirstPaint();\n\n const loadPromises: Promise<void>[] = [];\n try {\n pixels.facebook?.forEach((px) => { if (px.enabled && px.pixelId) loadPromises.push(initMetaPixel(px.pixelId)); });\n pixels.tiktok?.forEach((px) => { if (px.enabled && px.pixelId) loadPromises.push(initTikTokPixel(px.pixelId)); });\n pixels.snapchat?.forEach((px) => { if (px.enabled && px.pixelId) loadPromises.push(initSnapchatPixel(px.pixelId)); });\n pixels.pinterest?.forEach((px) => { if (px.enabled && px.pixelId) loadPromises.push(initPinterestPixel(px.pixelId)); });\n pixels.gtm?.forEach((px) => { if (px.enabled && (px as GTMTrackingConfig).containerId) loadPromises.push(initGTM((px as GTMTrackingConfig).containerId)); });\n pixels.clarity?.forEach((px) => { if (px.enabled && (px as ClarityTrackingConfig).projectId) loadPromises.push(initClarity((px as ClarityTrackingConfig).projectId)); });\n await Promise.all(loadPromises);\n } catch (error) {\n console.error('[SDK Pixels] Initialization error:', error);\n }\n pixelsInitialized = true;\n })();\n\n // Advanced matching: feed customer identity to Meta (fbq init, raw \u2014 Meta\n // hashes), Snapchat (re-init, hashed) + TikTok (identify, hashed). Applied\n // once per identity and cached, so repeated track()/identify() calls don't\n // re-apply. Each provider persists the match keys onto every subsequent\n // event it fires, so calling this as soon as the email is known lifts match\n // quality on InitiateCheckout + Purchase alike. `_identityReady` is awaited\n // before Snap/TikTok events fire so the hashed keys are attached in time.\n let _identityKey: string | null = null;\n let _identityReady: Promise<void> | null = null;\n\n const applyIdentity = (id: PixelRawIdentity): Promise<void> | null => {\n if (!pixels) return null;\n if (!id.email && !id.phone && !id.externalId) return null;\n\n const key = `${id.email ?? ''}|${id.phone ?? ''}|${id.externalId ?? ''}`;\n if (_identityKey === key && _identityReady) return _identityReady;\n _identityKey = key;\n\n // Meta takes raw values and hashes in-browser \u2014 apply immediately, no need\n // to await our own hashing (and it works even without SubtleCrypto).\n pixels.facebook?.forEach((px) => {\n if (px.enabled && px.pixelId) applyMetaIdentity(win, px.pixelId, id);\n });\n\n // Google Ads enhanced conversions: gtag('set','user_data') persists onto\n // every subsequent gtag event, including the send_to conversion. Raw values,\n // Google hashes in-browser (same rationale as Meta).\n if (pixels.gtm?.some((px) => px.enabled)) {\n applyGoogleIdentity(win, { email_address: id.email, phone_number: id.phone });\n }\n\n // Snapchat + TikTok want pre-hashed SHA-256 values, which we compute\n // ourselves so raw PII never leaves the page. Skips when no secure context.\n if (!canHashIdentity()) return (_identityReady = Promise.resolve());\n\n // Always resolves (errors are swallowed) so deferred event fires never hang.\n _identityReady = (async () => {\n try {\n const hashed = await buildHashedIdentity(id);\n pixels.snapchat?.forEach((px) => {\n if (px.enabled && px.pixelId) applySnapchatIdentity(win, px.pixelId, hashed);\n });\n pixels.tiktok?.forEach((px) => {\n if (px.enabled && px.pixelId) applyTikTokIdentity(win, px.pixelId, hashed);\n });\n } catch (error) {\n console.error('[SDK Pixels] identify error:', error);\n }\n })();\n return _identityReady;\n };\n\n // Derive identity from the GA4 enrichment the thank-you page already attaches\n // (`_ga4.user_data`), so Purchase events get advanced matching with no\n // call-site changes. Returns the readiness promise, or null when absent.\n const applyIdentityFromParams = (\n parameters: Record<string, unknown>,\n ): Promise<void> | null => {\n const ga4 = parameters[GA4_PARAM_KEY] as Ga4PurchasePayload | undefined;\n const ud = ga4?.user_data;\n if (!ud) return null;\n // Google enhanced conversions get the FULL user_data (incl. address) here,\n // richer than the email/phone identity below \u2014 and this runs synchronously\n // before the gtag('event') fires in track(), which is what Google requires.\n // Bypasses the identity dedup on purpose: gtag('set') is idempotent and the\n // address may not have been known at identify() time.\n if (pixels?.gtm?.some((px) => px.enabled)) applyGoogleIdentity(win, ud);\n return applyIdentity({\n email: ud.email_address,\n phone: ud.phone_number,\n externalId: ga4?.user_id,\n });\n };\n\n const track = (\n eventName: StandardPixelEvent,\n parameters: Record<string, unknown> = {},\n options: TrackOptions = {},\n ): void => {\n if (!pixels || !pixelsInitialized) return;\n if (!shouldTrackEvent(eventName, parameters, options.eventId)) return;\n\n try {\n // Apply advanced matching before firing so Snap/TikTok carry the match\n // keys on this event. Other providers fire immediately (unaffected).\n const identityReady = applyIdentityFromParams(parameters);\n\n const events = resolvePixelEvents(pixels, eventName, parameters);\n // Deduplicate by provider: the Snapchat/Pinterest SDKs broadcast to all\n // registered pixel IDs internally, so we only need to fire once per\n // provider. GTM, TikTok and Meta need per-pixel firing (GTM for Google Ads\n // send_to targeting, TikTok because ttq.instance() targets a specific\n // pixel, Meta because fbq('trackSingle') does \u2014 relying on Meta's\n // broadcast instead leaked our events onto pixels a pasted script had\n // initialised).\n const firedProviders = new Set<string>();\n // Per-pixel providers still need per-pixel dedup: a merchant field of\n // \"123;123\" expands into two entries with the same id (splitPixelConfig),\n // which would otherwise fire the same event twice at the same pixel.\n const firedPixels = new Set<string>();\n for (const { provider, mapped, pixel } of events) {\n // Gate Snap/TikTok on identity application (when present) so the match\n // keys are set first; a few ms of deferral, only for those providers.\n const emit =\n identityReady && (provider === 'snapchat' || provider === 'tiktok')\n ? (fn: () => void) => { identityReady.then(fn); }\n : (fn: () => void) => { fn(); };\n\n if (provider === 'gtm' || provider === 'tiktok' || provider === 'facebook') {\n const pixelKey = `${provider}:${pixelIdOf(pixel) ?? ''}`;\n if (firedPixels.has(pixelKey)) continue;\n firedPixels.add(pixelKey);\n emit(() => fire(provider, mapped.name, mapped.params, pixel, options));\n } else {\n if (!firedProviders.has(provider)) {\n emit(() => fire(provider, mapped.name, mapped.params, undefined, options));\n firedProviders.add(provider);\n }\n }\n }\n } catch (error) {\n console.error('[SDK Pixels] Tracking error:', error);\n }\n };\n\n // Auto page-view: fire once after init resolves.\n if (opts?.autoPageView !== false) initPromise.then(() => {\n if (typeof window === 'undefined') return;\n track('PageView', { path: window.location.pathname });\n });\n\n return {\n initPromise,\n get pixelsInitialized() { return pixelsInitialized; },\n track,\n identify: (identity: PixelRawIdentity) => { applyIdentity(identity); },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Window bootstrap\n// ---------------------------------------------------------------------------\n\ndeclare global {\n interface Window {\n __TGD_PIXEL_TRACKER__?: PixelTracker;\n __TGD_STEP_CONFIG__?: string | Record<string, unknown>;\n }\n}\n\nfunction readPixelsFromStepConfig(): PixelsConfig | undefined {\n if (typeof window === 'undefined') return undefined;\n const raw = window.__TGD_STEP_CONFIG__;\n if (!raw) return undefined;\n try {\n const parsed = typeof raw === 'string' ? JSON.parse(raw) : raw;\n const pixels = (parsed as { pixels?: PixelsConfig })?.pixels;\n return pixels && typeof pixels === 'object' ? pixels : undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * One-shot bootstrap: reads `window.__TGD_STEP_CONFIG__.pixels`, creates a\n * tracker, kicks off init, and stashes it on `window.__TGD_PIXEL_TRACKER__`.\n *\n * Idempotent \u2014 both the islands SDK and the full-SPA runtime may call this,\n * but only the first call creates a tracker. Returns the active tracker\n * (existing or newly created), or null if there's no window or no pixels.\n */\nexport function bootstrapPixelTrackerFromWindow(): PixelTracker | null {\n if (typeof window === 'undefined') return null;\n if (window.__TGD_PIXEL_TRACKER__) return window.__TGD_PIXEL_TRACKER__;\n\n const pixels = readPixelsFromStepConfig();\n if (!pixels) return null;\n\n const tracker = createPixelTracker(pixels);\n window.__TGD_PIXEL_TRACKER__ = tracker;\n return tracker;\n}\n", "/**\n * The browser pixel engine.\n *\n * It wraps the lifted `createPixelTracker` with three things the hosted runtime\n * does not need: it stays inert until `init()`, it gates every fire on the\n * per-step configuration served by the SDK config route, and it reports what it\n * could not do (a pixel already on the page, a pixel blocked by the CSP).\n */\nimport type { PixelRawIdentity } from './pixelIdentity.js';\nimport { pixelIdKeyOf } from './pixelMapping.js';\nimport type { PixelProviderKey, StandardPixelEvent } from './pixelMapping.js';\nimport { createPixelTracker, isSafePixelId } from './pixelTracker.js';\nimport type { PixelTracker } from './pixelTracker.js';\nimport type { PixelConfig, PixelsConfig } from './types.js';\n\nexport type PixelSignalKind = 'pixel_blocked' | 'pixel_duplicate';\nexport interface PixelSignal { kind: PixelSignalKind; provider: PixelProviderKey; detail: Record<string, string> }\nexport type SdkPixelProvider = 'facebook' | 'tiktok' | 'snapchat' | 'gtm' | 'clarity';\nexport const SDK_PIXEL_PROVIDERS: readonly SdkPixelProvider[] = ['facebook', 'tiktok', 'snapchat', 'gtm', 'clarity'];\n\nexport interface PixelEngineConfig {\n pixels: PixelsConfig;\n /** Keyed by the MANIFEST step id (`sdk_steps.key`, e.g. `paywall`) \u2014 the id the merchant passes to\n `track.step()` \u2014 never the `sdkstep_\u2026` node id. R4 re-keys onto it server-side (contract \u00A76). */\n steps?: Record<string, { type?: string; events: Record<string, PixelProviderKey[]> }>;\n checkout?: { InitiateCheckout?: PixelProviderKey[]; Purchase?: PixelProviderKey[] };\n requireConsent?: boolean;\n onSignal?: (signal: PixelSignal) => void;\n}\n\nexport interface PixelEngine {\n init(): Promise<void>;\n pageView(path: string, options?: { stepId?: string }): void;\n track(event: StandardPixelEvent, data?: Record<string, unknown>, options?: { eventId?: string; stepId?: string }): void;\n trackCustom(name: string, data?: Record<string, unknown>, options?: { stepId?: string }): void;\n identify(identity: PixelRawIdentity): void;\n consent(state: { marketing: boolean }): void;\n destroy(): void;\n}\n\n/** The single origin each provider's loader fetches its script from; the drift test pins it. */\nexport const SCRIPT_ORIGINS: Record<SdkPixelProvider, string> = {\n facebook: 'https://connect.facebook.net', tiktok: 'https://analytics.tiktok.com',\n snapchat: 'https://sc-static.net', gtm: 'https://www.googletagmanager.com',\n clarity: 'https://www.clarity.ms',\n};\n\n/** The global a provider's own script installs; its presence means a second tag is on the page. */\nconst PROVIDER_GLOBALS: Record<SdkPixelProvider, string> = {\n facebook: 'fbq', tiktok: 'ttq', snapchat: 'snaptr', gtm: 'dataLayer', clarity: 'clarity',\n};\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\ntype VendorWindow = Record<string, any>;\n/* eslint-enable @typescript-eslint/no-explicit-any */\n\nconst QUEUE_LIMIT = 50;\n/** Same window as the SDK's own step dedup: React StrictMode double-renders, nothing more. */\nconst PAGE_VIEW_DEDUP_MS = 1000;\n\nfunction isSdkProvider(provider: string): provider is SdkPixelProvider {\n return (SDK_PIXEL_PROVIDERS as readonly string[]).includes(provider);\n}\n\n/** The five SDK providers and nothing else, copied key by key: a spread would carry `pinterest` through. */\nfunction filterPixels(pixels: PixelsConfig): PixelsConfig {\n const out: PixelsConfig = {};\n if (pixels.facebook) out.facebook = pixels.facebook;\n if (pixels.tiktok) out.tiktok = pixels.tiktok;\n if (pixels.snapchat) out.snapchat = pixels.snapchat;\n if (pixels.gtm) out.gtm = pixels.gtm;\n if (pixels.clarity) out.clarity = pixels.clarity;\n return out;\n}\n\nfunction entriesOf(pixels: PixelsConfig, provider: SdkPixelProvider): PixelConfig[] {\n const list = (pixels as Record<string, PixelConfig[] | undefined>)[provider];\n return Array.isArray(list) ? list : [];\n}\n\nfunction usableIdOf(pixel: PixelConfig): string | null {\n const value = (pixel as unknown as Record<string, unknown>)[pixelIdKeyOf(pixel)];\n return isSafePixelId(value) ? value.trim() : null;\n}\n\nexport function createPixelEngine(config: PixelEngineConfig): PixelEngine {\n const pixels = filterPixels(config.pixels);\n const trackers = new Map<SdkPixelProvider, PixelTracker>();\n /** `stepId|path` \u2192 when it last fired. A window, not a page-lifetime latch: an SPA that comes\n back to a step later in the session must count as a second page view. */\n const seen = new Map<string, number>();\n const signalled = new Set<string>();\n const queue: Array<() => void> = [];\n let granted = config.requireConsent !== true;\n let latchedOff = false;\n let started = false;\n let cspHandler: ((event: Event) => void) | null = null;\n\n const signal = (kind: PixelSignalKind, provider: SdkPixelProvider, detail: Record<string, string>): void => {\n const key = `${provider}|${kind}`;\n if (signalled.has(key)) return;\n signalled.add(key);\n try { config.onSignal?.({ kind, provider, detail }); } catch { /* a consumer callback never breaks a page */ }\n };\n\n const configuredProviders = (): SdkPixelProvider[] =>\n SDK_PIXEL_PROVIDERS.filter((provider) => entriesOf(pixels, provider).length > 0);\n\n const gateFor = (event: string, stepId?: string): SdkPixelProvider[] => {\n const raw = event === 'InitiateCheckout' || event === 'Purchase'\n ? config.checkout?.[event] ?? []\n : config.steps?.[stepId ?? '']?.events?.[event] ?? [];\n return raw.filter(isSdkProvider);\n };\n\n const detectDuplicates = (win: VendorWindow): void => {\n for (const provider of configuredProviders()) {\n const host = typeof win.location?.host === 'string' ? win.location.host : '';\n if (provider === 'gtm') {\n const loaded = win.google_tag_manager;\n const clash = entriesOf(pixels, 'gtm').some((px) => {\n const id = usableIdOf(px);\n return id !== null && loaded?.[id] !== undefined;\n });\n if (clash) signal('pixel_duplicate', 'gtm', { origin: host });\n continue;\n }\n if (win[PROVIDER_GLOBALS[provider]] !== undefined) signal('pixel_duplicate', provider, { origin: host });\n }\n };\n\n const watchCsp = (win: VendorWindow): void => {\n cspHandler = (event: Event): void => {\n const violation = event as SecurityPolicyViolationEvent;\n const blocked = typeof violation.blockedURI === 'string' ? violation.blockedURI : '';\n for (const provider of SDK_PIXEL_PROVIDERS) {\n if (!blocked.startsWith(SCRIPT_ORIGINS[provider])) continue;\n signal('pixel_blocked', provider, { reason: 'csp', directive: violation.violatedDirective ?? '' });\n return;\n }\n };\n win.addEventListener('securitypolicyviolation', cspHandler);\n };\n\n const enqueue = (run: () => void): void => {\n if (latchedOff) return;\n if (queue.length >= QUEUE_LIMIT) queue.shift();\n queue.push(run);\n };\n\n const guardEventId = (eventId: string): boolean => {\n try { if (sessionStorage.getItem(`__tgd_px:${eventId}`)) return false; } catch { /* private mode */ }\n return true;\n };\n\n const markEventId = (eventId: string): void => {\n try { sessionStorage.setItem(`__tgd_px:${eventId}`, '1'); } catch { /* private mode */ }\n };\n\n const engine: PixelEngine = {\n async init(): Promise<void> {\n if (started || typeof window === 'undefined') return;\n if (!granted) return;\n started = true;\n const win = window as unknown as VendorWindow;\n detectDuplicates(win);\n watchCsp(win);\n const ready: Promise<void>[] = [];\n for (const provider of configuredProviders()) {\n // One tracker per provider: the lifted tracker fires to every provider of its own\n // config, so a per-provider gate needs a per-provider tracker.\n const tracker = createPixelTracker({ [provider]: entriesOf(pixels, provider) } as PixelsConfig, { autoPageView: false });\n trackers.set(provider, tracker);\n ready.push(tracker.initPromise);\n }\n // `track()` no-ops until `pixelsInitialized` flips, which only happens when these settle.\n await Promise.all(ready);\n },\n\n pageView(path, options): void {\n if (typeof window === 'undefined') return;\n if (!granted) { enqueue(() => engine.pageView(path, options)); return; }\n const key = `${options?.stepId ?? ''}|${path}`;\n const now = Date.now();\n const previous = seen.get(key);\n if (previous !== undefined && now - previous < PAGE_VIEW_DEDUP_MS) return;\n for (const [other, when] of seen) if (now - when >= PAGE_VIEW_DEDUP_MS) seen.delete(other);\n seen.set(key, now);\n const allowed = gateFor('PageView', options?.stepId);\n if (allowed.length === 0) return;\n // A per-step id, and a per-fire one: two steps on one path would otherwise collapse into a\n // single fire inside the tracker's own 5 s duplicate guard, and so would a genuine return\n // to the same step later in the session.\n for (const provider of allowed) trackers.get(provider)?.track('PageView', { path }, { eventId: `PageView_${key}|${now}` });\n },\n\n track(event, data, options): void {\n if (typeof window === 'undefined') return;\n if (!granted) { enqueue(() => engine.track(event, data, options)); return; }\n if (event === 'InitiateCheckout' || event === 'Purchase') {\n if (!options?.eventId) return;\n if (!guardEventId(options.eventId)) return;\n }\n const allowed = gateFor(event, options?.stepId);\n if (allowed.length === 0) return;\n for (const provider of allowed) {\n trackers.get(provider)?.track(event, data ?? {}, options?.eventId ? { eventId: options.eventId } : undefined);\n }\n if (options?.eventId) markEventId(options.eventId);\n },\n\n trackCustom(name, data, options): void {\n if (typeof window === 'undefined') return;\n if (!granted) { enqueue(() => engine.trackCustom(name, data, options)); return; }\n const win = window as unknown as VendorWindow;\n const params = data ?? {};\n for (const provider of gateFor(name, options?.stepId)) {\n for (const px of entriesOf(pixels, provider)) {\n if (!px.enabled) continue;\n const id = usableIdOf(px);\n if (id === null) continue;\n switch (provider) {\n // `trackSingle` with a custom name is read by Meta as an unknown standard event.\n case 'facebook': win.fbq?.('trackSingleCustom', id, name, params); break;\n case 'tiktok': win.ttq?.instance?.(id)?.track?.(name, params); break;\n // Snap offers no per-pixel target: the global broadcasts to every Snap pixel.\n case 'snapchat': win.snaptr?.('track', name, params); break;\n case 'gtm': win.gtag?.('event', name, params); break;\n case 'clarity': win.clarity?.('event', name); break;\n }\n }\n }\n },\n\n identify(identity): void {\n if (typeof window === 'undefined') return;\n for (const tracker of trackers.values()) tracker.identify(identity);\n },\n\n consent(state): void {\n if (!state.marketing) { queue.length = 0; latchedOff = true; granted = false; return; }\n if (latchedOff || granted) return;\n granted = true;\n void engine.init().then(() => {\n const pending = queue.splice(0, queue.length);\n for (const run of pending) run();\n });\n },\n\n destroy(): void {\n queue.length = 0;\n if (cspHandler && typeof window !== 'undefined') {\n window.removeEventListener('securitypolicyviolation', cspHandler);\n }\n cspHandler = null;\n trackers.clear();\n },\n };\n\n return engine;\n}\n", "/**\n * Stable event_id helper for Meta CAPI / browser pixel deduplication.\n *\n * The browser side (`fbq('track', name, params, { eventID })`) and the server\n * side (`ServerEvent.setEventId(...)`) must publish the same value to let Meta\n * dedup. This helper is the single source of truth for the formula, mirrored\n * on the server in `src/app/services/meta/meta-event-id.ts`. A parity test in\n * the server package keeps them byte-identical.\n *\n * Convention: `${eventName}_${entityId}`. Different event names get different\n * IDs even when fired for the same entity (e.g. a Purchase + Subscribe pair on\n * the same order), so each dedups independently.\n */\nexport function makeMetaEventId(eventName: string, entityId: string): string {\n return `${eventName}_${entityId}`;\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["pixels_exports", "__export", "SDK_PIXEL_PROVIDERS", "bootstrapPixelTrackerFromWindow", "buildGa4PurchasePayload", "createPixelEngine", "createPixelTracker", "getEligiblePixels", "isEventEnabled", "isSafePixelId", "makeMetaEventId", "pixelIdKeyOf", "resolvePixelEvents", "pixelIdKeyOf", "pixel", "GA4_PARAM_KEY", "extractCouponCodes", "order", "codes", "p", "_a", "c", "buildGa4PurchasePayload", "_b", "_c", "_d", "_e", "_f", "_g", "sourceItems", "coupon", "summary", "s", "itemsSum", "sum", "i", "lineLevelDiscountTotal", "orderLevelDiscount", "remainingAllocation", "items", "item", "index", "quantity", "unitAdjusted", "lineValue", "lineAllocation", "unitAllocation", "unitDiscount", "ga4Item", "value", "payload", "addr", "userData", "phone", "address", "v", "ZERO_DECIMAL_CURRENCIES", "THREE_DECIMAL_CURRENCIES", "minorToMajor", "amount", "currency", "code", "isEventEnabled", "eventName", "events", "getEligiblePixels", "pixels", "ensureCurrencyUppercase", "params", "convertValueToMajor", "major", "convertMonetaryFieldsToMajor", "result", "field", "convertContentsPricesToMajor", "itemCurrency", "converted", "baseTransform", "META_EVENT_MAP", "mapMetaEvent", "parameters", "name", "TIKTOK_EVENT_MAP", "mapTikTokEvent", "ids", "SNAPCHAT_EVENT_MAP", "mapSnapchatEvent", "PINTEREST_EVENT_MAP", "mapPinterestEvent", "GTM_EVENT_MAP", "mapGTMEvent", "ga4", "toMajor", "ecommerce", "out", "CLARITY_EVENT_MAP", "mapClarityEvent", "applyGoogleAdsConversion", "resolvePixelEvents", "results", "fb", "mapped", "tt", "sc", "pt", "clarity", "gtm", "finalParams", "normalizeEmail", "email", "normalizePhone", "phone", "trimmed", "hasPlus", "digits", "sha256Hex", "input", "data", "buf", "b", "canHashIdentity", "buildHashedIdentity", "id", "out", "n", "createDuplicateGuard", "windowMs", "lastEvents", "eventName", "parameters", "eventId", "key", "now", "last", "pixelIdOf", "pixel", "value", "pixelIdKeyOf", "fire", "provider", "name", "params", "options", "_a", "_b", "_c", "_d", "_e", "_f", "_g", "_h", "_i", "_j", "w", "pixelId", "target", "fireGTM", "applySnapchatIdentity", "h", "userInfo", "applyTikTokIdentity", "info", "applyMetaIdentity", "raw", "ud", "d", "applyGoogleIdentity", "userData", "phone", "a", "address", "event", "hasEcommerce", "ecommerce", "rest", "error", "win", "SCRIPT_LOAD_TIMEOUT_MS", "waitForScriptLoad", "script", "resolve", "done", "timer", "_metaScriptEl", "initMetaPixel", "n", "args", "t", "s", "_tiktokBaseInitialized", "initTikTokPixel", "ttq", "e", "method", "r", "p", "scripts", "lastScript", "_snapchatScriptEl", "initSnapchatPixel", "u", "_pinterestScriptEl", "initPinterestPixel", "initClarity", "projectId", "q", "first", "initGTM", "containerId", "isGtmContainer", "scriptUrlPart", "ref", "f", "j", "noscript", "iframe", "_args", "linkerConfig", "firstScript", "MAX_PIXEL_ID_LENGTH", "SAFE_PIXEL_ID_PATTERN", "isSafePixelId", "sanitizePixels", "pixels", "out", "dropped", "list", "kept", "px", "PAINT_FALLBACK_MS", "afterFirstPaint", "settled", "finish", "fallback", "raf", "createPixelTracker", "rawPixels", "opts", "shouldTrackEvent", "pixelsInitialized", "initPromise", "loadPromises", "_identityKey", "_identityReady", "applyIdentity", "id", "canHashIdentity", "hashed", "buildHashedIdentity", "applyIdentityFromParams", "ga4", "GA4_PARAM_KEY", "track", "identityReady", "events", "resolvePixelEvents", "firedProviders", "firedPixels", "mapped", "emit", "fn", "pixelKey", "identity", "readPixelsFromStepConfig", "parsed", "bootstrapPixelTrackerFromWindow", "tracker", "SDK_PIXEL_PROVIDERS", "SCRIPT_ORIGINS", "PROVIDER_GLOBALS", "QUEUE_LIMIT", "PAGE_VIEW_DEDUP_MS", "isSdkProvider", "provider", "filterPixels", "pixels", "out", "entriesOf", "list", "usableIdOf", "pixel", "value", "pixelIdKeyOf", "isSafePixelId", "createPixelEngine", "config", "trackers", "seen", "signalled", "queue", "granted", "latchedOff", "started", "cspHandler", "signal", "kind", "detail", "_a", "key", "configuredProviders", "gateFor", "event", "stepId", "_b", "_c", "_d", "detectDuplicates", "win", "host", "loaded", "px", "id", "watchCsp", "violation", "blocked", "enqueue", "run", "guardEventId", "eventId", "markEventId", "engine", "ready", "tracker", "createPixelTracker", "path", "options", "now", "previous", "other", "when", "allowed", "data", "name", "_e", "_f", "_g", "_h", "params", "identity", "state", "pending", "makeMetaEventId", "eventName", "entityId"]
7
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tagadapay/headless-sdk",
3
- "version": "1.14.1",
3
+ "version": "1.16.0",
4
4
  "description": "Headless SDK for using TagadaPay as a checkout, offers, and CRM backend from any external website",
5
5
  "type": "module",
6
6
  "main": "dist/core/index.js",
@@ -15,15 +15,22 @@
15
15
  "types": "./dist/react/index.d.ts",
16
16
  "import": "./dist/react/index.js",
17
17
  "require": "./dist/react/index.js"
18
+ },
19
+ "./stripe": {
20
+ "types": "./dist/stripe/index.d.ts",
21
+ "import": "./dist/stripe/index.js",
22
+ "require": "./dist/stripe/index.js"
18
23
  }
19
24
  },
20
25
  "scripts": {
26
+ "prebuild": "node scripts/sync-pixels.mjs",
21
27
  "build": "tsc && node build-cdn.js",
22
28
  "build:types": "tsc",
23
29
  "build:cdn": "node build-cdn.js",
24
30
  "clean": "rm -rf dist",
25
31
  "dev": "tsc --watch",
26
32
  "lint": "echo \"No linting configured\"",
33
+ "pretest": "node scripts/sync-pixels.mjs",
27
34
  "test": "vitest run",
28
35
  "prepublishOnly": "npm run clean && npm run build"
29
36
  },