@walkeros/web-destination-amplitude 4.7.2 → 4.8.0-next-1791496487198

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 CHANGED
@@ -1,5 +1,20 @@
1
1
  # @walkeros/web-destination-amplitude
2
2
 
3
+ ## 4.8.0-next-1791496487198
4
+
5
+ ### Patch Changes
6
+
7
+ - 5593d7b: The `sessionReplay`, `experiment` and `engagement` descriptions now
8
+ say that `@amplitude/unified` sets up all three plugins on every init and that
9
+ these settings only pass options to them, and how Session Replay sampling is
10
+ decided. The step examples name the destination config they rely on, and the
11
+ login example uses a millisecond timestamp.
12
+ - Updated dependencies [7132619]
13
+ - Updated dependencies [5593d7b]
14
+ - Updated dependencies [421233d]
15
+ - @walkeros/core@4.8.0-next-1791496487198
16
+ - @walkeros/web-core@4.8.0-next-1791496487198
17
+
3
18
  ## 4.7.2
4
19
 
5
20
  ### Patch Changes
package/README.md CHANGED
@@ -33,7 +33,11 @@ npm install @walkeros/web-destination-amplitude
33
33
  "destinations": {
34
34
  "amplitude": {
35
35
  "package": "@walkeros/web-destination-amplitude",
36
- "config": {}
36
+ "config": {
37
+ "settings": {
38
+ "apiKey": "YOUR_AMPLITUDE_API_KEY"
39
+ }
40
+ }
37
41
  }
38
42
  }
39
43
  }
package/dist/dev.d.mts CHANGED
@@ -186,12 +186,12 @@ declare const defaultEventForwarding: AmplitudeStepExample;
186
186
  */
187
187
  declare const wildcardIgnored: AmplitudeStepExample;
188
188
  /**
189
- * Destination-level settings.include flattens the walkerOS `data` section
190
- * into prefixed event_properties on every push.
189
+ * Destination-level include (config.include) flattens the walkerOS `data`
190
+ * section into prefixed event_properties on every push.
191
191
  */
192
192
  declare const destinationLevelInclude: AmplitudeStepExample;
193
193
  /**
194
- * Per-rule settings.include REPLACES destination-level include for the
194
+ * Per-rule include REPLACES the destination-level config.include for the
195
195
  * matched rule. Here destination-level sends `data`, but the rule
196
196
  * overrides it with `globals` only.
197
197
  */
package/dist/dev.d.ts CHANGED
@@ -186,12 +186,12 @@ declare const defaultEventForwarding: AmplitudeStepExample;
186
186
  */
187
187
  declare const wildcardIgnored: AmplitudeStepExample;
188
188
  /**
189
- * Destination-level settings.include flattens the walkerOS `data` section
190
- * into prefixed event_properties on every push.
189
+ * Destination-level include (config.include) flattens the walkerOS `data`
190
+ * section into prefixed event_properties on every push.
191
191
  */
192
192
  declare const destinationLevelInclude: AmplitudeStepExample;
193
193
  /**
194
- * Per-rule settings.include REPLACES destination-level include for the
194
+ * Per-rule include REPLACES the destination-level config.include for the
195
195
  * matched rule. Here destination-level sends `data`, but the rule
196
196
  * overrides it with `globals` only.
197
197
  */
package/dist/dev.js CHANGED
@@ -1 +1 @@
1
- "use strict";var e,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,i=Object.getOwnPropertyNames,r=Object.prototype.hasOwnProperty,a=(e,n)=>{for(var i in n)t(e,i,{get:n[i],enumerable:!0})},s={};a(s,{examples:()=>y,schemas:()=>o}),module.exports=(e=s,((e,a,s,o)=>{if(a&&"object"==typeof a||"function"==typeof a)for(let d of i(a))r.call(e,d)||d===s||t(e,d,{get:()=>a[d],enumerable:!(o=n(a,d))||o.enumerable});return e})(t({},"__esModule",{value:!0}),e));var o={};a(o,{MappingSchema:()=>c,SettingsSchema:()=>p,mapping:()=>v,settings:()=>m});var d=require("@walkeros/core/dev"),u=require("@walkeros/core/dev"),p=u.z.object({apiKey:u.z.string().min(1).describe('Your Amplitude project API key. Find it in your Amplitude project settings under "General" → "API Keys" (like a1b2c3d4e5f6789012345678abcdef12).'),serverZone:u.z.enum(["US","EU"]).describe("Amplitude server zone. Default: US.").optional(),flushIntervalMillis:u.z.number().int().positive().describe("How often (in ms) to flush the event queue. Default: 1000.").optional(),flushQueueSize:u.z.number().int().positive().describe("Max queued events before a flush. Default: 30.").optional(),flushMaxRetries:u.z.number().int().nonnegative().describe("Max retries on failed flush. Default: 5.").optional(),transport:u.z.enum(["fetch","xhr","beacon"]).describe("HTTP transport. Default: fetch.").optional(),useBatch:u.z.boolean().describe("Use the Amplitude batch endpoint instead of the standard endpoint. Default: false.").optional(),appVersion:u.z.string().describe("Application version; tagged onto every event.").optional(),identify:u.z.unknown().describe("walkerOS mapping value resolving to an identity object. Keys: user, device, session, set, setOnce, add, append, prepend, preInsert, postInsert, remove, unset, clearAll.").optional(),sessionReplay:u.z.unknown().describe("Session Replay options. When present, session replay is enabled via @amplitude/unified with the provided options.").optional(),experiment:u.z.unknown().describe("Feature Experiment config. Must include `deploymentKey`. When present, the experiment plugin from @amplitude/unified is configured with the provided options.").optional(),engagement:u.z.unknown().describe("Guides & Surveys config. Pass `true` for defaults, or an options object for custom configuration. Enabled via @amplitude/unified.").optional()}),l=require("@walkeros/core/dev"),c=l.z.object({identify:l.z.unknown().describe("Per-event identity mapping. Resolves to an object with any of: user, device, session, set, setOnce, add, append, prepend, preInsert, postInsert, remove, unset, clearAll.").optional(),revenue:l.z.unknown().describe("Revenue mapping. Resolves to a single object or (via loop) an array of objects, each with: productId, price, quantity, revenueType, currency, revenue, receipt, receiptSig, eventProperties. One amplitude.revenue() call fires per item.").optional(),group:l.z.unknown().describe("Group assignment. Resolves to { type, name } → amplitude.setGroup(type, name).").optional(),groupIdentify:l.z.unknown().describe("Group properties. Resolves to { type, name, set?, setOnce?, ... } → amplitude.groupIdentify(type, name, identify).").optional(),reset:l.z.unknown().describe("Logout trigger. Resolves to a truthy value → amplitude.reset() (clears userId, regenerates deviceId). Typically used with silent: true on a user logout rule.").optional()}),m=(0,d.zodToSchema)(p),v=(0,d.zodToSchema)(c),y={};a(y,{env:()=>g,step:()=>O});var g={};a(g,{init:()=>_,push:()=>w,simulation:()=>k});var h=()=>{},f=()=>({promise:Promise.resolve()}),b=class{constructor(){this._ops={}}_record(e,t,n){return this._ops[e]||(this._ops[e]={}),this._ops[e][t]=n,this}set(e,t){return this._record("set",e,t)}setOnce(e,t){return this._record("setOnce",e,t)}add(e,t){return this._record("add",e,t)}append(e,t){return this._record("append",e,t)}prepend(e,t){return this._record("prepend",e,t)}preInsert(e,t){return this._record("preInsert",e,t)}postInsert(e,t){return this._record("postInsert",e,t)}remove(e,t){return this._record("remove",e,t)}unset(e){return this._record("unset",e)}clearAll(){return this._ops.clearAll={},this}toJSON(){return this._ops}},I=class{constructor(){this._data={}}setProductId(e){return this._data.productId=e,this}setPrice(e){return this._data.price=e,this}setQuantity(e){return this._data.quantity=e,this}setRevenueType(e){return this._data.revenueType=e,this}setCurrency(e){return this._data.currency=e,this}setRevenue(e){return this._data.revenue=e,this}setReceipt(e){return this._data.receipt=e,this}setReceiptSig(e){return this._data.receiptSig=e,this}setEventProperties(e){return this._data.eventProperties=e,this}toJSON(){return this._data}},_={amplitude:{initAll:()=>Promise.resolve(),track:h,identify:h,revenue:h,reset:h,setOptOut:h,setUserId:h,setDeviceId:h,setSessionId:h,setGroup:h,groupIdentify:h,flush:f,add:f,Identify:b,Revenue:I}},w={amplitude:{initAll:()=>Promise.resolve(),track:h,identify:h,revenue:h,reset:h,setOptOut:h,setUserId:h,setDeviceId:h,setSessionId:h,setGroup:h,groupIdentify:h,flush:f,add:f,Identify:b,Revenue:I}},k=["call:amplitude.initAll","call:amplitude.track","call:amplitude.identify","call:amplitude.revenue","call:amplitude.reset","call:amplitude.setOptOut","call:amplitude.setUserId","call:amplitude.setDeviceId","call:amplitude.setSessionId","call:amplitude.setGroup","call:amplitude.groupIdentify"],O={};a(O,{consentGrantOptIn:()=>x,consentRevokeOptOut:()=>G,defaultEventForwarding:()=>R,destinationLevelIdentify:()=>P,destinationLevelInclude:()=>E,groupAssignmentWithProperties:()=>T,orderCompleteMultiProduct:()=>q,ruleIncludeReplaces:()=>S,subscriptionRenewRevenue:()=>j,userLoginIdentify:()=>U,userLogoutReset:()=>D,wildcardIgnored:()=>z});var A=require("@walkeros/core"),R={title:"Default track",description:"A walker event is forwarded to Amplitude as an amplitude.track call with the event name and empty properties.",in:(0,A.getEvent)("product view",{timestamp:1700000100}),out:[["amplitude.track","product view",{}]]},z={public:!1,in:(0,A.getEvent)("debug noise",{timestamp:1700000101}),mapping:{ignore:!0},out:[]},E={title:"Include data",description:"Destination-level include flattens the event data section into prefixed event_properties on every track call.",in:(0,A.getEvent)("product view",{timestamp:1700000102}),configInclude:["data"],out:[["amplitude.track","product view",{data_id:"ers",data_name:"Everyday Ruck Snack",data_color:"black",data_size:"l",data_price:420}]]},S={title:"Rule include overrides",description:"A per-rule include replaces the destination-level include for the matched event, here using only globals.",in:(0,A.getEvent)("order complete",{timestamp:1700000103}),configInclude:["data"],mapping:{include:["globals"]},out:[["amplitude.track","order complete",{globals_pagegroup:"shop"}]]},P={title:"Destination identify",description:"Destination-level identify sets userId, deviceId, and sessionId on the Amplitude client before sending events; setters only re-fire when the resolved values change (cached values are not re-applied on subsequent pushes).",in:(0,A.getEvent)("page view",{timestamp:1700000104}),settings:{identify:{map:{user:"user.id",device:"user.device",session:"user.session"}}},out:[["amplitude.setUserId","us3r"],["amplitude.setDeviceId","c00k13"],["amplitude.setSessionId",394324160],["amplitude.track","page view",{}]]},U={title:"User login identify",description:"A user login sets the Amplitude userId and runs identify with set, setOnce, and add operations.",in:(0,A.getEvent)("user login",{timestamp:1700000105,data:{user_id:"new-user-123",plan:"premium",company:"Acme",email:"user@acme.com"}}),mapping:{silent:!0,settings:{identify:{map:{user:"data.user_id",set:{map:{plan:"data.plan",company:"data.company",email:"data.email"}},setOnce:{map:{first_login:"timestamp"}},add:{map:{login_count:{value:1}}}}}}},out:[["amplitude.setUserId","new-user-123"],["amplitude.identify",{set:{plan:"premium",company:"Acme",email:"user@acme.com"},setOnce:{first_login:1700000105},add:{login_count:1}}]]},D={title:"User logout reset",description:"A user logout calls amplitude.reset to clear the userId and regenerate the deviceId.",in:(0,A.getEvent)("user logout",{timestamp:1700000106}),mapping:{silent:!0,settings:{reset:!0}},out:[["amplitude.reset"]]},j={title:"Subscription revenue",description:"A subscription renewal fires a single amplitude.revenue call with productId, price, and currency fallback.",in:(0,A.getEvent)("subscription renew",{timestamp:1700000107,data:{plan_id:"plan-pro",amount:9.99}}),mapping:{silent:!0,settings:{revenue:{map:{productId:"data.plan_id",price:"data.amount",revenueType:{value:"renewal"},currency:{key:"data.currency",value:"EUR"}}}}},out:[["amplitude.revenue",{productId:"plan-pro",price:9.99,revenueType:"renewal",currency:"EUR"}]]},q={title:"Multi-product order",description:"An order fires one amplitude.revenue call per nested product plus a single track for the order totals.",in:(0,A.getEvent)("order complete",{timestamp:1700000108}),mapping:{include:["data","globals"],settings:{revenue:{loop:["nested",{condition:e=>{var t;return"number"==typeof(null==(t=null==e?void 0:e.data)?void 0:t.price)},map:{productId:"data.id",price:"data.price",quantity:{key:"data.quantity",value:1},revenueType:{value:"purchase"},currency:{key:"data.currency",value:"EUR"}}}]}}},out:[["amplitude.revenue",{productId:"ers",price:420,quantity:1,revenueType:"purchase",currency:"EUR"}],["amplitude.revenue",{productId:"cc",price:42,quantity:1,revenueType:"purchase",currency:"EUR"}],["amplitude.track","order complete",{data_id:"0rd3r1d",data_currency:"EUR",data_shipping:5.22,data_taxes:73.76,data_total:555,globals_pagegroup:"shop"}]]},T={title:"Group assignment",description:"A company update assigns the user to a group and sets group properties via setGroup and groupIdentify.",in:(0,A.getEvent)("company update",{timestamp:1700000109,data:{company:"Acme",industry:"tech",employee_count:50,founded_year:2020}}),mapping:{silent:!0,settings:{group:{map:{type:{value:"company"},name:"data.company"}},groupIdentify:{map:{type:{value:"company"},name:"data.company",set:{map:{industry:"data.industry",size:"data.employee_count"}},setOnce:{map:{founded:"data.founded_year"}}}}}},out:[["amplitude.setGroup","company","Acme"],["amplitude.groupIdentify","company","Acme",{set:{industry:"tech",size:50},setOnce:{founded:2020}}]]},G={title:"Consent revoked",description:"A walker consent command with analytics denied opts out of Amplitude tracking via setOptOut(true).",command:"consent",before:{analytics:!0},in:{analytics:!1},settings:{},out:[["amplitude.setOptOut",!1],["amplitude.setOptOut",!0]]},x={title:"Consent granted",description:"A walker consent command with analytics granted opts back into Amplitude tracking via setOptOut(false).",command:"consent",in:{analytics:!0},settings:{},out:[["amplitude.setOptOut",!1]]};//# sourceMappingURL=dev.js.map
1
+ "use strict";var e,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,i=Object.getOwnPropertyNames,r=Object.prototype.hasOwnProperty,s=(e,n)=>{for(var i in n)t(e,i,{get:n[i],enumerable:!0})},a={};s(a,{examples:()=>y,schemas:()=>o}),module.exports=(e=a,((e,s,a,o)=>{if(s&&"object"==typeof s||"function"==typeof s)for(let d of i(s))r.call(e,d)||d===a||t(e,d,{get:()=>s[d],enumerable:!(o=n(s,d))||o.enumerable});return e})(t({},"__esModule",{value:!0}),e));var o={};s(o,{MappingSchema:()=>c,SettingsSchema:()=>p,mapping:()=>v,settings:()=>m});var d=require("@walkeros/core/dev"),u=require("@walkeros/core/dev"),p=u.z.object({apiKey:u.z.string().min(1).describe('Your Amplitude project API key. Find it in your Amplitude project settings under "General" → "API Keys" (like a1b2c3d4e5f6789012345678abcdef12).'),serverZone:u.z.enum(["US","EU"]).describe("Amplitude server zone. Default: US.").optional(),flushIntervalMillis:u.z.number().int().positive().describe("How often (in ms) to flush the event queue. Default: 1000.").optional(),flushQueueSize:u.z.number().int().positive().describe("Max queued events before a flush. Default: 30.").optional(),flushMaxRetries:u.z.number().int().nonnegative().describe("Max retries on failed flush. Default: 5.").optional(),transport:u.z.enum(["fetch","xhr","beacon"]).describe("HTTP transport. Default: fetch.").optional(),useBatch:u.z.boolean().describe("Use the Amplitude batch endpoint instead of the standard endpoint. Default: false.").optional(),appVersion:u.z.string().describe("Application version; tagged onto every event.").optional(),identify:u.z.unknown().describe("walkerOS mapping value resolving to an identity object. Keys: user, device, session, set, setOnce, add, append, prepend, preInsert, postInsert, remove, unset, clearAll.").optional(),sessionReplay:u.z.unknown().describe("Session Replay options, passed to the Session Replay plugin. @amplitude/unified sets up the plugin on every init, whether or not this is set; it records a sampled share of sessions, set by the project sampling settings in Amplitude when present, else by sampleRate (default 0).").optional(),experiment:u.z.unknown().describe("Feature Experiment options. Passed to the Experiment plugin only when they include `deploymentKey`. @amplitude/unified sets up the plugin on every init; without a deploymentKey it uses the API key.").optional(),engagement:u.z.unknown().describe("Guides & Surveys options object. @amplitude/unified loads the Guides & Surveys SDK from cdn.amplitude.com on every init, whether or not this is set; `true` passes no options.").optional()}),l=require("@walkeros/core/dev"),c=l.z.object({identify:l.z.unknown().describe("Per-event identity mapping. Resolves to an object with any of: user, device, session, set, setOnce, add, append, prepend, preInsert, postInsert, remove, unset, clearAll.").optional(),revenue:l.z.unknown().describe("Revenue mapping. Resolves to a single object or (via loop) an array of objects, each with: productId, price, quantity, revenueType, currency, revenue, receipt, receiptSig, eventProperties. One amplitude.revenue() call fires per item.").optional(),group:l.z.unknown().describe("Group assignment. Resolves to { type, name } → amplitude.setGroup(type, name).").optional(),groupIdentify:l.z.unknown().describe("Group properties. Resolves to { type, name, set?, setOnce?, ... } → amplitude.groupIdentify(type, name, identify).").optional(),reset:l.z.unknown().describe("Logout trigger. Resolves to a truthy value → amplitude.reset() (clears userId, regenerates deviceId). Typically used with silent: true on a user logout rule.").optional()}),m=(0,d.zodToSchema)(p),v=(0,d.zodToSchema)(c),y={};s(y,{env:()=>g,step:()=>O});var g={};s(g,{init:()=>_,push:()=>w,simulation:()=>k});var h=()=>{},f=()=>({promise:Promise.resolve()}),b=class{constructor(){this._ops={}}_record(e,t,n){return this._ops[e]||(this._ops[e]={}),this._ops[e][t]=n,this}set(e,t){return this._record("set",e,t)}setOnce(e,t){return this._record("setOnce",e,t)}add(e,t){return this._record("add",e,t)}append(e,t){return this._record("append",e,t)}prepend(e,t){return this._record("prepend",e,t)}preInsert(e,t){return this._record("preInsert",e,t)}postInsert(e,t){return this._record("postInsert",e,t)}remove(e,t){return this._record("remove",e,t)}unset(e){return this._record("unset",e)}clearAll(){return this._ops.clearAll={},this}toJSON(){return this._ops}},I=class{constructor(){this._data={}}setProductId(e){return this._data.productId=e,this}setPrice(e){return this._data.price=e,this}setQuantity(e){return this._data.quantity=e,this}setRevenueType(e){return this._data.revenueType=e,this}setCurrency(e){return this._data.currency=e,this}setRevenue(e){return this._data.revenue=e,this}setReceipt(e){return this._data.receipt=e,this}setReceiptSig(e){return this._data.receiptSig=e,this}setEventProperties(e){return this._data.eventProperties=e,this}toJSON(){return this._data}},_={amplitude:{initAll:()=>Promise.resolve(),track:h,identify:h,revenue:h,reset:h,setOptOut:h,setUserId:h,setDeviceId:h,setSessionId:h,setGroup:h,groupIdentify:h,flush:f,add:f,Identify:b,Revenue:I}},w={amplitude:{initAll:()=>Promise.resolve(),track:h,identify:h,revenue:h,reset:h,setOptOut:h,setUserId:h,setDeviceId:h,setSessionId:h,setGroup:h,groupIdentify:h,flush:f,add:f,Identify:b,Revenue:I}},k=["call:amplitude.initAll","call:amplitude.track","call:amplitude.identify","call:amplitude.revenue","call:amplitude.reset","call:amplitude.setOptOut","call:amplitude.setUserId","call:amplitude.setDeviceId","call:amplitude.setSessionId","call:amplitude.setGroup","call:amplitude.groupIdentify"],O={};s(O,{consentGrantOptIn:()=>x,consentRevokeOptOut:()=>q,defaultEventForwarding:()=>R,destinationLevelIdentify:()=>P,destinationLevelInclude:()=>S,groupAssignmentWithProperties:()=>T,orderCompleteMultiProduct:()=>G,ruleIncludeReplaces:()=>E,subscriptionRenewRevenue:()=>D,userLoginIdentify:()=>U,userLogoutReset:()=>j,wildcardIgnored:()=>z});var A=require("@walkeros/core"),R={title:"Default track",description:"A walker event is forwarded to Amplitude as an amplitude.track call with the event name and empty properties.",in:(0,A.getEvent)("product view",{timestamp:1700000100}),out:[["amplitude.track","product view",{}]]},z={public:!1,in:(0,A.getEvent)("debug noise",{timestamp:1700000101}),mapping:{ignore:!0},out:[]},S={title:"Include data",description:"With include: ['data'] in the destination config, the event data section is flattened into prefixed event_properties on every track call.",in:(0,A.getEvent)("product view",{timestamp:1700000102}),configInclude:["data"],out:[["amplitude.track","product view",{data_id:"ers",data_name:"Everyday Ruck Snack",data_color:"black",data_size:"l",data_price:420}]]},E={title:"Rule include overrides",description:"With include: ['data'] in the destination config, the rule's include: ['globals'] replaces it, so this event forwards only globals.",in:(0,A.getEvent)("order complete",{timestamp:1700000103}),configInclude:["data"],mapping:{include:["globals"]},out:[["amplitude.track","order complete",{globals_pagegroup:"shop"}]]},P={title:"Destination identify",description:"With settings.identify mapping user, device, and session to 'user.id', 'user.device', and 'user.session', the destination sets userId, deviceId, and sessionId before the track call. A non-numeric session string is hashed to a stable number. Setters only re-fire when the resolved values change.",in:(0,A.getEvent)("page view",{timestamp:1700000104}),settings:{identify:{map:{user:"user.id",device:"user.device",session:"user.session"}}},out:[["amplitude.setUserId","us3r"],["amplitude.setDeviceId","c00k13"],["amplitude.setSessionId",394324160],["amplitude.track","page view",{}]]},U={title:"User login identify",description:"A user login sets the Amplitude userId and runs identify with set, setOnce, and add operations.",in:(0,A.getEvent)("user login",{timestamp:1700000105e3,data:{user_id:"new-user-123",plan:"premium",company:"Acme",email:"user@acme.com"}}),mapping:{silent:!0,settings:{identify:{map:{user:"data.user_id",set:{map:{plan:"data.plan",company:"data.company",email:"data.email"}},setOnce:{map:{first_login:"timestamp"}},add:{map:{login_count:{value:1}}}}}}},out:[["amplitude.setUserId","new-user-123"],["amplitude.identify",{set:{plan:"premium",company:"Acme",email:"user@acme.com"},setOnce:{first_login:1700000105e3},add:{login_count:1}}]]},j={title:"User logout reset",description:"A user logout calls amplitude.reset to clear the userId and regenerate the deviceId.",in:(0,A.getEvent)("user logout",{timestamp:1700000106}),mapping:{silent:!0,settings:{reset:!0}},out:[["amplitude.reset"]]},D={title:"Subscription revenue",description:"A subscription renewal fires a single amplitude.revenue call with productId, price, and currency fallback.",in:(0,A.getEvent)("subscription renew",{timestamp:1700000107,data:{plan_id:"plan-pro",amount:9.99}}),mapping:{silent:!0,settings:{revenue:{map:{productId:"data.plan_id",price:"data.amount",revenueType:{value:"renewal"},currency:{key:"data.currency",value:"EUR"}}}}},out:[["amplitude.revenue",{productId:"plan-pro",price:9.99,revenueType:"renewal",currency:"EUR"}]]},G={title:"Multi-product order",description:"An order fires one amplitude.revenue call per nested product plus a single track for the order totals.",in:(0,A.getEvent)("order complete",{timestamp:1700000108}),mapping:{include:["data","globals"],settings:{revenue:{loop:["nested",{condition:e=>{var t;return"number"==typeof(null==(t=null==e?void 0:e.data)?void 0:t.price)},map:{productId:"data.id",price:"data.price",quantity:{key:"data.quantity",value:1},revenueType:{value:"purchase"},currency:{key:"data.currency",value:"EUR"}}}]}}},out:[["amplitude.revenue",{productId:"ers",price:420,quantity:1,revenueType:"purchase",currency:"EUR"}],["amplitude.revenue",{productId:"cc",price:42,quantity:1,revenueType:"purchase",currency:"EUR"}],["amplitude.track","order complete",{data_id:"0rd3r1d",data_currency:"EUR",data_shipping:5.22,data_taxes:73.76,data_total:555,globals_pagegroup:"shop"}]]},T={title:"Group assignment",description:"A company update assigns the user to a group and sets group properties via setGroup and groupIdentify.",in:(0,A.getEvent)("company update",{timestamp:1700000109,data:{company:"Acme",industry:"tech",employee_count:50,founded_year:2020}}),mapping:{silent:!0,settings:{group:{map:{type:{value:"company"},name:"data.company"}},groupIdentify:{map:{type:{value:"company"},name:"data.company",set:{map:{industry:"data.industry",size:"data.employee_count"}},setOnce:{map:{founded:"data.founded_year"}}}}}},out:[["amplitude.setGroup","company","Acme"],["amplitude.groupIdentify","company","Acme",{set:{industry:"tech",size:50},setOnce:{founded:2020}}]]},q={title:"Consent revoked",description:"With consent: { analytics: true } in the destination config, a walker consent command that denies analytics opts out of Amplitude tracking via setOptOut(true).",command:"consent",before:{analytics:!0},in:{analytics:!1},settings:{},out:[["amplitude.setOptOut",!1],["amplitude.setOptOut",!0]]},x={title:"Consent granted",description:"With consent: { analytics: true } in the destination config, a walker consent command that grants analytics opts into Amplitude tracking via setOptOut(false).",command:"consent",in:{analytics:!0},settings:{},out:[["amplitude.setOptOut",!1]]};//# sourceMappingURL=dev.js.map
package/dist/dev.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/dev.ts","../src/schemas/index.ts","../src/schemas/settings.ts","../src/schemas/mapping.ts","../src/examples/index.ts","../src/examples/env.ts","../src/examples/step.ts"],"sourcesContent":["export * as schemas from './schemas';\nexport * as examples from './examples';\n","import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\nimport { MappingSchema } from './mapping';\n\nexport { SettingsSchema, type Settings } from './settings';\nexport { MappingSchema, type Mapping } from './mapping';\n\n// JSON Schema\nexport const settings = zodToSchema(SettingsSchema);\nexport const mapping = zodToSchema(MappingSchema);\n","import { z } from '@walkeros/core/dev';\n\nexport const SettingsSchema = z.object({\n apiKey: z\n .string()\n .min(1)\n .describe(\n 'Your Amplitude project API key. Find it in your Amplitude project settings under \"General\" → \"API Keys\" (like a1b2c3d4e5f6789012345678abcdef12).',\n ),\n serverZone: z\n .enum(['US', 'EU'])\n .describe('Amplitude server zone. Default: US.')\n .optional(),\n flushIntervalMillis: z\n .number()\n .int()\n .positive()\n .describe('How often (in ms) to flush the event queue. Default: 1000.')\n .optional(),\n flushQueueSize: z\n .number()\n .int()\n .positive()\n .describe('Max queued events before a flush. Default: 30.')\n .optional(),\n flushMaxRetries: z\n .number()\n .int()\n .nonnegative()\n .describe('Max retries on failed flush. Default: 5.')\n .optional(),\n transport: z\n .enum(['fetch', 'xhr', 'beacon'])\n .describe('HTTP transport. Default: fetch.')\n .optional(),\n useBatch: z\n .boolean()\n .describe(\n 'Use the Amplitude batch endpoint instead of the standard endpoint. Default: false.',\n )\n .optional(),\n appVersion: z\n .string()\n .describe('Application version; tagged onto every event.')\n .optional(),\n identify: z\n .unknown()\n .describe(\n 'walkerOS mapping value resolving to an identity object. Keys: user, device, session, set, setOnce, add, append, prepend, preInsert, postInsert, remove, unset, clearAll.',\n )\n .optional(),\n sessionReplay: z\n .unknown()\n .describe(\n 'Session Replay options. When present, session replay is enabled via @amplitude/unified with the provided options.',\n )\n .optional(),\n experiment: z\n .unknown()\n .describe(\n 'Feature Experiment config. Must include `deploymentKey`. When present, the experiment plugin from @amplitude/unified is configured with the provided options.',\n )\n .optional(),\n engagement: z\n .unknown()\n .describe(\n 'Guides & Surveys config. Pass `true` for defaults, or an options object for custom configuration. Enabled via @amplitude/unified.',\n )\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\nexport const MappingSchema = z.object({\n identify: z\n .unknown()\n .describe(\n 'Per-event identity mapping. Resolves to an object with any of: user, device, session, set, setOnce, add, append, prepend, preInsert, postInsert, remove, unset, clearAll.',\n )\n .optional(),\n revenue: z\n .unknown()\n .describe(\n 'Revenue mapping. Resolves to a single object or (via loop) an array of objects, each with: productId, price, quantity, revenueType, currency, revenue, receipt, receiptSig, eventProperties. One amplitude.revenue() call fires per item.',\n )\n .optional(),\n group: z\n .unknown()\n .describe(\n 'Group assignment. Resolves to { type, name } → amplitude.setGroup(type, name).',\n )\n .optional(),\n groupIdentify: z\n .unknown()\n .describe(\n 'Group properties. Resolves to { type, name, set?, setOnce?, ... } → amplitude.groupIdentify(type, name, identify).',\n )\n .optional(),\n reset: z\n .unknown()\n .describe(\n 'Logout trigger. Resolves to a truthy value → amplitude.reset() (clears userId, regenerates deviceId). Typically used with silent: true on a user logout rule.',\n )\n .optional(),\n});\n\nexport type Mapping = z.infer<typeof MappingSchema>;\n","export * as env from './env';\nexport * as step from './step';\n","import type { Env, IdentifyInstance, RevenueInstance } from '../types';\n\n/**\n * Example environment configurations for the Amplitude destination.\n *\n * Tests clone `push` and replace individual methods with jest spies.\n * Production leaves `env.amplitude` undefined — the destination falls back\n * to the real `@amplitude/unified` module namespace.\n */\n\nconst noop = () => {};\nconst noopPromise = () => ({ promise: Promise.resolve() });\n\n/**\n * Minimal chainable Identify mock. The real SDK class has the same shape.\n * Tests spy by replacing these methods with jest.fn() in the test runner.\n */\nclass MockIdentify implements IdentifyInstance {\n _ops: Record<string, Record<string, unknown>> = {};\n\n private _record(op: string, prop: string, value?: unknown) {\n if (!this._ops[op]) this._ops[op] = {};\n this._ops[op][prop] = value;\n return this;\n }\n\n set(prop: string, value: unknown) {\n return this._record('set', prop, value);\n }\n setOnce(prop: string, value: unknown) {\n return this._record('setOnce', prop, value);\n }\n add(prop: string, value: unknown) {\n return this._record('add', prop, value);\n }\n append(prop: string, value: unknown) {\n return this._record('append', prop, value);\n }\n prepend(prop: string, value: unknown) {\n return this._record('prepend', prop, value);\n }\n preInsert(prop: string, value: unknown) {\n return this._record('preInsert', prop, value);\n }\n postInsert(prop: string, value: unknown) {\n return this._record('postInsert', prop, value);\n }\n remove(prop: string, value: unknown) {\n return this._record('remove', prop, value);\n }\n unset(prop: string) {\n return this._record('unset', prop);\n }\n clearAll() {\n this._ops['clearAll'] = {};\n return this;\n }\n\n toJSON() {\n return this._ops;\n }\n}\n\n/** Minimal chainable Revenue mock. */\nclass MockRevenue implements RevenueInstance {\n _data: Record<string, unknown> = {};\n\n setProductId(v: string) {\n this._data.productId = v;\n return this;\n }\n setPrice(v: number) {\n this._data.price = v;\n return this;\n }\n setQuantity(v: number) {\n this._data.quantity = v;\n return this;\n }\n setRevenueType(v: string) {\n this._data.revenueType = v;\n return this;\n }\n setCurrency(v: string) {\n this._data.currency = v;\n return this;\n }\n setRevenue(v: number) {\n this._data.revenue = v;\n return this;\n }\n setReceipt(v: string) {\n this._data.receipt = v;\n return this;\n }\n setReceiptSig(v: string) {\n this._data.receiptSig = v;\n return this;\n }\n setEventProperties(v: unknown) {\n this._data.eventProperties = v;\n return this;\n }\n\n toJSON() {\n return this._data;\n }\n}\n\n/**\n * Pre-init env — all methods are no-ops until the test runner wires spies.\n */\nexport const init: Env | undefined = {\n amplitude: {\n initAll: () => Promise.resolve(),\n track: noop,\n identify: noop,\n revenue: noop,\n reset: noop,\n setOptOut: noop,\n setUserId: noop,\n setDeviceId: noop,\n setSessionId: noop,\n setGroup: noop,\n groupIdentify: noop,\n flush: noopPromise,\n add: noopPromise,\n Identify: MockIdentify,\n Revenue: MockRevenue,\n },\n};\n\n/**\n * Post-init env — same shape. The test runner clones this and replaces\n * individual methods with jest.fn() so it can assert on calls.\n */\nexport const push: Env = {\n amplitude: {\n initAll: () => Promise.resolve(),\n track: noop,\n identify: noop,\n revenue: noop,\n reset: noop,\n setOptOut: noop,\n setUserId: noop,\n setDeviceId: noop,\n setSessionId: noop,\n setGroup: noop,\n groupIdentify: noop,\n flush: noopPromise,\n add: noopPromise,\n Identify: MockIdentify,\n Revenue: MockRevenue,\n },\n};\n\n/** Simulation tracking paths for CLI --simulate. */\nexport const simulation = [\n 'call:amplitude.initAll',\n 'call:amplitude.track',\n 'call:amplitude.identify',\n 'call:amplitude.revenue',\n 'call:amplitude.reset',\n 'call:amplitude.setOptOut',\n 'call:amplitude.setUserId',\n 'call:amplitude.setDeviceId',\n 'call:amplitude.setSessionId',\n 'call:amplitude.setGroup',\n 'call:amplitude.groupIdentify',\n];\n","import type { Flow, WalkerOS } from '@walkeros/core';\nimport { getEvent } from '@walkeros/core';\nimport type { Settings } from '../types';\n\n/**\n * Examples may optionally carry destination-level settings and/or an\n * `await` hint for async scenarios. The test runner reads `settings`\n * from the example and merges it into the base destination settings\n * on top of the fixed apiKey. `configInclude` is passed as config-level\n * include when registering the destination.\n */\nexport type AmplitudeStepExample = Flow.StepExample & {\n settings?: Partial<Settings>;\n configInclude?: string[];\n /** Consent granted before `in` so a gated destination is loaded first. */\n before?: WalkerOS.Consent;\n};\n\n/**\n * Default event forwarding - every walkerOS event becomes\n * amplitude.track(event.name, event_properties). With no mapping and\n * no destination-level include, event_properties is `{}`.\n */\nexport const defaultEventForwarding: AmplitudeStepExample = {\n title: 'Default track',\n description:\n 'A walker event is forwarded to Amplitude as an amplitude.track call with the event name and empty properties.',\n in: getEvent('product view', { timestamp: 1700000100 }),\n out: [['amplitude.track', 'product view', {}]],\n};\n\n/**\n * Wildcard ignore - walkerOS's standard way to drop events. The rule\n * matches but does nothing. The destination fires zero SDK calls.\n */\nexport const wildcardIgnored: AmplitudeStepExample = {\n public: false,\n in: getEvent('debug noise', { timestamp: 1700000101 }),\n mapping: { ignore: true },\n out: [],\n};\n\n/**\n * Destination-level settings.include flattens the walkerOS `data` section\n * into prefixed event_properties on every push.\n */\nexport const destinationLevelInclude: AmplitudeStepExample = {\n title: 'Include data',\n description:\n 'Destination-level include flattens the event data section into prefixed event_properties on every track call.',\n in: getEvent('product view', { timestamp: 1700000102 }),\n configInclude: ['data'],\n out: [\n [\n 'amplitude.track',\n 'product view',\n {\n data_id: 'ers',\n data_name: 'Everyday Ruck Snack',\n data_color: 'black',\n data_size: 'l',\n data_price: 420,\n },\n ],\n ],\n};\n\n/**\n * Per-rule settings.include REPLACES destination-level include for the\n * matched rule. Here destination-level sends `data`, but the rule\n * overrides it with `globals` only.\n */\nexport const ruleIncludeReplaces: AmplitudeStepExample = {\n title: 'Rule include overrides',\n description:\n 'A per-rule include replaces the destination-level include for the matched event, here using only globals.',\n in: getEvent('order complete', { timestamp: 1700000103 }),\n configInclude: ['data'],\n mapping: {\n include: ['globals'],\n },\n out: [\n [\n 'amplitude.track',\n 'order complete',\n {\n globals_pagegroup: 'shop',\n },\n ],\n ],\n};\n\n/**\n * Destination-level settings.identify fires on the first push (once the\n * state cache is empty). The destination sets user/device/session IDs\n * and tracks them in runtime state; subsequent pushes with unchanged\n * values do NOT re-fire the setters.\n *\n * This example represents the first push in a fresh session. user.id,\n * user.device, user.session come from the walkerOS session fixture.\n *\n * The walkerOS fixture's user.session is 's3ss10n' (string). The\n * destination deterministically hashes non-numeric session strings via\n * djb2 so the same walkerOS session always maps to the same Amplitude\n * session number (cross-page-load consistency). djb2('s3ss10n') = 394324160.\n */\nexport const destinationLevelIdentify: AmplitudeStepExample = {\n title: 'Destination identify',\n description:\n 'Destination-level identify sets userId, deviceId, and sessionId on the Amplitude client before sending events; setters only re-fire when the resolved values change (cached values are not re-applied on subsequent pushes).',\n in: getEvent('page view', { timestamp: 1700000104 }),\n settings: {\n identify: {\n map: {\n user: 'user.id',\n device: 'user.device',\n session: 'user.session',\n },\n },\n },\n out: [\n ['amplitude.setUserId', 'us3r'],\n ['amplitude.setDeviceId', 'c00k13'],\n ['amplitude.setSessionId', 394324160],\n ['amplitude.track', 'page view', {}],\n ],\n};\n\n/**\n * Per-event identify with the full operation vocabulary - this is the\n * \"user login\" pattern: set user_id, enrich user properties. `silent: true`\n * suppresses the default amplitude.track() call because we're running\n * identity side effects only.\n */\nexport const userLoginIdentify: AmplitudeStepExample = {\n title: 'User login identify',\n description:\n 'A user login sets the Amplitude userId and runs identify with set, setOnce, and add operations.',\n in: getEvent('user login', {\n timestamp: 1700000105,\n data: {\n user_id: 'new-user-123',\n plan: 'premium',\n company: 'Acme',\n email: 'user@acme.com',\n },\n }),\n mapping: {\n silent: true,\n settings: {\n identify: {\n map: {\n user: 'data.user_id',\n set: {\n map: {\n plan: 'data.plan',\n company: 'data.company',\n email: 'data.email',\n },\n },\n setOnce: {\n map: {\n first_login: 'timestamp',\n },\n },\n add: {\n map: {\n login_count: { value: 1 },\n },\n },\n },\n },\n },\n },\n out: [\n ['amplitude.setUserId', 'new-user-123'],\n [\n 'amplitude.identify',\n {\n set: {\n plan: 'premium',\n company: 'Acme',\n email: 'user@acme.com',\n },\n setOnce: {\n first_login: 1700000105,\n },\n add: {\n login_count: 1,\n },\n },\n ],\n ],\n};\n\n/**\n * User logout - reset: true fires amplitude.reset(), which clears userId\n * and regenerates deviceId. `silent: true` because we're only running the\n * reset side effect, no default track().\n */\nexport const userLogoutReset: AmplitudeStepExample = {\n title: 'User logout reset',\n description:\n 'A user logout calls amplitude.reset to clear the userId and regenerate the deviceId.',\n in: getEvent('user logout', { timestamp: 1700000106 }),\n mapping: {\n silent: true,\n settings: {\n reset: true,\n },\n },\n out: [['amplitude.reset']],\n};\n\n/**\n * Single-product revenue - resolves `settings.revenue` to one object and\n * fires one amplitude.revenue() call. Note the `{ key: \"data.currency\",\n * value: \"EUR\" }` fallback syntax: try data.currency, default to \"EUR\".\n *\n * The walkerOS default event has no data.currency, so the fallback fires.\n */\nexport const subscriptionRenewRevenue: AmplitudeStepExample = {\n title: 'Subscription revenue',\n description:\n 'A subscription renewal fires a single amplitude.revenue call with productId, price, and currency fallback.',\n in: getEvent('subscription renew', {\n timestamp: 1700000107,\n data: {\n plan_id: 'plan-pro',\n amount: 9.99,\n },\n }),\n mapping: {\n silent: true,\n settings: {\n revenue: {\n map: {\n productId: 'data.plan_id',\n price: 'data.amount',\n revenueType: { value: 'renewal' },\n currency: { key: 'data.currency', value: 'EUR' },\n },\n },\n },\n },\n out: [\n [\n 'amplitude.revenue',\n {\n productId: 'plan-pro',\n price: 9.99,\n revenueType: 'renewal',\n currency: 'EUR',\n },\n ],\n ],\n};\n\n/**\n * Multi-product order - the canonical Amplitude ecommerce pattern.\n * `revenue.loop: [\"nested\", { map: ... }]` iterates event.nested and\n * resolves one revenue item per entry. Each becomes a separate\n * amplitude.revenue() call. The order-level track() fires once with\n * include-based event_properties.\n *\n * The default \"order complete\" fixture has 3 nested entries: two\n * products (ers, cc) and one gift. Products have `data.price`; the\n * gift has only `data.name`. The `condition` on the loop inner value\n * filters to products only (price must be present).\n */\nexport const orderCompleteMultiProduct: AmplitudeStepExample = {\n title: 'Multi-product order',\n description:\n 'An order fires one amplitude.revenue call per nested product plus a single track for the order totals.',\n in: getEvent('order complete', { timestamp: 1700000108 }),\n mapping: {\n include: ['data', 'globals'],\n settings: {\n revenue: {\n loop: [\n 'nested',\n {\n // Only iterate nested entries that have a price field (products).\n condition: (value: unknown) => {\n const v = value as { data?: { price?: unknown } };\n return typeof v?.data?.price === 'number';\n },\n map: {\n productId: 'data.id',\n price: 'data.price',\n quantity: { key: 'data.quantity', value: 1 },\n revenueType: { value: 'purchase' },\n currency: { key: 'data.currency', value: 'EUR' },\n },\n },\n ],\n },\n },\n },\n out: [\n [\n 'amplitude.revenue',\n {\n productId: 'ers',\n price: 420,\n quantity: 1,\n revenueType: 'purchase',\n currency: 'EUR',\n },\n ],\n [\n 'amplitude.revenue',\n {\n productId: 'cc',\n price: 42,\n quantity: 1,\n revenueType: 'purchase',\n currency: 'EUR',\n },\n ],\n [\n 'amplitude.track',\n 'order complete',\n {\n data_id: '0rd3r1d',\n data_currency: 'EUR',\n data_shipping: 5.22,\n data_taxes: 73.76,\n data_total: 555,\n globals_pagegroup: 'shop',\n },\n ],\n ],\n};\n\n/**\n * Group assignment + group properties. Typically used for B2B products\n * where a user belongs to a company. Both SDK calls fire on the same rule.\n */\nexport const groupAssignmentWithProperties: AmplitudeStepExample = {\n title: 'Group assignment',\n description:\n 'A company update assigns the user to a group and sets group properties via setGroup and groupIdentify.',\n in: getEvent('company update', {\n timestamp: 1700000109,\n data: {\n company: 'Acme',\n industry: 'tech',\n employee_count: 50,\n founded_year: 2020,\n },\n }),\n mapping: {\n silent: true,\n settings: {\n group: {\n map: {\n type: { value: 'company' },\n name: 'data.company',\n },\n },\n groupIdentify: {\n map: {\n type: { value: 'company' },\n name: 'data.company',\n set: {\n map: {\n industry: 'data.industry',\n size: 'data.employee_count',\n },\n },\n setOnce: {\n map: {\n founded: 'data.founded_year',\n },\n },\n },\n },\n },\n },\n out: [\n ['amplitude.setGroup', 'company', 'Acme'],\n [\n 'amplitude.groupIdentify',\n 'company',\n 'Acme',\n {\n set: {\n industry: 'tech',\n size: 50,\n },\n setOnce: {\n founded: 2020,\n },\n },\n ],\n ],\n};\n\n/**\n * Consent revoked → amplitude.setOptOut(true). The destination checks\n * the consent keys declared in config.consent and toggles optOut\n * accordingly (strict: all required keys must be granted).\n *\n * Uses the canonical StepExample.command='consent' pattern: the test\n * runner dispatches via elb('walker consent', in) instead of pushing\n * an event.\n */\nexport const consentRevokeOptOut: AmplitudeStepExample = {\n title: 'Consent revoked',\n description:\n 'A walker consent command with analytics denied opts out of Amplitude tracking via setOptOut(true).',\n command: 'consent',\n before: { analytics: true },\n in: { analytics: false } as WalkerOS.Consent,\n settings: {} as Partial<Settings>,\n out: [\n ['amplitude.setOptOut', false],\n ['amplitude.setOptOut', true],\n ],\n};\n\n/**\n * Consent granted → amplitude.setOptOut(false).\n */\nexport const consentGrantOptIn: AmplitudeStepExample = {\n title: 'Consent granted',\n description:\n 'A walker consent command with analytics granted opts back into Amplitude tracking via setOptOut(false).',\n command: 'consent',\n in: { analytics: true } as WalkerOS.Consent,\n settings: {} as Partial<Settings>,\n out: [['amplitude.setOptOut', false]],\n};\n"],"mappings":"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","names":["import_dev","import_dev"]}
1
+ {"version":3,"sources":["../src/dev.ts","../src/schemas/index.ts","../src/schemas/settings.ts","../src/schemas/mapping.ts","../src/examples/index.ts","../src/examples/env.ts","../src/examples/step.ts"],"sourcesContent":["export * as schemas from './schemas';\nexport * as examples from './examples';\n","import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\nimport { MappingSchema } from './mapping';\n\nexport { SettingsSchema, type Settings } from './settings';\nexport { MappingSchema, type Mapping } from './mapping';\n\n// JSON Schema\nexport const settings = zodToSchema(SettingsSchema);\nexport const mapping = zodToSchema(MappingSchema);\n","import { z } from '@walkeros/core/dev';\n\nexport const SettingsSchema = z.object({\n apiKey: z\n .string()\n .min(1)\n .describe(\n 'Your Amplitude project API key. Find it in your Amplitude project settings under \"General\" → \"API Keys\" (like a1b2c3d4e5f6789012345678abcdef12).',\n ),\n serverZone: z\n .enum(['US', 'EU'])\n .describe('Amplitude server zone. Default: US.')\n .optional(),\n flushIntervalMillis: z\n .number()\n .int()\n .positive()\n .describe('How often (in ms) to flush the event queue. Default: 1000.')\n .optional(),\n flushQueueSize: z\n .number()\n .int()\n .positive()\n .describe('Max queued events before a flush. Default: 30.')\n .optional(),\n flushMaxRetries: z\n .number()\n .int()\n .nonnegative()\n .describe('Max retries on failed flush. Default: 5.')\n .optional(),\n transport: z\n .enum(['fetch', 'xhr', 'beacon'])\n .describe('HTTP transport. Default: fetch.')\n .optional(),\n useBatch: z\n .boolean()\n .describe(\n 'Use the Amplitude batch endpoint instead of the standard endpoint. Default: false.',\n )\n .optional(),\n appVersion: z\n .string()\n .describe('Application version; tagged onto every event.')\n .optional(),\n identify: z\n .unknown()\n .describe(\n 'walkerOS mapping value resolving to an identity object. Keys: user, device, session, set, setOnce, add, append, prepend, preInsert, postInsert, remove, unset, clearAll.',\n )\n .optional(),\n sessionReplay: z\n .unknown()\n .describe(\n 'Session Replay options, passed to the Session Replay plugin. @amplitude/unified sets up the plugin on every init, whether or not this is set; it records a sampled share of sessions, set by the project sampling settings in Amplitude when present, else by sampleRate (default 0).',\n )\n .optional(),\n experiment: z\n .unknown()\n .describe(\n 'Feature Experiment options. Passed to the Experiment plugin only when they include `deploymentKey`. @amplitude/unified sets up the plugin on every init; without a deploymentKey it uses the API key.',\n )\n .optional(),\n engagement: z\n .unknown()\n .describe(\n 'Guides & Surveys options object. @amplitude/unified loads the Guides & Surveys SDK from cdn.amplitude.com on every init, whether or not this is set; `true` passes no options.',\n )\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\nexport const MappingSchema = z.object({\n identify: z\n .unknown()\n .describe(\n 'Per-event identity mapping. Resolves to an object with any of: user, device, session, set, setOnce, add, append, prepend, preInsert, postInsert, remove, unset, clearAll.',\n )\n .optional(),\n revenue: z\n .unknown()\n .describe(\n 'Revenue mapping. Resolves to a single object or (via loop) an array of objects, each with: productId, price, quantity, revenueType, currency, revenue, receipt, receiptSig, eventProperties. One amplitude.revenue() call fires per item.',\n )\n .optional(),\n group: z\n .unknown()\n .describe(\n 'Group assignment. Resolves to { type, name } → amplitude.setGroup(type, name).',\n )\n .optional(),\n groupIdentify: z\n .unknown()\n .describe(\n 'Group properties. Resolves to { type, name, set?, setOnce?, ... } → amplitude.groupIdentify(type, name, identify).',\n )\n .optional(),\n reset: z\n .unknown()\n .describe(\n 'Logout trigger. Resolves to a truthy value → amplitude.reset() (clears userId, regenerates deviceId). Typically used with silent: true on a user logout rule.',\n )\n .optional(),\n});\n\nexport type Mapping = z.infer<typeof MappingSchema>;\n","export * as env from './env';\nexport * as step from './step';\n","import type { Env, IdentifyInstance, RevenueInstance } from '../types';\n\n/**\n * Example environment configurations for the Amplitude destination.\n *\n * Tests clone `push` and replace individual methods with jest spies.\n * Production leaves `env.amplitude` undefined — the destination falls back\n * to the real `@amplitude/unified` module namespace.\n */\n\nconst noop = () => {};\nconst noopPromise = () => ({ promise: Promise.resolve() });\n\n/**\n * Minimal chainable Identify mock. The real SDK class has the same shape.\n * Tests spy by replacing these methods with jest.fn() in the test runner.\n */\nclass MockIdentify implements IdentifyInstance {\n _ops: Record<string, Record<string, unknown>> = {};\n\n private _record(op: string, prop: string, value?: unknown) {\n if (!this._ops[op]) this._ops[op] = {};\n this._ops[op][prop] = value;\n return this;\n }\n\n set(prop: string, value: unknown) {\n return this._record('set', prop, value);\n }\n setOnce(prop: string, value: unknown) {\n return this._record('setOnce', prop, value);\n }\n add(prop: string, value: unknown) {\n return this._record('add', prop, value);\n }\n append(prop: string, value: unknown) {\n return this._record('append', prop, value);\n }\n prepend(prop: string, value: unknown) {\n return this._record('prepend', prop, value);\n }\n preInsert(prop: string, value: unknown) {\n return this._record('preInsert', prop, value);\n }\n postInsert(prop: string, value: unknown) {\n return this._record('postInsert', prop, value);\n }\n remove(prop: string, value: unknown) {\n return this._record('remove', prop, value);\n }\n unset(prop: string) {\n return this._record('unset', prop);\n }\n clearAll() {\n this._ops['clearAll'] = {};\n return this;\n }\n\n toJSON() {\n return this._ops;\n }\n}\n\n/** Minimal chainable Revenue mock. */\nclass MockRevenue implements RevenueInstance {\n _data: Record<string, unknown> = {};\n\n setProductId(v: string) {\n this._data.productId = v;\n return this;\n }\n setPrice(v: number) {\n this._data.price = v;\n return this;\n }\n setQuantity(v: number) {\n this._data.quantity = v;\n return this;\n }\n setRevenueType(v: string) {\n this._data.revenueType = v;\n return this;\n }\n setCurrency(v: string) {\n this._data.currency = v;\n return this;\n }\n setRevenue(v: number) {\n this._data.revenue = v;\n return this;\n }\n setReceipt(v: string) {\n this._data.receipt = v;\n return this;\n }\n setReceiptSig(v: string) {\n this._data.receiptSig = v;\n return this;\n }\n setEventProperties(v: unknown) {\n this._data.eventProperties = v;\n return this;\n }\n\n toJSON() {\n return this._data;\n }\n}\n\n/**\n * Pre-init env — all methods are no-ops until the test runner wires spies.\n */\nexport const init: Env | undefined = {\n amplitude: {\n initAll: () => Promise.resolve(),\n track: noop,\n identify: noop,\n revenue: noop,\n reset: noop,\n setOptOut: noop,\n setUserId: noop,\n setDeviceId: noop,\n setSessionId: noop,\n setGroup: noop,\n groupIdentify: noop,\n flush: noopPromise,\n add: noopPromise,\n Identify: MockIdentify,\n Revenue: MockRevenue,\n },\n};\n\n/**\n * Post-init env — same shape. The test runner clones this and replaces\n * individual methods with jest.fn() so it can assert on calls.\n */\nexport const push: Env = {\n amplitude: {\n initAll: () => Promise.resolve(),\n track: noop,\n identify: noop,\n revenue: noop,\n reset: noop,\n setOptOut: noop,\n setUserId: noop,\n setDeviceId: noop,\n setSessionId: noop,\n setGroup: noop,\n groupIdentify: noop,\n flush: noopPromise,\n add: noopPromise,\n Identify: MockIdentify,\n Revenue: MockRevenue,\n },\n};\n\n/** Simulation tracking paths for CLI --simulate. */\nexport const simulation = [\n 'call:amplitude.initAll',\n 'call:amplitude.track',\n 'call:amplitude.identify',\n 'call:amplitude.revenue',\n 'call:amplitude.reset',\n 'call:amplitude.setOptOut',\n 'call:amplitude.setUserId',\n 'call:amplitude.setDeviceId',\n 'call:amplitude.setSessionId',\n 'call:amplitude.setGroup',\n 'call:amplitude.groupIdentify',\n];\n","import type { Flow, WalkerOS } from '@walkeros/core';\nimport { getEvent } from '@walkeros/core';\nimport type { Settings } from '../types';\n\n/**\n * Examples may optionally carry destination-level settings and/or an\n * `await` hint for async scenarios. The test runner reads `settings`\n * from the example and merges it into the base destination settings\n * on top of the fixed apiKey. `configInclude` is passed as config-level\n * include when registering the destination.\n */\nexport type AmplitudeStepExample = Flow.StepExample & {\n settings?: Partial<Settings>;\n configInclude?: string[];\n /** Consent granted before `in` so a gated destination is loaded first. */\n before?: WalkerOS.Consent;\n};\n\n/**\n * Default event forwarding - every walkerOS event becomes\n * amplitude.track(event.name, event_properties). With no mapping and\n * no destination-level include, event_properties is `{}`.\n */\nexport const defaultEventForwarding: AmplitudeStepExample = {\n title: 'Default track',\n description:\n 'A walker event is forwarded to Amplitude as an amplitude.track call with the event name and empty properties.',\n in: getEvent('product view', { timestamp: 1700000100 }),\n out: [['amplitude.track', 'product view', {}]],\n};\n\n/**\n * Wildcard ignore - walkerOS's standard way to drop events. The rule\n * matches but does nothing. The destination fires zero SDK calls.\n */\nexport const wildcardIgnored: AmplitudeStepExample = {\n public: false,\n in: getEvent('debug noise', { timestamp: 1700000101 }),\n mapping: { ignore: true },\n out: [],\n};\n\n/**\n * Destination-level include (config.include) flattens the walkerOS `data`\n * section into prefixed event_properties on every push.\n */\nexport const destinationLevelInclude: AmplitudeStepExample = {\n title: 'Include data',\n description:\n \"With include: ['data'] in the destination config, the event data section is flattened into prefixed event_properties on every track call.\",\n in: getEvent('product view', { timestamp: 1700000102 }),\n configInclude: ['data'],\n out: [\n [\n 'amplitude.track',\n 'product view',\n {\n data_id: 'ers',\n data_name: 'Everyday Ruck Snack',\n data_color: 'black',\n data_size: 'l',\n data_price: 420,\n },\n ],\n ],\n};\n\n/**\n * Per-rule include REPLACES the destination-level config.include for the\n * matched rule. Here destination-level sends `data`, but the rule\n * overrides it with `globals` only.\n */\nexport const ruleIncludeReplaces: AmplitudeStepExample = {\n title: 'Rule include overrides',\n description:\n \"With include: ['data'] in the destination config, the rule's include: ['globals'] replaces it, so this event forwards only globals.\",\n in: getEvent('order complete', { timestamp: 1700000103 }),\n configInclude: ['data'],\n mapping: {\n include: ['globals'],\n },\n out: [\n [\n 'amplitude.track',\n 'order complete',\n {\n globals_pagegroup: 'shop',\n },\n ],\n ],\n};\n\n/**\n * Destination-level settings.identify fires on the first push (once the\n * state cache is empty). The destination sets user/device/session IDs\n * and tracks them in runtime state; subsequent pushes with unchanged\n * values do NOT re-fire the setters.\n *\n * This example represents the first push in a fresh session. user.id,\n * user.device, user.session come from the walkerOS session fixture.\n *\n * The walkerOS fixture's user.session is 's3ss10n' (string). The\n * destination deterministically hashes non-numeric session strings via\n * djb2 so the same walkerOS session always maps to the same Amplitude\n * session number (cross-page-load consistency). djb2('s3ss10n') = 394324160.\n */\nexport const destinationLevelIdentify: AmplitudeStepExample = {\n title: 'Destination identify',\n description:\n \"With settings.identify mapping user, device, and session to 'user.id', 'user.device', and 'user.session', the destination sets userId, deviceId, and sessionId before the track call. A non-numeric session string is hashed to a stable number. Setters only re-fire when the resolved values change.\",\n in: getEvent('page view', { timestamp: 1700000104 }),\n settings: {\n identify: {\n map: {\n user: 'user.id',\n device: 'user.device',\n session: 'user.session',\n },\n },\n },\n out: [\n ['amplitude.setUserId', 'us3r'],\n ['amplitude.setDeviceId', 'c00k13'],\n ['amplitude.setSessionId', 394324160],\n ['amplitude.track', 'page view', {}],\n ],\n};\n\n/**\n * Per-event identify with the full operation vocabulary - this is the\n * \"user login\" pattern: set user_id, enrich user properties. `silent: true`\n * suppresses the default amplitude.track() call because we're running\n * identity side effects only.\n */\nexport const userLoginIdentify: AmplitudeStepExample = {\n title: 'User login identify',\n description:\n 'A user login sets the Amplitude userId and runs identify with set, setOnce, and add operations.',\n in: getEvent('user login', {\n timestamp: 1700000105000,\n data: {\n user_id: 'new-user-123',\n plan: 'premium',\n company: 'Acme',\n email: 'user@acme.com',\n },\n }),\n mapping: {\n silent: true,\n settings: {\n identify: {\n map: {\n user: 'data.user_id',\n set: {\n map: {\n plan: 'data.plan',\n company: 'data.company',\n email: 'data.email',\n },\n },\n setOnce: {\n map: {\n first_login: 'timestamp',\n },\n },\n add: {\n map: {\n login_count: { value: 1 },\n },\n },\n },\n },\n },\n },\n out: [\n ['amplitude.setUserId', 'new-user-123'],\n [\n 'amplitude.identify',\n {\n set: {\n plan: 'premium',\n company: 'Acme',\n email: 'user@acme.com',\n },\n setOnce: {\n first_login: 1700000105000,\n },\n add: {\n login_count: 1,\n },\n },\n ],\n ],\n};\n\n/**\n * User logout - reset: true fires amplitude.reset(), which clears userId\n * and regenerates deviceId. `silent: true` because we're only running the\n * reset side effect, no default track().\n */\nexport const userLogoutReset: AmplitudeStepExample = {\n title: 'User logout reset',\n description:\n 'A user logout calls amplitude.reset to clear the userId and regenerate the deviceId.',\n in: getEvent('user logout', { timestamp: 1700000106 }),\n mapping: {\n silent: true,\n settings: {\n reset: true,\n },\n },\n out: [['amplitude.reset']],\n};\n\n/**\n * Single-product revenue - resolves `settings.revenue` to one object and\n * fires one amplitude.revenue() call. Note the `{ key: \"data.currency\",\n * value: \"EUR\" }` fallback syntax: try data.currency, default to \"EUR\".\n *\n * The walkerOS default event has no data.currency, so the fallback fires.\n */\nexport const subscriptionRenewRevenue: AmplitudeStepExample = {\n title: 'Subscription revenue',\n description:\n 'A subscription renewal fires a single amplitude.revenue call with productId, price, and currency fallback.',\n in: getEvent('subscription renew', {\n timestamp: 1700000107,\n data: {\n plan_id: 'plan-pro',\n amount: 9.99,\n },\n }),\n mapping: {\n silent: true,\n settings: {\n revenue: {\n map: {\n productId: 'data.plan_id',\n price: 'data.amount',\n revenueType: { value: 'renewal' },\n currency: { key: 'data.currency', value: 'EUR' },\n },\n },\n },\n },\n out: [\n [\n 'amplitude.revenue',\n {\n productId: 'plan-pro',\n price: 9.99,\n revenueType: 'renewal',\n currency: 'EUR',\n },\n ],\n ],\n};\n\n/**\n * Multi-product order - the canonical Amplitude ecommerce pattern.\n * `revenue.loop: [\"nested\", { map: ... }]` iterates event.nested and\n * resolves one revenue item per entry. Each becomes a separate\n * amplitude.revenue() call. The order-level track() fires once with\n * include-based event_properties.\n *\n * The default \"order complete\" fixture has 3 nested entries: two\n * products (ers, cc) and one gift. Products have `data.price`; the\n * gift has only `data.name`. The `condition` on the loop inner value\n * filters to products only (price must be present).\n */\nexport const orderCompleteMultiProduct: AmplitudeStepExample = {\n title: 'Multi-product order',\n description:\n 'An order fires one amplitude.revenue call per nested product plus a single track for the order totals.',\n in: getEvent('order complete', { timestamp: 1700000108 }),\n mapping: {\n include: ['data', 'globals'],\n settings: {\n revenue: {\n loop: [\n 'nested',\n {\n // Only iterate nested entries that have a price field (products).\n condition: (value: unknown) => {\n const v = value as { data?: { price?: unknown } };\n return typeof v?.data?.price === 'number';\n },\n map: {\n productId: 'data.id',\n price: 'data.price',\n quantity: { key: 'data.quantity', value: 1 },\n revenueType: { value: 'purchase' },\n currency: { key: 'data.currency', value: 'EUR' },\n },\n },\n ],\n },\n },\n },\n out: [\n [\n 'amplitude.revenue',\n {\n productId: 'ers',\n price: 420,\n quantity: 1,\n revenueType: 'purchase',\n currency: 'EUR',\n },\n ],\n [\n 'amplitude.revenue',\n {\n productId: 'cc',\n price: 42,\n quantity: 1,\n revenueType: 'purchase',\n currency: 'EUR',\n },\n ],\n [\n 'amplitude.track',\n 'order complete',\n {\n data_id: '0rd3r1d',\n data_currency: 'EUR',\n data_shipping: 5.22,\n data_taxes: 73.76,\n data_total: 555,\n globals_pagegroup: 'shop',\n },\n ],\n ],\n};\n\n/**\n * Group assignment + group properties. Typically used for B2B products\n * where a user belongs to a company. Both SDK calls fire on the same rule.\n */\nexport const groupAssignmentWithProperties: AmplitudeStepExample = {\n title: 'Group assignment',\n description:\n 'A company update assigns the user to a group and sets group properties via setGroup and groupIdentify.',\n in: getEvent('company update', {\n timestamp: 1700000109,\n data: {\n company: 'Acme',\n industry: 'tech',\n employee_count: 50,\n founded_year: 2020,\n },\n }),\n mapping: {\n silent: true,\n settings: {\n group: {\n map: {\n type: { value: 'company' },\n name: 'data.company',\n },\n },\n groupIdentify: {\n map: {\n type: { value: 'company' },\n name: 'data.company',\n set: {\n map: {\n industry: 'data.industry',\n size: 'data.employee_count',\n },\n },\n setOnce: {\n map: {\n founded: 'data.founded_year',\n },\n },\n },\n },\n },\n },\n out: [\n ['amplitude.setGroup', 'company', 'Acme'],\n [\n 'amplitude.groupIdentify',\n 'company',\n 'Acme',\n {\n set: {\n industry: 'tech',\n size: 50,\n },\n setOnce: {\n founded: 2020,\n },\n },\n ],\n ],\n};\n\n/**\n * Consent revoked → amplitude.setOptOut(true). The destination checks\n * the consent keys declared in config.consent and toggles optOut\n * accordingly (strict: all required keys must be granted).\n *\n * Uses the canonical StepExample.command='consent' pattern: the test\n * runner dispatches via elb('walker consent', in) instead of pushing\n * an event.\n */\nexport const consentRevokeOptOut: AmplitudeStepExample = {\n title: 'Consent revoked',\n description:\n 'With consent: { analytics: true } in the destination config, a walker consent command that denies analytics opts out of Amplitude tracking via setOptOut(true).',\n command: 'consent',\n before: { analytics: true },\n in: { analytics: false } as WalkerOS.Consent,\n settings: {} as Partial<Settings>,\n out: [\n ['amplitude.setOptOut', false],\n ['amplitude.setOptOut', true],\n ],\n};\n\n/**\n * Consent granted → amplitude.setOptOut(false).\n */\nexport const consentGrantOptIn: AmplitudeStepExample = {\n title: 'Consent granted',\n description:\n 'With consent: { analytics: true } in the destination config, a walker consent command that grants analytics opts into Amplitude tracking via setOptOut(false).',\n command: 'consent',\n in: { analytics: true } as WalkerOS.Consent,\n settings: {} as Partial<Settings>,\n out: [['amplitude.setOptOut', false]],\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAAA,cAA4B;;;ACA5B,iBAAkB;AAEX,IAAM,iBAAiB,aAAE,OAAO;AAAA,EACrC,QAAQ,aACL,OAAO,EACP,IAAI,CAAC,EACL;AAAA,IACC;AAAA,EACF;AAAA,EACF,YAAY,aACT,KAAK,CAAC,MAAM,IAAI,CAAC,EACjB,SAAS,qCAAqC,EAC9C,SAAS;AAAA,EACZ,qBAAqB,aAClB,OAAO,EACP,IAAI,EACJ,SAAS,EACT,SAAS,4DAA4D,EACrE,SAAS;AAAA,EACZ,gBAAgB,aACb,OAAO,EACP,IAAI,EACJ,SAAS,EACT,SAAS,gDAAgD,EACzD,SAAS;AAAA,EACZ,iBAAiB,aACd,OAAO,EACP,IAAI,EACJ,YAAY,EACZ,SAAS,0CAA0C,EACnD,SAAS;AAAA,EACZ,WAAW,aACR,KAAK,CAAC,SAAS,OAAO,QAAQ,CAAC,EAC/B,SAAS,iCAAiC,EAC1C,SAAS;AAAA,EACZ,UAAU,aACP,QAAQ,EACR;AAAA,IACC;AAAA,EACF,EACC,SAAS;AAAA,EACZ,YAAY,aACT,OAAO,EACP,SAAS,+CAA+C,EACxD,SAAS;AAAA,EACZ,UAAU,aACP,QAAQ,EACR;AAAA,IACC;AAAA,EACF,EACC,SAAS;AAAA,EACZ,eAAe,aACZ,QAAQ,EACR;AAAA,IACC;AAAA,EACF,EACC,SAAS;AAAA,EACZ,YAAY,aACT,QAAQ,EACR;AAAA,IACC;AAAA,EACF,EACC,SAAS;AAAA,EACZ,YAAY,aACT,QAAQ,EACR;AAAA,IACC;AAAA,EACF,EACC,SAAS;AACd,CAAC;;;ACrED,IAAAC,cAAkB;AAEX,IAAM,gBAAgB,cAAE,OAAO;AAAA,EACpC,UAAU,cACP,QAAQ,EACR;AAAA,IACC;AAAA,EACF,EACC,SAAS;AAAA,EACZ,SAAS,cACN,QAAQ,EACR;AAAA,IACC;AAAA,EACF,EACC,SAAS;AAAA,EACZ,OAAO,cACJ,QAAQ,EACR;AAAA,IACC;AAAA,EACF,EACC,SAAS;AAAA,EACZ,eAAe,cACZ,QAAQ,EACR;AAAA,IACC;AAAA,EACF,EACC,SAAS;AAAA,EACZ,OAAO,cACJ,QAAQ,EACR;AAAA,IACC;AAAA,EACF,EACC,SAAS;AACd,CAAC;;;AFzBM,IAAM,eAAW,yBAAY,cAAc;AAC3C,IAAM,cAAU,yBAAY,aAAa;;;AGThD;AAAA;AAAA;AAAA;AAAA;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUA,IAAM,OAAO,MAAM;AAAC;AACpB,IAAM,cAAc,OAAO,EAAE,SAAS,QAAQ,QAAQ,EAAE;AAMxD,IAAM,eAAN,MAA+C;AAAA,EAA/C;AACE,gBAAgD,CAAC;AAAA;AAAA,EAEzC,QAAQ,IAAY,MAAc,OAAiB;AACzD,QAAI,CAAC,KAAK,KAAK,EAAE,EAAG,MAAK,KAAK,EAAE,IAAI,CAAC;AACrC,SAAK,KAAK,EAAE,EAAE,IAAI,IAAI;AACtB,WAAO;AAAA,EACT;AAAA,EAEA,IAAI,MAAc,OAAgB;AAChC,WAAO,KAAK,QAAQ,OAAO,MAAM,KAAK;AAAA,EACxC;AAAA,EACA,QAAQ,MAAc,OAAgB;AACpC,WAAO,KAAK,QAAQ,WAAW,MAAM,KAAK;AAAA,EAC5C;AAAA,EACA,IAAI,MAAc,OAAgB;AAChC,WAAO,KAAK,QAAQ,OAAO,MAAM,KAAK;AAAA,EACxC;AAAA,EACA,OAAO,MAAc,OAAgB;AACnC,WAAO,KAAK,QAAQ,UAAU,MAAM,KAAK;AAAA,EAC3C;AAAA,EACA,QAAQ,MAAc,OAAgB;AACpC,WAAO,KAAK,QAAQ,WAAW,MAAM,KAAK;AAAA,EAC5C;AAAA,EACA,UAAU,MAAc,OAAgB;AACtC,WAAO,KAAK,QAAQ,aAAa,MAAM,KAAK;AAAA,EAC9C;AAAA,EACA,WAAW,MAAc,OAAgB;AACvC,WAAO,KAAK,QAAQ,cAAc,MAAM,KAAK;AAAA,EAC/C;AAAA,EACA,OAAO,MAAc,OAAgB;AACnC,WAAO,KAAK,QAAQ,UAAU,MAAM,KAAK;AAAA,EAC3C;AAAA,EACA,MAAM,MAAc;AAClB,WAAO,KAAK,QAAQ,SAAS,IAAI;AAAA,EACnC;AAAA,EACA,WAAW;AACT,SAAK,KAAK,UAAU,IAAI,CAAC;AACzB,WAAO;AAAA,EACT;AAAA,EAEA,SAAS;AACP,WAAO,KAAK;AAAA,EACd;AACF;AAGA,IAAM,cAAN,MAA6C;AAAA,EAA7C;AACE,iBAAiC,CAAC;AAAA;AAAA,EAElC,aAAa,GAAW;AACtB,SAAK,MAAM,YAAY;AACvB,WAAO;AAAA,EACT;AAAA,EACA,SAAS,GAAW;AAClB,SAAK,MAAM,QAAQ;AACnB,WAAO;AAAA,EACT;AAAA,EACA,YAAY,GAAW;AACrB,SAAK,MAAM,WAAW;AACtB,WAAO;AAAA,EACT;AAAA,EACA,eAAe,GAAW;AACxB,SAAK,MAAM,cAAc;AACzB,WAAO;AAAA,EACT;AAAA,EACA,YAAY,GAAW;AACrB,SAAK,MAAM,WAAW;AACtB,WAAO;AAAA,EACT;AAAA,EACA,WAAW,GAAW;AACpB,SAAK,MAAM,UAAU;AACrB,WAAO;AAAA,EACT;AAAA,EACA,WAAW,GAAW;AACpB,SAAK,MAAM,UAAU;AACrB,WAAO;AAAA,EACT;AAAA,EACA,cAAc,GAAW;AACvB,SAAK,MAAM,aAAa;AACxB,WAAO;AAAA,EACT;AAAA,EACA,mBAAmB,GAAY;AAC7B,SAAK,MAAM,kBAAkB;AAC7B,WAAO;AAAA,EACT;AAAA,EAEA,SAAS;AACP,WAAO,KAAK;AAAA,EACd;AACF;AAKO,IAAM,OAAwB;AAAA,EACnC,WAAW;AAAA,IACT,SAAS,MAAM,QAAQ,QAAQ;AAAA,IAC/B,OAAO;AAAA,IACP,UAAU;AAAA,IACV,SAAS;AAAA,IACT,OAAO;AAAA,IACP,WAAW;AAAA,IACX,WAAW;AAAA,IACX,aAAa;AAAA,IACb,cAAc;AAAA,IACd,UAAU;AAAA,IACV,eAAe;AAAA,IACf,OAAO;AAAA,IACP,KAAK;AAAA,IACL,UAAU;AAAA,IACV,SAAS;AAAA,EACX;AACF;AAMO,IAAM,OAAY;AAAA,EACvB,WAAW;AAAA,IACT,SAAS,MAAM,QAAQ,QAAQ;AAAA,IAC/B,OAAO;AAAA,IACP,UAAU;AAAA,IACV,SAAS;AAAA,IACT,OAAO;AAAA,IACP,WAAW;AAAA,IACX,WAAW;AAAA,IACX,aAAa;AAAA,IACb,cAAc;AAAA,IACd,UAAU;AAAA,IACV,eAAe;AAAA,IACf,OAAO;AAAA,IACP,KAAK;AAAA,IACL,UAAU;AAAA,IACV,SAAS;AAAA,EACX;AACF;AAGO,IAAM,aAAa;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ACzKA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,kBAAyB;AAsBlB,IAAM,yBAA+C;AAAA,EAC1D,OAAO;AAAA,EACP,aACE;AAAA,EACF,QAAI,sBAAS,gBAAgB,EAAE,WAAW,WAAW,CAAC;AAAA,EACtD,KAAK,CAAC,CAAC,mBAAmB,gBAAgB,CAAC,CAAC,CAAC;AAC/C;AAMO,IAAM,kBAAwC;AAAA,EACnD,QAAQ;AAAA,EACR,QAAI,sBAAS,eAAe,EAAE,WAAW,WAAW,CAAC;AAAA,EACrD,SAAS,EAAE,QAAQ,KAAK;AAAA,EACxB,KAAK,CAAC;AACR;AAMO,IAAM,0BAAgD;AAAA,EAC3D,OAAO;AAAA,EACP,aACE;AAAA,EACF,QAAI,sBAAS,gBAAgB,EAAE,WAAW,WAAW,CAAC;AAAA,EACtD,eAAe,CAAC,MAAM;AAAA,EACtB,KAAK;AAAA,IACH;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,QACE,SAAS;AAAA,QACT,WAAW;AAAA,QACX,YAAY;AAAA,QACZ,WAAW;AAAA,QACX,YAAY;AAAA,MACd;AAAA,IACF;AAAA,EACF;AACF;AAOO,IAAM,sBAA4C;AAAA,EACvD,OAAO;AAAA,EACP,aACE;AAAA,EACF,QAAI,sBAAS,kBAAkB,EAAE,WAAW,WAAW,CAAC;AAAA,EACxD,eAAe,CAAC,MAAM;AAAA,EACtB,SAAS;AAAA,IACP,SAAS,CAAC,SAAS;AAAA,EACrB;AAAA,EACA,KAAK;AAAA,IACH;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,QACE,mBAAmB;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AACF;AAgBO,IAAM,2BAAiD;AAAA,EAC5D,OAAO;AAAA,EACP,aACE;AAAA,EACF,QAAI,sBAAS,aAAa,EAAE,WAAW,WAAW,CAAC;AAAA,EACnD,UAAU;AAAA,IACR,UAAU;AAAA,MACR,KAAK;AAAA,QACH,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF;AAAA,EACA,KAAK;AAAA,IACH,CAAC,uBAAuB,MAAM;AAAA,IAC9B,CAAC,yBAAyB,QAAQ;AAAA,IAClC,CAAC,0BAA0B,SAAS;AAAA,IACpC,CAAC,mBAAmB,aAAa,CAAC,CAAC;AAAA,EACrC;AACF;AAQO,IAAM,oBAA0C;AAAA,EACrD,OAAO;AAAA,EACP,aACE;AAAA,EACF,QAAI,sBAAS,cAAc;AAAA,IACzB,WAAW;AAAA,IACX,MAAM;AAAA,MACJ,SAAS;AAAA,MACT,MAAM;AAAA,MACN,SAAS;AAAA,MACT,OAAO;AAAA,IACT;AAAA,EACF,CAAC;AAAA,EACD,SAAS;AAAA,IACP,QAAQ;AAAA,IACR,UAAU;AAAA,MACR,UAAU;AAAA,QACR,KAAK;AAAA,UACH,MAAM;AAAA,UACN,KAAK;AAAA,YACH,KAAK;AAAA,cACH,MAAM;AAAA,cACN,SAAS;AAAA,cACT,OAAO;AAAA,YACT;AAAA,UACF;AAAA,UACA,SAAS;AAAA,YACP,KAAK;AAAA,cACH,aAAa;AAAA,YACf;AAAA,UACF;AAAA,UACA,KAAK;AAAA,YACH,KAAK;AAAA,cACH,aAAa,EAAE,OAAO,EAAE;AAAA,YAC1B;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,KAAK;AAAA,IACH,CAAC,uBAAuB,cAAc;AAAA,IACtC;AAAA,MACE;AAAA,MACA;AAAA,QACE,KAAK;AAAA,UACH,MAAM;AAAA,UACN,SAAS;AAAA,UACT,OAAO;AAAA,QACT;AAAA,QACA,SAAS;AAAA,UACP,aAAa;AAAA,QACf;AAAA,QACA,KAAK;AAAA,UACH,aAAa;AAAA,QACf;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAOO,IAAM,kBAAwC;AAAA,EACnD,OAAO;AAAA,EACP,aACE;AAAA,EACF,QAAI,sBAAS,eAAe,EAAE,WAAW,WAAW,CAAC;AAAA,EACrD,SAAS;AAAA,IACP,QAAQ;AAAA,IACR,UAAU;AAAA,MACR,OAAO;AAAA,IACT;AAAA,EACF;AAAA,EACA,KAAK,CAAC,CAAC,iBAAiB,CAAC;AAC3B;AASO,IAAM,2BAAiD;AAAA,EAC5D,OAAO;AAAA,EACP,aACE;AAAA,EACF,QAAI,sBAAS,sBAAsB;AAAA,IACjC,WAAW;AAAA,IACX,MAAM;AAAA,MACJ,SAAS;AAAA,MACT,QAAQ;AAAA,IACV;AAAA,EACF,CAAC;AAAA,EACD,SAAS;AAAA,IACP,QAAQ;AAAA,IACR,UAAU;AAAA,MACR,SAAS;AAAA,QACP,KAAK;AAAA,UACH,WAAW;AAAA,UACX,OAAO;AAAA,UACP,aAAa,EAAE,OAAO,UAAU;AAAA,UAChC,UAAU,EAAE,KAAK,iBAAiB,OAAO,MAAM;AAAA,QACjD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,KAAK;AAAA,IACH;AAAA,MACE;AAAA,MACA;AAAA,QACE,WAAW;AAAA,QACX,OAAO;AAAA,QACP,aAAa;AAAA,QACb,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AACF;AAcO,IAAM,4BAAkD;AAAA,EAC7D,OAAO;AAAA,EACP,aACE;AAAA,EACF,QAAI,sBAAS,kBAAkB,EAAE,WAAW,WAAW,CAAC;AAAA,EACxD,SAAS;AAAA,IACP,SAAS,CAAC,QAAQ,SAAS;AAAA,IAC3B,UAAU;AAAA,MACR,SAAS;AAAA,QACP,MAAM;AAAA,UACJ;AAAA,UACA;AAAA;AAAA,YAEE,WAAW,CAAC,UAAmB;AA3R3C;AA4Rc,oBAAM,IAAI;AACV,qBAAO,SAAO,4BAAG,SAAH,mBAAS,WAAU;AAAA,YACnC;AAAA,YACA,KAAK;AAAA,cACH,WAAW;AAAA,cACX,OAAO;AAAA,cACP,UAAU,EAAE,KAAK,iBAAiB,OAAO,EAAE;AAAA,cAC3C,aAAa,EAAE,OAAO,WAAW;AAAA,cACjC,UAAU,EAAE,KAAK,iBAAiB,OAAO,MAAM;AAAA,YACjD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,KAAK;AAAA,IACH;AAAA,MACE;AAAA,MACA;AAAA,QACE,WAAW;AAAA,QACX,OAAO;AAAA,QACP,UAAU;AAAA,QACV,aAAa;AAAA,QACb,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,QACE,WAAW;AAAA,QACX,OAAO;AAAA,QACP,UAAU;AAAA,QACV,aAAa;AAAA,QACb,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,QACE,SAAS;AAAA,QACT,eAAe;AAAA,QACf,eAAe;AAAA,QACf,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,mBAAmB;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AACF;AAMO,IAAM,gCAAsD;AAAA,EACjE,OAAO;AAAA,EACP,aACE;AAAA,EACF,QAAI,sBAAS,kBAAkB;AAAA,IAC7B,WAAW;AAAA,IACX,MAAM;AAAA,MACJ,SAAS;AAAA,MACT,UAAU;AAAA,MACV,gBAAgB;AAAA,MAChB,cAAc;AAAA,IAChB;AAAA,EACF,CAAC;AAAA,EACD,SAAS;AAAA,IACP,QAAQ;AAAA,IACR,UAAU;AAAA,MACR,OAAO;AAAA,QACL,KAAK;AAAA,UACH,MAAM,EAAE,OAAO,UAAU;AAAA,UACzB,MAAM;AAAA,QACR;AAAA,MACF;AAAA,MACA,eAAe;AAAA,QACb,KAAK;AAAA,UACH,MAAM,EAAE,OAAO,UAAU;AAAA,UACzB,MAAM;AAAA,UACN,KAAK;AAAA,YACH,KAAK;AAAA,cACH,UAAU;AAAA,cACV,MAAM;AAAA,YACR;AAAA,UACF;AAAA,UACA,SAAS;AAAA,YACP,KAAK;AAAA,cACH,SAAS;AAAA,YACX;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,KAAK;AAAA,IACH,CAAC,sBAAsB,WAAW,MAAM;AAAA,IACxC;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,QACE,KAAK;AAAA,UACH,UAAU;AAAA,UACV,MAAM;AAAA,QACR;AAAA,QACA,SAAS;AAAA,UACP,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAWO,IAAM,sBAA4C;AAAA,EACvD,OAAO;AAAA,EACP,aACE;AAAA,EACF,SAAS;AAAA,EACT,QAAQ,EAAE,WAAW,KAAK;AAAA,EAC1B,IAAI,EAAE,WAAW,MAAM;AAAA,EACvB,UAAU,CAAC;AAAA,EACX,KAAK;AAAA,IACH,CAAC,uBAAuB,KAAK;AAAA,IAC7B,CAAC,uBAAuB,IAAI;AAAA,EAC9B;AACF;AAKO,IAAM,oBAA0C;AAAA,EACrD,OAAO;AAAA,EACP,aACE;AAAA,EACF,SAAS;AAAA,EACT,IAAI,EAAE,WAAW,KAAK;AAAA,EACtB,UAAU,CAAC;AAAA,EACX,KAAK,CAAC,CAAC,uBAAuB,KAAK,CAAC;AACtC;","names":["import_dev","import_dev"]}
package/dist/dev.mjs CHANGED
@@ -1 +1 @@
1
- var e=Object.defineProperty,t=(t,i)=>{for(var n in i)e(t,n,{get:i[n],enumerable:!0})},i={};t(i,{MappingSchema:()=>o,SettingsSchema:()=>a,mapping:()=>p,settings:()=>d});import{zodToSchema as n}from"@walkeros/core/dev";import{z as r}from"@walkeros/core/dev";var a=r.object({apiKey:r.string().min(1).describe('Your Amplitude project API key. Find it in your Amplitude project settings under "General" → "API Keys" (like a1b2c3d4e5f6789012345678abcdef12).'),serverZone:r.enum(["US","EU"]).describe("Amplitude server zone. Default: US.").optional(),flushIntervalMillis:r.number().int().positive().describe("How often (in ms) to flush the event queue. Default: 1000.").optional(),flushQueueSize:r.number().int().positive().describe("Max queued events before a flush. Default: 30.").optional(),flushMaxRetries:r.number().int().nonnegative().describe("Max retries on failed flush. Default: 5.").optional(),transport:r.enum(["fetch","xhr","beacon"]).describe("HTTP transport. Default: fetch.").optional(),useBatch:r.boolean().describe("Use the Amplitude batch endpoint instead of the standard endpoint. Default: false.").optional(),appVersion:r.string().describe("Application version; tagged onto every event.").optional(),identify:r.unknown().describe("walkerOS mapping value resolving to an identity object. Keys: user, device, session, set, setOnce, add, append, prepend, preInsert, postInsert, remove, unset, clearAll.").optional(),sessionReplay:r.unknown().describe("Session Replay options. When present, session replay is enabled via @amplitude/unified with the provided options.").optional(),experiment:r.unknown().describe("Feature Experiment config. Must include `deploymentKey`. When present, the experiment plugin from @amplitude/unified is configured with the provided options.").optional(),engagement:r.unknown().describe("Guides & Surveys config. Pass `true` for defaults, or an options object for custom configuration. Enabled via @amplitude/unified.").optional()});import{z as s}from"@walkeros/core/dev";var o=s.object({identify:s.unknown().describe("Per-event identity mapping. Resolves to an object with any of: user, device, session, set, setOnce, add, append, prepend, preInsert, postInsert, remove, unset, clearAll.").optional(),revenue:s.unknown().describe("Revenue mapping. Resolves to a single object or (via loop) an array of objects, each with: productId, price, quantity, revenueType, currency, revenue, receipt, receiptSig, eventProperties. One amplitude.revenue() call fires per item.").optional(),group:s.unknown().describe("Group assignment. Resolves to { type, name } → amplitude.setGroup(type, name).").optional(),groupIdentify:s.unknown().describe("Group properties. Resolves to { type, name, set?, setOnce?, ... } → amplitude.groupIdentify(type, name, identify).").optional(),reset:s.unknown().describe("Logout trigger. Resolves to a truthy value → amplitude.reset() (clears userId, regenerates deviceId). Typically used with silent: true on a user logout rule.").optional()}),d=n(a),p=n(o),u={};t(u,{env:()=>l,step:()=>I});var l={};t(l,{init:()=>g,push:()=>h,simulation:()=>f});var c=()=>{},m=()=>({promise:Promise.resolve()}),v=class{constructor(){this._ops={}}_record(e,t,i){return this._ops[e]||(this._ops[e]={}),this._ops[e][t]=i,this}set(e,t){return this._record("set",e,t)}setOnce(e,t){return this._record("setOnce",e,t)}add(e,t){return this._record("add",e,t)}append(e,t){return this._record("append",e,t)}prepend(e,t){return this._record("prepend",e,t)}preInsert(e,t){return this._record("preInsert",e,t)}postInsert(e,t){return this._record("postInsert",e,t)}remove(e,t){return this._record("remove",e,t)}unset(e){return this._record("unset",e)}clearAll(){return this._ops.clearAll={},this}toJSON(){return this._ops}},y=class{constructor(){this._data={}}setProductId(e){return this._data.productId=e,this}setPrice(e){return this._data.price=e,this}setQuantity(e){return this._data.quantity=e,this}setRevenueType(e){return this._data.revenueType=e,this}setCurrency(e){return this._data.currency=e,this}setRevenue(e){return this._data.revenue=e,this}setReceipt(e){return this._data.receipt=e,this}setReceiptSig(e){return this._data.receiptSig=e,this}setEventProperties(e){return this._data.eventProperties=e,this}toJSON(){return this._data}},g={amplitude:{initAll:()=>Promise.resolve(),track:c,identify:c,revenue:c,reset:c,setOptOut:c,setUserId:c,setDeviceId:c,setSessionId:c,setGroup:c,groupIdentify:c,flush:m,add:m,Identify:v,Revenue:y}},h={amplitude:{initAll:()=>Promise.resolve(),track:c,identify:c,revenue:c,reset:c,setOptOut:c,setUserId:c,setDeviceId:c,setSessionId:c,setGroup:c,groupIdentify:c,flush:m,add:m,Identify:v,Revenue:y}},f=["call:amplitude.initAll","call:amplitude.track","call:amplitude.identify","call:amplitude.revenue","call:amplitude.reset","call:amplitude.setOptOut","call:amplitude.setUserId","call:amplitude.setDeviceId","call:amplitude.setSessionId","call:amplitude.setGroup","call:amplitude.groupIdentify"],I={};t(I,{consentGrantOptIn:()=>G,consentRevokeOptOut:()=>E,defaultEventForwarding:()=>_,destinationLevelIdentify:()=>O,destinationLevelInclude:()=>k,groupAssignmentWithProperties:()=>D,orderCompleteMultiProduct:()=>P,ruleIncludeReplaces:()=>A,subscriptionRenewRevenue:()=>U,userLoginIdentify:()=>R,userLogoutReset:()=>S,wildcardIgnored:()=>w});import{getEvent as b}from"@walkeros/core";var _={title:"Default track",description:"A walker event is forwarded to Amplitude as an amplitude.track call with the event name and empty properties.",in:b("product view",{timestamp:1700000100}),out:[["amplitude.track","product view",{}]]},w={public:!1,in:b("debug noise",{timestamp:1700000101}),mapping:{ignore:!0},out:[]},k={title:"Include data",description:"Destination-level include flattens the event data section into prefixed event_properties on every track call.",in:b("product view",{timestamp:1700000102}),configInclude:["data"],out:[["amplitude.track","product view",{data_id:"ers",data_name:"Everyday Ruck Snack",data_color:"black",data_size:"l",data_price:420}]]},A={title:"Rule include overrides",description:"A per-rule include replaces the destination-level include for the matched event, here using only globals.",in:b("order complete",{timestamp:1700000103}),configInclude:["data"],mapping:{include:["globals"]},out:[["amplitude.track","order complete",{globals_pagegroup:"shop"}]]},O={title:"Destination identify",description:"Destination-level identify sets userId, deviceId, and sessionId on the Amplitude client before sending events; setters only re-fire when the resolved values change (cached values are not re-applied on subsequent pushes).",in:b("page view",{timestamp:1700000104}),settings:{identify:{map:{user:"user.id",device:"user.device",session:"user.session"}}},out:[["amplitude.setUserId","us3r"],["amplitude.setDeviceId","c00k13"],["amplitude.setSessionId",394324160],["amplitude.track","page view",{}]]},R={title:"User login identify",description:"A user login sets the Amplitude userId and runs identify with set, setOnce, and add operations.",in:b("user login",{timestamp:1700000105,data:{user_id:"new-user-123",plan:"premium",company:"Acme",email:"user@acme.com"}}),mapping:{silent:!0,settings:{identify:{map:{user:"data.user_id",set:{map:{plan:"data.plan",company:"data.company",email:"data.email"}},setOnce:{map:{first_login:"timestamp"}},add:{map:{login_count:{value:1}}}}}}},out:[["amplitude.setUserId","new-user-123"],["amplitude.identify",{set:{plan:"premium",company:"Acme",email:"user@acme.com"},setOnce:{first_login:1700000105},add:{login_count:1}}]]},S={title:"User logout reset",description:"A user logout calls amplitude.reset to clear the userId and regenerate the deviceId.",in:b("user logout",{timestamp:1700000106}),mapping:{silent:!0,settings:{reset:!0}},out:[["amplitude.reset"]]},U={title:"Subscription revenue",description:"A subscription renewal fires a single amplitude.revenue call with productId, price, and currency fallback.",in:b("subscription renew",{timestamp:1700000107,data:{plan_id:"plan-pro",amount:9.99}}),mapping:{silent:!0,settings:{revenue:{map:{productId:"data.plan_id",price:"data.amount",revenueType:{value:"renewal"},currency:{key:"data.currency",value:"EUR"}}}}},out:[["amplitude.revenue",{productId:"plan-pro",price:9.99,revenueType:"renewal",currency:"EUR"}]]},P={title:"Multi-product order",description:"An order fires one amplitude.revenue call per nested product plus a single track for the order totals.",in:b("order complete",{timestamp:1700000108}),mapping:{include:["data","globals"],settings:{revenue:{loop:["nested",{condition:e=>{var t;return"number"==typeof(null==(t=null==e?void 0:e.data)?void 0:t.price)},map:{productId:"data.id",price:"data.price",quantity:{key:"data.quantity",value:1},revenueType:{value:"purchase"},currency:{key:"data.currency",value:"EUR"}}}]}}},out:[["amplitude.revenue",{productId:"ers",price:420,quantity:1,revenueType:"purchase",currency:"EUR"}],["amplitude.revenue",{productId:"cc",price:42,quantity:1,revenueType:"purchase",currency:"EUR"}],["amplitude.track","order complete",{data_id:"0rd3r1d",data_currency:"EUR",data_shipping:5.22,data_taxes:73.76,data_total:555,globals_pagegroup:"shop"}]]},D={title:"Group assignment",description:"A company update assigns the user to a group and sets group properties via setGroup and groupIdentify.",in:b("company update",{timestamp:1700000109,data:{company:"Acme",industry:"tech",employee_count:50,founded_year:2020}}),mapping:{silent:!0,settings:{group:{map:{type:{value:"company"},name:"data.company"}},groupIdentify:{map:{type:{value:"company"},name:"data.company",set:{map:{industry:"data.industry",size:"data.employee_count"}},setOnce:{map:{founded:"data.founded_year"}}}}}},out:[["amplitude.setGroup","company","Acme"],["amplitude.groupIdentify","company","Acme",{set:{industry:"tech",size:50},setOnce:{founded:2020}}]]},E={title:"Consent revoked",description:"A walker consent command with analytics denied opts out of Amplitude tracking via setOptOut(true).",command:"consent",before:{analytics:!0},in:{analytics:!1},settings:{},out:[["amplitude.setOptOut",!1],["amplitude.setOptOut",!0]]},G={title:"Consent granted",description:"A walker consent command with analytics granted opts back into Amplitude tracking via setOptOut(false).",command:"consent",in:{analytics:!0},settings:{},out:[["amplitude.setOptOut",!1]]};export{u as examples,i as schemas};//# sourceMappingURL=dev.mjs.map
1
+ var e=Object.defineProperty,t=(t,i)=>{for(var n in i)e(t,n,{get:i[n],enumerable:!0})},i={};t(i,{MappingSchema:()=>o,SettingsSchema:()=>r,mapping:()=>p,settings:()=>d});import{zodToSchema as n}from"@walkeros/core/dev";import{z as s}from"@walkeros/core/dev";var r=s.object({apiKey:s.string().min(1).describe('Your Amplitude project API key. Find it in your Amplitude project settings under "General" → "API Keys" (like a1b2c3d4e5f6789012345678abcdef12).'),serverZone:s.enum(["US","EU"]).describe("Amplitude server zone. Default: US.").optional(),flushIntervalMillis:s.number().int().positive().describe("How often (in ms) to flush the event queue. Default: 1000.").optional(),flushQueueSize:s.number().int().positive().describe("Max queued events before a flush. Default: 30.").optional(),flushMaxRetries:s.number().int().nonnegative().describe("Max retries on failed flush. Default: 5.").optional(),transport:s.enum(["fetch","xhr","beacon"]).describe("HTTP transport. Default: fetch.").optional(),useBatch:s.boolean().describe("Use the Amplitude batch endpoint instead of the standard endpoint. Default: false.").optional(),appVersion:s.string().describe("Application version; tagged onto every event.").optional(),identify:s.unknown().describe("walkerOS mapping value resolving to an identity object. Keys: user, device, session, set, setOnce, add, append, prepend, preInsert, postInsert, remove, unset, clearAll.").optional(),sessionReplay:s.unknown().describe("Session Replay options, passed to the Session Replay plugin. @amplitude/unified sets up the plugin on every init, whether or not this is set; it records a sampled share of sessions, set by the project sampling settings in Amplitude when present, else by sampleRate (default 0).").optional(),experiment:s.unknown().describe("Feature Experiment options. Passed to the Experiment plugin only when they include `deploymentKey`. @amplitude/unified sets up the plugin on every init; without a deploymentKey it uses the API key.").optional(),engagement:s.unknown().describe("Guides & Surveys options object. @amplitude/unified loads the Guides & Surveys SDK from cdn.amplitude.com on every init, whether or not this is set; `true` passes no options.").optional()});import{z as a}from"@walkeros/core/dev";var o=a.object({identify:a.unknown().describe("Per-event identity mapping. Resolves to an object with any of: user, device, session, set, setOnce, add, append, prepend, preInsert, postInsert, remove, unset, clearAll.").optional(),revenue:a.unknown().describe("Revenue mapping. Resolves to a single object or (via loop) an array of objects, each with: productId, price, quantity, revenueType, currency, revenue, receipt, receiptSig, eventProperties. One amplitude.revenue() call fires per item.").optional(),group:a.unknown().describe("Group assignment. Resolves to { type, name } → amplitude.setGroup(type, name).").optional(),groupIdentify:a.unknown().describe("Group properties. Resolves to { type, name, set?, setOnce?, ... } → amplitude.groupIdentify(type, name, identify).").optional(),reset:a.unknown().describe("Logout trigger. Resolves to a truthy value → amplitude.reset() (clears userId, regenerates deviceId). Typically used with silent: true on a user logout rule.").optional()}),d=n(r),p=n(o),u={};t(u,{env:()=>l,step:()=>I});var l={};t(l,{init:()=>h,push:()=>g,simulation:()=>f});var c=()=>{},m=()=>({promise:Promise.resolve()}),y=class{constructor(){this._ops={}}_record(e,t,i){return this._ops[e]||(this._ops[e]={}),this._ops[e][t]=i,this}set(e,t){return this._record("set",e,t)}setOnce(e,t){return this._record("setOnce",e,t)}add(e,t){return this._record("add",e,t)}append(e,t){return this._record("append",e,t)}prepend(e,t){return this._record("prepend",e,t)}preInsert(e,t){return this._record("preInsert",e,t)}postInsert(e,t){return this._record("postInsert",e,t)}remove(e,t){return this._record("remove",e,t)}unset(e){return this._record("unset",e)}clearAll(){return this._ops.clearAll={},this}toJSON(){return this._ops}},v=class{constructor(){this._data={}}setProductId(e){return this._data.productId=e,this}setPrice(e){return this._data.price=e,this}setQuantity(e){return this._data.quantity=e,this}setRevenueType(e){return this._data.revenueType=e,this}setCurrency(e){return this._data.currency=e,this}setRevenue(e){return this._data.revenue=e,this}setReceipt(e){return this._data.receipt=e,this}setReceiptSig(e){return this._data.receiptSig=e,this}setEventProperties(e){return this._data.eventProperties=e,this}toJSON(){return this._data}},h={amplitude:{initAll:()=>Promise.resolve(),track:c,identify:c,revenue:c,reset:c,setOptOut:c,setUserId:c,setDeviceId:c,setSessionId:c,setGroup:c,groupIdentify:c,flush:m,add:m,Identify:y,Revenue:v}},g={amplitude:{initAll:()=>Promise.resolve(),track:c,identify:c,revenue:c,reset:c,setOptOut:c,setUserId:c,setDeviceId:c,setSessionId:c,setGroup:c,groupIdentify:c,flush:m,add:m,Identify:y,Revenue:v}},f=["call:amplitude.initAll","call:amplitude.track","call:amplitude.identify","call:amplitude.revenue","call:amplitude.reset","call:amplitude.setOptOut","call:amplitude.setUserId","call:amplitude.setDeviceId","call:amplitude.setSessionId","call:amplitude.setGroup","call:amplitude.groupIdentify"],I={};t(I,{consentGrantOptIn:()=>E,consentRevokeOptOut:()=>G,defaultEventForwarding:()=>_,destinationLevelIdentify:()=>A,destinationLevelInclude:()=>k,groupAssignmentWithProperties:()=>D,orderCompleteMultiProduct:()=>U,ruleIncludeReplaces:()=>O,subscriptionRenewRevenue:()=>P,userLoginIdentify:()=>R,userLogoutReset:()=>S,wildcardIgnored:()=>w});import{getEvent as b}from"@walkeros/core";var _={title:"Default track",description:"A walker event is forwarded to Amplitude as an amplitude.track call with the event name and empty properties.",in:b("product view",{timestamp:1700000100}),out:[["amplitude.track","product view",{}]]},w={public:!1,in:b("debug noise",{timestamp:1700000101}),mapping:{ignore:!0},out:[]},k={title:"Include data",description:"With include: ['data'] in the destination config, the event data section is flattened into prefixed event_properties on every track call.",in:b("product view",{timestamp:1700000102}),configInclude:["data"],out:[["amplitude.track","product view",{data_id:"ers",data_name:"Everyday Ruck Snack",data_color:"black",data_size:"l",data_price:420}]]},O={title:"Rule include overrides",description:"With include: ['data'] in the destination config, the rule's include: ['globals'] replaces it, so this event forwards only globals.",in:b("order complete",{timestamp:1700000103}),configInclude:["data"],mapping:{include:["globals"]},out:[["amplitude.track","order complete",{globals_pagegroup:"shop"}]]},A={title:"Destination identify",description:"With settings.identify mapping user, device, and session to 'user.id', 'user.device', and 'user.session', the destination sets userId, deviceId, and sessionId before the track call. A non-numeric session string is hashed to a stable number. Setters only re-fire when the resolved values change.",in:b("page view",{timestamp:1700000104}),settings:{identify:{map:{user:"user.id",device:"user.device",session:"user.session"}}},out:[["amplitude.setUserId","us3r"],["amplitude.setDeviceId","c00k13"],["amplitude.setSessionId",394324160],["amplitude.track","page view",{}]]},R={title:"User login identify",description:"A user login sets the Amplitude userId and runs identify with set, setOnce, and add operations.",in:b("user login",{timestamp:1700000105e3,data:{user_id:"new-user-123",plan:"premium",company:"Acme",email:"user@acme.com"}}),mapping:{silent:!0,settings:{identify:{map:{user:"data.user_id",set:{map:{plan:"data.plan",company:"data.company",email:"data.email"}},setOnce:{map:{first_login:"timestamp"}},add:{map:{login_count:{value:1}}}}}}},out:[["amplitude.setUserId","new-user-123"],["amplitude.identify",{set:{plan:"premium",company:"Acme",email:"user@acme.com"},setOnce:{first_login:1700000105e3},add:{login_count:1}}]]},S={title:"User logout reset",description:"A user logout calls amplitude.reset to clear the userId and regenerate the deviceId.",in:b("user logout",{timestamp:1700000106}),mapping:{silent:!0,settings:{reset:!0}},out:[["amplitude.reset"]]},P={title:"Subscription revenue",description:"A subscription renewal fires a single amplitude.revenue call with productId, price, and currency fallback.",in:b("subscription renew",{timestamp:1700000107,data:{plan_id:"plan-pro",amount:9.99}}),mapping:{silent:!0,settings:{revenue:{map:{productId:"data.plan_id",price:"data.amount",revenueType:{value:"renewal"},currency:{key:"data.currency",value:"EUR"}}}}},out:[["amplitude.revenue",{productId:"plan-pro",price:9.99,revenueType:"renewal",currency:"EUR"}]]},U={title:"Multi-product order",description:"An order fires one amplitude.revenue call per nested product plus a single track for the order totals.",in:b("order complete",{timestamp:1700000108}),mapping:{include:["data","globals"],settings:{revenue:{loop:["nested",{condition:e=>{var t;return"number"==typeof(null==(t=null==e?void 0:e.data)?void 0:t.price)},map:{productId:"data.id",price:"data.price",quantity:{key:"data.quantity",value:1},revenueType:{value:"purchase"},currency:{key:"data.currency",value:"EUR"}}}]}}},out:[["amplitude.revenue",{productId:"ers",price:420,quantity:1,revenueType:"purchase",currency:"EUR"}],["amplitude.revenue",{productId:"cc",price:42,quantity:1,revenueType:"purchase",currency:"EUR"}],["amplitude.track","order complete",{data_id:"0rd3r1d",data_currency:"EUR",data_shipping:5.22,data_taxes:73.76,data_total:555,globals_pagegroup:"shop"}]]},D={title:"Group assignment",description:"A company update assigns the user to a group and sets group properties via setGroup and groupIdentify.",in:b("company update",{timestamp:1700000109,data:{company:"Acme",industry:"tech",employee_count:50,founded_year:2020}}),mapping:{silent:!0,settings:{group:{map:{type:{value:"company"},name:"data.company"}},groupIdentify:{map:{type:{value:"company"},name:"data.company",set:{map:{industry:"data.industry",size:"data.employee_count"}},setOnce:{map:{founded:"data.founded_year"}}}}}},out:[["amplitude.setGroup","company","Acme"],["amplitude.groupIdentify","company","Acme",{set:{industry:"tech",size:50},setOnce:{founded:2020}}]]},G={title:"Consent revoked",description:"With consent: { analytics: true } in the destination config, a walker consent command that denies analytics opts out of Amplitude tracking via setOptOut(true).",command:"consent",before:{analytics:!0},in:{analytics:!1},settings:{},out:[["amplitude.setOptOut",!1],["amplitude.setOptOut",!0]]},E={title:"Consent granted",description:"With consent: { analytics: true } in the destination config, a walker consent command that grants analytics opts into Amplitude tracking via setOptOut(false).",command:"consent",in:{analytics:!0},settings:{},out:[["amplitude.setOptOut",!1]]};export{u as examples,i as schemas};//# sourceMappingURL=dev.mjs.map
package/dist/dev.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/schemas/index.ts","../src/schemas/settings.ts","../src/schemas/mapping.ts","../src/examples/index.ts","../src/examples/env.ts","../src/examples/step.ts"],"sourcesContent":["import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\nimport { MappingSchema } from './mapping';\n\nexport { SettingsSchema, type Settings } from './settings';\nexport { MappingSchema, type Mapping } from './mapping';\n\n// JSON Schema\nexport const settings = zodToSchema(SettingsSchema);\nexport const mapping = zodToSchema(MappingSchema);\n","import { z } from '@walkeros/core/dev';\n\nexport const SettingsSchema = z.object({\n apiKey: z\n .string()\n .min(1)\n .describe(\n 'Your Amplitude project API key. Find it in your Amplitude project settings under \"General\" → \"API Keys\" (like a1b2c3d4e5f6789012345678abcdef12).',\n ),\n serverZone: z\n .enum(['US', 'EU'])\n .describe('Amplitude server zone. Default: US.')\n .optional(),\n flushIntervalMillis: z\n .number()\n .int()\n .positive()\n .describe('How often (in ms) to flush the event queue. Default: 1000.')\n .optional(),\n flushQueueSize: z\n .number()\n .int()\n .positive()\n .describe('Max queued events before a flush. Default: 30.')\n .optional(),\n flushMaxRetries: z\n .number()\n .int()\n .nonnegative()\n .describe('Max retries on failed flush. Default: 5.')\n .optional(),\n transport: z\n .enum(['fetch', 'xhr', 'beacon'])\n .describe('HTTP transport. Default: fetch.')\n .optional(),\n useBatch: z\n .boolean()\n .describe(\n 'Use the Amplitude batch endpoint instead of the standard endpoint. Default: false.',\n )\n .optional(),\n appVersion: z\n .string()\n .describe('Application version; tagged onto every event.')\n .optional(),\n identify: z\n .unknown()\n .describe(\n 'walkerOS mapping value resolving to an identity object. Keys: user, device, session, set, setOnce, add, append, prepend, preInsert, postInsert, remove, unset, clearAll.',\n )\n .optional(),\n sessionReplay: z\n .unknown()\n .describe(\n 'Session Replay options. When present, session replay is enabled via @amplitude/unified with the provided options.',\n )\n .optional(),\n experiment: z\n .unknown()\n .describe(\n 'Feature Experiment config. Must include `deploymentKey`. When present, the experiment plugin from @amplitude/unified is configured with the provided options.',\n )\n .optional(),\n engagement: z\n .unknown()\n .describe(\n 'Guides & Surveys config. Pass `true` for defaults, or an options object for custom configuration. Enabled via @amplitude/unified.',\n )\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\nexport const MappingSchema = z.object({\n identify: z\n .unknown()\n .describe(\n 'Per-event identity mapping. Resolves to an object with any of: user, device, session, set, setOnce, add, append, prepend, preInsert, postInsert, remove, unset, clearAll.',\n )\n .optional(),\n revenue: z\n .unknown()\n .describe(\n 'Revenue mapping. Resolves to a single object or (via loop) an array of objects, each with: productId, price, quantity, revenueType, currency, revenue, receipt, receiptSig, eventProperties. One amplitude.revenue() call fires per item.',\n )\n .optional(),\n group: z\n .unknown()\n .describe(\n 'Group assignment. Resolves to { type, name } → amplitude.setGroup(type, name).',\n )\n .optional(),\n groupIdentify: z\n .unknown()\n .describe(\n 'Group properties. Resolves to { type, name, set?, setOnce?, ... } → amplitude.groupIdentify(type, name, identify).',\n )\n .optional(),\n reset: z\n .unknown()\n .describe(\n 'Logout trigger. Resolves to a truthy value → amplitude.reset() (clears userId, regenerates deviceId). Typically used with silent: true on a user logout rule.',\n )\n .optional(),\n});\n\nexport type Mapping = z.infer<typeof MappingSchema>;\n","export * as env from './env';\nexport * as step from './step';\n","import type { Env, IdentifyInstance, RevenueInstance } from '../types';\n\n/**\n * Example environment configurations for the Amplitude destination.\n *\n * Tests clone `push` and replace individual methods with jest spies.\n * Production leaves `env.amplitude` undefined — the destination falls back\n * to the real `@amplitude/unified` module namespace.\n */\n\nconst noop = () => {};\nconst noopPromise = () => ({ promise: Promise.resolve() });\n\n/**\n * Minimal chainable Identify mock. The real SDK class has the same shape.\n * Tests spy by replacing these methods with jest.fn() in the test runner.\n */\nclass MockIdentify implements IdentifyInstance {\n _ops: Record<string, Record<string, unknown>> = {};\n\n private _record(op: string, prop: string, value?: unknown) {\n if (!this._ops[op]) this._ops[op] = {};\n this._ops[op][prop] = value;\n return this;\n }\n\n set(prop: string, value: unknown) {\n return this._record('set', prop, value);\n }\n setOnce(prop: string, value: unknown) {\n return this._record('setOnce', prop, value);\n }\n add(prop: string, value: unknown) {\n return this._record('add', prop, value);\n }\n append(prop: string, value: unknown) {\n return this._record('append', prop, value);\n }\n prepend(prop: string, value: unknown) {\n return this._record('prepend', prop, value);\n }\n preInsert(prop: string, value: unknown) {\n return this._record('preInsert', prop, value);\n }\n postInsert(prop: string, value: unknown) {\n return this._record('postInsert', prop, value);\n }\n remove(prop: string, value: unknown) {\n return this._record('remove', prop, value);\n }\n unset(prop: string) {\n return this._record('unset', prop);\n }\n clearAll() {\n this._ops['clearAll'] = {};\n return this;\n }\n\n toJSON() {\n return this._ops;\n }\n}\n\n/** Minimal chainable Revenue mock. */\nclass MockRevenue implements RevenueInstance {\n _data: Record<string, unknown> = {};\n\n setProductId(v: string) {\n this._data.productId = v;\n return this;\n }\n setPrice(v: number) {\n this._data.price = v;\n return this;\n }\n setQuantity(v: number) {\n this._data.quantity = v;\n return this;\n }\n setRevenueType(v: string) {\n this._data.revenueType = v;\n return this;\n }\n setCurrency(v: string) {\n this._data.currency = v;\n return this;\n }\n setRevenue(v: number) {\n this._data.revenue = v;\n return this;\n }\n setReceipt(v: string) {\n this._data.receipt = v;\n return this;\n }\n setReceiptSig(v: string) {\n this._data.receiptSig = v;\n return this;\n }\n setEventProperties(v: unknown) {\n this._data.eventProperties = v;\n return this;\n }\n\n toJSON() {\n return this._data;\n }\n}\n\n/**\n * Pre-init env — all methods are no-ops until the test runner wires spies.\n */\nexport const init: Env | undefined = {\n amplitude: {\n initAll: () => Promise.resolve(),\n track: noop,\n identify: noop,\n revenue: noop,\n reset: noop,\n setOptOut: noop,\n setUserId: noop,\n setDeviceId: noop,\n setSessionId: noop,\n setGroup: noop,\n groupIdentify: noop,\n flush: noopPromise,\n add: noopPromise,\n Identify: MockIdentify,\n Revenue: MockRevenue,\n },\n};\n\n/**\n * Post-init env — same shape. The test runner clones this and replaces\n * individual methods with jest.fn() so it can assert on calls.\n */\nexport const push: Env = {\n amplitude: {\n initAll: () => Promise.resolve(),\n track: noop,\n identify: noop,\n revenue: noop,\n reset: noop,\n setOptOut: noop,\n setUserId: noop,\n setDeviceId: noop,\n setSessionId: noop,\n setGroup: noop,\n groupIdentify: noop,\n flush: noopPromise,\n add: noopPromise,\n Identify: MockIdentify,\n Revenue: MockRevenue,\n },\n};\n\n/** Simulation tracking paths for CLI --simulate. */\nexport const simulation = [\n 'call:amplitude.initAll',\n 'call:amplitude.track',\n 'call:amplitude.identify',\n 'call:amplitude.revenue',\n 'call:amplitude.reset',\n 'call:amplitude.setOptOut',\n 'call:amplitude.setUserId',\n 'call:amplitude.setDeviceId',\n 'call:amplitude.setSessionId',\n 'call:amplitude.setGroup',\n 'call:amplitude.groupIdentify',\n];\n","import type { Flow, WalkerOS } from '@walkeros/core';\nimport { getEvent } from '@walkeros/core';\nimport type { Settings } from '../types';\n\n/**\n * Examples may optionally carry destination-level settings and/or an\n * `await` hint for async scenarios. The test runner reads `settings`\n * from the example and merges it into the base destination settings\n * on top of the fixed apiKey. `configInclude` is passed as config-level\n * include when registering the destination.\n */\nexport type AmplitudeStepExample = Flow.StepExample & {\n settings?: Partial<Settings>;\n configInclude?: string[];\n /** Consent granted before `in` so a gated destination is loaded first. */\n before?: WalkerOS.Consent;\n};\n\n/**\n * Default event forwarding - every walkerOS event becomes\n * amplitude.track(event.name, event_properties). With no mapping and\n * no destination-level include, event_properties is `{}`.\n */\nexport const defaultEventForwarding: AmplitudeStepExample = {\n title: 'Default track',\n description:\n 'A walker event is forwarded to Amplitude as an amplitude.track call with the event name and empty properties.',\n in: getEvent('product view', { timestamp: 1700000100 }),\n out: [['amplitude.track', 'product view', {}]],\n};\n\n/**\n * Wildcard ignore - walkerOS's standard way to drop events. The rule\n * matches but does nothing. The destination fires zero SDK calls.\n */\nexport const wildcardIgnored: AmplitudeStepExample = {\n public: false,\n in: getEvent('debug noise', { timestamp: 1700000101 }),\n mapping: { ignore: true },\n out: [],\n};\n\n/**\n * Destination-level settings.include flattens the walkerOS `data` section\n * into prefixed event_properties on every push.\n */\nexport const destinationLevelInclude: AmplitudeStepExample = {\n title: 'Include data',\n description:\n 'Destination-level include flattens the event data section into prefixed event_properties on every track call.',\n in: getEvent('product view', { timestamp: 1700000102 }),\n configInclude: ['data'],\n out: [\n [\n 'amplitude.track',\n 'product view',\n {\n data_id: 'ers',\n data_name: 'Everyday Ruck Snack',\n data_color: 'black',\n data_size: 'l',\n data_price: 420,\n },\n ],\n ],\n};\n\n/**\n * Per-rule settings.include REPLACES destination-level include for the\n * matched rule. Here destination-level sends `data`, but the rule\n * overrides it with `globals` only.\n */\nexport const ruleIncludeReplaces: AmplitudeStepExample = {\n title: 'Rule include overrides',\n description:\n 'A per-rule include replaces the destination-level include for the matched event, here using only globals.',\n in: getEvent('order complete', { timestamp: 1700000103 }),\n configInclude: ['data'],\n mapping: {\n include: ['globals'],\n },\n out: [\n [\n 'amplitude.track',\n 'order complete',\n {\n globals_pagegroup: 'shop',\n },\n ],\n ],\n};\n\n/**\n * Destination-level settings.identify fires on the first push (once the\n * state cache is empty). The destination sets user/device/session IDs\n * and tracks them in runtime state; subsequent pushes with unchanged\n * values do NOT re-fire the setters.\n *\n * This example represents the first push in a fresh session. user.id,\n * user.device, user.session come from the walkerOS session fixture.\n *\n * The walkerOS fixture's user.session is 's3ss10n' (string). The\n * destination deterministically hashes non-numeric session strings via\n * djb2 so the same walkerOS session always maps to the same Amplitude\n * session number (cross-page-load consistency). djb2('s3ss10n') = 394324160.\n */\nexport const destinationLevelIdentify: AmplitudeStepExample = {\n title: 'Destination identify',\n description:\n 'Destination-level identify sets userId, deviceId, and sessionId on the Amplitude client before sending events; setters only re-fire when the resolved values change (cached values are not re-applied on subsequent pushes).',\n in: getEvent('page view', { timestamp: 1700000104 }),\n settings: {\n identify: {\n map: {\n user: 'user.id',\n device: 'user.device',\n session: 'user.session',\n },\n },\n },\n out: [\n ['amplitude.setUserId', 'us3r'],\n ['amplitude.setDeviceId', 'c00k13'],\n ['amplitude.setSessionId', 394324160],\n ['amplitude.track', 'page view', {}],\n ],\n};\n\n/**\n * Per-event identify with the full operation vocabulary - this is the\n * \"user login\" pattern: set user_id, enrich user properties. `silent: true`\n * suppresses the default amplitude.track() call because we're running\n * identity side effects only.\n */\nexport const userLoginIdentify: AmplitudeStepExample = {\n title: 'User login identify',\n description:\n 'A user login sets the Amplitude userId and runs identify with set, setOnce, and add operations.',\n in: getEvent('user login', {\n timestamp: 1700000105,\n data: {\n user_id: 'new-user-123',\n plan: 'premium',\n company: 'Acme',\n email: 'user@acme.com',\n },\n }),\n mapping: {\n silent: true,\n settings: {\n identify: {\n map: {\n user: 'data.user_id',\n set: {\n map: {\n plan: 'data.plan',\n company: 'data.company',\n email: 'data.email',\n },\n },\n setOnce: {\n map: {\n first_login: 'timestamp',\n },\n },\n add: {\n map: {\n login_count: { value: 1 },\n },\n },\n },\n },\n },\n },\n out: [\n ['amplitude.setUserId', 'new-user-123'],\n [\n 'amplitude.identify',\n {\n set: {\n plan: 'premium',\n company: 'Acme',\n email: 'user@acme.com',\n },\n setOnce: {\n first_login: 1700000105,\n },\n add: {\n login_count: 1,\n },\n },\n ],\n ],\n};\n\n/**\n * User logout - reset: true fires amplitude.reset(), which clears userId\n * and regenerates deviceId. `silent: true` because we're only running the\n * reset side effect, no default track().\n */\nexport const userLogoutReset: AmplitudeStepExample = {\n title: 'User logout reset',\n description:\n 'A user logout calls amplitude.reset to clear the userId and regenerate the deviceId.',\n in: getEvent('user logout', { timestamp: 1700000106 }),\n mapping: {\n silent: true,\n settings: {\n reset: true,\n },\n },\n out: [['amplitude.reset']],\n};\n\n/**\n * Single-product revenue - resolves `settings.revenue` to one object and\n * fires one amplitude.revenue() call. Note the `{ key: \"data.currency\",\n * value: \"EUR\" }` fallback syntax: try data.currency, default to \"EUR\".\n *\n * The walkerOS default event has no data.currency, so the fallback fires.\n */\nexport const subscriptionRenewRevenue: AmplitudeStepExample = {\n title: 'Subscription revenue',\n description:\n 'A subscription renewal fires a single amplitude.revenue call with productId, price, and currency fallback.',\n in: getEvent('subscription renew', {\n timestamp: 1700000107,\n data: {\n plan_id: 'plan-pro',\n amount: 9.99,\n },\n }),\n mapping: {\n silent: true,\n settings: {\n revenue: {\n map: {\n productId: 'data.plan_id',\n price: 'data.amount',\n revenueType: { value: 'renewal' },\n currency: { key: 'data.currency', value: 'EUR' },\n },\n },\n },\n },\n out: [\n [\n 'amplitude.revenue',\n {\n productId: 'plan-pro',\n price: 9.99,\n revenueType: 'renewal',\n currency: 'EUR',\n },\n ],\n ],\n};\n\n/**\n * Multi-product order - the canonical Amplitude ecommerce pattern.\n * `revenue.loop: [\"nested\", { map: ... }]` iterates event.nested and\n * resolves one revenue item per entry. Each becomes a separate\n * amplitude.revenue() call. The order-level track() fires once with\n * include-based event_properties.\n *\n * The default \"order complete\" fixture has 3 nested entries: two\n * products (ers, cc) and one gift. Products have `data.price`; the\n * gift has only `data.name`. The `condition` on the loop inner value\n * filters to products only (price must be present).\n */\nexport const orderCompleteMultiProduct: AmplitudeStepExample = {\n title: 'Multi-product order',\n description:\n 'An order fires one amplitude.revenue call per nested product plus a single track for the order totals.',\n in: getEvent('order complete', { timestamp: 1700000108 }),\n mapping: {\n include: ['data', 'globals'],\n settings: {\n revenue: {\n loop: [\n 'nested',\n {\n // Only iterate nested entries that have a price field (products).\n condition: (value: unknown) => {\n const v = value as { data?: { price?: unknown } };\n return typeof v?.data?.price === 'number';\n },\n map: {\n productId: 'data.id',\n price: 'data.price',\n quantity: { key: 'data.quantity', value: 1 },\n revenueType: { value: 'purchase' },\n currency: { key: 'data.currency', value: 'EUR' },\n },\n },\n ],\n },\n },\n },\n out: [\n [\n 'amplitude.revenue',\n {\n productId: 'ers',\n price: 420,\n quantity: 1,\n revenueType: 'purchase',\n currency: 'EUR',\n },\n ],\n [\n 'amplitude.revenue',\n {\n productId: 'cc',\n price: 42,\n quantity: 1,\n revenueType: 'purchase',\n currency: 'EUR',\n },\n ],\n [\n 'amplitude.track',\n 'order complete',\n {\n data_id: '0rd3r1d',\n data_currency: 'EUR',\n data_shipping: 5.22,\n data_taxes: 73.76,\n data_total: 555,\n globals_pagegroup: 'shop',\n },\n ],\n ],\n};\n\n/**\n * Group assignment + group properties. Typically used for B2B products\n * where a user belongs to a company. Both SDK calls fire on the same rule.\n */\nexport const groupAssignmentWithProperties: AmplitudeStepExample = {\n title: 'Group assignment',\n description:\n 'A company update assigns the user to a group and sets group properties via setGroup and groupIdentify.',\n in: getEvent('company update', {\n timestamp: 1700000109,\n data: {\n company: 'Acme',\n industry: 'tech',\n employee_count: 50,\n founded_year: 2020,\n },\n }),\n mapping: {\n silent: true,\n settings: {\n group: {\n map: {\n type: { value: 'company' },\n name: 'data.company',\n },\n },\n groupIdentify: {\n map: {\n type: { value: 'company' },\n name: 'data.company',\n set: {\n map: {\n industry: 'data.industry',\n size: 'data.employee_count',\n },\n },\n setOnce: {\n map: {\n founded: 'data.founded_year',\n },\n },\n },\n },\n },\n },\n out: [\n ['amplitude.setGroup', 'company', 'Acme'],\n [\n 'amplitude.groupIdentify',\n 'company',\n 'Acme',\n {\n set: {\n industry: 'tech',\n size: 50,\n },\n setOnce: {\n founded: 2020,\n },\n },\n ],\n ],\n};\n\n/**\n * Consent revoked → amplitude.setOptOut(true). The destination checks\n * the consent keys declared in config.consent and toggles optOut\n * accordingly (strict: all required keys must be granted).\n *\n * Uses the canonical StepExample.command='consent' pattern: the test\n * runner dispatches via elb('walker consent', in) instead of pushing\n * an event.\n */\nexport const consentRevokeOptOut: AmplitudeStepExample = {\n title: 'Consent revoked',\n description:\n 'A walker consent command with analytics denied opts out of Amplitude tracking via setOptOut(true).',\n command: 'consent',\n before: { analytics: true },\n in: { analytics: false } as WalkerOS.Consent,\n settings: {} as Partial<Settings>,\n out: [\n ['amplitude.setOptOut', false],\n ['amplitude.setOptOut', true],\n ],\n};\n\n/**\n * Consent granted → amplitude.setOptOut(false).\n */\nexport const consentGrantOptIn: AmplitudeStepExample = {\n title: 'Consent granted',\n description:\n 'A walker consent command with analytics granted opts back into Amplitude tracking via setOptOut(false).',\n command: 'consent',\n in: { analytics: true } as WalkerOS.Consent,\n settings: {} as Partial<Settings>,\n out: [['amplitude.setOptOut', false]],\n};\n"],"mappings":";;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAAS,mBAAmB;;;ACA5B,SAAS,SAAS;AAEX,IAAM,iBAAiB,EAAE,OAAO;AAAA,EACrC,QAAQ,EACL,OAAO,EACP,IAAI,CAAC,EACL;AAAA,IACC;AAAA,EACF;AAAA,EACF,YAAY,EACT,KAAK,CAAC,MAAM,IAAI,CAAC,EACjB,SAAS,qCAAqC,EAC9C,SAAS;AAAA,EACZ,qBAAqB,EAClB,OAAO,EACP,IAAI,EACJ,SAAS,EACT,SAAS,4DAA4D,EACrE,SAAS;AAAA,EACZ,gBAAgB,EACb,OAAO,EACP,IAAI,EACJ,SAAS,EACT,SAAS,gDAAgD,EACzD,SAAS;AAAA,EACZ,iBAAiB,EACd,OAAO,EACP,IAAI,EACJ,YAAY,EACZ,SAAS,0CAA0C,EACnD,SAAS;AAAA,EACZ,WAAW,EACR,KAAK,CAAC,SAAS,OAAO,QAAQ,CAAC,EAC/B,SAAS,iCAAiC,EAC1C,SAAS;AAAA,EACZ,UAAU,EACP,QAAQ,EACR;AAAA,IACC;AAAA,EACF,EACC,SAAS;AAAA,EACZ,YAAY,EACT,OAAO,EACP,SAAS,+CAA+C,EACxD,SAAS;AAAA,EACZ,UAAU,EACP,QAAQ,EACR;AAAA,IACC;AAAA,EACF,EACC,SAAS;AAAA,EACZ,eAAe,EACZ,QAAQ,EACR;AAAA,IACC;AAAA,EACF,EACC,SAAS;AAAA,EACZ,YAAY,EACT,QAAQ,EACR;AAAA,IACC;AAAA,EACF,EACC,SAAS;AAAA,EACZ,YAAY,EACT,QAAQ,EACR;AAAA,IACC;AAAA,EACF,EACC,SAAS;AACd,CAAC;;;ACrED,SAAS,KAAAA,UAAS;AAEX,IAAM,gBAAgBA,GAAE,OAAO;AAAA,EACpC,UAAUA,GACP,QAAQ,EACR;AAAA,IACC;AAAA,EACF,EACC,SAAS;AAAA,EACZ,SAASA,GACN,QAAQ,EACR;AAAA,IACC;AAAA,EACF,EACC,SAAS;AAAA,EACZ,OAAOA,GACJ,QAAQ,EACR;AAAA,IACC;AAAA,EACF,EACC,SAAS;AAAA,EACZ,eAAeA,GACZ,QAAQ,EACR;AAAA,IACC;AAAA,EACF,EACC,SAAS;AAAA,EACZ,OAAOA,GACJ,QAAQ,EACR;AAAA,IACC;AAAA,EACF,EACC,SAAS;AACd,CAAC;;;AFzBM,IAAM,WAAW,YAAY,cAAc;AAC3C,IAAM,UAAU,YAAY,aAAa;;;AGThD;AAAA;AAAA;AAAA;AAAA;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUA,IAAM,OAAO,MAAM;AAAC;AACpB,IAAM,cAAc,OAAO,EAAE,SAAS,QAAQ,QAAQ,EAAE;AAMxD,IAAM,eAAN,MAA+C;AAAA,EAA/C;AACE,gBAAgD,CAAC;AAAA;AAAA,EAEzC,QAAQ,IAAY,MAAc,OAAiB;AACzD,QAAI,CAAC,KAAK,KAAK,EAAE,EAAG,MAAK,KAAK,EAAE,IAAI,CAAC;AACrC,SAAK,KAAK,EAAE,EAAE,IAAI,IAAI;AACtB,WAAO;AAAA,EACT;AAAA,EAEA,IAAI,MAAc,OAAgB;AAChC,WAAO,KAAK,QAAQ,OAAO,MAAM,KAAK;AAAA,EACxC;AAAA,EACA,QAAQ,MAAc,OAAgB;AACpC,WAAO,KAAK,QAAQ,WAAW,MAAM,KAAK;AAAA,EAC5C;AAAA,EACA,IAAI,MAAc,OAAgB;AAChC,WAAO,KAAK,QAAQ,OAAO,MAAM,KAAK;AAAA,EACxC;AAAA,EACA,OAAO,MAAc,OAAgB;AACnC,WAAO,KAAK,QAAQ,UAAU,MAAM,KAAK;AAAA,EAC3C;AAAA,EACA,QAAQ,MAAc,OAAgB;AACpC,WAAO,KAAK,QAAQ,WAAW,MAAM,KAAK;AAAA,EAC5C;AAAA,EACA,UAAU,MAAc,OAAgB;AACtC,WAAO,KAAK,QAAQ,aAAa,MAAM,KAAK;AAAA,EAC9C;AAAA,EACA,WAAW,MAAc,OAAgB;AACvC,WAAO,KAAK,QAAQ,cAAc,MAAM,KAAK;AAAA,EAC/C;AAAA,EACA,OAAO,MAAc,OAAgB;AACnC,WAAO,KAAK,QAAQ,UAAU,MAAM,KAAK;AAAA,EAC3C;AAAA,EACA,MAAM,MAAc;AAClB,WAAO,KAAK,QAAQ,SAAS,IAAI;AAAA,EACnC;AAAA,EACA,WAAW;AACT,SAAK,KAAK,UAAU,IAAI,CAAC;AACzB,WAAO;AAAA,EACT;AAAA,EAEA,SAAS;AACP,WAAO,KAAK;AAAA,EACd;AACF;AAGA,IAAM,cAAN,MAA6C;AAAA,EAA7C;AACE,iBAAiC,CAAC;AAAA;AAAA,EAElC,aAAa,GAAW;AACtB,SAAK,MAAM,YAAY;AACvB,WAAO;AAAA,EACT;AAAA,EACA,SAAS,GAAW;AAClB,SAAK,MAAM,QAAQ;AACnB,WAAO;AAAA,EACT;AAAA,EACA,YAAY,GAAW;AACrB,SAAK,MAAM,WAAW;AACtB,WAAO;AAAA,EACT;AAAA,EACA,eAAe,GAAW;AACxB,SAAK,MAAM,cAAc;AACzB,WAAO;AAAA,EACT;AAAA,EACA,YAAY,GAAW;AACrB,SAAK,MAAM,WAAW;AACtB,WAAO;AAAA,EACT;AAAA,EACA,WAAW,GAAW;AACpB,SAAK,MAAM,UAAU;AACrB,WAAO;AAAA,EACT;AAAA,EACA,WAAW,GAAW;AACpB,SAAK,MAAM,UAAU;AACrB,WAAO;AAAA,EACT;AAAA,EACA,cAAc,GAAW;AACvB,SAAK,MAAM,aAAa;AACxB,WAAO;AAAA,EACT;AAAA,EACA,mBAAmB,GAAY;AAC7B,SAAK,MAAM,kBAAkB;AAC7B,WAAO;AAAA,EACT;AAAA,EAEA,SAAS;AACP,WAAO,KAAK;AAAA,EACd;AACF;AAKO,IAAM,OAAwB;AAAA,EACnC,WAAW;AAAA,IACT,SAAS,MAAM,QAAQ,QAAQ;AAAA,IAC/B,OAAO;AAAA,IACP,UAAU;AAAA,IACV,SAAS;AAAA,IACT,OAAO;AAAA,IACP,WAAW;AAAA,IACX,WAAW;AAAA,IACX,aAAa;AAAA,IACb,cAAc;AAAA,IACd,UAAU;AAAA,IACV,eAAe;AAAA,IACf,OAAO;AAAA,IACP,KAAK;AAAA,IACL,UAAU;AAAA,IACV,SAAS;AAAA,EACX;AACF;AAMO,IAAM,OAAY;AAAA,EACvB,WAAW;AAAA,IACT,SAAS,MAAM,QAAQ,QAAQ;AAAA,IAC/B,OAAO;AAAA,IACP,UAAU;AAAA,IACV,SAAS;AAAA,IACT,OAAO;AAAA,IACP,WAAW;AAAA,IACX,WAAW;AAAA,IACX,aAAa;AAAA,IACb,cAAc;AAAA,IACd,UAAU;AAAA,IACV,eAAe;AAAA,IACf,OAAO;AAAA,IACP,KAAK;AAAA,IACL,UAAU;AAAA,IACV,SAAS;AAAA,EACX;AACF;AAGO,IAAM,aAAa;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ACzKA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,SAAS,gBAAgB;AAsBlB,IAAM,yBAA+C;AAAA,EAC1D,OAAO;AAAA,EACP,aACE;AAAA,EACF,IAAI,SAAS,gBAAgB,EAAE,WAAW,WAAW,CAAC;AAAA,EACtD,KAAK,CAAC,CAAC,mBAAmB,gBAAgB,CAAC,CAAC,CAAC;AAC/C;AAMO,IAAM,kBAAwC;AAAA,EACnD,QAAQ;AAAA,EACR,IAAI,SAAS,eAAe,EAAE,WAAW,WAAW,CAAC;AAAA,EACrD,SAAS,EAAE,QAAQ,KAAK;AAAA,EACxB,KAAK,CAAC;AACR;AAMO,IAAM,0BAAgD;AAAA,EAC3D,OAAO;AAAA,EACP,aACE;AAAA,EACF,IAAI,SAAS,gBAAgB,EAAE,WAAW,WAAW,CAAC;AAAA,EACtD,eAAe,CAAC,MAAM;AAAA,EACtB,KAAK;AAAA,IACH;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,QACE,SAAS;AAAA,QACT,WAAW;AAAA,QACX,YAAY;AAAA,QACZ,WAAW;AAAA,QACX,YAAY;AAAA,MACd;AAAA,IACF;AAAA,EACF;AACF;AAOO,IAAM,sBAA4C;AAAA,EACvD,OAAO;AAAA,EACP,aACE;AAAA,EACF,IAAI,SAAS,kBAAkB,EAAE,WAAW,WAAW,CAAC;AAAA,EACxD,eAAe,CAAC,MAAM;AAAA,EACtB,SAAS;AAAA,IACP,SAAS,CAAC,SAAS;AAAA,EACrB;AAAA,EACA,KAAK;AAAA,IACH;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,QACE,mBAAmB;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AACF;AAgBO,IAAM,2BAAiD;AAAA,EAC5D,OAAO;AAAA,EACP,aACE;AAAA,EACF,IAAI,SAAS,aAAa,EAAE,WAAW,WAAW,CAAC;AAAA,EACnD,UAAU;AAAA,IACR,UAAU;AAAA,MACR,KAAK;AAAA,QACH,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF;AAAA,EACA,KAAK;AAAA,IACH,CAAC,uBAAuB,MAAM;AAAA,IAC9B,CAAC,yBAAyB,QAAQ;AAAA,IAClC,CAAC,0BAA0B,SAAS;AAAA,IACpC,CAAC,mBAAmB,aAAa,CAAC,CAAC;AAAA,EACrC;AACF;AAQO,IAAM,oBAA0C;AAAA,EACrD,OAAO;AAAA,EACP,aACE;AAAA,EACF,IAAI,SAAS,cAAc;AAAA,IACzB,WAAW;AAAA,IACX,MAAM;AAAA,MACJ,SAAS;AAAA,MACT,MAAM;AAAA,MACN,SAAS;AAAA,MACT,OAAO;AAAA,IACT;AAAA,EACF,CAAC;AAAA,EACD,SAAS;AAAA,IACP,QAAQ;AAAA,IACR,UAAU;AAAA,MACR,UAAU;AAAA,QACR,KAAK;AAAA,UACH,MAAM;AAAA,UACN,KAAK;AAAA,YACH,KAAK;AAAA,cACH,MAAM;AAAA,cACN,SAAS;AAAA,cACT,OAAO;AAAA,YACT;AAAA,UACF;AAAA,UACA,SAAS;AAAA,YACP,KAAK;AAAA,cACH,aAAa;AAAA,YACf;AAAA,UACF;AAAA,UACA,KAAK;AAAA,YACH,KAAK;AAAA,cACH,aAAa,EAAE,OAAO,EAAE;AAAA,YAC1B;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,KAAK;AAAA,IACH,CAAC,uBAAuB,cAAc;AAAA,IACtC;AAAA,MACE;AAAA,MACA;AAAA,QACE,KAAK;AAAA,UACH,MAAM;AAAA,UACN,SAAS;AAAA,UACT,OAAO;AAAA,QACT;AAAA,QACA,SAAS;AAAA,UACP,aAAa;AAAA,QACf;AAAA,QACA,KAAK;AAAA,UACH,aAAa;AAAA,QACf;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAOO,IAAM,kBAAwC;AAAA,EACnD,OAAO;AAAA,EACP,aACE;AAAA,EACF,IAAI,SAAS,eAAe,EAAE,WAAW,WAAW,CAAC;AAAA,EACrD,SAAS;AAAA,IACP,QAAQ;AAAA,IACR,UAAU;AAAA,MACR,OAAO;AAAA,IACT;AAAA,EACF;AAAA,EACA,KAAK,CAAC,CAAC,iBAAiB,CAAC;AAC3B;AASO,IAAM,2BAAiD;AAAA,EAC5D,OAAO;AAAA,EACP,aACE;AAAA,EACF,IAAI,SAAS,sBAAsB;AAAA,IACjC,WAAW;AAAA,IACX,MAAM;AAAA,MACJ,SAAS;AAAA,MACT,QAAQ;AAAA,IACV;AAAA,EACF,CAAC;AAAA,EACD,SAAS;AAAA,IACP,QAAQ;AAAA,IACR,UAAU;AAAA,MACR,SAAS;AAAA,QACP,KAAK;AAAA,UACH,WAAW;AAAA,UACX,OAAO;AAAA,UACP,aAAa,EAAE,OAAO,UAAU;AAAA,UAChC,UAAU,EAAE,KAAK,iBAAiB,OAAO,MAAM;AAAA,QACjD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,KAAK;AAAA,IACH;AAAA,MACE;AAAA,MACA;AAAA,QACE,WAAW;AAAA,QACX,OAAO;AAAA,QACP,aAAa;AAAA,QACb,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AACF;AAcO,IAAM,4BAAkD;AAAA,EAC7D,OAAO;AAAA,EACP,aACE;AAAA,EACF,IAAI,SAAS,kBAAkB,EAAE,WAAW,WAAW,CAAC;AAAA,EACxD,SAAS;AAAA,IACP,SAAS,CAAC,QAAQ,SAAS;AAAA,IAC3B,UAAU;AAAA,MACR,SAAS;AAAA,QACP,MAAM;AAAA,UACJ;AAAA,UACA;AAAA;AAAA,YAEE,WAAW,CAAC,UAAmB;AA3R3C;AA4Rc,oBAAM,IAAI;AACV,qBAAO,SAAO,4BAAG,SAAH,mBAAS,WAAU;AAAA,YACnC;AAAA,YACA,KAAK;AAAA,cACH,WAAW;AAAA,cACX,OAAO;AAAA,cACP,UAAU,EAAE,KAAK,iBAAiB,OAAO,EAAE;AAAA,cAC3C,aAAa,EAAE,OAAO,WAAW;AAAA,cACjC,UAAU,EAAE,KAAK,iBAAiB,OAAO,MAAM;AAAA,YACjD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,KAAK;AAAA,IACH;AAAA,MACE;AAAA,MACA;AAAA,QACE,WAAW;AAAA,QACX,OAAO;AAAA,QACP,UAAU;AAAA,QACV,aAAa;AAAA,QACb,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,QACE,WAAW;AAAA,QACX,OAAO;AAAA,QACP,UAAU;AAAA,QACV,aAAa;AAAA,QACb,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,QACE,SAAS;AAAA,QACT,eAAe;AAAA,QACf,eAAe;AAAA,QACf,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,mBAAmB;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AACF;AAMO,IAAM,gCAAsD;AAAA,EACjE,OAAO;AAAA,EACP,aACE;AAAA,EACF,IAAI,SAAS,kBAAkB;AAAA,IAC7B,WAAW;AAAA,IACX,MAAM;AAAA,MACJ,SAAS;AAAA,MACT,UAAU;AAAA,MACV,gBAAgB;AAAA,MAChB,cAAc;AAAA,IAChB;AAAA,EACF,CAAC;AAAA,EACD,SAAS;AAAA,IACP,QAAQ;AAAA,IACR,UAAU;AAAA,MACR,OAAO;AAAA,QACL,KAAK;AAAA,UACH,MAAM,EAAE,OAAO,UAAU;AAAA,UACzB,MAAM;AAAA,QACR;AAAA,MACF;AAAA,MACA,eAAe;AAAA,QACb,KAAK;AAAA,UACH,MAAM,EAAE,OAAO,UAAU;AAAA,UACzB,MAAM;AAAA,UACN,KAAK;AAAA,YACH,KAAK;AAAA,cACH,UAAU;AAAA,cACV,MAAM;AAAA,YACR;AAAA,UACF;AAAA,UACA,SAAS;AAAA,YACP,KAAK;AAAA,cACH,SAAS;AAAA,YACX;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,KAAK;AAAA,IACH,CAAC,sBAAsB,WAAW,MAAM;AAAA,IACxC;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,QACE,KAAK;AAAA,UACH,UAAU;AAAA,UACV,MAAM;AAAA,QACR;AAAA,QACA,SAAS;AAAA,UACP,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAWO,IAAM,sBAA4C;AAAA,EACvD,OAAO;AAAA,EACP,aACE;AAAA,EACF,SAAS;AAAA,EACT,QAAQ,EAAE,WAAW,KAAK;AAAA,EAC1B,IAAI,EAAE,WAAW,MAAM;AAAA,EACvB,UAAU,CAAC;AAAA,EACX,KAAK;AAAA,IACH,CAAC,uBAAuB,KAAK;AAAA,IAC7B,CAAC,uBAAuB,IAAI;AAAA,EAC9B;AACF;AAKO,IAAM,oBAA0C;AAAA,EACrD,OAAO;AAAA,EACP,aACE;AAAA,EACF,SAAS;AAAA,EACT,IAAI,EAAE,WAAW,KAAK;AAAA,EACtB,UAAU,CAAC;AAAA,EACX,KAAK,CAAC,CAAC,uBAAuB,KAAK,CAAC;AACtC;","names":["z"]}
1
+ {"version":3,"sources":["../src/schemas/index.ts","../src/schemas/settings.ts","../src/schemas/mapping.ts","../src/examples/index.ts","../src/examples/env.ts","../src/examples/step.ts"],"sourcesContent":["import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\nimport { MappingSchema } from './mapping';\n\nexport { SettingsSchema, type Settings } from './settings';\nexport { MappingSchema, type Mapping } from './mapping';\n\n// JSON Schema\nexport const settings = zodToSchema(SettingsSchema);\nexport const mapping = zodToSchema(MappingSchema);\n","import { z } from '@walkeros/core/dev';\n\nexport const SettingsSchema = z.object({\n apiKey: z\n .string()\n .min(1)\n .describe(\n 'Your Amplitude project API key. Find it in your Amplitude project settings under \"General\" → \"API Keys\" (like a1b2c3d4e5f6789012345678abcdef12).',\n ),\n serverZone: z\n .enum(['US', 'EU'])\n .describe('Amplitude server zone. Default: US.')\n .optional(),\n flushIntervalMillis: z\n .number()\n .int()\n .positive()\n .describe('How often (in ms) to flush the event queue. Default: 1000.')\n .optional(),\n flushQueueSize: z\n .number()\n .int()\n .positive()\n .describe('Max queued events before a flush. Default: 30.')\n .optional(),\n flushMaxRetries: z\n .number()\n .int()\n .nonnegative()\n .describe('Max retries on failed flush. Default: 5.')\n .optional(),\n transport: z\n .enum(['fetch', 'xhr', 'beacon'])\n .describe('HTTP transport. Default: fetch.')\n .optional(),\n useBatch: z\n .boolean()\n .describe(\n 'Use the Amplitude batch endpoint instead of the standard endpoint. Default: false.',\n )\n .optional(),\n appVersion: z\n .string()\n .describe('Application version; tagged onto every event.')\n .optional(),\n identify: z\n .unknown()\n .describe(\n 'walkerOS mapping value resolving to an identity object. Keys: user, device, session, set, setOnce, add, append, prepend, preInsert, postInsert, remove, unset, clearAll.',\n )\n .optional(),\n sessionReplay: z\n .unknown()\n .describe(\n 'Session Replay options, passed to the Session Replay plugin. @amplitude/unified sets up the plugin on every init, whether or not this is set; it records a sampled share of sessions, set by the project sampling settings in Amplitude when present, else by sampleRate (default 0).',\n )\n .optional(),\n experiment: z\n .unknown()\n .describe(\n 'Feature Experiment options. Passed to the Experiment plugin only when they include `deploymentKey`. @amplitude/unified sets up the plugin on every init; without a deploymentKey it uses the API key.',\n )\n .optional(),\n engagement: z\n .unknown()\n .describe(\n 'Guides & Surveys options object. @amplitude/unified loads the Guides & Surveys SDK from cdn.amplitude.com on every init, whether or not this is set; `true` passes no options.',\n )\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\nexport const MappingSchema = z.object({\n identify: z\n .unknown()\n .describe(\n 'Per-event identity mapping. Resolves to an object with any of: user, device, session, set, setOnce, add, append, prepend, preInsert, postInsert, remove, unset, clearAll.',\n )\n .optional(),\n revenue: z\n .unknown()\n .describe(\n 'Revenue mapping. Resolves to a single object or (via loop) an array of objects, each with: productId, price, quantity, revenueType, currency, revenue, receipt, receiptSig, eventProperties. One amplitude.revenue() call fires per item.',\n )\n .optional(),\n group: z\n .unknown()\n .describe(\n 'Group assignment. Resolves to { type, name } → amplitude.setGroup(type, name).',\n )\n .optional(),\n groupIdentify: z\n .unknown()\n .describe(\n 'Group properties. Resolves to { type, name, set?, setOnce?, ... } → amplitude.groupIdentify(type, name, identify).',\n )\n .optional(),\n reset: z\n .unknown()\n .describe(\n 'Logout trigger. Resolves to a truthy value → amplitude.reset() (clears userId, regenerates deviceId). Typically used with silent: true on a user logout rule.',\n )\n .optional(),\n});\n\nexport type Mapping = z.infer<typeof MappingSchema>;\n","export * as env from './env';\nexport * as step from './step';\n","import type { Env, IdentifyInstance, RevenueInstance } from '../types';\n\n/**\n * Example environment configurations for the Amplitude destination.\n *\n * Tests clone `push` and replace individual methods with jest spies.\n * Production leaves `env.amplitude` undefined — the destination falls back\n * to the real `@amplitude/unified` module namespace.\n */\n\nconst noop = () => {};\nconst noopPromise = () => ({ promise: Promise.resolve() });\n\n/**\n * Minimal chainable Identify mock. The real SDK class has the same shape.\n * Tests spy by replacing these methods with jest.fn() in the test runner.\n */\nclass MockIdentify implements IdentifyInstance {\n _ops: Record<string, Record<string, unknown>> = {};\n\n private _record(op: string, prop: string, value?: unknown) {\n if (!this._ops[op]) this._ops[op] = {};\n this._ops[op][prop] = value;\n return this;\n }\n\n set(prop: string, value: unknown) {\n return this._record('set', prop, value);\n }\n setOnce(prop: string, value: unknown) {\n return this._record('setOnce', prop, value);\n }\n add(prop: string, value: unknown) {\n return this._record('add', prop, value);\n }\n append(prop: string, value: unknown) {\n return this._record('append', prop, value);\n }\n prepend(prop: string, value: unknown) {\n return this._record('prepend', prop, value);\n }\n preInsert(prop: string, value: unknown) {\n return this._record('preInsert', prop, value);\n }\n postInsert(prop: string, value: unknown) {\n return this._record('postInsert', prop, value);\n }\n remove(prop: string, value: unknown) {\n return this._record('remove', prop, value);\n }\n unset(prop: string) {\n return this._record('unset', prop);\n }\n clearAll() {\n this._ops['clearAll'] = {};\n return this;\n }\n\n toJSON() {\n return this._ops;\n }\n}\n\n/** Minimal chainable Revenue mock. */\nclass MockRevenue implements RevenueInstance {\n _data: Record<string, unknown> = {};\n\n setProductId(v: string) {\n this._data.productId = v;\n return this;\n }\n setPrice(v: number) {\n this._data.price = v;\n return this;\n }\n setQuantity(v: number) {\n this._data.quantity = v;\n return this;\n }\n setRevenueType(v: string) {\n this._data.revenueType = v;\n return this;\n }\n setCurrency(v: string) {\n this._data.currency = v;\n return this;\n }\n setRevenue(v: number) {\n this._data.revenue = v;\n return this;\n }\n setReceipt(v: string) {\n this._data.receipt = v;\n return this;\n }\n setReceiptSig(v: string) {\n this._data.receiptSig = v;\n return this;\n }\n setEventProperties(v: unknown) {\n this._data.eventProperties = v;\n return this;\n }\n\n toJSON() {\n return this._data;\n }\n}\n\n/**\n * Pre-init env — all methods are no-ops until the test runner wires spies.\n */\nexport const init: Env | undefined = {\n amplitude: {\n initAll: () => Promise.resolve(),\n track: noop,\n identify: noop,\n revenue: noop,\n reset: noop,\n setOptOut: noop,\n setUserId: noop,\n setDeviceId: noop,\n setSessionId: noop,\n setGroup: noop,\n groupIdentify: noop,\n flush: noopPromise,\n add: noopPromise,\n Identify: MockIdentify,\n Revenue: MockRevenue,\n },\n};\n\n/**\n * Post-init env — same shape. The test runner clones this and replaces\n * individual methods with jest.fn() so it can assert on calls.\n */\nexport const push: Env = {\n amplitude: {\n initAll: () => Promise.resolve(),\n track: noop,\n identify: noop,\n revenue: noop,\n reset: noop,\n setOptOut: noop,\n setUserId: noop,\n setDeviceId: noop,\n setSessionId: noop,\n setGroup: noop,\n groupIdentify: noop,\n flush: noopPromise,\n add: noopPromise,\n Identify: MockIdentify,\n Revenue: MockRevenue,\n },\n};\n\n/** Simulation tracking paths for CLI --simulate. */\nexport const simulation = [\n 'call:amplitude.initAll',\n 'call:amplitude.track',\n 'call:amplitude.identify',\n 'call:amplitude.revenue',\n 'call:amplitude.reset',\n 'call:amplitude.setOptOut',\n 'call:amplitude.setUserId',\n 'call:amplitude.setDeviceId',\n 'call:amplitude.setSessionId',\n 'call:amplitude.setGroup',\n 'call:amplitude.groupIdentify',\n];\n","import type { Flow, WalkerOS } from '@walkeros/core';\nimport { getEvent } from '@walkeros/core';\nimport type { Settings } from '../types';\n\n/**\n * Examples may optionally carry destination-level settings and/or an\n * `await` hint for async scenarios. The test runner reads `settings`\n * from the example and merges it into the base destination settings\n * on top of the fixed apiKey. `configInclude` is passed as config-level\n * include when registering the destination.\n */\nexport type AmplitudeStepExample = Flow.StepExample & {\n settings?: Partial<Settings>;\n configInclude?: string[];\n /** Consent granted before `in` so a gated destination is loaded first. */\n before?: WalkerOS.Consent;\n};\n\n/**\n * Default event forwarding - every walkerOS event becomes\n * amplitude.track(event.name, event_properties). With no mapping and\n * no destination-level include, event_properties is `{}`.\n */\nexport const defaultEventForwarding: AmplitudeStepExample = {\n title: 'Default track',\n description:\n 'A walker event is forwarded to Amplitude as an amplitude.track call with the event name and empty properties.',\n in: getEvent('product view', { timestamp: 1700000100 }),\n out: [['amplitude.track', 'product view', {}]],\n};\n\n/**\n * Wildcard ignore - walkerOS's standard way to drop events. The rule\n * matches but does nothing. The destination fires zero SDK calls.\n */\nexport const wildcardIgnored: AmplitudeStepExample = {\n public: false,\n in: getEvent('debug noise', { timestamp: 1700000101 }),\n mapping: { ignore: true },\n out: [],\n};\n\n/**\n * Destination-level include (config.include) flattens the walkerOS `data`\n * section into prefixed event_properties on every push.\n */\nexport const destinationLevelInclude: AmplitudeStepExample = {\n title: 'Include data',\n description:\n \"With include: ['data'] in the destination config, the event data section is flattened into prefixed event_properties on every track call.\",\n in: getEvent('product view', { timestamp: 1700000102 }),\n configInclude: ['data'],\n out: [\n [\n 'amplitude.track',\n 'product view',\n {\n data_id: 'ers',\n data_name: 'Everyday Ruck Snack',\n data_color: 'black',\n data_size: 'l',\n data_price: 420,\n },\n ],\n ],\n};\n\n/**\n * Per-rule include REPLACES the destination-level config.include for the\n * matched rule. Here destination-level sends `data`, but the rule\n * overrides it with `globals` only.\n */\nexport const ruleIncludeReplaces: AmplitudeStepExample = {\n title: 'Rule include overrides',\n description:\n \"With include: ['data'] in the destination config, the rule's include: ['globals'] replaces it, so this event forwards only globals.\",\n in: getEvent('order complete', { timestamp: 1700000103 }),\n configInclude: ['data'],\n mapping: {\n include: ['globals'],\n },\n out: [\n [\n 'amplitude.track',\n 'order complete',\n {\n globals_pagegroup: 'shop',\n },\n ],\n ],\n};\n\n/**\n * Destination-level settings.identify fires on the first push (once the\n * state cache is empty). The destination sets user/device/session IDs\n * and tracks them in runtime state; subsequent pushes with unchanged\n * values do NOT re-fire the setters.\n *\n * This example represents the first push in a fresh session. user.id,\n * user.device, user.session come from the walkerOS session fixture.\n *\n * The walkerOS fixture's user.session is 's3ss10n' (string). The\n * destination deterministically hashes non-numeric session strings via\n * djb2 so the same walkerOS session always maps to the same Amplitude\n * session number (cross-page-load consistency). djb2('s3ss10n') = 394324160.\n */\nexport const destinationLevelIdentify: AmplitudeStepExample = {\n title: 'Destination identify',\n description:\n \"With settings.identify mapping user, device, and session to 'user.id', 'user.device', and 'user.session', the destination sets userId, deviceId, and sessionId before the track call. A non-numeric session string is hashed to a stable number. Setters only re-fire when the resolved values change.\",\n in: getEvent('page view', { timestamp: 1700000104 }),\n settings: {\n identify: {\n map: {\n user: 'user.id',\n device: 'user.device',\n session: 'user.session',\n },\n },\n },\n out: [\n ['amplitude.setUserId', 'us3r'],\n ['amplitude.setDeviceId', 'c00k13'],\n ['amplitude.setSessionId', 394324160],\n ['amplitude.track', 'page view', {}],\n ],\n};\n\n/**\n * Per-event identify with the full operation vocabulary - this is the\n * \"user login\" pattern: set user_id, enrich user properties. `silent: true`\n * suppresses the default amplitude.track() call because we're running\n * identity side effects only.\n */\nexport const userLoginIdentify: AmplitudeStepExample = {\n title: 'User login identify',\n description:\n 'A user login sets the Amplitude userId and runs identify with set, setOnce, and add operations.',\n in: getEvent('user login', {\n timestamp: 1700000105000,\n data: {\n user_id: 'new-user-123',\n plan: 'premium',\n company: 'Acme',\n email: 'user@acme.com',\n },\n }),\n mapping: {\n silent: true,\n settings: {\n identify: {\n map: {\n user: 'data.user_id',\n set: {\n map: {\n plan: 'data.plan',\n company: 'data.company',\n email: 'data.email',\n },\n },\n setOnce: {\n map: {\n first_login: 'timestamp',\n },\n },\n add: {\n map: {\n login_count: { value: 1 },\n },\n },\n },\n },\n },\n },\n out: [\n ['amplitude.setUserId', 'new-user-123'],\n [\n 'amplitude.identify',\n {\n set: {\n plan: 'premium',\n company: 'Acme',\n email: 'user@acme.com',\n },\n setOnce: {\n first_login: 1700000105000,\n },\n add: {\n login_count: 1,\n },\n },\n ],\n ],\n};\n\n/**\n * User logout - reset: true fires amplitude.reset(), which clears userId\n * and regenerates deviceId. `silent: true` because we're only running the\n * reset side effect, no default track().\n */\nexport const userLogoutReset: AmplitudeStepExample = {\n title: 'User logout reset',\n description:\n 'A user logout calls amplitude.reset to clear the userId and regenerate the deviceId.',\n in: getEvent('user logout', { timestamp: 1700000106 }),\n mapping: {\n silent: true,\n settings: {\n reset: true,\n },\n },\n out: [['amplitude.reset']],\n};\n\n/**\n * Single-product revenue - resolves `settings.revenue` to one object and\n * fires one amplitude.revenue() call. Note the `{ key: \"data.currency\",\n * value: \"EUR\" }` fallback syntax: try data.currency, default to \"EUR\".\n *\n * The walkerOS default event has no data.currency, so the fallback fires.\n */\nexport const subscriptionRenewRevenue: AmplitudeStepExample = {\n title: 'Subscription revenue',\n description:\n 'A subscription renewal fires a single amplitude.revenue call with productId, price, and currency fallback.',\n in: getEvent('subscription renew', {\n timestamp: 1700000107,\n data: {\n plan_id: 'plan-pro',\n amount: 9.99,\n },\n }),\n mapping: {\n silent: true,\n settings: {\n revenue: {\n map: {\n productId: 'data.plan_id',\n price: 'data.amount',\n revenueType: { value: 'renewal' },\n currency: { key: 'data.currency', value: 'EUR' },\n },\n },\n },\n },\n out: [\n [\n 'amplitude.revenue',\n {\n productId: 'plan-pro',\n price: 9.99,\n revenueType: 'renewal',\n currency: 'EUR',\n },\n ],\n ],\n};\n\n/**\n * Multi-product order - the canonical Amplitude ecommerce pattern.\n * `revenue.loop: [\"nested\", { map: ... }]` iterates event.nested and\n * resolves one revenue item per entry. Each becomes a separate\n * amplitude.revenue() call. The order-level track() fires once with\n * include-based event_properties.\n *\n * The default \"order complete\" fixture has 3 nested entries: two\n * products (ers, cc) and one gift. Products have `data.price`; the\n * gift has only `data.name`. The `condition` on the loop inner value\n * filters to products only (price must be present).\n */\nexport const orderCompleteMultiProduct: AmplitudeStepExample = {\n title: 'Multi-product order',\n description:\n 'An order fires one amplitude.revenue call per nested product plus a single track for the order totals.',\n in: getEvent('order complete', { timestamp: 1700000108 }),\n mapping: {\n include: ['data', 'globals'],\n settings: {\n revenue: {\n loop: [\n 'nested',\n {\n // Only iterate nested entries that have a price field (products).\n condition: (value: unknown) => {\n const v = value as { data?: { price?: unknown } };\n return typeof v?.data?.price === 'number';\n },\n map: {\n productId: 'data.id',\n price: 'data.price',\n quantity: { key: 'data.quantity', value: 1 },\n revenueType: { value: 'purchase' },\n currency: { key: 'data.currency', value: 'EUR' },\n },\n },\n ],\n },\n },\n },\n out: [\n [\n 'amplitude.revenue',\n {\n productId: 'ers',\n price: 420,\n quantity: 1,\n revenueType: 'purchase',\n currency: 'EUR',\n },\n ],\n [\n 'amplitude.revenue',\n {\n productId: 'cc',\n price: 42,\n quantity: 1,\n revenueType: 'purchase',\n currency: 'EUR',\n },\n ],\n [\n 'amplitude.track',\n 'order complete',\n {\n data_id: '0rd3r1d',\n data_currency: 'EUR',\n data_shipping: 5.22,\n data_taxes: 73.76,\n data_total: 555,\n globals_pagegroup: 'shop',\n },\n ],\n ],\n};\n\n/**\n * Group assignment + group properties. Typically used for B2B products\n * where a user belongs to a company. Both SDK calls fire on the same rule.\n */\nexport const groupAssignmentWithProperties: AmplitudeStepExample = {\n title: 'Group assignment',\n description:\n 'A company update assigns the user to a group and sets group properties via setGroup and groupIdentify.',\n in: getEvent('company update', {\n timestamp: 1700000109,\n data: {\n company: 'Acme',\n industry: 'tech',\n employee_count: 50,\n founded_year: 2020,\n },\n }),\n mapping: {\n silent: true,\n settings: {\n group: {\n map: {\n type: { value: 'company' },\n name: 'data.company',\n },\n },\n groupIdentify: {\n map: {\n type: { value: 'company' },\n name: 'data.company',\n set: {\n map: {\n industry: 'data.industry',\n size: 'data.employee_count',\n },\n },\n setOnce: {\n map: {\n founded: 'data.founded_year',\n },\n },\n },\n },\n },\n },\n out: [\n ['amplitude.setGroup', 'company', 'Acme'],\n [\n 'amplitude.groupIdentify',\n 'company',\n 'Acme',\n {\n set: {\n industry: 'tech',\n size: 50,\n },\n setOnce: {\n founded: 2020,\n },\n },\n ],\n ],\n};\n\n/**\n * Consent revoked → amplitude.setOptOut(true). The destination checks\n * the consent keys declared in config.consent and toggles optOut\n * accordingly (strict: all required keys must be granted).\n *\n * Uses the canonical StepExample.command='consent' pattern: the test\n * runner dispatches via elb('walker consent', in) instead of pushing\n * an event.\n */\nexport const consentRevokeOptOut: AmplitudeStepExample = {\n title: 'Consent revoked',\n description:\n 'With consent: { analytics: true } in the destination config, a walker consent command that denies analytics opts out of Amplitude tracking via setOptOut(true).',\n command: 'consent',\n before: { analytics: true },\n in: { analytics: false } as WalkerOS.Consent,\n settings: {} as Partial<Settings>,\n out: [\n ['amplitude.setOptOut', false],\n ['amplitude.setOptOut', true],\n ],\n};\n\n/**\n * Consent granted → amplitude.setOptOut(false).\n */\nexport const consentGrantOptIn: AmplitudeStepExample = {\n title: 'Consent granted',\n description:\n 'With consent: { analytics: true } in the destination config, a walker consent command that grants analytics opts into Amplitude tracking via setOptOut(false).',\n command: 'consent',\n in: { analytics: true } as WalkerOS.Consent,\n settings: {} as Partial<Settings>,\n out: [['amplitude.setOptOut', false]],\n};\n"],"mappings":"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","names":["z"]}
@@ -140,12 +140,12 @@ declare const defaultEventForwarding: AmplitudeStepExample;
140
140
  */
141
141
  declare const wildcardIgnored: AmplitudeStepExample;
142
142
  /**
143
- * Destination-level settings.include flattens the walkerOS `data` section
144
- * into prefixed event_properties on every push.
143
+ * Destination-level include (config.include) flattens the walkerOS `data`
144
+ * section into prefixed event_properties on every push.
145
145
  */
146
146
  declare const destinationLevelInclude: AmplitudeStepExample;
147
147
  /**
148
- * Per-rule settings.include REPLACES destination-level include for the
148
+ * Per-rule include REPLACES the destination-level config.include for the
149
149
  * matched rule. Here destination-level sends `data`, but the rule
150
150
  * overrides it with `globals` only.
151
151
  */
@@ -140,12 +140,12 @@ declare const defaultEventForwarding: AmplitudeStepExample;
140
140
  */
141
141
  declare const wildcardIgnored: AmplitudeStepExample;
142
142
  /**
143
- * Destination-level settings.include flattens the walkerOS `data` section
144
- * into prefixed event_properties on every push.
143
+ * Destination-level include (config.include) flattens the walkerOS `data`
144
+ * section into prefixed event_properties on every push.
145
145
  */
146
146
  declare const destinationLevelInclude: AmplitudeStepExample;
147
147
  /**
148
- * Per-rule settings.include REPLACES destination-level include for the
148
+ * Per-rule include REPLACES the destination-level config.include for the
149
149
  * matched rule. Here destination-level sends `data`, but the rule
150
150
  * overrides it with `globals` only.
151
151
  */
@@ -206,7 +206,7 @@ var wildcardIgnored = {
206
206
  };
207
207
  var destinationLevelInclude = {
208
208
  title: "Include data",
209
- description: "Destination-level include flattens the event data section into prefixed event_properties on every track call.",
209
+ description: "With include: ['data'] in the destination config, the event data section is flattened into prefixed event_properties on every track call.",
210
210
  in: (0, import_core.getEvent)("product view", { timestamp: 1700000102 }),
211
211
  configInclude: ["data"],
212
212
  out: [
@@ -225,7 +225,7 @@ var destinationLevelInclude = {
225
225
  };
226
226
  var ruleIncludeReplaces = {
227
227
  title: "Rule include overrides",
228
- description: "A per-rule include replaces the destination-level include for the matched event, here using only globals.",
228
+ description: "With include: ['data'] in the destination config, the rule's include: ['globals'] replaces it, so this event forwards only globals.",
229
229
  in: (0, import_core.getEvent)("order complete", { timestamp: 1700000103 }),
230
230
  configInclude: ["data"],
231
231
  mapping: {
@@ -243,7 +243,7 @@ var ruleIncludeReplaces = {
243
243
  };
244
244
  var destinationLevelIdentify = {
245
245
  title: "Destination identify",
246
- description: "Destination-level identify sets userId, deviceId, and sessionId on the Amplitude client before sending events; setters only re-fire when the resolved values change (cached values are not re-applied on subsequent pushes).",
246
+ description: "With settings.identify mapping user, device, and session to 'user.id', 'user.device', and 'user.session', the destination sets userId, deviceId, and sessionId before the track call. A non-numeric session string is hashed to a stable number. Setters only re-fire when the resolved values change.",
247
247
  in: (0, import_core.getEvent)("page view", { timestamp: 1700000104 }),
248
248
  settings: {
249
249
  identify: {
@@ -265,7 +265,7 @@ var userLoginIdentify = {
265
265
  title: "User login identify",
266
266
  description: "A user login sets the Amplitude userId and runs identify with set, setOnce, and add operations.",
267
267
  in: (0, import_core.getEvent)("user login", {
268
- timestamp: 1700000105,
268
+ timestamp: 1700000105e3,
269
269
  data: {
270
270
  user_id: "new-user-123",
271
271
  plan: "premium",
@@ -311,7 +311,7 @@ var userLoginIdentify = {
311
311
  email: "user@acme.com"
312
312
  },
313
313
  setOnce: {
314
- first_login: 1700000105
314
+ first_login: 1700000105e3
315
315
  },
316
316
  add: {
317
317
  login_count: 1
@@ -491,7 +491,7 @@ var groupAssignmentWithProperties = {
491
491
  };
492
492
  var consentRevokeOptOut = {
493
493
  title: "Consent revoked",
494
- description: "A walker consent command with analytics denied opts out of Amplitude tracking via setOptOut(true).",
494
+ description: "With consent: { analytics: true } in the destination config, a walker consent command that denies analytics opts out of Amplitude tracking via setOptOut(true).",
495
495
  command: "consent",
496
496
  before: { analytics: true },
497
497
  in: { analytics: false },
@@ -503,7 +503,7 @@ var consentRevokeOptOut = {
503
503
  };
504
504
  var consentGrantOptIn = {
505
505
  title: "Consent granted",
506
- description: "A walker consent command with analytics granted opts back into Amplitude tracking via setOptOut(false).",
506
+ description: "With consent: { analytics: true } in the destination config, a walker consent command that grants analytics opts into Amplitude tracking via setOptOut(false).",
507
507
  command: "consent",
508
508
  in: { analytics: true },
509
509
  settings: {},