@walkeros/transformer-ga4 4.1.0 → 4.1.1-next-1779485810490
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/dev.js +1 -1
- package/dist/dev.js.map +1 -1
- package/dist/dev.mjs +1 -1
- package/dist/dev.mjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/walkerOS.json +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @walkeros/transformer-ga4
|
|
2
2
|
|
|
3
|
+
## 4.1.1-next-1779485810490
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- b0279ee: Add `extend` and `remove` to mapping rules. `extend` deep-merges a
|
|
8
|
+
partial rule onto a package-shipped default (a `null` value clears an
|
|
9
|
+
inherited field); `remove` strips fields from the produced payload. Rules
|
|
10
|
+
without either keyword keep the existing replace behavior.
|
|
11
|
+
- Updated dependencies [b0279ee]
|
|
12
|
+
- Updated dependencies [b0279ee]
|
|
13
|
+
- @walkeros/core@4.1.1-next-1779485810490
|
|
14
|
+
|
|
3
15
|
## 4.1.0
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/dist/dev.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e,t=Object.defineProperty,a=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.prototype.hasOwnProperty,n=(e,a)=>{for(var r in a)t(e,r,{get:a[r],enumerable:!0})},o={};function c(e){const t={},a=e.indexOf("?");if(-1===a)return t;return new URLSearchParams(e.slice(a+1)).forEach((e,a)=>{t[a]=e}),t}function s(e){return e?e.split(/\r?\n/).map(e=>e.trim()).filter(e=>e.length>0).map(e=>{const t={};return new URLSearchParams(e).forEach((e,a)=>{t[a]=e}),t}):[]}n(o,{defaultMapping:()=>_,examples:()=>E,mapHitToEvents:()=>h,parseBody:()=>s,parseConsent:()=>v,parseItem:()=>l,parseQuery:()=>c,parseRequest:()=>y}),module.exports=(e=o,((e,n,o,c)=>{if(n&&"object"==typeof n||"function"==typeof n)for(let s of r(n))i.call(e,s)||s===o||t(e,s,{get:()=>n[s],enumerable:!(c=a(n,s))||c.enumerable});return e})(t({},"__esModule",{value:!0}),e));var p={id:"id",nm:"name",br:"brand",ca:"category",c2:"category2",c3:"category3",c4:"category4",c5:"category5",va:"variant",cp:"coupon",ln:"listName",li:"listId",lo:"locationId",af:"affiliation",cn:"creativeName",cs:"creativeSlot",pi:"promotionId",pn:"promotionName"},d={pr:"price",qt:"quantity",ds:"discount",lp:"listPosition"};function m(e,t,a){switch(t){case"id":return void(e.id=a);case"name":return void(e.name=a);case"brand":return void(e.brand=a);case"category":return void(e.category=a);case"category2":return void(e.category2=a);case"category3":return void(e.category3=a);case"category4":return void(e.category4=a);case"category5":return void(e.category5=a);case"variant":return void(e.variant=a);case"coupon":return void(e.coupon=a);case"listName":return void(e.listName=a);case"listId":return void(e.listId=a);case"locationId":return void(e.locationId=a);case"affiliation":return void(e.affiliation=a);case"creativeName":return void(e.creativeName=a);case"creativeSlot":return void(e.creativeSlot=a);case"promotionId":return void(e.promotionId=a);case"promotionName":return void(e.promotionName=a)}}function u(e,t,a){switch(t){case"price":return void(e.price=a);case"quantity":return void(e.quantity=a);case"discount":return void(e.discount=a);case"listPosition":return void(e.listPosition=a)}}function l(e){const t={custom:{}},a=new Map,r=new Map;for(const i of e.split("~")){if(0===i.length)continue;const e=/^([kv])(\d+)(.*)$/.exec(i);if(e){const[,t,i,n]=e;"k"===t?a.set(i,n):r.set(i,n);continue}if(i.length<2)continue;const n=i.slice(0,2),o=i.slice(2),c=p[n];if(void 0!==c){m(t,c,o);continue}const s=d[n];if(void 0!==s){const e=Number(o);Number.isNaN(e)||u(t,s,e);continue}}for(const[e,i]of a){const a=r.get(e);void 0!==a&&(t.custom[i]=a)}return t}function v(e){const t=e.gcs;return t&&/^G[01]{3}$/.test(t)?{marketing:"1"===t[2],analytics:"1"===t[3]}:{}}var g=new Set(["v","tid","cid","sid","sct","seg","_p","_z","gtm","dl","dt","dr","ul","sr","uid","_dbg","_s","_ss","_fv","gcs","gcd","dma","dma_cps","npa","p"]);function y(e){const t=c(e.url),a={},r={};for(const[e,i]of Object.entries(t))g.has(e)?a[e]=i:r[e]=i;const i=e.body?s(e.body):[];return{hit:a,events:(i.length>0?i:Object.keys(r).length>0?[r]:[]).filter(e=>"string"==typeof e.en&&e.en.length>0).map(e=>function(e){const t={ep:{},epn:{},up:{},upn:{}},a=[];for(const[r,i]of Object.entries(e)){if("en"===r)continue;const e=/^pr(\d+)$/.exec(r);if(e)a.push([Number(e[1]),i]);else if(r.startsWith("ep."))t.ep[r.slice(3)]=i;else{if(r.startsWith("epn.")){const e=Number(i);Number.isNaN(e)||(t.epn[r.slice(4)]=e);continue}if(r.startsWith("up."))t.up[r.slice(3)]=i;else{if(r.startsWith("upn.")){const e=Number(i);Number.isNaN(e)||(t.upn[r.slice(4)]=e);continue}if("_et"===r){const e=Number(i);Number.isNaN(e)||(t._et=e);continue}"_c"!==r||(t._c=i)}}}a.sort((e,t)=>e[0]-t[0]);const r=a.map(([,e])=>l(e));return{en:e.en,params:t,items:r}}(e))}}var _={page_view:{name:"page view",data:{map:{id:"hit.dl",title:"hit.dt",referrer:"hit.dr"}}},purchase:{name:"order complete",data:{map:{id:"params.ep.transaction_id",currency:"params.ep.currency",total:"params.epn.value",tax:"params.epn.tax",shipping:"params.epn.shipping",coupon:"params.ep.coupon"}}},view_item:{name:"product view",data:{map:{currency:"params.ep.currency",value:"params.epn.value"}}},add_to_cart:{name:"product add",data:{map:{currency:"params.ep.currency",value:"params.epn.value"}}},remove_from_cart:{name:"product remove",data:{map:{currency:"params.ep.currency",value:"params.epn.value"}}},view_cart:{name:"cart view",data:{map:{currency:"params.ep.currency",value:"params.epn.value"}}},begin_checkout:{name:"order start",data:{map:{currency:"params.ep.currency",value:"params.epn.value",coupon:"params.ep.coupon"}}},add_shipping_info:{name:"order shipping",data:{map:{currency:"params.ep.currency",value:"params.epn.value",tier:"params.ep.shipping_tier"}}},add_payment_info:{name:"order payment",data:{map:{currency:"params.ep.currency",value:"params.epn.value",type:"params.ep.payment_type"}}},refund:{name:"order refund",data:{map:{id:"params.ep.transaction_id",currency:"params.ep.currency",total:"params.epn.value"}}},add_to_wishlist:{name:"wishlist add",data:{map:{currency:"params.ep.currency",value:"params.epn.value"}}},view_item_list:{name:"list view",data:{map:{id:"params.ep.item_list_id",name:"params.ep.item_list_name"}}},select_item:{name:"product click",data:{map:{list_id:"params.ep.item_list_id",list_name:"params.ep.item_list_name"}}},view_promotion:{name:"promotion view",data:{map:{id:"firstItem.promotionId",name:"firstItem.promotionName",creative:"firstItem.creativeName",slot:"firstItem.creativeSlot"}}},select_promotion:{name:"promotion click",data:{map:{id:"firstItem.promotionId",name:"firstItem.promotionName",creative:"firstItem.creativeName",slot:"firstItem.creativeSlot"}}},select_content:{name:"content select",data:{map:{type:"params.ep.content_type",id:"params.ep.content_id"}}},scroll:{name:"page scroll",data:{map:{percent:"params.epn.percent_scrolled"}}},click:{name:"link click",data:{map:{url:"params.ep.link_url",domain:"params.ep.link_domain",outbound:"params.ep.outbound"}}},file_download:{name:"file download",data:{map:{name:"params.ep.file_name",extension:"params.ep.file_extension",url:"params.ep.link_url"}}},video_start:{name:"video start",data:{map:{title:"params.ep.video_title",duration:"params.epn.video_duration",current:"params.epn.video_current_time",percent:"params.epn.video_percent"}}},video_progress:{name:"video progress",data:{map:{title:"params.ep.video_title",duration:"params.epn.video_duration",current:"params.epn.video_current_time",percent:"params.epn.video_percent"}}},video_complete:{name:"video complete",data:{map:{title:"params.ep.video_title",duration:"params.epn.video_duration",current:"params.epn.video_current_time",percent:"params.epn.video_percent"}}},form_start:{name:"form start",data:{map:{id:"params.ep.form_id",name:"params.ep.form_name",destination:"params.ep.form_destination"}}},form_submit:{name:"form submit",data:{map:{id:"params.ep.form_id",name:"params.ep.form_name",destination:"params.ep.form_destination"}}},search:{name:"search submit",data:{map:{term:"params.ep.search_term"}}},login:{name:"session login",data:{map:{method:"params.ep.method"}}},sign_up:{name:"session signup",data:{map:{method:"params.ep.method"}}},generate_lead:{name:"lead generate",data:{map:{currency:"params.ep.currency",value:"params.epn.value"}}},share:{name:"content share",data:{map:{method:"params.ep.method",type:"params.ep.content_type",id:"params.ep.item_id"}}},user_engagement:{ignore:!0},session_start:{ignore:!0},first_visit:{ignore:!0},"*":{name:"ga4 track",data:{map:{event_name:"en"}}}},f=require("@walkeros/core");function h(e,t){const a=[];for(const r of e.events){const i=w(e.hit,r,t);i&&a.push(i)}return a}function w(e,t,a){const r=a[t.en]??a["*"];if(!r)return null;const i=Array.isArray(r)?r[0]:r;if(!i||i.ignore)return null;const n={hit:e,params:t.params,items:t.items,en:t.en,...t.items.length>0?{firstItem:t.items[0]}:{}},o={};if(i.name){const[e,...t]=i.name.split(" ");o.name=i.name,o.entity=e,o.action=t.join(" ")}if(void 0!==i.data){const e=b(i.data,n);void 0!==e&&(o.data=e)}o.user={...void 0!==e.uid?{id:e.uid}:{},...void 0!==e.cid?{device:e.cid}:{},...void 0!==e.sid?{session:e.sid}:{}},o.globals={...void 0!==e.ul?{language:e.ul}:{},...void 0!==e.sr?{screen:e.sr}:{}},o.source={type:"ga4",...void 0!==e.p?{platform:e.p}:{}},o.consent=v(e),o.id=e._p??(0,f.getId)();const c=e.sid?Number(e.sid):NaN;return o.timestamp=!Number.isNaN(c)&&c>0?1e3*c:Date.now(),o.timing=t.params._et??0,o.trigger="ga4",t.items.length>0&&(o.nested=t.items.map(e=>{const t={};void 0!==e.id&&(t.id=e.id),void 0!==e.name&&(t.name=e.name),void 0!==e.brand&&(t.brand=e.brand),void 0!==e.category&&(t.category=e.category),void 0!==e.category2&&(t.category2=e.category2),void 0!==e.category3&&(t.category3=e.category3),void 0!==e.category4&&(t.category4=e.category4),void 0!==e.category5&&(t.category5=e.category5),void 0!==e.variant&&(t.variant=e.variant),void 0!==e.price&&(t.price=e.price),void 0!==e.quantity&&(t.quantity=e.quantity),void 0!==e.coupon&&(t.coupon=e.coupon),void 0!==e.discount&&(t.discount=e.discount),void 0!==e.listName&&(t.list_name=e.listName),void 0!==e.listId&&(t.list_id=e.listId),void 0!==e.listPosition&&(t.list_position=e.listPosition),void 0!==e.locationId&&(t.location_id=e.locationId),void 0!==e.affiliation&&(t.affiliation=e.affiliation),void 0!==e.creativeName&&(t.creative_name=e.creativeName),void 0!==e.creativeSlot&&(t.creative_slot=e.creativeSlot),void 0!==e.promotionId&&(t.promotion_id=e.promotionId),void 0!==e.promotionName&&(t.promotion_name=e.promotionName);for(const[a,r]of Object.entries(e.custom))t[a]=r;return{entity:"product",data:t,nested:[],context:{}}})),o}function b(e,t){if(Array.isArray(e))for(const a of e){const e=b(a,t);if(null!=e)return e}else{if("string"==typeof e)return(0,f.getByPath)(t,e);if("object"==typeof e&&null!==e){if("value"in e&&void 0!==e.value)return e.value;if("key"in e&&"string"==typeof e.key)return(0,f.getByPath)(t,e.key);if("map"in e&&e.map){const a={};for(const[r,i]of Object.entries(e.map)){const e=b(i,t);void 0!==e&&(a[r]=e)}return a}}}}var E={};n(E,{step:()=>N});var N={};n(N,{addToCart:()=>G,batchPost:()=>j,beginCheckout:()=>S,consentDenied:()=>U,customEvent:()=>R,login:()=>L,pageView:()=>P,purchase:()=>I,scroll:()=>M,search:()=>x,userEngagementIgnored:()=>X,viewItem:()=>O});var k="1700000000";function A(e){return{id:"p1",timestamp:17e11,timing:0,trigger:"ga4",user:{device:"cid-1",session:k},globals:{},source:{type:"ga4"},consent:{},...e}}var P={title:"Page view",description:"A standard GA4 page_view hit decoded to a walkerOS page view with id, title, and referrer.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+k+"&en=page_view&dl=https%3A%2F%2Fshop.example.com%2Fproducts%2Fsku-123&dt=Trail%20Runner%20Pro&dr=https%3A%2F%2Fshop.example.com%2F"},out:[["return",A({name:"page view",entity:"page",action:"view",data:{id:"https://shop.example.com/products/sku-123",title:"Trail Runner Pro",referrer:"https://shop.example.com/"}})]]},I={title:"Purchase (canary)",description:"A GA4 purchase hit decoded to a walkerOS order complete event with id, currency, total, tax, shipping, and coupon.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+k+"&en=purchase&ep.transaction_id=T-9001&ep.currency=EUR&epn.value=149.97&epn.tax=23.97&epn.shipping=4.95&ep.coupon=WELCOME10"},out:[["return",A({name:"order complete",entity:"order",action:"complete",data:{id:"T-9001",currency:"EUR",total:149.97,tax:23.97,shipping:4.95,coupon:"WELCOME10"}})]]},O={title:"View item",description:"A GA4 view_item hit decoded to a walkerOS product view event with currency and value.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+k+"&en=view_item&ep.currency=EUR&epn.value=129.99"},out:[["return",A({name:"product view",entity:"product",action:"view",data:{currency:"EUR",value:129.99}})]]},G={title:"Add to cart",description:"A GA4 add_to_cart hit decoded to a walkerOS product add event with currency and value.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+k+"&en=add_to_cart&ep.currency=EUR&epn.value=129.99"},out:[["return",A({name:"product add",entity:"product",action:"add",data:{currency:"EUR",value:129.99}})]]},S={title:"Begin checkout",description:"A GA4 begin_checkout hit decoded to a walkerOS order start event with currency, value, and coupon.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+k+"&en=begin_checkout&ep.currency=EUR&epn.value=149.97&ep.coupon=WELCOME10"},out:[["return",A({name:"order start",entity:"order",action:"start",data:{currency:"EUR",value:149.97,coupon:"WELCOME10"}})]]},M={title:"Scroll",description:"A GA4 scroll hit decoded to a walkerOS page scroll event with the percent_scrolled value.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+k+"&en=scroll&epn.percent_scrolled=90"},out:[["return",A({name:"page scroll",entity:"page",action:"scroll",data:{percent:90}})]]},x={title:"Search",description:"A GA4 search hit decoded to a walkerOS search submit event carrying the search term.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+k+"&en=search&ep.search_term=trail%20runner"},out:[["return",A({name:"search submit",entity:"search",action:"submit",data:{term:"trail runner"}})]]},L={title:"Login",description:"A GA4 login hit decoded to a walkerOS session login event with the auth method.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+k+"&en=login&ep.method=google"},out:[["return",A({name:"session login",entity:"session",action:"login",data:{method:"google"}})]]},R={title:"Custom event (* fallback)",description:"Unknown GA4 event names hit the * fallback rule and surface as a ga4 track event carrying the original name.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+k+"&en=newsletter_subscribe&ep.source=footer"},out:[["return",A({name:"ga4 track",entity:"ga4",action:"track",data:{event_name:"newsletter_subscribe"}})]]},U={title:"Consent denied (gcs=G100)",description:"A page_view hit with gcs=G100 still maps, with consent.{marketing,analytics} both false on the resulting event.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+k+"&gcs=G100&en=page_view&dl=https%3A%2F%2Fx&dt=X"},out:[["return",A({name:"page view",entity:"page",action:"view",data:{id:"https://x",title:"X"},consent:{marketing:!1,analytics:!1}})]]},X={title:"user_engagement (ignored)",description:"Auto-fired GA4 user_engagement events are dropped by default — the transformer returns false.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+k+"&en=user_engagement&_et=1500"},out:[["return",!1]]},j={title:"Batched POST (fan-out)",description:"A single POST request carrying two newline-separated events fans out into two walkerOS events.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+k,body:["en=add_to_cart&ep.currency=EUR&epn.value=19.99","en=add_to_cart&ep.currency=EUR&epn.value=29.99"].join("\n")},out:[["return",A({name:"product add",entity:"product",action:"add",data:{currency:"EUR",value:19.99}})],["return",A({name:"product add",entity:"product",action:"add",data:{currency:"EUR",value:29.99}})]]};//# sourceMappingURL=dev.js.map
|
|
1
|
+
"use strict";var e,t=Object.defineProperty,a=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.prototype.hasOwnProperty,n=(e,a)=>{for(var r in a)t(e,r,{get:a[r],enumerable:!0})},o={};function c(e){const t={},a=e.indexOf("?");if(-1===a)return t;return new URLSearchParams(e.slice(a+1)).forEach((e,a)=>{t[a]=e}),t}function s(e){return e?e.split(/\r?\n/).map(e=>e.trim()).filter(e=>e.length>0).map(e=>{const t={};return new URLSearchParams(e).forEach((e,a)=>{t[a]=e}),t}):[]}n(o,{defaultMapping:()=>_,examples:()=>E,mapHitToEvents:()=>h,parseBody:()=>s,parseConsent:()=>v,parseItem:()=>u,parseQuery:()=>c,parseRequest:()=>y}),module.exports=(e=o,((e,n,o,c)=>{if(n&&"object"==typeof n||"function"==typeof n)for(let s of r(n))i.call(e,s)||s===o||t(e,s,{get:()=>n[s],enumerable:!(c=a(n,s))||c.enumerable});return e})(t({},"__esModule",{value:!0}),e));var p={id:"id",nm:"name",br:"brand",ca:"category",c2:"category2",c3:"category3",c4:"category4",c5:"category5",va:"variant",cp:"coupon",ln:"listName",li:"listId",lo:"locationId",af:"affiliation",cn:"creativeName",cs:"creativeSlot",pi:"promotionId",pn:"promotionName"},d={pr:"price",qt:"quantity",ds:"discount",lp:"listPosition"};function m(e,t,a){switch(t){case"id":return void(e.id=a);case"name":return void(e.name=a);case"brand":return void(e.brand=a);case"category":return void(e.category=a);case"category2":return void(e.category2=a);case"category3":return void(e.category3=a);case"category4":return void(e.category4=a);case"category5":return void(e.category5=a);case"variant":return void(e.variant=a);case"coupon":return void(e.coupon=a);case"listName":return void(e.listName=a);case"listId":return void(e.listId=a);case"locationId":return void(e.locationId=a);case"affiliation":return void(e.affiliation=a);case"creativeName":return void(e.creativeName=a);case"creativeSlot":return void(e.creativeSlot=a);case"promotionId":return void(e.promotionId=a);case"promotionName":return void(e.promotionName=a)}}function l(e,t,a){switch(t){case"price":return void(e.price=a);case"quantity":return void(e.quantity=a);case"discount":return void(e.discount=a);case"listPosition":return void(e.listPosition=a)}}function u(e){const t={custom:{}},a=new Map,r=new Map;for(const i of e.split("~")){if(0===i.length)continue;const e=/^([kv])(\d+)(.*)$/.exec(i);if(e){const[,t,i,n]=e;"k"===t?a.set(i,n):r.set(i,n);continue}if(i.length<2)continue;const n=i.slice(0,2),o=i.slice(2),c=p[n];if(void 0!==c){m(t,c,o);continue}const s=d[n];if(void 0!==s){const e=Number(o);Number.isNaN(e)||l(t,s,e);continue}}for(const[e,i]of a){const a=r.get(e);void 0!==a&&(t.custom[i]=a)}return t}function v(e){const t=e.gcs;return t&&/^G[01]{3}$/.test(t)?{marketing:"1"===t[2],analytics:"1"===t[3]}:{}}var g=new Set(["v","tid","cid","sid","sct","seg","_p","_z","gtm","dl","dt","dr","ul","sr","uid","_dbg","_s","_ss","_fv","gcs","gcd","dma","dma_cps","npa","p"]);function y(e){const t=c(e.url),a={},r={};for(const[e,i]of Object.entries(t))g.has(e)?a[e]=i:r[e]=i;const i=e.body?s(e.body):[];return{hit:a,events:(i.length>0?i:Object.keys(r).length>0?[r]:[]).filter(e=>"string"==typeof e.en&&e.en.length>0).map(e=>function(e){const t={ep:{},epn:{},up:{},upn:{}},a=[];for(const[r,i]of Object.entries(e)){if("en"===r)continue;const e=/^pr(\d+)$/.exec(r);if(e)a.push([Number(e[1]),i]);else if(r.startsWith("ep."))t.ep[r.slice(3)]=i;else{if(r.startsWith("epn.")){const e=Number(i);Number.isNaN(e)||(t.epn[r.slice(4)]=e);continue}if(r.startsWith("up."))t.up[r.slice(3)]=i;else{if(r.startsWith("upn.")){const e=Number(i);Number.isNaN(e)||(t.upn[r.slice(4)]=e);continue}if("_et"===r){const e=Number(i);Number.isNaN(e)||(t._et=e);continue}"_c"!==r||(t._c=i)}}}a.sort((e,t)=>e[0]-t[0]);const r=a.map(([,e])=>u(e));return{en:e.en,params:t,items:r}}(e))}}var _={page_view:{name:"page view",data:{map:{id:"hit.dl",title:"hit.dt",referrer:"hit.dr"}}},purchase:{name:"order complete",data:{map:{id:"params.ep.transaction_id",currency:"params.ep.currency",total:"params.epn.value",tax:"params.epn.tax",shipping:"params.epn.shipping",coupon:"params.ep.coupon"}}},view_item:{name:"product view",data:{map:{currency:"params.ep.currency",value:"params.epn.value"}}},add_to_cart:{name:"product add",data:{map:{currency:"params.ep.currency",value:"params.epn.value"}}},remove_from_cart:{name:"product remove",data:{map:{currency:"params.ep.currency",value:"params.epn.value"}}},view_cart:{name:"cart view",data:{map:{currency:"params.ep.currency",value:"params.epn.value"}}},begin_checkout:{name:"order start",data:{map:{currency:"params.ep.currency",value:"params.epn.value",coupon:"params.ep.coupon"}}},add_shipping_info:{name:"order shipping",data:{map:{currency:"params.ep.currency",value:"params.epn.value",tier:"params.ep.shipping_tier"}}},add_payment_info:{name:"order payment",data:{map:{currency:"params.ep.currency",value:"params.epn.value",type:"params.ep.payment_type"}}},refund:{name:"order refund",data:{map:{id:"params.ep.transaction_id",currency:"params.ep.currency",total:"params.epn.value"}}},add_to_wishlist:{name:"wishlist add",data:{map:{currency:"params.ep.currency",value:"params.epn.value"}}},view_item_list:{name:"list view",data:{map:{id:"params.ep.item_list_id",name:"params.ep.item_list_name"}}},select_item:{name:"product click",data:{map:{list_id:"params.ep.item_list_id",list_name:"params.ep.item_list_name"}}},view_promotion:{name:"promotion view",data:{map:{id:"firstItem.promotionId",name:"firstItem.promotionName",creative:"firstItem.creativeName",slot:"firstItem.creativeSlot"}}},select_promotion:{name:"promotion click",data:{map:{id:"firstItem.promotionId",name:"firstItem.promotionName",creative:"firstItem.creativeName",slot:"firstItem.creativeSlot"}}},select_content:{name:"content select",data:{map:{type:"params.ep.content_type",id:"params.ep.content_id"}}},scroll:{name:"page scroll",data:{map:{percent:"params.epn.percent_scrolled"}}},click:{name:"link click",data:{map:{url:"params.ep.link_url",domain:"params.ep.link_domain",outbound:"params.ep.outbound"}}},file_download:{name:"file download",data:{map:{name:"params.ep.file_name",extension:"params.ep.file_extension",url:"params.ep.link_url"}}},video_start:{name:"video start",data:{map:{title:"params.ep.video_title",duration:"params.epn.video_duration",current:"params.epn.video_current_time",percent:"params.epn.video_percent"}}},video_progress:{name:"video progress",data:{map:{title:"params.ep.video_title",duration:"params.epn.video_duration",current:"params.epn.video_current_time",percent:"params.epn.video_percent"}}},video_complete:{name:"video complete",data:{map:{title:"params.ep.video_title",duration:"params.epn.video_duration",current:"params.epn.video_current_time",percent:"params.epn.video_percent"}}},form_start:{name:"form start",data:{map:{id:"params.ep.form_id",name:"params.ep.form_name",destination:"params.ep.form_destination"}}},form_submit:{name:"form submit",data:{map:{id:"params.ep.form_id",name:"params.ep.form_name",destination:"params.ep.form_destination"}}},search:{name:"search submit",data:{map:{term:"params.ep.search_term"}}},login:{name:"session login",data:{map:{method:"params.ep.method"}}},sign_up:{name:"session signup",data:{map:{method:"params.ep.method"}}},generate_lead:{name:"lead generate",data:{map:{currency:"params.ep.currency",value:"params.epn.value"}}},share:{name:"content share",data:{map:{method:"params.ep.method",type:"params.ep.content_type",id:"params.ep.item_id"}}},user_engagement:{ignore:!0},session_start:{ignore:!0},first_visit:{ignore:!0},"*":{name:"ga4 track",data:{map:{event_name:"en"}}}},f=require("@walkeros/core");function h(e,t){const a=[];for(const r of e.events){const i=w(e.hit,r,t);i&&a.push(i)}return a}function w(e,t,a){const r=a[t.en]??a["*"];if(!r)return null;const i=Array.isArray(r)?r[0]:r;if(!i||i.ignore)return null;const n={hit:e,params:t.params,items:t.items,en:t.en,...t.items.length>0?{firstItem:t.items[0]}:{}},o={};if(i.name){const[e,...t]=i.name.split(" ");o.name=i.name,o.entity=e,o.action=t.join(" ")}if(void 0!==i.data){let e=b(i.data,n);if(i.remove&&(0,f.isObject)(e))for(const t of i.remove)e=(0,f.deleteByPath)(e,t);void 0!==e&&(o.data=e)}o.user={...void 0!==e.uid?{id:e.uid}:{},...void 0!==e.cid?{device:e.cid}:{},...void 0!==e.sid?{session:e.sid}:{}},o.globals={...void 0!==e.ul?{language:e.ul}:{},...void 0!==e.sr?{screen:e.sr}:{}},o.source={type:"ga4",...void 0!==e.p?{platform:e.p}:{}},o.consent=v(e),o.id=e._p??(0,f.getId)();const c=e.sid?Number(e.sid):NaN;return o.timestamp=!Number.isNaN(c)&&c>0?1e3*c:Date.now(),o.timing=t.params._et??0,o.trigger="ga4",t.items.length>0&&(o.nested=t.items.map(e=>{const t={};void 0!==e.id&&(t.id=e.id),void 0!==e.name&&(t.name=e.name),void 0!==e.brand&&(t.brand=e.brand),void 0!==e.category&&(t.category=e.category),void 0!==e.category2&&(t.category2=e.category2),void 0!==e.category3&&(t.category3=e.category3),void 0!==e.category4&&(t.category4=e.category4),void 0!==e.category5&&(t.category5=e.category5),void 0!==e.variant&&(t.variant=e.variant),void 0!==e.price&&(t.price=e.price),void 0!==e.quantity&&(t.quantity=e.quantity),void 0!==e.coupon&&(t.coupon=e.coupon),void 0!==e.discount&&(t.discount=e.discount),void 0!==e.listName&&(t.list_name=e.listName),void 0!==e.listId&&(t.list_id=e.listId),void 0!==e.listPosition&&(t.list_position=e.listPosition),void 0!==e.locationId&&(t.location_id=e.locationId),void 0!==e.affiliation&&(t.affiliation=e.affiliation),void 0!==e.creativeName&&(t.creative_name=e.creativeName),void 0!==e.creativeSlot&&(t.creative_slot=e.creativeSlot),void 0!==e.promotionId&&(t.promotion_id=e.promotionId),void 0!==e.promotionName&&(t.promotion_name=e.promotionName);for(const[a,r]of Object.entries(e.custom))t[a]=r;return{entity:"product",data:t,nested:[],context:{}}})),o}function b(e,t){if(Array.isArray(e))for(const a of e){const e=b(a,t);if(null!=e)return e}else{if("string"==typeof e)return(0,f.getByPath)(t,e);if("object"==typeof e&&null!==e){if("value"in e&&void 0!==e.value)return e.value;if("key"in e&&"string"==typeof e.key)return(0,f.getByPath)(t,e.key);if("map"in e&&e.map){const a={};for(const[r,i]of Object.entries(e.map)){const e=b(i,t);void 0!==e&&(a[r]=e)}return a}}}}var E={};n(E,{step:()=>N});var N={};n(N,{addToCart:()=>G,batchPost:()=>X,beginCheckout:()=>S,consentDenied:()=>U,customEvent:()=>R,login:()=>L,pageView:()=>P,purchase:()=>I,scroll:()=>M,search:()=>x,userEngagementIgnored:()=>j,viewItem:()=>O});var k="1700000000";function A(e){return{id:"p1",timestamp:17e11,timing:0,trigger:"ga4",user:{device:"cid-1",session:k},globals:{},source:{type:"ga4"},consent:{},...e}}var P={title:"Page view",description:"A standard GA4 page_view hit decoded to a walkerOS page view with id, title, and referrer.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+k+"&en=page_view&dl=https%3A%2F%2Fshop.example.com%2Fproducts%2Fsku-123&dt=Trail%20Runner%20Pro&dr=https%3A%2F%2Fshop.example.com%2F"},out:[["return",A({name:"page view",entity:"page",action:"view",data:{id:"https://shop.example.com/products/sku-123",title:"Trail Runner Pro",referrer:"https://shop.example.com/"}})]]},I={title:"Purchase (canary)",description:"A GA4 purchase hit decoded to a walkerOS order complete event with id, currency, total, tax, shipping, and coupon.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+k+"&en=purchase&ep.transaction_id=T-9001&ep.currency=EUR&epn.value=149.97&epn.tax=23.97&epn.shipping=4.95&ep.coupon=WELCOME10"},out:[["return",A({name:"order complete",entity:"order",action:"complete",data:{id:"T-9001",currency:"EUR",total:149.97,tax:23.97,shipping:4.95,coupon:"WELCOME10"}})]]},O={title:"View item",description:"A GA4 view_item hit decoded to a walkerOS product view event with currency and value.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+k+"&en=view_item&ep.currency=EUR&epn.value=129.99"},out:[["return",A({name:"product view",entity:"product",action:"view",data:{currency:"EUR",value:129.99}})]]},G={title:"Add to cart",description:"A GA4 add_to_cart hit decoded to a walkerOS product add event with currency and value.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+k+"&en=add_to_cart&ep.currency=EUR&epn.value=129.99"},out:[["return",A({name:"product add",entity:"product",action:"add",data:{currency:"EUR",value:129.99}})]]},S={title:"Begin checkout",description:"A GA4 begin_checkout hit decoded to a walkerOS order start event with currency, value, and coupon.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+k+"&en=begin_checkout&ep.currency=EUR&epn.value=149.97&ep.coupon=WELCOME10"},out:[["return",A({name:"order start",entity:"order",action:"start",data:{currency:"EUR",value:149.97,coupon:"WELCOME10"}})]]},M={title:"Scroll",description:"A GA4 scroll hit decoded to a walkerOS page scroll event with the percent_scrolled value.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+k+"&en=scroll&epn.percent_scrolled=90"},out:[["return",A({name:"page scroll",entity:"page",action:"scroll",data:{percent:90}})]]},x={title:"Search",description:"A GA4 search hit decoded to a walkerOS search submit event carrying the search term.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+k+"&en=search&ep.search_term=trail%20runner"},out:[["return",A({name:"search submit",entity:"search",action:"submit",data:{term:"trail runner"}})]]},L={title:"Login",description:"A GA4 login hit decoded to a walkerOS session login event with the auth method.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+k+"&en=login&ep.method=google"},out:[["return",A({name:"session login",entity:"session",action:"login",data:{method:"google"}})]]},R={title:"Custom event (* fallback)",description:"Unknown GA4 event names hit the * fallback rule and surface as a ga4 track event carrying the original name.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+k+"&en=newsletter_subscribe&ep.source=footer"},out:[["return",A({name:"ga4 track",entity:"ga4",action:"track",data:{event_name:"newsletter_subscribe"}})]]},U={title:"Consent denied (gcs=G100)",description:"A page_view hit with gcs=G100 still maps, with consent.{marketing,analytics} both false on the resulting event.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+k+"&gcs=G100&en=page_view&dl=https%3A%2F%2Fx&dt=X"},out:[["return",A({name:"page view",entity:"page",action:"view",data:{id:"https://x",title:"X"},consent:{marketing:!1,analytics:!1}})]]},j={title:"user_engagement (ignored)",description:"Auto-fired GA4 user_engagement events are dropped by default — the transformer returns false.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+k+"&en=user_engagement&_et=1500"},out:[["return",!1]]},X={title:"Batched POST (fan-out)",description:"A single POST request carrying two newline-separated events fans out into two walkerOS events.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+k,body:["en=add_to_cart&ep.currency=EUR&epn.value=19.99","en=add_to_cart&ep.currency=EUR&epn.value=29.99"].join("\n")},out:[["return",A({name:"product add",entity:"product",action:"add",data:{currency:"EUR",value:19.99}})],["return",A({name:"product add",entity:"product",action:"add",data:{currency:"EUR",value:29.99}})]]};//# sourceMappingURL=dev.js.map
|
package/dist/dev.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/dev.ts","../src/parse.ts","../src/defaults.ts","../src/map.ts","../src/examples/index.ts","../src/examples/step.ts"],"sourcesContent":["/**\n * Development exports for transformer-ga4.\n * Used by website documentation, step examples, and downstream tests.\n *\n * Mirrors the validator's dev.ts pattern: only primitives leak out here, the\n * transformer instance is reached via the package entry (`./index.ts`).\n */\n\nexport {\n parseRequest,\n parseQuery,\n parseBody,\n parseItem,\n parseConsent,\n} from './parse';\nexport { defaultMapping } from './defaults';\nexport { mapHitToEvents } from './map';\nexport type {\n GA4Settings,\n GA4Mapping,\n GA4Request,\n GA4Hit,\n GA4Event,\n GA4EventParams,\n GA4HitParams,\n GA4Item,\n} from './types';\n\nexport * as examples from './examples';\n","import type { WalkerOS } from '@walkeros/core';\nimport type {\n GA4Event,\n GA4EventParams,\n GA4Hit,\n GA4HitParams,\n GA4Item,\n GA4Request,\n} from './types';\n\nexport function parseQuery(url: string): Record<string, string> {\n const out: Record<string, string> = {};\n const qIdx = url.indexOf('?');\n if (qIdx === -1) return out;\n const usp = new URLSearchParams(url.slice(qIdx + 1));\n usp.forEach((value, key) => {\n out[key] = value;\n });\n return out;\n}\n\nexport function parseBody(body: string): Record<string, string>[] {\n if (!body) return [];\n return body\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .filter((line) => line.length > 0)\n .map((line) => {\n const out: Record<string, string> = {};\n const usp = new URLSearchParams(line);\n usp.forEach((v, k) => {\n out[k] = v;\n });\n return out;\n });\n}\n\n// Two separate dispatch maps keyed by 2-char prefix.\n// Split by type so the assignment site stays type-safe (no cast).\nconst ITEM_STRING_FIELDS: Readonly<Record<string, keyof GA4Item>> = {\n id: 'id',\n nm: 'name',\n br: 'brand',\n ca: 'category',\n c2: 'category2',\n c3: 'category3',\n c4: 'category4',\n c5: 'category5',\n va: 'variant',\n cp: 'coupon',\n ln: 'listName',\n li: 'listId',\n lo: 'locationId',\n af: 'affiliation',\n cn: 'creativeName',\n cs: 'creativeSlot',\n pi: 'promotionId',\n pn: 'promotionName',\n};\n\nconst ITEM_NUMBER_FIELDS: Readonly<Record<string, keyof GA4Item>> = {\n pr: 'price',\n qt: 'quantity',\n ds: 'discount',\n lp: 'listPosition',\n};\n\nfunction setItemString(item: GA4Item, key: keyof GA4Item, value: string): void {\n // Narrow assignment by key — these are the string-typed fields.\n switch (key) {\n case 'id':\n item.id = value;\n return;\n case 'name':\n item.name = value;\n return;\n case 'brand':\n item.brand = value;\n return;\n case 'category':\n item.category = value;\n return;\n case 'category2':\n item.category2 = value;\n return;\n case 'category3':\n item.category3 = value;\n return;\n case 'category4':\n item.category4 = value;\n return;\n case 'category5':\n item.category5 = value;\n return;\n case 'variant':\n item.variant = value;\n return;\n case 'coupon':\n item.coupon = value;\n return;\n case 'listName':\n item.listName = value;\n return;\n case 'listId':\n item.listId = value;\n return;\n case 'locationId':\n item.locationId = value;\n return;\n case 'affiliation':\n item.affiliation = value;\n return;\n case 'creativeName':\n item.creativeName = value;\n return;\n case 'creativeSlot':\n item.creativeSlot = value;\n return;\n case 'promotionId':\n item.promotionId = value;\n return;\n case 'promotionName':\n item.promotionName = value;\n return;\n }\n}\n\nfunction setItemNumber(item: GA4Item, key: keyof GA4Item, value: number): void {\n switch (key) {\n case 'price':\n item.price = value;\n return;\n case 'quantity':\n item.quantity = value;\n return;\n case 'discount':\n item.discount = value;\n return;\n case 'listPosition':\n item.listPosition = value;\n return;\n }\n}\n\nexport function parseItem(value: string): GA4Item {\n const item: GA4Item = { custom: {} };\n const customKeys = new Map<string, string>();\n const customVals = new Map<string, string>();\n\n for (const raw of value.split('~')) {\n if (raw.length === 0) continue;\n\n // Variable-length k<N>/v<N> (must match before 2-char prefix lookup\n // because k10/v10 etc are wider than 2 chars).\n const kvMatch = /^([kv])(\\d+)(.*)$/.exec(raw);\n if (kvMatch) {\n const [, kind, idx, val] = kvMatch;\n if (kind === 'k') customKeys.set(idx, val);\n else customVals.set(idx, val);\n continue;\n }\n\n if (raw.length < 2) continue;\n const prefix = raw.slice(0, 2);\n const val = raw.slice(2);\n\n const stringKey = ITEM_STRING_FIELDS[prefix];\n if (stringKey !== undefined) {\n setItemString(item, stringKey, val);\n continue;\n }\n const numberKey = ITEM_NUMBER_FIELDS[prefix];\n if (numberKey !== undefined) {\n const n = Number(val);\n if (!Number.isNaN(n)) setItemNumber(item, numberKey, n);\n continue;\n }\n }\n\n // Pair k<N> with v<N>; drop unmatched.\n for (const [idx, key] of customKeys) {\n const v = customVals.get(idx);\n if (v !== undefined) item.custom[key] = v;\n }\n return item;\n}\n\nexport function parseConsent(hit: { gcs?: string }): WalkerOS.Consent {\n const gcs = hit.gcs;\n if (!gcs || !/^G[01]{3}$/.test(gcs)) return {};\n // gcs[1] is reserved (always '1' for current consent mode v2)\n return {\n marketing: gcs[2] === '1', // ad_storage\n analytics: gcs[3] === '1', // analytics_storage\n };\n}\n\nconst HIT_PARAM_KEYS = new Set([\n 'v',\n 'tid',\n 'cid',\n 'sid',\n 'sct',\n 'seg',\n '_p',\n '_z',\n 'gtm',\n 'dl',\n 'dt',\n 'dr',\n 'ul',\n 'sr',\n 'uid',\n '_dbg',\n '_s',\n '_ss',\n '_fv',\n 'gcs',\n 'gcd',\n 'dma',\n 'dma_cps',\n 'npa',\n 'p',\n]);\n\nexport function parseRequest(req: GA4Request): GA4Hit {\n const queryParams = parseQuery(req.url);\n const hit: GA4HitParams = {};\n const queryEventParams: Record<string, string> = {};\n\n // Split URL params into hit-level vs event-level.\n for (const [k, v] of Object.entries(queryParams)) {\n if (HIT_PARAM_KEYS.has(k)) hit[k] = v;\n else queryEventParams[k] = v;\n }\n\n // GET: event params live in the URL alongside hit params.\n // POST: in body lines.\n const bodyLines = req.body ? parseBody(req.body) : [];\n const rawEvents =\n bodyLines.length > 0\n ? bodyLines\n : Object.keys(queryEventParams).length > 0\n ? [queryEventParams]\n : [];\n\n const events: GA4Event[] = rawEvents\n .filter((raw) => typeof raw.en === 'string' && raw.en.length > 0)\n .map((raw) => buildEvent(raw));\n\n return { hit, events };\n}\n\nfunction buildEvent(raw: Record<string, string>): GA4Event {\n const params: GA4EventParams = { ep: {}, epn: {}, up: {}, upn: {} };\n const itemEntries: Array<[number, string]> = [];\n\n for (const [k, v] of Object.entries(raw)) {\n if (k === 'en') continue;\n\n // pr<N> items\n const prMatch = /^pr(\\d+)$/.exec(k);\n if (prMatch) {\n itemEntries.push([Number(prMatch[1]), v]);\n continue;\n }\n\n // Dotted-key nesting\n if (k.startsWith('ep.')) {\n params.ep[k.slice(3)] = v;\n continue;\n }\n if (k.startsWith('epn.')) {\n const n = Number(v);\n if (!Number.isNaN(n)) params.epn[k.slice(4)] = n;\n continue;\n }\n if (k.startsWith('up.')) {\n params.up[k.slice(3)] = v;\n continue;\n }\n if (k.startsWith('upn.')) {\n const n = Number(v);\n if (!Number.isNaN(n)) params.upn[k.slice(4)] = n;\n continue;\n }\n\n // Standalone numeric keys\n if (k === '_et') {\n const n = Number(v);\n if (!Number.isNaN(n)) params._et = n;\n continue;\n }\n if (k === '_c') {\n params._c = v;\n continue;\n }\n // Unknown standalone keys: drop. Add to GA4EventParams type if a future\n // need surfaces.\n }\n\n itemEntries.sort((a, b) => a[0] - b[0]);\n const items = itemEntries.map(([, v]) => parseItem(v));\n\n return { en: raw.en, params, items };\n}\n","import type { GA4Mapping } from './types';\n\n/**\n * Default GA4 event-name → walkerOS mapping rules.\n * Users may override or extend these via settings.mapping at config time.\n * The `'*'` key is the fallback for unknown event names.\n *\n * Field naming for `data.map`:\n * - Monetary: `currency` from `ep.currency`, `value`/`total` from `epn.value`,\n * `tax` from `epn.tax`, `shipping` from `epn.shipping`, `coupon` from\n * `ep.coupon`.\n * - Promotions read from `firstItem` (synthetic `items[0]` reference exposed by\n * the mapper), since GA4 encodes promotion info inside item tilde strings.\n */\nexport const defaultMapping: GA4Mapping = {\n // --- page ---\n page_view: {\n name: 'page view',\n data: {\n map: {\n id: 'hit.dl',\n title: 'hit.dt',\n referrer: 'hit.dr',\n },\n },\n },\n\n // --- ecommerce ---\n purchase: {\n name: 'order complete',\n data: {\n map: {\n id: 'params.ep.transaction_id',\n currency: 'params.ep.currency',\n total: 'params.epn.value',\n tax: 'params.epn.tax',\n shipping: 'params.epn.shipping',\n coupon: 'params.ep.coupon',\n },\n },\n },\n view_item: {\n name: 'product view',\n data: {\n map: {\n currency: 'params.ep.currency',\n value: 'params.epn.value',\n },\n },\n },\n add_to_cart: {\n name: 'product add',\n data: {\n map: {\n currency: 'params.ep.currency',\n value: 'params.epn.value',\n },\n },\n },\n remove_from_cart: {\n name: 'product remove',\n data: {\n map: {\n currency: 'params.ep.currency',\n value: 'params.epn.value',\n },\n },\n },\n view_cart: {\n name: 'cart view',\n data: {\n map: {\n currency: 'params.ep.currency',\n value: 'params.epn.value',\n },\n },\n },\n begin_checkout: {\n name: 'order start',\n data: {\n map: {\n currency: 'params.ep.currency',\n value: 'params.epn.value',\n coupon: 'params.ep.coupon',\n },\n },\n },\n add_shipping_info: {\n name: 'order shipping',\n data: {\n map: {\n currency: 'params.ep.currency',\n value: 'params.epn.value',\n tier: 'params.ep.shipping_tier',\n },\n },\n },\n add_payment_info: {\n name: 'order payment',\n data: {\n map: {\n currency: 'params.ep.currency',\n value: 'params.epn.value',\n type: 'params.ep.payment_type',\n },\n },\n },\n refund: {\n name: 'order refund',\n data: {\n map: {\n id: 'params.ep.transaction_id',\n currency: 'params.ep.currency',\n total: 'params.epn.value',\n },\n },\n },\n add_to_wishlist: {\n name: 'wishlist add',\n data: {\n map: {\n currency: 'params.ep.currency',\n value: 'params.epn.value',\n },\n },\n },\n\n // --- list / promotion ---\n view_item_list: {\n name: 'list view',\n data: {\n map: {\n id: 'params.ep.item_list_id',\n name: 'params.ep.item_list_name',\n },\n },\n },\n select_item: {\n name: 'product click',\n data: {\n map: {\n list_id: 'params.ep.item_list_id',\n list_name: 'params.ep.item_list_name',\n },\n },\n },\n view_promotion: {\n name: 'promotion view',\n data: {\n map: {\n id: 'firstItem.promotionId',\n name: 'firstItem.promotionName',\n creative: 'firstItem.creativeName',\n slot: 'firstItem.creativeSlot',\n },\n },\n },\n select_promotion: {\n name: 'promotion click',\n data: {\n map: {\n id: 'firstItem.promotionId',\n name: 'firstItem.promotionName',\n creative: 'firstItem.creativeName',\n slot: 'firstItem.creativeSlot',\n },\n },\n },\n select_content: {\n name: 'content select',\n data: {\n map: {\n type: 'params.ep.content_type',\n id: 'params.ep.content_id',\n },\n },\n },\n\n // --- engagement ---\n scroll: {\n name: 'page scroll',\n data: {\n map: {\n percent: 'params.epn.percent_scrolled',\n },\n },\n },\n click: {\n name: 'link click',\n data: {\n map: {\n url: 'params.ep.link_url',\n domain: 'params.ep.link_domain',\n outbound: 'params.ep.outbound',\n },\n },\n },\n file_download: {\n name: 'file download',\n data: {\n map: {\n name: 'params.ep.file_name',\n extension: 'params.ep.file_extension',\n url: 'params.ep.link_url',\n },\n },\n },\n video_start: {\n name: 'video start',\n data: {\n map: {\n title: 'params.ep.video_title',\n duration: 'params.epn.video_duration',\n current: 'params.epn.video_current_time',\n percent: 'params.epn.video_percent',\n },\n },\n },\n video_progress: {\n name: 'video progress',\n data: {\n map: {\n title: 'params.ep.video_title',\n duration: 'params.epn.video_duration',\n current: 'params.epn.video_current_time',\n percent: 'params.epn.video_percent',\n },\n },\n },\n video_complete: {\n name: 'video complete',\n data: {\n map: {\n title: 'params.ep.video_title',\n duration: 'params.epn.video_duration',\n current: 'params.epn.video_current_time',\n percent: 'params.epn.video_percent',\n },\n },\n },\n form_start: {\n name: 'form start',\n data: {\n map: {\n id: 'params.ep.form_id',\n name: 'params.ep.form_name',\n destination: 'params.ep.form_destination',\n },\n },\n },\n form_submit: {\n name: 'form submit',\n data: {\n map: {\n id: 'params.ep.form_id',\n name: 'params.ep.form_name',\n destination: 'params.ep.form_destination',\n },\n },\n },\n search: {\n name: 'search submit',\n data: {\n map: {\n term: 'params.ep.search_term',\n },\n },\n },\n login: {\n name: 'session login',\n data: {\n map: {\n method: 'params.ep.method',\n },\n },\n },\n sign_up: {\n name: 'session signup',\n data: {\n map: {\n method: 'params.ep.method',\n },\n },\n },\n generate_lead: {\n name: 'lead generate',\n data: {\n map: {\n currency: 'params.ep.currency',\n value: 'params.epn.value',\n },\n },\n },\n share: {\n name: 'content share',\n data: {\n map: {\n method: 'params.ep.method',\n type: 'params.ep.content_type',\n id: 'params.ep.item_id',\n },\n },\n },\n\n // --- auto-fired noise: ignore by default (users can override) ---\n user_engagement: { ignore: true },\n session_start: { ignore: true },\n first_visit: { ignore: true },\n\n // --- fallback for unknown event names ---\n '*': {\n name: 'ga4 track',\n data: {\n map: {\n event_name: 'en',\n },\n },\n },\n};\n","import type { Mapping, WalkerOS } from '@walkeros/core';\nimport { getByPath, getId } from '@walkeros/core';\nimport type {\n GA4Event,\n GA4Hit,\n GA4HitParams,\n GA4Item,\n GA4Mapping,\n} from './types';\nimport { parseConsent } from './parse';\n\n/**\n * Lookup root for mapping path resolution. Mapping rules reference keys via\n * dotted paths: `hit.dl`, `params.ep.transaction_id`, `params.epn.value`, `items`.\n *\n * `en` exposes the GA4 event name (used by the `*` fallback so unknown events\n * can carry their original name through). `firstItem` exposes `items[0]` so\n * promotion-style mappings can resolve `firstItem.promotionId` etc. without\n * needing array-index syntax in `getByPath`.\n *\n * Typed as `Record<string, unknown> & { ... }` so `getByPath` (which accepts\n * unknown) is happy without any narrowing cast on the call site.\n */\ntype LookupRoot = Record<string, unknown> & {\n hit: GA4HitParams;\n params: GA4Event['params'];\n items: GA4Event['items'];\n en: string;\n firstItem?: GA4Item;\n};\n\n/**\n * Convert a parsed GA4 hit into zero or more walkerOS events.\n * One GA4 hit may carry several events (POST batch); each is mapped\n * independently with hit-level metadata merged in.\n */\nexport function mapHitToEvents(\n hit: GA4Hit,\n mapping: GA4Mapping,\n): WalkerOS.DeepPartialEvent[] {\n const out: WalkerOS.DeepPartialEvent[] = [];\n for (const event of hit.events) {\n const mapped = mapOneEvent(hit.hit, event, mapping);\n if (mapped) out.push(mapped);\n }\n return out;\n}\n\nfunction mapOneEvent(\n hitParams: GA4HitParams,\n event: GA4Event,\n mapping: GA4Mapping,\n): WalkerOS.DeepPartialEvent | null {\n const ruleEntry = mapping[event.en] ?? mapping['*'];\n if (!ruleEntry) return null;\n // For v1, only single-rule entries are supported (no array fan-out).\n const rule: Mapping.Rule = Array.isArray(ruleEntry)\n ? ruleEntry[0]\n : ruleEntry;\n if (!rule || rule.ignore) return null;\n\n const lookup: LookupRoot = {\n hit: hitParams,\n params: event.params,\n items: event.items,\n en: event.en,\n ...(event.items.length > 0 ? { firstItem: event.items[0] } : {}),\n };\n\n const evaluated: WalkerOS.DeepPartialEvent = {};\n\n if (rule.name) {\n const [entity, ...rest] = rule.name.split(' ');\n evaluated.name = rule.name;\n evaluated.entity = entity;\n evaluated.action = rest.join(' ');\n }\n\n if (rule.data !== undefined) {\n const data = evalValue(rule.data, lookup);\n if (data !== undefined) {\n evaluated.data = data as WalkerOS.Properties;\n }\n }\n\n // Hit-level merge: user / globals / source.\n evaluated.user = {\n ...(hitParams.uid !== undefined ? { id: hitParams.uid } : {}),\n ...(hitParams.cid !== undefined ? { device: hitParams.cid } : {}),\n ...(hitParams.sid !== undefined ? { session: hitParams.sid } : {}),\n };\n evaluated.globals = {\n ...(hitParams.ul !== undefined ? { language: hitParams.ul } : {}),\n ...(hitParams.sr !== undefined ? { screen: hitParams.sr } : {}),\n };\n evaluated.source = {\n type: 'ga4',\n ...(hitParams.p !== undefined ? { platform: hitParams.p } : {}),\n };\n\n // Consent from gcs string, id from hit._p (fallback to generated string),\n // timestamp from sid (epoch seconds → ms; falls back to wall-clock now),\n // timing from event._et (ms; 0 if absent), trigger hard-coded to \"ga4\" for v1.\n evaluated.consent = parseConsent(hitParams);\n evaluated.id = hitParams._p ?? getId();\n const sidNum = hitParams.sid ? Number(hitParams.sid) : NaN;\n evaluated.timestamp =\n !Number.isNaN(sidNum) && sidNum > 0 ? sidNum * 1000 : Date.now();\n evaluated.timing = event.params._et ?? 0;\n evaluated.trigger = 'ga4';\n\n if (event.items.length > 0) {\n evaluated.nested = itemsToNested(event.items);\n }\n\n return evaluated;\n}\n\n/**\n * GA4 items → walkerOS nested product entities.\n * Field naming: camelCase GA4Item keys are emitted as snake_case data keys\n * (`listName` → `list_name`, `promotionId` → `promotion_id`, etc).\n * Custom k<N>/v<N> pairs are spread as-is.\n *\n * Returns `WalkerOS.Entities` (i.e. `Array<WalkerOS.Entity>`). Note that the\n * canonical `WalkerOS.Entity` interface uses `entity: string` as the kind\n * discriminator (not `type`).\n */\nfunction itemsToNested(items: GA4Item[]): WalkerOS.Entities {\n return items.map((item): WalkerOS.Entity => {\n const data: WalkerOS.Properties = {};\n if (item.id !== undefined) data.id = item.id;\n if (item.name !== undefined) data.name = item.name;\n if (item.brand !== undefined) data.brand = item.brand;\n if (item.category !== undefined) data.category = item.category;\n if (item.category2 !== undefined) data.category2 = item.category2;\n if (item.category3 !== undefined) data.category3 = item.category3;\n if (item.category4 !== undefined) data.category4 = item.category4;\n if (item.category5 !== undefined) data.category5 = item.category5;\n if (item.variant !== undefined) data.variant = item.variant;\n if (item.price !== undefined) data.price = item.price;\n if (item.quantity !== undefined) data.quantity = item.quantity;\n if (item.coupon !== undefined) data.coupon = item.coupon;\n if (item.discount !== undefined) data.discount = item.discount;\n if (item.listName !== undefined) data.list_name = item.listName;\n if (item.listId !== undefined) data.list_id = item.listId;\n if (item.listPosition !== undefined) data.list_position = item.listPosition;\n if (item.locationId !== undefined) data.location_id = item.locationId;\n if (item.affiliation !== undefined) data.affiliation = item.affiliation;\n if (item.creativeName !== undefined) data.creative_name = item.creativeName;\n if (item.creativeSlot !== undefined) data.creative_slot = item.creativeSlot;\n if (item.promotionId !== undefined) data.promotion_id = item.promotionId;\n if (item.promotionName !== undefined)\n data.promotion_name = item.promotionName;\n for (const [k, v] of Object.entries(item.custom)) data[k] = v;\n return { entity: 'product', data, nested: [], context: {} };\n });\n}\n\n/**\n * Minimal mapping evaluator. v1 supports:\n * - string → path lookup via getByPath\n * - Array<Value> → fallback chain: first non-undefined wins\n * - { value: X } → literal\n * - { key: 'path' } → path lookup\n * - { map: {...} } → recursive object build\n *\n * Deferred to v2: condition, loop, fn, validate, set, consent, $code.\n */\nfunction evalValue(\n value: Mapping.Value | Mapping.Values,\n root: LookupRoot,\n): unknown {\n if (Array.isArray(value)) {\n for (const v of value) {\n const resolved = evalValue(v, root);\n if (resolved !== undefined && resolved !== null) return resolved;\n }\n return undefined;\n }\n if (typeof value === 'string') {\n return getByPath(root, value);\n }\n if (typeof value === 'object' && value !== null) {\n if ('value' in value && value.value !== undefined) return value.value;\n if ('key' in value && typeof value.key === 'string') {\n return getByPath(root, value.key);\n }\n if ('map' in value && value.map) {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value.map)) {\n const resolved = evalValue(v, root);\n if (resolved !== undefined) out[k] = resolved;\n }\n return out;\n }\n }\n return undefined;\n}\n","export * as step from './step';\n","import type { Flow } from '@walkeros/core';\n\n/**\n * Step examples for transformer-ga4.\n *\n * `in` is a raw `GA4Request` (`{ url, body? }`) — the shape the transformer\n * reads from `ctx.ingest`. `out` is the array of effect tuples produced by\n * pushing that request through the transformer:\n *\n * - Mapped event (single): `out: [['return', event]]`\n * - Mapped events (fan-out): `out: [['return', e1], ['return', e2], ...]`\n * - Dropped (ignore / no en): `out: [['return', false]]`\n *\n * Examples set `_p` (becomes `event.id`) and `sid` (becomes `event.timestamp`\n * in ms via `sid * 1000`) so the assertions are deterministic. The synthetic\n * walkerOS event shape mirrors what `mapHitToEvents` produces in `map.ts`:\n * - `entity` + `action` derived from rule.name's first/rest words\n * - `user.{id,device,session}` from `uid/cid/sid`\n * - `source: { type: 'ga4', platform? }` from `p`\n * - `consent` from `gcs` (`G100` → all false, `G111` → all true)\n * - `timing` from event `_et` (defaults to 0 if absent)\n * - `trigger: 'ga4'` (hard-coded in v1)\n * - `nested[]` only set when items are present (POST-only example below)\n */\n\n// --- helpers (typed, no casts) -----------------------------------------------\n\nconst SID = '1700000000'; // → timestamp 1700000000000\n\nfunction ga4Event(overrides: Record<string, unknown>): Record<string, unknown> {\n return {\n id: 'p1',\n timestamp: 1700000000000,\n timing: 0,\n trigger: 'ga4',\n user: { device: 'cid-1', session: SID },\n globals: {},\n source: { type: 'ga4' },\n consent: {},\n ...overrides,\n };\n}\n\n// --- examples ---------------------------------------------------------------\n\nexport const pageView: Flow.StepExample = {\n title: 'Page view',\n description:\n 'A standard GA4 page_view hit decoded to a walkerOS page view with id, title, and referrer.',\n in: {\n url:\n 'https://www.google-analytics.com/g/collect' +\n '?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid=' +\n SID +\n '&en=page_view' +\n '&dl=https%3A%2F%2Fshop.example.com%2Fproducts%2Fsku-123' +\n '&dt=Trail%20Runner%20Pro' +\n '&dr=https%3A%2F%2Fshop.example.com%2F',\n },\n out: [\n [\n 'return',\n ga4Event({\n name: 'page view',\n entity: 'page',\n action: 'view',\n data: {\n id: 'https://shop.example.com/products/sku-123',\n title: 'Trail Runner Pro',\n referrer: 'https://shop.example.com/',\n },\n }),\n ],\n ],\n};\n\nexport const purchase: Flow.StepExample = {\n title: 'Purchase (canary)',\n description:\n 'A GA4 purchase hit decoded to a walkerOS order complete event with id, currency, total, tax, shipping, and coupon.',\n in: {\n url:\n 'https://www.google-analytics.com/g/collect' +\n '?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid=' +\n SID +\n '&en=purchase' +\n '&ep.transaction_id=T-9001' +\n '&ep.currency=EUR' +\n '&epn.value=149.97' +\n '&epn.tax=23.97' +\n '&epn.shipping=4.95' +\n '&ep.coupon=WELCOME10',\n },\n out: [\n [\n 'return',\n ga4Event({\n name: 'order complete',\n entity: 'order',\n action: 'complete',\n data: {\n id: 'T-9001',\n currency: 'EUR',\n total: 149.97,\n tax: 23.97,\n shipping: 4.95,\n coupon: 'WELCOME10',\n },\n }),\n ],\n ],\n};\n\nexport const viewItem: Flow.StepExample = {\n title: 'View item',\n description:\n 'A GA4 view_item hit decoded to a walkerOS product view event with currency and value.',\n in: {\n url:\n 'https://www.google-analytics.com/g/collect' +\n '?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid=' +\n SID +\n '&en=view_item&ep.currency=EUR&epn.value=129.99',\n },\n out: [\n [\n 'return',\n ga4Event({\n name: 'product view',\n entity: 'product',\n action: 'view',\n data: { currency: 'EUR', value: 129.99 },\n }),\n ],\n ],\n};\n\nexport const addToCart: Flow.StepExample = {\n title: 'Add to cart',\n description:\n 'A GA4 add_to_cart hit decoded to a walkerOS product add event with currency and value.',\n in: {\n url:\n 'https://www.google-analytics.com/g/collect' +\n '?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid=' +\n SID +\n '&en=add_to_cart&ep.currency=EUR&epn.value=129.99',\n },\n out: [\n [\n 'return',\n ga4Event({\n name: 'product add',\n entity: 'product',\n action: 'add',\n data: { currency: 'EUR', value: 129.99 },\n }),\n ],\n ],\n};\n\nexport const beginCheckout: Flow.StepExample = {\n title: 'Begin checkout',\n description:\n 'A GA4 begin_checkout hit decoded to a walkerOS order start event with currency, value, and coupon.',\n in: {\n url:\n 'https://www.google-analytics.com/g/collect' +\n '?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid=' +\n SID +\n '&en=begin_checkout' +\n '&ep.currency=EUR&epn.value=149.97&ep.coupon=WELCOME10',\n },\n out: [\n [\n 'return',\n ga4Event({\n name: 'order start',\n entity: 'order',\n action: 'start',\n data: {\n currency: 'EUR',\n value: 149.97,\n coupon: 'WELCOME10',\n },\n }),\n ],\n ],\n};\n\nexport const scroll: Flow.StepExample = {\n title: 'Scroll',\n description:\n 'A GA4 scroll hit decoded to a walkerOS page scroll event with the percent_scrolled value.',\n in: {\n url:\n 'https://www.google-analytics.com/g/collect' +\n '?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid=' +\n SID +\n '&en=scroll&epn.percent_scrolled=90',\n },\n out: [\n [\n 'return',\n ga4Event({\n name: 'page scroll',\n entity: 'page',\n action: 'scroll',\n data: { percent: 90 },\n }),\n ],\n ],\n};\n\nexport const search: Flow.StepExample = {\n title: 'Search',\n description:\n 'A GA4 search hit decoded to a walkerOS search submit event carrying the search term.',\n in: {\n url:\n 'https://www.google-analytics.com/g/collect' +\n '?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid=' +\n SID +\n '&en=search&ep.search_term=trail%20runner',\n },\n out: [\n [\n 'return',\n ga4Event({\n name: 'search submit',\n entity: 'search',\n action: 'submit',\n data: { term: 'trail runner' },\n }),\n ],\n ],\n};\n\nexport const login: Flow.StepExample = {\n title: 'Login',\n description:\n 'A GA4 login hit decoded to a walkerOS session login event with the auth method.',\n in: {\n url:\n 'https://www.google-analytics.com/g/collect' +\n '?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid=' +\n SID +\n '&en=login&ep.method=google',\n },\n out: [\n [\n 'return',\n ga4Event({\n name: 'session login',\n entity: 'session',\n action: 'login',\n data: { method: 'google' },\n }),\n ],\n ],\n};\n\nexport const customEvent: Flow.StepExample = {\n title: 'Custom event (* fallback)',\n description:\n 'Unknown GA4 event names hit the * fallback rule and surface as a ga4 track event carrying the original name.',\n in: {\n url:\n 'https://www.google-analytics.com/g/collect' +\n '?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid=' +\n SID +\n '&en=newsletter_subscribe&ep.source=footer',\n },\n out: [\n [\n 'return',\n ga4Event({\n name: 'ga4 track',\n entity: 'ga4',\n action: 'track',\n data: { event_name: 'newsletter_subscribe' },\n }),\n ],\n ],\n};\n\nexport const consentDenied: Flow.StepExample = {\n title: 'Consent denied (gcs=G100)',\n description:\n 'A page_view hit with gcs=G100 still maps, with consent.{marketing,analytics} both false on the resulting event.',\n in: {\n url:\n 'https://www.google-analytics.com/g/collect' +\n '?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid=' +\n SID +\n '&gcs=G100' +\n '&en=page_view&dl=https%3A%2F%2Fx&dt=X',\n },\n out: [\n [\n 'return',\n ga4Event({\n name: 'page view',\n entity: 'page',\n action: 'view',\n data: { id: 'https://x', title: 'X' },\n consent: { marketing: false, analytics: false },\n }),\n ],\n ],\n};\n\nexport const userEngagementIgnored: Flow.StepExample = {\n title: 'user_engagement (ignored)',\n description:\n 'Auto-fired GA4 user_engagement events are dropped by default — the transformer returns false.',\n in: {\n url:\n 'https://www.google-analytics.com/g/collect' +\n '?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid=' +\n SID +\n '&en=user_engagement&_et=1500',\n },\n out: [['return', false]],\n};\n\nexport const batchPost: Flow.StepExample = {\n title: 'Batched POST (fan-out)',\n description:\n 'A single POST request carrying two newline-separated events fans out into two walkerOS events.',\n in: {\n url:\n 'https://www.google-analytics.com/g/collect' +\n '?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid=' +\n SID,\n body: [\n 'en=add_to_cart&ep.currency=EUR&epn.value=19.99',\n 'en=add_to_cart&ep.currency=EUR&epn.value=29.99',\n ].join('\\n'),\n },\n out: [\n [\n 'return',\n ga4Event({\n name: 'product add',\n entity: 'product',\n action: 'add',\n data: { currency: 'EUR', value: 19.99 },\n }),\n ],\n [\n 'return',\n ga4Event({\n name: 'product add',\n entity: 'product',\n action: 'add',\n data: { currency: 'EUR', value: 29.99 },\n }),\n ],\n ],\n};\n"],"mappings":"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","names":["val"]}
|
|
1
|
+
{"version":3,"sources":["../src/dev.ts","../src/parse.ts","../src/defaults.ts","../src/map.ts","../src/examples/index.ts","../src/examples/step.ts"],"sourcesContent":["/**\n * Development exports for transformer-ga4.\n * Used by website documentation, step examples, and downstream tests.\n *\n * Mirrors the validator's dev.ts pattern: only primitives leak out here, the\n * transformer instance is reached via the package entry (`./index.ts`).\n */\n\nexport {\n parseRequest,\n parseQuery,\n parseBody,\n parseItem,\n parseConsent,\n} from './parse';\nexport { defaultMapping } from './defaults';\nexport { mapHitToEvents } from './map';\nexport type {\n GA4Settings,\n GA4Mapping,\n GA4Request,\n GA4Hit,\n GA4Event,\n GA4EventParams,\n GA4HitParams,\n GA4Item,\n} from './types';\n\nexport * as examples from './examples';\n","import type { WalkerOS } from '@walkeros/core';\nimport type {\n GA4Event,\n GA4EventParams,\n GA4Hit,\n GA4HitParams,\n GA4Item,\n GA4Request,\n} from './types';\n\nexport function parseQuery(url: string): Record<string, string> {\n const out: Record<string, string> = {};\n const qIdx = url.indexOf('?');\n if (qIdx === -1) return out;\n const usp = new URLSearchParams(url.slice(qIdx + 1));\n usp.forEach((value, key) => {\n out[key] = value;\n });\n return out;\n}\n\nexport function parseBody(body: string): Record<string, string>[] {\n if (!body) return [];\n return body\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .filter((line) => line.length > 0)\n .map((line) => {\n const out: Record<string, string> = {};\n const usp = new URLSearchParams(line);\n usp.forEach((v, k) => {\n out[k] = v;\n });\n return out;\n });\n}\n\n// Two separate dispatch maps keyed by 2-char prefix.\n// Split by type so the assignment site stays type-safe (no cast).\nconst ITEM_STRING_FIELDS: Readonly<Record<string, keyof GA4Item>> = {\n id: 'id',\n nm: 'name',\n br: 'brand',\n ca: 'category',\n c2: 'category2',\n c3: 'category3',\n c4: 'category4',\n c5: 'category5',\n va: 'variant',\n cp: 'coupon',\n ln: 'listName',\n li: 'listId',\n lo: 'locationId',\n af: 'affiliation',\n cn: 'creativeName',\n cs: 'creativeSlot',\n pi: 'promotionId',\n pn: 'promotionName',\n};\n\nconst ITEM_NUMBER_FIELDS: Readonly<Record<string, keyof GA4Item>> = {\n pr: 'price',\n qt: 'quantity',\n ds: 'discount',\n lp: 'listPosition',\n};\n\nfunction setItemString(item: GA4Item, key: keyof GA4Item, value: string): void {\n // Narrow assignment by key — these are the string-typed fields.\n switch (key) {\n case 'id':\n item.id = value;\n return;\n case 'name':\n item.name = value;\n return;\n case 'brand':\n item.brand = value;\n return;\n case 'category':\n item.category = value;\n return;\n case 'category2':\n item.category2 = value;\n return;\n case 'category3':\n item.category3 = value;\n return;\n case 'category4':\n item.category4 = value;\n return;\n case 'category5':\n item.category5 = value;\n return;\n case 'variant':\n item.variant = value;\n return;\n case 'coupon':\n item.coupon = value;\n return;\n case 'listName':\n item.listName = value;\n return;\n case 'listId':\n item.listId = value;\n return;\n case 'locationId':\n item.locationId = value;\n return;\n case 'affiliation':\n item.affiliation = value;\n return;\n case 'creativeName':\n item.creativeName = value;\n return;\n case 'creativeSlot':\n item.creativeSlot = value;\n return;\n case 'promotionId':\n item.promotionId = value;\n return;\n case 'promotionName':\n item.promotionName = value;\n return;\n }\n}\n\nfunction setItemNumber(item: GA4Item, key: keyof GA4Item, value: number): void {\n switch (key) {\n case 'price':\n item.price = value;\n return;\n case 'quantity':\n item.quantity = value;\n return;\n case 'discount':\n item.discount = value;\n return;\n case 'listPosition':\n item.listPosition = value;\n return;\n }\n}\n\nexport function parseItem(value: string): GA4Item {\n const item: GA4Item = { custom: {} };\n const customKeys = new Map<string, string>();\n const customVals = new Map<string, string>();\n\n for (const raw of value.split('~')) {\n if (raw.length === 0) continue;\n\n // Variable-length k<N>/v<N> (must match before 2-char prefix lookup\n // because k10/v10 etc are wider than 2 chars).\n const kvMatch = /^([kv])(\\d+)(.*)$/.exec(raw);\n if (kvMatch) {\n const [, kind, idx, val] = kvMatch;\n if (kind === 'k') customKeys.set(idx, val);\n else customVals.set(idx, val);\n continue;\n }\n\n if (raw.length < 2) continue;\n const prefix = raw.slice(0, 2);\n const val = raw.slice(2);\n\n const stringKey = ITEM_STRING_FIELDS[prefix];\n if (stringKey !== undefined) {\n setItemString(item, stringKey, val);\n continue;\n }\n const numberKey = ITEM_NUMBER_FIELDS[prefix];\n if (numberKey !== undefined) {\n const n = Number(val);\n if (!Number.isNaN(n)) setItemNumber(item, numberKey, n);\n continue;\n }\n }\n\n // Pair k<N> with v<N>; drop unmatched.\n for (const [idx, key] of customKeys) {\n const v = customVals.get(idx);\n if (v !== undefined) item.custom[key] = v;\n }\n return item;\n}\n\nexport function parseConsent(hit: { gcs?: string }): WalkerOS.Consent {\n const gcs = hit.gcs;\n if (!gcs || !/^G[01]{3}$/.test(gcs)) return {};\n // gcs[1] is reserved (always '1' for current consent mode v2)\n return {\n marketing: gcs[2] === '1', // ad_storage\n analytics: gcs[3] === '1', // analytics_storage\n };\n}\n\nconst HIT_PARAM_KEYS = new Set([\n 'v',\n 'tid',\n 'cid',\n 'sid',\n 'sct',\n 'seg',\n '_p',\n '_z',\n 'gtm',\n 'dl',\n 'dt',\n 'dr',\n 'ul',\n 'sr',\n 'uid',\n '_dbg',\n '_s',\n '_ss',\n '_fv',\n 'gcs',\n 'gcd',\n 'dma',\n 'dma_cps',\n 'npa',\n 'p',\n]);\n\nexport function parseRequest(req: GA4Request): GA4Hit {\n const queryParams = parseQuery(req.url);\n const hit: GA4HitParams = {};\n const queryEventParams: Record<string, string> = {};\n\n // Split URL params into hit-level vs event-level.\n for (const [k, v] of Object.entries(queryParams)) {\n if (HIT_PARAM_KEYS.has(k)) hit[k] = v;\n else queryEventParams[k] = v;\n }\n\n // GET: event params live in the URL alongside hit params.\n // POST: in body lines.\n const bodyLines = req.body ? parseBody(req.body) : [];\n const rawEvents =\n bodyLines.length > 0\n ? bodyLines\n : Object.keys(queryEventParams).length > 0\n ? [queryEventParams]\n : [];\n\n const events: GA4Event[] = rawEvents\n .filter((raw) => typeof raw.en === 'string' && raw.en.length > 0)\n .map((raw) => buildEvent(raw));\n\n return { hit, events };\n}\n\nfunction buildEvent(raw: Record<string, string>): GA4Event {\n const params: GA4EventParams = { ep: {}, epn: {}, up: {}, upn: {} };\n const itemEntries: Array<[number, string]> = [];\n\n for (const [k, v] of Object.entries(raw)) {\n if (k === 'en') continue;\n\n // pr<N> items\n const prMatch = /^pr(\\d+)$/.exec(k);\n if (prMatch) {\n itemEntries.push([Number(prMatch[1]), v]);\n continue;\n }\n\n // Dotted-key nesting\n if (k.startsWith('ep.')) {\n params.ep[k.slice(3)] = v;\n continue;\n }\n if (k.startsWith('epn.')) {\n const n = Number(v);\n if (!Number.isNaN(n)) params.epn[k.slice(4)] = n;\n continue;\n }\n if (k.startsWith('up.')) {\n params.up[k.slice(3)] = v;\n continue;\n }\n if (k.startsWith('upn.')) {\n const n = Number(v);\n if (!Number.isNaN(n)) params.upn[k.slice(4)] = n;\n continue;\n }\n\n // Standalone numeric keys\n if (k === '_et') {\n const n = Number(v);\n if (!Number.isNaN(n)) params._et = n;\n continue;\n }\n if (k === '_c') {\n params._c = v;\n continue;\n }\n // Unknown standalone keys: drop. Add to GA4EventParams type if a future\n // need surfaces.\n }\n\n itemEntries.sort((a, b) => a[0] - b[0]);\n const items = itemEntries.map(([, v]) => parseItem(v));\n\n return { en: raw.en, params, items };\n}\n","import type { GA4Mapping } from './types';\n\n/**\n * Default GA4 event-name → walkerOS mapping rules.\n * Users may override or extend these via settings.mapping at config time.\n * The `'*'` key is the fallback for unknown event names.\n *\n * Field naming for `data.map`:\n * - Monetary: `currency` from `ep.currency`, `value`/`total` from `epn.value`,\n * `tax` from `epn.tax`, `shipping` from `epn.shipping`, `coupon` from\n * `ep.coupon`.\n * - Promotions read from `firstItem` (synthetic `items[0]` reference exposed by\n * the mapper), since GA4 encodes promotion info inside item tilde strings.\n */\nexport const defaultMapping: GA4Mapping = {\n // --- page ---\n page_view: {\n name: 'page view',\n data: {\n map: {\n id: 'hit.dl',\n title: 'hit.dt',\n referrer: 'hit.dr',\n },\n },\n },\n\n // --- ecommerce ---\n purchase: {\n name: 'order complete',\n data: {\n map: {\n id: 'params.ep.transaction_id',\n currency: 'params.ep.currency',\n total: 'params.epn.value',\n tax: 'params.epn.tax',\n shipping: 'params.epn.shipping',\n coupon: 'params.ep.coupon',\n },\n },\n },\n view_item: {\n name: 'product view',\n data: {\n map: {\n currency: 'params.ep.currency',\n value: 'params.epn.value',\n },\n },\n },\n add_to_cart: {\n name: 'product add',\n data: {\n map: {\n currency: 'params.ep.currency',\n value: 'params.epn.value',\n },\n },\n },\n remove_from_cart: {\n name: 'product remove',\n data: {\n map: {\n currency: 'params.ep.currency',\n value: 'params.epn.value',\n },\n },\n },\n view_cart: {\n name: 'cart view',\n data: {\n map: {\n currency: 'params.ep.currency',\n value: 'params.epn.value',\n },\n },\n },\n begin_checkout: {\n name: 'order start',\n data: {\n map: {\n currency: 'params.ep.currency',\n value: 'params.epn.value',\n coupon: 'params.ep.coupon',\n },\n },\n },\n add_shipping_info: {\n name: 'order shipping',\n data: {\n map: {\n currency: 'params.ep.currency',\n value: 'params.epn.value',\n tier: 'params.ep.shipping_tier',\n },\n },\n },\n add_payment_info: {\n name: 'order payment',\n data: {\n map: {\n currency: 'params.ep.currency',\n value: 'params.epn.value',\n type: 'params.ep.payment_type',\n },\n },\n },\n refund: {\n name: 'order refund',\n data: {\n map: {\n id: 'params.ep.transaction_id',\n currency: 'params.ep.currency',\n total: 'params.epn.value',\n },\n },\n },\n add_to_wishlist: {\n name: 'wishlist add',\n data: {\n map: {\n currency: 'params.ep.currency',\n value: 'params.epn.value',\n },\n },\n },\n\n // --- list / promotion ---\n view_item_list: {\n name: 'list view',\n data: {\n map: {\n id: 'params.ep.item_list_id',\n name: 'params.ep.item_list_name',\n },\n },\n },\n select_item: {\n name: 'product click',\n data: {\n map: {\n list_id: 'params.ep.item_list_id',\n list_name: 'params.ep.item_list_name',\n },\n },\n },\n view_promotion: {\n name: 'promotion view',\n data: {\n map: {\n id: 'firstItem.promotionId',\n name: 'firstItem.promotionName',\n creative: 'firstItem.creativeName',\n slot: 'firstItem.creativeSlot',\n },\n },\n },\n select_promotion: {\n name: 'promotion click',\n data: {\n map: {\n id: 'firstItem.promotionId',\n name: 'firstItem.promotionName',\n creative: 'firstItem.creativeName',\n slot: 'firstItem.creativeSlot',\n },\n },\n },\n select_content: {\n name: 'content select',\n data: {\n map: {\n type: 'params.ep.content_type',\n id: 'params.ep.content_id',\n },\n },\n },\n\n // --- engagement ---\n scroll: {\n name: 'page scroll',\n data: {\n map: {\n percent: 'params.epn.percent_scrolled',\n },\n },\n },\n click: {\n name: 'link click',\n data: {\n map: {\n url: 'params.ep.link_url',\n domain: 'params.ep.link_domain',\n outbound: 'params.ep.outbound',\n },\n },\n },\n file_download: {\n name: 'file download',\n data: {\n map: {\n name: 'params.ep.file_name',\n extension: 'params.ep.file_extension',\n url: 'params.ep.link_url',\n },\n },\n },\n video_start: {\n name: 'video start',\n data: {\n map: {\n title: 'params.ep.video_title',\n duration: 'params.epn.video_duration',\n current: 'params.epn.video_current_time',\n percent: 'params.epn.video_percent',\n },\n },\n },\n video_progress: {\n name: 'video progress',\n data: {\n map: {\n title: 'params.ep.video_title',\n duration: 'params.epn.video_duration',\n current: 'params.epn.video_current_time',\n percent: 'params.epn.video_percent',\n },\n },\n },\n video_complete: {\n name: 'video complete',\n data: {\n map: {\n title: 'params.ep.video_title',\n duration: 'params.epn.video_duration',\n current: 'params.epn.video_current_time',\n percent: 'params.epn.video_percent',\n },\n },\n },\n form_start: {\n name: 'form start',\n data: {\n map: {\n id: 'params.ep.form_id',\n name: 'params.ep.form_name',\n destination: 'params.ep.form_destination',\n },\n },\n },\n form_submit: {\n name: 'form submit',\n data: {\n map: {\n id: 'params.ep.form_id',\n name: 'params.ep.form_name',\n destination: 'params.ep.form_destination',\n },\n },\n },\n search: {\n name: 'search submit',\n data: {\n map: {\n term: 'params.ep.search_term',\n },\n },\n },\n login: {\n name: 'session login',\n data: {\n map: {\n method: 'params.ep.method',\n },\n },\n },\n sign_up: {\n name: 'session signup',\n data: {\n map: {\n method: 'params.ep.method',\n },\n },\n },\n generate_lead: {\n name: 'lead generate',\n data: {\n map: {\n currency: 'params.ep.currency',\n value: 'params.epn.value',\n },\n },\n },\n share: {\n name: 'content share',\n data: {\n map: {\n method: 'params.ep.method',\n type: 'params.ep.content_type',\n id: 'params.ep.item_id',\n },\n },\n },\n\n // --- auto-fired noise: ignore by default (users can override) ---\n user_engagement: { ignore: true },\n session_start: { ignore: true },\n first_visit: { ignore: true },\n\n // --- fallback for unknown event names ---\n '*': {\n name: 'ga4 track',\n data: {\n map: {\n event_name: 'en',\n },\n },\n },\n};\n","import type { Mapping, WalkerOS } from '@walkeros/core';\nimport { getByPath, getId, deleteByPath, isObject } from '@walkeros/core';\nimport type {\n GA4Event,\n GA4Hit,\n GA4HitParams,\n GA4Item,\n GA4Mapping,\n} from './types';\nimport { parseConsent } from './parse';\n\n/**\n * Lookup root for mapping path resolution. Mapping rules reference keys via\n * dotted paths: `hit.dl`, `params.ep.transaction_id`, `params.epn.value`, `items`.\n *\n * `en` exposes the GA4 event name (used by the `*` fallback so unknown events\n * can carry their original name through). `firstItem` exposes `items[0]` so\n * promotion-style mappings can resolve `firstItem.promotionId` etc. without\n * needing array-index syntax in `getByPath`.\n *\n * Typed as `Record<string, unknown> & { ... }` so `getByPath` (which accepts\n * unknown) is happy without any narrowing cast on the call site.\n */\ntype LookupRoot = Record<string, unknown> & {\n hit: GA4HitParams;\n params: GA4Event['params'];\n items: GA4Event['items'];\n en: string;\n firstItem?: GA4Item;\n};\n\n/**\n * Convert a parsed GA4 hit into zero or more walkerOS events.\n * One GA4 hit may carry several events (POST batch); each is mapped\n * independently with hit-level metadata merged in.\n */\nexport function mapHitToEvents(\n hit: GA4Hit,\n mapping: GA4Mapping,\n): WalkerOS.DeepPartialEvent[] {\n const out: WalkerOS.DeepPartialEvent[] = [];\n for (const event of hit.events) {\n const mapped = mapOneEvent(hit.hit, event, mapping);\n if (mapped) out.push(mapped);\n }\n return out;\n}\n\nfunction mapOneEvent(\n hitParams: GA4HitParams,\n event: GA4Event,\n mapping: GA4Mapping,\n): WalkerOS.DeepPartialEvent | null {\n const ruleEntry = mapping[event.en] ?? mapping['*'];\n if (!ruleEntry) return null;\n // For v1, only single-rule entries are supported (no array fan-out).\n const rule: Mapping.Rule = Array.isArray(ruleEntry)\n ? ruleEntry[0]\n : ruleEntry;\n if (!rule || rule.ignore) return null;\n\n const lookup: LookupRoot = {\n hit: hitParams,\n params: event.params,\n items: event.items,\n en: event.en,\n ...(event.items.length > 0 ? { firstItem: event.items[0] } : {}),\n };\n\n const evaluated: WalkerOS.DeepPartialEvent = {};\n\n if (rule.name) {\n const [entity, ...rest] = rule.name.split(' ');\n evaluated.name = rule.name;\n evaluated.entity = entity;\n evaluated.action = rest.join(' ');\n }\n\n if (rule.data !== undefined) {\n let data = evalValue(rule.data, lookup);\n if (rule.remove && isObject(data)) {\n for (const path of rule.remove) data = deleteByPath(data, path);\n }\n if (data !== undefined) {\n evaluated.data = data as WalkerOS.Properties;\n }\n }\n\n // Hit-level merge: user / globals / source.\n evaluated.user = {\n ...(hitParams.uid !== undefined ? { id: hitParams.uid } : {}),\n ...(hitParams.cid !== undefined ? { device: hitParams.cid } : {}),\n ...(hitParams.sid !== undefined ? { session: hitParams.sid } : {}),\n };\n evaluated.globals = {\n ...(hitParams.ul !== undefined ? { language: hitParams.ul } : {}),\n ...(hitParams.sr !== undefined ? { screen: hitParams.sr } : {}),\n };\n evaluated.source = {\n type: 'ga4',\n ...(hitParams.p !== undefined ? { platform: hitParams.p } : {}),\n };\n\n // Consent from gcs string, id from hit._p (fallback to generated string),\n // timestamp from sid (epoch seconds → ms; falls back to wall-clock now),\n // timing from event._et (ms; 0 if absent), trigger hard-coded to \"ga4\" for v1.\n evaluated.consent = parseConsent(hitParams);\n evaluated.id = hitParams._p ?? getId();\n const sidNum = hitParams.sid ? Number(hitParams.sid) : NaN;\n evaluated.timestamp =\n !Number.isNaN(sidNum) && sidNum > 0 ? sidNum * 1000 : Date.now();\n evaluated.timing = event.params._et ?? 0;\n evaluated.trigger = 'ga4';\n\n if (event.items.length > 0) {\n evaluated.nested = itemsToNested(event.items);\n }\n\n return evaluated;\n}\n\n/**\n * GA4 items → walkerOS nested product entities.\n * Field naming: camelCase GA4Item keys are emitted as snake_case data keys\n * (`listName` → `list_name`, `promotionId` → `promotion_id`, etc).\n * Custom k<N>/v<N> pairs are spread as-is.\n *\n * Returns `WalkerOS.Entities` (i.e. `Array<WalkerOS.Entity>`). Note that the\n * canonical `WalkerOS.Entity` interface uses `entity: string` as the kind\n * discriminator (not `type`).\n */\nfunction itemsToNested(items: GA4Item[]): WalkerOS.Entities {\n return items.map((item): WalkerOS.Entity => {\n const data: WalkerOS.Properties = {};\n if (item.id !== undefined) data.id = item.id;\n if (item.name !== undefined) data.name = item.name;\n if (item.brand !== undefined) data.brand = item.brand;\n if (item.category !== undefined) data.category = item.category;\n if (item.category2 !== undefined) data.category2 = item.category2;\n if (item.category3 !== undefined) data.category3 = item.category3;\n if (item.category4 !== undefined) data.category4 = item.category4;\n if (item.category5 !== undefined) data.category5 = item.category5;\n if (item.variant !== undefined) data.variant = item.variant;\n if (item.price !== undefined) data.price = item.price;\n if (item.quantity !== undefined) data.quantity = item.quantity;\n if (item.coupon !== undefined) data.coupon = item.coupon;\n if (item.discount !== undefined) data.discount = item.discount;\n if (item.listName !== undefined) data.list_name = item.listName;\n if (item.listId !== undefined) data.list_id = item.listId;\n if (item.listPosition !== undefined) data.list_position = item.listPosition;\n if (item.locationId !== undefined) data.location_id = item.locationId;\n if (item.affiliation !== undefined) data.affiliation = item.affiliation;\n if (item.creativeName !== undefined) data.creative_name = item.creativeName;\n if (item.creativeSlot !== undefined) data.creative_slot = item.creativeSlot;\n if (item.promotionId !== undefined) data.promotion_id = item.promotionId;\n if (item.promotionName !== undefined)\n data.promotion_name = item.promotionName;\n for (const [k, v] of Object.entries(item.custom)) data[k] = v;\n return { entity: 'product', data, nested: [], context: {} };\n });\n}\n\n/**\n * Minimal mapping evaluator. v1 supports:\n * - string → path lookup via getByPath\n * - Array<Value> → fallback chain: first non-undefined wins\n * - { value: X } → literal\n * - { key: 'path' } → path lookup\n * - { map: {...} } → recursive object build\n *\n * Deferred to v2: condition, loop, fn, validate, set, consent, $code.\n */\nfunction evalValue(\n value: Mapping.Value | Mapping.Values,\n root: LookupRoot,\n): unknown {\n if (Array.isArray(value)) {\n for (const v of value) {\n const resolved = evalValue(v, root);\n if (resolved !== undefined && resolved !== null) return resolved;\n }\n return undefined;\n }\n if (typeof value === 'string') {\n return getByPath(root, value);\n }\n if (typeof value === 'object' && value !== null) {\n if ('value' in value && value.value !== undefined) return value.value;\n if ('key' in value && typeof value.key === 'string') {\n return getByPath(root, value.key);\n }\n if ('map' in value && value.map) {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value.map)) {\n const resolved = evalValue(v, root);\n if (resolved !== undefined) out[k] = resolved;\n }\n return out;\n }\n }\n return undefined;\n}\n","export * as step from './step';\n","import type { Flow } from '@walkeros/core';\n\n/**\n * Step examples for transformer-ga4.\n *\n * `in` is a raw `GA4Request` (`{ url, body? }`) — the shape the transformer\n * reads from `ctx.ingest`. `out` is the array of effect tuples produced by\n * pushing that request through the transformer:\n *\n * - Mapped event (single): `out: [['return', event]]`\n * - Mapped events (fan-out): `out: [['return', e1], ['return', e2], ...]`\n * - Dropped (ignore / no en): `out: [['return', false]]`\n *\n * Examples set `_p` (becomes `event.id`) and `sid` (becomes `event.timestamp`\n * in ms via `sid * 1000`) so the assertions are deterministic. The synthetic\n * walkerOS event shape mirrors what `mapHitToEvents` produces in `map.ts`:\n * - `entity` + `action` derived from rule.name's first/rest words\n * - `user.{id,device,session}` from `uid/cid/sid`\n * - `source: { type: 'ga4', platform? }` from `p`\n * - `consent` from `gcs` (`G100` → all false, `G111` → all true)\n * - `timing` from event `_et` (defaults to 0 if absent)\n * - `trigger: 'ga4'` (hard-coded in v1)\n * - `nested[]` only set when items are present (POST-only example below)\n */\n\n// --- helpers (typed, no casts) -----------------------------------------------\n\nconst SID = '1700000000'; // → timestamp 1700000000000\n\nfunction ga4Event(overrides: Record<string, unknown>): Record<string, unknown> {\n return {\n id: 'p1',\n timestamp: 1700000000000,\n timing: 0,\n trigger: 'ga4',\n user: { device: 'cid-1', session: SID },\n globals: {},\n source: { type: 'ga4' },\n consent: {},\n ...overrides,\n };\n}\n\n// --- examples ---------------------------------------------------------------\n\nexport const pageView: Flow.StepExample = {\n title: 'Page view',\n description:\n 'A standard GA4 page_view hit decoded to a walkerOS page view with id, title, and referrer.',\n in: {\n url:\n 'https://www.google-analytics.com/g/collect' +\n '?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid=' +\n SID +\n '&en=page_view' +\n '&dl=https%3A%2F%2Fshop.example.com%2Fproducts%2Fsku-123' +\n '&dt=Trail%20Runner%20Pro' +\n '&dr=https%3A%2F%2Fshop.example.com%2F',\n },\n out: [\n [\n 'return',\n ga4Event({\n name: 'page view',\n entity: 'page',\n action: 'view',\n data: {\n id: 'https://shop.example.com/products/sku-123',\n title: 'Trail Runner Pro',\n referrer: 'https://shop.example.com/',\n },\n }),\n ],\n ],\n};\n\nexport const purchase: Flow.StepExample = {\n title: 'Purchase (canary)',\n description:\n 'A GA4 purchase hit decoded to a walkerOS order complete event with id, currency, total, tax, shipping, and coupon.',\n in: {\n url:\n 'https://www.google-analytics.com/g/collect' +\n '?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid=' +\n SID +\n '&en=purchase' +\n '&ep.transaction_id=T-9001' +\n '&ep.currency=EUR' +\n '&epn.value=149.97' +\n '&epn.tax=23.97' +\n '&epn.shipping=4.95' +\n '&ep.coupon=WELCOME10',\n },\n out: [\n [\n 'return',\n ga4Event({\n name: 'order complete',\n entity: 'order',\n action: 'complete',\n data: {\n id: 'T-9001',\n currency: 'EUR',\n total: 149.97,\n tax: 23.97,\n shipping: 4.95,\n coupon: 'WELCOME10',\n },\n }),\n ],\n ],\n};\n\nexport const viewItem: Flow.StepExample = {\n title: 'View item',\n description:\n 'A GA4 view_item hit decoded to a walkerOS product view event with currency and value.',\n in: {\n url:\n 'https://www.google-analytics.com/g/collect' +\n '?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid=' +\n SID +\n '&en=view_item&ep.currency=EUR&epn.value=129.99',\n },\n out: [\n [\n 'return',\n ga4Event({\n name: 'product view',\n entity: 'product',\n action: 'view',\n data: { currency: 'EUR', value: 129.99 },\n }),\n ],\n ],\n};\n\nexport const addToCart: Flow.StepExample = {\n title: 'Add to cart',\n description:\n 'A GA4 add_to_cart hit decoded to a walkerOS product add event with currency and value.',\n in: {\n url:\n 'https://www.google-analytics.com/g/collect' +\n '?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid=' +\n SID +\n '&en=add_to_cart&ep.currency=EUR&epn.value=129.99',\n },\n out: [\n [\n 'return',\n ga4Event({\n name: 'product add',\n entity: 'product',\n action: 'add',\n data: { currency: 'EUR', value: 129.99 },\n }),\n ],\n ],\n};\n\nexport const beginCheckout: Flow.StepExample = {\n title: 'Begin checkout',\n description:\n 'A GA4 begin_checkout hit decoded to a walkerOS order start event with currency, value, and coupon.',\n in: {\n url:\n 'https://www.google-analytics.com/g/collect' +\n '?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid=' +\n SID +\n '&en=begin_checkout' +\n '&ep.currency=EUR&epn.value=149.97&ep.coupon=WELCOME10',\n },\n out: [\n [\n 'return',\n ga4Event({\n name: 'order start',\n entity: 'order',\n action: 'start',\n data: {\n currency: 'EUR',\n value: 149.97,\n coupon: 'WELCOME10',\n },\n }),\n ],\n ],\n};\n\nexport const scroll: Flow.StepExample = {\n title: 'Scroll',\n description:\n 'A GA4 scroll hit decoded to a walkerOS page scroll event with the percent_scrolled value.',\n in: {\n url:\n 'https://www.google-analytics.com/g/collect' +\n '?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid=' +\n SID +\n '&en=scroll&epn.percent_scrolled=90',\n },\n out: [\n [\n 'return',\n ga4Event({\n name: 'page scroll',\n entity: 'page',\n action: 'scroll',\n data: { percent: 90 },\n }),\n ],\n ],\n};\n\nexport const search: Flow.StepExample = {\n title: 'Search',\n description:\n 'A GA4 search hit decoded to a walkerOS search submit event carrying the search term.',\n in: {\n url:\n 'https://www.google-analytics.com/g/collect' +\n '?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid=' +\n SID +\n '&en=search&ep.search_term=trail%20runner',\n },\n out: [\n [\n 'return',\n ga4Event({\n name: 'search submit',\n entity: 'search',\n action: 'submit',\n data: { term: 'trail runner' },\n }),\n ],\n ],\n};\n\nexport const login: Flow.StepExample = {\n title: 'Login',\n description:\n 'A GA4 login hit decoded to a walkerOS session login event with the auth method.',\n in: {\n url:\n 'https://www.google-analytics.com/g/collect' +\n '?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid=' +\n SID +\n '&en=login&ep.method=google',\n },\n out: [\n [\n 'return',\n ga4Event({\n name: 'session login',\n entity: 'session',\n action: 'login',\n data: { method: 'google' },\n }),\n ],\n ],\n};\n\nexport const customEvent: Flow.StepExample = {\n title: 'Custom event (* fallback)',\n description:\n 'Unknown GA4 event names hit the * fallback rule and surface as a ga4 track event carrying the original name.',\n in: {\n url:\n 'https://www.google-analytics.com/g/collect' +\n '?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid=' +\n SID +\n '&en=newsletter_subscribe&ep.source=footer',\n },\n out: [\n [\n 'return',\n ga4Event({\n name: 'ga4 track',\n entity: 'ga4',\n action: 'track',\n data: { event_name: 'newsletter_subscribe' },\n }),\n ],\n ],\n};\n\nexport const consentDenied: Flow.StepExample = {\n title: 'Consent denied (gcs=G100)',\n description:\n 'A page_view hit with gcs=G100 still maps, with consent.{marketing,analytics} both false on the resulting event.',\n in: {\n url:\n 'https://www.google-analytics.com/g/collect' +\n '?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid=' +\n SID +\n '&gcs=G100' +\n '&en=page_view&dl=https%3A%2F%2Fx&dt=X',\n },\n out: [\n [\n 'return',\n ga4Event({\n name: 'page view',\n entity: 'page',\n action: 'view',\n data: { id: 'https://x', title: 'X' },\n consent: { marketing: false, analytics: false },\n }),\n ],\n ],\n};\n\nexport const userEngagementIgnored: Flow.StepExample = {\n title: 'user_engagement (ignored)',\n description:\n 'Auto-fired GA4 user_engagement events are dropped by default — the transformer returns false.',\n in: {\n url:\n 'https://www.google-analytics.com/g/collect' +\n '?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid=' +\n SID +\n '&en=user_engagement&_et=1500',\n },\n out: [['return', false]],\n};\n\nexport const batchPost: Flow.StepExample = {\n title: 'Batched POST (fan-out)',\n description:\n 'A single POST request carrying two newline-separated events fans out into two walkerOS events.',\n in: {\n url:\n 'https://www.google-analytics.com/g/collect' +\n '?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid=' +\n SID,\n body: [\n 'en=add_to_cart&ep.currency=EUR&epn.value=19.99',\n 'en=add_to_cart&ep.currency=EUR&epn.value=29.99',\n ].join('\\n'),\n },\n out: [\n [\n 'return',\n ga4Event({\n name: 'product add',\n entity: 'product',\n action: 'add',\n data: { currency: 'EUR', value: 19.99 },\n }),\n ],\n [\n 'return',\n ga4Event({\n name: 'product add',\n entity: 'product',\n action: 'add',\n data: { currency: 'EUR', value: 29.99 },\n }),\n ],\n ],\n};\n"],"mappings":"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","names":["val"]}
|
package/dist/dev.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e=Object.defineProperty,t=(t,a)=>{for(var i in a)e(t,i,{get:a[i],enumerable:!0})};function a(e){const t={},a=e.indexOf("?");if(-1===a)return t;return new URLSearchParams(e.slice(a+1)).forEach((e,a)=>{t[a]=e}),t}function i(e){return e?e.split(/\r?\n/).map(e=>e.trim()).filter(e=>e.length>0).map(e=>{const t={};return new URLSearchParams(e).forEach((e,a)=>{t[a]=e}),t}):[]}var r={id:"id",nm:"name",br:"brand",ca:"category",c2:"category2",c3:"category3",c4:"category4",c5:"category5",va:"variant",cp:"coupon",ln:"listName",li:"listId",lo:"locationId",af:"affiliation",cn:"creativeName",cs:"creativeSlot",pi:"promotionId",pn:"promotionName"},n={pr:"price",qt:"quantity",ds:"discount",lp:"listPosition"};function o(e,t,a){switch(t){case"id":return void(e.id=a);case"name":return void(e.name=a);case"brand":return void(e.brand=a);case"category":return void(e.category=a);case"category2":return void(e.category2=a);case"category3":return void(e.category3=a);case"category4":return void(e.category4=a);case"category5":return void(e.category5=a);case"variant":return void(e.variant=a);case"coupon":return void(e.coupon=a);case"listName":return void(e.listName=a);case"listId":return void(e.listId=a);case"locationId":return void(e.locationId=a);case"affiliation":return void(e.affiliation=a);case"creativeName":return void(e.creativeName=a);case"creativeSlot":return void(e.creativeSlot=a);case"promotionId":return void(e.promotionId=a);case"promotionName":return void(e.promotionName=a)}}function c(e,t,a){switch(t){case"price":return void(e.price=a);case"quantity":return void(e.quantity=a);case"discount":return void(e.discount=a);case"listPosition":return void(e.listPosition=a)}}function s(e){const t={custom:{}},a=new Map,i=new Map;for(const s of e.split("~")){if(0===s.length)continue;const e=/^([kv])(\d+)(.*)$/.exec(s);if(e){const[,t,r,n]=e;"k"===t?a.set(r,n):i.set(r,n);continue}if(s.length<2)continue;const p=s.slice(0,2),d=s.slice(2),m=r[p];if(void 0!==m){o(t,m,d);continue}const l=n[p];if(void 0!==l){const e=Number(d);Number.isNaN(e)||c(t,l,e);continue}}for(const[e,r]of a){const a=i.get(e);void 0!==a&&(t.custom[r]=a)}return t}function p(e){const t=e.gcs;return t&&/^G[01]{3}$/.test(t)?{marketing:"1"===t[2],analytics:"1"===t[3]}:{}}var d=new Set(["v","tid","cid","sid","sct","seg","_p","_z","gtm","dl","dt","dr","ul","sr","uid","_dbg","_s","_ss","_fv","gcs","gcd","dma","dma_cps","npa","p"]);function m(e){const t=a(e.url),r={},n={};for(const[e,a]of Object.entries(t))d.has(e)?r[e]=a:n[e]=a;const o=e.body?i(e.body):[];return{hit:r,events:(o.length>0?o:Object.keys(n).length>0?[n]:[]).filter(e=>"string"==typeof e.en&&e.en.length>0).map(e=>function(e){const t={ep:{},epn:{},up:{},upn:{}},a=[];for(const[i,r]of Object.entries(e)){if("en"===i)continue;const e=/^pr(\d+)$/.exec(i);if(e)a.push([Number(e[1]),r]);else if(i.startsWith("ep."))t.ep[i.slice(3)]=r;else{if(i.startsWith("epn.")){const e=Number(r);Number.isNaN(e)||(t.epn[i.slice(4)]=e);continue}if(i.startsWith("up."))t.up[i.slice(3)]=r;else{if(i.startsWith("upn.")){const e=Number(r);Number.isNaN(e)||(t.upn[i.slice(4)]=e);continue}if("_et"===i){const e=Number(r);Number.isNaN(e)||(t._et=e);continue}"_c"!==i||(t._c=r)}}}a.sort((e,t)=>e[0]-t[0]);const i=a.map(([,e])=>s(e));return{en:e.en,params:t,items:i}}(e))}}var l={page_view:{name:"page view",data:{map:{id:"hit.dl",title:"hit.dt",referrer:"hit.dr"}}},purchase:{name:"order complete",data:{map:{id:"params.ep.transaction_id",currency:"params.ep.currency",total:"params.epn.value",tax:"params.epn.tax",shipping:"params.epn.shipping",coupon:"params.ep.coupon"}}},view_item:{name:"product view",data:{map:{currency:"params.ep.currency",value:"params.epn.value"}}},add_to_cart:{name:"product add",data:{map:{currency:"params.ep.currency",value:"params.epn.value"}}},remove_from_cart:{name:"product remove",data:{map:{currency:"params.ep.currency",value:"params.epn.value"}}},view_cart:{name:"cart view",data:{map:{currency:"params.ep.currency",value:"params.epn.value"}}},begin_checkout:{name:"order start",data:{map:{currency:"params.ep.currency",value:"params.epn.value",coupon:"params.ep.coupon"}}},add_shipping_info:{name:"order shipping",data:{map:{currency:"params.ep.currency",value:"params.epn.value",tier:"params.ep.shipping_tier"}}},add_payment_info:{name:"order payment",data:{map:{currency:"params.ep.currency",value:"params.epn.value",type:"params.ep.payment_type"}}},refund:{name:"order refund",data:{map:{id:"params.ep.transaction_id",currency:"params.ep.currency",total:"params.epn.value"}}},add_to_wishlist:{name:"wishlist add",data:{map:{currency:"params.ep.currency",value:"params.epn.value"}}},view_item_list:{name:"list view",data:{map:{id:"params.ep.item_list_id",name:"params.ep.item_list_name"}}},select_item:{name:"product click",data:{map:{list_id:"params.ep.item_list_id",list_name:"params.ep.item_list_name"}}},view_promotion:{name:"promotion view",data:{map:{id:"firstItem.promotionId",name:"firstItem.promotionName",creative:"firstItem.creativeName",slot:"firstItem.creativeSlot"}}},select_promotion:{name:"promotion click",data:{map:{id:"firstItem.promotionId",name:"firstItem.promotionName",creative:"firstItem.creativeName",slot:"firstItem.creativeSlot"}}},select_content:{name:"content select",data:{map:{type:"params.ep.content_type",id:"params.ep.content_id"}}},scroll:{name:"page scroll",data:{map:{percent:"params.epn.percent_scrolled"}}},click:{name:"link click",data:{map:{url:"params.ep.link_url",domain:"params.ep.link_domain",outbound:"params.ep.outbound"}}},file_download:{name:"file download",data:{map:{name:"params.ep.file_name",extension:"params.ep.file_extension",url:"params.ep.link_url"}}},video_start:{name:"video start",data:{map:{title:"params.ep.video_title",duration:"params.epn.video_duration",current:"params.epn.video_current_time",percent:"params.epn.video_percent"}}},video_progress:{name:"video progress",data:{map:{title:"params.ep.video_title",duration:"params.epn.video_duration",current:"params.epn.video_current_time",percent:"params.epn.video_percent"}}},video_complete:{name:"video complete",data:{map:{title:"params.ep.video_title",duration:"params.epn.video_duration",current:"params.epn.video_current_time",percent:"params.epn.video_percent"}}},form_start:{name:"form start",data:{map:{id:"params.ep.form_id",name:"params.ep.form_name",destination:"params.ep.form_destination"}}},form_submit:{name:"form submit",data:{map:{id:"params.ep.form_id",name:"params.ep.form_name",destination:"params.ep.form_destination"}}},search:{name:"search submit",data:{map:{term:"params.ep.search_term"}}},login:{name:"session login",data:{map:{method:"params.ep.method"}}},sign_up:{name:"session signup",data:{map:{method:"params.ep.method"}}},generate_lead:{name:"lead generate",data:{map:{currency:"params.ep.currency",value:"params.epn.value"}}},share:{name:"content share",data:{map:{method:"params.ep.method",type:"params.ep.content_type",id:"params.ep.item_id"}}},user_engagement:{ignore:!0},session_start:{ignore:!0},first_visit:{ignore:!0},"*":{name:"ga4 track",data:{map:{event_name:"en"}}}};import{getByPath as u,getId as v}from"@walkeros/core";function g(e,t){const a=[];for(const i of e.events){const r=_(e.hit,i,t);r&&a.push(r)}return a}function _(e,t,a){const i=a[t.en]??a["*"];if(!i)return null;const r=Array.isArray(i)?i[0]:i;if(!r||r.ignore)return null;const n={hit:e,params:t.params,items:t.items,en:t.en,...t.items.length>0?{firstItem:t.items[0]}:{}},o={};if(r.name){const[e,...t]=r.name.split(" ");o.name=r.name,o.entity=e,o.action=t.join(" ")}if(void 0!==r.data){const e=y(r.data,n);void 0!==e&&(o.data=e)}o.user={...void 0!==e.uid?{id:e.uid}:{},...void 0!==e.cid?{device:e.cid}:{},...void 0!==e.sid?{session:e.sid}:{}},o.globals={...void 0!==e.ul?{language:e.ul}:{},...void 0!==e.sr?{screen:e.sr}:{}},o.source={type:"ga4",...void 0!==e.p?{platform:e.p}:{}},o.consent=p(e),o.id=e._p??v();const c=e.sid?Number(e.sid):NaN;return o.timestamp=!Number.isNaN(c)&&c>0?1e3*c:Date.now(),o.timing=t.params._et??0,o.trigger="ga4",t.items.length>0&&(o.nested=t.items.map(e=>{const t={};void 0!==e.id&&(t.id=e.id),void 0!==e.name&&(t.name=e.name),void 0!==e.brand&&(t.brand=e.brand),void 0!==e.category&&(t.category=e.category),void 0!==e.category2&&(t.category2=e.category2),void 0!==e.category3&&(t.category3=e.category3),void 0!==e.category4&&(t.category4=e.category4),void 0!==e.category5&&(t.category5=e.category5),void 0!==e.variant&&(t.variant=e.variant),void 0!==e.price&&(t.price=e.price),void 0!==e.quantity&&(t.quantity=e.quantity),void 0!==e.coupon&&(t.coupon=e.coupon),void 0!==e.discount&&(t.discount=e.discount),void 0!==e.listName&&(t.list_name=e.listName),void 0!==e.listId&&(t.list_id=e.listId),void 0!==e.listPosition&&(t.list_position=e.listPosition),void 0!==e.locationId&&(t.location_id=e.locationId),void 0!==e.affiliation&&(t.affiliation=e.affiliation),void 0!==e.creativeName&&(t.creative_name=e.creativeName),void 0!==e.creativeSlot&&(t.creative_slot=e.creativeSlot),void 0!==e.promotionId&&(t.promotion_id=e.promotionId),void 0!==e.promotionName&&(t.promotion_name=e.promotionName);for(const[a,i]of Object.entries(e.custom))t[a]=i;return{entity:"product",data:t,nested:[],context:{}}})),o}function y(e,t){if(Array.isArray(e))for(const a of e){const e=y(a,t);if(null!=e)return e}else{if("string"==typeof e)return u(t,e);if("object"==typeof e&&null!==e){if("value"in e&&void 0!==e.value)return e.value;if("key"in e&&"string"==typeof e.key)return u(t,e.key);if("map"in e&&e.map){const a={};for(const[i,r]of Object.entries(e.map)){const e=y(r,t);void 0!==e&&(a[i]=e)}return a}}}}var f={};t(f,{step:()=>h});var h={};t(h,{addToCart:()=>A,batchPost:()=>M,beginCheckout:()=>I,consentDenied:()=>x,customEvent:()=>O,login:()=>S,pageView:()=>E,purchase:()=>N,scroll:()=>P,search:()=>G,userEngagementIgnored:()=>L,viewItem:()=>k});var w="1700000000";function b(e){return{id:"p1",timestamp:17e11,timing:0,trigger:"ga4",user:{device:"cid-1",session:w},globals:{},source:{type:"ga4"},consent:{},...e}}var E={title:"Page view",description:"A standard GA4 page_view hit decoded to a walkerOS page view with id, title, and referrer.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+w+"&en=page_view&dl=https%3A%2F%2Fshop.example.com%2Fproducts%2Fsku-123&dt=Trail%20Runner%20Pro&dr=https%3A%2F%2Fshop.example.com%2F"},out:[["return",b({name:"page view",entity:"page",action:"view",data:{id:"https://shop.example.com/products/sku-123",title:"Trail Runner Pro",referrer:"https://shop.example.com/"}})]]},N={title:"Purchase (canary)",description:"A GA4 purchase hit decoded to a walkerOS order complete event with id, currency, total, tax, shipping, and coupon.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+w+"&en=purchase&ep.transaction_id=T-9001&ep.currency=EUR&epn.value=149.97&epn.tax=23.97&epn.shipping=4.95&ep.coupon=WELCOME10"},out:[["return",b({name:"order complete",entity:"order",action:"complete",data:{id:"T-9001",currency:"EUR",total:149.97,tax:23.97,shipping:4.95,coupon:"WELCOME10"}})]]},k={title:"View item",description:"A GA4 view_item hit decoded to a walkerOS product view event with currency and value.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+w+"&en=view_item&ep.currency=EUR&epn.value=129.99"},out:[["return",b({name:"product view",entity:"product",action:"view",data:{currency:"EUR",value:129.99}})]]},A={title:"Add to cart",description:"A GA4 add_to_cart hit decoded to a walkerOS product add event with currency and value.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+w+"&en=add_to_cart&ep.currency=EUR&epn.value=129.99"},out:[["return",b({name:"product add",entity:"product",action:"add",data:{currency:"EUR",value:129.99}})]]},I={title:"Begin checkout",description:"A GA4 begin_checkout hit decoded to a walkerOS order start event with currency, value, and coupon.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+w+"&en=begin_checkout&ep.currency=EUR&epn.value=149.97&ep.coupon=WELCOME10"},out:[["return",b({name:"order start",entity:"order",action:"start",data:{currency:"EUR",value:149.97,coupon:"WELCOME10"}})]]},P={title:"Scroll",description:"A GA4 scroll hit decoded to a walkerOS page scroll event with the percent_scrolled value.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+w+"&en=scroll&epn.percent_scrolled=90"},out:[["return",b({name:"page scroll",entity:"page",action:"scroll",data:{percent:90}})]]},G={title:"Search",description:"A GA4 search hit decoded to a walkerOS search submit event carrying the search term.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+w+"&en=search&ep.search_term=trail%20runner"},out:[["return",b({name:"search submit",entity:"search",action:"submit",data:{term:"trail runner"}})]]},S={title:"Login",description:"A GA4 login hit decoded to a walkerOS session login event with the auth method.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+w+"&en=login&ep.method=google"},out:[["return",b({name:"session login",entity:"session",action:"login",data:{method:"google"}})]]},O={title:"Custom event (* fallback)",description:"Unknown GA4 event names hit the * fallback rule and surface as a ga4 track event carrying the original name.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+w+"&en=newsletter_subscribe&ep.source=footer"},out:[["return",b({name:"ga4 track",entity:"ga4",action:"track",data:{event_name:"newsletter_subscribe"}})]]},x={title:"Consent denied (gcs=G100)",description:"A page_view hit with gcs=G100 still maps, with consent.{marketing,analytics} both false on the resulting event.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+w+"&gcs=G100&en=page_view&dl=https%3A%2F%2Fx&dt=X"},out:[["return",b({name:"page view",entity:"page",action:"view",data:{id:"https://x",title:"X"},consent:{marketing:!1,analytics:!1}})]]},L={title:"user_engagement (ignored)",description:"Auto-fired GA4 user_engagement events are dropped by default — the transformer returns false.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+w+"&en=user_engagement&_et=1500"},out:[["return",!1]]},M={title:"Batched POST (fan-out)",description:"A single POST request carrying two newline-separated events fans out into two walkerOS events.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+w,body:["en=add_to_cart&ep.currency=EUR&epn.value=19.99","en=add_to_cart&ep.currency=EUR&epn.value=29.99"].join("\n")},out:[["return",b({name:"product add",entity:"product",action:"add",data:{currency:"EUR",value:19.99}})],["return",b({name:"product add",entity:"product",action:"add",data:{currency:"EUR",value:29.99}})]]};export{l as defaultMapping,f as examples,g as mapHitToEvents,i as parseBody,p as parseConsent,s as parseItem,a as parseQuery,m as parseRequest};//# sourceMappingURL=dev.mjs.map
|
|
1
|
+
var e=Object.defineProperty,t=(t,a)=>{for(var i in a)e(t,i,{get:a[i],enumerable:!0})};function a(e){const t={},a=e.indexOf("?");if(-1===a)return t;return new URLSearchParams(e.slice(a+1)).forEach((e,a)=>{t[a]=e}),t}function i(e){return e?e.split(/\r?\n/).map(e=>e.trim()).filter(e=>e.length>0).map(e=>{const t={};return new URLSearchParams(e).forEach((e,a)=>{t[a]=e}),t}):[]}var r={id:"id",nm:"name",br:"brand",ca:"category",c2:"category2",c3:"category3",c4:"category4",c5:"category5",va:"variant",cp:"coupon",ln:"listName",li:"listId",lo:"locationId",af:"affiliation",cn:"creativeName",cs:"creativeSlot",pi:"promotionId",pn:"promotionName"},n={pr:"price",qt:"quantity",ds:"discount",lp:"listPosition"};function o(e,t,a){switch(t){case"id":return void(e.id=a);case"name":return void(e.name=a);case"brand":return void(e.brand=a);case"category":return void(e.category=a);case"category2":return void(e.category2=a);case"category3":return void(e.category3=a);case"category4":return void(e.category4=a);case"category5":return void(e.category5=a);case"variant":return void(e.variant=a);case"coupon":return void(e.coupon=a);case"listName":return void(e.listName=a);case"listId":return void(e.listId=a);case"locationId":return void(e.locationId=a);case"affiliation":return void(e.affiliation=a);case"creativeName":return void(e.creativeName=a);case"creativeSlot":return void(e.creativeSlot=a);case"promotionId":return void(e.promotionId=a);case"promotionName":return void(e.promotionName=a)}}function c(e,t,a){switch(t){case"price":return void(e.price=a);case"quantity":return void(e.quantity=a);case"discount":return void(e.discount=a);case"listPosition":return void(e.listPosition=a)}}function s(e){const t={custom:{}},a=new Map,i=new Map;for(const s of e.split("~")){if(0===s.length)continue;const e=/^([kv])(\d+)(.*)$/.exec(s);if(e){const[,t,r,n]=e;"k"===t?a.set(r,n):i.set(r,n);continue}if(s.length<2)continue;const p=s.slice(0,2),d=s.slice(2),m=r[p];if(void 0!==m){o(t,m,d);continue}const l=n[p];if(void 0!==l){const e=Number(d);Number.isNaN(e)||c(t,l,e);continue}}for(const[e,r]of a){const a=i.get(e);void 0!==a&&(t.custom[r]=a)}return t}function p(e){const t=e.gcs;return t&&/^G[01]{3}$/.test(t)?{marketing:"1"===t[2],analytics:"1"===t[3]}:{}}var d=new Set(["v","tid","cid","sid","sct","seg","_p","_z","gtm","dl","dt","dr","ul","sr","uid","_dbg","_s","_ss","_fv","gcs","gcd","dma","dma_cps","npa","p"]);function m(e){const t=a(e.url),r={},n={};for(const[e,a]of Object.entries(t))d.has(e)?r[e]=a:n[e]=a;const o=e.body?i(e.body):[];return{hit:r,events:(o.length>0?o:Object.keys(n).length>0?[n]:[]).filter(e=>"string"==typeof e.en&&e.en.length>0).map(e=>function(e){const t={ep:{},epn:{},up:{},upn:{}},a=[];for(const[i,r]of Object.entries(e)){if("en"===i)continue;const e=/^pr(\d+)$/.exec(i);if(e)a.push([Number(e[1]),r]);else if(i.startsWith("ep."))t.ep[i.slice(3)]=r;else{if(i.startsWith("epn.")){const e=Number(r);Number.isNaN(e)||(t.epn[i.slice(4)]=e);continue}if(i.startsWith("up."))t.up[i.slice(3)]=r;else{if(i.startsWith("upn.")){const e=Number(r);Number.isNaN(e)||(t.upn[i.slice(4)]=e);continue}if("_et"===i){const e=Number(r);Number.isNaN(e)||(t._et=e);continue}"_c"!==i||(t._c=r)}}}a.sort((e,t)=>e[0]-t[0]);const i=a.map(([,e])=>s(e));return{en:e.en,params:t,items:i}}(e))}}var l={page_view:{name:"page view",data:{map:{id:"hit.dl",title:"hit.dt",referrer:"hit.dr"}}},purchase:{name:"order complete",data:{map:{id:"params.ep.transaction_id",currency:"params.ep.currency",total:"params.epn.value",tax:"params.epn.tax",shipping:"params.epn.shipping",coupon:"params.ep.coupon"}}},view_item:{name:"product view",data:{map:{currency:"params.ep.currency",value:"params.epn.value"}}},add_to_cart:{name:"product add",data:{map:{currency:"params.ep.currency",value:"params.epn.value"}}},remove_from_cart:{name:"product remove",data:{map:{currency:"params.ep.currency",value:"params.epn.value"}}},view_cart:{name:"cart view",data:{map:{currency:"params.ep.currency",value:"params.epn.value"}}},begin_checkout:{name:"order start",data:{map:{currency:"params.ep.currency",value:"params.epn.value",coupon:"params.ep.coupon"}}},add_shipping_info:{name:"order shipping",data:{map:{currency:"params.ep.currency",value:"params.epn.value",tier:"params.ep.shipping_tier"}}},add_payment_info:{name:"order payment",data:{map:{currency:"params.ep.currency",value:"params.epn.value",type:"params.ep.payment_type"}}},refund:{name:"order refund",data:{map:{id:"params.ep.transaction_id",currency:"params.ep.currency",total:"params.epn.value"}}},add_to_wishlist:{name:"wishlist add",data:{map:{currency:"params.ep.currency",value:"params.epn.value"}}},view_item_list:{name:"list view",data:{map:{id:"params.ep.item_list_id",name:"params.ep.item_list_name"}}},select_item:{name:"product click",data:{map:{list_id:"params.ep.item_list_id",list_name:"params.ep.item_list_name"}}},view_promotion:{name:"promotion view",data:{map:{id:"firstItem.promotionId",name:"firstItem.promotionName",creative:"firstItem.creativeName",slot:"firstItem.creativeSlot"}}},select_promotion:{name:"promotion click",data:{map:{id:"firstItem.promotionId",name:"firstItem.promotionName",creative:"firstItem.creativeName",slot:"firstItem.creativeSlot"}}},select_content:{name:"content select",data:{map:{type:"params.ep.content_type",id:"params.ep.content_id"}}},scroll:{name:"page scroll",data:{map:{percent:"params.epn.percent_scrolled"}}},click:{name:"link click",data:{map:{url:"params.ep.link_url",domain:"params.ep.link_domain",outbound:"params.ep.outbound"}}},file_download:{name:"file download",data:{map:{name:"params.ep.file_name",extension:"params.ep.file_extension",url:"params.ep.link_url"}}},video_start:{name:"video start",data:{map:{title:"params.ep.video_title",duration:"params.epn.video_duration",current:"params.epn.video_current_time",percent:"params.epn.video_percent"}}},video_progress:{name:"video progress",data:{map:{title:"params.ep.video_title",duration:"params.epn.video_duration",current:"params.epn.video_current_time",percent:"params.epn.video_percent"}}},video_complete:{name:"video complete",data:{map:{title:"params.ep.video_title",duration:"params.epn.video_duration",current:"params.epn.video_current_time",percent:"params.epn.video_percent"}}},form_start:{name:"form start",data:{map:{id:"params.ep.form_id",name:"params.ep.form_name",destination:"params.ep.form_destination"}}},form_submit:{name:"form submit",data:{map:{id:"params.ep.form_id",name:"params.ep.form_name",destination:"params.ep.form_destination"}}},search:{name:"search submit",data:{map:{term:"params.ep.search_term"}}},login:{name:"session login",data:{map:{method:"params.ep.method"}}},sign_up:{name:"session signup",data:{map:{method:"params.ep.method"}}},generate_lead:{name:"lead generate",data:{map:{currency:"params.ep.currency",value:"params.epn.value"}}},share:{name:"content share",data:{map:{method:"params.ep.method",type:"params.ep.content_type",id:"params.ep.item_id"}}},user_engagement:{ignore:!0},session_start:{ignore:!0},first_visit:{ignore:!0},"*":{name:"ga4 track",data:{map:{event_name:"en"}}}};import{getByPath as u,getId as v,deleteByPath as g,isObject as _}from"@walkeros/core";function y(e,t){const a=[];for(const i of e.events){const r=f(e.hit,i,t);r&&a.push(r)}return a}function f(e,t,a){const i=a[t.en]??a["*"];if(!i)return null;const r=Array.isArray(i)?i[0]:i;if(!r||r.ignore)return null;const n={hit:e,params:t.params,items:t.items,en:t.en,...t.items.length>0?{firstItem:t.items[0]}:{}},o={};if(r.name){const[e,...t]=r.name.split(" ");o.name=r.name,o.entity=e,o.action=t.join(" ")}if(void 0!==r.data){let e=h(r.data,n);if(r.remove&&_(e))for(const t of r.remove)e=g(e,t);void 0!==e&&(o.data=e)}o.user={...void 0!==e.uid?{id:e.uid}:{},...void 0!==e.cid?{device:e.cid}:{},...void 0!==e.sid?{session:e.sid}:{}},o.globals={...void 0!==e.ul?{language:e.ul}:{},...void 0!==e.sr?{screen:e.sr}:{}},o.source={type:"ga4",...void 0!==e.p?{platform:e.p}:{}},o.consent=p(e),o.id=e._p??v();const c=e.sid?Number(e.sid):NaN;return o.timestamp=!Number.isNaN(c)&&c>0?1e3*c:Date.now(),o.timing=t.params._et??0,o.trigger="ga4",t.items.length>0&&(o.nested=t.items.map(e=>{const t={};void 0!==e.id&&(t.id=e.id),void 0!==e.name&&(t.name=e.name),void 0!==e.brand&&(t.brand=e.brand),void 0!==e.category&&(t.category=e.category),void 0!==e.category2&&(t.category2=e.category2),void 0!==e.category3&&(t.category3=e.category3),void 0!==e.category4&&(t.category4=e.category4),void 0!==e.category5&&(t.category5=e.category5),void 0!==e.variant&&(t.variant=e.variant),void 0!==e.price&&(t.price=e.price),void 0!==e.quantity&&(t.quantity=e.quantity),void 0!==e.coupon&&(t.coupon=e.coupon),void 0!==e.discount&&(t.discount=e.discount),void 0!==e.listName&&(t.list_name=e.listName),void 0!==e.listId&&(t.list_id=e.listId),void 0!==e.listPosition&&(t.list_position=e.listPosition),void 0!==e.locationId&&(t.location_id=e.locationId),void 0!==e.affiliation&&(t.affiliation=e.affiliation),void 0!==e.creativeName&&(t.creative_name=e.creativeName),void 0!==e.creativeSlot&&(t.creative_slot=e.creativeSlot),void 0!==e.promotionId&&(t.promotion_id=e.promotionId),void 0!==e.promotionName&&(t.promotion_name=e.promotionName);for(const[a,i]of Object.entries(e.custom))t[a]=i;return{entity:"product",data:t,nested:[],context:{}}})),o}function h(e,t){if(Array.isArray(e))for(const a of e){const e=h(a,t);if(null!=e)return e}else{if("string"==typeof e)return u(t,e);if("object"==typeof e&&null!==e){if("value"in e&&void 0!==e.value)return e.value;if("key"in e&&"string"==typeof e.key)return u(t,e.key);if("map"in e&&e.map){const a={};for(const[i,r]of Object.entries(e.map)){const e=h(r,t);void 0!==e&&(a[i]=e)}return a}}}}var w={};t(w,{step:()=>b});var b={};t(b,{addToCart:()=>P,batchPost:()=>U,beginCheckout:()=>G,consentDenied:()=>M,customEvent:()=>L,login:()=>x,pageView:()=>k,purchase:()=>A,scroll:()=>S,search:()=>O,userEngagementIgnored:()=>R,viewItem:()=>I});var E="1700000000";function N(e){return{id:"p1",timestamp:17e11,timing:0,trigger:"ga4",user:{device:"cid-1",session:E},globals:{},source:{type:"ga4"},consent:{},...e}}var k={title:"Page view",description:"A standard GA4 page_view hit decoded to a walkerOS page view with id, title, and referrer.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+E+"&en=page_view&dl=https%3A%2F%2Fshop.example.com%2Fproducts%2Fsku-123&dt=Trail%20Runner%20Pro&dr=https%3A%2F%2Fshop.example.com%2F"},out:[["return",N({name:"page view",entity:"page",action:"view",data:{id:"https://shop.example.com/products/sku-123",title:"Trail Runner Pro",referrer:"https://shop.example.com/"}})]]},A={title:"Purchase (canary)",description:"A GA4 purchase hit decoded to a walkerOS order complete event with id, currency, total, tax, shipping, and coupon.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+E+"&en=purchase&ep.transaction_id=T-9001&ep.currency=EUR&epn.value=149.97&epn.tax=23.97&epn.shipping=4.95&ep.coupon=WELCOME10"},out:[["return",N({name:"order complete",entity:"order",action:"complete",data:{id:"T-9001",currency:"EUR",total:149.97,tax:23.97,shipping:4.95,coupon:"WELCOME10"}})]]},I={title:"View item",description:"A GA4 view_item hit decoded to a walkerOS product view event with currency and value.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+E+"&en=view_item&ep.currency=EUR&epn.value=129.99"},out:[["return",N({name:"product view",entity:"product",action:"view",data:{currency:"EUR",value:129.99}})]]},P={title:"Add to cart",description:"A GA4 add_to_cart hit decoded to a walkerOS product add event with currency and value.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+E+"&en=add_to_cart&ep.currency=EUR&epn.value=129.99"},out:[["return",N({name:"product add",entity:"product",action:"add",data:{currency:"EUR",value:129.99}})]]},G={title:"Begin checkout",description:"A GA4 begin_checkout hit decoded to a walkerOS order start event with currency, value, and coupon.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+E+"&en=begin_checkout&ep.currency=EUR&epn.value=149.97&ep.coupon=WELCOME10"},out:[["return",N({name:"order start",entity:"order",action:"start",data:{currency:"EUR",value:149.97,coupon:"WELCOME10"}})]]},S={title:"Scroll",description:"A GA4 scroll hit decoded to a walkerOS page scroll event with the percent_scrolled value.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+E+"&en=scroll&epn.percent_scrolled=90"},out:[["return",N({name:"page scroll",entity:"page",action:"scroll",data:{percent:90}})]]},O={title:"Search",description:"A GA4 search hit decoded to a walkerOS search submit event carrying the search term.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+E+"&en=search&ep.search_term=trail%20runner"},out:[["return",N({name:"search submit",entity:"search",action:"submit",data:{term:"trail runner"}})]]},x={title:"Login",description:"A GA4 login hit decoded to a walkerOS session login event with the auth method.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+E+"&en=login&ep.method=google"},out:[["return",N({name:"session login",entity:"session",action:"login",data:{method:"google"}})]]},L={title:"Custom event (* fallback)",description:"Unknown GA4 event names hit the * fallback rule and surface as a ga4 track event carrying the original name.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+E+"&en=newsletter_subscribe&ep.source=footer"},out:[["return",N({name:"ga4 track",entity:"ga4",action:"track",data:{event_name:"newsletter_subscribe"}})]]},M={title:"Consent denied (gcs=G100)",description:"A page_view hit with gcs=G100 still maps, with consent.{marketing,analytics} both false on the resulting event.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+E+"&gcs=G100&en=page_view&dl=https%3A%2F%2Fx&dt=X"},out:[["return",N({name:"page view",entity:"page",action:"view",data:{id:"https://x",title:"X"},consent:{marketing:!1,analytics:!1}})]]},R={title:"user_engagement (ignored)",description:"Auto-fired GA4 user_engagement events are dropped by default — the transformer returns false.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+E+"&en=user_engagement&_et=1500"},out:[["return",!1]]},U={title:"Batched POST (fan-out)",description:"A single POST request carrying two newline-separated events fans out into two walkerOS events.",in:{url:"https://www.google-analytics.com/g/collect?v=2&tid=G-EXAMPLE&_p=p1&cid=cid-1&sid="+E,body:["en=add_to_cart&ep.currency=EUR&epn.value=19.99","en=add_to_cart&ep.currency=EUR&epn.value=29.99"].join("\n")},out:[["return",N({name:"product add",entity:"product",action:"add",data:{currency:"EUR",value:19.99}})],["return",N({name:"product add",entity:"product",action:"add",data:{currency:"EUR",value:29.99}})]]};export{l as defaultMapping,w as examples,y as mapHitToEvents,i as parseBody,p as parseConsent,s as parseItem,a as parseQuery,m as parseRequest};//# sourceMappingURL=dev.mjs.map
|