@walkeros/server-destination-amplitude 4.2.0 → 4.2.1-next-1781538735002

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,13 @@
1
1
  # @walkeros/server-destination-amplitude
2
2
 
3
+ ## 4.2.1-next-1781538735002
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [5cbcd23]
8
+ - @walkeros/core@4.2.1-next-1781538735002
9
+ - @walkeros/server-core@4.2.1-next-1781538735002
10
+
3
11
  ## 4.2.0
4
12
 
5
13
  ### Patch Changes
package/dist/dev.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as _walkeros_core_dev from '@walkeros/core/dev';
2
2
  import { z } from '@walkeros/core/dev';
3
- import { Mapping as Mapping$1, Flow } from '@walkeros/core';
3
+ import { Mapping as Mapping$1, Flow, WalkerOS } from '@walkeros/core';
4
4
  import { DestinationServer } from '@walkeros/server-core';
5
5
 
6
6
  declare const SettingsSchema: z.ZodObject<{
@@ -178,6 +178,8 @@ declare namespace env {
178
178
  type AmplitudeStepExample = Flow.StepExample & {
179
179
  settings?: Partial<Settings>;
180
180
  configInclude?: string[];
181
+ /** Consent granted before `in` so a gated destination is loaded first. */
182
+ before?: WalkerOS.Consent;
181
183
  };
182
184
  /**
183
185
  * Default event forwarding -- every walkerOS event becomes
@@ -248,9 +250,10 @@ declare const groupAssignmentWithProperties: AmplitudeStepExample;
248
250
  */
249
251
  declare const eventOptionsTimeInsertId: AmplitudeStepExample;
250
252
  /**
251
- * Consent revoked -> amplitude.setOptOut(true). The destination checks
252
- * the consent keys declared in config.consent and toggles optOut
253
- * accordingly (strict: all required keys must be granted).
253
+ * Consent revoked -> amplitude.setOptOut(true). After analytics consent is
254
+ * granted (the destination loads), revoking it toggles optOut via the
255
+ * on('consent') handler. The destination is never loaded under denied consent,
256
+ * so the opt-out is a real revocation of an already-granted destination.
254
257
  *
255
258
  * Uses the canonical StepExample.command='consent' pattern: the test
256
259
  * runner dispatches via elb('walker consent', in) instead of pushing
package/dist/dev.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as _walkeros_core_dev from '@walkeros/core/dev';
2
2
  import { z } from '@walkeros/core/dev';
3
- import { Mapping as Mapping$1, Flow } from '@walkeros/core';
3
+ import { Mapping as Mapping$1, Flow, WalkerOS } from '@walkeros/core';
4
4
  import { DestinationServer } from '@walkeros/server-core';
5
5
 
6
6
  declare const SettingsSchema: z.ZodObject<{
@@ -178,6 +178,8 @@ declare namespace env {
178
178
  type AmplitudeStepExample = Flow.StepExample & {
179
179
  settings?: Partial<Settings>;
180
180
  configInclude?: string[];
181
+ /** Consent granted before `in` so a gated destination is loaded first. */
182
+ before?: WalkerOS.Consent;
181
183
  };
182
184
  /**
183
185
  * Default event forwarding -- every walkerOS event becomes
@@ -248,9 +250,10 @@ declare const groupAssignmentWithProperties: AmplitudeStepExample;
248
250
  */
249
251
  declare const eventOptionsTimeInsertId: AmplitudeStepExample;
250
252
  /**
251
- * Consent revoked -> amplitude.setOptOut(true). The destination checks
252
- * the consent keys declared in config.consent and toggles optOut
253
- * accordingly (strict: all required keys must be granted).
253
+ * Consent revoked -> amplitude.setOptOut(true). After analytics consent is
254
+ * granted (the destination loads), revoking it toggles optOut via the
255
+ * on('consent') handler. The destination is never loaded under denied consent,
256
+ * so the opt-out is a real revocation of an already-granted destination.
254
257
  *
255
258
  * Uses the canonical StepExample.command='consent' pattern: the test
256
259
  * runner dispatches via elb('walker consent', in) instead of pushing
package/dist/dev.js CHANGED
@@ -1 +1 @@
1
- "use strict";var e,t=Object.defineProperty,i=Object.getOwnPropertyDescriptor,n=Object.getOwnPropertyNames,r=Object.prototype.hasOwnProperty,a=(e,i)=>{for(var n in i)t(e,n,{get:i[n],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 p of n(a))r.call(e,p)||p===s||t(e,p,{get:()=>a[p],enumerable:!(o=i(a,p))||o.enumerable});return e})(t({},"__esModule",{value:!0}),e));var o={};a(o,{MappingSchema:()=>c,SettingsSchema:()=>u,mapping:()=>v,settings:()=>m});var p=require("@walkeros/core/dev"),d=require("@walkeros/core/dev"),u=d.z.object({apiKey:d.z.string().min(1).describe('Your Amplitude project API key. Find it in your Amplitude project settings under "General" -> "API Keys".'),serverZone:d.z.enum(["US","EU"]).describe("Amplitude data residency zone. Use EU for European data residency. Default: US.").optional(),flushIntervalMillis:d.z.number().int().positive().describe("How often (in ms) to flush the event queue. Default: 10000.").optional(),flushQueueSize:d.z.number().int().positive().describe("Max queued events before a flush. Default: 200.").optional(),flushMaxRetries:d.z.number().int().nonnegative().describe("Max retries on failed flush. Default: 12.").optional(),useBatch:d.z.boolean().describe("Use the Amplitude batch endpoint for higher rate limits. Recommended for high-volume server flows. Default: false.").optional(),minIdLength:d.z.number().int().positive().describe("Minimum length for user_id and device_id fields.").optional(),serverUrl:d.z.string().url().describe("Custom server URL for proxies or self-hosted endpoints.").optional(),optOut:d.z.boolean().describe("Initial opt-out state. When true, no events are sent. Default: false.").optional(),enableRequestBodyCompression:d.z.boolean().describe("Enable gzip compression for request payloads. Default: false.").optional(),identify:d.z.unknown().describe("walkerOS mapping value resolving to per-event identity. Keys: user_id, device_id, session_id, set, setOnce, add, append, prepend, preInsert, postInsert, remove, unset, clearAll.").optional(),eventOptions:d.z.unknown().describe("walkerOS mapping value resolving to per-event EventOptions. Keys: time, insert_id, ip, city, country, region, language, platform, os_name, os_version, device_brand, device_model, app_version, user_agent.").optional(),include:d.z.array(d.z.string()).describe("walkerOS event sections to include as event_properties (like ['data', 'globals']).").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_id, device_id, session_id, 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, 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, eventOptions).").optional(),groupIdentify:l.z.unknown().describe("Group properties. Resolves to { type, name, set?, setOnce?, ... } -> amplitude.groupIdentify(type, name, identify, eventOptions).").optional(),eventOptions:l.z.unknown().describe("Per-rule EventOptions override. Resolves to { time?, insert_id?, ip?, ... }. Overrides destination-level eventOptions for this rule.").optional(),include:l.z.array(l.z.string()).describe("Per-rule include override. Replaces destination-level include for this rule.").optional()}),m=(0,p.zodToSchema)(u),v=(0,p.zodToSchema)(c),y={};a(y,{env:()=>g,step:()=>I});var g={};a(g,{init:()=>O,push:()=>w,simulation:()=>k});var f=()=>{},h=()=>({promise:Promise.resolve()}),b=class{set(){return this}setOnce(){return this}add(){return this}append(){return this}prepend(){return this}preInsert(){return this}postInsert(){return this}remove(){return this}unset(){return this}clearAll(){return this}},_=class{setProductId(){return this}setPrice(){return this}setQuantity(){return this}setRevenueType(){return this}setCurrency(){return this}setRevenue(){return this}setReceipt(){return this}setReceiptSig(){return this}setEventProperties(){return this}},O={amplitude:{init:h,track:f,identify:f,revenue:f,setOptOut:f,setGroup:f,groupIdentify:f,flush:h,Identify:b,Revenue:_}},w={amplitude:{init:h,track:f,identify:f,revenue:f,setOptOut:f,setGroup:f,groupIdentify:f,flush:h,Identify:b,Revenue:_}},k=["call:amplitude.init","call:amplitude.track","call:amplitude.identify","call:amplitude.revenue","call:amplitude.setOptOut","call:amplitude.setGroup","call:amplitude.groupIdentify"],I={};a(I,{consentGrantOptIn:()=>T,consentRevokeOptOut:()=>G,defaultEventForwarding:()=>A,destinationLevelIdentify:()=>P,destinationLevelInclude:()=>E,eventOptionsTimeInsertId:()=>j,groupAssignmentWithProperties:()=>D,orderCompleteMultiProduct:()=>q,subscriptionRenewRevenue:()=>U,userLoginIdentify:()=>S,wildcardIgnored:()=>R});var z=require("@walkeros/core"),A={title:"Default event",description:"A walkerOS event forwarded as an Amplitude track call with the event name and empty properties.",in:(0,z.getEvent)("product view",{timestamp:1700000100}),out:[["amplitude.track","product view",{}]]},R={public:!1,in:(0,z.getEvent)("debug noise",{timestamp:1700000101}),mapping:{ignore:!0},out:[]},E={title:"Include data section",description:"Destination-level include flattens the event data section into prefixed event_properties on every track call.",in:(0,z.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}]]},P={title:"Identify per event",description:"Destination-level identify resolves user_id, device_id, and session_id into the Amplitude EventOptions on every call.",in:(0,z.getEvent)("page view",{timestamp:1700000104}),settings:{identify:{map:{user_id:"user.id",device_id:"user.device",session_id:"user.session"}}},out:[["amplitude.track","page view",{},{user_id:"us3r",device_id:"c00k13",session_id:394324160}]]},S={title:"User login identify",description:"A user login maps to amplitude.identify with set, setOnce, and add operations while the default track call is skipped.",in:(0,z.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_id:"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.identify",{set:{plan:"premium",company:"Acme",email:"user@acme.com"},setOnce:{first_login:1700000105},add:{login_count:1}},{user_id:"new-user-123"}]]},U={title:"Subscription revenue",description:"A subscription renewal fires a single amplitude.revenue call with productId, price, and a currency fallback.",in:(0,z.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 with multiple nested products fires one amplitude.revenue per product plus a single track for the order.",in:(0,z.getEvent)("order complete",{timestamp:1700000108}),mapping:{include:["data","globals"],settings:{revenue:{loop:["nested",{condition:e=>{const t=e;return"number"==typeof t?.data?.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 plus groupIdentify.",in:(0,z.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}}]]},j={title:"Event options",description:"Destination-level eventOptions map walker fields into Amplitude per-event metadata such as time and insert_id.",in:(0,z.getEvent)("page view",{timestamp:1700000110,id:"1700000110abcdef"}),settings:{eventOptions:{map:{time:"timestamp",insert_id:"id"}}},out:[["amplitude.track","page view",{},{time:1700000110,insert_id:"1700000110abcdef"}]]},G={title:"Consent revoked",description:"A walker consent command with analytics denied opts out of Amplitude tracking via setOptOut(true).",command:"consent",in:{analytics:!1},settings:{},out:[["amplitude.setOptOut",!0]]},T={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,i=Object.getOwnPropertyDescriptor,n=Object.getOwnPropertyNames,r=Object.prototype.hasOwnProperty,a=(e,i)=>{for(var n in i)t(e,n,{get:i[n],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 p of n(a))r.call(e,p)||p===s||t(e,p,{get:()=>a[p],enumerable:!(o=i(a,p))||o.enumerable});return e})(t({},"__esModule",{value:!0}),e));var o={};a(o,{MappingSchema:()=>c,SettingsSchema:()=>u,mapping:()=>v,settings:()=>m});var p=require("@walkeros/core/dev"),d=require("@walkeros/core/dev"),u=d.z.object({apiKey:d.z.string().min(1).describe('Your Amplitude project API key. Find it in your Amplitude project settings under "General" -> "API Keys".'),serverZone:d.z.enum(["US","EU"]).describe("Amplitude data residency zone. Use EU for European data residency. Default: US.").optional(),flushIntervalMillis:d.z.number().int().positive().describe("How often (in ms) to flush the event queue. Default: 10000.").optional(),flushQueueSize:d.z.number().int().positive().describe("Max queued events before a flush. Default: 200.").optional(),flushMaxRetries:d.z.number().int().nonnegative().describe("Max retries on failed flush. Default: 12.").optional(),useBatch:d.z.boolean().describe("Use the Amplitude batch endpoint for higher rate limits. Recommended for high-volume server flows. Default: false.").optional(),minIdLength:d.z.number().int().positive().describe("Minimum length for user_id and device_id fields.").optional(),serverUrl:d.z.string().url().describe("Custom server URL for proxies or self-hosted endpoints.").optional(),optOut:d.z.boolean().describe("Initial opt-out state. When true, no events are sent. Default: false.").optional(),enableRequestBodyCompression:d.z.boolean().describe("Enable gzip compression for request payloads. Default: false.").optional(),identify:d.z.unknown().describe("walkerOS mapping value resolving to per-event identity. Keys: user_id, device_id, session_id, set, setOnce, add, append, prepend, preInsert, postInsert, remove, unset, clearAll.").optional(),eventOptions:d.z.unknown().describe("walkerOS mapping value resolving to per-event EventOptions. Keys: time, insert_id, ip, city, country, region, language, platform, os_name, os_version, device_brand, device_model, app_version, user_agent.").optional(),include:d.z.array(d.z.string()).describe("walkerOS event sections to include as event_properties (like ['data', 'globals']).").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_id, device_id, session_id, 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, 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, eventOptions).").optional(),groupIdentify:l.z.unknown().describe("Group properties. Resolves to { type, name, set?, setOnce?, ... } -> amplitude.groupIdentify(type, name, identify, eventOptions).").optional(),eventOptions:l.z.unknown().describe("Per-rule EventOptions override. Resolves to { time?, insert_id?, ip?, ... }. Overrides destination-level eventOptions for this rule.").optional(),include:l.z.array(l.z.string()).describe("Per-rule include override. Replaces destination-level include for this rule.").optional()}),m=(0,p.zodToSchema)(u),v=(0,p.zodToSchema)(c),y={};a(y,{env:()=>g,step:()=>I});var g={};a(g,{init:()=>O,push:()=>w,simulation:()=>k});var f=()=>{},h=()=>({promise:Promise.resolve()}),b=class{set(){return this}setOnce(){return this}add(){return this}append(){return this}prepend(){return this}preInsert(){return this}postInsert(){return this}remove(){return this}unset(){return this}clearAll(){return this}},_=class{setProductId(){return this}setPrice(){return this}setQuantity(){return this}setRevenueType(){return this}setCurrency(){return this}setRevenue(){return this}setReceipt(){return this}setReceiptSig(){return this}setEventProperties(){return this}},O={amplitude:{init:h,track:f,identify:f,revenue:f,setOptOut:f,setGroup:f,groupIdentify:f,flush:h,Identify:b,Revenue:_}},w={amplitude:{init:h,track:f,identify:f,revenue:f,setOptOut:f,setGroup:f,groupIdentify:f,flush:h,Identify:b,Revenue:_}},k=["call:amplitude.init","call:amplitude.track","call:amplitude.identify","call:amplitude.revenue","call:amplitude.setOptOut","call:amplitude.setGroup","call:amplitude.groupIdentify"],I={};a(I,{consentGrantOptIn:()=>T,consentRevokeOptOut:()=>G,defaultEventForwarding:()=>A,destinationLevelIdentify:()=>P,destinationLevelInclude:()=>E,eventOptionsTimeInsertId:()=>j,groupAssignmentWithProperties:()=>D,orderCompleteMultiProduct:()=>q,subscriptionRenewRevenue:()=>U,userLoginIdentify:()=>S,wildcardIgnored:()=>R});var z=require("@walkeros/core"),A={title:"Default event",description:"A walkerOS event forwarded as an Amplitude track call with the event name and empty properties.",in:(0,z.getEvent)("product view",{timestamp:1700000100}),out:[["amplitude.track","product view",{}]]},R={public:!1,in:(0,z.getEvent)("debug noise",{timestamp:1700000101}),mapping:{ignore:!0},out:[]},E={title:"Include data section",description:"Destination-level include flattens the event data section into prefixed event_properties on every track call.",in:(0,z.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}]]},P={title:"Identify per event",description:"Destination-level identify resolves user_id, device_id, and session_id into the Amplitude EventOptions on every call.",in:(0,z.getEvent)("page view",{timestamp:1700000104}),settings:{identify:{map:{user_id:"user.id",device_id:"user.device",session_id:"user.session"}}},out:[["amplitude.track","page view",{},{user_id:"us3r",device_id:"c00k13",session_id:394324160}]]},S={title:"User login identify",description:"A user login maps to amplitude.identify with set, setOnce, and add operations while the default track call is skipped.",in:(0,z.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_id:"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.identify",{set:{plan:"premium",company:"Acme",email:"user@acme.com"},setOnce:{first_login:1700000105},add:{login_count:1}},{user_id:"new-user-123"}]]},U={title:"Subscription revenue",description:"A subscription renewal fires a single amplitude.revenue call with productId, price, and a currency fallback.",in:(0,z.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 with multiple nested products fires one amplitude.revenue per product plus a single track for the order.",in:(0,z.getEvent)("order complete",{timestamp:1700000108}),mapping:{include:["data","globals"],settings:{revenue:{loop:["nested",{condition:e=>{const t=e;return"number"==typeof t?.data?.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 plus groupIdentify.",in:(0,z.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}}]]},j={title:"Event options",description:"Destination-level eventOptions map walker fields into Amplitude per-event metadata such as time and insert_id.",in:(0,z.getEvent)("page view",{timestamp:1700000110,id:"1700000110abcdef"}),settings:{eventOptions:{map:{time:"timestamp",insert_id:"id"}}},out:[["amplitude.track","page view",{},{time:1700000110,insert_id:"1700000110abcdef"}]]},G={title:"Consent revoked",description:"After analytics consent is granted (Amplitude loads), revoking it opts out of tracking via setOptOut(true).",command:"consent",before:{analytics:!0},in:{analytics:!1},settings:{},out:[["amplitude.setOptOut",!1],["amplitude.setOptOut",!0]]},T={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
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\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\".',\n ),\n serverZone: z\n .enum(['US', 'EU'])\n .describe(\n 'Amplitude data residency zone. Use EU for European data residency. Default: US.',\n )\n .optional(),\n flushIntervalMillis: z\n .number()\n .int()\n .positive()\n .describe('How often (in ms) to flush the event queue. Default: 10000.')\n .optional(),\n flushQueueSize: z\n .number()\n .int()\n .positive()\n .describe('Max queued events before a flush. Default: 200.')\n .optional(),\n flushMaxRetries: z\n .number()\n .int()\n .nonnegative()\n .describe('Max retries on failed flush. Default: 12.')\n .optional(),\n useBatch: z\n .boolean()\n .describe(\n 'Use the Amplitude batch endpoint for higher rate limits. Recommended for high-volume server flows. Default: false.',\n )\n .optional(),\n minIdLength: z\n .number()\n .int()\n .positive()\n .describe('Minimum length for user_id and device_id fields.')\n .optional(),\n serverUrl: z\n .string()\n .url()\n .describe('Custom server URL for proxies or self-hosted endpoints.')\n .optional(),\n optOut: z\n .boolean()\n .describe(\n 'Initial opt-out state. When true, no events are sent. Default: false.',\n )\n .optional(),\n enableRequestBodyCompression: z\n .boolean()\n .describe('Enable gzip compression for request payloads. Default: false.')\n .optional(),\n identify: z\n .unknown()\n .describe(\n 'walkerOS mapping value resolving to per-event identity. Keys: user_id, device_id, session_id, set, setOnce, add, append, prepend, preInsert, postInsert, remove, unset, clearAll.',\n )\n .optional(),\n eventOptions: z\n .unknown()\n .describe(\n 'walkerOS mapping value resolving to per-event EventOptions. Keys: time, insert_id, ip, city, country, region, language, platform, os_name, os_version, device_brand, device_model, app_version, user_agent.',\n )\n .optional(),\n include: z\n .array(z.string())\n .describe(\n \"walkerOS event sections to include as event_properties (like ['data', 'globals']).\",\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_id, device_id, session_id, 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, 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, eventOptions).',\n )\n .optional(),\n groupIdentify: z\n .unknown()\n .describe(\n 'Group properties. Resolves to { type, name, set?, setOnce?, ... } -> amplitude.groupIdentify(type, name, identify, eventOptions).',\n )\n .optional(),\n eventOptions: z\n .unknown()\n .describe(\n 'Per-rule EventOptions override. Resolves to { time?, insert_id?, ip?, ... }. Overrides destination-level eventOptions for this rule.',\n )\n .optional(),\n include: z\n .array(z.string())\n .describe(\n 'Per-rule include override. Replaces destination-level include for this 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\nconst noop = () => {};\nconst noopPromise = () => ({ promise: Promise.resolve() });\n\nclass MockIdentify implements IdentifyInstance {\n set() {\n return this;\n }\n setOnce() {\n return this;\n }\n add() {\n return this;\n }\n append() {\n return this;\n }\n prepend() {\n return this;\n }\n preInsert() {\n return this;\n }\n postInsert() {\n return this;\n }\n remove() {\n return this;\n }\n unset() {\n return this;\n }\n clearAll() {\n return this;\n }\n}\n\nclass MockRevenue implements RevenueInstance {\n setProductId() {\n return this;\n }\n setPrice() {\n return this;\n }\n setQuantity() {\n return this;\n }\n setRevenueType() {\n return this;\n }\n setCurrency() {\n return this;\n }\n setRevenue() {\n return this;\n }\n setReceipt() {\n return this;\n }\n setReceiptSig() {\n return this;\n }\n setEventProperties() {\n return this;\n }\n}\n\nexport const init: Env | undefined = {\n amplitude: {\n init: noopPromise,\n track: noop,\n identify: noop,\n revenue: noop,\n setOptOut: noop,\n setGroup: noop,\n groupIdentify: noop,\n flush: noopPromise,\n Identify: MockIdentify,\n Revenue: MockRevenue,\n },\n};\n\nexport const push: Env = {\n amplitude: {\n init: noopPromise,\n track: noop,\n identify: noop,\n revenue: noop,\n setOptOut: noop,\n setGroup: noop,\n groupIdentify: noop,\n flush: noopPromise,\n Identify: MockIdentify,\n Revenue: MockRevenue,\n },\n};\n\nexport const simulation = [\n 'call:amplitude.init',\n 'call:amplitude.track',\n 'call:amplitude.identify',\n 'call:amplitude.revenue',\n 'call:amplitude.setOptOut',\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 * Extended step example type for Amplitude server destination.\n * Settings and configInclude are read by the test runner and merged\n * into the base destination configuration.\n */\nexport type AmplitudeStepExample = Flow.StepExample & {\n settings?: Partial<Settings>;\n configInclude?: string[];\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 event',\n description:\n 'A walkerOS event forwarded 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 section',\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 * Destination-level settings.identify resolves per-event identity.\n * Unlike the web destination (which uses setUserId/setDeviceId/setSessionId),\n * server-side identity goes into EventOptions passed to every SDK call.\n *\n * user.session is 's3ss10n' (string). The destination deterministically\n * hashes non-numeric session strings via djb2.\n * djb2('s3ss10n') = 394324160.\n */\nexport const destinationLevelIdentify: AmplitudeStepExample = {\n title: 'Identify per event',\n description:\n 'Destination-level identify resolves user_id, device_id, and session_id into the Amplitude EventOptions on every call.',\n in: getEvent('page view', { timestamp: 1700000104 }),\n settings: {\n identify: {\n map: {\n user_id: 'user.id',\n device_id: 'user.device',\n session_id: 'user.session',\n },\n },\n },\n out: [\n [\n 'amplitude.track',\n 'page view',\n {},\n {\n user_id: 'us3r',\n device_id: 'c00k13',\n session_id: 394324160,\n },\n ],\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 *\n * Server-side, user_id is passed via EventOptions on identify().\n */\nexport const userLoginIdentify: AmplitudeStepExample = {\n title: 'User login identify',\n description:\n 'A user login maps to amplitude.identify with set, setOnce, and add operations while the default track call is skipped.',\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_id: '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 [\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 user_id: 'new-user-123',\n },\n ],\n ],\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 custom event has no data.currency, so the fallback fires.\n * `silent: true` suppresses the default track().\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 a 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 with multiple nested products fires one amplitude.revenue per product plus a single track for the order.',\n in: getEvent('order complete', { timestamp: 1700000108 }),\n mapping: {\n include: ['data', 'globals'],\n settings: {\n revenue: {\n loop: [\n 'nested',\n {\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 plus 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 * EventOptions mapping -- `settings.eventOptions` maps walkerOS fields\n * to Amplitude per-event metadata. Here `time` maps from the event\n * timestamp and `insert_id` maps from the event id for deduplication.\n */\nexport const eventOptionsTimeInsertId: AmplitudeStepExample = {\n title: 'Event options',\n description:\n 'Destination-level eventOptions map walker fields into Amplitude per-event metadata such as time and insert_id.',\n in: getEvent('page view', {\n timestamp: 1700000110,\n id: '1700000110abcdef',\n }),\n settings: {\n eventOptions: {\n map: {\n time: 'timestamp',\n insert_id: 'id',\n },\n },\n },\n out: [\n [\n 'amplitude.track',\n 'page view',\n {},\n {\n time: 1700000110,\n insert_id: '1700000110abcdef',\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 in: { analytics: false } as WalkerOS.Consent,\n settings: {} as Partial<Settings>,\n out: [['amplitude.setOptOut', true]],\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\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\".',\n ),\n serverZone: z\n .enum(['US', 'EU'])\n .describe(\n 'Amplitude data residency zone. Use EU for European data residency. Default: US.',\n )\n .optional(),\n flushIntervalMillis: z\n .number()\n .int()\n .positive()\n .describe('How often (in ms) to flush the event queue. Default: 10000.')\n .optional(),\n flushQueueSize: z\n .number()\n .int()\n .positive()\n .describe('Max queued events before a flush. Default: 200.')\n .optional(),\n flushMaxRetries: z\n .number()\n .int()\n .nonnegative()\n .describe('Max retries on failed flush. Default: 12.')\n .optional(),\n useBatch: z\n .boolean()\n .describe(\n 'Use the Amplitude batch endpoint for higher rate limits. Recommended for high-volume server flows. Default: false.',\n )\n .optional(),\n minIdLength: z\n .number()\n .int()\n .positive()\n .describe('Minimum length for user_id and device_id fields.')\n .optional(),\n serverUrl: z\n .string()\n .url()\n .describe('Custom server URL for proxies or self-hosted endpoints.')\n .optional(),\n optOut: z\n .boolean()\n .describe(\n 'Initial opt-out state. When true, no events are sent. Default: false.',\n )\n .optional(),\n enableRequestBodyCompression: z\n .boolean()\n .describe('Enable gzip compression for request payloads. Default: false.')\n .optional(),\n identify: z\n .unknown()\n .describe(\n 'walkerOS mapping value resolving to per-event identity. Keys: user_id, device_id, session_id, set, setOnce, add, append, prepend, preInsert, postInsert, remove, unset, clearAll.',\n )\n .optional(),\n eventOptions: z\n .unknown()\n .describe(\n 'walkerOS mapping value resolving to per-event EventOptions. Keys: time, insert_id, ip, city, country, region, language, platform, os_name, os_version, device_brand, device_model, app_version, user_agent.',\n )\n .optional(),\n include: z\n .array(z.string())\n .describe(\n \"walkerOS event sections to include as event_properties (like ['data', 'globals']).\",\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_id, device_id, session_id, 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, 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, eventOptions).',\n )\n .optional(),\n groupIdentify: z\n .unknown()\n .describe(\n 'Group properties. Resolves to { type, name, set?, setOnce?, ... } -> amplitude.groupIdentify(type, name, identify, eventOptions).',\n )\n .optional(),\n eventOptions: z\n .unknown()\n .describe(\n 'Per-rule EventOptions override. Resolves to { time?, insert_id?, ip?, ... }. Overrides destination-level eventOptions for this rule.',\n )\n .optional(),\n include: z\n .array(z.string())\n .describe(\n 'Per-rule include override. Replaces destination-level include for this 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\nconst noop = () => {};\nconst noopPromise = () => ({ promise: Promise.resolve() });\n\nclass MockIdentify implements IdentifyInstance {\n set() {\n return this;\n }\n setOnce() {\n return this;\n }\n add() {\n return this;\n }\n append() {\n return this;\n }\n prepend() {\n return this;\n }\n preInsert() {\n return this;\n }\n postInsert() {\n return this;\n }\n remove() {\n return this;\n }\n unset() {\n return this;\n }\n clearAll() {\n return this;\n }\n}\n\nclass MockRevenue implements RevenueInstance {\n setProductId() {\n return this;\n }\n setPrice() {\n return this;\n }\n setQuantity() {\n return this;\n }\n setRevenueType() {\n return this;\n }\n setCurrency() {\n return this;\n }\n setRevenue() {\n return this;\n }\n setReceipt() {\n return this;\n }\n setReceiptSig() {\n return this;\n }\n setEventProperties() {\n return this;\n }\n}\n\nexport const init: Env | undefined = {\n amplitude: {\n init: noopPromise,\n track: noop,\n identify: noop,\n revenue: noop,\n setOptOut: noop,\n setGroup: noop,\n groupIdentify: noop,\n flush: noopPromise,\n Identify: MockIdentify,\n Revenue: MockRevenue,\n },\n};\n\nexport const push: Env = {\n amplitude: {\n init: noopPromise,\n track: noop,\n identify: noop,\n revenue: noop,\n setOptOut: noop,\n setGroup: noop,\n groupIdentify: noop,\n flush: noopPromise,\n Identify: MockIdentify,\n Revenue: MockRevenue,\n },\n};\n\nexport const simulation = [\n 'call:amplitude.init',\n 'call:amplitude.track',\n 'call:amplitude.identify',\n 'call:amplitude.revenue',\n 'call:amplitude.setOptOut',\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 * Extended step example type for Amplitude server destination.\n * Settings and configInclude are read by the test runner and merged\n * into the base destination configuration.\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 event',\n description:\n 'A walkerOS event forwarded 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 section',\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 * Destination-level settings.identify resolves per-event identity.\n * Unlike the web destination (which uses setUserId/setDeviceId/setSessionId),\n * server-side identity goes into EventOptions passed to every SDK call.\n *\n * user.session is 's3ss10n' (string). The destination deterministically\n * hashes non-numeric session strings via djb2.\n * djb2('s3ss10n') = 394324160.\n */\nexport const destinationLevelIdentify: AmplitudeStepExample = {\n title: 'Identify per event',\n description:\n 'Destination-level identify resolves user_id, device_id, and session_id into the Amplitude EventOptions on every call.',\n in: getEvent('page view', { timestamp: 1700000104 }),\n settings: {\n identify: {\n map: {\n user_id: 'user.id',\n device_id: 'user.device',\n session_id: 'user.session',\n },\n },\n },\n out: [\n [\n 'amplitude.track',\n 'page view',\n {},\n {\n user_id: 'us3r',\n device_id: 'c00k13',\n session_id: 394324160,\n },\n ],\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 *\n * Server-side, user_id is passed via EventOptions on identify().\n */\nexport const userLoginIdentify: AmplitudeStepExample = {\n title: 'User login identify',\n description:\n 'A user login maps to amplitude.identify with set, setOnce, and add operations while the default track call is skipped.',\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_id: '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 [\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 user_id: 'new-user-123',\n },\n ],\n ],\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 custom event has no data.currency, so the fallback fires.\n * `silent: true` suppresses the default track().\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 a 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 with multiple nested products fires one amplitude.revenue per product plus a single track for the order.',\n in: getEvent('order complete', { timestamp: 1700000108 }),\n mapping: {\n include: ['data', 'globals'],\n settings: {\n revenue: {\n loop: [\n 'nested',\n {\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 plus 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 * EventOptions mapping -- `settings.eventOptions` maps walkerOS fields\n * to Amplitude per-event metadata. Here `time` maps from the event\n * timestamp and `insert_id` maps from the event id for deduplication.\n */\nexport const eventOptionsTimeInsertId: AmplitudeStepExample = {\n title: 'Event options',\n description:\n 'Destination-level eventOptions map walker fields into Amplitude per-event metadata such as time and insert_id.',\n in: getEvent('page view', {\n timestamp: 1700000110,\n id: '1700000110abcdef',\n }),\n settings: {\n eventOptions: {\n map: {\n time: 'timestamp',\n insert_id: 'id',\n },\n },\n },\n out: [\n [\n 'amplitude.track',\n 'page view',\n {},\n {\n time: 1700000110,\n insert_id: '1700000110abcdef',\n },\n ],\n ],\n};\n\n/**\n * Consent revoked -> amplitude.setOptOut(true). After analytics consent is\n * granted (the destination loads), revoking it toggles optOut via the\n * on('consent') handler. The destination is never loaded under denied consent,\n * so the opt-out is a real revocation of an already-granted destination.\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 'After analytics consent is granted (Amplitude loads), revoking it opts out of 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"]}
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:()=>d,settings:()=>p});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".'),serverZone:r.enum(["US","EU"]).describe("Amplitude data residency zone. Use EU for European data residency. Default: US.").optional(),flushIntervalMillis:r.number().int().positive().describe("How often (in ms) to flush the event queue. Default: 10000.").optional(),flushQueueSize:r.number().int().positive().describe("Max queued events before a flush. Default: 200.").optional(),flushMaxRetries:r.number().int().nonnegative().describe("Max retries on failed flush. Default: 12.").optional(),useBatch:r.boolean().describe("Use the Amplitude batch endpoint for higher rate limits. Recommended for high-volume server flows. Default: false.").optional(),minIdLength:r.number().int().positive().describe("Minimum length for user_id and device_id fields.").optional(),serverUrl:r.string().url().describe("Custom server URL for proxies or self-hosted endpoints.").optional(),optOut:r.boolean().describe("Initial opt-out state. When true, no events are sent. Default: false.").optional(),enableRequestBodyCompression:r.boolean().describe("Enable gzip compression for request payloads. Default: false.").optional(),identify:r.unknown().describe("walkerOS mapping value resolving to per-event identity. Keys: user_id, device_id, session_id, set, setOnce, add, append, prepend, preInsert, postInsert, remove, unset, clearAll.").optional(),eventOptions:r.unknown().describe("walkerOS mapping value resolving to per-event EventOptions. Keys: time, insert_id, ip, city, country, region, language, platform, os_name, os_version, device_brand, device_model, app_version, user_agent.").optional(),include:r.array(r.string()).describe("walkerOS event sections to include as event_properties (like ['data', 'globals']).").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_id, device_id, session_id, 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, 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, eventOptions).").optional(),groupIdentify:s.unknown().describe("Group properties. Resolves to { type, name, set?, setOnce?, ... } -> amplitude.groupIdentify(type, name, identify, eventOptions).").optional(),eventOptions:s.unknown().describe("Per-rule EventOptions override. Resolves to { time?, insert_id?, ip?, ... }. Overrides destination-level eventOptions for this rule.").optional(),include:s.array(s.string()).describe("Per-rule include override. Replaces destination-level include for this rule.").optional()}),p=n(a),d=n(o),u={};t(u,{env:()=>l,step:()=>_});var l={};t(l,{init:()=>f,push:()=>g,simulation:()=>h});var c=()=>{},m=()=>({promise:Promise.resolve()}),v=class{set(){return this}setOnce(){return this}add(){return this}append(){return this}prepend(){return this}preInsert(){return this}postInsert(){return this}remove(){return this}unset(){return this}clearAll(){return this}},y=class{setProductId(){return this}setPrice(){return this}setQuantity(){return this}setRevenueType(){return this}setCurrency(){return this}setRevenue(){return this}setReceipt(){return this}setReceiptSig(){return this}setEventProperties(){return this}},f={amplitude:{init:m,track:c,identify:c,revenue:c,setOptOut:c,setGroup:c,groupIdentify:c,flush:m,Identify:v,Revenue:y}},g={amplitude:{init:m,track:c,identify:c,revenue:c,setOptOut:c,setGroup:c,groupIdentify:c,flush:m,Identify:v,Revenue:y}},h=["call:amplitude.init","call:amplitude.track","call:amplitude.identify","call:amplitude.revenue","call:amplitude.setOptOut","call:amplitude.setGroup","call:amplitude.groupIdentify"],_={};t(_,{consentGrantOptIn:()=>D,consentRevokeOptOut:()=>P,defaultEventForwarding:()=>w,destinationLevelIdentify:()=>I,destinationLevelInclude:()=>O,eventOptionsTimeInsertId:()=>S,groupAssignmentWithProperties:()=>U,orderCompleteMultiProduct:()=>E,subscriptionRenewRevenue:()=>R,userLoginIdentify:()=>A,wildcardIgnored:()=>k});import{getEvent as b}from"@walkeros/core";var w={title:"Default event",description:"A walkerOS event forwarded as an Amplitude track call with the event name and empty properties.",in:b("product view",{timestamp:1700000100}),out:[["amplitude.track","product view",{}]]},k={public:!1,in:b("debug noise",{timestamp:1700000101}),mapping:{ignore:!0},out:[]},O={title:"Include data section",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}]]},I={title:"Identify per event",description:"Destination-level identify resolves user_id, device_id, and session_id into the Amplitude EventOptions on every call.",in:b("page view",{timestamp:1700000104}),settings:{identify:{map:{user_id:"user.id",device_id:"user.device",session_id:"user.session"}}},out:[["amplitude.track","page view",{},{user_id:"us3r",device_id:"c00k13",session_id:394324160}]]},A={title:"User login identify",description:"A user login maps to amplitude.identify with set, setOnce, and add operations while the default track call is skipped.",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_id:"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.identify",{set:{plan:"premium",company:"Acme",email:"user@acme.com"},setOnce:{first_login:1700000105},add:{login_count:1}},{user_id:"new-user-123"}]]},R={title:"Subscription revenue",description:"A subscription renewal fires a single amplitude.revenue call with productId, price, and a 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"}]]},E={title:"Multi-product order",description:"An order with multiple nested products fires one amplitude.revenue per product plus a single track for the order.",in:b("order complete",{timestamp:1700000108}),mapping:{include:["data","globals"],settings:{revenue:{loop:["nested",{condition:e=>{const t=e;return"number"==typeof t?.data?.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"}]]},U={title:"Group assignment",description:"A company update assigns the user to a group and sets group properties via setGroup plus 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}}]]},S={title:"Event options",description:"Destination-level eventOptions map walker fields into Amplitude per-event metadata such as time and insert_id.",in:b("page view",{timestamp:1700000110,id:"1700000110abcdef"}),settings:{eventOptions:{map:{time:"timestamp",insert_id:"id"}}},out:[["amplitude.track","page view",{},{time:1700000110,insert_id:"1700000110abcdef"}]]},P={title:"Consent revoked",description:"A walker consent command with analytics denied opts out of Amplitude tracking via setOptOut(true).",command:"consent",in:{analytics:!1},settings:{},out:[["amplitude.setOptOut",!0]]},D={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:()=>a,mapping:()=>d,settings:()=>p});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".'),serverZone:r.enum(["US","EU"]).describe("Amplitude data residency zone. Use EU for European data residency. Default: US.").optional(),flushIntervalMillis:r.number().int().positive().describe("How often (in ms) to flush the event queue. Default: 10000.").optional(),flushQueueSize:r.number().int().positive().describe("Max queued events before a flush. Default: 200.").optional(),flushMaxRetries:r.number().int().nonnegative().describe("Max retries on failed flush. Default: 12.").optional(),useBatch:r.boolean().describe("Use the Amplitude batch endpoint for higher rate limits. Recommended for high-volume server flows. Default: false.").optional(),minIdLength:r.number().int().positive().describe("Minimum length for user_id and device_id fields.").optional(),serverUrl:r.string().url().describe("Custom server URL for proxies or self-hosted endpoints.").optional(),optOut:r.boolean().describe("Initial opt-out state. When true, no events are sent. Default: false.").optional(),enableRequestBodyCompression:r.boolean().describe("Enable gzip compression for request payloads. Default: false.").optional(),identify:r.unknown().describe("walkerOS mapping value resolving to per-event identity. Keys: user_id, device_id, session_id, set, setOnce, add, append, prepend, preInsert, postInsert, remove, unset, clearAll.").optional(),eventOptions:r.unknown().describe("walkerOS mapping value resolving to per-event EventOptions. Keys: time, insert_id, ip, city, country, region, language, platform, os_name, os_version, device_brand, device_model, app_version, user_agent.").optional(),include:r.array(r.string()).describe("walkerOS event sections to include as event_properties (like ['data', 'globals']).").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_id, device_id, session_id, 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, 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, eventOptions).").optional(),groupIdentify:s.unknown().describe("Group properties. Resolves to { type, name, set?, setOnce?, ... } -> amplitude.groupIdentify(type, name, identify, eventOptions).").optional(),eventOptions:s.unknown().describe("Per-rule EventOptions override. Resolves to { time?, insert_id?, ip?, ... }. Overrides destination-level eventOptions for this rule.").optional(),include:s.array(s.string()).describe("Per-rule include override. Replaces destination-level include for this rule.").optional()}),p=n(a),d=n(o),u={};t(u,{env:()=>l,step:()=>_});var l={};t(l,{init:()=>f,push:()=>g,simulation:()=>h});var c=()=>{},m=()=>({promise:Promise.resolve()}),v=class{set(){return this}setOnce(){return this}add(){return this}append(){return this}prepend(){return this}preInsert(){return this}postInsert(){return this}remove(){return this}unset(){return this}clearAll(){return this}},y=class{setProductId(){return this}setPrice(){return this}setQuantity(){return this}setRevenueType(){return this}setCurrency(){return this}setRevenue(){return this}setReceipt(){return this}setReceiptSig(){return this}setEventProperties(){return this}},f={amplitude:{init:m,track:c,identify:c,revenue:c,setOptOut:c,setGroup:c,groupIdentify:c,flush:m,Identify:v,Revenue:y}},g={amplitude:{init:m,track:c,identify:c,revenue:c,setOptOut:c,setGroup:c,groupIdentify:c,flush:m,Identify:v,Revenue:y}},h=["call:amplitude.init","call:amplitude.track","call:amplitude.identify","call:amplitude.revenue","call:amplitude.setOptOut","call:amplitude.setGroup","call:amplitude.groupIdentify"],_={};t(_,{consentGrantOptIn:()=>D,consentRevokeOptOut:()=>P,defaultEventForwarding:()=>O,destinationLevelIdentify:()=>I,destinationLevelInclude:()=>w,eventOptionsTimeInsertId:()=>S,groupAssignmentWithProperties:()=>U,orderCompleteMultiProduct:()=>E,subscriptionRenewRevenue:()=>R,userLoginIdentify:()=>A,wildcardIgnored:()=>k});import{getEvent as b}from"@walkeros/core";var O={title:"Default event",description:"A walkerOS event forwarded as an Amplitude track call with the event name and empty properties.",in:b("product view",{timestamp:1700000100}),out:[["amplitude.track","product view",{}]]},k={public:!1,in:b("debug noise",{timestamp:1700000101}),mapping:{ignore:!0},out:[]},w={title:"Include data section",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}]]},I={title:"Identify per event",description:"Destination-level identify resolves user_id, device_id, and session_id into the Amplitude EventOptions on every call.",in:b("page view",{timestamp:1700000104}),settings:{identify:{map:{user_id:"user.id",device_id:"user.device",session_id:"user.session"}}},out:[["amplitude.track","page view",{},{user_id:"us3r",device_id:"c00k13",session_id:394324160}]]},A={title:"User login identify",description:"A user login maps to amplitude.identify with set, setOnce, and add operations while the default track call is skipped.",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_id:"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.identify",{set:{plan:"premium",company:"Acme",email:"user@acme.com"},setOnce:{first_login:1700000105},add:{login_count:1}},{user_id:"new-user-123"}]]},R={title:"Subscription revenue",description:"A subscription renewal fires a single amplitude.revenue call with productId, price, and a 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"}]]},E={title:"Multi-product order",description:"An order with multiple nested products fires one amplitude.revenue per product plus a single track for the order.",in:b("order complete",{timestamp:1700000108}),mapping:{include:["data","globals"],settings:{revenue:{loop:["nested",{condition:e=>{const t=e;return"number"==typeof t?.data?.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"}]]},U={title:"Group assignment",description:"A company update assigns the user to a group and sets group properties via setGroup plus 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}}]]},S={title:"Event options",description:"Destination-level eventOptions map walker fields into Amplitude per-event metadata such as time and insert_id.",in:b("page view",{timestamp:1700000110,id:"1700000110abcdef"}),settings:{eventOptions:{map:{time:"timestamp",insert_id:"id"}}},out:[["amplitude.track","page view",{},{time:1700000110,insert_id:"1700000110abcdef"}]]},P={title:"Consent revoked",description:"After analytics consent is granted (Amplitude loads), revoking it opts out of tracking via setOptOut(true).",command:"consent",before:{analytics:!0},in:{analytics:!1},settings:{},out:[["amplitude.setOptOut",!1],["amplitude.setOptOut",!0]]},D={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
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\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\".',\n ),\n serverZone: z\n .enum(['US', 'EU'])\n .describe(\n 'Amplitude data residency zone. Use EU for European data residency. Default: US.',\n )\n .optional(),\n flushIntervalMillis: z\n .number()\n .int()\n .positive()\n .describe('How often (in ms) to flush the event queue. Default: 10000.')\n .optional(),\n flushQueueSize: z\n .number()\n .int()\n .positive()\n .describe('Max queued events before a flush. Default: 200.')\n .optional(),\n flushMaxRetries: z\n .number()\n .int()\n .nonnegative()\n .describe('Max retries on failed flush. Default: 12.')\n .optional(),\n useBatch: z\n .boolean()\n .describe(\n 'Use the Amplitude batch endpoint for higher rate limits. Recommended for high-volume server flows. Default: false.',\n )\n .optional(),\n minIdLength: z\n .number()\n .int()\n .positive()\n .describe('Minimum length for user_id and device_id fields.')\n .optional(),\n serverUrl: z\n .string()\n .url()\n .describe('Custom server URL for proxies or self-hosted endpoints.')\n .optional(),\n optOut: z\n .boolean()\n .describe(\n 'Initial opt-out state. When true, no events are sent. Default: false.',\n )\n .optional(),\n enableRequestBodyCompression: z\n .boolean()\n .describe('Enable gzip compression for request payloads. Default: false.')\n .optional(),\n identify: z\n .unknown()\n .describe(\n 'walkerOS mapping value resolving to per-event identity. Keys: user_id, device_id, session_id, set, setOnce, add, append, prepend, preInsert, postInsert, remove, unset, clearAll.',\n )\n .optional(),\n eventOptions: z\n .unknown()\n .describe(\n 'walkerOS mapping value resolving to per-event EventOptions. Keys: time, insert_id, ip, city, country, region, language, platform, os_name, os_version, device_brand, device_model, app_version, user_agent.',\n )\n .optional(),\n include: z\n .array(z.string())\n .describe(\n \"walkerOS event sections to include as event_properties (like ['data', 'globals']).\",\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_id, device_id, session_id, 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, 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, eventOptions).',\n )\n .optional(),\n groupIdentify: z\n .unknown()\n .describe(\n 'Group properties. Resolves to { type, name, set?, setOnce?, ... } -> amplitude.groupIdentify(type, name, identify, eventOptions).',\n )\n .optional(),\n eventOptions: z\n .unknown()\n .describe(\n 'Per-rule EventOptions override. Resolves to { time?, insert_id?, ip?, ... }. Overrides destination-level eventOptions for this rule.',\n )\n .optional(),\n include: z\n .array(z.string())\n .describe(\n 'Per-rule include override. Replaces destination-level include for this 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\nconst noop = () => {};\nconst noopPromise = () => ({ promise: Promise.resolve() });\n\nclass MockIdentify implements IdentifyInstance {\n set() {\n return this;\n }\n setOnce() {\n return this;\n }\n add() {\n return this;\n }\n append() {\n return this;\n }\n prepend() {\n return this;\n }\n preInsert() {\n return this;\n }\n postInsert() {\n return this;\n }\n remove() {\n return this;\n }\n unset() {\n return this;\n }\n clearAll() {\n return this;\n }\n}\n\nclass MockRevenue implements RevenueInstance {\n setProductId() {\n return this;\n }\n setPrice() {\n return this;\n }\n setQuantity() {\n return this;\n }\n setRevenueType() {\n return this;\n }\n setCurrency() {\n return this;\n }\n setRevenue() {\n return this;\n }\n setReceipt() {\n return this;\n }\n setReceiptSig() {\n return this;\n }\n setEventProperties() {\n return this;\n }\n}\n\nexport const init: Env | undefined = {\n amplitude: {\n init: noopPromise,\n track: noop,\n identify: noop,\n revenue: noop,\n setOptOut: noop,\n setGroup: noop,\n groupIdentify: noop,\n flush: noopPromise,\n Identify: MockIdentify,\n Revenue: MockRevenue,\n },\n};\n\nexport const push: Env = {\n amplitude: {\n init: noopPromise,\n track: noop,\n identify: noop,\n revenue: noop,\n setOptOut: noop,\n setGroup: noop,\n groupIdentify: noop,\n flush: noopPromise,\n Identify: MockIdentify,\n Revenue: MockRevenue,\n },\n};\n\nexport const simulation = [\n 'call:amplitude.init',\n 'call:amplitude.track',\n 'call:amplitude.identify',\n 'call:amplitude.revenue',\n 'call:amplitude.setOptOut',\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 * Extended step example type for Amplitude server destination.\n * Settings and configInclude are read by the test runner and merged\n * into the base destination configuration.\n */\nexport type AmplitudeStepExample = Flow.StepExample & {\n settings?: Partial<Settings>;\n configInclude?: string[];\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 event',\n description:\n 'A walkerOS event forwarded 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 section',\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 * Destination-level settings.identify resolves per-event identity.\n * Unlike the web destination (which uses setUserId/setDeviceId/setSessionId),\n * server-side identity goes into EventOptions passed to every SDK call.\n *\n * user.session is 's3ss10n' (string). The destination deterministically\n * hashes non-numeric session strings via djb2.\n * djb2('s3ss10n') = 394324160.\n */\nexport const destinationLevelIdentify: AmplitudeStepExample = {\n title: 'Identify per event',\n description:\n 'Destination-level identify resolves user_id, device_id, and session_id into the Amplitude EventOptions on every call.',\n in: getEvent('page view', { timestamp: 1700000104 }),\n settings: {\n identify: {\n map: {\n user_id: 'user.id',\n device_id: 'user.device',\n session_id: 'user.session',\n },\n },\n },\n out: [\n [\n 'amplitude.track',\n 'page view',\n {},\n {\n user_id: 'us3r',\n device_id: 'c00k13',\n session_id: 394324160,\n },\n ],\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 *\n * Server-side, user_id is passed via EventOptions on identify().\n */\nexport const userLoginIdentify: AmplitudeStepExample = {\n title: 'User login identify',\n description:\n 'A user login maps to amplitude.identify with set, setOnce, and add operations while the default track call is skipped.',\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_id: '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 [\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 user_id: 'new-user-123',\n },\n ],\n ],\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 custom event has no data.currency, so the fallback fires.\n * `silent: true` suppresses the default track().\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 a 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 with multiple nested products fires one amplitude.revenue per product plus a single track for the order.',\n in: getEvent('order complete', { timestamp: 1700000108 }),\n mapping: {\n include: ['data', 'globals'],\n settings: {\n revenue: {\n loop: [\n 'nested',\n {\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 plus 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 * EventOptions mapping -- `settings.eventOptions` maps walkerOS fields\n * to Amplitude per-event metadata. Here `time` maps from the event\n * timestamp and `insert_id` maps from the event id for deduplication.\n */\nexport const eventOptionsTimeInsertId: AmplitudeStepExample = {\n title: 'Event options',\n description:\n 'Destination-level eventOptions map walker fields into Amplitude per-event metadata such as time and insert_id.',\n in: getEvent('page view', {\n timestamp: 1700000110,\n id: '1700000110abcdef',\n }),\n settings: {\n eventOptions: {\n map: {\n time: 'timestamp',\n insert_id: 'id',\n },\n },\n },\n out: [\n [\n 'amplitude.track',\n 'page view',\n {},\n {\n time: 1700000110,\n insert_id: '1700000110abcdef',\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 in: { analytics: false } as WalkerOS.Consent,\n settings: {} as Partial<Settings>,\n out: [['amplitude.setOptOut', true]],\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;AAAA,IACC;AAAA,EACF,EACC,SAAS;AAAA,EACZ,qBAAqB,EAClB,OAAO,EACP,IAAI,EACJ,SAAS,EACT,SAAS,6DAA6D,EACtE,SAAS;AAAA,EACZ,gBAAgB,EACb,OAAO,EACP,IAAI,EACJ,SAAS,EACT,SAAS,iDAAiD,EAC1D,SAAS;AAAA,EACZ,iBAAiB,EACd,OAAO,EACP,IAAI,EACJ,YAAY,EACZ,SAAS,2CAA2C,EACpD,SAAS;AAAA,EACZ,UAAU,EACP,QAAQ,EACR;AAAA,IACC;AAAA,EACF,EACC,SAAS;AAAA,EACZ,aAAa,EACV,OAAO,EACP,IAAI,EACJ,SAAS,EACT,SAAS,kDAAkD,EAC3D,SAAS;AAAA,EACZ,WAAW,EACR,OAAO,EACP,IAAI,EACJ,SAAS,yDAAyD,EAClE,SAAS;AAAA,EACZ,QAAQ,EACL,QAAQ,EACR;AAAA,IACC;AAAA,EACF,EACC,SAAS;AAAA,EACZ,8BAA8B,EAC3B,QAAQ,EACR,SAAS,+DAA+D,EACxE,SAAS;AAAA,EACZ,UAAU,EACP,QAAQ,EACR;AAAA,IACC;AAAA,EACF,EACC,SAAS;AAAA,EACZ,cAAc,EACX,QAAQ,EACR;AAAA,IACC;AAAA,EACF,EACC,SAAS;AAAA,EACZ,SAAS,EACN,MAAM,EAAE,OAAO,CAAC,EAChB;AAAA,IACC;AAAA,EACF,EACC,SAAS;AACd,CAAC;;;AC9ED,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,cAAcA,GACX,QAAQ,EACR;AAAA,IACC;AAAA,EACF,EACC,SAAS;AAAA,EACZ,SAASA,GACN,MAAMA,GAAE,OAAO,CAAC,EAChB;AAAA,IACC;AAAA,EACF,EACC,SAAS;AACd,CAAC;;;AFhCM,IAAM,WAAW,YAAY,cAAc;AAC3C,IAAM,UAAU,YAAY,aAAa;;;AGRhD;AAAA;AAAA;AAAA;AAAA;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,IAAM,OAAO,MAAM;AAAC;AACpB,IAAM,cAAc,OAAO,EAAE,SAAS,QAAQ,QAAQ,EAAE;AAExD,IAAM,eAAN,MAA+C;AAAA,EAC7C,MAAM;AACJ,WAAO;AAAA,EACT;AAAA,EACA,UAAU;AACR,WAAO;AAAA,EACT;AAAA,EACA,MAAM;AACJ,WAAO;AAAA,EACT;AAAA,EACA,SAAS;AACP,WAAO;AAAA,EACT;AAAA,EACA,UAAU;AACR,WAAO;AAAA,EACT;AAAA,EACA,YAAY;AACV,WAAO;AAAA,EACT;AAAA,EACA,aAAa;AACX,WAAO;AAAA,EACT;AAAA,EACA,SAAS;AACP,WAAO;AAAA,EACT;AAAA,EACA,QAAQ;AACN,WAAO;AAAA,EACT;AAAA,EACA,WAAW;AACT,WAAO;AAAA,EACT;AACF;AAEA,IAAM,cAAN,MAA6C;AAAA,EAC3C,eAAe;AACb,WAAO;AAAA,EACT;AAAA,EACA,WAAW;AACT,WAAO;AAAA,EACT;AAAA,EACA,cAAc;AACZ,WAAO;AAAA,EACT;AAAA,EACA,iBAAiB;AACf,WAAO;AAAA,EACT;AAAA,EACA,cAAc;AACZ,WAAO;AAAA,EACT;AAAA,EACA,aAAa;AACX,WAAO;AAAA,EACT;AAAA,EACA,aAAa;AACX,WAAO;AAAA,EACT;AAAA,EACA,gBAAgB;AACd,WAAO;AAAA,EACT;AAAA,EACA,qBAAqB;AACnB,WAAO;AAAA,EACT;AACF;AAEO,IAAM,OAAwB;AAAA,EACnC,WAAW;AAAA,IACT,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,SAAS;AAAA,IACT,WAAW;AAAA,IACX,UAAU;AAAA,IACV,eAAe;AAAA,IACf,OAAO;AAAA,IACP,UAAU;AAAA,IACV,SAAS;AAAA,EACX;AACF;AAEO,IAAM,OAAY;AAAA,EACvB,WAAW;AAAA,IACT,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,SAAS;AAAA,IACT,WAAW;AAAA,IACX,UAAU;AAAA,IACV,eAAe;AAAA,IACf,OAAO;AAAA,IACP,UAAU;AAAA,IACV,SAAS;AAAA,EACX;AACF;AAEO,IAAM,aAAa;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;AC1GA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,SAAS,gBAAgB;AAkBlB,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;AAWO,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,SAAS;AAAA,QACT,WAAW;AAAA,QACX,YAAY;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAAA,EACA,KAAK;AAAA,IACH;AAAA,MACE;AAAA,MACA;AAAA,MACA,CAAC;AAAA,MACD;AAAA,QACE,SAAS;AAAA,QACT,WAAW;AAAA,QACX,YAAY;AAAA,MACd;AAAA,IACF;AAAA,EACF;AACF;AAUO,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,SAAS;AAAA,UACT,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;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,MACA;AAAA,QACE,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF;AACF;AAUO,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,YACE,WAAW,CAAC,UAAmB;AAC7B,oBAAM,IAAI;AACV,qBAAO,OAAO,GAAG,MAAM,UAAU;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;AAOO,IAAM,2BAAiD;AAAA,EAC5D,OAAO;AAAA,EACP,aACE;AAAA,EACF,IAAI,SAAS,aAAa;AAAA,IACxB,WAAW;AAAA,IACX,IAAI;AAAA,EACN,CAAC;AAAA,EACD,UAAU;AAAA,IACR,cAAc;AAAA,MACZ,KAAK;AAAA,QACH,MAAM;AAAA,QACN,WAAW;AAAA,MACb;AAAA,IACF;AAAA,EACF;AAAA,EACA,KAAK;AAAA,IACH;AAAA,MACE;AAAA,MACA;AAAA,MACA,CAAC;AAAA,MACD;AAAA,QACE,MAAM;AAAA,QACN,WAAW;AAAA,MACb;AAAA,IACF;AAAA,EACF;AACF;AAWO,IAAM,sBAA4C;AAAA,EACvD,OAAO;AAAA,EACP,aACE;AAAA,EACF,SAAS;AAAA,EACT,IAAI,EAAE,WAAW,MAAM;AAAA,EACvB,UAAU,CAAC;AAAA,EACX,KAAK,CAAC,CAAC,uBAAuB,IAAI,CAAC;AACrC;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\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\".',\n ),\n serverZone: z\n .enum(['US', 'EU'])\n .describe(\n 'Amplitude data residency zone. Use EU for European data residency. Default: US.',\n )\n .optional(),\n flushIntervalMillis: z\n .number()\n .int()\n .positive()\n .describe('How often (in ms) to flush the event queue. Default: 10000.')\n .optional(),\n flushQueueSize: z\n .number()\n .int()\n .positive()\n .describe('Max queued events before a flush. Default: 200.')\n .optional(),\n flushMaxRetries: z\n .number()\n .int()\n .nonnegative()\n .describe('Max retries on failed flush. Default: 12.')\n .optional(),\n useBatch: z\n .boolean()\n .describe(\n 'Use the Amplitude batch endpoint for higher rate limits. Recommended for high-volume server flows. Default: false.',\n )\n .optional(),\n minIdLength: z\n .number()\n .int()\n .positive()\n .describe('Minimum length for user_id and device_id fields.')\n .optional(),\n serverUrl: z\n .string()\n .url()\n .describe('Custom server URL for proxies or self-hosted endpoints.')\n .optional(),\n optOut: z\n .boolean()\n .describe(\n 'Initial opt-out state. When true, no events are sent. Default: false.',\n )\n .optional(),\n enableRequestBodyCompression: z\n .boolean()\n .describe('Enable gzip compression for request payloads. Default: false.')\n .optional(),\n identify: z\n .unknown()\n .describe(\n 'walkerOS mapping value resolving to per-event identity. Keys: user_id, device_id, session_id, set, setOnce, add, append, prepend, preInsert, postInsert, remove, unset, clearAll.',\n )\n .optional(),\n eventOptions: z\n .unknown()\n .describe(\n 'walkerOS mapping value resolving to per-event EventOptions. Keys: time, insert_id, ip, city, country, region, language, platform, os_name, os_version, device_brand, device_model, app_version, user_agent.',\n )\n .optional(),\n include: z\n .array(z.string())\n .describe(\n \"walkerOS event sections to include as event_properties (like ['data', 'globals']).\",\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_id, device_id, session_id, 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, 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, eventOptions).',\n )\n .optional(),\n groupIdentify: z\n .unknown()\n .describe(\n 'Group properties. Resolves to { type, name, set?, setOnce?, ... } -> amplitude.groupIdentify(type, name, identify, eventOptions).',\n )\n .optional(),\n eventOptions: z\n .unknown()\n .describe(\n 'Per-rule EventOptions override. Resolves to { time?, insert_id?, ip?, ... }. Overrides destination-level eventOptions for this rule.',\n )\n .optional(),\n include: z\n .array(z.string())\n .describe(\n 'Per-rule include override. Replaces destination-level include for this 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\nconst noop = () => {};\nconst noopPromise = () => ({ promise: Promise.resolve() });\n\nclass MockIdentify implements IdentifyInstance {\n set() {\n return this;\n }\n setOnce() {\n return this;\n }\n add() {\n return this;\n }\n append() {\n return this;\n }\n prepend() {\n return this;\n }\n preInsert() {\n return this;\n }\n postInsert() {\n return this;\n }\n remove() {\n return this;\n }\n unset() {\n return this;\n }\n clearAll() {\n return this;\n }\n}\n\nclass MockRevenue implements RevenueInstance {\n setProductId() {\n return this;\n }\n setPrice() {\n return this;\n }\n setQuantity() {\n return this;\n }\n setRevenueType() {\n return this;\n }\n setCurrency() {\n return this;\n }\n setRevenue() {\n return this;\n }\n setReceipt() {\n return this;\n }\n setReceiptSig() {\n return this;\n }\n setEventProperties() {\n return this;\n }\n}\n\nexport const init: Env | undefined = {\n amplitude: {\n init: noopPromise,\n track: noop,\n identify: noop,\n revenue: noop,\n setOptOut: noop,\n setGroup: noop,\n groupIdentify: noop,\n flush: noopPromise,\n Identify: MockIdentify,\n Revenue: MockRevenue,\n },\n};\n\nexport const push: Env = {\n amplitude: {\n init: noopPromise,\n track: noop,\n identify: noop,\n revenue: noop,\n setOptOut: noop,\n setGroup: noop,\n groupIdentify: noop,\n flush: noopPromise,\n Identify: MockIdentify,\n Revenue: MockRevenue,\n },\n};\n\nexport const simulation = [\n 'call:amplitude.init',\n 'call:amplitude.track',\n 'call:amplitude.identify',\n 'call:amplitude.revenue',\n 'call:amplitude.setOptOut',\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 * Extended step example type for Amplitude server destination.\n * Settings and configInclude are read by the test runner and merged\n * into the base destination configuration.\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 event',\n description:\n 'A walkerOS event forwarded 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 section',\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 * Destination-level settings.identify resolves per-event identity.\n * Unlike the web destination (which uses setUserId/setDeviceId/setSessionId),\n * server-side identity goes into EventOptions passed to every SDK call.\n *\n * user.session is 's3ss10n' (string). The destination deterministically\n * hashes non-numeric session strings via djb2.\n * djb2('s3ss10n') = 394324160.\n */\nexport const destinationLevelIdentify: AmplitudeStepExample = {\n title: 'Identify per event',\n description:\n 'Destination-level identify resolves user_id, device_id, and session_id into the Amplitude EventOptions on every call.',\n in: getEvent('page view', { timestamp: 1700000104 }),\n settings: {\n identify: {\n map: {\n user_id: 'user.id',\n device_id: 'user.device',\n session_id: 'user.session',\n },\n },\n },\n out: [\n [\n 'amplitude.track',\n 'page view',\n {},\n {\n user_id: 'us3r',\n device_id: 'c00k13',\n session_id: 394324160,\n },\n ],\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 *\n * Server-side, user_id is passed via EventOptions on identify().\n */\nexport const userLoginIdentify: AmplitudeStepExample = {\n title: 'User login identify',\n description:\n 'A user login maps to amplitude.identify with set, setOnce, and add operations while the default track call is skipped.',\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_id: '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 [\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 user_id: 'new-user-123',\n },\n ],\n ],\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 custom event has no data.currency, so the fallback fires.\n * `silent: true` suppresses the default track().\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 a 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 with multiple nested products fires one amplitude.revenue per product plus a single track for the order.',\n in: getEvent('order complete', { timestamp: 1700000108 }),\n mapping: {\n include: ['data', 'globals'],\n settings: {\n revenue: {\n loop: [\n 'nested',\n {\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 plus 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 * EventOptions mapping -- `settings.eventOptions` maps walkerOS fields\n * to Amplitude per-event metadata. Here `time` maps from the event\n * timestamp and `insert_id` maps from the event id for deduplication.\n */\nexport const eventOptionsTimeInsertId: AmplitudeStepExample = {\n title: 'Event options',\n description:\n 'Destination-level eventOptions map walker fields into Amplitude per-event metadata such as time and insert_id.',\n in: getEvent('page view', {\n timestamp: 1700000110,\n id: '1700000110abcdef',\n }),\n settings: {\n eventOptions: {\n map: {\n time: 'timestamp',\n insert_id: 'id',\n },\n },\n },\n out: [\n [\n 'amplitude.track',\n 'page view',\n {},\n {\n time: 1700000110,\n insert_id: '1700000110abcdef',\n },\n ],\n ],\n};\n\n/**\n * Consent revoked -> amplitude.setOptOut(true). After analytics consent is\n * granted (the destination loads), revoking it toggles optOut via the\n * on('consent') handler. The destination is never loaded under denied consent,\n * so the opt-out is a real revocation of an already-granted destination.\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 'After analytics consent is granted (Amplitude loads), revoking it opts out of 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":["z"]}
@@ -1,4 +1,4 @@
1
- import { Mapping, Flow } from '@walkeros/core';
1
+ import { Mapping, Flow, WalkerOS } from '@walkeros/core';
2
2
  import { DestinationServer } from '@walkeros/server-core';
3
3
 
4
4
  /**
@@ -134,6 +134,8 @@ declare namespace env {
134
134
  type AmplitudeStepExample = Flow.StepExample & {
135
135
  settings?: Partial<Settings>;
136
136
  configInclude?: string[];
137
+ /** Consent granted before `in` so a gated destination is loaded first. */
138
+ before?: WalkerOS.Consent;
137
139
  };
138
140
  /**
139
141
  * Default event forwarding -- every walkerOS event becomes
@@ -204,9 +206,10 @@ declare const groupAssignmentWithProperties: AmplitudeStepExample;
204
206
  */
205
207
  declare const eventOptionsTimeInsertId: AmplitudeStepExample;
206
208
  /**
207
- * Consent revoked -> amplitude.setOptOut(true). The destination checks
208
- * the consent keys declared in config.consent and toggles optOut
209
- * accordingly (strict: all required keys must be granted).
209
+ * Consent revoked -> amplitude.setOptOut(true). After analytics consent is
210
+ * granted (the destination loads), revoking it toggles optOut via the
211
+ * on('consent') handler. The destination is never loaded under denied consent,
212
+ * so the opt-out is a real revocation of an already-granted destination.
210
213
  *
211
214
  * Uses the canonical StepExample.command='consent' pattern: the test
212
215
  * runner dispatches via elb('walker consent', in) instead of pushing
@@ -1,4 +1,4 @@
1
- import { Mapping, Flow } from '@walkeros/core';
1
+ import { Mapping, Flow, WalkerOS } from '@walkeros/core';
2
2
  import { DestinationServer } from '@walkeros/server-core';
3
3
 
4
4
  /**
@@ -134,6 +134,8 @@ declare namespace env {
134
134
  type AmplitudeStepExample = Flow.StepExample & {
135
135
  settings?: Partial<Settings>;
136
136
  configInclude?: string[];
137
+ /** Consent granted before `in` so a gated destination is loaded first. */
138
+ before?: WalkerOS.Consent;
137
139
  };
138
140
  /**
139
141
  * Default event forwarding -- every walkerOS event becomes
@@ -204,9 +206,10 @@ declare const groupAssignmentWithProperties: AmplitudeStepExample;
204
206
  */
205
207
  declare const eventOptionsTimeInsertId: AmplitudeStepExample;
206
208
  /**
207
- * Consent revoked -> amplitude.setOptOut(true). The destination checks
208
- * the consent keys declared in config.consent and toggles optOut
209
- * accordingly (strict: all required keys must be granted).
209
+ * Consent revoked -> amplitude.setOptOut(true). After analytics consent is
210
+ * granted (the destination loads), revoking it toggles optOut via the
211
+ * on('consent') handler. The destination is never loaded under denied consent,
212
+ * so the opt-out is a real revocation of an already-granted destination.
210
213
  *
211
214
  * Uses the canonical StepExample.command='consent' pattern: the test
212
215
  * runner dispatches via elb('walker consent', in) instead of pushing
@@ -452,11 +452,15 @@ var eventOptionsTimeInsertId = {
452
452
  };
453
453
  var consentRevokeOptOut = {
454
454
  title: "Consent revoked",
455
- description: "A walker consent command with analytics denied opts out of Amplitude tracking via setOptOut(true).",
455
+ description: "After analytics consent is granted (Amplitude loads), revoking it opts out of tracking via setOptOut(true).",
456
456
  command: "consent",
457
+ before: { analytics: true },
457
458
  in: { analytics: false },
458
459
  settings: {},
459
- out: [["amplitude.setOptOut", true]]
460
+ out: [
461
+ ["amplitude.setOptOut", false],
462
+ ["amplitude.setOptOut", true]
463
+ ]
460
464
  };
461
465
  var consentGrantOptIn = {
462
466
  title: "Consent granted",
@@ -431,11 +431,15 @@ var eventOptionsTimeInsertId = {
431
431
  };
432
432
  var consentRevokeOptOut = {
433
433
  title: "Consent revoked",
434
- description: "A walker consent command with analytics denied opts out of Amplitude tracking via setOptOut(true).",
434
+ description: "After analytics consent is granted (Amplitude loads), revoking it opts out of tracking via setOptOut(true).",
435
435
  command: "consent",
436
+ before: { analytics: true },
436
437
  in: { analytics: false },
437
438
  settings: {},
438
- out: [["amplitude.setOptOut", true]]
439
+ out: [
440
+ ["amplitude.setOptOut", false],
441
+ ["amplitude.setOptOut", true]
442
+ ]
439
443
  };
440
444
  var consentGrantOptIn = {
441
445
  title: "Consent granted",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$meta": {
3
3
  "package": "@walkeros/server-destination-amplitude",
4
- "version": "4.2.0",
4
+ "version": "4.2.1-next-1781538735002",
5
5
  "type": "destination",
6
6
  "platform": [
7
7
  "server"
@@ -215,13 +215,20 @@
215
215
  },
216
216
  "consentRevokeOptOut": {
217
217
  "title": "Consent revoked",
218
- "description": "A walker consent command with analytics denied opts out of Amplitude tracking via setOptOut(true).",
218
+ "description": "After analytics consent is granted (Amplitude loads), revoking it opts out of tracking via setOptOut(true).",
219
219
  "command": "consent",
220
+ "before": {
221
+ "analytics": true
222
+ },
220
223
  "in": {
221
224
  "analytics": false
222
225
  },
223
226
  "settings": {},
224
227
  "out": [
228
+ [
229
+ "amplitude.setOptOut",
230
+ false
231
+ ],
225
232
  [
226
233
  "amplitude.setOptOut",
227
234
  true
@@ -261,7 +268,7 @@
261
268
  "consent": {
262
269
  "functional": true
263
270
  },
264
- "id": "5e37c29b916dd5d6",
271
+ "id": "12eb7250ffe6f49f",
265
272
  "trigger": "load",
266
273
  "entity": "product",
267
274
  "action": "view",
@@ -321,7 +328,7 @@
321
328
  "consent": {
322
329
  "functional": true
323
330
  },
324
- "id": "df8076c67d45a4d6",
331
+ "id": "3d5cfc02c392748a",
325
332
  "trigger": "load",
326
333
  "entity": "page",
327
334
  "action": "view",
@@ -387,7 +394,7 @@
387
394
  "consent": {
388
395
  "functional": true
389
396
  },
390
- "id": "2d646b4ad379092e",
397
+ "id": "01e53dba6bc4df83",
391
398
  "trigger": "load",
392
399
  "entity": "product",
393
400
  "action": "view",
@@ -526,7 +533,7 @@
526
533
  "consent": {
527
534
  "functional": true
528
535
  },
529
- "id": "cd3df0814eda768c",
536
+ "id": "9f4df3e7bbaffdef",
530
537
  "trigger": "test",
531
538
  "entity": "company",
532
539
  "action": "update",
@@ -671,7 +678,7 @@
671
678
  "consent": {
672
679
  "functional": true
673
680
  },
674
- "id": "fb4f6b99259bff6f",
681
+ "id": "d9eaeedcb8924a8a",
675
682
  "trigger": "load",
676
683
  "entity": "order",
677
684
  "action": "complete",
@@ -787,7 +794,7 @@
787
794
  "consent": {
788
795
  "functional": true
789
796
  },
790
- "id": "4f6bfe06eed0b33d",
797
+ "id": "872cb33c0a52af2f",
791
798
  "trigger": "test",
792
799
  "entity": "subscription",
793
800
  "action": "renew",
@@ -867,7 +874,7 @@
867
874
  "consent": {
868
875
  "functional": true
869
876
  },
870
- "id": "e64308672b5551ee",
877
+ "id": "f9f1b578cb317bff",
871
878
  "trigger": "test",
872
879
  "entity": "user",
873
880
  "action": "login",
@@ -971,7 +978,7 @@
971
978
  "consent": {
972
979
  "functional": true
973
980
  },
974
- "id": "d4e8f5823c2106c5",
981
+ "id": "69de0acd74e6a613",
975
982
  "trigger": "test",
976
983
  "entity": "debug",
977
984
  "action": "noise",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@walkeros/server-destination-amplitude",
3
3
  "description": "Amplitude server destination for walkerOS",
4
- "version": "4.2.0",
4
+ "version": "4.2.1-next-1781538735002",
5
5
  "license": "MIT",
6
6
  "exports": {
7
7
  ".": {
@@ -36,11 +36,11 @@
36
36
  },
37
37
  "dependencies": {
38
38
  "@amplitude/analytics-node": "^1.5.53",
39
- "@walkeros/core": "4.2.0",
40
- "@walkeros/server-core": "4.2.0"
39
+ "@walkeros/core": "4.2.1-next-1781538735002",
40
+ "@walkeros/server-core": "4.2.1-next-1781538735002"
41
41
  },
42
42
  "devDependencies": {
43
- "@walkeros/collector": "4.2.0"
43
+ "@walkeros/collector": "4.2.1-next-1781538735002"
44
44
  },
45
45
  "repository": {
46
46
  "url": "git+https://github.com/elbwalker/walkerOS.git",